From 00df0c1e80811f3cf5eca0b28e720bf1bcc84a53 Mon Sep 17 00:00:00 2001 From: paul Date: Fri, 13 Dec 2002 21:07:36 +0000 Subject: [zebra 14631] Generic PtP and RFC3021 interface addressing support --- bgpd/bgp_nexthop.c | 8 ++--- lib/if.c | 34 +++++++----------- ospfd/ospf_snmp.c | 2 +- ospfd/ospfd.c | 6 ++-- ripd/rip_interface.c | 100 --------------------------------------------------- ripd/ripd.c | 4 +-- ripd/ripd.h | 2 -- zebra/connected.c | 8 ++--- zebra/rt_netlink.c | 68 ++++++++++++++++++++--------------- 9 files changed, 67 insertions(+), 165 deletions(-) diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index 24a113d9..ad932b51 100644 --- a/bgpd/bgp_nexthop.c +++ b/bgpd/bgp_nexthop.c @@ -663,7 +663,7 @@ bgp_connected_add (struct connected *ifc) p.family = AF_INET; p.prefixlen = addr->prefixlen; - if (if_is_pointopoint (ifp)) + if (ifc_pointopoint (ifc)) p.u.prefix4 = dest->u.prefix4; else p.u.prefix4 = addr->u.prefix4; @@ -694,7 +694,7 @@ bgp_connected_add (struct connected *ifc) p.family = AF_INET6; p.prefixlen = addr->prefixlen; - if (if_is_pointopoint (ifp)) + if (ifc_pointopoint (ifc)) p.u.prefix6 = dest->u.prefix6; else p.u.prefix6 = addr->u.prefix6; @@ -748,7 +748,7 @@ bgp_connected_delete (struct connected *ifc) p.family = AF_INET; p.prefixlen = addr->prefixlen; - if (if_is_pointopoint (ifp)) + if (ifc_pointopoint (ifc)) p.u.prefix4 = dest->u.prefix4; else p.u.prefix4 = addr->u.prefix4; @@ -779,7 +779,7 @@ bgp_connected_delete (struct connected *ifc) p.family = AF_INET6; p.prefixlen = addr->prefixlen; - if (if_is_pointopoint (ifp)) + if (ifc_pointopoint (ifc)) p.u.prefix6 = dest->u.prefix6; else p.u.prefix6 = addr->u.prefix6; diff --git a/lib/if.c b/lib/if.c index ce3595d3..e1a18393 100644 --- a/lib/if.c +++ b/lib/if.c @@ -189,11 +189,13 @@ if_lookup_address (struct in_addr src) listnode node; struct prefix addr; struct prefix best; + struct prefix peer; listnode cnode; struct interface *ifp; struct prefix *p; struct connected *c; struct interface *match; + int prefixlen; /* Zero structures - get rid of rubbish from stack */ memset(&addr, 0, sizeof(addr)); @@ -212,34 +214,24 @@ if_lookup_address (struct in_addr src) for (cnode = listhead (ifp->connected); cnode; nextnode (cnode)) { c = getdata (cnode); + p = c->address; - if (if_is_pointopoint (ifp)) + if (p->family == AF_INET) { - p = c->address; + prefixlen = p->prefixlen; - if (p && p->family == AF_INET) + if (if_is_pointopoint (ifp) || + prefixlen >= IPV4_MAX_PREFIXLEN - 1) { -#ifdef OLD_RIB /* PTP links are conventionally identified - by the address of the far end - MAG */ - if (IPV4_ADDR_SAME (&p->u.prefix4, &src)) - return ifp; -#endif - p = c->destination; - if (p && IPV4_ADDR_SAME (&p->u.prefix4, &src)) - return ifp; + peer = *c->destination; + peer.prefixlen = prefixlen; + p = &peer; } - } - else - { - p = c->address; - if (p->family == AF_INET) + if (prefix_match (p, &addr) && prefixlen > best.prefixlen) { - if (prefix_match (p, &addr) && p->prefixlen > best.prefixlen) - { - best = *p; - match = ifp; - } + best = *p; + match = ifp; } } } diff --git a/ospfd/ospf_snmp.c b/ospfd/ospf_snmp.c index 6187977e..4ed0ecd3 100644 --- a/ospfd/ospf_snmp.c +++ b/ospfd/ospf_snmp.c @@ -1413,7 +1413,7 @@ ospf_snmp_if_update (struct interface *ifp) /* Lookup first IPv4 address entry. */ LIST_LOOP (ifp->connected, ifc, nn) { - if (if_is_pointopoint (ifp)) + if (ifc_pointopoint (ifc)) p = ifc->destination; else p = ifc->address; diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index e8bd360b..19bc1e53 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -699,17 +699,17 @@ ospf_network_run (struct ospf *ospf, struct prefix *p, struct ospf_area *area) struct connected *co = getdata (cn); struct prefix *addr; - if (if_is_pointopoint (ifp)) + if (ifc_pointopoint (co)) addr = co->destination; else addr = co->address; if (p->family == co->address->family && ! ospf_if_is_configured (&(addr->u.prefix4))) - if ((if_is_pointopoint (ifp) && + if ((ifc_pointopoint (co) && IPV4_ADDR_SAME (&(addr->u.prefix4), &(p->u.prefix4))) || prefix_match (p, addr)) - { + { struct ospf_interface *oi; oi = ospf_if_new (ifp, co->address); diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c index bdfca575..9432717e 100644 --- a/ripd/rip_interface.c +++ b/ripd/rip_interface.c @@ -391,106 +391,6 @@ rip_if_ipv4_address_check (struct interface *ifp) return count; } - - - - -/* Does this address belongs to me ? */ -int -if_check_address (struct in_addr addr) -{ - listnode node; - - for (node = listhead (iflist); node; nextnode (node)) - { - listnode cnode; - struct interface *ifp; - - ifp = getdata (node); - - for (cnode = listhead (ifp->connected); cnode; nextnode (cnode)) - { - struct connected *connected; - struct prefix_ipv4 *p; - - connected = getdata (cnode); - p = (struct prefix_ipv4 *) connected->address; - - if (p->family != AF_INET) - continue; - - if (IPV4_ADDR_CMP (&p->prefix, &addr) == 0) - return 1; - } - } - return 0; -} - -/* is this address from a valid neighbor? (RFC2453 - Sec. 3.9.2) */ -int -if_valid_neighbor (struct in_addr addr) -{ - listnode node; - struct connected *connected = NULL; - struct prefix_ipv4 *p; - - for (node = listhead (iflist); node; nextnode (node)) - { - listnode cnode; - struct interface *ifp; - - ifp = getdata (node); - - 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)) - { - p = (struct prefix_ipv4 *) connected->address; - - if (p && p->family == AF_INET) - { - if (IPV4_ADDR_SAME (&p->prefix, &addr)) - return 1; - - p = (struct prefix_ipv4 *) connected->destination; - if (p && IPV4_ADDR_SAME (&p->prefix, &addr)) - 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); - } - } - } - return 0; -} /* Inteface link down message processing. */ int diff --git a/ripd/ripd.c b/ripd/ripd.c index c63bf104..62ebd47c 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -976,7 +976,7 @@ rip_response_process (struct rip_packet *packet, int size, /* The datagram's IPv4 source address should be checked to see whether the datagram is from a valid neighbor; the source of the datagram must be on a directly connected network */ - if (! if_valid_neighbor (from->sin_addr)) + if (if_lookup_address (from->sin_addr) == NULL) { zlog_info ("This datagram doesn't came from a valid neighbor: %s", inet_ntoa (from->sin_addr)); @@ -1535,7 +1535,7 @@ rip_read (struct thread *t) } /* Check is this packet comming from myself? */ - if (if_check_address (from.sin_addr)) + if (if_lookup_exact_address (from.sin_addr)) { if (IS_RIP_DEBUG_PACKET) zlog_warn ("ignore packet comes from myself"); diff --git a/ripd/ripd.h b/ripd/ripd.h index 2545db04..17301c37 100644 --- a/ripd/ripd.h +++ b/ripd/ripd.h @@ -359,8 +359,6 @@ void rip_zclient_init (); void rip_zclient_start (); void rip_zclient_reset (); void rip_offset_init (); -int if_check_address (struct in_addr addr); -int if_valid_neighbor (struct in_addr addr); int rip_request_send (struct sockaddr_in *, struct interface *, u_char); int rip_neighbor_lookup (struct sockaddr_in *); diff --git a/zebra/connected.c b/zebra/connected.c index cb43074b..22c9a1f6 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -69,7 +69,7 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc) p.prefixlen = addr->prefixlen; /* Point-to-point check. */ - if (if_is_pointopoint (ifp)) + if (ifc_pointopoint (ifc)) p.prefix = dest->prefix; else p.prefix = addr->prefix; @@ -162,7 +162,7 @@ connected_down_ipv4 (struct interface *ifp, struct connected *ifc) p.family = AF_INET; p.prefixlen = addr->prefixlen; - if (if_is_pointopoint (ifp)) + if (ifc_pointopoint (ifc)) p.prefix = dest->prefix; else p.prefix = addr->prefix; @@ -249,7 +249,7 @@ connected_up_ipv6 (struct interface *ifp, struct connected *ifc) p.family = AF_INET6; p.prefixlen = addr->prefixlen; - if (if_is_pointopoint (ifp) && dest) + if (ifc_pointopoint (ifc) && dest) { if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix)) p.prefix = addr->prefix; @@ -339,7 +339,7 @@ connected_down_ipv6 (struct interface *ifp, struct connected *ifc) p.family = AF_INET6; p.prefixlen = addr->prefixlen; - if (if_is_pointopoint (ifp) && dest) + if (ifc_pointopoint (ifc) && dest) { if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix)) p.prefix = addr->prefix; diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index fa4dc54f..1e39d8a7 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -388,6 +388,7 @@ netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h) void *broad = NULL; u_char flags = 0; char *label = NULL; + int peeronly = 0; ifa = NLMSG_DATA (h); @@ -416,40 +417,51 @@ netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h) return -1; } - if (tb[IFA_ADDRESS] == NULL) - tb[IFA_ADDRESS] = tb[IFA_LOCAL]; - - if (ifp->flags & IFF_POINTOPOINT) + if (IS_ZEBRA_DEBUG_KERNEL) /* remove this line to see initial ifcfg */ { + char buf[BUFSIZ]; + zlog_info ("netlink_interface_addr %s %s/%d:", + lookup (nlmsg_str, h->nlmsg_type), + ifp->name, ifa->ifa_prefixlen); if (tb[IFA_LOCAL]) - { - addr = RTA_DATA (tb[IFA_LOCAL]); - if (tb[IFA_ADDRESS]) - broad = RTA_DATA (tb[IFA_ADDRESS]); - else - broad = NULL; - } - else - { - if (tb[IFA_ADDRESS]) - addr = RTA_DATA (tb[IFA_ADDRESS]); - else - addr = NULL; - } - } - else - { + zlog_info (" IFA_LOCAL %s", inet_ntop (ifa->ifa_family, + RTA_DATA (tb[IFA_LOCAL]), buf, BUFSIZ)); if (tb[IFA_ADDRESS]) - addr = RTA_DATA (tb[IFA_ADDRESS]); - else - addr = NULL; - + zlog_info (" IFA_ADDRESS %s", inet_ntop (ifa->ifa_family, + RTA_DATA (tb[IFA_ADDRESS]), buf, BUFSIZ)); if (tb[IFA_BROADCAST]) - broad = RTA_DATA(tb[IFA_BROADCAST]); - else - broad = NULL; + zlog_info (" IFA_BROADCAST %s", inet_ntop (ifa->ifa_family, + RTA_DATA (tb[IFA_BROADCAST]), buf, BUFSIZ)); + if (tb[IFA_LABEL] && strcmp (ifp->name, RTA_DATA (tb[IFA_LABEL]))) + zlog_info (" IFA_LABEL %s", RTA_DATA (tb[IFA_LABEL])); } + /* peer or broadcast network? */ + if (ifa->ifa_family == AF_INET) + peeronly = if_is_pointopoint (ifp) || + ifa->ifa_prefixlen >= IPV4_MAX_PREFIXLEN - 1; +#ifdef HAVE_IPV6 + if (ifa->ifa_family == AF_INET6) + peeronly = if_is_pointopoint (ifp) || + ifa->ifa_prefixlen >= IPV6_MAX_PREFIXLEN - 1; +#endif /* HAVE_IPV6*/ + + /* network. prefixlen applies to IFA_ADDRESS rather than IFA_LOCAL */ + if (tb[IFA_ADDRESS] && !peeronly) + addr = RTA_DATA (tb[IFA_ADDRESS]); + else if (tb[IFA_LOCAL]) + addr = RTA_DATA (tb[IFA_LOCAL]); + else + addr = NULL; + + /* broadcast/peer */ + if (tb[IFA_BROADCAST]) + broad = RTA_DATA (tb[IFA_BROADCAST]); + else if (tb[IFA_ADDRESS] && peeronly) + broad = RTA_DATA (tb[IFA_ADDRESS]); /* peer address specified */ + else + broad = NULL; + /* Flags. */ if (ifa->ifa_flags & IFA_F_SECONDARY) SET_FLAG (flags, ZEBRA_IFA_SECONDARY); -- cgit v1.2.1