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