From: Donald Sharp Date: Mon, 16 Nov 2015 20:48:07 +0000 (-0800) Subject: Zebra: Remove reliance on NEXTHOP_TYPE_IPV4_ONLINK X-Git-Tag: frr-2.0-rc1~1199^2~2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=d44ca835fc8000889a92b98af5a22b8139b2a3b7;p=matthieu%2Ffrr.git Zebra: Remove reliance on NEXTHOP_TYPE_IPV4_ONLINK Zebra already knows if an interface is unnumbered or not. This is communicated to OSPF. OSPF would only send a NEXTHOP_TYPE_IPV4_ONLINK *if* the path was unnumbered, which it learns from Zebra. As such, Have OSPF use the normal NEXTHOP_TYPE_IPV4_IFINDEX type for unnumbered paths. In Zebra, if the ifindex recieved is unnumbered then assume that the link is NEXTHOP_FLAG_ONLINK. Ticket: CM-8145 Reviewed-by: CCR-3771 Testing: See bug Signed-off-by: Donald Sharp --- diff --git a/lib/zclient.c b/lib/zclient.c index f1486f4ade..512abc24d7 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -611,23 +611,7 @@ zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p, stream_write (s, (u_char *) & p->prefix, psize); /* Nexthop, ifindex, distance and metric information. */ - /* ZAPI_MESSAGE_ONLINK implies interleaving */ - if (CHECK_FLAG (api->message, ZAPI_MESSAGE_ONLINK)) - { - /* ZAPI_MESSAGE_NEXTHOP is required for proper receiving */ - assert (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP)); - /* 64-bit data units, interleaved between nexthop[] and ifindex[] */ - assert (api->nexthop_num == api->ifindex_num); - stream_putc (s, api->nexthop_num * 2); - for (i = 0; i < api->nexthop_num; i++) - { - stream_putc (s, ZEBRA_NEXTHOP_IPV4_ONLINK); - stream_put_in_addr (s, api->nexthop[i]); - stream_putc (s, ZEBRA_NEXTHOP_IFINDEX); - stream_putl (s, api->ifindex[i]); - } - } - else if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP)) + if (CHECK_FLAG (api->message, ZAPI_MESSAGE_NEXTHOP)) { /* traditional 32-bit data units */ if (CHECK_FLAG (api->flags, ZEBRA_FLAG_BLACKHOLE)) diff --git a/lib/zclient.h b/lib/zclient.h index 4d855a426a..949d42365d 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -115,7 +115,6 @@ struct zclient #define ZAPI_MESSAGE_DISTANCE 0x04 #define ZAPI_MESSAGE_METRIC 0x08 #define ZAPI_MESSAGE_TAG 0x10 -#define ZAPI_MESSAGE_ONLINK 0x20 /* Zserv protocol message header */ struct zserv_header diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index 4408627fd9..0d77e8d3a7 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -387,38 +387,27 @@ ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or) for (ALL_LIST_ELEMENTS_RO (or->paths, node, path)) { #ifdef HAVE_NETLINK - if (path->unnumbered) - { - stream_putc (s, ZEBRA_NEXTHOP_IPV4_ONLINK); - stream_put_in_addr (s, &path->nexthop); - if (path->ifindex) - stream_putl (s, path->ifindex); - else - stream_putl (s, 0); - } - else - { - if (path->nexthop.s_addr != INADDR_ANY && - path->ifindex != 0) - { - stream_putc (s, ZEBRA_NEXTHOP_IPV4_IFINDEX); - stream_put_in_addr (s, &path->nexthop); - stream_putl (s, path->ifindex); - } - else if (path->nexthop.s_addr != INADDR_ANY) - { - stream_putc (s, ZEBRA_NEXTHOP_IPV4); - stream_put_in_addr (s, &path->nexthop); - } - else - { - stream_putc (s, ZEBRA_NEXTHOP_IFINDEX); - if (path->ifindex) - stream_putl (s, path->ifindex); - else - stream_putl (s, 0); - } - } + if (path->unnumbered || + (path->nexthop.s_addr != INADDR_ANY && + path->ifindex != 0)) + { + stream_putc (s, ZEBRA_NEXTHOP_IPV4_IFINDEX); + stream_put_in_addr (s, &path->nexthop); + stream_putl (s, path->ifindex); + } + else if (path->nexthop.s_addr != INADDR_ANY) + { + stream_putc (s, ZEBRA_NEXTHOP_IPV4); + stream_put_in_addr (s, &path->nexthop); + } + else + { + stream_putc (s, ZEBRA_NEXTHOP_IFINDEX); + if (path->ifindex) + stream_putl (s, path->ifindex); + else + stream_putl (s, 0); + } #else /* HAVE_NETLINK */ if (path->nexthop.s_addr != INADDR_ANY && path->ifindex != 0) diff --git a/zebra/connected.c b/zebra/connected.c index 0d2407a3e0..b6dbad39bd 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -544,3 +544,18 @@ connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address, rib_update_static(ifp->vrf_id); } #endif /* HAVE_IPV6 */ + +int +connected_is_unnumbered (struct interface *ifp) +{ + struct connected *connected; + struct listnode *node; + + for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected)) + { + if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) && + connected->address->family == AF_INET) + return CHECK_FLAG(connected->flags, ZEBRA_IFA_UNNUMBERED); + } + return 0; +} diff --git a/zebra/connected.h b/zebra/connected.h index 55709440c6..f35f47fb6a 100644 --- a/zebra/connected.h +++ b/zebra/connected.h @@ -55,4 +55,6 @@ extern void connected_down_ipv6 (struct interface *ifp, struct connected *); #endif /* HAVE_IPV6 */ +extern int connected_is_unnumbered (struct interface *); + #endif /*_ZEBRA_CONNECTED_H */ diff --git a/zebra/rib.h b/zebra/rib.h index ca1e97a378..3656646c9b 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -385,8 +385,6 @@ extern struct nexthop *nexthop_ifname_add (struct rib *, char *); extern struct nexthop *nexthop_blackhole_add (struct rib *); extern struct nexthop *nexthop_ipv4_add (struct rib *, struct in_addr *, struct in_addr *); -extern struct nexthop * nexthop_ipv4_ifindex_ol_add (struct rib *, const struct in_addr *, - const struct in_addr *, const unsigned); extern struct nexthop *nexthop_ipv4_ifindex_add (struct rib *, struct in_addr *, struct in_addr *, diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 481c9e0d33..0fa9a79c31 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -45,6 +45,7 @@ #include "zebra/zebra_fpm.h" #include "zebra/zebra_rnh.h" #include "zebra/interface.h" +#include "zebra/connected.h" /* Default rtm_table for all clients */ extern struct zebra_t zebrad; @@ -317,6 +318,7 @@ nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4, struct in_addr *src, unsigned int ifindex) { struct nexthop *nexthop; + struct interface *ifp; nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop)); nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX; @@ -324,28 +326,16 @@ nexthop_ipv4_ifindex_add (struct rib *rib, struct in_addr *ipv4, if (src) nexthop->src.ipv4 = *src; nexthop->ifindex = ifindex; + ifp = if_lookup_by_index (nexthop->ifindex); + if (connected_is_unnumbered(ifp)) { + SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK); + } nexthop_add (rib, nexthop); return nexthop; } -struct nexthop * -nexthop_ipv4_ifindex_ol_add (struct rib *rib, const struct in_addr *ipv4, - const struct in_addr *src, const unsigned int ifindex) -{ - struct nexthop *nexthop = XCALLOC (MTYPE_NEXTHOP, sizeof (struct nexthop)); - - nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX; - IPV4_ADDR_COPY (&nexthop->gate.ipv4, ipv4); - if (src) - IPV4_ADDR_COPY (&nexthop->src.ipv4, src); - nexthop->ifindex = ifindex; - SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK); - nexthop_add (rib, nexthop); - return nexthop; -} - struct nexthop * nexthop_ipv6_add (struct rib *rib, struct in6_addr *ipv6) { @@ -456,15 +446,21 @@ nexthop_active_ipv4 (struct rib *rib, struct nexthop *nexthop, int set, if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FILTERED)) return 0; - /* onlink flag is an indication that we need to only check that - * the link is up, we won't find the GW address in the routing - * table. + /* + * Check to see if we should trust the passed in information + * for UNNUMBERED interfaces as that we won't find the GW + * address in the routing table. */ if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) { ifp = if_lookup_by_index (nexthop->ifindex); - if (ifp && if_is_operative(ifp)) - return 1; + if (ifp && connected_is_unnumbered(ifp)) + { + if (if_is_operative(ifp)) + return 1; + else + return 0; + } else return 0; } diff --git a/zebra/zserv.c b/zebra/zserv.c index cb823a0c19..3f7d73285f 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -1069,7 +1069,7 @@ zread_ipv4_add (struct zserv *client, u_short length, vrf_id_t vrf_id) struct stream *s; unsigned int ifindex; u_char ifname_len; - safi_t safi; + safi_t safi; int ret; /* Get input stream. */ @@ -1130,11 +1130,6 @@ zread_ipv4_add (struct zserv *client, u_short length, vrf_id_t vrf_id) case ZEBRA_NEXTHOP_BLACKHOLE: nexthop_blackhole_add (rib); break; - case ZEBRA_NEXTHOP_IPV4_ONLINK: - nexthop.s_addr = stream_get_ipv4 (s); - ifindex = stream_getl (s); - nexthop_ipv4_ifindex_ol_add (rib, &nexthop, NULL, ifindex); - break; } } }