summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDonatas Abraitis <donatas.abraitis@gmail.com>2021-04-02 10:08:58 +0200
committerGitHub <noreply@github.com>2021-04-02 10:08:58 +0200
commit61778eb80b48e29c6de44fab4ba767172a94a4e5 (patch)
tree0f00d91df15ad07e3f738d3bdc5392e7eb1e3858
parentMerge pull request #8375 from mjstapp/fix_ignore_pcep_test_files (diff)
parentbgpd: fix old vpn command compilation failures (diff)
downloadfrr-61778eb80b48e29c6de44fab4ba767172a94a4e5.tar.xz
frr-61778eb80b48e29c6de44fab4ba767172a94a4e5.zip
Merge pull request #8382 from taspelund/add_rd_all_v2
Add support for 'rd all' in EVPN and L3VPN commands
-rw-r--r--bgpd/bgp_evpn_vty.c310
-rw-r--r--bgpd/bgp_mplsvpn.c81
-rw-r--r--bgpd/bgp_route.c12
-rw-r--r--bgpd/bgp_routemap.c3
-rw-r--r--doc/user/bgp.rst37
5 files changed, 348 insertions, 95 deletions
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index 5a0258f3b..381e6f082 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -1397,33 +1397,43 @@ DEFUN(show_ip_bgp_l2vpn_evpn,
"show [ip] bgp l2vpn evpn [json]",
SHOW_STR IP_STR BGP_STR L2VPN_HELP_STR EVPN_HELP_STR JSON_STR)
{
- return bgp_show_ethernet_vpn(vty, NULL, bgp_show_type_normal, NULL, 0,
+ return bgp_show_ethernet_vpn(vty, NULL, bgp_show_type_normal, NULL,
+ SHOW_DISPLAY_STANDARD,
use_json(argc, argv));
}
DEFUN(show_ip_bgp_l2vpn_evpn_rd,
show_ip_bgp_l2vpn_evpn_rd_cmd,
- "show [ip] bgp l2vpn evpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
+ "show [ip] bgp l2vpn evpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> [json]",
SHOW_STR
IP_STR
BGP_STR
L2VPN_HELP_STR
EVPN_HELP_STR
"Display information for a route distinguisher\n"
- "VPN Route Distinguisher\n" JSON_STR)
+ "VPN Route Distinguisher\n"
+ "All VPN Route Distinguishers\n"
+ JSON_STR)
{
int idx_ext_community = 0;
int ret;
struct prefix_rd prd;
+ int rd_all = 0;
- argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community);
+ argv_find(argv, argc, "all", &rd_all);
+ if (rd_all)
+ return bgp_show_ethernet_vpn(vty, NULL, bgp_show_type_normal,
+ NULL, SHOW_DISPLAY_STANDARD,
+ use_json(argc, argv));
+ argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community);
ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
if (!ret) {
vty_out(vty, "%% Malformed Route Distinguisher\n");
return CMD_WARNING;
}
- return bgp_show_ethernet_vpn(vty, &prd, bgp_show_type_normal, NULL, 0,
+ return bgp_show_ethernet_vpn(vty, &prd, bgp_show_type_normal, NULL,
+ SHOW_DISPLAY_STANDARD,
use_json(argc, argv));
}
@@ -1438,34 +1448,41 @@ DEFUN(show_ip_bgp_l2vpn_evpn_all_tags,
"Display information about all EVPN NLRIs\n"
"Display BGP tags for prefixes\n")
{
- return bgp_show_ethernet_vpn(vty, NULL, bgp_show_type_normal, NULL, 1,
- 0);
+ return bgp_show_ethernet_vpn(vty, NULL, bgp_show_type_normal, NULL,
+ SHOW_DISPLAY_TAGS, 0);
}
DEFUN(show_ip_bgp_l2vpn_evpn_rd_tags,
show_ip_bgp_l2vpn_evpn_rd_tags_cmd,
- "show [ip] bgp l2vpn evpn rd ASN:NN_OR_IP-ADDRESS:NN tags",
+ "show [ip] bgp l2vpn evpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> tags",
SHOW_STR
IP_STR
BGP_STR
L2VPN_HELP_STR
EVPN_HELP_STR
"Display information for a route distinguisher\n"
- "VPN Route Distinguisher\n" "Display BGP tags for prefixes\n")
+ "VPN Route Distinguisher\n"
+ "All VPN Route Distinguishers\n"
+ "Display BGP tags for prefixes\n")
{
int idx_ext_community = 0;
int ret;
struct prefix_rd prd;
+ int rd_all = 0;
- argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community);
+ argv_find(argv, argc, "all", &rd_all);
+ if (rd_all)
+ return bgp_show_ethernet_vpn(vty, NULL, bgp_show_type_normal,
+ NULL, SHOW_DISPLAY_TAGS, 0);
+ argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community);
ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
if (!ret) {
vty_out(vty, "%% Malformed Route Distinguisher\n");
return CMD_WARNING;
}
- return bgp_show_ethernet_vpn(vty, &prd, bgp_show_type_normal, NULL, 1,
- 0);
+ return bgp_show_ethernet_vpn(vty, &prd, bgp_show_type_normal, NULL,
+ SHOW_DISPLAY_TAGS, 0);
}
DEFUN(show_ip_bgp_l2vpn_evpn_neighbor_routes,
@@ -1531,13 +1548,13 @@ DEFUN(show_ip_bgp_l2vpn_evpn_neighbor_routes,
return CMD_WARNING;
}
- return bgp_show_ethernet_vpn(vty, NULL, bgp_show_type_neighbor, peer, 0,
- uj);
+ return bgp_show_ethernet_vpn(vty, NULL, bgp_show_type_neighbor, peer,
+ SHOW_DISPLAY_STANDARD, uj);
}
DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_routes,
show_ip_bgp_l2vpn_evpn_rd_neighbor_routes_cmd,
- "show [ip] bgp l2vpn evpn rd ASN:NN_OR_IP-ADDRESS:NN neighbors <A.B.C.D|X:X::X:X|WORD> routes [json]",
+ "show [ip] bgp l2vpn evpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors <A.B.C.D|X:X::X:X|WORD> routes [json]",
SHOW_STR
IP_STR
BGP_STR
@@ -1545,6 +1562,7 @@ DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_routes,
EVPN_HELP_STR
"Display information for a route distinguisher\n"
"VPN Route Distinguisher\n"
+ "All VPN Route Distinguishers\n"
"Detailed information on TCP and BGP neighbor connections\n"
"IPv4 Neighbor to display information about\n"
"IPv6 Neighbor to display information about\n"
@@ -1561,6 +1579,7 @@ DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_routes,
afi_t afi = AFI_L2VPN;
safi_t safi = SAFI_EVPN;
struct bgp *bgp = NULL;
+ int rd_all = 0;
bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
&bgp, uj);
@@ -1569,20 +1588,26 @@ DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_routes,
return CMD_WARNING;
}
- argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community);
- ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
- if (!ret) {
- if (uj) {
- json_object *json_no = NULL;
- json_no = json_object_new_object();
- json_object_string_add(json_no, "warning",
- "Malformed Route Distinguisher");
- vty_out(vty, "%s\n",
- json_object_to_json_string(json_no));
- json_object_free(json_no);
- } else
- vty_out(vty, "%% Malformed Route Distinguisher\n");
- return CMD_WARNING;
+ argv_find(argv, argc, "all", &rd_all);
+ if (!rd_all) {
+ argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN",
+ &idx_ext_community);
+ ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
+ if (!ret) {
+ if (uj) {
+ json_object *json_no = NULL;
+ json_no = json_object_new_object();
+ json_object_string_add(
+ json_no, "warning",
+ "Malformed Route Distinguisher");
+ vty_out(vty, "%s\n",
+ json_object_to_json_string(json_no));
+ json_object_free(json_no);
+ } else
+ vty_out(vty,
+ "%% Malformed Route Distinguisher\n");
+ return CMD_WARNING;
+ }
}
/* neighbors <A.B.C.D|X:X::X:X|WORD> */
@@ -1619,8 +1644,13 @@ DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_routes,
return CMD_WARNING;
}
- return bgp_show_ethernet_vpn(vty, &prd, bgp_show_type_neighbor, peer, 0,
- uj);
+
+ if (rd_all)
+ return bgp_show_ethernet_vpn(vty, NULL, bgp_show_type_neighbor,
+ peer, SHOW_DISPLAY_STANDARD, uj);
+ else
+ return bgp_show_ethernet_vpn(vty, &prd, bgp_show_type_neighbor,
+ peer, SHOW_DISPLAY_STANDARD, uj);
}
DEFUN(show_ip_bgp_l2vpn_evpn_neighbor_advertised_routes,
@@ -1694,7 +1724,7 @@ DEFUN(show_ip_bgp_l2vpn_evpn_neighbor_advertised_routes,
DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes,
show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes_cmd,
- "show [ip] bgp l2vpn evpn rd ASN:NN_OR_IP-ADDRESS:NN neighbors <A.B.C.D|X:X::X:X|WORD> advertised-routes [json]",
+ "show [ip] bgp l2vpn evpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors <A.B.C.D|X:X::X:X|WORD> advertised-routes [json]",
SHOW_STR
IP_STR
BGP_STR
@@ -1702,6 +1732,7 @@ DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes,
EVPN_HELP_STR
"Display information for a route distinguisher\n"
"VPN Route Distinguisher\n"
+ "All VPN Route Distinguishers\n"
"Detailed information on TCP and BGP neighbor connections\n"
"IPv4 Neighbor to display information about\n"
"IPv6 Neighbor to display information about\n"
@@ -1718,6 +1749,7 @@ DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes,
char *peerstr = NULL;
afi_t afi = AFI_L2VPN;
safi_t safi = SAFI_EVPN;
+ int rd_all = 0;
if (uj)
argc--;
@@ -1732,8 +1764,6 @@ DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes,
return CMD_WARNING;
}
- argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community);
-
/* neighbors <A.B.C.D|X:X::X:X|WORD> */
argv_find(argv, argc, "neighbors", &idx);
peerstr = argv[++idx]->arg;
@@ -1768,19 +1798,29 @@ DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes,
return CMD_WARNING;
}
- ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
- if (!ret) {
- if (uj) {
- json_object *json_no = NULL;
- json_no = json_object_new_object();
- json_object_string_add(json_no, "warning",
- "Malformed Route Distinguisher");
- vty_out(vty, "%s\n",
- json_object_to_json_string(json_no));
- json_object_free(json_no);
- } else
- vty_out(vty, "%% Malformed Route Distinguisher\n");
- return CMD_WARNING;
+ argv_find(argv, argc, "all", &rd_all);
+ if (rd_all)
+ return show_adj_route_vpn(vty, peer, NULL, AFI_L2VPN, SAFI_EVPN,
+ uj);
+ else {
+ argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN",
+ &idx_ext_community);
+ ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
+ if (!ret) {
+ if (uj) {
+ json_object *json_no = NULL;
+ json_no = json_object_new_object();
+ json_object_string_add(
+ json_no, "warning",
+ "Malformed Route Distinguisher");
+ vty_out(vty, "%s\n",
+ json_object_to_json_string(json_no));
+ json_object_free(json_no);
+ } else
+ vty_out(vty,
+ "%% Malformed Route Distinguisher\n");
+ return CMD_WARNING;
+ }
}
return show_adj_route_vpn(vty, peer, &prd, AFI_L2VPN, SAFI_EVPN, uj);
@@ -1805,7 +1845,7 @@ DEFUN(show_ip_bgp_l2vpn_evpn_all_overlay,
DEFUN(show_ip_bgp_evpn_rd_overlay,
show_ip_bgp_evpn_rd_overlay_cmd,
- "show [ip] bgp l2vpn evpn rd ASN:NN_OR_IP-ADDRESS:NN overlay",
+ "show [ip] bgp l2vpn evpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> overlay",
SHOW_STR
IP_STR
BGP_STR
@@ -1813,14 +1853,21 @@ DEFUN(show_ip_bgp_evpn_rd_overlay,
EVPN_HELP_STR
"Display information for a route distinguisher\n"
"VPN Route Distinguisher\n"
+ "All VPN Route Distinguishers\n"
"Display BGP Overlay Information for prefixes\n")
{
int idx_ext_community = 0;
int ret;
struct prefix_rd prd;
+ int rd_all = 0;
- argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community);
+ argv_find(argv, argc, "all", &rd_all);
+ if (rd_all)
+ return bgp_show_ethernet_vpn(vty, NULL, bgp_show_type_normal,
+ NULL, SHOW_DISPLAY_OVERLAY,
+ use_json(argc, argv));
+ argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community);
ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
if (!ret) {
vty_out(vty, "%% Malformed Route Distinguisher\n");
@@ -2722,6 +2769,131 @@ static void evpn_show_route_rd(struct vty *vty, struct bgp *bgp,
}
/*
+ * Display BGP EVPN routing table -- all RDs and MAC and/or IP
+ * (vty handler). Only matching type-2 routes will be displayed.
+ */
+static void evpn_show_route_rd_all_macip(struct vty *vty, struct bgp *bgp,
+ struct ethaddr *mac, struct ipaddr *ip,
+ json_object *json)
+{
+ struct bgp_dest *rd_dest;
+ struct bgp_table *table;
+ struct bgp_dest *dest;
+ struct bgp_path_info *pi;
+ afi_t afi = AFI_L2VPN;
+ safi_t safi = SAFI_EVPN;
+ uint32_t prefix_cnt, path_cnt;
+ prefix_cnt = path_cnt = 0;
+
+ /* EVPN routing table is a 2-level table with the first level being
+ * the RD. We need to look in every RD we know about.
+ */
+ for (rd_dest = bgp_table_top(bgp->rib[afi][safi]); rd_dest;
+ rd_dest = bgp_route_next(rd_dest)) {
+ json_object *json_paths = NULL; /* paths array for prefix */
+ json_object *json_prefix = NULL; /* prefix within an RD */
+ json_object *json_rd = NULL; /* holds all prefixes for RD */
+ char rd_str[RD_ADDRSTRLEN];
+ char prefix_str[BUFSIZ];
+ int add_rd_to_json = 0;
+ struct prefix_evpn ep;
+ const struct prefix *rd_destp = bgp_dest_get_prefix(rd_dest);
+
+ table = bgp_dest_get_bgp_table_info(rd_dest);
+ if (table == NULL)
+ continue;
+
+ prefix_rd2str((struct prefix_rd *)rd_destp, rd_str,
+ sizeof(rd_str));
+
+ /* Construct an RT-2 from the user-supplied mac(ip),
+ * then search the l2vpn evpn table for it.
+ */
+ build_evpn_type2_prefix(&ep, mac, ip);
+ dest = bgp_afi_node_lookup(bgp->rib[afi][safi], afi, safi,
+ (struct prefix *)&ep,
+ (struct prefix_rd *)rd_destp);
+ if (!dest)
+ continue;
+
+ if (json)
+ json_rd = json_object_new_object();
+
+ const struct prefix *p = bgp_dest_get_prefix(dest);
+
+ prefix2str(p, prefix_str, sizeof(prefix_str));
+
+ pi = bgp_dest_get_bgp_path_info(dest);
+ if (pi) {
+ /* RD header - per RD. */
+ bgp_evpn_show_route_rd_header(vty, rd_dest, json_rd,
+ rd_str, RD_ADDRSTRLEN);
+ prefix_cnt++;
+ }
+
+ if (json) {
+ json_prefix = json_object_new_object();
+ json_paths = json_object_new_array();
+ json_object_string_add(json_prefix, "prefix",
+ prefix_str);
+ json_object_int_add(json_prefix, "prefixLen",
+ p->prefixlen);
+ } else
+ /* Prefix and num paths displayed once per prefix. */
+ route_vty_out_detail_header(
+ vty, bgp, dest, (struct prefix_rd *)rd_destp,
+ AFI_L2VPN, SAFI_EVPN, json_prefix);
+
+ /* For EVPN, the prefix is displayed for each path (to
+ * fit in with code that already exists).
+ */
+ for (; pi; pi = pi->next) {
+ json_object *json_path = NULL;
+
+ add_rd_to_json = 1;
+ path_cnt++;
+
+ if (json)
+ json_path = json_object_new_array();
+
+ route_vty_out_detail(vty, bgp, dest, pi, AFI_L2VPN,
+ SAFI_EVPN, RPKI_NOT_BEING_USED,
+ json_path);
+
+ if (json)
+ json_object_array_add(json_paths, json_path);
+ else
+ vty_out(vty, "\n");
+ }
+
+ if (json) {
+ json_object_object_add(json_prefix, "paths",
+ json_paths);
+ json_object_object_add(json_rd, prefix_str,
+ json_prefix);
+ if (add_rd_to_json)
+ json_object_object_add(json, rd_str, json_rd);
+ else {
+ json_object_free(json_rd);
+ json_rd = NULL;
+ }
+ }
+ }
+
+ if (json) {
+ json_object_int_add(json, "numPrefix", prefix_cnt);
+ json_object_int_add(json, "numPaths", path_cnt);
+ } else {
+ if (prefix_cnt == 0) {
+ vty_out(vty, "No Matching EVPN prefixes exist\n");
+ } else {
+ vty_out(vty, "Displayed %u prefixes (%u paths)\n",
+ prefix_cnt, path_cnt);
+ }
+ }
+}
+
+/*
* Display BGP EVPN routing table - all routes (vty handler).
* If 'type' is non-zero, only routes matching that type are shown.
*/
@@ -2833,6 +3005,7 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
*/
for (; pi; pi = pi->next) {
json_object *json_path = NULL;
+
path_cnt++;
add_prefix_to_json = 1;
add_rd_to_json = 1;
@@ -4260,7 +4433,7 @@ DEFUN(show_bgp_l2vpn_evpn_route,
*/
DEFUN(show_bgp_l2vpn_evpn_route_rd,
show_bgp_l2vpn_evpn_route_rd_cmd,
- "show bgp l2vpn evpn route rd ASN:NN_OR_IP-ADDRESS:NN [type "EVPN_TYPE_ALL_LIST"] [json]",
+ "show bgp l2vpn evpn route rd <ASN:NN_OR_IP-ADDRESS:NN|all> [type "EVPN_TYPE_ALL_LIST"] [json]",
SHOW_STR
BGP_STR
L2VPN_HELP_STR
@@ -4268,6 +4441,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_rd,
EVPN_RT_HELP_STR
EVPN_RT_DIST_HELP_STR
EVPN_ASN_IP_HELP_STR
+ "All VPN Route Distinguishers\n"
EVPN_TYPE_HELP_STR
EVPN_TYPE_ALL_LIST_HELP_STR
JSON_STR)
@@ -4276,9 +4450,10 @@ DEFUN(show_bgp_l2vpn_evpn_route_rd,
int ret;
struct prefix_rd prd;
int type = 0;
- int rd_idx = 0;
bool uj = false;
json_object *json = NULL;
+ int idx_ext_community = 0;
+ int rd_all = 0;
bgp = bgp_get_evpn();
if (!bgp)
@@ -4289,10 +4464,12 @@ DEFUN(show_bgp_l2vpn_evpn_route_rd,
if (uj)
json = json_object_new_object();
- /* get the RD */
- if (argv_find(argv, argc, "rd", &rd_idx)) {
- ret = str2prefix_rd(argv[rd_idx + 1]->arg, &prd);
-
+ argv_find(argv, argc, "all", &rd_all);
+ if (!rd_all) {
+ /* get the RD */
+ argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN",
+ &idx_ext_community);
+ ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
if (!ret) {
vty_out(vty, "%% Malformed Route Distinguisher\n");
return CMD_WARNING;
@@ -4302,7 +4479,10 @@ DEFUN(show_bgp_l2vpn_evpn_route_rd,
if (bgp_evpn_cli_parse_type(&type, argv, argc) < 0)
return CMD_WARNING;
- evpn_show_route_rd(vty, bgp, &prd, type, json);
+ if (rd_all)
+ evpn_show_all_routes(vty, bgp, type, json, 1);
+ else
+ evpn_show_route_rd(vty, bgp, &prd, type, json);
if (uj) {
vty_out(vty, "%s\n", json_object_to_json_string_ext(
@@ -4318,7 +4498,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_rd,
*/
DEFUN(show_bgp_l2vpn_evpn_route_rd_macip,
show_bgp_l2vpn_evpn_route_rd_macip_cmd,
- "show bgp l2vpn evpn route rd ASN:NN_OR_IP-ADDRESS:NN mac WORD [ip WORD] [json]",
+ "show bgp l2vpn evpn route rd <ASN:NN_OR_IP-ADDRESS:NN|all> mac WORD [ip WORD] [json]",
SHOW_STR
BGP_STR
L2VPN_HELP_STR
@@ -4326,6 +4506,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_rd_macip,
EVPN_RT_HELP_STR
EVPN_RT_DIST_HELP_STR
EVPN_ASN_IP_HELP_STR
+ "All VPN Route Distinguishers\n"
"MAC\n"
"MAC address (e.g., 00:e0:ec:20:12:62)\n"
"IP\n"
@@ -4337,11 +4518,12 @@ DEFUN(show_bgp_l2vpn_evpn_route_rd_macip,
struct prefix_rd prd;
struct ethaddr mac;
struct ipaddr ip;
- int rd_idx = 0;
+ int idx_ext_community = 0;
int mac_idx = 0;
int ip_idx = 0;
bool uj = false;
json_object *json = NULL;
+ int rd_all = 0;
memset(&mac, 0, sizeof(struct ethaddr));
memset(&ip, 0, sizeof(struct ipaddr));
@@ -4356,8 +4538,11 @@ DEFUN(show_bgp_l2vpn_evpn_route_rd_macip,
json = json_object_new_object();
/* get the prd */
- if (argv_find(argv, argc, "rd", &rd_idx)) {
- ret = str2prefix_rd(argv[rd_idx + 1]->arg, &prd);
+ argv_find(argv, argc, "all", &rd_all);
+ if (!rd_all) {
+ argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN",
+ &idx_ext_community);
+ ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
if (!ret) {
vty_out(vty, "%% Malformed Route Distinguisher\n");
return CMD_WARNING;
@@ -4380,7 +4565,10 @@ DEFUN(show_bgp_l2vpn_evpn_route_rd_macip,
}
}
- evpn_show_route_rd_macip(vty, bgp, &prd, &mac, &ip, json);
+ if (rd_all)
+ evpn_show_route_rd_all_macip(vty, bgp, &mac, &ip, json);
+ else
+ evpn_show_route_rd_macip(vty, bgp, &prd, &mac, &ip, json);
if (uj) {
vty_out(vty, "%s\n", json_object_to_json_string_ext(
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index d9acda8bd..a902c63de 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -2043,7 +2043,7 @@ int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd,
DEFUN (show_bgp_ip_vpn_all_rd,
show_bgp_ip_vpn_all_rd_cmd,
- "show bgp "BGP_AFI_CMD_STR" vpn all [rd ASN:NN_OR_IP-ADDRESS:NN] [json]",
+ "show bgp "BGP_AFI_CMD_STR" vpn all [rd <ASN:NN_OR_IP-ADDRESS:NN|all>] [json]",
SHOW_STR
BGP_STR
BGP_VPNVX_HELP_STR
@@ -2051,6 +2051,7 @@ DEFUN (show_bgp_ip_vpn_all_rd,
"Display VPN NLRI specific information\n"
"Display information for a route distinguisher\n"
"VPN Route Distinguisher\n"
+ "All VPN Route Distinguishers\n"
JSON_STR)
{
int ret;
@@ -2059,7 +2060,9 @@ DEFUN (show_bgp_ip_vpn_all_rd,
int idx = 0;
if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
- if (argv_find(argv, argc, "rd", &idx)) {
+ /* Constrain search if user supplies RD && RD != "all" */
+ if (argv_find(argv, argc, "rd", &idx)
+ && strcmp(argv[idx + 1]->arg, "all")) {
ret = str2prefix_rd(argv[idx + 1]->arg, &prd);
if (!ret) {
vty_out(vty,
@@ -2080,26 +2083,28 @@ DEFUN (show_bgp_ip_vpn_all_rd,
ALIAS(show_bgp_ip_vpn_all_rd,
show_bgp_ip_vpn_rd_cmd,
- "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN [json]",
+ "show bgp "BGP_AFI_CMD_STR" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> [json]",
SHOW_STR
BGP_STR
BGP_VPNVX_HELP_STR
"Display VPN NLRI specific information\n"
"Display information for a route distinguisher\n"
"VPN Route Distinguisher\n"
+ "All VPN Route Distinguishers\n"
JSON_STR)
#ifdef KEEP_OLD_VPN_COMMANDS
DEFUN (show_ip_bgp_vpn_rd,
show_ip_bgp_vpn_rd_cmd,
- "show ip bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN",
+ "show ip bgp "BGP_AFI_CMD_STR" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all>",
SHOW_STR
IP_STR
BGP_STR
BGP_AFI_HELP_STR
"Address Family modifier\n"
"Display information for a route distinguisher\n"
- "VPN Route Distinguisher\n")
+ "VPN Route Distinguisher\n"
+ "All VPN Route Distinguishers\n")
{
int idx_ext_community = argc - 1;
int ret;
@@ -2108,6 +2113,10 @@ DEFUN (show_ip_bgp_vpn_rd,
int idx = 0;
if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
+ if (!strcmp(argv[idx_ext_community]->arg, "all"))
+ return bgp_show_mpls_vpn(vty, afi, NULL,
+ bgp_show_type_normal, NULL, 0,
+ 0);
ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
if (!ret) {
vty_out(vty, "%% Malformed Route Distinguisher\n");
@@ -2157,13 +2166,14 @@ DEFUN (show_ip_bgp_vpn_all_tags,
DEFUN (show_ip_bgp_vpn_rd_tags,
show_ip_bgp_vpn_rd_tags_cmd,
- "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN tags",
+ "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> tags",
SHOW_STR
IP_STR
BGP_STR
BGP_VPNVX_HELP_STR
"Display information for a route distinguisher\n"
"VPN Route Distinguisher\n"
+ "All VPN Route Distinguishers\n"
"Display BGP tags for prefixes\n")
{
int idx_ext_community = 5;
@@ -2173,6 +2183,10 @@ DEFUN (show_ip_bgp_vpn_rd_tags,
int idx = 0;
if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
+ if (!strcmp(argv[idx_ext_community]->arg, "all"))
+ return bgp_show_mpls_vpn(vty, afi, NULL,
+ bgp_show_type_normal, NULL, 1,
+ 0);
ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
if (!ret) {
vty_out(vty, "%% Malformed Route Distinguisher\n");
@@ -2247,13 +2261,14 @@ DEFUN (show_ip_bgp_vpn_all_neighbor_routes,
DEFUN (show_ip_bgp_vpn_rd_neighbor_routes,
show_ip_bgp_vpn_rd_neighbor_routes_cmd,
- "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D routes [json]",
+ "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D routes [json]",
SHOW_STR
IP_STR
BGP_STR
BGP_VPNVX_HELP_STR
"Display information for a route distinguisher\n"
"VPN Route Distinguisher\n"
+ "All VPN Route Distinguishers\n"
"Detailed information on TCP and BGP neighbor connections\n"
"Neighbor to display information about\n"
"Display routes learned from neighbor\n"
@@ -2265,26 +2280,32 @@ DEFUN (show_ip_bgp_vpn_rd_neighbor_routes,
union sockunion su;
struct peer *peer;
struct prefix_rd prd;
+ bool prefix_rd_all = false;
bool uj = use_json(argc, argv);
afi_t afi;
int idx = 0;
if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
- ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
- if (!ret) {
- if (uj) {
- json_object *json_no = NULL;
- json_no = json_object_new_object();
- json_object_string_add(
- json_no, "warning",
- "Malformed Route Distinguisher");
- vty_out(vty, "%s\n",
- json_object_to_json_string(json_no));
- json_object_free(json_no);
- } else
- vty_out(vty,
- "%% Malformed Route Distinguisher\n");
- return CMD_WARNING;
+ if (!strcmp(argv[idx_ext_community]->arg, "all"))
+ prefix_rd_all = true;
+ else {
+ ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
+ if (!ret) {
+ if (uj) {
+ json_object *json_no = NULL;
+ json_no = json_object_new_object();
+ json_object_string_add(
+ json_no, "warning",
+ "Malformed Route Distinguisher");
+ vty_out(vty, "%s\n",
+ json_object_to_json_string(
+ json_no));
+ json_object_free(json_no);
+ } else
+ vty_out(vty,
+ "%% Malformed Route Distinguisher\n");
+ return CMD_WARNING;
+ }
}
ret = str2sockunion(argv[idx_ipv4]->arg, &su);
@@ -2320,8 +2341,14 @@ DEFUN (show_ip_bgp_vpn_rd_neighbor_routes,
return CMD_WARNING;
}
- return bgp_show_mpls_vpn(vty, afi, &prd, bgp_show_type_neighbor,
- &su, 0, uj);
+ if (prefix_rd_all)
+ return bgp_show_mpls_vpn(vty, afi, NULL,
+ bgp_show_type_neighbor, &su, 0,
+ uj);
+ else
+ return bgp_show_mpls_vpn(vty, afi, &prd,
+ bgp_show_type_neighbor, &su, 0,
+ uj);
}
return CMD_SUCCESS;
}
@@ -2387,13 +2414,14 @@ DEFUN (show_ip_bgp_vpn_all_neighbor_advertised_routes,
DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes,
show_ip_bgp_vpn_rd_neighbor_advertised_routes_cmd,
- "show [ip] bgp <vpnv4|vpnv6> rd ASN:NN_OR_IP-ADDRESS:NN neighbors A.B.C.D advertised-routes [json]",
+ "show [ip] bgp <vpnv4|vpnv6> rd <ASN:NN_OR_IP-ADDRESS:NN|all> neighbors A.B.C.D advertised-routes [json]",
SHOW_STR
IP_STR
BGP_STR
BGP_VPNVX_HELP_STR
"Display information for a route distinguisher\n"
"VPN Route Distinguisher\n"
+ "All VPN Route Distinguishers\n"
"Detailed information on TCP and BGP neighbor connections\n"
"Neighbor to display information about\n"
"Display the routes advertised to a BGP neighbor\n"
@@ -2442,6 +2470,9 @@ DEFUN (show_ip_bgp_vpn_rd_neighbor_advertised_routes,
return CMD_WARNING;
}
+ if (!strcmp(argv[idx_ext_community]->arg, "all"))
+ return show_adj_route_vpn(vty, peer, NULL, AFI_IP,
+ SAFI_MPLS_VPN, uj);
ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd);
if (!ret) {
if (uj) {
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 5e533e829..35a931622 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -13060,7 +13060,8 @@ DEFUN (show_ip_bgp_vpn_all_route_prefix,
}
return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
- BGP_PATH_SHOW_ALL, use_json(argc, argv));
+ BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
+ use_json(argc, argv));
}
#endif /* KEEP_OLD_VPN_COMMANDS */
@@ -13916,13 +13917,14 @@ struct bgp_distance {
DEFUN (show_bgp_afi_vpn_rd_route,
show_bgp_afi_vpn_rd_route_cmd,
- "show bgp "BGP_AFI_CMD_STR" vpn rd ASN:NN_OR_IP-ADDRESS:NN <A.B.C.D/M|X:X::X:X/M> [json]",
+ "show bgp "BGP_AFI_CMD_STR" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> <A.B.C.D/M|X:X::X:X/M> [json]",
SHOW_STR
BGP_STR
BGP_AFI_HELP_STR
"Address Family modifier\n"
"Display information for a route distinguisher\n"
"Route Distinguisher\n"
+ "All Route Distinguishers\n"
"Network in the BGP routing table to display\n"
"Network in the BGP routing table to display\n"
JSON_STR)
@@ -13937,6 +13939,12 @@ DEFUN (show_bgp_afi_vpn_rd_route,
return CMD_WARNING;
}
+ if (!strcmp(argv[5]->arg, "all"))
+ return bgp_show_route(vty, NULL, argv[6]->arg, afi,
+ SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
+ RPKI_NOT_BEING_USED,
+ use_json(argc, argv));
+
ret = str2prefix_rd(argv[5]->arg, &prd);
if (!ret) {
vty_out(vty, "%% Malformed Route Distinguisher\n");
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index a43b76da7..7692bb7ff 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -5865,6 +5865,7 @@ DEFUN_YANG (set_vpn_nexthop,
int idx_ip = 3;
afi_t afi;
int idx = 0;
+ char xpath_value[XPATH_MAXLEN];
if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
if (afi == AFI_IP) {
@@ -5908,8 +5909,6 @@ DEFUN_YANG (no_set_vpn_nexthop,
"VPN next-hop address\n"
"IPv6 address of next hop\n")
{
- int idx_ip = 4;
- char *arg;
afi_t afi;
int idx = 0;
diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
index 57c1ae65f..5d3f4f0e7 100644
--- a/doc/user/bgp.rst
+++ b/doc/user/bgp.rst
@@ -3166,17 +3166,15 @@ structure is extended with :clicmd:`show bgp [afi] [safi]`.
.. clicmd:: show bgp [afi] [safi] [all] [wide|json]
-.. clicmd:: show bgp <ipv4|ipv6> <unicast|multicast|vpn|labeled-unicast>
+.. clicmd:: show bgp [<ipv4|ipv6> <unicast|multicast|vpn|labeled-unicast|flowspec> | l2vpn evpn]
These commands display BGP routes for the specific routing table indicated by
the selected afi and the selected safi. If no afi and no safi value is given,
the command falls back to the default IPv6 routing table.
- For EVPN prefixes, you can display the full BGP table for this AFI/SAFI
- using the standard `show bgp [afi] [safi]` syntax.
.. clicmd:: show bgp l2vpn evpn route [type <macip|2|multicast|3|es|4|prefix|5>]
- Additionally, you can also filter this output by route type.
+ EVPN prefixes can also be filtered by EVPN route type.
.. clicmd:: show bgp [afi] [safi] [all] summary [json]
@@ -3193,11 +3191,21 @@ structure is extended with :clicmd:`show bgp [afi] [safi]`.
Show a bgp peer summary for peers that are succesfully exchanging routes
for the specified address family, and subsequent address-family.
-.. clicmd:: show bgp [afi] [safi] neighbor [PEER]
+.. clicmd:: show bgp [afi] [safi] [neighbor [PEER] [routes|advertised-routes|received-routes] [json]
This command shows information on a specific BGP peer of the relevant
afi and safi selected.
+ The ``routes`` keyword displays only routes in this address-family's BGP
+ table that were received by this peer and accepted by inbound policy.
+
+ The ``advertised-routes`` keyword displays only the routes in this
+ address-family's BGP table that were permitted by outbound policy and
+ advertised to to this peer.
+
+ The ``received-routes`` keyword displays all routes belonging to this
+ address-family (prior to inbound policy) that were received by this peer.
+
.. clicmd:: show bgp [afi] [safi] [all] dampening dampened-paths [wide|json]
Display paths suppressed due to dampening of the selected afi and safi
@@ -3359,6 +3367,25 @@ Displaying Routes by AS Path
Print a summary of neighbor connections for the specified AFI/SAFI combination.
+Displaying Routes by Route Distinguisher
+----------------------------------------
+
+.. clicmd:: show bgp [<ipv4|ipv6> vpn | l2vpn evpn [route]] rd <all|RD>
+
+ For L3VPN and EVPN address-families, routes can be displayed on a per-RD
+ (Route Distinguisher) basis or for all RD's.
+
+.. clicmd:: show bgp l2vpn evpn rd <all|RD> [overlay | tags]
+
+ Use the ``overlay`` or ``tags`` keywords to display the overlay/tag
+ information about the EVPN prefixes in the selected Route Distinguisher.
+
+.. clicmd:: show bgp l2vpn evpn route rd <all|RD> mac <MAC> [ip <MAC>] [json]
+
+ For EVPN Type 2 (macip) routes, a MAC address (and optionally an IP address)
+ can be supplied to the command to only display matching prefixes in the
+ specified RD.
+
Displaying Update Group Information
-----------------------------------