summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_main.c10
-rw-r--r--bgpd/bgp_zebra.c19
-rw-r--r--bgpd/bgpd.c46
-rw-r--r--bgpd/bgpd.h2
-rw-r--r--zebra/redistribute.c17
5 files changed, 61 insertions, 33 deletions
diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c
index ddc5c61ee7..d545becded 100644
--- a/bgpd/bgp_main.c
+++ b/bgpd/bgp_main.c
@@ -314,9 +314,6 @@ static int bgp_vrf_enable(struct vrf *vrf)
bgp_vrf_link(bgp, vrf);
bgp_handle_socket(bgp, vrf, old_vrf_id, true);
- /* Update any redistribution if vrf_id changed */
- if (old_vrf_id != bgp->vrf_id)
- bgp_redistribute_redo(bgp);
bgp_instance_up(bgp);
vpn_leak_zebra_vrf_label_update(bgp, AFI_IP);
vpn_leak_zebra_vrf_label_update(bgp, AFI_IP6);
@@ -336,7 +333,6 @@ static int bgp_vrf_enable(struct vrf *vrf)
static int bgp_vrf_disable(struct vrf *vrf)
{
struct bgp *bgp;
- vrf_id_t old_vrf_id;
if (vrf->vrf_id == VRF_DEFAULT)
return 0;
@@ -358,15 +354,11 @@ static int bgp_vrf_disable(struct vrf *vrf)
vpn_leak_prechange(BGP_VPN_POLICY_DIR_FROMVPN, AFI_IP6,
bgp_get_default(), bgp);
- old_vrf_id = bgp->vrf_id;
bgp_handle_socket(bgp, vrf, VRF_UNKNOWN, false);
/* We have instance configured, unlink from VRF and make it
* "down". */
- bgp_vrf_unlink(bgp, vrf);
- /* Delete any redistribute vrf bitmaps if the vrf_id changed */
- if (old_vrf_id != bgp->vrf_id)
- bgp_unset_redist_vrf_bitmaps(bgp, old_vrf_id);
bgp_instance_down(bgp);
+ bgp_vrf_unlink(bgp, vrf);
}
/* Note: This is a callback, the VRF will be deleted by the caller. */
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 288c2851b3..45b60b4903 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -1700,6 +1700,9 @@ int bgp_redistribute_set(struct bgp *bgp, afi_t afi, int type,
redist_add_instance(&zclient->mi_redist[afi][type], instance);
} else {
+ if (vrf_bitmap_check(zclient->redist[afi][type], bgp->vrf_id))
+ return CMD_WARNING;
+
#ifdef ENABLE_BGP_VNC
if (EVPN_ENABLED(bgp) && type == ZEBRA_ROUTE_VNC_DIRECT) {
vnc_export_bgp_enable(
@@ -1909,22 +1912,6 @@ void bgp_redistribute_redo(struct bgp *bgp)
}
}
-/* Unset redistribute vrf bitmap during triggers like
- restart networking or delete VRFs */
-void bgp_unset_redist_vrf_bitmaps(struct bgp *bgp, vrf_id_t old_vrf_id)
-{
- int i;
- afi_t afi;
-
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
- if (vrf_bitmap_check(zclient->redist[afi][i],
- old_vrf_id))
- vrf_bitmap_unset(zclient->redist[afi][i],
- old_vrf_id);
- return;
-}
-
void bgp_zclient_reset(void)
{
zclient_reset(zclient);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 21abfeb001..5e731eb5a0 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -3438,6 +3438,46 @@ int bgp_get(struct bgp **bgp_val, as_t *as, const char *name,
return BGP_CREATED;
}
+static void bgp_zclient_set_redist(afi_t afi, int type, unsigned short instance,
+ vrf_id_t vrf_id, bool set)
+{
+ if (instance) {
+ if (set)
+ redist_add_instance(&zclient->mi_redist[afi][type],
+ instance);
+ else
+ redist_del_instance(&zclient->mi_redist[afi][type],
+ instance);
+ } else {
+ if (set)
+ vrf_bitmap_set(zclient->redist[afi][type], vrf_id);
+ else
+ vrf_bitmap_unset(zclient->redist[afi][type], vrf_id);
+ }
+}
+
+static void bgp_set_redist_vrf_bitmaps(struct bgp *bgp, bool set)
+{
+ afi_t afi;
+ int i;
+ struct list *red_list;
+ struct listnode *node;
+ struct bgp_redist *red;
+
+ for (afi = AFI_IP; afi < AFI_MAX; afi++) {
+ for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
+
+ red_list = bgp->redist[afi][i];
+ if (!red_list)
+ continue;
+
+ for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
+ bgp_zclient_set_redist(afi, i, red->instance,
+ bgp->vrf_id, set);
+ }
+ }
+}
+
/*
* Make BGP instance "up". Applies only to VRFs (non-default) and
* implies the VRF has been learnt from Zebra.
@@ -3447,6 +3487,8 @@ void bgp_instance_up(struct bgp *bgp)
struct peer *peer;
struct listnode *node, *next;
+ bgp_set_redist_vrf_bitmaps(bgp, true);
+
/* Register with zebra. */
bgp_zebra_instance_register(bgp);
@@ -3491,6 +3533,10 @@ void bgp_instance_down(struct bgp *bgp)
/* Cleanup registered nexthops (flags) */
bgp_cleanup_nexthops(bgp);
+
+ bgp_zebra_instance_deregister(bgp);
+
+ bgp_set_redist_vrf_bitmaps(bgp, false);
}
/* Delete BGP instance. */
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 38c6a70b8b..4a17b72b7f 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -2386,8 +2386,6 @@ static inline bool bgp_in_graceful_shutdown(struct bgp *bgp)
!!CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN));
}
-extern void bgp_unset_redist_vrf_bitmaps(struct bgp *, vrf_id_t);
-
/* For benefit of rfapi */
extern struct peer *peer_new(struct bgp *bgp);
diff --git a/zebra/redistribute.c b/zebra/redistribute.c
index 7cb426359d..89f46f9c97 100644
--- a/zebra/redistribute.c
+++ b/zebra/redistribute.c
@@ -337,12 +337,17 @@ void zebra_redistribute_add(ZAPI_HANDLER_ARGS)
zvrf_id(zvrf), afi);
}
} else {
- if (IS_ZEBRA_DEBUG_EVENT)
- zlog_debug("%s: setting vrf %s(%u) redist bitmap",
- __func__, VRF_LOGNAME(zvrf->vrf),
- zvrf_id(zvrf));
- vrf_bitmap_set(client->redist[afi][type], zvrf_id(zvrf));
- zebra_redistribute(client, type, 0, zvrf_id(zvrf), afi);
+ if (!vrf_bitmap_check(client->redist[afi][type],
+ zvrf_id(zvrf))) {
+ if (IS_ZEBRA_DEBUG_EVENT)
+ zlog_debug(
+ "%s: setting vrf %s(%u) redist bitmap",
+ __func__, VRF_LOGNAME(zvrf->vrf),
+ zvrf_id(zvrf));
+ vrf_bitmap_set(client->redist[afi][type],
+ zvrf_id(zvrf));
+ zebra_redistribute(client, type, 0, zvrf_id(zvrf), afi);
+ }
}
stream_failure: