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);
}
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);
}
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. */
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))
struct peer *peer;
struct peer_group *group;
struct listnode *node, *next;
+ struct vrf *vrf;
afi_t afi;
int i;
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 */
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 */