diff options
| author | Philippe Guibert <philippe.guibert@6wind.com> | 2016-10-27 08:02:36 +0200 | 
|---|---|---|
| committer | Philippe Guibert <philippe.guibert@6wind.com> | 2017-02-14 13:58:59 +0100 | 
| commit | 3da6fcd55711c5226fc2a29738ad886155d94bc5 (patch) | |
| tree | ef43da8f20e90d76922bd04f7389fd98b2b712ed | |
| parent | 4c63a661e367cdbb16edbdaff50a804428027dcc (diff) | |
bgpd: enhance network command for evpn route type 5
A new vty command available under evpn address family. This command
takes following format:
(af-evpn)# [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 routermac WORD
		 [route-map WORD]
Among new parameters, ethtag stands for the ethernet tag indentifier.
ESI stands for the ethernet segment identifier, and must be entered in
following format: 00:11:22:33:44:55:66:77:88:99.
gwip stands for the gateway IP address contained in RT5 message. A
check is done on that value since if gwip is ipv4, then ip prefix must
be ipv4. The same for ipv6.
RouterMAc is the gateway mac address sent as extended community
attribute.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
| -rw-r--r-- | bgpd/bgp_attr_evpn.c | 42 | ||||
| -rw-r--r-- | bgpd/bgp_attr_evpn.h | 2 | ||||
| -rw-r--r-- | bgpd/bgp_encap.c | 6 | ||||
| -rw-r--r-- | bgpd/bgp_evpn_vty.c | 68 | ||||
| -rw-r--r-- | bgpd/bgp_mplsvpn.c | 16 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 152 | ||||
| -rw-r--r-- | bgpd/bgp_route.h | 6 | 
7 files changed, 265 insertions, 27 deletions
diff --git a/bgpd/bgp_attr_evpn.c b/bgpd/bgp_attr_evpn.c index a85ba002db..6f5a5ffc49 100644 --- a/bgpd/bgp_attr_evpn.c +++ b/bgpd/bgp_attr_evpn.c @@ -32,6 +32,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  #include "bgpd/bgp_route.h"  #include "bgpd/bgp_attr_evpn.h"  #include "bgpd/bgp_ecommunity.h" +#include "bgpd/bgp_evpn.h"  void bgp_add_routermac_ecom (struct attr* attr, char * routermac)  { @@ -281,3 +282,44 @@ char *ecom_mac2str(char *ecom_mac)    en+=2;    return mac2str(en);  } + +/* dst prefix must be AF_INET or AF_INET6 prefix, to forge EVPN prefix */ +extern int bgp_build_evpn_prefix (int evpn_type, uint32_t eth_tag, struct prefix *dst) +{ +#if defined(HAVE_EVPN) +  struct evpn_addr *p_evpn_p; +  struct prefix p2; +  struct prefix *src = &p2; + +  if (!dst || dst->family == 0) +    return -1; +  /* store initial prefix in src */ +  prefix_copy (src, dst); +  memset (dst, 0, sizeof (struct prefix)); +  p_evpn_p = &(dst->u.prefix_evpn); +  dst->family = AF_ETHERNET; +  p_evpn_p->route_type = evpn_type; +  if (evpn_type == EVPN_IP_PREFIX) +    { +      p_evpn_p->eth_tag = eth_tag; +      p_evpn_p->ip_prefix_length = p2.prefixlen; +      if (src->family == AF_INET) +        { +          p_evpn_p->flags = IP_PREFIX_V4; +          memcpy (&p_evpn_p->ip.v4_addr, &src->u.prefix4, sizeof(struct in_addr)); +          dst->prefixlen = (u_char)PREFIX_LEN_ROUTE_TYPE_5_IPV4; +        } +      else +        { +          p_evpn_p->flags = IP_PREFIX_V6; +          memcpy (&p_evpn_p->ip.v6_addr, &src->u.prefix6, sizeof(struct in6_addr)); +          dst->prefixlen = (u_char)PREFIX_LEN_ROUTE_TYPE_5_IPV6; +        } +    } +  else +    return -1; +  return 0; +#else +  return -1; +#endif /* !(HAVE_EVPN) */ +} diff --git a/bgpd/bgp_attr_evpn.h b/bgpd/bgp_attr_evpn.h index 6a779aefbf..89a666ba23 100644 --- a/bgpd/bgp_attr_evpn.h +++ b/bgpd/bgp_attr_evpn.h @@ -60,5 +60,5 @@ extern char *mac2str (char *mac);  extern char *ecom_mac2str(char *ecom_mac);  extern void bgp_add_routermac_ecom (struct attr* attr, char * routermac); - +extern int bgp_build_evpn_prefix (int type, uint32_t eth_tag, struct prefix *dst);  #endif /* _QUAGGA_BGP_ATTR_EVPN_H */ diff --git a/bgpd/bgp_encap.c b/bgpd/bgp_encap.c index 72a30220ff..6e021c4e9e 100644 --- a/bgpd/bgp_encap.c +++ b/bgpd/bgp_encap.c @@ -219,7 +219,8 @@ DEFUN (encap_network,    int idx_ipv4 = 1;    int idx_rd = 3;    int idx_word = 5; -  return bgp_static_set_safi (SAFI_ENCAP, vty, argv[idx_ipv4]->arg, argv[idx_rd]->arg, argv[idx_word]->arg, NULL); +  return bgp_static_set_safi (SAFI_ENCAP, vty, argv[idx_ipv4]->arg, argv[idx_rd]->arg, argv[idx_word]->arg, +                              NULL, 0, NULL, NULL, NULL, NULL);  }  /* For testing purpose, static route of ENCAP. */ @@ -237,7 +238,8 @@ DEFUN (no_encap_network,    int idx_ipv4 = 2;    int idx_rd = 4;    int idx_word = 6; -  return bgp_static_unset_safi (SAFI_ENCAP, vty, argv[idx_ipv4]->arg, argv[idx_rd]->arg, argv[idx_word]->arg); +  return bgp_static_unset_safi (SAFI_ENCAP, vty, argv[idx_ipv4]->arg, argv[idx_rd]->arg, argv[idx_word]->arg, +                                0, NULL, NULL, NULL);  }  static int diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index 862d0ff92b..bb144bfe4a 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -30,6 +30,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  #include "bgpd/bgp_mplsvpn.h"  #include "bgpd/bgp_vpn.h"  #include "bgpd/bgp_evpn_vty.h" +#include "bgpd/bgp_evpn.h"  #define SHOW_DISPLAY_STANDARD 0  #define SHOW_DISPLAY_TAGS 1 @@ -577,6 +578,71 @@ DEFUN (show_ip_bgp_evpn_rd_overlay,                                  SHOW_DISPLAY_OVERLAY, use_json (argc, argv));  } +/* For testing purpose, static route of MPLS-VPN. */ +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]", +       "Specify a network to announce via BGP\n" +       "IP prefix\n" +       "IPv6 prefix\n" +       "Specify Route Distinguisher\n" +       "VPN Route Distinguisher\n" +       "Ethernet Tag\n" +       "Ethernet Tag Value\n" +       "BGP label\n" +       "label value\n" +       "Ethernet Segment Identifier\n" +       "ESI value ( 00:11:22:33:44:55:66:77:88:99 format) \n" +       "Gateway IP\n" +       "Gateway IP ( A.B.C.D )\n" +       "Gateway IPv6 ( X:X::X:X )\n" +       "Router Mac Ext Comm\n" +       "Router Mac address Value ( aa:bb:cc:dd:ee:ff format)\n") +{ +  int idx_ipv4_prefixlen = 1; +  int idx_ext_community = 3; +  int idx_word = 7; +  int idx_esi = 9; +  int idx_gwip = 11; +  int idx_ethtag = 5; +  int idx_routermac = 13; +  int idx_rmap = 15; +  return bgp_static_set_safi (SAFI_EVPN, vty, argv[idx_ipv4_prefixlen]->arg, argv[idx_ext_community]->arg,  +                              argv[idx_word]->arg, argv[idx_rmap]?argv[idx_gwip]->arg:NULL, +                              EVPN_IP_PREFIX, argv[idx_esi]->arg, argv[idx_gwip]->arg, +                              argv[idx_ethtag]->arg, argv[idx_routermac]->arg); +} + +/* For testing purpose, static route of MPLS-VPN. */ +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>", +       NO_STR +       "Specify a network to announce via BGP\n" +       "IP prefix\n" +       "IPv6 prefix\n" +       "Specify Route Distinguisher\n" +       "VPN Route Distinguisher\n" +       "Ethernet Tag\n" +       "Ethernet Tag Value\n" +       "BGP label\n" +       "label value\n" +       "Ethernet Segment Identifier\n" +       "ESI value ( 00:11:22:33:44:55:66:77:88:99 format) \n" +       "Gateway IP\n" +       "Gateway IP ( A.B.C.D )\n" +       "Gateway IPv6 ( X:X::X:X )\n") +{ +  int idx_ipv4_prefixlen = 2; +  int idx_ext_community = 4; +  int idx_label = 8; +  int idx_ethtag = 6; +  int idx_esi = 10; +  int idx_gwip = 12; +  return bgp_static_unset_safi (SAFI_EVPN, vty, argv[idx_ipv4_prefixlen]->arg, argv[idx_ext_community]->arg, argv[idx_label]->arg, +                                EVPN_IP_PREFIX, argv[idx_esi]->arg, argv[idx_gwip]->arg, argv[idx_ethtag]->arg); +} +  void  bgp_ethernetvpn_init (void) @@ -591,4 +657,6 @@ bgp_ethernetvpn_init (void)    install_element (VIEW_NODE, &show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes_cmd);    install_element (VIEW_NODE, &show_ip_bgp_evpn_rd_overlay_cmd);    install_element (VIEW_NODE, &show_ip_bgp_l2vpn_evpn_all_overlay_cmd); +  install_element (BGP_EVPN_NODE, &no_evpnrt5_network_cmd); +  install_element (BGP_EVPN_NODE, &evpnrt5_network_cmd);  } diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 5fd322b65e..d29fb26030 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -471,7 +471,8 @@ DEFUN (vpnv4_network,    int idx_ipv4_prefixlen = 1;    int idx_ext_community = 3;    int idx_word = 5; -  return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg, NULL); +  return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg, argv[idx_ext_community]->arg, +                              argv[idx_word]->arg, NULL, 0, NULL, NULL, NULL, NULL);  }  DEFUN (vpnv4_network_route_map, @@ -490,7 +491,8 @@ DEFUN (vpnv4_network_route_map,    int idx_ext_community = 3;    int idx_word = 5;    int idx_word_2 = 7; -  return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg, argv[idx_word_2]->arg); +  return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg, +                              argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);  }  /* For testing purpose, static route of MPLS-VPN. */ @@ -508,7 +510,9 @@ DEFUN (no_vpnv4_network,    int idx_ipv4_prefixlen = 2;    int idx_ext_community = 4;    int idx_word = 6; -  return bgp_static_unset_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg); +  return bgp_static_unset_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv4_prefixlen]->arg, +                                argv[idx_ext_community]->arg, argv[idx_word]->arg, +                                0, NULL, NULL, NULL);  }  DEFUN (vpnv6_network, @@ -528,9 +532,9 @@ DEFUN (vpnv6_network,    int idx_word = 5;    int idx_word_2 = 7;    if (argv[idx_word_2]) -    return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg, argv[idx_word_2]->arg); +    return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg, argv[idx_word_2]->arg, 0, NULL, NULL, NULL, NULL);    else -    return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg, NULL); +    return bgp_static_set_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg, NULL, 0, NULL, NULL, NULL, NULL);  }  /* For testing purpose, static route of MPLS-VPN. */ @@ -548,7 +552,7 @@ DEFUN (no_vpnv6_network,    int idx_ipv6_prefix = 2;    int idx_ext_community = 4;    int idx_word = 6; -  return bgp_static_unset_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg); +  return bgp_static_unset_safi (SAFI_MPLS_VPN, vty, argv[idx_ipv6_prefix]->arg, argv[idx_ext_community]->arg, argv[idx_word]->arg, 0, NULL, NULL, NULL);  }  int diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index d5d5546a8d..6d8336032f 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -71,6 +71,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  #include "bgpd/bgp_encap_types.h"  #include "bgpd/bgp_encap_tlv.h"  #include "bgpd/bgp_evpn.h" +#include "bgpd/bgp_evpn_vty.h"  /* Extern from bgp_dump.c */ @@ -4432,7 +4433,8 @@ bgp_purge_static_redist_routes (struct bgp *bgp)  int  bgp_static_set_safi (safi_t safi, struct vty *vty, const char *ip_str,                       const char *rd_str, const char *tag_str, -                     const char *rmap_str) +                     const char *rmap_str, int evpn_type, const char *esi, const char *gwip, +                     const char *ethtag, const char *routermac)  {    VTY_DECLVAR_CONTEXT(bgp, bgp);    int ret; @@ -4444,7 +4446,14 @@ bgp_static_set_safi (safi_t safi, struct vty *vty, const char *ip_str,    struct bgp_static *bgp_static;    u_char tag[3];    afi_t afi; +  struct prefix gw_ip; +  if(safi == SAFI_EVPN) +    afi = AFI_L2VPN; +  else +    afi = AFI_IP; + +  /* validate ip prefix */    ret = str2prefix (ip_str, &p);    if (! ret)      { @@ -4452,6 +4461,12 @@ bgp_static_set_safi (safi_t safi, struct vty *vty, const char *ip_str,        return CMD_WARNING;      }    apply_mask (&p); +  if ( (afi == AFI_L2VPN) && +       (bgp_build_evpn_prefix ( evpn_type, ethtag!=NULL?atol(ethtag):0, &p))) +    { +      vty_out (vty, "%% L2VPN prefix could not be forged%s", VTY_NEWLINE); +      return CMD_WARNING; +    }    ret = str2prefix_rd (rd_str, &prd);    if (! ret) @@ -4460,20 +4475,47 @@ bgp_static_set_safi (safi_t safi, struct vty *vty, const char *ip_str,        return CMD_WARNING;      } -  ret = str2tag (tag_str, tag); -  if (! ret) +  if (tag_str)      { -      vty_out (vty, "%% Malformed tag%s", VTY_NEWLINE); -      return CMD_WARNING; +      ret = str2tag (tag_str, tag); +      if (! ret) +        { +          vty_out (vty, "%% Malformed tag%s", VTY_NEWLINE); +          return CMD_WARNING; +        }      } -  if (p.family == AF_INET) -    afi = AFI_IP; -  else if (p.family == AF_INET6) -    afi = AFI_IP6;    else      { -      vty_out (vty, "%% Non Supported prefix%s", VTY_NEWLINE); -      return CMD_WARNING; +      encode_label (0, tag); +    } +  if (safi == SAFI_EVPN) +    { +      if( esi && str2esi (esi, NULL) == 0) +        { +          vty_out (vty, "%% Malformed ESI%s", VTY_NEWLINE); +          return CMD_WARNING; +        } +      if( routermac && str2mac (routermac, NULL) == 0) +        { +          vty_out (vty, "%% Malformed Router MAC%s", VTY_NEWLINE); +          return CMD_WARNING; +        } +      if (gwip) +        { +          memset (&gw_ip, 0, sizeof (struct prefix)); +          ret = str2prefix (gwip, &gw_ip); +          if (! ret) +            { +              vty_out (vty, "%% Malformed GatewayIp%s", VTY_NEWLINE); +              return CMD_WARNING; +            } +          if((gw_ip.family == AF_INET &&  (p.u.prefix_evpn.flags & IP_PREFIX_V6)) +             || (gw_ip.family == AF_INET6 &&  (p.u.prefix_evpn.flags & IP_PREFIX_V4))) +            { +              vty_out (vty, "%% GatewayIp family differs with IP prefix%s", VTY_NEWLINE); +              return CMD_WARNING; +            } +        }      }    prn = bgp_node_get (bgp->route[afi][safi],  			(struct prefix *)&prd); @@ -4508,6 +4550,22 @@ bgp_static_set_safi (safi_t safi, struct vty *vty, const char *ip_str,  	  bgp_static->rmap.name = strdup (rmap_str);  	  bgp_static->rmap.map = route_map_lookup_by_name (rmap_str);  	} + +      if (safi == SAFI_EVPN) +        { +          if(esi) +            { +              bgp_static->eth_s_id = XCALLOC (MTYPE_ATTR, sizeof(struct eth_segment_id)); +              str2esi (esi, bgp_static->eth_s_id); +            } +          if( routermac) +            { +              bgp_static->router_mac = XCALLOC (MTYPE_ATTR, MAC_LEN+1); +              str2mac (routermac, bgp_static->router_mac); +            } +          if (gwip) +            prefix_copy (&bgp_static->gatewayIp, &gw_ip); +        }        rn->info = bgp_static;        bgp_static->valid = 1; @@ -4520,7 +4578,8 @@ bgp_static_set_safi (safi_t safi, struct vty *vty, const char *ip_str,  /* Configure static BGP network. */  int  bgp_static_unset_safi(safi_t safi, struct vty *vty, const char *ip_str, -                      const char *rd_str, const char *tag_str) +                      const char *rd_str, const char *tag_str, +                      int evpn_type, const char *esi, const char *gwip, const char *ethtag)  {    VTY_DECLVAR_CONTEXT(bgp, bgp);    int ret; @@ -4531,6 +4590,12 @@ bgp_static_unset_safi(safi_t safi, struct vty *vty, const char *ip_str,    struct bgp_table *table;    struct bgp_static *bgp_static;    u_char tag[3]; +  afi_t afi; + +  if(safi == SAFI_EVPN) +    afi = AFI_L2VPN; +  else +    afi = AFI_IP;    /* Convert IP prefix string to struct prefix. */    ret = str2prefix (ip_str, &p); @@ -4540,7 +4605,12 @@ bgp_static_unset_safi(safi_t safi, struct vty *vty, const char *ip_str,        return CMD_WARNING;      }    apply_mask (&p); - +  if ( (afi == AFI_L2VPN) && +       (bgp_build_evpn_prefix ( evpn_type, ethtag!=NULL?atol(ethtag):0, &p))) +    { +      vty_out (vty, "%% L2VPN prefix could not be forged%s", VTY_NEWLINE); +      return CMD_WARNING; +    }    ret = str2prefix_rd (rd_str, &prd);    if (! ret)      { @@ -4555,10 +4625,10 @@ bgp_static_unset_safi(safi_t safi, struct vty *vty, const char *ip_str,        return CMD_WARNING;      } -  prn = bgp_node_get (bgp->route[AFI_IP][safi], +  prn = bgp_node_get (bgp->route[afi][safi],  			(struct prefix *)&prd);    if (prn->info == NULL) -    prn->info = bgp_table_init (AFI_IP, safi); +    prn->info = bgp_table_init (afi, safi);    else      bgp_unlock_node (prn);    table = prn->info; @@ -4567,7 +4637,7 @@ bgp_static_unset_safi(safi_t safi, struct vty *vty, const char *ip_str,    if (rn)      { -      bgp_static_withdraw_safi (bgp, &p, AFI_IP, safi, &prd, tag); +      bgp_static_withdraw_safi (bgp, &p, afi, safi, &prd, tag);        bgp_static = rn->info;        bgp_static_free (bgp_static); @@ -10427,6 +10497,53 @@ bgp_config_write_network_vpn (struct vty *vty, struct bgp *bgp,    return 0;  } +static int +bgp_config_write_network_evpn (struct vty *vty, struct bgp *bgp, +                               afi_t afi, safi_t safi, int *write) +{ +  struct bgp_node *prn; +  struct bgp_node *rn; +  struct bgp_table *table; +  struct prefix *p; +  struct prefix_rd *prd; +  struct bgp_static *bgp_static; +  char buf[PREFIX_STRLEN]; +  char buf2[SU_ADDRSTRLEN]; +  char rdbuf[RD_ADDRSTRLEN]; + +  /* Network configuration. */ +  for (prn = bgp_table_top (bgp->route[afi][safi]); prn; prn = bgp_route_next (prn)) +    if ((table = prn->info) != NULL) +      for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))  +	if ((bgp_static = rn->info) != NULL) +	  { +            char *macrouter = NULL; +            char *esi = NULL; + +            if(bgp_static->router_mac) +              macrouter = mac2str(bgp_static->router_mac); +            if(bgp_static->eth_s_id) +              esi = esi2str(bgp_static->eth_s_id); +	    p = &rn->p; +	    prd = (struct prefix_rd *) &prn->p; + +	    /* "address-family" display.  */ +	    bgp_config_write_family_header (vty, afi, safi, write); + +	    /* "network" configuration display.  */ +	    prefix_rd2str (prd, rdbuf, RD_ADDRSTRLEN); + +            inet_ntop (AF_INET, &bgp_static->igpnexthop, buf2, SU_ADDRSTRLEN); + +            prefix2str (p, buf, sizeof (buf)), +	    vty_out (vty, " network %s rd %s ethtag %u tag %u esi %s gwip %s routermac %s", +		     buf, rdbuf, p->u.prefix_evpn.eth_tag, +                     decode_label (bgp_static->tag), esi, buf2 , macrouter); +	    vty_out (vty, "%s", VTY_NEWLINE); +	  } +  return 0; +} +  /* Configuration of static route announcement and aggregate     information. */  int @@ -10442,6 +10559,9 @@ bgp_config_write_network (struct vty *vty, struct bgp *bgp,    if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))      return bgp_config_write_network_vpn (vty, bgp, afi, safi, write); +  if (afi == AFI_L2VPN && safi == SAFI_EVPN) +    return bgp_config_write_network_evpn (vty, bgp, afi, safi, write); +    /* Network configuration. */    for (rn = bgp_table_top (bgp->route[afi][safi]); rn; rn = bgp_route_next (rn))       if ((bgp_static = rn->info) != NULL) diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 1f9586d343..da015feb21 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -319,10 +319,12 @@ extern void bgp_static_update (struct bgp *, struct prefix *, struct bgp_static  extern void bgp_static_withdraw (struct bgp *, struct prefix *, afi_t, safi_t);  extern int bgp_static_set_safi (safi_t safi, struct vty *vty, const char *, -                          const char *, const char *, const char *); +                                const char *, const char *, const char *, +                                int, const char *, const char *, const char *, const char *);  extern int bgp_static_unset_safi (safi_t safi, struct vty *, const char *, -                            const char *, const char *); +                                  const char *, const char *, +                                  int, const char *, const char *, const char *);  /* this is primarily for MPLS-VPN */  extern int bgp_update (struct peer *, struct prefix *, u_int32_t, struct attr *,  | 
