diff options
-rw-r--r-- | bgpd/bgp_nexthop.c | 8 | ||||
-rw-r--r-- | lib/if.c | 34 | ||||
-rw-r--r-- | ospfd/ospf_snmp.c | 2 | ||||
-rw-r--r-- | ospfd/ospfd.c | 4 | ||||
-rw-r--r-- | ripd/rip_interface.c | 100 | ||||
-rw-r--r-- | ripd/ripd.c | 4 | ||||
-rw-r--r-- | ripd/ripd.h | 2 | ||||
-rw-r--r-- | zebra/connected.c | 8 | ||||
-rw-r--r-- | zebra/rt_netlink.c | 60 |
9 files changed, 166 insertions, 56 deletions
diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index 77b024e5..3b91373b 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 (ifc_pointopoint (ifc)) + if (if_is_pointopoint (ifp)) 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 (ifc_pointopoint (ifc)) + if (if_is_pointopoint (ifp)) 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 (ifc_pointopoint (ifc)) + if (if_is_pointopoint (ifp)) 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 (ifc_pointopoint (ifc)) + if (if_is_pointopoint (ifp)) p.u.prefix6 = dest->u.prefix6; else p.u.prefix6 = addr->u.prefix6; @@ -245,13 +245,11 @@ 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)); @@ -270,24 +268,34 @@ if_lookup_address (struct in_addr src) for (cnode = listhead (ifp->connected); cnode; nextnode (cnode)) { c = getdata (cnode); - p = c->address; - if (p->family == AF_INET) + if (if_is_pointopoint (ifp)) { - prefixlen = p->prefixlen; + p = c->address; - if (if_is_pointopoint (ifp) || - prefixlen >= IPV4_MAX_PREFIXLEN - 1) + if (p && p->family == AF_INET) { - peer = *c->destination; - peer.prefixlen = prefixlen; - p = &peer; +#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; } + } + else + { + p = c->address; - if (prefix_match (p, &addr) && prefixlen > best.prefixlen) + if (p->family == AF_INET) { - best = *p; - match = ifp; + if (prefix_match (p, &addr) && p->prefixlen > best.prefixlen) + { + best = *p; + match = ifp; + } } } } diff --git a/ospfd/ospf_snmp.c b/ospfd/ospf_snmp.c index 41955ba5..e3d01fb6 100644 --- a/ospfd/ospf_snmp.c +++ b/ospfd/ospf_snmp.c @@ -1440,7 +1440,7 @@ ospf_snmp_if_update (struct interface *ifp) /* Lookup first IPv4 address entry. */ LIST_LOOP (ifp->connected, ifc, nn) { - if (ifc_pointopoint (ifc)) + if (if_is_pointopoint (ifp)) p = ifc->destination; else p = ifc->address; diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index aeae8e13..77bb6a47 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -714,7 +714,7 @@ ospf_network_match_iface(struct connected *co, struct prefix *net) * PtP special case: network specified == iface peer addr -> ospf */ return ( - ((ifc_pointopoint (co) && + ((if_is_pointopoint (co) && IPV4_ADDR_SAME ( &(co->destination->u.prefix4), &(net->u.prefix4))) || prefix_match (net, co->address)) ? 1 : 0 @@ -756,7 +756,7 @@ ospf_network_run (struct ospf *ospf, struct prefix *p, struct ospf_area *area) if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY)) continue; - if (ifc_pointopoint (co)) + if (if_is_pointopoint (co)) addr = co->destination; else addr = co->address; diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c index b4725225..2668e7dc 100644 --- a/ripd/rip_interface.c +++ b/ripd/rip_interface.c @@ -396,6 +396,106 @@ 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 d2a6b4d4..68f49ac2 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -1017,7 +1017,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_lookup_address (from->sin_addr) == NULL) + if (! if_valid_neighbor (from->sin_addr)) { zlog_info ("This datagram doesn't came from a valid neighbor: %s", inet_ntoa (from->sin_addr)); @@ -1602,7 +1602,7 @@ rip_read (struct thread *t) } /* Check is this packet comming from myself? */ - if (if_lookup_exact_address (from.sin_addr)) + if (if_check_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 c414c76d..dc2f64d0 100644 --- a/ripd/ripd.h +++ b/ripd/ripd.h @@ -374,6 +374,8 @@ 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 280e423e..1d19258f 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 (ifc_pointopoint (ifc) && dest) + if (if_is_pointopoint (ifc) && dest) p.prefix = dest->prefix; else p.prefix = addr->prefix; @@ -163,7 +163,7 @@ connected_down_ipv4 (struct interface *ifp, struct connected *ifc) p.prefixlen = addr->prefixlen; /* Point-to-point check. */ - if (dest && ifc_pointopoint (ifc)) + if (dest && if_is_pointopoint (ifc)) p.prefix = dest->prefix; else p.prefix = addr->prefix; @@ -250,7 +250,7 @@ connected_up_ipv6 (struct interface *ifp, struct connected *ifc) p.family = AF_INET6; p.prefixlen = addr->prefixlen; - if (ifc_pointopoint (ifc) && dest) + if (if_is_pointopoint (ifp) && dest) { if (IN6_IS_ADDR_UNSPECIFIED (&dest->prefix)) p.prefix = addr->prefix; @@ -343,7 +343,7 @@ connected_down_ipv6 (struct interface *ifp, struct connected *ifc) p.family = AF_INET6; p.prefixlen = addr->prefixlen; - if (ifc_pointopoint (ifc) && dest) + if (if_is_pointopoint (ifp) && 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 a2efa17a..02cae6ee 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -487,7 +487,6 @@ 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); @@ -539,40 +538,41 @@ netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h) 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) + + if (tb[IFA_ADDRESS] == NULL) + tb[IFA_ADDRESS] = tb[IFA_LOCAL]; + + if (ifp->flags & IFF_POINTOPOINT) { - peeronly = if_is_pointopoint (ifp) || - ifa->ifa_prefixlen >= IPV6_MAX_PREFIXLEN - 1; + 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; + } } -#endif /* HAVE_IPV6 */ - if (!(tb[IFA_LOCAL] && tb[IFA_ADDRESS])) + else { - /* FIXME: IPv6 Appears to have only IFA_ADDRESS */ - peeronly = 0; + if (tb[IFA_ADDRESS]) + addr = RTA_DATA (tb[IFA_ADDRESS]); + else + addr = NULL; + + if (tb[IFA_BROADCAST]) + broad = RTA_DATA(tb[IFA_BROADCAST]); + else + broad = NULL; } - /* 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); |