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.guib...@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

Reply via email to