diff options
Diffstat (limited to 'bgpd/bgp_debug.c')
-rw-r--r-- | bgpd/bgp_debug.c | 188 |
1 files changed, 141 insertions, 47 deletions
diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c index 123a1ca..3ecdc0d 100644 --- a/bgpd/bgp_debug.c +++ b/bgpd/bgp_debug.c @@ -16,6 +16,7 @@ #include "memory.h" #include "queue.h" #include "filter.h" +#include "hook.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_aspath.h" @@ -37,6 +38,9 @@ #include "bgpd/bgp_debug_clippy.c" +DEFINE_HOOK(bgp_hook_config_write_debug, (struct vty *vty, bool running), + (vty, running)); + unsigned long conf_bgp_debug_as4; unsigned long conf_bgp_debug_neighbor_events; unsigned long conf_bgp_debug_events; @@ -216,6 +220,7 @@ static void bgp_debug_list_free(struct list *list) listnode_delete(list, filter); prefix_free(&filter->p); XFREE(MTYPE_BGP_DEBUG_STR, filter->host); + XFREE(MTYPE_BGP_DEBUG_STR, filter->plist_name); XFREE(MTYPE_BGP_DEBUG_FILTER, filter); } } @@ -233,15 +238,21 @@ static void bgp_debug_list_print(struct vty *vty, const char *desc, vty_out(vty, "%s", desc); if (list && !list_isempty(list)) { - vty_out(vty, " for"); + vty_out(vty, " for:\n"); for (ALL_LIST_ELEMENTS(list, node, nnode, filter)) { if (filter->host) - vty_out(vty, " %s", filter->host); + vty_out(vty, " %s", filter->host); + + if (filter->plist_name) + vty_out(vty, " with prefix-list %s", + filter->plist_name); if (filter->p && filter->p->family == AF_EVPN) bgp_debug_print_evpn_prefix(vty, "", filter->p); else if (filter->p) vty_out(vty, " %pFX", filter->p); + + vty_out(vty, "\n"); } } @@ -261,7 +272,11 @@ static int bgp_debug_list_conf_print(struct vty *vty, const char *desc, if (list && !list_isempty(list)) { for (ALL_LIST_ELEMENTS(list, node, nnode, filter)) { - if (filter->host) { + if (filter->host && filter->plist_name) { + vty_out(vty, "%s %s prefix-list %s\n", desc, + filter->host, filter->plist_name); + write++; + } else if (filter->host) { vty_out(vty, "%s %s\n", desc, filter->host); write++; } @@ -286,7 +301,8 @@ static int bgp_debug_list_conf_print(struct vty *vty, const char *desc, } static void bgp_debug_list_add_entry(struct list *list, const char *host, - const struct prefix *p) + const struct prefix *p, + const char *plist_name) { struct bgp_debug_filter *filter; @@ -295,13 +311,27 @@ static void bgp_debug_list_add_entry(struct list *list, const char *host, if (host) { filter->host = XSTRDUP(MTYPE_BGP_DEBUG_STR, host); + filter->plist_name = NULL; + filter->plist_v4 = NULL; + filter->plist_v6 = NULL; filter->p = NULL; } else if (p) { filter->host = NULL; + filter->plist_name = NULL; + filter->plist_v4 = NULL; + filter->plist_v6 = NULL; filter->p = prefix_new(); prefix_copy(filter->p, p); } + if (plist_name) { + filter->plist_name = XSTRDUP(MTYPE_BGP_DEBUG_STR, plist_name); + filter->plist_v4 = prefix_list_lookup(AFI_IP, + filter->plist_name); + filter->plist_v6 = prefix_list_lookup(AFI_IP6, + filter->plist_name); + } + listnode_add(list, filter); } @@ -315,6 +345,7 @@ static bool bgp_debug_list_remove_entry(struct list *list, const char *host, if (host && strcmp(filter->host, host) == 0) { listnode_delete(list, filter); XFREE(MTYPE_BGP_DEBUG_STR, filter->host); + XFREE(MTYPE_BGP_DEBUG_STR, filter->plist_name); XFREE(MTYPE_BGP_DEBUG_FILTER, filter); return true; } else if (p && filter->p->prefixlen == p->prefixlen @@ -330,16 +361,20 @@ static bool bgp_debug_list_remove_entry(struct list *list, const char *host, } static bool bgp_debug_list_has_entry(struct list *list, const char *host, - const struct prefix *p) + const struct prefix *p, + const char *plist_name) { struct bgp_debug_filter *filter; struct listnode *node, *nnode; for (ALL_LIST_ELEMENTS(list, node, nnode, filter)) { - if (host) { - if (strcmp(filter->host, host) == 0) { + if (host && plist_name) { + if (strmatch(filter->host, host) && filter->plist_name && + strmatch(filter->plist_name, plist_name)) + return true; + } else if (host) { + if (strmatch(filter->host, host)) return true; - } } else if (p) { if (filter->p->prefixlen == p->prefixlen && prefix_match(filter->p, p)) { @@ -353,7 +388,7 @@ static bool bgp_debug_list_has_entry(struct list *list, const char *host, bool bgp_debug_peer_updout_enabled(char *host) { - return (bgp_debug_list_has_entry(bgp_debug_update_out_peers, host, + return (bgp_debug_list_has_entry(bgp_debug_update_out_peers, host, NULL, NULL)); } @@ -780,14 +815,15 @@ DEFUN (debug_bgp_neighbor_events_peer, bgp_debug_neighbor_events_peers = list_new(); if (bgp_debug_list_has_entry(bgp_debug_neighbor_events_peers, host, - NULL)) { + NULL, NULL)) { vty_out(vty, "BGP neighbor-events debugging is already enabled for %s\n", host); return CMD_SUCCESS; } - bgp_debug_list_add_entry(bgp_debug_neighbor_events_peers, host, NULL); + bgp_debug_list_add_entry(bgp_debug_neighbor_events_peers, host, NULL, + NULL); if (vty->node == CONFIG_NODE) DEBUG_ON(neighbor_events, NEIGHBOR_EVENTS); @@ -927,14 +963,15 @@ DEFUN (debug_bgp_keepalive_peer, if (!bgp_debug_keepalive_peers) bgp_debug_keepalive_peers = list_new(); - if (bgp_debug_list_has_entry(bgp_debug_keepalive_peers, host, NULL)) { + if (bgp_debug_list_has_entry(bgp_debug_keepalive_peers, host, NULL, + NULL)) { vty_out(vty, "BGP keepalive debugging is already enabled for %s\n", host); return CMD_SUCCESS; } - bgp_debug_list_add_entry(bgp_debug_keepalive_peers, host, NULL); + bgp_debug_list_add_entry(bgp_debug_keepalive_peers, host, NULL, NULL); if (vty->node == CONFIG_NODE) DEBUG_ON(keepalive, KEEPALIVE); @@ -1015,15 +1052,16 @@ DEFPY (debug_bgp_bestpath_prefix, if (!bgp_debug_bestpath_prefixes) bgp_debug_bestpath_prefixes = list_new(); - if (bgp_debug_list_has_entry(bgp_debug_bestpath_prefixes, NULL, - prefix)) { + if (bgp_debug_list_has_entry(bgp_debug_bestpath_prefixes, NULL, prefix, + NULL)) { vty_out(vty, "BGP bestpath debugging is already enabled for %s\n", prefix_str); return CMD_SUCCESS; } - bgp_debug_list_add_entry(bgp_debug_bestpath_prefixes, NULL, prefix); + bgp_debug_list_add_entry(bgp_debug_bestpath_prefixes, NULL, prefix, + NULL); if (vty->node == CONFIG_NODE) { DEBUG_ON(bestpath, BESTPATH); @@ -1116,6 +1154,31 @@ DEFUN (debug_bgp_update, return CMD_SUCCESS; } +DEFPY (debug_bgp_update_detail, + debug_bgp_update_detail_cmd, + "[no] debug bgp updates detail", + NO_STR + DEBUG_STR + BGP_STR + "BGP updates\n" + "Show detailed information about updates\n") +{ + if (vty->node == CONFIG_NODE) { + if (no) + DEBUG_OFF(update, UPDATE_DETAIL); + else + DEBUG_ON(update, UPDATE_DETAIL); + } else { + if (no) + TERM_DEBUG_OFF(update, UPDATE_DETAIL); + else + TERM_DEBUG_ON(update, UPDATE_DETAIL); + vty_out(vty, "BGP updates detail debugging is on\n"); + } + + return CMD_SUCCESS; +} + DEFUN (debug_bgp_update_direct, debug_bgp_update_direct_cmd, "debug bgp updates <in|out>", @@ -1150,9 +1213,9 @@ DEFUN (debug_bgp_update_direct, return CMD_SUCCESS; } -DEFUN (debug_bgp_update_direct_peer, +DEFPY (debug_bgp_update_direct_peer, debug_bgp_update_direct_peer_cmd, - "debug bgp updates <in|out> <A.B.C.D|X:X::X:X|WORD>", + "debug bgp updates <in|out> <A.B.C.D|X:X::X:X|WORD> [prefix-list PREFIXLIST_NAME$plist]", DEBUG_STR BGP_STR "BGP updates\n" @@ -1160,7 +1223,9 @@ DEFUN (debug_bgp_update_direct_peer, "Outbound updates\n" "BGP neighbor IP address to debug\n" "BGP IPv6 neighbor to debug\n" - "BGP neighbor on interface to debug\n") + "BGP neighbor on interface to debug\n" + "Use prefix-list to filter prefixes to debug\n" + "Name of prefix-list\n") { int idx_in_out = 3; int idx_peer = 4; @@ -1180,7 +1245,7 @@ DEFUN (debug_bgp_update_direct_peer, if (inbound) { if (bgp_debug_list_has_entry(bgp_debug_update_in_peers, host, - NULL)) { + NULL, plist)) { vty_out(vty, "BGP inbound update debugging is already enabled for %s\n", host); @@ -1190,7 +1255,7 @@ DEFUN (debug_bgp_update_direct_peer, else { if (bgp_debug_list_has_entry(bgp_debug_update_out_peers, host, - NULL)) { + NULL, plist)) { vty_out(vty, "BGP outbound update debugging is already enabled for %s\n", host); @@ -1199,14 +1264,15 @@ DEFUN (debug_bgp_update_direct_peer, } if (inbound) - bgp_debug_list_add_entry(bgp_debug_update_in_peers, host, NULL); + bgp_debug_list_add_entry(bgp_debug_update_in_peers, host, NULL, + plist); else { struct peer *peer; struct peer_af *paf; int afidx; - bgp_debug_list_add_entry(bgp_debug_update_out_peers, host, - NULL); + bgp_debug_list_add_entry(bgp_debug_update_out_peers, host, NULL, + plist); peer = bgp_find_peer(vty, host); if (peer) { @@ -1283,7 +1349,7 @@ DEFUN (no_debug_bgp_update_direct, DEFUN (no_debug_bgp_update_direct_peer, no_debug_bgp_update_direct_peer_cmd, - "no debug bgp updates <in|out> <A.B.C.D|X:X::X:X|WORD>", + "no debug bgp updates <in|out> <A.B.C.D|X:X::X:X|WORD> [prefix-list PREFIXLIST_NAME]", NO_STR DEBUG_STR BGP_STR @@ -1292,7 +1358,9 @@ DEFUN (no_debug_bgp_update_direct_peer, "Outbound updates\n" "BGP neighbor IP address to debug\n" "BGP IPv6 neighbor to debug\n" - "BGP neighbor on interface to debug\n") + "BGP neighbor on interface to debug\n" + "Use prefix-list to filter prefixes to debug\n" + "Name of prefix-list\n") { int idx_in_out = 4; int idx_peer = 5; @@ -1414,15 +1482,15 @@ DEFPY (debug_bgp_update_prefix_afi_safi, if (!bgp_debug_update_prefixes) bgp_debug_update_prefixes = list_new(); - if (bgp_debug_list_has_entry(bgp_debug_update_prefixes, NULL, - &argv_p)) { + if (bgp_debug_list_has_entry(bgp_debug_update_prefixes, NULL, &argv_p, + NULL)) { vty_out(vty, "BGP updates debugging is already enabled for %pFX\n", &argv_p); return CMD_SUCCESS; } - bgp_debug_list_add_entry(bgp_debug_update_prefixes, NULL, &argv_p); + bgp_debug_list_add_entry(bgp_debug_update_prefixes, NULL, &argv_p, NULL); if (vty->node == CONFIG_NODE) { DEBUG_ON(update, UPDATE_PREFIX); @@ -1510,14 +1578,15 @@ DEFPY (debug_bgp_update_prefix, if (!bgp_debug_update_prefixes) bgp_debug_update_prefixes = list_new(); - if (bgp_debug_list_has_entry(bgp_debug_update_prefixes, NULL, prefix)) { + if (bgp_debug_list_has_entry(bgp_debug_update_prefixes, NULL, prefix, + NULL)) { vty_out(vty, "BGP updates debugging is already enabled for %s\n", prefix_str); return CMD_SUCCESS; } - bgp_debug_list_add_entry(bgp_debug_update_prefixes, NULL, prefix); + bgp_debug_list_add_entry(bgp_debug_update_prefixes, NULL, prefix, NULL); if (vty->node == CONFIG_NODE) { DEBUG_ON(update, UPDATE_PREFIX); @@ -1647,13 +1716,14 @@ DEFPY (debug_bgp_zebra_prefix, if (!bgp_debug_zebra_prefixes) bgp_debug_zebra_prefixes = list_new(); - if (bgp_debug_list_has_entry(bgp_debug_zebra_prefixes, NULL, prefix)) { + if (bgp_debug_list_has_entry(bgp_debug_zebra_prefixes, NULL, prefix, + NULL)) { vty_out(vty, "BGP zebra debugging is already enabled for %s\n", prefix_str); return CMD_SUCCESS; } - bgp_debug_list_add_entry(bgp_debug_zebra_prefixes, NULL, prefix); + bgp_debug_list_add_entry(bgp_debug_zebra_prefixes, NULL, prefix, NULL); if (vty->node == CONFIG_NODE) DEBUG_ON(zebra, ZEBRA); @@ -2206,6 +2276,8 @@ DEFUN_NOSH (show_debugging_bgp, cmd_show_lib_debugs(vty); + hook_call(bgp_hook_config_write_debug, vty, false); + return CMD_SUCCESS; } @@ -2265,6 +2337,11 @@ static int bgp_config_write_debug(struct vty *vty) bgp_debug_update_out_peers); } + if (CONF_BGP_DEBUG(update, UPDATE_DETAIL)) { + vty_out(vty, "debug bgp updates detail\n"); + write++; + } + if (CONF_BGP_DEBUG(zebra, ZEBRA)) { if (!bgp_debug_zebra_prefixes || list_isempty(bgp_debug_zebra_prefixes)) { @@ -2340,6 +2417,9 @@ static int bgp_config_write_debug(struct vty *vty) write++; } + if (hook_call(bgp_hook_config_write_debug, vty, true)) + write++; + return write; } @@ -2370,6 +2450,8 @@ void bgp_debug_init(void) install_element(CONFIG_NODE, &debug_bgp_keepalive_cmd); install_element(ENABLE_NODE, &debug_bgp_update_cmd); install_element(CONFIG_NODE, &debug_bgp_update_cmd); + install_element(ENABLE_NODE, &debug_bgp_update_detail_cmd); + install_element(CONFIG_NODE, &debug_bgp_update_detail_cmd); install_element(ENABLE_NODE, &debug_bgp_zebra_cmd); install_element(CONFIG_NODE, &debug_bgp_zebra_cmd); install_element(ENABLE_NODE, &debug_bgp_update_groups_cmd); @@ -2510,7 +2592,8 @@ static int bgp_debug_per_prefix(const struct prefix *p, /* Return true if this peer is on the per_peer_list of peers to debug * for BGP_DEBUG_TYPE */ -static bool bgp_debug_per_peer(char *host, unsigned long term_bgp_debug_type, +static bool bgp_debug_per_peer(char *host, const struct prefix *p, + unsigned long term_bgp_debug_type, unsigned int BGP_DEBUG_TYPE, struct list *per_peer_list) { @@ -2522,17 +2605,28 @@ static bool bgp_debug_per_peer(char *host, unsigned long term_bgp_debug_type, if (!per_peer_list || list_isempty(per_peer_list)) return true; - else { - if (!host) - return false; + if (!host) + return false; - for (ALL_LIST_ELEMENTS(per_peer_list, node, nnode, - filter)) - if (strcmp(filter->host, host) == 0) - return true; + for (ALL_LIST_ELEMENTS(per_peer_list, node, nnode, filter)) + if (strmatch(filter->host, host) && + filter->plist_name && p) { + struct prefix_list *plist; + afi_t afi = family2afi(p->family); - return false; - } + plist = (afi == AFI_IP) ? filter->plist_v4 + : filter->plist_v6; + + if (!plist) + continue; + + return prefix_list_apply(plist, p) == + PREFIX_PERMIT; + } else if (strmatch(filter->host, host)) { + return true; + } + + return false; } return false; @@ -2545,7 +2639,7 @@ bool bgp_debug_neighbor_events(const struct peer *peer) if (peer) host = peer->host; - return bgp_debug_per_peer(host, term_bgp_debug_neighbor_events, + return bgp_debug_per_peer(host, NULL, term_bgp_debug_neighbor_events, BGP_DEBUG_NEIGHBOR_EVENTS, bgp_debug_neighbor_events_peers); } @@ -2557,7 +2651,7 @@ bool bgp_debug_keepalive(const struct peer *peer) if (peer) host = peer->host; - return bgp_debug_per_peer(host, term_bgp_debug_keepalive, + return bgp_debug_per_peer(host, NULL, term_bgp_debug_keepalive, BGP_DEBUG_KEEPALIVE, bgp_debug_keepalive_peers); } @@ -2571,7 +2665,7 @@ bool bgp_debug_update(const struct peer *peer, const struct prefix *p, host = peer->host; if (inbound) { - if (bgp_debug_per_peer(host, term_bgp_debug_update, + if (bgp_debug_per_peer(host, p, term_bgp_debug_update, BGP_DEBUG_UPDATE_IN, bgp_debug_update_in_peers)) return true; @@ -2579,7 +2673,7 @@ bool bgp_debug_update(const struct peer *peer, const struct prefix *p, /* outbound */ else { - if (bgp_debug_per_peer(host, term_bgp_debug_update, + if (bgp_debug_per_peer(host, p, term_bgp_debug_update, BGP_DEBUG_UPDATE_OUT, bgp_debug_update_out_peers)) return true; |