Merge pull request #8701 from ton31337/feature/show_ip_bgp_alias

bgpd: Show BGP prefixes by community alias
This commit is contained in:
Donald Sharp 2021-05-21 07:23:10 -04:00 committed by GitHub
commit 2db528e384
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 148 additions and 54 deletions

View File

@ -451,9 +451,11 @@ static void set_community_string(struct community *com, bool make_json)
val = comval & 0xFFFF; val = comval & 0xFFFF;
char buf[32]; char buf[32];
snprintf(buf, sizeof(buf), "%u:%d", as, val); snprintf(buf, sizeof(buf), "%u:%d", as, val);
strlcat(str, bgp_community2alias(buf), len); const char *com2alias = bgp_community2alias(buf);
strlcat(str, com2alias, len);
if (make_json) { if (make_json) {
json_string = json_object_new_string(buf); json_string = json_object_new_string(com2alias);
json_object_array_add(json_community_list, json_object_array_add(json_community_list,
json_string); json_string);
} }

View File

@ -232,11 +232,13 @@ static void set_lcommunity_string(struct lcommunity *lcom, bool make_json)
snprintf(lcsb, sizeof(lcsb), "%u:%u:%u", global, local1, snprintf(lcsb, sizeof(lcsb), "%u:%u:%u", global, local1,
local2); local2);
len = strlcat(str_buf, bgp_community2alias(lcsb), str_buf_sz); const char *com2alias = bgp_community2alias(lcsb);
len = strlcat(str_buf, com2alias, str_buf_sz);
assert((unsigned int)len < str_buf_sz); assert((unsigned int)len < str_buf_sz);
if (make_json) { if (make_json) {
json_string = json_object_new_string(lcsb); json_string = json_object_new_string(com2alias);
json_object_array_add(json_lcommunity_list, json_object_array_add(json_lcommunity_list,
json_string); json_string);
} }

View File

@ -23,6 +23,7 @@
#include <math.h> #include <math.h>
#include "printfrr.h" #include "printfrr.h"
#include "frrstr.h"
#include "prefix.h" #include "prefix.h"
#include "linklist.h" #include "linklist.h"
#include "memory.h" #include "memory.h"
@ -10570,7 +10571,6 @@ static int bgp_show_community(struct vty *vty, struct bgp *bgp,
const char *comstr, int exact, afi_t afi, const char *comstr, int exact, afi_t afi,
safi_t safi, uint8_t show_flags); safi_t safi, uint8_t show_flags);
static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
struct bgp_table *table, enum bgp_show_type type, struct bgp_table *table, enum bgp_show_type type,
void *output_arg, char *rd, int is_last, void *output_arg, char *rd, int is_last,
@ -10647,6 +10647,48 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
continue; continue;
} }
if (type == bgp_show_type_community_alias) {
char *alias = output_arg;
char **communities;
int num;
bool found = false;
if (pi->attr->community) {
frrstr_split(pi->attr->community->str,
" ", &communities, &num);
for (int i = 0; i < num; i++) {
const char *com2alias =
bgp_community2alias(
communities[i]);
if (strncmp(alias, com2alias,
strlen(com2alias))
== 0) {
found = true;
break;
}
}
}
if (!found && pi->attr->lcommunity) {
frrstr_split(pi->attr->lcommunity->str,
" ", &communities, &num);
for (int i = 0; i < num; i++) {
const char *com2alias =
bgp_community2alias(
communities[i]);
if (strncmp(alias, com2alias,
strlen(com2alias))
== 0) {
found = true;
break;
}
}
}
if (!found)
continue;
}
if (type == bgp_show_type_rpki) { if (type == bgp_show_type_rpki) {
if (dest_p->family == AF_INET if (dest_p->family == AF_INET
|| dest_p->family == AF_INET6) || dest_p->family == AF_INET6)
@ -11920,9 +11962,10 @@ DEFPY(show_ip_bgp, show_ip_bgp_cmd,
} }
/* BGP route print out function with JSON */ /* BGP route print out function with JSON */
DEFPY (show_ip_bgp_json, DEFPY(show_ip_bgp_json, show_ip_bgp_json_cmd,
show_ip_bgp_json_cmd, "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
"show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]\ " [" BGP_SAFI_WITH_LABEL_CMD_STR
"]]\
[all$all]\ [all$all]\
[cidr-only\ [cidr-only\
|dampening <flap-statistics|dampened-paths>\ |dampening <flap-statistics|dampened-paths>\
@ -11933,20 +11976,16 @@ DEFPY (show_ip_bgp_json,
|route-filter-translated-v4] [exact-match]\ |route-filter-translated-v4] [exact-match]\
|rpki <invalid|valid|notfound>\ |rpki <invalid|valid|notfound>\
|version (1-4294967295)\ |version (1-4294967295)\
|alias WORD\
] [json$uj [detail$detail] | wide$wide]", ] [json$uj [detail$detail] | wide$wide]",
SHOW_STR SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
IP_STR
BGP_STR
BGP_INSTANCE_HELP_STR
BGP_AFI_HELP_STR
BGP_SAFI_WITH_LABEL_HELP_STR BGP_SAFI_WITH_LABEL_HELP_STR
"Display the entries for all address families\n" "Display the entries for all address families\n"
"Display only routes with non-natural netmasks\n" "Display only routes with non-natural netmasks\n"
"Display detailed information about dampening\n" "Display detailed information about dampening\n"
"Display flap statistics of routes\n" "Display flap statistics of routes\n"
"Display paths suppressed due to dampening\n" "Display paths suppressed due to dampening\n"
"Display routes matching the communities\n" "Display routes matching the communities\n" COMMUNITY_AANN_STR
COMMUNITY_AANN_STR
"Do not send outside local AS (well-known community)\n" "Do not send outside local AS (well-known community)\n"
"Do not advertise to any peer (well-known community)\n" "Do not advertise to any peer (well-known community)\n"
"Do not export to next AS (well-known community)\n" "Do not export to next AS (well-known community)\n"
@ -11968,7 +12007,8 @@ DEFPY (show_ip_bgp_json,
"A path that has no rpki data\n" "A path that has no rpki data\n"
"Display prefixes with matching version numbers\n" "Display prefixes with matching version numbers\n"
"Version number and above\n" "Version number and above\n"
JSON_STR "Display prefixes with matching BGP community alias\n"
"BGP community alias\n" JSON_STR
"Display detailed version of JSON output\n" "Display detailed version of JSON output\n"
"Increase table width for longer prefixes\n") "Increase table width for longer prefixes\n")
{ {
@ -11980,6 +12020,7 @@ DEFPY (show_ip_bgp_json,
int exact_match = 0; int exact_match = 0;
char *community = NULL; char *community = NULL;
char *prefix_version = NULL; char *prefix_version = NULL;
char *bgp_community_alias = NULL;
bool first = true; bool first = true;
uint8_t show_flags = 0; uint8_t show_flags = 0;
enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED; enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
@ -12056,6 +12097,12 @@ DEFPY (show_ip_bgp_json,
prefix_version = argv[idx + 1]->arg; prefix_version = argv[idx + 1]->arg;
} }
/* Display prefixes with matching BGP community alias */
if (argv_find(argv, argc, "alias", &idx)) {
sh_type = bgp_show_type_community_alias;
bgp_community_alias = argv[idx + 1]->arg;
}
if (!all) { if (!all) {
/* show bgp: AFI_IP6, show ip bgp: AFI_IP */ /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
if (community) if (community)
@ -12066,6 +12113,10 @@ DEFPY (show_ip_bgp_json,
return bgp_show(vty, bgp, afi, safi, sh_type, return bgp_show(vty, bgp, afi, safi, sh_type,
prefix_version, show_flags, prefix_version, show_flags,
rpki_target_state); rpki_target_state);
else if (bgp_community_alias)
return bgp_show(vty, bgp, afi, safi, sh_type,
bgp_community_alias, show_flags,
rpki_target_state);
else else
return bgp_show(vty, bgp, afi, safi, sh_type, NULL, return bgp_show(vty, bgp, afi, safi, sh_type, NULL,
show_flags, rpki_target_state); show_flags, rpki_target_state);
@ -12108,6 +12159,11 @@ DEFPY (show_ip_bgp_json,
sh_type, prefix_version, sh_type, prefix_version,
show_flags, show_flags,
rpki_target_state); rpki_target_state);
else if (bgp_community_alias)
return bgp_show(
vty, bgp, afi, safi, sh_type,
bgp_community_alias, show_flags,
rpki_target_state);
else else
bgp_show(vty, bgp, afi, safi, sh_type, bgp_show(vty, bgp, afi, safi, sh_type,
NULL, show_flags, NULL, show_flags,

View File

@ -42,6 +42,7 @@ enum bgp_show_type {
bgp_show_type_neighbor, bgp_show_type_neighbor,
bgp_show_type_cidr_only, bgp_show_type_cidr_only,
bgp_show_type_prefix_longer, bgp_show_type_prefix_longer,
bgp_show_type_community_alias,
bgp_show_type_community_all, bgp_show_type_community_all,
bgp_show_type_community, bgp_show_type_community,
bgp_show_type_community_exact, bgp_show_type_community_exact,

View File

@ -2111,6 +2111,10 @@ things on the wire.
Large Community: lcommunity-1 65001:123:2 Large Community: lcommunity-1 65001:123:2
Last update: Fri Apr 16 12:51:27 2021 Last update: Fri Apr 16 12:51:27 2021
.. clicmd:: show bgp [afi] [safi] [all] alias WORD [wide|json]
Display prefixes with matching BGP community alias.
.. _bgp-using-communities-in-route-map: .. _bgp-using-communities-in-route-map:
Using Communities in Route Maps Using Communities in Route Maps

View File

@ -1,7 +1,7 @@
! !
bgp community alias 65002:1 community-r2-1 bgp community alias 65001:1 community-r2-1
bgp community alias 65002:2 community-r2-2 bgp community alias 65002:2 community-r2-2
bgp community alias 65002:1:1 large-community-r2-1 bgp community alias 65001:1:1 large-community-r2-1
! !
router bgp 65001 router bgp 65001
no bgp ebgp-requires-policy no bgp ebgp-requires-policy

View File

@ -6,7 +6,14 @@ router bgp 65002
neighbor 192.168.1.1 route-map r1 out neighbor 192.168.1.1 route-map r1 out
exit-address-family exit-address-family
! !
route-map r1 permit 10 ip prefix-list p1 permit 172.16.16.1/32
set community 65002:1 65002:2 ip prefix-list p2 permit 172.16.16.2/32
set large-community 65002:1:1 65002:2:1 !
route-map r1 permit 10
match ip address prefix-list p1
set community 65001:1 65001:2
set large-community 65001:1:1 65001:1:2
route-map r1 permit 20
match ip address prefix-list p2
set community 65002:1 65002:2
! !

View File

@ -1,4 +1,8 @@
! !
int lo
ip address 172.16.16.1/32
ip address 172.16.16.2/32
!
int r2-eth0 int r2-eth0
ip address 192.168.1.2/24 ip address 192.168.1.2/24
! !

View File

@ -84,12 +84,14 @@ def test_bgp_community_alias():
router = tgen.gears["r1"] router = tgen.gears["r1"]
def _bgp_converge(router): def _bgp_converge(router):
output = json.loads(router.vtysh_cmd("show ip bgp 192.168.1.0/24 json")) output = json.loads(
router.vtysh_cmd("show bgp ipv4 unicast 172.16.16.1/32 json")
)
expected = { expected = {
"paths": [ "paths": [
{ {
"community": {"string": "community-r2-1 community-r2-2"}, "community": {"string": "community-r2-1 65001:2"},
"largeCommunity": {"string": "large-community-r2-1 65002:2:1"}, "largeCommunity": {"string": "large-community-r2-1 65001:1:2"},
} }
] ]
} }
@ -97,9 +99,25 @@ def test_bgp_community_alias():
test_func = functools.partial(_bgp_converge, router) test_func = functools.partial(_bgp_converge, router)
success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert result is None, 'Cannot see BGP community aliases "{}"'.format(router) assert result is None, 'Cannot see BGP community aliases "{}"'.format(router)
def _bgp_show_prefixes_by_alias(router):
output = json.loads(
router.vtysh_cmd("show bgp ipv4 unicast alias community-r2-2 json detail")
)
expected = {
"routes": {
"172.16.16.2/32": [{"community": {"string": "65002:1 community-r2-2"}}]
}
}
return topotest.json_cmp(output, expected)
test_func = functools.partial(_bgp_show_prefixes_by_alias, router)
success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
assert result is None, 'Cannot see BGP prefixes by community alias "{}"'.format(
router
)
if __name__ == "__main__": if __name__ == "__main__":
args = ["-s"] + sys.argv[1:] args = ["-s"] + sys.argv[1:]