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,44 +11976,41 @@ 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_SAFI_WITH_LABEL_HELP_STR
BGP_STR "Display the entries for all address families\n"
BGP_INSTANCE_HELP_STR "Display only routes with non-natural netmasks\n"
BGP_AFI_HELP_STR "Display detailed information about dampening\n"
BGP_SAFI_WITH_LABEL_HELP_STR "Display flap statistics of routes\n"
"Display the entries for all address families\n" "Display paths suppressed due to dampening\n"
"Display only routes with non-natural netmasks\n" "Display routes matching the communities\n" COMMUNITY_AANN_STR
"Display detailed information about dampening\n" "Do not send outside local AS (well-known community)\n"
"Display flap statistics of routes\n" "Do not advertise to any peer (well-known community)\n"
"Display paths suppressed due to dampening\n" "Do not export to next AS (well-known community)\n"
"Display routes matching the communities\n" "Graceful shutdown (well-known community)\n"
COMMUNITY_AANN_STR "Do not export to any peer (well-known community)\n"
"Do not send outside local AS (well-known community)\n" "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
"Do not advertise to any peer (well-known community)\n" "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
"Do not export to next AS (well-known community)\n" "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
"Graceful shutdown (well-known community)\n" "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
"Do not export to any peer (well-known community)\n" "Should accept VPN route with local nexthop (well-known community)\n"
"Inform EBGP peers to blackhole traffic to prefix (well-known community)\n" "RT VPNv6 route filtering (well-known community)\n"
"Staled Long-lived Graceful Restart VPN route (well-known community)\n" "RT VPNv4 route filtering (well-known community)\n"
"Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n" "RT translated VPNv6 route filtering (well-known community)\n"
"Should accept local VPN route if exported and imported into different VRF (well-known community)\n" "RT translated VPNv4 route filtering (well-known community)\n"
"Should accept VPN route with local nexthop (well-known community)\n" "Exact match of the communities\n"
"RT VPNv6 route filtering (well-known community)\n" "RPKI route types\n"
"RT VPNv4 route filtering (well-known community)\n" "A valid path as determined by rpki\n"
"RT translated VPNv6 route filtering (well-known community)\n" "A invalid path as determined by rpki\n"
"RT translated VPNv4 route filtering (well-known community)\n" "A path that has no rpki data\n"
"Exact match of the communities\n" "Display prefixes with matching version numbers\n"
"RPKI route types\n" "Version number and above\n"
"A valid path as determined by rpki\n" "Display prefixes with matching BGP community alias\n"
"A invalid path as determined by rpki\n" "BGP community alias\n" JSON_STR
"A path that has no rpki data\n" "Display detailed version of JSON output\n"
"Display prefixes with matching version numbers\n" "Increase table width for longer prefixes\n")
"Version number and above\n"
JSON_STR
"Display detailed version of JSON output\n"
"Increase table width for longer prefixes\n")
{ {
afi_t afi = AFI_IP6; afi_t afi = AFI_IP6;
safi_t safi = SAFI_UNICAST; safi_t safi = SAFI_UNICAST;
@ -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:]