From 3fb9cd6ef456959b6eff939d5c316f6785c2dda4 Mon Sep 17 00:00:00 2001 From: hasso Date: Tue, 19 Oct 2004 19:44:43 +0000 Subject: OK. Here it is - PtP patch from Andrew J. Schorr. No problems with ospfd, ripd might need some more testing though. --- ripd/ChangeLog | 12 +++++ ripd/rip_interface.c | 132 ++++++++++++++++++++++++++------------------------- ripd/ripd.c | 16 ++++--- 3 files changed, 88 insertions(+), 72 deletions(-) (limited to 'ripd') 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 + + * 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 * 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) -- cgit v1.2.1