Skip to content

Commit

Permalink
bgpd: Add an ability to filter UPDATEs using neighbor with prefix-list
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
ton31337 committed Nov 17, 2023
1 parent 64c4f2d commit c2d832a
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 45 deletions.
130 changes: 85 additions & 45 deletions bgpd/bgp_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand All @@ -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)
Expand All @@ -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++;
}
Expand All @@ -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;

Expand All @@ -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);
}

Expand All @@ -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
Expand All @@ -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)) {
Expand All @@ -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));
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -1150,17 +1171,19 @@ 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"
"Inbound updates\n"
"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;
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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) {
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
{
Expand All @@ -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;
Expand All @@ -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);
}
Expand All @@ -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);
}
Expand All @@ -2571,15 +2611,15 @@ 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;
}

/* 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;
Expand Down
1 change: 1 addition & 0 deletions bgpd/bgp_debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ extern struct list *bgp_debug_zebra_prefixes;

struct bgp_debug_filter {
char *host;
char *plist_name;
struct prefix *p;
};

Expand Down

0 comments on commit c2d832a

Please sign in to comment.