]> git.puffer.fish Git - matthieu/frr.git/commitdiff
BGP: Cleanup interfaces properly on instance delete or exit
authorvivek <vivek@cumulusnetworks.com>
Mon, 22 Feb 2016 06:36:37 +0000 (06:36 +0000)
committervivek <vivek@cumulusnetworks.com>
Mon, 22 Feb 2016 06:36:37 +0000 (06:36 +0000)
Perform interface cleanup as an instance is deleted. This takes care of the
scenario when BGP exits (or is stopped/restarted) too as instances undergo
deletion and the interface cleanup is done as the last step in that.

Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Fixes: 46abd3e3e6eb1f723ea7905c9919b65f1a76f385
Ticket: CM-9410
Reviewed By: CCR-4143
Testing Done: Reran failed test

bgpd/bgp_main.c
bgpd/bgpd.c
bgpd/bgpd.h
lib/vrf.c
lib/vrf.h

index 3ea74f2bdbd66252aa88cd05f6651b10245e45f0..7626077c95daf59fa74a39347e3bd5af661d6642 100644 (file)
@@ -234,9 +234,6 @@ bgp_exit (int status)
   if (retain_mode)
     if_add_hook (IF_DELETE_HOOK, NULL);
 
-  /* free interface and connected route information. */
-  bgp_if_finish ();
-
   /* reverse bgp_master_init */
   for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
     bgp_delete (bgp);
index a7d2f7f928befa78ed5e329d25d50c7daa26fbe2..38cabed3d511731a64956106e60e8da8cdabfa15 100644 (file)
@@ -3058,6 +3058,9 @@ bgp_delete (struct bgp *bgp)
   if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
     bgp_zebra_instance_deregister (bgp);
 
+  /* Free interfaces in this instance. */
+  bgp_if_finish (bgp);
+
   /* If Default instance or VRF, unlink from the VRF structure. */
   vrf = bgp_vrf_lookup_by_instance_type (bgp);
   if (vrf)
@@ -7158,34 +7161,27 @@ bgp_master_init (void)
 }
 
 /*
- * Free up connected routes and interfaces; invoked upon bgp_exit()
+ * Free up connected routes and interfaces for a BGP instance. Invoked upon
+ * instance delete (non-default only) or BGP exit.
  */
 void
-bgp_if_finish (void)
+bgp_if_finish (struct bgp *bgp)
 {
-  struct bgp *bgp;
-  struct listnode *node, *nnode;
-
-  for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
-    {
-      struct listnode *ifnode, *ifnnode;
-      struct interface *ifp;
+  struct listnode *ifnode, *ifnnode;
+  struct interface *ifp;
   
-      if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW)
-        continue;
+  if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW)
+    return;
 
-      for (ALL_LIST_ELEMENTS (vrf_iflist(bgp->vrf_id), ifnode, ifnnode, ifp))
-        {
-          struct listnode *c_node, *c_nnode;
-          struct connected *c;
+  for (ALL_LIST_ELEMENTS (vrf_iflist(bgp->vrf_id), ifnode, ifnnode, ifp))
+    {
+      struct listnode *c_node, *c_nnode;
+      struct connected *c;
 
-          for (ALL_LIST_ELEMENTS (ifp->connected, c_node, c_nnode, c))
-            bgp_connected_delete (bgp, c);
-           
-          if_delete (ifp);
-        }
-      list_free (vrf_iflist(bgp->vrf_id));
+      for (ALL_LIST_ELEMENTS (ifp->connected, c_node, c_nnode, c))
+        bgp_connected_delete (bgp, c);
     }
+  vrf_iflist_terminate (bgp->vrf_id);
 }
 
 void
index 8c6addacb33863ac4de36ab589741bbe2d5bc13d..04f5f09586715c632738a9c521579bb768391481 100644 (file)
@@ -1174,7 +1174,7 @@ extern char *peer_uptime (time_t, char *, size_t, u_char, json_object *);
 extern int bgp_config_write (struct vty *);
 extern void bgp_config_write_family_header (struct vty *, afi_t, safi_t, int *);
 
-extern void bgp_if_finish (void);
+extern void bgp_if_finish (struct bgp *);
 extern void bgp_master_init (void);
 
 extern void bgp_init (void);
index 45cc8735a21ef0eb48ec3b715e3f91fb96ba2278..a4cddeefb4e522d8636fb95165dc9cbe8302c1d2 100644 (file)
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -495,6 +495,15 @@ vrf_iflist_get (vrf_id_t vrf_id)
    return vrf->iflist;
 }
 
+/* Free the interface list of the specified VRF. */
+void
+vrf_iflist_terminate (vrf_id_t vrf_id)
+{
+   struct vrf * vrf = vrf_lookup (vrf_id);
+   if (vrf && vrf->iflist)
+     if_terminate (vrf->vrf_id, &vrf->iflist);
+}
+
 /*
  * VRF bit-map
  */
index 3ef2979dc100076cb05c0d265502c185e42ae62e..9f3b2317354ec810a455a998f09093af2d0e2689 100644 (file)
--- a/lib/vrf.h
+++ b/lib/vrf.h
@@ -180,6 +180,8 @@ extern void *vrf_info_lookup (vrf_id_t);
 extern struct list *vrf_iflist (vrf_id_t);
 /* Get the interface list of the specified VRF. Create one if not find. */
 extern struct list *vrf_iflist_get (vrf_id_t);
+/* Free the interface list of the specified VRF. */
+extern void vrf_iflist_terminate (vrf_id_t vrf_id);
 
 /*
  * VRF bit-map: maintaining flags, one bit per VRF ID