]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib, zebra: Allow protocols to use Distance as part of RR semantics
authorDonald Sharp <sharpd@cumulusnetworks.com>
Fri, 22 Jun 2018 01:49:03 +0000 (21:49 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Sun, 29 Jul 2018 16:43:23 +0000 (12:43 -0400)
Allow protocols to specify to zebra that they would like zebra
to use the distance passed down as part of determine sameness for
Route Replace semantics.

This will be used by the static daemon to allow it to have
backup static routes with greater distances.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
lib/zebra.h
zebra/connected.c
zebra/kernel_socket.c
zebra/redistribute.c
zebra/rib.h
zebra/rt_netlink.c
zebra/zapi_msg.c
zebra/zebra_rib.c

index 98428eaab237685d5e6872e801705ef9123a308b..edae75207fd4096662fe26c8c32e16411276c989 100644 (file)
@@ -414,6 +414,7 @@ extern const char *zserv_command_string(unsigned int command);
 #define ZEBRA_FLAG_SCOPE_LINK         0x100
 #define ZEBRA_FLAG_FIB_OVERRIDE       0x200
 #define ZEBRA_FLAG_EVPN_ROUTE         0x400
+#define ZEBRA_FLAG_RR_USE_DISTANCE    0x800
 /* ZEBRA_FLAG_BLACKHOLE was 0x04 */
 /* ZEBRA_FLAG_REJECT was 0x80 */
 
index 8869d34fd6f886f9a1b69e077b8fe9e9b09e268c..57bfcc4d16d59bbd6553bd3641f3acfa9a6ecf0d 100644 (file)
@@ -403,10 +403,10 @@ void connected_down(struct interface *ifp, struct connected *ifc)
         * head.
         */
        rib_delete(afi, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0,
-                  &p, NULL, &nh, 0, 0, false);
+                  &p, NULL, &nh, 0, 0, 0, false);
 
        rib_delete(afi, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0,
-                  &p, NULL, &nh, 0, 0, false);
+                  &p, NULL, &nh, 0, 0, 0, false);
 
        if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
                char buf[PREFIX_STRLEN];
index b85c4748c4c138046b5f7fa9443f04689f273951..71d709e72d43784d5749f5a3d76729738c5c9071 100644 (file)
@@ -1043,7 +1043,7 @@ void rtm_read(struct rt_msghdr *rtm)
                if (rtm->rtm_type == RTM_CHANGE)
                        rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
                                   ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
-                                  NULL, 0, 0, true);
+                                  NULL, 0, 0, 0, true);
 
                if (!nh.type) {
                        nh.type = NEXTHOP_TYPE_IPV4;
@@ -1058,7 +1058,7 @@ void rtm_read(struct rt_msghdr *rtm)
                else
                        rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
                                   ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
-                                  &nh, 0, 0, true);
+                                  &nh, 0, 0, 0, true);
        }
        if (dest.sa.sa_family == AF_INET6) {
                /* One day we might have a debug section here like one in the
@@ -1089,7 +1089,7 @@ void rtm_read(struct rt_msghdr *rtm)
                if (rtm->rtm_type == RTM_CHANGE)
                        rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
                                   ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
-                                  NULL, 0, 0, true);
+                                  NULL, 0, 0, 0, true);
 
                if (!nh.type) {
                        nh.type = ifindex ? NEXTHOP_TYPE_IPV6_IFINDEX
@@ -1106,7 +1106,7 @@ void rtm_read(struct rt_msghdr *rtm)
                else
                        rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
                                   ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
-                                  &nh, 0, 0, true);
+                                  &nh, 0, 0, 0, true);
        }
 }
 
index 69c0ebb7ec50474d0f996cd661aeae64a16bfbfe..e3101fbe72c262bcfce9116ddb8020553680e28b 100644 (file)
@@ -597,7 +597,7 @@ int zebra_del_import_table_entry(struct route_node *rn, struct route_entry *re)
 
        rib_delete(afi, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE, re->table,
                   re->flags, &p, NULL, re->ng.nexthop,
-                  zebrad.rtm_table_default, re->metric, false);
+                  zebrad.rtm_table_default, re->metric, re->distance, false);
 
        return 0;
 }
index 439327aa48c6d2fede1e09e4d8e2310453402867..a37b2bf221881cb71cc45b775fca5bc254b5aaef 100644 (file)
@@ -311,7 +311,8 @@ extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
 extern void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
                       unsigned short instance, int flags, struct prefix *p,
                       struct prefix_ipv6 *src_p, const struct nexthop *nh,
-                      uint32_t table_id, uint32_t metric, bool fromkernel);
+                      uint32_t table_id, uint32_t metric, uint8_t distance,
+                      bool fromkernel);
 
 extern struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id,
                                     union g_addr *addr,
index 5facfa5faa49f7ab757365705c006a91ff288f43..918152aa6e2ce8ce8b8b7bccf1a314297011d9cd 100644 (file)
@@ -644,12 +644,12 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
                        if (gate)
                                memcpy(&nh.gate, gate, sz);
                        rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0, flags,
-                                  &p, &src_p, &nh, table, metric, true);
+                                  &p, &src_p, &nh, table, metric, distance, true);
                } else {
                        /* XXX: need to compare the entire list of nexthops
                         * here for NLM_F_APPEND stupidity */
                        rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0, flags,
-                                  &p, &src_p, NULL, table, metric, true);
+                                  &p, &src_p, NULL, table, metric, distance, true);
                }
        }
 
index b41cb812cb8b728354c5dec48ab04c4bdfc22e73..ad574d7e8b91fcff8625cda13a56293fe7ba7544 100644 (file)
@@ -1565,7 +1565,7 @@ static void zread_route_del(ZAPI_HANDLER_ARGS)
 
        rib_delete(afi, api.safi, zvrf_id(zvrf), api.type, api.instance,
                   api.flags, &api.prefix, src_p, NULL, table_id, api.metric,
-                  false);
+                  api.distance, false);
 
        /* Stats */
        switch (api.prefix.family) {
@@ -1767,7 +1767,7 @@ static void zread_ipv4_delete(ZAPI_HANDLER_ARGS)
        table_id = zvrf->table_id;
 
        rib_delete(AFI_IP, api.safi, zvrf_id(zvrf), api.type, api.instance,
-                  api.flags, &p, NULL, NULL, table_id, 0, false);
+                  api.flags, &p, NULL, NULL, table_id, 0, 0, false);
        client->v4_route_del_cnt++;
 
 stream_failure:
@@ -2191,7 +2191,7 @@ static void zread_ipv6_delete(ZAPI_HANDLER_ARGS)
                src_pp = NULL;
 
        rib_delete(AFI_IP6, api.safi, zvrf_id(zvrf), api.type, api.instance,
-                  api.flags, &p, src_pp, NULL, client->rtm_table, 0, false);
+                  api.flags, &p, src_pp, NULL, client->rtm_table, 0, 0, false);
 
        client->v6_route_del_cnt++;
 
index 33eebfe99ec0c0f6046c27758728145482613ee8..18bd6b6cbef60d8a18ebea6a49afa50f8f8832a6 100644 (file)
@@ -2321,7 +2321,7 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
 {
        struct route_table *table;
        struct route_node *rn;
-       struct route_entry *same;
+       struct route_entry *same = NULL;
        struct nexthop *nexthop;
        int ret = 0;
 
@@ -2355,8 +2355,13 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
        /* Lookup route node.*/
        rn = srcdest_rnode_get(table, p, src_p);
 
-       /* If same type of route are installed, treat it as a implicit
-          withdraw. */
+       zlog_debug("Distance: %d", re->distance);
+       /*
+        * If same type of route are installed, treat it as a implicit
+        * withdraw.
+        * If the user has specified the No route replace semantics
+        * for the install don't do a route replace.
+        */
        RNODE_FOREACH_RE (rn, same) {
                if (CHECK_FLAG(same->status, ROUTE_ENTRY_REMOVED))
                        continue;
@@ -2368,14 +2373,21 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
                if (same->type == ZEBRA_ROUTE_KERNEL
                    && same->metric != re->metric)
                        continue;
+
+               if (CHECK_FLAG(re->flags, ZEBRA_FLAG_RR_USE_DISTANCE) &&
+                   same->distance != re->distance)
+                       continue;
+
                /*
-                * We should allow duplicate connected routes because of
-                * IPv6 link-local routes and unnumbered interfaces on Linux.
+                * We should allow duplicate connected routes
+                * because of IPv6 link-local routes and unnumbered
+                * interfaces on Linux.
                 */
                if (same->type != ZEBRA_ROUTE_CONNECT)
                        break;
        }
 
+       zlog_debug("same: %p distance: %d", same, same ? same->distance : -1);
        /* If this route is kernel route, set FIB flag to the route. */
        if (RIB_SYSTEM_ROUTE(re))
                for (nexthop = re->ng.nexthop; nexthop; nexthop = nexthop->next)
@@ -2407,7 +2419,8 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
 void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
                unsigned short instance, int flags, struct prefix *p,
                struct prefix_ipv6 *src_p, const struct nexthop *nh,
-               uint32_t table_id, uint32_t metric, bool fromkernel)
+               uint32_t table_id, uint32_t metric, uint8_t distance,
+               bool fromkernel)
 {
        struct route_table *table;
        struct route_node *rn;
@@ -2461,6 +2474,10 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
                        continue;
                if (re->instance != instance)
                        continue;
+               if (CHECK_FLAG(re->flags, ZEBRA_FLAG_RR_USE_DISTANCE) &&
+                   distance != re->distance)
+                       continue;
+
                if (re->type == ZEBRA_ROUTE_KERNEL && re->metric != metric)
                        continue;
                if (re->type == ZEBRA_ROUTE_CONNECT && (rtnh = re->ng.nexthop)