Mailing List Archive

[PATCH 30/57] bgpd: enhance EPVN vty show commands
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