summaryrefslogtreecommitdiff
path: root/ripd
diff options
context:
space:
mode:
Diffstat (limited to 'ripd')
-rw-r--r--ripd/ChangeLog12
-rw-r--r--ripd/rip_interface.c132
-rw-r--r--ripd/ripd.c16
3 files changed, 88 insertions, 72 deletions
diff --git a/ripd/ChangeLog b/ripd/ChangeLog
index ee878ff6..ae67e72d 100644
--- a/ripd/ChangeLog
+++ b/ripd/ChangeLog
@@ -1,3 +1,15 @@
+2004-10-19 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * ripd.c: (rip_update_interface) if connected->destination is NULL,
+ get the broadcast address with ipv4_broadcast_addr()
+ * rip_interface.c: (rip_interface_multicast_set)
+ connected->destination may be NULL. Improve message if
+ setsockopt_multicast_ipv4 fails. Improve message if bind fails.
+ (rip_request_interface_send) If connected->destination is NULL,
+ get the broadcast address with ipv4_broadcast_addr().
+ (if_valid_neighbor) Handle PtP subnet addressing properly.
+ Speed up code by using prefix_match properly.
+
2004-10-13 Hasso Tepper <hasso at quagga.net>
* ripd_snmp.c: Remove defaults used to initialize smux connection to
diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c
index 509d5ed5..19f6f114 100644
--- a/ripd/rip_interface.c
+++ b/ripd/rip_interface.c
@@ -143,16 +143,16 @@ rip_interface_multicast_set (int sock, struct connected *connected)
int ret;
struct servent *sp;
struct sockaddr_in from;
- struct in_addr addr;
+ struct in_addr addr;
struct prefix_ipv4 *p;
if (connected != NULL)
{
- if (if_is_pointopoint(connected->ifp))
- p = (struct prefix_ipv4 *) connected->destination;
- else
- p = (struct prefix_ipv4 *) connected->address;
- addr = p->prefix;
+ if (if_is_pointopoint(connected->ifp) && CONNECTED_DEST_HOST(connected))
+ p = (struct prefix_ipv4 *) connected->destination;
+ else
+ p = (struct prefix_ipv4 *) connected->address;
+ addr = p->prefix;
}
else
{
@@ -161,46 +161,52 @@ rip_interface_multicast_set (int sock, struct connected *connected)
if (setsockopt_multicast_ipv4 (sock, IP_MULTICAST_IF, addr, 0,
connected->ifp->ifindex) < 0)
- {
- zlog_warn ("Can't setsockopt IP_MULTICAST_IF to fd %d, ifindex %d",
- sock, connected->ifp->ifindex);
- return;
- }
+ {
+ zlog_warn ("Can't setsockopt IP_MULTICAST_IF on fd %d to "
+ "source address %s for interface %s",
+ sock, inet_ntoa(addr),
+ (connected ? connected->ifp->name : "(unknown)"));
+ return;
+ }
- /* Bind myself. */
- memset (&from, 0, sizeof (struct sockaddr_in));
+ /* Bind myself. */
+ memset (&from, 0, sizeof (struct sockaddr_in));
- /* Set RIP port. */
- sp = getservbyname ("router", "udp");
- if (sp)
- from.sin_port = sp->s_port;
- else
- from.sin_port = htons (RIP_PORT_DEFAULT);
+ /* Set RIP port. */
+ sp = getservbyname ("router", "udp");
+ if (sp)
+ from.sin_port = sp->s_port;
+ else
+ from.sin_port = htons (RIP_PORT_DEFAULT);
/* Address should be any address. */
- from.sin_family = AF_INET;
+ from.sin_family = AF_INET;
if (connected)
- addr = ((struct prefix_ipv4 *) connected->address)->prefix;
- from.sin_addr = addr;
+ addr = ((struct prefix_ipv4 *) connected->address)->prefix;
+ from.sin_addr = addr;
#ifdef HAVE_SIN_LEN
- from.sin_len = sizeof (struct sockaddr_in);
+ from.sin_len = sizeof (struct sockaddr_in);
#endif /* HAVE_SIN_LEN */
- if (ripd_privs.change (ZPRIVS_RAISE))
- zlog_err ("rip_interface_multicast_set: could not raise privs");
+ if (ripd_privs.change (ZPRIVS_RAISE))
+ zlog_err ("rip_interface_multicast_set: could not raise privs");
ret = bind (sock, (struct sockaddr *) & from, sizeof (struct sockaddr_in));
- if (ret < 0)
- {
- zlog_warn ("Can't bind socket: %s", strerror (errno));
- }
-
- if (ripd_privs.change (ZPRIVS_LOWER))
- zlog_err ("rip_interface_multicast_set: could not lower privs");
+ if (ret < 0)
+ {
+ zlog_warn ("Can't bind socket fd %d to %s port %d for "
+ "interface %s: %s",
+ sock,inet_ntoa(from.sin_addr),
+ (int)ntohs(from.sin_port),
+ (connected ? connected->ifp->name : "(unknown)"),
+ strerror (errno));
+ }
- return;
+ if (ripd_privs.change (ZPRIVS_LOWER))
+ zlog_err ("rip_interface_multicast_set: could not lower privs");
- }
+ return;
+}
/* Send RIP request packet to specified interface. */
void
@@ -229,17 +235,22 @@ rip_request_interface_send (struct interface *ifp, u_char version)
for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
{
- struct prefix_ipv4 *p;
struct connected *connected;
connected = getdata (cnode);
- p = (struct prefix_ipv4 *) connected->destination;
- if (p->family == AF_INET)
+ if (connected->address->family == AF_INET)
{
memset (&to, 0, sizeof (struct sockaddr_in));
to.sin_port = htons (RIP_PORT_DEFAULT);
- to.sin_addr = p->prefix;
+ if (connected->destination)
+ /* use specified broadcast or point-to-point destination addr */
+ to.sin_addr = connected->destination->u.prefix4;
+ else
+ /* calculate the appropriate broadcast address */
+ to.sin_addr.s_addr =
+ ipv4_broadcast_addr(connected->address->u.prefix4.s_addr,
+ connected->address->prefixlen);
if (IS_RIP_DEBUG_EVENT)
zlog_info ("SEND request to %s", inet_ntoa (to.sin_addr));
@@ -439,6 +450,11 @@ if_valid_neighbor (struct in_addr addr)
struct listnode *node;
struct connected *connected = NULL;
struct prefix_ipv4 *p;
+ struct prefix_ipv4 pa;
+
+ pa.family = AF_INET;
+ pa.prefix = addr;
+ pa.prefixlen = IPV4_MAX_PREFIXLEN;
for (node = listhead (iflist); node; nextnode (node))
{
@@ -449,9 +465,6 @@ if_valid_neighbor (struct in_addr addr)
for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
{
- struct prefix *pxn = NULL; /* Prefix of the neighbor */
- struct prefix *pxc = NULL; /* Prefix of the connected network */
-
connected = getdata (cnode);
if (if_is_pointopoint (ifp))
@@ -464,34 +477,23 @@ if_valid_neighbor (struct in_addr addr)
return 1;
p = (struct prefix_ipv4 *) connected->destination;
- if (p && IPV4_ADDR_SAME (&p->prefix, &addr))
- return 1;
+ if (p)
+ {
+ if (IPV4_ADDR_SAME (&p->prefix, &addr))
+ return 1;
+ }
+ else
+ {
+ if (prefix_match(connected->address,(struct prefix *)&pa))
+ return 1;
+ }
}
}
else
{
- p = (struct prefix_ipv4 *) connected->address;
-
- if (p->family != AF_INET)
- continue;
-
- pxn = prefix_new();
- pxn->family = AF_INET;
- pxn->prefixlen = 32;
- pxn->u.prefix4 = addr;
-
- pxc = prefix_new();
- prefix_copy(pxc, (struct prefix *) p);
- apply_mask(pxc);
-
- if (prefix_match (pxc, pxn))
- {
- prefix_free (pxn);
- prefix_free (pxc);
- return 1;
- }
- prefix_free(pxc);
- prefix_free(pxn);
+ if ((connected->address->family == AF_INET) &&
+ prefix_match(connected->address,(struct prefix *)&pa))
+ return 1;
}
}
}
diff --git a/ripd/ripd.c b/ripd/ripd.c
index 2b4e1b2f..94324f03 100644
--- a/ripd/ripd.c
+++ b/ripd/ripd.c
@@ -2391,7 +2391,6 @@ void
rip_update_interface (struct interface *ifp, u_char version, int route_type,
struct connected *sconn)
{
- struct prefix_ipv4 *p;
struct connected *connected;
struct listnode *node;
struct sockaddr_in to;
@@ -2415,15 +2414,18 @@ rip_update_interface (struct interface *ifp, u_char version, int route_type,
{
connected = getdata (node);
- /* Fetch broadcast address or poin-to-point destination
- address . */
- p = (struct prefix_ipv4 *) connected->destination;
-
- if (p->family == AF_INET)
+ if (connected->address->family == AF_INET)
{
/* Destination address and port setting. */
memset (&to, 0, sizeof (struct sockaddr_in));
- to.sin_addr = p->prefix;
+ if (connected->destination)
+ /* use specified broadcast or point-to-point destination addr */
+ to.sin_addr = connected->destination->u.prefix4;
+ else
+ /* calculate the appropriate broadcast address */
+ to.sin_addr.s_addr =
+ ipv4_broadcast_addr(connected->address->u.prefix4.s_addr,
+ connected->address->prefixlen);
to.sin_port = htons (RIP_PORT_DEFAULT);
if (IS_RIP_DEBUG_EVENT)