Merge pull request #11983 from maduri111/bgpd-cond-adv-debug

bgpd: adding debug command for conditional advertisement
This commit is contained in:
Donatas Abraitis 2022-10-06 12:42:28 +03:00 committed by GitHub
commit 5640afc641
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 249 additions and 189 deletions

View File

@ -53,8 +53,7 @@ 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(
bgp_cond_adv_debug(
"%s: Condition map routes present in BGP table",
__func__);
@ -63,8 +62,7 @@ bgp_check_rmap_prefixes_in_bgp_table(struct bgp_table *table,
}
}
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,8 +266,7 @@ 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(
bgp_cond_adv_debug(
"%s: advmap.update_type changed for peer %s, adjusting update_group.",
__func__, peer->host);
@ -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(
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));
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;
}

View File

@ -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

View File

@ -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

View File

@ -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))

View File

@ -5476,7 +5476,7 @@ 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,
void peer_on_policy_change(struct peer *peer, afi_t afi, safi_t safi,
int outbound)
{
if (outbound) {
@ -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))

View File

@ -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 *)

View File

@ -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