summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_conditional_adv.c199
-rw-r--r--bgpd/bgp_conditional_adv.h19
-rw-r--r--bgpd/bgp_debug.c43
-rw-r--r--bgpd/bgp_debug.h3
-rw-r--r--bgpd/bgpd.c167
-rw-r--r--bgpd/bgpd.h3
-rw-r--r--doc/user/bgp.rst4
7 files changed, 249 insertions, 189 deletions
diff --git a/bgpd/bgp_conditional_adv.c b/bgpd/bgp_conditional_adv.c
index fc44e86cbc..2598361ad2 100644
--- a/bgpd/bgp_conditional_adv.c
+++ b/bgpd/bgp_conditional_adv.c
@@ -53,18 +53,16 @@ bgp_check_rmap_prefixes_in_bgp_table(struct bgp_table *table,
if (ret == RMAP_PERMITMATCH) {
bgp_dest_unlock_node(dest);
- if (BGP_DEBUG(update, UPDATE_OUT))
- zlog_debug(
- "%s: Condition map routes present in BGP table",
- __func__);
+ bgp_cond_adv_debug(
+ "%s: Condition map routes present in BGP table",
+ __func__);
return ret;
}
}
}
- if (BGP_DEBUG(update, UPDATE_OUT))
- zlog_debug("%s: Condition map routes not present in BGP table",
+ bgp_cond_adv_debug("%s: Condition map routes not present in BGP table",
__func__);
return ret;
@@ -98,8 +96,7 @@ static void bgp_conditional_adv_routes(struct peer *peer, afi_t afi,
subgrp->pscount = 0;
SET_FLAG(subgrp->sflags, SUBGRP_STATUS_TABLE_REPARSING);
- if (BGP_DEBUG(update, UPDATE_OUT))
- zlog_debug("%s: %s routes to/from %s for %s", __func__,
+ bgp_cond_adv_debug("%s: %s routes to/from %s for %s", __func__,
update_type == UPDATE_TYPE_ADVERTISE ? "Advertise"
: "Withdraw",
peer->host, get_afi_safi_str(afi, safi, false));
@@ -224,7 +221,7 @@ static void bgp_conditional_adv_timer(struct thread *t)
&& !peer->advmap_table_change)
continue;
- if (BGP_DEBUG(update, UPDATE_OUT)) {
+ if (BGP_DEBUG(cond_adv, COND_ADV)) {
if (peer->advmap_table_change)
zlog_debug(
"%s: %s - routes changed in BGP table.",
@@ -269,10 +266,9 @@ static void bgp_conditional_adv_timer(struct thread *t)
.advmap.update_type !=
filter->advmap.update_type)) {
/* Handle change to peer advmap */
- if (BGP_DEBUG(update, UPDATE_OUT))
- zlog_debug(
- "%s: advmap.update_type changed for peer %s, adjusting update_group.",
- __func__, peer->host);
+ bgp_cond_adv_debug(
+ "%s: advmap.update_type changed for peer %s, adjusting update_group.",
+ __func__, peer->host);
update_group_adjust_peer(paf);
}
@@ -283,12 +279,10 @@ static void bgp_conditional_adv_timer(struct thread *t)
*/
if (peer->advmap_config_change[afi][safi]) {
- if (BGP_DEBUG(update, UPDATE_OUT))
- zlog_debug(
- "%s: Configuration is changed on peer %s for %s, send the normal update first.",
- __func__, peer->host,
- get_afi_safi_str(afi, safi,
- false));
+ bgp_cond_adv_debug(
+ "%s: Configuration is changed on peer %s for %s, send the normal update first.",
+ __func__, peer->host,
+ get_afi_safi_str(afi, safi, false));
if (paf) {
update_subgroup_split_peer(paf, NULL);
subgrp = paf->subgroup;
@@ -325,8 +319,7 @@ void bgp_conditional_adv_enable(struct peer *peer, afi_t afi, safi_t safi)
* neighbors (AFI/SAFI). So just increment the counter.
*/
if (++bgp->condition_filter_count > 1) {
- if (BGP_DEBUG(update, UPDATE_OUT))
- zlog_debug("%s: condition_filter_count %d", __func__,
+ bgp_cond_adv_debug("%s: condition_filter_count %d", __func__,
bgp->condition_filter_count);
return;
@@ -349,8 +342,7 @@ void bgp_conditional_adv_disable(struct peer *peer, afi_t afi, safi_t safi)
* So there's nothing to do except decrementing the counter.
*/
if (--bgp->condition_filter_count != 0) {
- if (BGP_DEBUG(update, UPDATE_OUT))
- zlog_debug("%s: condition_filter_count %d", __func__,
+ bgp_cond_adv_debug("%s: condition_filter_count %d", __func__,
bgp->condition_filter_count);
return;
@@ -359,3 +351,164 @@ void bgp_conditional_adv_disable(struct peer *peer, afi_t afi, safi_t safi)
/* Last filter removed. So cancel conditional routes polling thread. */
THREAD_OFF(bgp->t_condition_check);
}
+
+static void peer_advertise_map_filter_update(struct peer *peer, afi_t afi,
+ safi_t safi, const char *amap_name,
+ struct route_map *amap,
+ const char *cmap_name,
+ struct route_map *cmap,
+ bool condition, bool set)
+{
+ struct bgp_filter *filter;
+ bool filter_exists = false;
+
+ filter = &peer->filter[afi][safi];
+
+ /* advertise-map is already configured. */
+ if (filter->advmap.aname) {
+ filter_exists = true;
+ XFREE(MTYPE_BGP_FILTER_NAME, filter->advmap.aname);
+ XFREE(MTYPE_BGP_FILTER_NAME, filter->advmap.cname);
+ }
+
+ route_map_counter_decrement(filter->advmap.amap);
+
+ /* Removed advertise-map configuration */
+ if (!set) {
+ memset(&filter->advmap, 0, sizeof(filter->advmap));
+
+ /* decrement condition_filter_count delete timer if
+ * this is the last advertise-map to be removed.
+ */
+ if (filter_exists)
+ bgp_conditional_adv_disable(peer, afi, safi);
+
+ /* Process peer route updates. */
+ peer_on_policy_change(peer, afi, safi, 1);
+
+ return;
+ }
+
+ /* Update filter data with newly configured values. */
+ filter->advmap.aname = XSTRDUP(MTYPE_BGP_FILTER_NAME, amap_name);
+ filter->advmap.cname = XSTRDUP(MTYPE_BGP_FILTER_NAME, cmap_name);
+ filter->advmap.amap = amap;
+ filter->advmap.cmap = cmap;
+ filter->advmap.condition = condition;
+ route_map_counter_increment(filter->advmap.amap);
+ peer->advmap_config_change[afi][safi] = true;
+
+ /* Increment condition_filter_count and/or create timer. */
+ if (!filter_exists) {
+ filter->advmap.update_type = UPDATE_TYPE_ADVERTISE;
+ bgp_conditional_adv_enable(peer, afi, safi);
+ }
+
+ /* Process peer route updates. */
+ peer_on_policy_change(peer, afi, safi, 1);
+}
+
+/* Set advertise-map to the peer. */
+int peer_advertise_map_set(struct peer *peer, afi_t afi, safi_t safi,
+ const char *advertise_name,
+ struct route_map *advertise_map,
+ const char *condition_name,
+ struct route_map *condition_map, bool condition)
+{
+ struct peer *member;
+ struct listnode *node, *nnode;
+
+ /* Set configuration on peer. */
+ peer_advertise_map_filter_update(peer, afi, safi, advertise_name,
+ advertise_map, condition_name,
+ condition_map, condition, true);
+
+ /* Check if handling a regular peer & Skip peer-group mechanics. */
+ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
+ /* Set override-flag and process peer route updates. */
+ SET_FLAG(peer->filter_override[afi][safi][RMAP_OUT],
+ PEER_FT_ADVERTISE_MAP);
+ return 0;
+ }
+
+ /*
+ * Set configuration on all peer-group members, unless they are
+ * explicitly overriding peer-group configuration.
+ */
+ for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
+ /* Skip peers with overridden configuration. */
+ if (CHECK_FLAG(member->filter_override[afi][safi][RMAP_OUT],
+ PEER_FT_ADVERTISE_MAP))
+ continue;
+
+ /* Set configuration on peer-group member. */
+ peer_advertise_map_filter_update(
+ member, afi, safi, advertise_name, advertise_map,
+ condition_name, condition_map, condition, true);
+ }
+
+ return 0;
+}
+
+/* Unset advertise-map from the peer. */
+int peer_advertise_map_unset(struct peer *peer, afi_t afi, safi_t safi,
+ const char *advertise_name,
+ struct route_map *advertise_map,
+ const char *condition_name,
+ struct route_map *condition_map, bool condition)
+{
+ struct peer *member;
+ struct listnode *node, *nnode;
+
+ /* advertise-map is not configured */
+ if (!peer->filter[afi][safi].advmap.aname)
+ return 0;
+
+ /* Unset override-flag unconditionally. */
+ UNSET_FLAG(peer->filter_override[afi][safi][RMAP_OUT],
+ PEER_FT_ADVERTISE_MAP);
+
+ /* Inherit configuration from peer-group if peer is member. */
+ if (peer_group_active(peer)) {
+ PEER_STR_ATTR_INHERIT(peer, peer->group,
+ filter[afi][safi].advmap.aname,
+ MTYPE_BGP_FILTER_NAME);
+ PEER_ATTR_INHERIT(peer, peer->group,
+ filter[afi][safi].advmap.amap);
+ } else
+ peer_advertise_map_filter_update(
+ peer, afi, safi, advertise_name, advertise_map,
+ condition_name, condition_map, condition, false);
+
+ /* Check if handling a regular peer and skip peer-group mechanics. */
+ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
+ /* Process peer route updates. */
+ bgp_cond_adv_debug("%s: Send normal update to %s for %s",
+ __func__, peer->host,
+ get_afi_safi_str(afi, safi, false));
+
+ return 0;
+ }
+
+ /*
+ * Remove configuration on all peer-group members, unless they are
+ * explicitly overriding peer-group configuration.
+ */
+ for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
+ /* Skip peers with overridden configuration. */
+ if (CHECK_FLAG(member->filter_override[afi][safi][RMAP_OUT],
+ PEER_FT_ADVERTISE_MAP))
+ continue;
+ /* Remove configuration on peer-group member. */
+ peer_advertise_map_filter_update(
+ member, afi, safi, advertise_name, advertise_map,
+ condition_name, condition_map, condition, false);
+
+ /* Process peer route updates. */
+ bgp_cond_adv_debug("%s: Send normal update to %s for %s ",
+ __func__, member->host,
+ get_afi_safi_str(afi, safi, false));
+ }
+
+ return 0;
+}
diff --git a/bgpd/bgp_conditional_adv.h b/bgpd/bgp_conditional_adv.h
index 371ae856c2..a4f1403a44 100644
--- a/bgpd/bgp_conditional_adv.h
+++ b/bgpd/bgp_conditional_adv.h
@@ -33,6 +33,13 @@
extern "C" {
#endif
+/* Macro to log debug message */
+#define bgp_cond_adv_debug(...) \
+ do { \
+ if (BGP_DEBUG(cond_adv, COND_ADV)) \
+ zlog_debug("" __VA_ARGS__); \
+ } while (0)
+
/* Polling time for monitoring condition-map routes in route table */
#define DEFAULT_CONDITIONAL_ROUTES_POLL_TIME 60
@@ -40,6 +47,18 @@ extern void bgp_conditional_adv_enable(struct peer *peer, afi_t afi,
safi_t safi);
extern void bgp_conditional_adv_disable(struct peer *peer, afi_t afi,
safi_t safi);
+extern int peer_advertise_map_set(struct peer *peer, afi_t afi, safi_t safi,
+ const char *advertise_name,
+ struct route_map *advertise_map,
+ const char *condition_name,
+ struct route_map *condition_map,
+ bool condition);
+extern int peer_advertise_map_unset(struct peer *peer, afi_t afi, safi_t safi,
+ const char *advertise_name,
+ struct route_map *advertise_map,
+ const char *condition_name,
+ struct route_map *condition_map,
+ bool condition);
#ifdef __cplusplus
}
#endif
diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c
index 864cdb51a0..df7262be64 100644
--- a/bgpd/bgp_debug.c
+++ b/bgpd/bgp_debug.c
@@ -70,6 +70,7 @@ unsigned long conf_bgp_debug_pbr;
unsigned long conf_bgp_debug_graceful_restart;
unsigned long conf_bgp_debug_evpn_mh;
unsigned long conf_bgp_debug_bfd;
+unsigned long conf_bgp_debug_cond_adv;
unsigned long term_bgp_debug_as4;
unsigned long term_bgp_debug_neighbor_events;
@@ -90,6 +91,7 @@ unsigned long term_bgp_debug_pbr;
unsigned long term_bgp_debug_graceful_restart;
unsigned long term_bgp_debug_evpn_mh;
unsigned long term_bgp_debug_bfd;
+unsigned long term_bgp_debug_cond_adv;
struct list *bgp_debug_neighbor_events_peers = NULL;
struct list *bgp_debug_keepalive_peers = NULL;
@@ -2108,6 +2110,33 @@ DEFPY(debug_bgp_bfd, debug_bgp_bfd_cmd,
return CMD_SUCCESS;
}
+DEFPY (debug_bgp_cond_adv,
+ debug_bgp_cond_adv_cmd,
+ "[no$no] debug bgp conditional-advertisement",
+ NO_STR
+ DEBUG_STR
+ BGP_STR
+ "BGP conditional advertisement\n")
+{
+ if (vty->node == CONFIG_NODE) {
+ if (no)
+ DEBUG_OFF(cond_adv, COND_ADV);
+ else
+ DEBUG_ON(cond_adv, COND_ADV);
+ } else {
+ if (no) {
+ TERM_DEBUG_OFF(cond_adv, COND_ADV);
+ vty_out(vty,
+ "BGP conditional advertisement debugging is off\n");
+ } else {
+ TERM_DEBUG_ON(cond_adv, COND_ADV);
+ vty_out(vty,
+ "BGP conditional advertisement debugging is on\n");
+ }
+ }
+ return CMD_SUCCESS;
+}
+
DEFUN (no_debug_bgp,
no_debug_bgp_cmd,
"no debug bgp",
@@ -2152,6 +2181,7 @@ DEFUN (no_debug_bgp,
TERM_DEBUG_OFF(evpn_mh, EVPN_MH_ES);
TERM_DEBUG_OFF(evpn_mh, EVPN_MH_RT);
TERM_DEBUG_OFF(bfd, BFD_LIB);
+ TERM_DEBUG_OFF(cond_adv, COND_ADV);
vty_out(vty, "All possible debugging has been turned off\n");
@@ -2244,6 +2274,10 @@ DEFUN_NOSH (show_debugging_bgp,
if (BGP_DEBUG(bfd, BFD_LIB))
vty_out(vty, " BGP BFD library debugging is on\n");
+ if (BGP_DEBUG(cond_adv, COND_ADV))
+ vty_out(vty,
+ " BGP conditional advertisement debugging is on\n");
+
return CMD_SUCCESS;
}
@@ -2373,6 +2407,11 @@ static int bgp_config_write_debug(struct vty *vty)
write++;
}
+ if (CONF_BGP_DEBUG(cond_adv, COND_ADV)) {
+ vty_out(vty, "debug bgp conditional-advertisement\n");
+ write++;
+ }
+
return write;
}
@@ -2501,6 +2540,10 @@ void bgp_debug_init(void)
/* debug bgp bfd */
install_element(ENABLE_NODE, &debug_bgp_bfd_cmd);
install_element(CONFIG_NODE, &debug_bgp_bfd_cmd);
+
+ /* debug bgp conditional advertisement */
+ install_element(ENABLE_NODE, &debug_bgp_cond_adv_cmd);
+ install_element(CONFIG_NODE, &debug_bgp_cond_adv_cmd);
}
/* Return true if this prefix is on the per_prefix_list of prefixes to debug
diff --git a/bgpd/bgp_debug.h b/bgpd/bgp_debug.h
index 62f5340dfd..be5ed0afdc 100644
--- a/bgpd/bgp_debug.h
+++ b/bgpd/bgp_debug.h
@@ -80,6 +80,7 @@ extern unsigned long conf_bgp_debug_pbr;
extern unsigned long conf_bgp_debug_graceful_restart;
extern unsigned long conf_bgp_debug_evpn_mh;
extern unsigned long conf_bgp_debug_bfd;
+extern unsigned long conf_bgp_debug_cond_adv;
extern unsigned long term_bgp_debug_as4;
extern unsigned long term_bgp_debug_neighbor_events;
@@ -98,6 +99,7 @@ extern unsigned long term_bgp_debug_pbr;
extern unsigned long term_bgp_debug_graceful_restart;
extern unsigned long term_bgp_debug_evpn_mh;
extern unsigned long term_bgp_debug_bfd;
+extern unsigned long term_bgp_debug_cond_adv;
extern struct list *bgp_debug_neighbor_events_peers;
extern struct list *bgp_debug_keepalive_peers;
@@ -143,6 +145,7 @@ struct bgp_debug_filter {
#define BGP_DEBUG_GRACEFUL_RESTART 0x01
#define BGP_DEBUG_BFD_LIB 0x01
+#define BGP_DEBUG_COND_ADV 0x01
#define CONF_DEBUG_ON(a, b) (conf_bgp_debug_ ## a |= (BGP_DEBUG_ ## b))
#define CONF_DEBUG_OFF(a, b) (conf_bgp_debug_ ## a &= ~(BGP_DEBUG_ ## b))
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 749e46ebe9..b2427d7307 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -5476,8 +5476,8 @@ void peer_tcp_mss_unset(struct peer *peer)
* being used by a peer has changed (AF specific). Automatically
* initiates inbound or outbound processing as needed.
*/
-static void peer_on_policy_change(struct peer *peer, afi_t afi, safi_t safi,
- int outbound)
+void peer_on_policy_change(struct peer *peer, afi_t afi, safi_t safi,
+ int outbound)
{
if (outbound) {
update_group_adjust_peer(peer_af_find(peer, afi, safi));
@@ -7219,169 +7219,6 @@ int peer_unsuppress_map_unset(struct peer *peer, afi_t afi, safi_t safi)
return 0;
}
-static void peer_advertise_map_filter_update(struct peer *peer, afi_t afi,
- safi_t safi, const char *amap_name,
- struct route_map *amap,
- const char *cmap_name,
- struct route_map *cmap,
- bool condition, bool set)
-{
- struct bgp_filter *filter;
- bool filter_exists = false;
-
- filter = &peer->filter[afi][safi];
-
- /* advertise-map is already configured. */
- if (filter->advmap.aname) {
- filter_exists = true;
- XFREE(MTYPE_BGP_FILTER_NAME, filter->advmap.aname);
- XFREE(MTYPE_BGP_FILTER_NAME, filter->advmap.cname);
- }
-
- route_map_counter_decrement(filter->advmap.amap);
-
- /* Removed advertise-map configuration */
- if (!set) {
- memset(&filter->advmap, 0, sizeof(filter->advmap));
-
- /* decrement condition_filter_count delete timer if
- * this is the last advertise-map to be removed.
- */
- if (filter_exists)
- bgp_conditional_adv_disable(peer, afi, safi);
-
- /* Process peer route updates. */
- peer_on_policy_change(peer, afi, safi, 1);
-
- return;
- }
-
- /* Update filter data with newly configured values. */
- filter->advmap.aname = XSTRDUP(MTYPE_BGP_FILTER_NAME, amap_name);
- filter->advmap.cname = XSTRDUP(MTYPE_BGP_FILTER_NAME, cmap_name);
- filter->advmap.amap = amap;
- filter->advmap.cmap = cmap;
- filter->advmap.condition = condition;
- route_map_counter_increment(filter->advmap.amap);
- peer->advmap_config_change[afi][safi] = true;
-
- /* Increment condition_filter_count and/or create timer. */
- if (!filter_exists) {
- filter->advmap.update_type = UPDATE_TYPE_ADVERTISE;
- bgp_conditional_adv_enable(peer, afi, safi);
- }
-
- /* Process peer route updates. */
- peer_on_policy_change(peer, afi, safi, 1);
-}
-
-/* Set advertise-map to the peer. */
-int peer_advertise_map_set(struct peer *peer, afi_t afi, safi_t safi,
- const char *advertise_name,
- struct route_map *advertise_map,
- const char *condition_name,
- struct route_map *condition_map, bool condition)
-{
- struct peer *member;
- struct listnode *node, *nnode;
-
- /* Set configuration on peer. */
- peer_advertise_map_filter_update(peer, afi, safi, advertise_name,
- advertise_map, condition_name,
- condition_map, condition, true);
-
- /* Check if handling a regular peer & Skip peer-group mechanics. */
- if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
- /* Set override-flag and process peer route updates. */
- SET_FLAG(peer->filter_override[afi][safi][RMAP_OUT],
- PEER_FT_ADVERTISE_MAP);
- return 0;
- }
-
- /*
- * Set configuration on all peer-group members, unless they are
- * explicitly overriding peer-group configuration.
- */
- for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
- /* Skip peers with overridden configuration. */
- if (CHECK_FLAG(member->filter_override[afi][safi][RMAP_OUT],
- PEER_FT_ADVERTISE_MAP))
- continue;
-
- /* Set configuration on peer-group member. */
- peer_advertise_map_filter_update(
- member, afi, safi, advertise_name, advertise_map,
- condition_name, condition_map, condition, true);
- }
-
- return 0;
-}
-
-/* Unset advertise-map from the peer. */
-int peer_advertise_map_unset(struct peer *peer, afi_t afi, safi_t safi,
- const char *advertise_name,
- struct route_map *advertise_map,
- const char *condition_name,
- struct route_map *condition_map, bool condition)
-{
- struct peer *member;
- struct listnode *node, *nnode;
-
- /* advertise-map is not configured */
- if (!peer->filter[afi][safi].advmap.aname)
- return 0;
-
- /* Unset override-flag unconditionally. */
- UNSET_FLAG(peer->filter_override[afi][safi][RMAP_OUT],
- PEER_FT_ADVERTISE_MAP);
-
- /* Inherit configuration from peer-group if peer is member. */
- if (peer_group_active(peer)) {
- PEER_STR_ATTR_INHERIT(peer, peer->group,
- filter[afi][safi].advmap.aname,
- MTYPE_BGP_FILTER_NAME);
- PEER_ATTR_INHERIT(peer, peer->group,
- filter[afi][safi].advmap.amap);
- } else
- peer_advertise_map_filter_update(
- peer, afi, safi, advertise_name, advertise_map,
- condition_name, condition_map, condition, false);
-
- /* Check if handling a regular peer and skip peer-group mechanics. */
- if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
- /* Process peer route updates. */
- if (BGP_DEBUG(update, UPDATE_OUT))
- zlog_debug("%s: Send normal update to %s for %s",
- __func__, peer->host,
- get_afi_safi_str(afi, safi, false));
-
- return 0;
- }
-
- /*
- * Remove configuration on all peer-group members, unless they are
- * explicitly overriding peer-group configuration.
- */
- for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
- /* Skip peers with overridden configuration. */
- if (CHECK_FLAG(member->filter_override[afi][safi][RMAP_OUT],
- PEER_FT_ADVERTISE_MAP))
- continue;
- /* Remove configuration on peer-group member. */
- peer_advertise_map_filter_update(
- member, afi, safi, advertise_name, advertise_map,
- condition_name, condition_map, condition, false);
-
- /* Process peer route updates. */
- if (BGP_DEBUG(update, UPDATE_OUT))
- zlog_debug("%s: Send normal update to %s for %s ",
- __func__, member->host,
- get_afi_safi_str(afi, safi, false));
- }
-
- return 0;
-}
-
static bool peer_maximum_prefix_clear_overflow(struct peer *peer)
{
if (!CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index f6162f33e4..2c6618e402 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -2576,7 +2576,8 @@ void peer_tcp_mss_unset(struct peer *peer);
extern void bgp_recalculate_afi_safi_bestpaths(struct bgp *bgp, afi_t afi,
safi_t safi);
-
+extern void peer_on_policy_change(struct peer *peer, afi_t afi, safi_t safi,
+ int outbound);
#ifdef _FRR_ATTRIBUTE_PRINTFRR
/* clang-format off */
#pragma FRR printfrr_ext "%pBP" (struct peer *)
diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
index 5ce857c50c..f136ea4ae1 100644
--- a/doc/user/bgp.rst
+++ b/doc/user/bgp.rst
@@ -3497,6 +3497,10 @@ Debugging
library messages and BGP BFD integration messages that are mostly state
transitions and validation problems.
+.. clicmd:: debug bgp conditional-advertisement
+
+ Enable or disable debugging of BGP conditional advertisement.
+
.. clicmd:: debug bgp neighbor-events
Enable or disable debugging for neighbor events. This provides general