]> git.puffer.fish Git - matthieu/frr.git/commitdiff
*: The onlink attribute should be owned by the nexthop not the route.
authorDonald Sharp <sharpd@cumulusnetworks.com>
Sun, 27 Jan 2019 01:44:42 +0000 (20:44 -0500)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Sun, 27 Jan 2019 02:02:26 +0000 (21:02 -0500)
The onlink attribute was being passed from upper level protocols
as an attribute of the route *not* the individual nexthop.  When
we pass this data to the kernel, we treat the onlink as a attribute
of the nexthop.  This commit modifies the code base to allow
us to pass the ONLINK attribute as an attribute of the nexthop.

This commit also fixes static routes that have multiple nexthops
some onlink and some not.

ip route 4.5.6.7/32 192.168.41.1 eveth1 onlink
ip route 4.5.6.7/32 192.168.42.2

S>* 4.5.6.7/32 [1/0] via 192.168.41.1, eveth1 onlink, 00:03:04
  *                  via 192.168.42.2, eveth2, 00:03:04

sharpd@robot ~/frr2> sudo ip netns exec EVA ip route show
4.5.6.7 proto 196 metric 20
nexthop via 192.168.41.1 dev eveth1 weight 1 onlink
nexthop via 192.168.42.2 dev eveth2 weight 1

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
isisd/isis_zebra.c
lib/zclient.c
lib/zclient.h
lib/zebra.h
staticd/static_zebra.c
zebra/zapi_msg.c
zebra/zebra_rib.c

index d03c1dde08924fed75a48e646c5626c802e34915..dfe74e325ed0f2831b0e5c303c3d2ae63ac5b2b3 100644 (file)
@@ -249,8 +249,6 @@ static void isis_zebra_route_add_route(struct prefix *prefix,
                return;
 
        memset(&api, 0, sizeof(api));
-       if (fabricd)
-               api.flags |= ZEBRA_FLAG_ONLINK;
        api.vrf_id = VRF_DEFAULT;
        api.type = PROTO_TYPE;
        api.safi = SAFI_UNICAST;
@@ -275,6 +273,8 @@ static void isis_zebra_route_add_route(struct prefix *prefix,
                        if (count >= MULTIPATH_NUM)
                                break;
                        api_nh = &api.nexthops[count];
+                       if (fabricd)
+                               api_nh->onlink = true;
                        api_nh->vrf_id = VRF_DEFAULT;
                        /* FIXME: can it be ? */
                        if (nexthop->ip.s_addr != INADDR_ANY) {
@@ -298,6 +298,8 @@ static void isis_zebra_route_add_route(struct prefix *prefix,
                        }
 
                        api_nh = &api.nexthops[count];
+                       if (fabricd)
+                               api_nh->onlink = true;
                        api_nh->vrf_id = VRF_DEFAULT;
                        api_nh->gate.ipv6 = nexthop6->ip6;
                        api_nh->ifindex = nexthop6->ifindex;
index 0e58d971745b750b9c0dadd679977e78518b9060..a01da776691df59af7965bb2893670b102e1fb5e 100644 (file)
@@ -807,6 +807,7 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
 
                        stream_putl(s, api_nh->vrf_id);
                        stream_putc(s, api_nh->type);
+                       stream_putc(s, api_nh->onlink);
                        switch (api_nh->type) {
                        case NEXTHOP_TYPE_BLACKHOLE:
                                stream_putc(s, api_nh->bh_type);
@@ -973,6 +974,7 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
 
                        STREAM_GETL(s, api_nh->vrf_id);
                        STREAM_GETC(s, api_nh->type);
+                       STREAM_GETC(s, api_nh->onlink);
                        switch (api_nh->type) {
                        case NEXTHOP_TYPE_BLACKHOLE:
                                STREAM_GETC(s, api_nh->bh_type);
index 8a3423cdd8c16f23d97d3aac4cff311608a7ee80..e00821f2f67a1577535fcc709fd88713200a6981 100644 (file)
@@ -306,6 +306,7 @@ struct zapi_nexthop {
        enum nexthop_types_t type;
        vrf_id_t vrf_id;
        ifindex_t ifindex;
+       bool onlink;
        union {
                union g_addr gate;
                enum blackhole_type bh_type;
index 09115951e9b6028cced52107f2e9cc01b4fc8f60..43ab4309c21f367522ccbd4297fc637ee80ae192 100644 (file)
@@ -446,11 +446,6 @@ extern const char *zserv_command_string(unsigned int command);
  * route entry.  This mainly is used for backup static routes.
  */
 #define ZEBRA_FLAG_RR_USE_DISTANCE    0x40
-/*
- * This flag tells Zebra that the passed down route is ONLINK and the
- * kernel install flag for it should be turned on
- */
-#define ZEBRA_FLAG_ONLINK             0x80
 
 #ifndef INADDR_LOOPBACK
 #define        INADDR_LOOPBACK 0x7f000001      /* Internet address 127.0.0.1.  */
index d6db60d3ed604676986901abd0db5005721c9a7a..3f3117752439a72b121eff0731f131424b165c0e 100644 (file)
@@ -370,8 +370,6 @@ extern void static_zebra_route_add(struct route_node *rn,
                memcpy(&api.src_prefix, src_pp, sizeof(api.src_prefix));
        }
        SET_FLAG(api.flags, ZEBRA_FLAG_RR_USE_DISTANCE);
-       if (si_changed->onlink)
-               SET_FLAG(api.flags, ZEBRA_FLAG_ONLINK);
        SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
        if (si_changed->distance) {
                SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE);
@@ -397,6 +395,8 @@ extern void static_zebra_route_add(struct route_node *rn,
                        continue;
 
                api_nh->vrf_id = si->nh_vrf_id;
+               api_nh->onlink = si->onlink;
+
                switch (si->type) {
                case STATIC_IFNAME:
                        if (si->ifindex == IFINDEX_INTERNAL)
index b6d0948d3503a81095f78aa81f6e3cf23a81af50..951a411f252ea440f15e771f7dc7312b8e14b675 100644 (file)
@@ -1521,6 +1521,9 @@ static void zread_route_add(ZAPI_HANDLER_ARGS)
                        XFREE(MTYPE_RE, re);
                        return;
                }
+               if (api_nh->onlink)
+                       SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK);
+
                /* MPLS labels for BGP-LU or Segment Routing */
                if (CHECK_FLAG(api.message, ZAPI_MESSAGE_LABEL)
                    && api_nh->type != NEXTHOP_TYPE_IFINDEX
index 0dc8a05e9c6d66742b9eeb34d4fde4769ef5b633..99ddd438ea9ada34080b818361856cf05b027f6c 100644 (file)
@@ -277,8 +277,7 @@ struct nexthop *route_entry_nexthop_ipv4_ifindex_add(struct route_entry *re,
          There was a crash because ifp here was coming to be NULL */
        if (ifp)
                if (connected_is_unnumbered(ifp)
-                   || CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE)
-                   || CHECK_FLAG(re->flags, ZEBRA_FLAG_ONLINK)) {
+                   || CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE)) {
                        SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK);
                }
 
@@ -315,10 +314,8 @@ struct nexthop *route_entry_nexthop_ipv6_ifindex_add(struct route_entry *re,
        nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
        nexthop->gate.ipv6 = *ipv6;
        nexthop->ifindex = ifindex;
-       if (CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE)
-           || CHECK_FLAG(re->flags, ZEBRA_FLAG_ONLINK)) {
+       if (CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE))
                SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK);
-       }
 
        route_entry_nexthop_add(re, nexthop);
 
@@ -457,8 +454,15 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
         */
        if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) {
                ifp = if_lookup_by_index(nexthop->ifindex, nexthop->vrf_id);
-               if ((ifp && connected_is_unnumbered(ifp))
-                   || CHECK_FLAG(re->flags, ZEBRA_FLAG_ONLINK)) {
+               if (!ifp) {
+                       if (IS_ZEBRA_DEBUG_RIB_DETAILED)
+                               zlog_debug(
+                                       "\t%s: Onlink and interface: %u[%u] does not exist",
+                                       __PRETTY_FUNCTION__, nexthop->ifindex,
+                                       nexthop->vrf_id);
+                       return 0;
+               }
+               if (connected_is_unnumbered(ifp)) {
                        if (if_is_operative(ifp))
                                return 1;
                        else {
@@ -468,7 +472,8 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
                                                __PRETTY_FUNCTION__, ifp->name);
                                return 0;
                        }
-               } else {
+               }
+               if (!if_is_operative(ifp)) {
                        if (IS_ZEBRA_DEBUG_RIB_DETAILED)
                                zlog_debug(
                                        "\t%s: Interface %s is not unnumbered",