This patch introduces show show bgp evpn commands to dump
NLRI entries configured or received on BGP, related to EVPN
route type 5. New command introduced is the following:
show bgp evpn [all | rd <rd name> ] [overlay]
This command displays gw ip field of the RT-5 message in the
nexthop field of the show command.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
---
bgpd/bgp_evpn.c | 495 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
bgpd/bgp_evpn.h | 1 +
bgpd/bgp_route.c | 91 ++++++++++
bgpd/bgp_route.h | 1 +
bgpd/bgpd.c | 1 +
5 files changed, 589 insertions(+)
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index 1d537fa7eab8..61335eaaa1ca 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -175,3 +175,498 @@ bgp_nlri_parse_evpn (struct peer *peer, struct attr *attr,
return 0;
}
+
+static int
+show_adj_route_evpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd)
+{
+ struct bgp *bgp;
+ struct bgp_table *table;
+ struct bgp_node *rn;
+ struct bgp_node *rm;
+ struct attr *attr;
+ int rd_header;
+ int header = 1;
+ char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
+
+ bgp = bgp_get_default ();
+ if (bgp == NULL)
+ {
+ vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ for (rn = bgp_table_top (bgp->rib[AFI_INTERNAL_L2VPN][SAFI_INTERNAL_EVPN]); rn;
+ rn = bgp_route_next (rn))
+ {
+ if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
+ continue;
+
+ if ((table = rn->info) != NULL)
+ {
+ rd_header = 1;
+
+ for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
+ if ((attr = rm->info) != NULL)
+ {
+ if (header)
+ {
+ vty_out (vty, "BGP table version is 0, local router ID is %s%s",
+ inet_ntoa (bgp->router_id), VTY_NEWLINE);
+ vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
+ VTY_NEWLINE);
+ vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
+ VTY_NEWLINE, VTY_NEWLINE);
+ vty_out (vty, v4_header, VTY_NEWLINE);
+ header = 0;
+ }
+
+ if (rd_header)
+ {
+ u_int16_t type;
+ struct rd_as rd_as;
+ struct rd_ip rd_ip;
+ u_char *pnt;
+
+ pnt = rn->p.u.val;
+
+ /* Decode RD type. */
+ type = decode_rd_type (pnt);
+ /* Decode RD value. */
+ if (type == RD_TYPE_AS)
+ decode_rd_as (pnt + 2, &rd_as);
+ else if (type == RD_TYPE_AS4)
+ decode_rd_as4 (pnt + 2, &rd_as);
+ else if (type == RD_TYPE_IP)
+ decode_rd_ip (pnt + 2, &rd_ip);
+
+ vty_out (vty, "Route Distinguisher: ");
+
+ if (type == RD_TYPE_AS)
+ vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
+ else if (type == RD_TYPE_AS4)
+ vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
+ else if (type == RD_TYPE_IP)
+ vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
+
+ vty_out (vty, "%s", VTY_NEWLINE);
+ rd_header = 0;
+ }
+ route_vty_out_tmp (vty, &rm->p, attr, SAFI_MPLS_VPN);
+ }
+ }
+ }
+ return CMD_SUCCESS;
+}
+
+enum bgp_show_type
+{
+ bgp_show_type_normal,
+ bgp_show_type_regexp,
+ bgp_show_type_prefix_list,
+ bgp_show_type_filter_list,
+ bgp_show_type_neighbor,
+ bgp_show_type_cidr_only,
+ bgp_show_type_prefix_longer,
+ bgp_show_type_community_all,
+ bgp_show_type_community,
+ bgp_show_type_community_exact,
+ bgp_show_type_community_list,
+ bgp_show_type_community_list_exact
+};
+
+#define SHOW_DISPLAY_STANDARD 0
+#define SHOW_DISPLAY_TAGS 1
+#define SHOW_DISPLAY_OVERLAY 2
+
+static int
+bgp_show_ethernet_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type type,
+ void *output_arg, int option)
+{
+ afi_t afi = AFI_INTERNAL_L2VPN;
+ struct bgp *bgp;
+ struct bgp_table *table;
+ struct bgp_node *rn;
+ struct bgp_node *rm;
+ struct bgp_info *ri;
+ int rd_header;
+ int header = 1;
+ char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
+ char v4_header_tag[] = " Network Next Hop In tag/Out tag%s";
+ char v4_header_overlay[] = " Network Next Hop EthTag Overlay Index RouterMac%s";
+
+ unsigned long output_count = 0;
+ unsigned long total_count = 0;
+
+ bgp = bgp_get_default ();
+ if (bgp == NULL)
+ {
+ vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ for (rn = bgp_table_top (bgp->rib[afi][SAFI_INTERNAL_EVPN]); rn; rn = bgp_route_next (rn))
+ {
+ if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
+ continue;
+
+ if ((table = rn->info) != NULL)
+ {
+ rd_header = 1;
+
+ for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
+ for (ri = rm->info; ri; ri = ri->next)
+ {
+ total_count++;
+ if (type == bgp_show_type_neighbor)
+ {
+ union sockunion *su = output_arg;
+
+ if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
+ continue;
+ }
+ if (header)
+ {
+ if (option == SHOW_DISPLAY_TAGS)
+ vty_out (vty, v4_header_tag, VTY_NEWLINE);
+ else if (option == SHOW_DISPLAY_OVERLAY)
+ vty_out (vty, v4_header_overlay, VTY_NEWLINE);
+ else
+ {
+ vty_out (vty, "BGP table version is 0, local router ID is %s%s",
+ inet_ntoa (bgp->router_id), VTY_NEWLINE);
+ vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
+ VTY_NEWLINE);
+ vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
+ VTY_NEWLINE, VTY_NEWLINE);
+ vty_out (vty, v4_header, VTY_NEWLINE);
+ }
+ header = 0;
+ }
+
+ if (rd_header)
+ {
+ u_int16_t type;
+ struct rd_as rd_as;
+ struct rd_ip rd_ip;
+ u_char *pnt;
+
+ pnt = rn->p.u.val;
+
+ /* Decode RD type. */
+ type = decode_rd_type (pnt);
+ /* Decode RD value. */
+ if (type == RD_TYPE_AS)
+ decode_rd_as (pnt + 2, &rd_as);
+ else if (type == RD_TYPE_AS4)
+ decode_rd_as4 (pnt + 2, &rd_as);
+ else if (type == RD_TYPE_IP)
+ decode_rd_ip (pnt + 2, &rd_ip);
+
+ vty_out (vty, "Route Distinguisher: ");
+
+ if (type == RD_TYPE_AS)
+ vty_out (vty, "as2 %u:%d", rd_as.as, rd_as.val);
+ else if (type == RD_TYPE_AS4)
+ vty_out (vty, "as4 %u:%d", rd_as.as, rd_as.val);
+ else if (type == RD_TYPE_IP)
+ vty_out (vty, "ip %s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
+ vty_out (vty, "%s", VTY_NEWLINE);
+ rd_header = 0;
+ }
+ if (option == SHOW_DISPLAY_TAGS)
+ route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_INTERNAL_EVPN);
+ else if (option == SHOW_DISPLAY_OVERLAY)
+ route_vty_out_overlay (vty, &rm->p, ri, 0);
+ else
+ route_vty_out (vty, &rm->p, ri, 0, SAFI_INTERNAL_EVPN);
+ output_count++;
+ }
+ }
+ }
+
+ if (output_count == 0)
+ {
+ vty_out (vty, "No prefixes displayed, %ld exist%s", total_count, VTY_NEWLINE);
+ }
+ else
+ vty_out (vty, "%sDisplayed %ld out of %ld total prefixes%s",
+ VTY_NEWLINE, output_count, total_count, VTY_NEWLINE);
+ return CMD_SUCCESS;
+}
+
+DEFUN (show_bgp_evpn_all,
+ show_bgp_evpn_all_cmd,
+ "show bgp evpn all",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display EVPN NLRI specific information\n"
+ "Display information about all EVPN NLRIs\n")
+{
+ return bgp_show_ethernet_vpn (vty, NULL, bgp_show_type_normal, NULL,
+ SHOW_DISPLAY_STANDARD);
+}
+
+DEFUN (show_bgp_evpn_rd,
+ show_bgp_evpn_rd_cmd,
+ "show bgp evpn rd ASN:nn_or_IP-address:nn",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display EVPN NLRI specific information\n"
+ "Display information for a route distinguisher\n"
+ "VPN Route Distinguisher\n")
+{
+ int ret;
+ struct prefix_rd prd;
+
+ ret = str2prefix_rd (argv[0], &prd);
+ if (! ret)
+ {
+ vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ return bgp_show_ethernet_vpn (vty, &prd, bgp_show_type_normal, NULL,
+ SHOW_DISPLAY_STANDARD);
+}
+
+DEFUN (show_bgp_evpn_all_tags,
+ show_bgp_evpn_all_tags_cmd,
+ "show bgp evpn all tags",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display EVPN NLRI specific information\n"
+ "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,
+ SHOW_DISPLAY_TAGS);
+}
+
+DEFUN (show_bgp_evpn_rd_tags,
+ show_bgp_evpn_rd_tags_cmd,
+ "show bgp evpn rd ASN:nn_or_IP-address:nn tags",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display EVPN NLRI specific information\n"
+ "Display information for a route distinguisher\n"
+ "VPN Route Distinguisher\n"
+ "Display BGP tags for prefixes\n")
+{
+ int ret;
+ struct prefix_rd prd;
+
+ ret = str2prefix_rd (argv[0], &prd);
+ if (! ret)
+ {
+ vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ return bgp_show_ethernet_vpn (vty, &prd, bgp_show_type_normal, NULL,
+ SHOW_DISPLAY_TAGS);
+}
+
+DEFUN (show_bgp_evpn_all_overlay,
+ show_bgp_evpn_all_overlay_cmd,
+ "show bgp evpn all overlay",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display EVPN NLRI specific information\n"
+ "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,
+ SHOW_DISPLAY_OVERLAY);
+}
+
+DEFUN (show_bgp_evpn_rd_overlay,
+ show_bgp_evpn_rd_overlay_cmd,
+ "show bgp evpn rd ASN:nn_or_IP-address:nn overlay",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display EVPN NLRI specific information\n"
+ "Display information for a route distinguisher\n"
+ "VPN Route Distinguisher\n"
+ "Display BGP tags for prefixes\n")
+{
+ int ret;
+ struct prefix_rd prd;
+
+ ret = str2prefix_rd (argv[0], &prd);
+ if (! ret)
+ {
+ vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ return bgp_show_ethernet_vpn (vty, &prd, bgp_show_type_normal, NULL,
+ SHOW_DISPLAY_OVERLAY);
+}
+
+DEFUN (show_bgp_evpn_all_neighbor_routes,
+ show_bgp_evpn_all_neighbor_routes_cmd,
+ "show bgp evpn all neighbors A.B.C.D routes",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display EVPN NLRI specific information\n"
+ "Display information about all EVPN NLRIs\n"
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Display routes learned from neighbor\n")
+{
+ union sockunion su;
+ struct peer *peer;
+ int ret;
+
+ ret = str2sockunion (argv[0], &su);
+ if (ret < 0)
+ {
+ vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ peer = peer_lookup (NULL, &su);
+ if (! peer || ! peer->afc[AFI_INTERNAL_L2VPN][SAFI_INTERNAL_EVPN])
+ {
+ vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_show_ethernet_vpn (vty, NULL, bgp_show_type_neighbor, &su,
+ SHOW_DISPLAY_STANDARD);
+}
+
+DEFUN (show_bgp_evpn_rd_neighbor_routes,
+ show_bgp_evpn_rd_neighbor_routes_cmd,
+ "show bgp evpn rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display EVPN NLRI specific information\n"
+ "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"
+ "Display routes learned from neighbor\n")
+{
+ int ret;
+ union sockunion su;
+ struct peer *peer;
+ struct prefix_rd prd;
+
+ ret = str2prefix_rd (argv[0], &prd);
+ if (! ret)
+ {
+ vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ ret = str2sockunion (argv[1], &su);
+ if (ret < 0)
+ {
+ vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ peer = peer_lookup (NULL, &su);
+ if (! peer || ! peer->afc[AFI_INTERNAL_L2VPN][SAFI_INTERNAL_EVPN])
+ {
+ vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_show_ethernet_vpn (vty, &prd, bgp_show_type_neighbor, &su,
+ SHOW_DISPLAY_STANDARD);
+}
+
+DEFUN (show_bgp_evpn_all_neighbor_advertised_routes,
+ show_bgp_evpn_all_neighbor_advertised_routes_cmd,
+ "show bgp evpn all neighbors A.B.C.D advertised-routes",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display EVPN NLRI specific information\n"
+ "Display information about all EVPN NLRIs\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")
+{
+ int ret;
+ struct peer *peer;
+ union sockunion su;
+
+ ret = str2sockunion (argv[0], &su);
+ if (ret < 0)
+ {
+ vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ peer = peer_lookup (NULL, &su);
+ if (! peer || ! peer->afc[AFI_INTERNAL_L2VPN][SAFI_INTERNAL_EVPN])
+ {
+ vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return show_adj_route_evpn (vty, peer, NULL);
+}
+
+DEFUN (show_bgp_evpn_rd_neighbor_advertised_routes,
+ show_bgp_evpn_rd_neighbor_advertised_routes_cmd,
+ "show bgp evpn rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display EVPN NLRI specific information\n"
+ "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"
+ "Display the routes advertised to a BGP neighbor\n")
+{
+ int ret;
+ struct peer *peer;
+ struct prefix_rd prd;
+ union sockunion su;
+
+ ret = str2sockunion (argv[1], &su);
+ if (ret < 0)
+ {
+ vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ peer = peer_lookup (NULL, &su);
+ if (! peer || ! peer->afc[AFI_INTERNAL_L2VPN][SAFI_INTERNAL_EVPN])
+ {
+ vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ ret = str2prefix_rd (argv[0], &prd);
+ if (! ret)
+ {
+ vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return show_adj_route_evpn (vty, peer, &prd);
+}
+
+void
+bgp_ethernetvpn_init (void)
+{
+ install_element (VIEW_NODE, &show_bgp_evpn_all_cmd);
+ install_element (VIEW_NODE, &show_bgp_evpn_rd_cmd);
+ install_element (VIEW_NODE, &show_bgp_evpn_all_tags_cmd);
+ install_element (VIEW_NODE, &show_bgp_evpn_rd_tags_cmd);
+ install_element (VIEW_NODE, &show_bgp_evpn_all_neighbor_routes_cmd);
+ install_element (VIEW_NODE, &show_bgp_evpn_rd_neighbor_routes_cmd);
+ install_element (VIEW_NODE, &show_bgp_evpn_all_neighbor_advertised_routes_cmd);
+ install_element (VIEW_NODE, &show_bgp_evpn_rd_neighbor_advertised_routes_cmd);
+ install_element (VIEW_NODE, &show_bgp_evpn_all_overlay_cmd);
+ install_element (VIEW_NODE, &show_bgp_evpn_rd_overlay_cmd);
+}
diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h
index a3c4f3498004..39e2db962a02 100644
--- a/bgpd/bgp_evpn.h
+++ b/bgpd/bgp_evpn.h
@@ -21,6 +21,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#ifndef _QUAGGA_BGP_EVPN_H
#define _QUAGGA_BGP_EVPN_H
+extern void bgp_ethernetvpn_init (void);
extern int bgp_nlri_parse_evpn (struct peer *peer, struct attr *attr,
struct bgp_nlri *packet);
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 3c8ebcab8676..e90760aad9ec 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -58,6 +58,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_mpath.h"
#include "bgpd/bgp_nht.h"
#include "bgpd/bgp_evpn.h"
+#include "bgpd/bgp_attr_evpn.h"
/* Extern from bgp_dump.c */
extern const char *bgp_origin_str[];
@@ -6890,6 +6891,18 @@ route_vty_out(
} else {
vty_out(vty, "?");
}
+ } else if (safi == SAFI_INTERNAL_EVPN) {
+ if (attr->extra) {
+ char buf[BUFSIZ];
+ if (p->family == AF_INET)
+ vty_out (vty, "%s", inet_ntop(AF_INET,
+ &(attr->extra->evpn_overlay.gw_ip.ipv4), buf, BUFSIZ));
+ else if (p->family == AF_INET6)
+ vty_out (vty, "%s", inet_ntop(AF_INET6,
+ &(attr->extra->evpn_overlay.gw_ip.ipv6), buf, BUFSIZ));
+ } else {
+ vty_out(vty, "?");
+ }
} else {
if (p->family == AF_INET)
@@ -7063,6 +7076,84 @@ route_vty_out_tag (struct vty *vty, struct prefix *p,
vty_out (vty, "%s", VTY_NEWLINE);
}
+void
+route_vty_out_overlay (struct vty *vty, struct prefix *p,
+ struct bgp_info *binfo, int display)
+{
+ struct attr *attr;
+
+ if (!binfo->extra)
+ return;
+
+ /* short status lead text */
+ route_vty_short_status_out (vty, binfo);
+
+ /* print prefix and mask */
+ if (! display)
+ route_vty_out_route (p, vty);
+ else
+ vty_out (vty, "%*s", 17, " ");
+
+ /* Print attribute */
+ attr = binfo->attr;
+ if (attr)
+ {
+ if (p->family == AF_INET)
+ {
+ vty_out (vty, "%-16s",
+ inet_ntoa (attr->extra->mp_nexthop_global_in));
+ }
+ else if (p->family == AF_INET6)
+ {
+ assert (attr->extra);
+ char buf[BUFSIZ];
+ char buf1[BUFSIZ];
+ if (attr->extra->mp_nexthop_len == 16)
+ vty_out (vty, "%s",
+ inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
+ buf, BUFSIZ));
+ else if (attr->extra->mp_nexthop_len == 32)
+ vty_out (vty, "%s(%s)",
+ inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
+ buf, BUFSIZ),
+ inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local,
+ buf1, BUFSIZ));
+ }
+ }
+
+ char buf[BUFSIZ];
+ vty_out (vty, "%u/", attr->extra->eth_t_id);
+ if(attr->extra)
+ {
+ struct eth_segment_id *id = &(attr->extra->evpn_overlay.eth_s_id);
+ char *str = esi2str(id);
+ vty_out (vty, "%s", str);
+ free(str);
+ if (p->family == AF_INET)
+ {
+ vty_out (vty, "/%s", inet_ntoa (attr->extra->evpn_overlay.gw_ip.ipv4));
+ }
+ else if (p->family == AF_INET6)
+ {
+ vty_out (vty, "/%s",
+ inet_ntop (AF_INET6, &(attr->extra->evpn_overlay.gw_ip.ipv6),
+ buf, BUFSIZ));
+ }
+ if(attr->extra->ecommunity)
+ {
+ struct ecommunity_val *routermac = ecommunity_lookup (attr->extra->ecommunity, ECOMMUNITY_ENCODE_EVPN);
+
+ if(routermac)
+ {
+ char *mac = ecom_mac2str(routermac->val);
+ vty_out (vty, "/%s",(char *)mac);
+ free(mac);
+ }
+ }
+ }
+ vty_out (vty, "%s", VTY_NEWLINE);
+}
+
/* dampening route */
static void
damp_route_vty_out (struct vty *vty, struct prefix *p,
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index 4301088fed3d..908a91f99182 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -288,6 +288,7 @@ extern safi_t bgp_node_safi (struct vty *);
extern void route_vty_out (struct vty *, struct prefix *, struct bgp_info *, int, safi_t);
extern void route_vty_out_tag (struct vty *, struct prefix *, struct bgp_info *, int, safi_t);
+extern void route_vty_out_overlay (struct vty *, struct prefix *, struct bgp_info *, int);
extern void route_vty_out_tmp (struct vty *, struct prefix *, struct attr *, safi_t);
extern void bgp_peer_clear_node_queue_drain_immediate (struct peer *peer);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 35266394b0cd..020182af6e55 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -5921,6 +5921,7 @@ bgp_init (void)
bgp_scan_vty_init();
bgp_mplsvpn_init ();
bgp_encap_init ();
+ bgp_ethernetvpn_init ();
/* Access list initialize. */
access_list_init ();
--
2.1.4
_______________________________________________
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev
NLRI entries configured or received on BGP, related to EVPN
route type 5. New command introduced is the following:
show bgp evpn [all | rd <rd name> ] [overlay]
This command displays gw ip field of the RT-5 message in the
nexthop field of the show command.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
---
bgpd/bgp_evpn.c | 495 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
bgpd/bgp_evpn.h | 1 +
bgpd/bgp_route.c | 91 ++++++++++
bgpd/bgp_route.h | 1 +
bgpd/bgpd.c | 1 +
5 files changed, 589 insertions(+)
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index 1d537fa7eab8..61335eaaa1ca 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -175,3 +175,498 @@ bgp_nlri_parse_evpn (struct peer *peer, struct attr *attr,
return 0;
}
+
+static int
+show_adj_route_evpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd)
+{
+ struct bgp *bgp;
+ struct bgp_table *table;
+ struct bgp_node *rn;
+ struct bgp_node *rm;
+ struct attr *attr;
+ int rd_header;
+ int header = 1;
+ char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
+
+ bgp = bgp_get_default ();
+ if (bgp == NULL)
+ {
+ vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ for (rn = bgp_table_top (bgp->rib[AFI_INTERNAL_L2VPN][SAFI_INTERNAL_EVPN]); rn;
+ rn = bgp_route_next (rn))
+ {
+ if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
+ continue;
+
+ if ((table = rn->info) != NULL)
+ {
+ rd_header = 1;
+
+ for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
+ if ((attr = rm->info) != NULL)
+ {
+ if (header)
+ {
+ vty_out (vty, "BGP table version is 0, local router ID is %s%s",
+ inet_ntoa (bgp->router_id), VTY_NEWLINE);
+ vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
+ VTY_NEWLINE);
+ vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
+ VTY_NEWLINE, VTY_NEWLINE);
+ vty_out (vty, v4_header, VTY_NEWLINE);
+ header = 0;
+ }
+
+ if (rd_header)
+ {
+ u_int16_t type;
+ struct rd_as rd_as;
+ struct rd_ip rd_ip;
+ u_char *pnt;
+
+ pnt = rn->p.u.val;
+
+ /* Decode RD type. */
+ type = decode_rd_type (pnt);
+ /* Decode RD value. */
+ if (type == RD_TYPE_AS)
+ decode_rd_as (pnt + 2, &rd_as);
+ else if (type == RD_TYPE_AS4)
+ decode_rd_as4 (pnt + 2, &rd_as);
+ else if (type == RD_TYPE_IP)
+ decode_rd_ip (pnt + 2, &rd_ip);
+
+ vty_out (vty, "Route Distinguisher: ");
+
+ if (type == RD_TYPE_AS)
+ vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
+ else if (type == RD_TYPE_AS4)
+ vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
+ else if (type == RD_TYPE_IP)
+ vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
+
+ vty_out (vty, "%s", VTY_NEWLINE);
+ rd_header = 0;
+ }
+ route_vty_out_tmp (vty, &rm->p, attr, SAFI_MPLS_VPN);
+ }
+ }
+ }
+ return CMD_SUCCESS;
+}
+
+enum bgp_show_type
+{
+ bgp_show_type_normal,
+ bgp_show_type_regexp,
+ bgp_show_type_prefix_list,
+ bgp_show_type_filter_list,
+ bgp_show_type_neighbor,
+ bgp_show_type_cidr_only,
+ bgp_show_type_prefix_longer,
+ bgp_show_type_community_all,
+ bgp_show_type_community,
+ bgp_show_type_community_exact,
+ bgp_show_type_community_list,
+ bgp_show_type_community_list_exact
+};
+
+#define SHOW_DISPLAY_STANDARD 0
+#define SHOW_DISPLAY_TAGS 1
+#define SHOW_DISPLAY_OVERLAY 2
+
+static int
+bgp_show_ethernet_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type type,
+ void *output_arg, int option)
+{
+ afi_t afi = AFI_INTERNAL_L2VPN;
+ struct bgp *bgp;
+ struct bgp_table *table;
+ struct bgp_node *rn;
+ struct bgp_node *rm;
+ struct bgp_info *ri;
+ int rd_header;
+ int header = 1;
+ char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
+ char v4_header_tag[] = " Network Next Hop In tag/Out tag%s";
+ char v4_header_overlay[] = " Network Next Hop EthTag Overlay Index RouterMac%s";
+
+ unsigned long output_count = 0;
+ unsigned long total_count = 0;
+
+ bgp = bgp_get_default ();
+ if (bgp == NULL)
+ {
+ vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ for (rn = bgp_table_top (bgp->rib[afi][SAFI_INTERNAL_EVPN]); rn; rn = bgp_route_next (rn))
+ {
+ if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
+ continue;
+
+ if ((table = rn->info) != NULL)
+ {
+ rd_header = 1;
+
+ for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
+ for (ri = rm->info; ri; ri = ri->next)
+ {
+ total_count++;
+ if (type == bgp_show_type_neighbor)
+ {
+ union sockunion *su = output_arg;
+
+ if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
+ continue;
+ }
+ if (header)
+ {
+ if (option == SHOW_DISPLAY_TAGS)
+ vty_out (vty, v4_header_tag, VTY_NEWLINE);
+ else if (option == SHOW_DISPLAY_OVERLAY)
+ vty_out (vty, v4_header_overlay, VTY_NEWLINE);
+ else
+ {
+ vty_out (vty, "BGP table version is 0, local router ID is %s%s",
+ inet_ntoa (bgp->router_id), VTY_NEWLINE);
+ vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s",
+ VTY_NEWLINE);
+ vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s",
+ VTY_NEWLINE, VTY_NEWLINE);
+ vty_out (vty, v4_header, VTY_NEWLINE);
+ }
+ header = 0;
+ }
+
+ if (rd_header)
+ {
+ u_int16_t type;
+ struct rd_as rd_as;
+ struct rd_ip rd_ip;
+ u_char *pnt;
+
+ pnt = rn->p.u.val;
+
+ /* Decode RD type. */
+ type = decode_rd_type (pnt);
+ /* Decode RD value. */
+ if (type == RD_TYPE_AS)
+ decode_rd_as (pnt + 2, &rd_as);
+ else if (type == RD_TYPE_AS4)
+ decode_rd_as4 (pnt + 2, &rd_as);
+ else if (type == RD_TYPE_IP)
+ decode_rd_ip (pnt + 2, &rd_ip);
+
+ vty_out (vty, "Route Distinguisher: ");
+
+ if (type == RD_TYPE_AS)
+ vty_out (vty, "as2 %u:%d", rd_as.as, rd_as.val);
+ else if (type == RD_TYPE_AS4)
+ vty_out (vty, "as4 %u:%d", rd_as.as, rd_as.val);
+ else if (type == RD_TYPE_IP)
+ vty_out (vty, "ip %s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
+ vty_out (vty, "%s", VTY_NEWLINE);
+ rd_header = 0;
+ }
+ if (option == SHOW_DISPLAY_TAGS)
+ route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_INTERNAL_EVPN);
+ else if (option == SHOW_DISPLAY_OVERLAY)
+ route_vty_out_overlay (vty, &rm->p, ri, 0);
+ else
+ route_vty_out (vty, &rm->p, ri, 0, SAFI_INTERNAL_EVPN);
+ output_count++;
+ }
+ }
+ }
+
+ if (output_count == 0)
+ {
+ vty_out (vty, "No prefixes displayed, %ld exist%s", total_count, VTY_NEWLINE);
+ }
+ else
+ vty_out (vty, "%sDisplayed %ld out of %ld total prefixes%s",
+ VTY_NEWLINE, output_count, total_count, VTY_NEWLINE);
+ return CMD_SUCCESS;
+}
+
+DEFUN (show_bgp_evpn_all,
+ show_bgp_evpn_all_cmd,
+ "show bgp evpn all",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display EVPN NLRI specific information\n"
+ "Display information about all EVPN NLRIs\n")
+{
+ return bgp_show_ethernet_vpn (vty, NULL, bgp_show_type_normal, NULL,
+ SHOW_DISPLAY_STANDARD);
+}
+
+DEFUN (show_bgp_evpn_rd,
+ show_bgp_evpn_rd_cmd,
+ "show bgp evpn rd ASN:nn_or_IP-address:nn",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display EVPN NLRI specific information\n"
+ "Display information for a route distinguisher\n"
+ "VPN Route Distinguisher\n")
+{
+ int ret;
+ struct prefix_rd prd;
+
+ ret = str2prefix_rd (argv[0], &prd);
+ if (! ret)
+ {
+ vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ return bgp_show_ethernet_vpn (vty, &prd, bgp_show_type_normal, NULL,
+ SHOW_DISPLAY_STANDARD);
+}
+
+DEFUN (show_bgp_evpn_all_tags,
+ show_bgp_evpn_all_tags_cmd,
+ "show bgp evpn all tags",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display EVPN NLRI specific information\n"
+ "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,
+ SHOW_DISPLAY_TAGS);
+}
+
+DEFUN (show_bgp_evpn_rd_tags,
+ show_bgp_evpn_rd_tags_cmd,
+ "show bgp evpn rd ASN:nn_or_IP-address:nn tags",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display EVPN NLRI specific information\n"
+ "Display information for a route distinguisher\n"
+ "VPN Route Distinguisher\n"
+ "Display BGP tags for prefixes\n")
+{
+ int ret;
+ struct prefix_rd prd;
+
+ ret = str2prefix_rd (argv[0], &prd);
+ if (! ret)
+ {
+ vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ return bgp_show_ethernet_vpn (vty, &prd, bgp_show_type_normal, NULL,
+ SHOW_DISPLAY_TAGS);
+}
+
+DEFUN (show_bgp_evpn_all_overlay,
+ show_bgp_evpn_all_overlay_cmd,
+ "show bgp evpn all overlay",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display EVPN NLRI specific information\n"
+ "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,
+ SHOW_DISPLAY_OVERLAY);
+}
+
+DEFUN (show_bgp_evpn_rd_overlay,
+ show_bgp_evpn_rd_overlay_cmd,
+ "show bgp evpn rd ASN:nn_or_IP-address:nn overlay",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display EVPN NLRI specific information\n"
+ "Display information for a route distinguisher\n"
+ "VPN Route Distinguisher\n"
+ "Display BGP tags for prefixes\n")
+{
+ int ret;
+ struct prefix_rd prd;
+
+ ret = str2prefix_rd (argv[0], &prd);
+ if (! ret)
+ {
+ vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ return bgp_show_ethernet_vpn (vty, &prd, bgp_show_type_normal, NULL,
+ SHOW_DISPLAY_OVERLAY);
+}
+
+DEFUN (show_bgp_evpn_all_neighbor_routes,
+ show_bgp_evpn_all_neighbor_routes_cmd,
+ "show bgp evpn all neighbors A.B.C.D routes",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display EVPN NLRI specific information\n"
+ "Display information about all EVPN NLRIs\n"
+ "Detailed information on TCP and BGP neighbor connections\n"
+ "Neighbor to display information about\n"
+ "Display routes learned from neighbor\n")
+{
+ union sockunion su;
+ struct peer *peer;
+ int ret;
+
+ ret = str2sockunion (argv[0], &su);
+ if (ret < 0)
+ {
+ vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ peer = peer_lookup (NULL, &su);
+ if (! peer || ! peer->afc[AFI_INTERNAL_L2VPN][SAFI_INTERNAL_EVPN])
+ {
+ vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_show_ethernet_vpn (vty, NULL, bgp_show_type_neighbor, &su,
+ SHOW_DISPLAY_STANDARD);
+}
+
+DEFUN (show_bgp_evpn_rd_neighbor_routes,
+ show_bgp_evpn_rd_neighbor_routes_cmd,
+ "show bgp evpn rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display EVPN NLRI specific information\n"
+ "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"
+ "Display routes learned from neighbor\n")
+{
+ int ret;
+ union sockunion su;
+ struct peer *peer;
+ struct prefix_rd prd;
+
+ ret = str2prefix_rd (argv[0], &prd);
+ if (! ret)
+ {
+ vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ ret = str2sockunion (argv[1], &su);
+ if (ret < 0)
+ {
+ vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ peer = peer_lookup (NULL, &su);
+ if (! peer || ! peer->afc[AFI_INTERNAL_L2VPN][SAFI_INTERNAL_EVPN])
+ {
+ vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_show_ethernet_vpn (vty, &prd, bgp_show_type_neighbor, &su,
+ SHOW_DISPLAY_STANDARD);
+}
+
+DEFUN (show_bgp_evpn_all_neighbor_advertised_routes,
+ show_bgp_evpn_all_neighbor_advertised_routes_cmd,
+ "show bgp evpn all neighbors A.B.C.D advertised-routes",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display EVPN NLRI specific information\n"
+ "Display information about all EVPN NLRIs\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")
+{
+ int ret;
+ struct peer *peer;
+ union sockunion su;
+
+ ret = str2sockunion (argv[0], &su);
+ if (ret < 0)
+ {
+ vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ peer = peer_lookup (NULL, &su);
+ if (! peer || ! peer->afc[AFI_INTERNAL_L2VPN][SAFI_INTERNAL_EVPN])
+ {
+ vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return show_adj_route_evpn (vty, peer, NULL);
+}
+
+DEFUN (show_bgp_evpn_rd_neighbor_advertised_routes,
+ show_bgp_evpn_rd_neighbor_advertised_routes_cmd,
+ "show bgp evpn rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes",
+ SHOW_STR
+ IP_STR
+ BGP_STR
+ "Display EVPN NLRI specific information\n"
+ "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"
+ "Display the routes advertised to a BGP neighbor\n")
+{
+ int ret;
+ struct peer *peer;
+ struct prefix_rd prd;
+ union sockunion su;
+
+ ret = str2sockunion (argv[1], &su);
+ if (ret < 0)
+ {
+ vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ peer = peer_lookup (NULL, &su);
+ if (! peer || ! peer->afc[AFI_INTERNAL_L2VPN][SAFI_INTERNAL_EVPN])
+ {
+ vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ ret = str2prefix_rd (argv[0], &prd);
+ if (! ret)
+ {
+ vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return show_adj_route_evpn (vty, peer, &prd);
+}
+
+void
+bgp_ethernetvpn_init (void)
+{
+ install_element (VIEW_NODE, &show_bgp_evpn_all_cmd);
+ install_element (VIEW_NODE, &show_bgp_evpn_rd_cmd);
+ install_element (VIEW_NODE, &show_bgp_evpn_all_tags_cmd);
+ install_element (VIEW_NODE, &show_bgp_evpn_rd_tags_cmd);
+ install_element (VIEW_NODE, &show_bgp_evpn_all_neighbor_routes_cmd);
+ install_element (VIEW_NODE, &show_bgp_evpn_rd_neighbor_routes_cmd);
+ install_element (VIEW_NODE, &show_bgp_evpn_all_neighbor_advertised_routes_cmd);
+ install_element (VIEW_NODE, &show_bgp_evpn_rd_neighbor_advertised_routes_cmd);
+ install_element (VIEW_NODE, &show_bgp_evpn_all_overlay_cmd);
+ install_element (VIEW_NODE, &show_bgp_evpn_rd_overlay_cmd);
+}
diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h
index a3c4f3498004..39e2db962a02 100644
--- a/bgpd/bgp_evpn.h
+++ b/bgpd/bgp_evpn.h
@@ -21,6 +21,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#ifndef _QUAGGA_BGP_EVPN_H
#define _QUAGGA_BGP_EVPN_H
+extern void bgp_ethernetvpn_init (void);
extern int bgp_nlri_parse_evpn (struct peer *peer, struct attr *attr,
struct bgp_nlri *packet);
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 3c8ebcab8676..e90760aad9ec 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -58,6 +58,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_mpath.h"
#include "bgpd/bgp_nht.h"
#include "bgpd/bgp_evpn.h"
+#include "bgpd/bgp_attr_evpn.h"
/* Extern from bgp_dump.c */
extern const char *bgp_origin_str[];
@@ -6890,6 +6891,18 @@ route_vty_out(
} else {
vty_out(vty, "?");
}
+ } else if (safi == SAFI_INTERNAL_EVPN) {
+ if (attr->extra) {
+ char buf[BUFSIZ];
+ if (p->family == AF_INET)
+ vty_out (vty, "%s", inet_ntop(AF_INET,
+ &(attr->extra->evpn_overlay.gw_ip.ipv4), buf, BUFSIZ));
+ else if (p->family == AF_INET6)
+ vty_out (vty, "%s", inet_ntop(AF_INET6,
+ &(attr->extra->evpn_overlay.gw_ip.ipv6), buf, BUFSIZ));
+ } else {
+ vty_out(vty, "?");
+ }
} else {
if (p->family == AF_INET)
@@ -7063,6 +7076,84 @@ route_vty_out_tag (struct vty *vty, struct prefix *p,
vty_out (vty, "%s", VTY_NEWLINE);
}
+void
+route_vty_out_overlay (struct vty *vty, struct prefix *p,
+ struct bgp_info *binfo, int display)
+{
+ struct attr *attr;
+
+ if (!binfo->extra)
+ return;
+
+ /* short status lead text */
+ route_vty_short_status_out (vty, binfo);
+
+ /* print prefix and mask */
+ if (! display)
+ route_vty_out_route (p, vty);
+ else
+ vty_out (vty, "%*s", 17, " ");
+
+ /* Print attribute */
+ attr = binfo->attr;
+ if (attr)
+ {
+ if (p->family == AF_INET)
+ {
+ vty_out (vty, "%-16s",
+ inet_ntoa (attr->extra->mp_nexthop_global_in));
+ }
+ else if (p->family == AF_INET6)
+ {
+ assert (attr->extra);
+ char buf[BUFSIZ];
+ char buf1[BUFSIZ];
+ if (attr->extra->mp_nexthop_len == 16)
+ vty_out (vty, "%s",
+ inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
+ buf, BUFSIZ));
+ else if (attr->extra->mp_nexthop_len == 32)
+ vty_out (vty, "%s(%s)",
+ inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
+ buf, BUFSIZ),
+ inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local,
+ buf1, BUFSIZ));
+ }
+ }
+
+ char buf[BUFSIZ];
+ vty_out (vty, "%u/", attr->extra->eth_t_id);
+ if(attr->extra)
+ {
+ struct eth_segment_id *id = &(attr->extra->evpn_overlay.eth_s_id);
+ char *str = esi2str(id);
+ vty_out (vty, "%s", str);
+ free(str);
+ if (p->family == AF_INET)
+ {
+ vty_out (vty, "/%s", inet_ntoa (attr->extra->evpn_overlay.gw_ip.ipv4));
+ }
+ else if (p->family == AF_INET6)
+ {
+ vty_out (vty, "/%s",
+ inet_ntop (AF_INET6, &(attr->extra->evpn_overlay.gw_ip.ipv6),
+ buf, BUFSIZ));
+ }
+ if(attr->extra->ecommunity)
+ {
+ struct ecommunity_val *routermac = ecommunity_lookup (attr->extra->ecommunity, ECOMMUNITY_ENCODE_EVPN);
+
+ if(routermac)
+ {
+ char *mac = ecom_mac2str(routermac->val);
+ vty_out (vty, "/%s",(char *)mac);
+ free(mac);
+ }
+ }
+ }
+ vty_out (vty, "%s", VTY_NEWLINE);
+}
+
/* dampening route */
static void
damp_route_vty_out (struct vty *vty, struct prefix *p,
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index 4301088fed3d..908a91f99182 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -288,6 +288,7 @@ extern safi_t bgp_node_safi (struct vty *);
extern void route_vty_out (struct vty *, struct prefix *, struct bgp_info *, int, safi_t);
extern void route_vty_out_tag (struct vty *, struct prefix *, struct bgp_info *, int, safi_t);
+extern void route_vty_out_overlay (struct vty *, struct prefix *, struct bgp_info *, int);
extern void route_vty_out_tmp (struct vty *, struct prefix *, struct attr *, safi_t);
extern void bgp_peer_clear_node_queue_drain_immediate (struct peer *peer);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 35266394b0cd..020182af6e55 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -5921,6 +5921,7 @@ bgp_init (void)
bgp_scan_vty_init();
bgp_mplsvpn_init ();
bgp_encap_init ();
+ bgp_ethernetvpn_init ();
/* Access list initialize. */
access_list_init ();
--
2.1.4
_______________________________________________
Quagga-dev mailing list
Quagga-dev@lists.quagga.net
https://lists.quagga.net/mailman/listinfo/quagga-dev