diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c index 097d3684f67c..319638e41244 100644 --- a/bgpd/bgp_debug.c +++ b/bgpd/bgp_debug.c @@ -60,6 +60,7 @@ 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 conf_bgp_debug_aggregate; unsigned long term_bgp_debug_as4; unsigned long term_bgp_debug_neighbor_events; @@ -80,6 +81,7 @@ 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; +unsigned long term_bgp_debug_aggregate; struct list *bgp_debug_neighbor_events_peers = NULL; struct list *bgp_debug_keepalive_peers = NULL; @@ -88,6 +90,7 @@ struct list *bgp_debug_update_in_peers = NULL; struct list *bgp_debug_update_prefixes = NULL; struct list *bgp_debug_bestpath_prefixes = NULL; struct list *bgp_debug_zebra_prefixes = NULL; +struct list *bgp_debug_aggregate_prefixes; /* messages for BGP-4 status */ const struct message bgp_status_msg[] = {{Idle, "Idle"}, @@ -1812,6 +1815,107 @@ DEFPY (no_debug_bgp_zebra_prefix, return CMD_SUCCESS; } +/* debug bgp aggregate */ +DEFPY (debug_bgp_aggregate, + debug_bgp_aggregate_cmd, + "debug bgp aggregate", + DEBUG_STR + BGP_STR + "BGP aggregate\n") +{ + if (vty->node == CONFIG_NODE) + DEBUG_ON(aggregate, AGGREGATE); + else { + TERM_DEBUG_ON(aggregate, AGGREGATE); + vty_out(vty, "BGP aggregate debugging is on\n"); + } + return CMD_SUCCESS; +} + +DEFPY (no_debug_bgp_aggregate, + no_debug_bgp_aggregate_cmd, + "no debug bgp aggregate", + NO_STR + DEBUG_STR + BGP_STR + "BGP aggregate\n") +{ + bgp_debug_list_free(bgp_debug_aggregate_prefixes); + + if (vty->node == CONFIG_NODE) + DEBUG_OFF(aggregate, AGGREGATE); + else { + TERM_DEBUG_OFF(aggregate, AGGREGATE); + vty_out(vty, "BGP aggregate debugging is off\n"); + } + return CMD_SUCCESS; +} + +DEFPY (debug_bgp_aggregate_prefix, + debug_bgp_aggregate_prefix_cmd, + "debug bgp aggregate prefix $prefix", + DEBUG_STR + BGP_STR + "BGP aggregate\n" + "Specify a prefix to debug\n" + "IPv4 prefix\n" + "IPv6 prefix\n") +{ + if (!bgp_debug_aggregate_prefixes) + bgp_debug_aggregate_prefixes = list_new(); + + if (bgp_debug_list_has_entry(bgp_debug_aggregate_prefixes, NULL, prefix, NULL)) { + vty_out(vty, "BGP aggregate debugging is already enabled for %s\n", prefix_str); + return CMD_SUCCESS; + } + + bgp_debug_list_add_entry(bgp_debug_aggregate_prefixes, NULL, prefix, NULL); + + if (vty->node == CONFIG_NODE) + DEBUG_ON(aggregate, AGGREGATE); + else { + TERM_DEBUG_ON(aggregate, AGGREGATE); + vty_out(vty, "BGP aggregate debugging is on for %s\n", prefix_str); + } + + return CMD_SUCCESS; +} + +DEFPY (no_debug_bgp_aggregate_prefix, + no_debug_bgp_aggregate_prefix_cmd, + "no debug bgp aggregate prefix $prefix", + NO_STR + DEBUG_STR + BGP_STR + "BGP aggregate\n" + "Specify a prefix to debug\n" + "IPv4 prefix\n" + "IPv6 prefix\n") +{ + bool found_prefix = false; + + if (bgp_debug_aggregate_prefixes && !list_isempty(bgp_debug_aggregate_prefixes)) { + found_prefix = bgp_debug_list_remove_entry(bgp_debug_aggregate_prefixes, NULL, + (struct prefix *)prefix); + + if (list_isempty(bgp_debug_aggregate_prefixes)) { + if (vty->node == CONFIG_NODE) + DEBUG_OFF(aggregate, AGGREGATE); + else { + TERM_DEBUG_OFF(aggregate, AGGREGATE); + vty_out(vty, "BGP aggregate debugging is off\n"); + } + } + } + + if (found_prefix) + vty_out(vty, "BGP aggregate debugging is off for %s\n", prefix_str); + else + vty_out(vty, "BGP aggregate debugging was not enabled for %s\n", prefix_str); + + return CMD_SUCCESS; +} + /* debug bgp update-groups */ DEFUN (debug_bgp_update_groups, debug_bgp_update_groups_cmd, @@ -2239,6 +2343,10 @@ DEFUN_NOSH (show_debugging_bgp, bgp_debug_list_print(vty, " BGP zebra debugging is on", bgp_debug_zebra_prefixes); + if (BGP_DEBUG(aggregate, AGGREGATE)) + bgp_debug_list_print(vty, " BGP aggregate debugging is on", + bgp_debug_aggregate_prefixes); + if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) vty_out(vty, " BGP graceful-restart debugging is on\n"); @@ -2412,6 +2520,16 @@ static int bgp_config_write_debug(struct vty *vty) write++; } + if (CONF_BGP_DEBUG(aggregate, AGGREGATE)) { + if (!bgp_debug_aggregate_prefixes || list_isempty(bgp_debug_aggregate_prefixes)) { + vty_out(vty, "debug bgp aggregate\n"); + write++; + } else { + write += bgp_debug_list_conf_print(vty, "debug bgp aggregate prefix", + bgp_debug_aggregate_prefixes); + } + } + if (hook_call(bgp_hook_config_write_debug, vty, true)) write++; @@ -2485,6 +2603,16 @@ void bgp_debug_init(void) install_element(ENABLE_NODE, &no_debug_bgp_zebra_prefix_cmd); install_element(CONFIG_NODE, &no_debug_bgp_zebra_prefix_cmd); + /* debug bgp aggregate prefix A.B.C.D/M */ + install_element(ENABLE_NODE, &debug_bgp_aggregate_cmd); + install_element(CONFIG_NODE, &debug_bgp_aggregate_cmd); + install_element(ENABLE_NODE, &no_debug_bgp_aggregate_cmd); + install_element(CONFIG_NODE, &no_debug_bgp_aggregate_cmd); + install_element(ENABLE_NODE, &debug_bgp_aggregate_prefix_cmd); + install_element(CONFIG_NODE, &debug_bgp_aggregate_prefix_cmd); + install_element(ENABLE_NODE, &no_debug_bgp_aggregate_prefix_cmd); + install_element(CONFIG_NODE, &no_debug_bgp_aggregate_prefix_cmd); + install_element(ENABLE_NODE, &no_debug_bgp_as4_cmd); install_element(CONFIG_NODE, &no_debug_bgp_as4_cmd); install_element(ENABLE_NODE, &no_debug_bgp_as4_segment_cmd); @@ -2714,6 +2842,17 @@ bool bgp_debug_zebra(const struct prefix *p) return false; } +bool bgp_debug_aggregate(const struct prefix *p) +{ + if (BGP_DEBUG(aggregate, AGGREGATE)) { + if (bgp_debug_per_prefix(p, term_bgp_debug_aggregate, BGP_DEBUG_AGGREGATE, + bgp_debug_aggregate_prefixes)) + return true; + } + + return false; +} + const char *bgp_debug_rdpfxpath2str(afi_t afi, safi_t safi, const struct prefix_rd *prd, union prefixconstptr pu, diff --git a/bgpd/bgp_debug.h b/bgpd/bgp_debug.h index 061d966dc392..11b5e52098ca 100644 --- a/bgpd/bgp_debug.h +++ b/bgpd/bgp_debug.h @@ -71,6 +71,7 @@ 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 conf_bgp_debug_aggregate; extern unsigned long term_bgp_debug_as4; extern unsigned long term_bgp_debug_neighbor_events; @@ -89,6 +90,7 @@ 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 unsigned long term_bgp_debug_aggregate; extern struct list *bgp_debug_neighbor_events_peers; extern struct list *bgp_debug_keepalive_peers; @@ -97,6 +99,7 @@ extern struct list *bgp_debug_update_out_peers; extern struct list *bgp_debug_update_prefixes; extern struct list *bgp_debug_bestpath_prefixes; extern struct list *bgp_debug_zebra_prefixes; +extern struct list *bgp_debug_aggregate_prefixes; struct bgp_debug_filter { char *host; @@ -135,6 +138,7 @@ struct bgp_debug_filter { #define BGP_DEBUG_BFD_LIB 0x01 #define BGP_DEBUG_COND_ADV 0x01 +#define BGP_DEBUG_AGGREGATE 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)) @@ -172,6 +176,7 @@ extern bool bgp_debug_update(const struct peer *peer, const struct prefix *p, struct update_group *updgrp, unsigned int inbound); extern bool bgp_debug_bestpath(struct bgp_dest *dest); extern bool bgp_debug_zebra(const struct prefix *p); +extern bool bgp_debug_aggregate(const struct prefix *p); extern const char *bgp_debug_rdpfxpath2str( afi_t afi, safi_t safi, const struct prefix_rd *prd, diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index f519534192f4..88d7704ac95c 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -7982,6 +7982,10 @@ static void bgp_aggregate_install( struct bgp_table *table; struct bgp_path_info *pi, *orig, *new; struct attr *attr; + bool debug = bgp_debug_aggregate(p); + + if (debug) + zlog_debug("%s: aggregate %pFX, count %lu", __func__, p, aggregate->count); table = bgp->rib[afi][safi]; @@ -8017,7 +8021,8 @@ static void bgp_aggregate_install( ecommunity_free(&ecommunity); if (lcommunity) lcommunity_free(&lcommunity); - + if (debug) + zlog_debug(" aggregate %pFX: duplicate", p); return; } @@ -8027,6 +8032,8 @@ static void bgp_aggregate_install( if (pi) { bgp_path_info_delete(dest, pi); bgp_process(bgp, dest, pi, afi, safi); + if (debug) + zlog_debug(" aggregate %pFX: existing, removed", p); } attr = bgp_attr_aggregate_intern( @@ -8040,9 +8047,8 @@ static void bgp_aggregate_install( lcommunity_free(&lcommunity); bgp_dest_unlock_node(dest); bgp_aggregate_delete(bgp, p, afi, safi, aggregate); - if (BGP_DEBUG(update_groups, UPDATE_GROUPS)) - zlog_debug("%s: %pFX null attribute", __func__, - p); + if (debug) + zlog_debug("%s: %pFX null attribute", __func__, p); return; } @@ -8053,6 +8059,8 @@ static void bgp_aggregate_install( bgp_path_info_add(dest, new); bgp_process(bgp, dest, new, afi, safi); + if (debug) + zlog_debug(" aggregate %pFX: installed", p); } else { uninstall_aggregate_route: for (pi = orig; pi; pi = pi->next) @@ -8065,6 +8073,8 @@ static void bgp_aggregate_install( if (pi) { bgp_path_info_delete(dest, pi); bgp_process(bgp, dest, pi, afi, safi); + if (debug) + zlog_debug(" aggregate %pFX: uninstall", p); } } diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index 36426817657d..d07bb6503555 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -4149,6 +4149,11 @@ Debugging Enable or disable debugging of communications between *bgpd* and *zebra*. +.. clicmd:: debug bgp aggregate [prefix ] + + Enable or disable debugging of route aggregation, either for one or more + aggregate addresses or for all aggregate addresses. + Dumping Messages and Routing Tables ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^