]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: Display received and advertised EVPN routes from neighbors
authorDinesh Dutt <5016467+ddutt@users.noreply.github.com>
Thu, 8 Aug 2019 02:58:18 +0000 (02:58 +0000)
committerDinesh Dutt <5016467+ddutt@users.noreply.github.com>
Thu, 8 Aug 2019 04:17:26 +0000 (04:17 +0000)
"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>
bgpd/bgp_evpn_vty.c
bgpd/bgp_route.c
bgpd/bgp_vpn.c
bgpd/bgpd.c
bgpd/bgpd.h

index a22082c0723b9eade40a442258673b55a01831e8..d031d34f1f9975c3c404af640ae0684be3c49b2d 100644 (file)
@@ -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);
index a5591e29f2a272edeb7c39ffcb2b2c71ef1886dd..abad1db5a2b32dc4e2009e81c542cd774db00fe4 100644 (file)
@@ -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,
index 54ca980cadb10b4e7e1bb1416af0c2a7bd87c0ff..09b1cb429b2bdc2eb4ec0918c42c5cf9b87230ef 100644 (file)
@@ -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);
                        }
                }
index d79a68dcab2873150d56d91afd6da1f8ba867ac0..b5f267cc3862221124651cfd7351a0212ff13ab7 100644 (file)
@@ -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;
+}
+
index 777db0ce223eeff4c33189bee0e8d1c42740c1f3..9e05fd5629d53f2e1ba535f3c0ead97ba4890216 100644 (file)
@@ -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 */