]> git.puffer.fish Git - matthieu/frr.git/commitdiff
BGP: Link BGP instance to corresponding VRF
authorvivek <vivek@cumulusnetworks.com>
Sat, 20 Feb 2016 02:43:30 +0000 (18:43 -0800)
committervivek <vivek@cumulusnetworks.com>
Sat, 20 Feb 2016 02:43:30 +0000 (18:43 -0800)
Link BGP instance (Default or VRF) to the corresponding VRF structure and
modify lookup to use this. The logic is very similar to what is implemented
in zebra - the 'struct zebra_vrf' there is essentially 'struct bgp' in BGP.

Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Ticket: CM-9122
Reviewed By: CCR-4102
Testing Done: Manual

bgpd/bgp_zebra.c
bgpd/bgpd.c
bgpd/bgpd.h

index 8a171045ffd35c2c0bb499abcca9ea828142b595..750b2263415ef106031f943d664fc5ebf81e1f99 100644 (file)
@@ -252,8 +252,8 @@ bgp_vrf_add (int command, struct zclient *zclient, zebra_size_t length,
   bgp = bgp_lookup_by_name(vrf->name);
   if (bgp)
     {
-      /* We have instance configured, make it "up". */
-      bgp->vrf_id = vrf_id;
+      /* We have instance configured, link to VRF and make it "up". */
+      bgp_vrf_link (bgp, vrf);
       bgp_instance_up (bgp);
     }
 
@@ -281,8 +281,8 @@ bgp_vrf_delete (int command, struct zclient *zclient, zebra_size_t length,
   bgp = bgp_lookup_by_name(vrf->name);
   if (bgp)
     {
-      /* We have instance configured, make it "down". */
-      bgp->vrf_id = VRF_DEFAULT;
+      /* We have instance configured, unlink from VRF and make it "down". */
+      bgp_vrf_unlink (bgp, vrf);
       bgp_instance_down (bgp);
     }
 
index 55320179e12da8745484192487b9e960be94f64d..a7d2f7f928befa78ed5e329d25d50c7daa26fbe2 100644 (file)
@@ -2823,41 +2823,18 @@ bgp_lookup_by_name (const char *name)
   return NULL;
 }
 
-/* Lookup BGP instance based on VRF id */
+/* Lookup BGP instance based on VRF id. */
+/* Note: Only to be used for incoming messages from Zebra. */
 struct bgp *
 bgp_lookup_by_vrf_id (vrf_id_t vrf_id)
-{
-  struct bgp *bgp;
-  struct listnode *node, *nnode;
-
-  for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
-    if (bgp->vrf_id == vrf_id)
-      return bgp;
-  return NULL;
-}
-
-/* Link BGP instance to VRF, if present. */
-static void
-bgp_vrf_link (struct bgp *bgp)
-{
-  struct vrf *vrf;
-
-  vrf = vrf_lookup_by_name(bgp->name);
-  if (!vrf)
-    return;
-  bgp->vrf_id = vrf->vrf_id;
-}
-
-/* Unlink BGP instance from VRF, if present. */
-static void
-bgp_vrf_unlink (struct bgp *bgp)
 {
   struct vrf *vrf;
 
-  vrf = vrf_lookup (bgp->vrf_id);
+  /* Lookup VRF (in tree) and follow link. */
+  vrf = vrf_lookup (vrf_id);
   if (!vrf)
-    return;
-  bgp->vrf_id = VRF_DEFAULT;
+    return NULL;
+  return (vrf->info) ? (struct bgp *)vrf->info : NULL;
 }
 
 /* Called from VTY commands. */
@@ -2930,9 +2907,16 @@ bgp_get (struct bgp **bgp_val, as_t *as, const char *name,
 
   listnode_add (bm->bgp, bgp);
 
-  /* If VRF, link to the VRF structure, if present. */
-  if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
-    bgp_vrf_link (bgp);
+  /* If Default instance or VRF, link to the VRF structure, if present. */
+  if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT ||
+      bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
+    {
+      struct vrf *vrf;
+
+      vrf = bgp_vrf_lookup_by_instance_type (bgp);
+      if (vrf)
+        bgp_vrf_link (bgp, vrf);
+    }
 
   /* Register with Zebra, if needed */
   if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
@@ -3006,6 +2990,7 @@ bgp_delete (struct bgp *bgp)
   struct peer *peer;
   struct peer_group *group;
   struct listnode *node, *next;
+  struct vrf *vrf;
   afi_t afi;
   int i;
 
@@ -3073,9 +3058,10 @@ bgp_delete (struct bgp *bgp)
   if (IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
     bgp_zebra_instance_deregister (bgp);
 
-  /* If VRF, unlink from the VRF structure. */
-  if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
-    bgp_vrf_unlink (bgp);
+  /* If Default instance or VRF, unlink from the VRF structure. */
+  vrf = bgp_vrf_lookup_by_instance_type (bgp);
+  if (vrf)
+    bgp_vrf_unlink (bgp, vrf);
 
   thread_master_free_unused(bm->master);
   bgp_unlock(bgp);  /* initial reference */
index ce318b33848c186233258540337d6c2dc786bf6e..8c6addacb33863ac4de36ab589741bbe2d5bc13d 100644 (file)
@@ -1438,4 +1438,39 @@ peer_cap_enhe (struct peer *peer)
   return (CHECK_FLAG(peer->af_cap[AFI_IP][SAFI_UNICAST], PEER_CAP_ENHE_AF_NEGO));
 }
 
+/* Lookup VRF for BGP instance based on its type. */
+static inline struct vrf *
+bgp_vrf_lookup_by_instance_type (struct bgp *bgp)
+{
+  struct vrf *vrf;
+
+  if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
+    vrf = vrf_lookup (VRF_DEFAULT);
+  else if (bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
+    vrf = vrf_lookup_by_name (bgp->name);
+  else
+    vrf = NULL;
+
+  return vrf;
+}
+
+/* Link BGP instance to VRF. */
+static inline void
+bgp_vrf_link (struct bgp *bgp, struct vrf *vrf)
+{
+  bgp->vrf_id = vrf->vrf_id;
+  bgp_lock (bgp);
+  vrf->info = (void *)bgp;
+
+}
+
+/* Unlink BGP instance from VRF. */
+static inline void
+bgp_vrf_unlink (struct bgp *bgp, struct vrf *vrf)
+{
+  vrf->info = NULL;
+  bgp_unlock (bgp);
+  bgp->vrf_id = VRF_DEFAULT;
+}
+
 #endif /* _QUAGGA_BGPD_H */