summaryrefslogtreecommitdiff
path: root/bgpd/bgp_debug.c
diff options
context:
space:
mode:
authorDonatas Abraitis <donatas@opensourcerouting.org>2023-11-17 08:39:33 +0200
committerDonatas Abraitis <donatas@opensourcerouting.org>2023-11-22 08:06:33 +0200
commitc0215ed1881319b986bbc961177c7688c932df64 (patch)
treec4f6caff1d4659ace3cb1aaa265d039f1026d31d /bgpd/bgp_debug.c
parent1315b7a7b46271349c18cf93532ace848dd6ab9b (diff)
bgpd: Add an ability to filter UPDATEs using neighbor with prefix-list
Before this patch we didn't have an option to filter debug UPDATE messages by specifying an arbitrary prefix, prefix-list or so. We had/have only an option to specify: ``` * debug bgp updates in 10.0.0.1 * debug bgp updates prefix 10.0.1.0/24 ``` Now adding: ``` * debug bgp updates <in|out> 10.0.0.1 prefix-list plist ``` CLI output: ``` r2# show debugging MGMT debugging status: Zebra debugging status: BGP debugging status: BGP updates debugging is on (inbound) for 192.168.2.6 with prefix-list debug Staticd debugging status r2# show running-config | include prefix-list debug debug bgp updates in 192.168.2.6 prefix-list debug r2# ``` Logs: ``` BGP: [PCFFM-WMARW] 192.168.2.3(r3) rcvd UPDATE wlen 0 attrlen 28 alen 5 BGP: [PCFFM-WMARW] 192.168.2.3(r3) rcvd UPDATE wlen 0 attrlen 28 alen 4 BGP: [PCFFM-WMARW] 192.168.2.3(r3) rcvd UPDATE wlen 0 attrlen 0 alen 0 BGP: [M59KS-A3ZXZ] bgp_update_receive: rcvd End-of-RIB for IPv4 Unicast from 192.168.2.3 in vrf default BGP: [PCFFM-WMARW] 192.168.2.4(r4) rcvd UPDATE wlen 0 attrlen 28 alen 5 BGP: [PCFFM-WMARW] 192.168.2.4(r4) rcvd UPDATE wlen 0 attrlen 28 alen 4 BGP: [PCFFM-WMARW] 192.168.2.4(r4) rcvd UPDATE wlen 0 attrlen 0 alen 0 BGP: [M59KS-A3ZXZ] bgp_update_receive: rcvd End-of-RIB for IPv4 Unicast from 192.168.2.4 in vrf default BGP: [PCFFM-WMARW] 192.168.1.1(r1) rcvd UPDATE wlen 0 attrlen 29 alen 5 BGP: [PCFFM-WMARW] 192.168.2.6(r6) rcvd UPDATE wlen 0 attrlen 28 alen 5 BGP: [XXWBM-V772F] 192.168.2.6(r6) rcvd UPDATE w/ attr: nexthop 192.168.2.6, origin ?, metric 0, path 65006 BGP: [YCKEM-GB33T] 192.168.2.6(r6) rcvd 172.16.16.254/32 IPv4 unicast <<<<<<<<<<<< BGP: [PCFFM-WMARW] 192.168.2.6(r6) rcvd UPDATE wlen 0 attrlen 28 alen 4 BGP: [PCFFM-WMARW] 192.168.2.6(r6) rcvd UPDATE wlen 0 attrlen 0 alen 0 BGP: [M59KS-A3ZXZ] bgp_update_receive: rcvd End-of-RIB for IPv4 Unicast from 192.168.2.6 in vrf default BGP: [PCFFM-WMARW] 192.168.2.5(r5) rcvd UPDATE wlen 0 attrlen 28 alen 5 BGP: [PCFFM-WMARW] 192.168.2.5(r5) rcvd UPDATE wlen 0 attrlen 28 alen 4 BGP: [PCFFM-WMARW] 192.168.2.5(r5) rcvd UPDATE wlen 0 attrlen 0 alen 0 BGP: [M59KS-A3ZXZ] bgp_update_receive: rcvd End-of-RIB for IPv4 Unicast from 192.168.2.5 in vrf default BGP: [PCFFM-WMARW] 192.168.1.1(r1) rcvd UPDATE wlen 0 attrlen 29 alen 5 BGP: [PCFFM-WMARW] 192.168.7.7(r7) rcvd UPDATE wlen 0 attrlen 0 alen 0 BGP: [M59KS-A3ZXZ] bgp_update_receive: rcvd End-of-RIB for IPv4 Unicast from 192.168.7.7 in vrf default ``` Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
Diffstat (limited to 'bgpd/bgp_debug.c')
-rw-r--r--bgpd/bgp_debug.c130
1 files changed, 85 insertions, 45 deletions
diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c
index 123a1cacf3..059f921ed1 100644
--- a/bgpd/bgp_debug.c
+++ b/bgpd/bgp_debug.c
@@ -216,6 +216,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);
}
}
@@ -238,6 +239,10 @@ static void bgp_debug_list_print(struct vty *vty, const char *desc,
if (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)
@@ -261,7 +266,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 +295,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;
@@ -302,6 +312,9 @@ static void bgp_debug_list_add_entry(struct list *list, const char *host,
prefix_copy(filter->p, p);
}
+ if (plist_name)
+ filter->plist_name = XSTRDUP(MTYPE_BGP_DEBUG_STR, plist_name);
+
listnode_add(list, filter);
}
@@ -315,6 +328,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 +344,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 +371,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 +798,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 +946,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 +1035,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);
@@ -1150,9 +1171,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 +1181,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 +1203,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 +1213,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 +1222,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 +1307,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 +1316,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 +1440,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 +1536,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 +1674,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);
@@ -2510,7 +2538,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 +2551,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 = prefix_list_lookup(afi,
+ filter->plist_name);
+
+ 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 +2585,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 +2597,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 +2611,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 +2619,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;