Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bgpd: Add an ability to filter UPDATEs using neighbor with prefix-list #14819

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 96 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 @@ -295,13 +305,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);
}

Expand All @@ -315,6 +339,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 +355,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 +382,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 +809,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 +957,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 +1046,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 +1182,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 +1214,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 +1224,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 +1233,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 +1318,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 +1327,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 +1451,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 +1547,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 +1685,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 +2549,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 +2562,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;
Expand All @@ -2545,7 +2596,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 +2608,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 +2622,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
3 changes: 3 additions & 0 deletions bgpd/bgp_debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ extern struct list *bgp_debug_zebra_prefixes;

struct bgp_debug_filter {
char *host;
char *plist_name;
struct prefix_list *plist_v4;
struct prefix_list *plist_v6;
struct prefix *p;
};

Expand Down
Loading
Loading