]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: Do not allow delete of route from kernel in non-startup case 1240/head
authorDonald Sharp <sharpd@cumulusnetworks.com>
Mon, 25 Sep 2017 16:28:39 +0000 (12:28 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Mon, 25 Sep 2017 16:28:39 +0000 (12:28 -0400)
This is a continuation of 915902cb82cfd.  Basically the netlink
read of messages up from the kernel is now noticing the proper
owner of the route.  As such when rib_delete was being called
as part of the upcall from the kernel we were not noticing that
we were the originator and not diss-allowing the rib_delete
from happening.  This restores this behavior that we were getting
pre-915902cb82cfd

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

index 77a560c6bdc0c41206552529236e6ab993516b3d..18dc6a970b5427d7374cc6a79665fdc500cce680 100644 (file)
@@ -396,10 +396,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);
+                  &p, NULL, &nh, 0, 0, false);
 
        rib_delete(afi, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0,
-                  0, &p, NULL, &nh, 0, 0);
+                  0, &p, NULL, &nh, 0, 0, false);
 
        if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
                char buf[PREFIX_STRLEN];
index df8cdb3ab3213f162a5e691bbc01a3532bf5097b..9907ef5b7969a110598e15727594e3b7a35f0755 100644 (file)
@@ -1042,7 +1042,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);
+                                  NULL, 0, 0, true);
 
                if (!nh.type) {
                        nh.type = NEXTHOP_TYPE_IPV4;
@@ -1057,7 +1057,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);
+                                  &nh, 0, 0, true);
        }
        if (dest.sa.sa_family == AF_INET6) {
                /* One day we might have a debug section here like one in the
@@ -1088,7 +1088,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);
+                                  NULL, 0, 0, true);
 
                if (!nh.type) {
                        nh.type = ifindex ? NEXTHOP_TYPE_IPV6_IFINDEX
@@ -1105,7 +1105,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);
+                                  &nh, 0, 0, true);
        }
 }
 
index 76e0df40b9aea5f1a958a339c4a4853c3c7b2cb8..890ad887daca4af4f7685fc86d6b22c9451db2c1 100644 (file)
@@ -558,7 +558,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, NULL,
-                  zebrad.rtm_table_default, re->metric);
+                  zebrad.rtm_table_default, re->metric, false);
 
        return 0;
 }
index 4cc69377d8abc52216e541a147c412926dcfda41..e361321247a31a15a120aea94942d1de0c8cbf63 100644 (file)
@@ -302,7 +302,7 @@ extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *,
 extern void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
                       u_short instance, int flags, struct prefix *p,
                       struct prefix_ipv6 *src_p, const struct nexthop *nh,
-                      u_int32_t table_id, u_int32_t metric);
+                      u_int32_t table_id, u_int32_t metric, bool fromkernel);
 
 extern struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t,
                                     union g_addr *,
index 039fac4e67d5a9aace331eb5f47060e49502f007..2a051ba1b68cd3d1cf37bec6e78d4a696c0dc2e6 100644 (file)
@@ -560,13 +560,13 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
                                memcpy(&nh.gate, gate, sz);
                        rib_delete(afi, SAFI_UNICAST, vrf_id,
                                   proto, 0, flags, &p, NULL, &nh,
-                                  table, metric);
+                                  table, metric, 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, NULL, NULL,
-                                  table, metric);
+                                  table, metric, true);
                }
        }
 
index bb496633191a3934b06964ea52a8d8144960c49e..c1c5168b22547487be99b91f3252103bc7cc7a22 100644 (file)
@@ -2294,7 +2294,7 @@ 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,
                u_short instance, int flags, struct prefix *p,
                struct prefix_ipv6 *src_p, const struct nexthop *nh,
-               u_int32_t table_id, u_int32_t metric)
+               u_int32_t table_id, u_int32_t metric, bool fromkernel)
 {
        struct route_table *table;
        struct route_node *rn;
@@ -2375,6 +2375,21 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
        /* If same type of route can't be found and this message is from
           kernel. */
        if (!same) {
+               /*
+                * In the past(HA!) we could get here because
+                * we were receiving a route delete from the
+                * kernel and we're not marking the proto
+                * as coming from it's appropriate originator.
+                * Now that we are properly noticing the fact
+                * that the kernel has deleted our route we
+                * are not going to get called in this path
+                * I am going to leave this here because
+                * this might still work this way on non-linux
+                * platforms as well as some weird state I have
+                * not properly thought of yet.
+                * If we can show that this code path is
+                * dead then we can remove it.
+                */
                if (fib && type == ZEBRA_ROUTE_KERNEL
                    && CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE)) {
                        if (IS_ZEBRA_DEBUG_RIB) {
@@ -2423,8 +2438,17 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
                }
        }
 
-       if (same)
+       if (same) {
+               if (fromkernel &&
+                   CHECK_FLAG(flags, ZEBRA_FLAG_SELFROUTE) &&
+                   !allow_delete) {
+                       rib_install_kernel(rn, same, NULL);
+                       route_unlock_node(rn);
+
+                       return;
+               }
                rib_delnode(rn, same);
+       }
 
        route_unlock_node(rn);
        return;
index 2c0e1a020061f67e8aa9ace4938faed5ed071223..fd2c5dd97cd5d946260f76a1d8b37d16e86c9dd1 100644 (file)
@@ -1165,7 +1165,7 @@ static int zread_route_del(struct zserv *client, u_short length,
 
        rib_delete(afi, api.safi, zvrf_id(zvrf), api.type, api.instance,
                   api.flags, &api.prefix, src_p, NULL, zvrf->table_id,
-                  api.metric);
+                  api.metric, false);
 
        /* Stats */
        switch (api.prefix.family) {
@@ -1331,7 +1331,7 @@ static int zread_ipv4_delete(struct zserv *client, u_short length,
        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);
+                  api.flags, &p, NULL, NULL, table_id, 0, false);
        client->v4_route_del_cnt++;
        return 0;
 }
@@ -1693,7 +1693,7 @@ static int zread_ipv6_delete(struct zserv *client, u_short length,
                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);
+                  api.flags, &p, src_pp, NULL, client->rtm_table, 0, false);
 
        client->v6_route_del_cnt++;
        return 0;