]> git.puffer.fish Git - mirror/frr.git/commitdiff
Ensure connected nexthop entry for the peer is freed when the peer is freed.
authorDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 20 May 2015 01:03:54 +0000 (18:03 -0700)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 20 May 2015 01:03:54 +0000 (18:03 -0700)
bgpd/bgp_nht.c
bgpd/bgp_nht.h
bgpd/bgpd.c

index c460f0ee6819607d80fd2d7f7e41aaf5841a7c68..ceb231a6dde6322cab3807e81255afad0e44b28b 100644 (file)
@@ -128,6 +128,13 @@ bgp_find_or_add_nexthop (struct bgp *bgp, afi_t afi, struct bgp_info *ri,
       bgp_lock_node(rn);
       if (connected)
        SET_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED);
+      if (BGP_DEBUG(nht, NHT))
+        {
+          char buf[INET6_ADDRSTRLEN];
+
+          zlog_debug("Allocated bnc %s peer %p",
+                     bnc_str(bnc, buf, INET6_ADDRSTRLEN), peer);
+        }
     }
 
   bnc = rn->info;
@@ -151,6 +158,61 @@ bgp_find_or_add_nexthop (struct bgp *bgp, afi_t afi, struct bgp_info *ri,
   return (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID));
 }
 
+void
+bgp_delete_connected_nexthop (afi_t afi, struct peer *peer)
+{
+  struct bgp_node *rn;
+  struct bgp_nexthop_cache *bnc;
+  struct prefix p;
+
+  if (afi == AFI_IP)
+    {
+      p.family = AF_INET;
+      p.prefixlen = IPV4_MAX_BITLEN;
+      p.u.prefix4 = peer->su.sin.sin_addr;
+    }
+  else if (afi == AFI_IP6)
+    {
+      p.family = AF_INET6;
+      p.prefixlen = IPV6_MAX_BITLEN;
+      p.u.prefix6 = peer->su.sin6.sin6_addr;
+    }
+
+  rn = bgp_node_lookup(bgp_nexthop_cache_table[family2afi(p.family)], &p);
+  if (!rn || !rn->info)
+    {
+      if (BGP_DEBUG(nht, NHT))
+        zlog_debug("Cannot find connected NHT node for peer %s", peer->host);
+      if (rn)
+        bgp_unlock_node (rn);
+      return;
+    }
+
+  bnc = rn->info;
+  bgp_unlock_node(rn);
+
+  if (bnc->nht_info != peer)
+    {
+      if (BGP_DEBUG(nht, NHT))
+        zlog_debug("Connected NHT %p node for peer %s points to %p",
+                    bnc, peer->host, bnc->nht_info);
+      return;
+    }
+
+  bnc->nht_info = NULL;
+
+  if (LIST_EMPTY(&(bnc->paths)))
+    {
+      if (BGP_DEBUG(nht, NHT))
+        zlog_debug("Freeing connected NHT node %p for peer %s",
+                    bnc,  peer->host);
+      unregister_nexthop(bnc);
+      bnc->node->info = NULL;
+      bgp_unlock_node(bnc->node);
+      bnc_free(bnc);
+    }
+}
+
 void
 bgp_parse_nexthop_update (void)
 {
index 2c779802b576a262cb63eba9192b8de78b3ffbe3..963dd00f27c9be8077a0e72285c0579a74f7ba86 100644 (file)
@@ -56,4 +56,14 @@ extern int bgp_find_or_add_nexthop(struct bgp *bgp, afi_t a,
  */
 extern void bgp_unlink_nexthop(struct bgp_info *p);
 
+/**
+ * bgp_delete_connected_nexthop() - Reset the 'peer' pointer for a connected
+ * nexthop entry. If no paths reference the nexthop, it will be unregistered
+ * and freed.
+ * ARGUMENTS:
+ *   afi - afi: AFI_IP or AF_IP6
+ *   peer - Ptr to peer
+ */
+extern void bgp_delete_connected_nexthop (afi_t afi, struct peer *peer);
+
 #endif /* _BGP_NHT_H */
index a204e972a6660c7320b3812fa585e87b3df8af65..aed6debfc4d3420ee2bcc4e10077ffb90e1081d9 100644 (file)
@@ -882,6 +882,11 @@ peer_free (struct peer *peer)
   BGP_WRITE_OFF (peer->t_write);
   BGP_EVENT_FLUSH (peer);
   
+  /* Free connected nexthop, if present */
+  if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE) &&
+      !peer_dynamic_neighbor (peer))
+    bgp_delete_connected_nexthop (family2afi(peer->su.sa.sa_family), peer);
+
   if (peer->desc)
     XFREE (MTYPE_PEER_DESC, peer->desc);