diff options
author | Dinesh Dutt <5016467+ddutt@users.noreply.github.com> | 2019-08-08 04:58:18 +0200 |
---|---|---|
committer | Dinesh Dutt <5016467+ddutt@users.noreply.github.com> | 2019-08-08 06:17:26 +0200 |
commit | dcc1615e1b5f8f439f01fd9e61845f377d28a07a (patch) | |
tree | 93cdbbddb48b5743242673800d372f11ff63b33c /bgpd | |
parent | Merge pull request #4763 from opensourcerouting/ds-work (diff) | |
download | frr-dcc1615e1b5f8f439f01fd9e61845f377d28a07a.tar.xz frr-dcc1615e1b5f8f439f01fd9e61845f377d28a07a.zip |
bgpd: Display received and advertised EVPN routes from neighbors
"show bgp l2vpn evpn neighbors <neighbor> [advertised-routes|routes]' did
not work due to various bugs. First, the command only accepted IPv4
addresses as valid neighbor ID, thereby rejecting unnumbered BGP and IPv6
neighbor address. Second, the SAFI was hardcoded to MPLS_VPN even though
we were passing the safi. Third, "all" made no sense in the command context
and to make the command uniform across all address families, I removed the
"all" keyword from the command.
Signed-off-by: Dinesh G Dutt <ddps4u@gmail.com>
Diffstat (limited to 'bgpd')
-rw-r--r-- | bgpd/bgp_evpn_vty.c | 168 | ||||
-rw-r--r-- | bgpd/bgp_route.c | 57 | ||||
-rw-r--r-- | bgpd/bgp_vpn.c | 4 | ||||
-rw-r--r-- | bgpd/bgpd.c | 58 | ||||
-rw-r--r-- | bgpd/bgpd.h | 4 |
5 files changed, 175 insertions, 116 deletions
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index a22082c07..d031d34f1 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -1069,11 +1069,9 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd, pi = pi->next) { total_count++; if (type == bgp_show_type_neighbor) { - union sockunion *su = output_arg; + struct peer *peer = output_arg; - if (pi->peer->su_remote == NULL - || !sockunion_same( - pi->peer->su_remote, su)) + if (peer_cmp(peer, pi->peer) != 0) continue; } if (header) { @@ -1292,29 +1290,41 @@ DEFUN(show_ip_bgp_l2vpn_evpn_rd_tags, 0); } -DEFUN(show_ip_bgp_l2vpn_evpn_all_neighbor_routes, - show_ip_bgp_l2vpn_evpn_all_neighbor_routes_cmd, - "show [ip] bgp l2vpn evpn all neighbors A.B.C.D routes [json]", +DEFUN(show_ip_bgp_l2vpn_evpn_neighbor_routes, + show_ip_bgp_l2vpn_evpn_neighbor_routes_cmd, + "show [ip] bgp l2vpn evpn neighbors <A.B.C.D|X:X::X:X|WORD> routes [json]", SHOW_STR IP_STR BGP_STR L2VPN_HELP_STR EVPN_HELP_STR - "Display information about all EVPN NLRIs\n" "Detailed information on TCP and BGP neighbor connections\n" - "Neighbor to display information about\n" + "IPv4 Neighbor to display information about\n" + "IPv6 Neighbor to display information about\n" + "Neighbor on BGP configured interface\n" "Display routes learned from neighbor\n" JSON_STR) { - int idx_ipv4 = 0; - union sockunion su; + int idx = 0; struct peer *peer; - int ret; + char *peerstr = NULL; bool uj = use_json(argc, argv); + afi_t afi = AFI_L2VPN; + safi_t safi = SAFI_EVPN; + struct bgp *bgp = NULL; - argv_find(argv, argc, "A.B.C.D", &idx_ipv4); + bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, + &bgp, uj); + if (!idx) { + vty_out(vty, "No index\n"); + return CMD_WARNING; + } + + /* neighbors <A.B.C.D|X:X::X:X|WORD> */ + argv_find(argv, argc, "neighbors", &idx); + peerstr = argv[++idx]->arg; - ret = str2sockunion(argv[idx_ipv4]->arg, &su); - if (ret < 0) { + peer = peer_lookup_in_view(vty, bgp, peerstr, uj); + if (!peer) { if (uj) { json_object *json_no = NULL; json_no = json_object_new_object(); @@ -1325,11 +1335,9 @@ DEFUN(show_ip_bgp_l2vpn_evpn_all_neighbor_routes, json_object_free(json_no); } else vty_out(vty, "Malformed address: %s\n", - argv[idx_ipv4]->arg); + argv[idx]->arg); return CMD_WARNING; } - - peer = peer_lookup(NULL, &su); if (!peer || !peer->afc[AFI_L2VPN][SAFI_EVPN]) { if (uj) { json_object *json_no = NULL; @@ -1345,13 +1353,13 @@ DEFUN(show_ip_bgp_l2vpn_evpn_all_neighbor_routes, return CMD_WARNING; } - return bgp_show_ethernet_vpn(vty, NULL, bgp_show_type_neighbor, &su, 0, + return bgp_show_ethernet_vpn(vty, NULL, bgp_show_type_neighbor, peer, 0, 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 routes [json]", + "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_STR IP_STR BGP_STR @@ -1360,20 +1368,30 @@ DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_routes, "Display information for a route distinguisher\n" "VPN Route Distinguisher\n" "Detailed information on TCP and BGP neighbor connections\n" - "Neighbor to display information about\n" + "IPv4 Neighbor to display information about\n" + "IPv6 Neighbor to display information about\n" + "Neighbor on BGP configured interface\n" "Display routes learned from neighbor\n" JSON_STR) { int idx_ext_community = 0; - int idx_ipv4 = 0; + int idx = 0; int ret; - union sockunion su; struct peer *peer; + char *peerstr = NULL; struct prefix_rd prd; bool uj = use_json(argc, argv); + afi_t afi = AFI_L2VPN; + safi_t safi = SAFI_EVPN; + struct bgp *bgp = NULL; - argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community); - argv_find(argv, argc, "A.B.C.D", &idx_ipv4); + bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, + &bgp, uj); + if (!idx) { + vty_out(vty, "No index\n"); + 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) { @@ -1389,8 +1407,12 @@ DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_routes, return CMD_WARNING; } - ret = str2sockunion(argv[idx_ipv4]->arg, &su); - if (ret < 0) { + /* neighbors <A.B.C.D|X:X::X:X|WORD> */ + argv_find(argv, argc, "neighbors", &idx); + peerstr = argv[++idx]->arg; + + peer = peer_lookup_in_view(vty, bgp, peerstr, uj); + if (!peer) { if (uj) { json_object *json_no = NULL; json_no = json_object_new_object(); @@ -1401,11 +1423,9 @@ DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_routes, json_object_free(json_no); } else vty_out(vty, "Malformed address: %s\n", - argv[idx_ext_community]->arg); + argv[idx]->arg); return CMD_WARNING; } - - peer = peer_lookup(NULL, &su); if (!peer || !peer->afc[AFI_L2VPN][SAFI_EVPN]) { if (uj) { json_object *json_no = NULL; @@ -1421,33 +1441,48 @@ DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_routes, return CMD_WARNING; } - return bgp_show_ethernet_vpn(vty, &prd, bgp_show_type_neighbor, &su, 0, + return bgp_show_ethernet_vpn(vty, &prd, bgp_show_type_neighbor, peer, 0, uj); } -DEFUN(show_ip_bgp_l2vpn_evpn_all_neighbor_advertised_routes, - show_ip_bgp_l2vpn_evpn_all_neighbor_advertised_routes_cmd, - "show [ip] bgp l2vpn evpn all neighbors A.B.C.D advertised-routes [json]", +DEFUN(show_ip_bgp_l2vpn_evpn_neighbor_advertised_routes, + show_ip_bgp_l2vpn_evpn_neighbor_advertised_routes_cmd, + "show [ip] bgp l2vpn evpn neighbors <A.B.C.D|X:X::X:X|WORD> advertised-routes [json]", SHOW_STR IP_STR BGP_STR L2VPN_HELP_STR EVPN_HELP_STR - "Display information about all EVPN NLRIs\n" "Detailed information on TCP and BGP neighbor connections\n" - "Neighbor to display information about\n" + "IPv4 Neighbor to display information about\n" + "IPv6 Neighbor to display information about\n" + "Neighbor on BGP configured interface\n" "Display the routes advertised to a BGP neighbor\n" JSON_STR) { - int idx_ipv4 = 0; - int ret; + int idx = 0; struct peer *peer; - union sockunion su; bool uj = use_json(argc, argv); + struct bgp *bgp = NULL; + afi_t afi = AFI_L2VPN; + safi_t safi = SAFI_EVPN; + char *peerstr = NULL; + + if (uj) + argc--; - argv_find(argv, argc, "A.B.C.D", &idx_ipv4); + bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, + &bgp, uj); + if (!idx) { + vty_out(vty, "No index\n"); + return CMD_WARNING; + } + + /* neighbors <A.B.C.D|X:X::X:X|WORD> */ + argv_find(argv, argc, "neighbors", &idx); + peerstr = argv[++idx]->arg; - ret = str2sockunion(argv[idx_ipv4]->arg, &su); - if (ret < 0) { + peer = peer_lookup_in_view(vty, bgp, peerstr, uj); + if (!peer) { if (uj) { json_object *json_no = NULL; json_no = json_object_new_object(); @@ -1458,10 +1493,9 @@ DEFUN(show_ip_bgp_l2vpn_evpn_all_neighbor_advertised_routes, json_object_free(json_no); } else vty_out(vty, "Malformed address: %s\n", - argv[idx_ipv4]->arg); + argv[idx]->arg); return CMD_WARNING; } - peer = peer_lookup(NULL, &su); if (!peer || !peer->afc[AFI_L2VPN][SAFI_EVPN]) { if (uj) { json_object *json_no = NULL; @@ -1482,7 +1516,7 @@ DEFUN(show_ip_bgp_l2vpn_evpn_all_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 advertised-routes [json]", + "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_STR IP_STR BGP_STR @@ -1491,22 +1525,43 @@ DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes, "Display information for a route distinguisher\n" "VPN Route Distinguisher\n" "Detailed information on TCP and BGP neighbor connections\n" - "Neighbor to display information about\n" + "IPv4 Neighbor to display information about\n" + "IPv6 Neighbor to display information about\n" + "Neighbor on BGP configured interface\n" "Display the routes advertised to a BGP neighbor\n" JSON_STR) { int idx_ext_community = 0; - int idx_ipv4 = 0; + int idx = 0; int ret; struct peer *peer; struct prefix_rd prd; - union sockunion su; + struct bgp *bgp = NULL; bool uj = use_json(argc, argv); + char *peerstr = NULL; + afi_t afi = AFI_L2VPN; + safi_t safi = SAFI_EVPN; + + if (uj) + argc--; + + if (uj) + argc--; + + bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, + &bgp, uj); + if (!idx) { + vty_out(vty, "No index\n"); + return CMD_WARNING; + } argv_find(argv, argc, "ASN:NN_OR_IP-ADDRESS:NN", &idx_ext_community); - argv_find(argv, argc, "A.B.C.D", &idx_ipv4); - ret = str2sockunion(argv[idx_ipv4]->arg, &su); - if (ret < 0) { + /* neighbors <A.B.C.D|X:X::X:X|WORD> */ + argv_find(argv, argc, "neighbors", &idx); + peerstr = argv[++idx]->arg; + + peer = peer_lookup_in_view(vty, bgp, peerstr, uj); + if (!peer) { if (uj) { json_object *json_no = NULL; json_no = json_object_new_object(); @@ -1517,10 +1572,9 @@ DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes, json_object_free(json_no); } else vty_out(vty, "Malformed address: %s\n", - argv[idx_ext_community]->arg); + argv[idx]->arg); return CMD_WARNING; } - peer = peer_lookup(NULL, &su); if (!peer || !peer->afc[AFI_L2VPN][SAFI_EVPN]) { if (uj) { json_object *json_no = NULL; @@ -1599,7 +1653,7 @@ DEFUN(show_ip_bgp_evpn_rd_overlay, use_json(argc, argv)); } -/* For testing purpose, static route of MPLS-VPN. */ +/* For testing purpose, static route of EVPN RT-5. */ DEFUN(evpnrt5_network, evpnrt5_network_cmd, "network <A.B.C.D/M|X:X::X:X/M> rd ASN:NN_OR_IP-ADDRESS:NN ethtag WORD label WORD esi WORD gwip <A.B.C.D|X:X::X:X> routermac WORD [route-map WORD]", @@ -1638,7 +1692,7 @@ DEFUN(evpnrt5_network, argv[idx_routermac]->arg); } -/* For testing purpose, static route of MPLS-VPN. */ +/* For testing purpose, static route of EVPN RT-5. */ DEFUN(no_evpnrt5_network, no_evpnrt5_network_cmd, "no network <A.B.C.D/M|X:X::X:X/M> rd ASN:NN_OR_IP-ADDRESS:NN ethtag WORD label WORD esi WORD gwip <A.B.C.D|X:X::X:X>", @@ -5323,12 +5377,12 @@ void bgp_ethernetvpn_init(void) install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_all_tags_cmd); install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_rd_tags_cmd); install_element(VIEW_NODE, - &show_ip_bgp_l2vpn_evpn_all_neighbor_routes_cmd); + &show_ip_bgp_l2vpn_evpn_neighbor_routes_cmd); install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_rd_neighbor_routes_cmd); install_element( VIEW_NODE, - &show_ip_bgp_l2vpn_evpn_all_neighbor_advertised_routes_cmd); + &show_ip_bgp_l2vpn_evpn_neighbor_advertised_routes_cmd); install_element( VIEW_NODE, &show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes_cmd); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index a5591e29f..abad1db5a 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -10493,63 +10493,6 @@ static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp, return ret; } -static struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp, - const char *ip_str, bool use_json) -{ - int ret; - struct peer *peer; - union sockunion su; - - /* Get peer sockunion. */ - ret = str2sockunion(ip_str, &su); - if (ret < 0) { - peer = peer_lookup_by_conf_if(bgp, ip_str); - if (!peer) { - peer = peer_lookup_by_hostname(bgp, ip_str); - - if (!peer) { - if (use_json) { - json_object *json_no = NULL; - json_no = json_object_new_object(); - json_object_string_add( - json_no, - "malformedAddressOrName", - ip_str); - vty_out(vty, "%s\n", - json_object_to_json_string_ext( - json_no, - JSON_C_TO_STRING_PRETTY)); - json_object_free(json_no); - } else - vty_out(vty, - "%% Malformed address or name: %s\n", - ip_str); - return NULL; - } - } - return peer; - } - - /* Peer structure lookup. */ - peer = peer_lookup(bgp, &su); - if (!peer) { - if (use_json) { - json_object *json_no = NULL; - json_no = json_object_new_object(); - json_object_string_add(json_no, "warning", - "No such neighbor in this view/vrf"); - vty_out(vty, "%s\n", - json_object_to_json_string_ext( - json_no, JSON_C_TO_STRING_PRETTY)); - json_object_free(json_no); - } else - vty_out(vty, "No such neighbor in this view/vrf\n"); - return NULL; - } - - return peer; -} - enum bgp_stats { BGP_STATS_MAXBITLEN = 0, BGP_STATS_RIB, diff --git a/bgpd/bgp_vpn.c b/bgpd/bgp_vpn.c index 54ca980ca..09b1cb429 100644 --- a/bgpd/bgp_vpn.c +++ b/bgpd/bgp_vpn.c @@ -74,7 +74,7 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer, json_object_string_add(json_ocode, "incomplete", "?"); } - for (rn = bgp_table_top(bgp->rib[afi][SAFI_MPLS_VPN]); rn; + for (rn = bgp_table_top(bgp->rib[afi][safi]); rn; rn = bgp_route_next(rn)) { if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0) continue; @@ -200,7 +200,7 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer, json_array); } else { route_vty_out_tmp(vty, &rm->p, path->attr, - SAFI_MPLS_VPN, use_json, + safi, use_json, json_array); } } diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index d79a68dca..b5f267cc3 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -8047,3 +8047,61 @@ void bgp_terminate(void) bgp_mac_finish(); } + +struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp, + const char *ip_str, bool use_json) +{ + int ret; + struct peer *peer; + union sockunion su; + + /* Get peer sockunion. */ + ret = str2sockunion(ip_str, &su); + if (ret < 0) { + peer = peer_lookup_by_conf_if(bgp, ip_str); + if (!peer) { + peer = peer_lookup_by_hostname(bgp, ip_str); + + if (!peer) { + if (use_json) { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add( + json_no, + "malformedAddressOrName", + ip_str); + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json_no, + JSON_C_TO_STRING_PRETTY)); + json_object_free(json_no); + } else + vty_out(vty, + "%% Malformed address or name: %s\n", + ip_str); + return NULL; + } + } + return peer; + } + + /* Peer structure lookup. */ + peer = peer_lookup(bgp, &su); + if (!peer) { + if (use_json) { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", + "No such neighbor in this view/vrf"); + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json_no, JSON_C_TO_STRING_PRETTY)); + json_object_free(json_no); + } else + vty_out(vty, "No such neighbor in this view/vrf\n"); + return NULL; + } + + return peer; +} + diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 777db0ce2..9e05fd562 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -1927,4 +1927,8 @@ extern void bgp_unset_redist_vrf_bitmaps(struct bgp *, vrf_id_t); /* For benefit of rfapi */ extern struct peer *peer_new(struct bgp *bgp); + +extern struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp, + const char *ip_str, bool use_json); + #endif /* _QUAGGA_BGPD_H */ |