]> git.puffer.fish Git - matthieu/frr.git/commitdiff
Zebra: Fix multiple RNH deletes
authorDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 20 May 2015 01:04:10 +0000 (18:04 -0700)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 20 May 2015 01:04:10 +0000 (18:04 -0700)
The code is structured in a way that ends up invoking zebra_delete_rnh()
multiple times which can lead to crashes and asserts. This patch fixes
the issue by setting a flag when an RNH structure is being deleted and
ignores any further attempts to delete the structure.

zebra/zebra_rib.c
zebra/zebra_rnh.c
zebra/zebra_rnh.h

index 133948292197e6d38fa66d2df0a62104b043215f..f2dfe04c934d5fcec25e8bd2be9d569f884650d0 100644 (file)
@@ -330,14 +330,15 @@ nexthops_free (struct nexthop *nexthop, struct route_node *rn)
          nh_p.family = AF_INET;
          nh_p.prefixlen = IPV4_MAX_BITLEN;
          nh_p.u.prefix4 = nh->gate.ipv4;
+         zebra_deregister_rnh_static_nh(&nh_p, rn);
        }
       else if (nh->type == NEXTHOP_TYPE_IPV6)
        {
          nh_p.family = AF_INET6;
          nh_p.prefixlen = IPV6_MAX_BITLEN;
          nh_p.u.prefix6 = nh->gate.ipv6;
+         zebra_deregister_rnh_static_nh(&nh_p, rn);
        }
-      zebra_deregister_rnh_static_nh(&nh_p, rn);
       nexthop_free (nh, rn);
     }
 }
index 2c2bd11993d96ed1e76d206764649d3ad2f63cc6..9b1c978ef7cd773fdc63d227eaab17e3df368d3a 100644 (file)
@@ -137,7 +137,7 @@ zebra_delete_rnh (struct rnh *rnh)
 {
   struct route_node *rn;
 
-  if (!rnh || !(rn = rnh->node))
+  if (!rnh || (rnh->flags & ZEBRA_NHT_DELETED) || !(rn = rnh->node))
     return;
 
   if (IS_ZEBRA_DEBUG_NHT)
@@ -146,6 +146,7 @@ zebra_delete_rnh (struct rnh *rnh)
       zlog_debug("delete rnh %s", rnh_str(rnh, buf, INET6_ADDRSTRLEN));
     }
 
+  rnh->flags |= ZEBRA_NHT_DELETED;
   list_free(rnh->client_list);
   list_free(rnh->zebra_static_route_list);
   free_state(rnh->state, rn);
@@ -206,7 +207,7 @@ zebra_deregister_rnh_static_nh(struct prefix *nh, struct route_node *static_rn)
   struct rnh *rnh;
 
   rnh = zebra_lookup_rnh(nh, 0);
-  if (!rnh)
+  if (!rnh || (rnh->flags & ZEBRA_NHT_DELETED))
     return;
 
   listnode_delete(rnh->zebra_static_route_list, static_rn);
index 53e932aa4962d886071c2e89641c86de8e89cefa..af56d36aaa88afb6859130bce1536f642a2732c9 100644 (file)
@@ -31,6 +31,7 @@ struct rnh
 {
   u_char flags;
 #define ZEBRA_NHT_CONNECTED    0x1
+#define ZEBRA_NHT_DELETED       0x2
   struct rib *state;
   struct list *client_list;
   struct list *zebra_static_route_list; /* static routes dependent on this NH */