diff options
-rw-r--r-- | bgpd/bgp_attr_evpn.c | 441 | ||||
-rw-r--r-- | bgpd/bgp_attr_evpn.h | 43 | ||||
-rw-r--r-- | bgpd/bgp_evpn.c | 368 | ||||
-rw-r--r-- | bgpd/bgp_evpn.h | 12 | ||||
-rw-r--r-- | bgpd/bgp_evpn_vty.c | 1248 | ||||
-rw-r--r-- | bgpd/bgp_evpn_vty.h | 6 |
6 files changed, 1086 insertions, 1032 deletions
diff --git a/bgpd/bgp_attr_evpn.c b/bgpd/bgp_attr_evpn.c index 26fc08f65..31f75baa2 100644 --- a/bgpd/bgp_attr_evpn.c +++ b/bgpd/bgp_attr_evpn.c @@ -34,43 +34,42 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #include "bgpd/bgp_ecommunity.h" #include "bgpd/bgp_evpn.h" -void bgp_add_routermac_ecom (struct attr* attr, char * routermac) +void bgp_add_routermac_ecom(struct attr *attr, char *routermac) { - struct ecommunity_val routermac_ecom; + struct ecommunity_val routermac_ecom; - if(attr->extra) - { - memset(&routermac_ecom, 0, sizeof(struct ecommunity_val)); - routermac_ecom.val[0] = ECOMMUNITY_ENCODE_EVPN; - routermac_ecom.val[1] = ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC; - memcpy(&routermac_ecom.val[2], routermac, MAC_LEN); - if(!attr->extra->ecommunity) - attr->extra->ecommunity = ecommunity_new (); - ecommunity_add_val(attr->extra->ecommunity, &routermac_ecom); - } + if (attr->extra) { + memset(&routermac_ecom, 0, sizeof(struct ecommunity_val)); + routermac_ecom.val[0] = ECOMMUNITY_ENCODE_EVPN; + routermac_ecom.val[1] = ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC; + memcpy(&routermac_ecom.val[2], routermac, MAC_LEN); + if (!attr->extra->ecommunity) + attr->extra->ecommunity = ecommunity_new(); + ecommunity_add_val(attr->extra->ecommunity, &routermac_ecom); + } } -static uint8_t convertchartohexa (uint8_t *hexa, int *error) +static uint8_t convertchartohexa(uint8_t * hexa, int *error) { - if( (*hexa == '0') || (*hexa == '1') || (*hexa == '2') || - (*hexa == '3') || (*hexa == '4') || (*hexa == '5') || - (*hexa == '6') || (*hexa == '7') || (*hexa == '8') || - (*hexa == '9')) - return (uint8_t)(*hexa)-'0'; - if((*hexa == 'a') || (*hexa == 'A')) - return 0xa; - if((*hexa == 'b') || (*hexa == 'B')) - return 0xb; - if((*hexa == 'c') || (*hexa == 'C')) - return 0xc; - if((*hexa == 'd') || (*hexa == 'D')) - return 0xd; - if((*hexa == 'e') || (*hexa == 'E')) - return 0xe; - if((*hexa == 'f') || (*hexa == 'F')) - return 0xf; - *error = -1; - return 0; + if ((*hexa == '0') || (*hexa == '1') || (*hexa == '2') || + (*hexa == '3') || (*hexa == '4') || (*hexa == '5') || + (*hexa == '6') || (*hexa == '7') || (*hexa == '8') + || (*hexa == '9')) + return (uint8_t) (*hexa) - '0'; + if ((*hexa == 'a') || (*hexa == 'A')) + return 0xa; + if ((*hexa == 'b') || (*hexa == 'B')) + return 0xb; + if ((*hexa == 'c') || (*hexa == 'C')) + return 0xc; + if ((*hexa == 'd') || (*hexa == 'D')) + return 0xd; + if ((*hexa == 'e') || (*hexa == 'E')) + return 0xe; + if ((*hexa == 'f') || (*hexa == 'F')) + return 0xf; + *error = -1; + return 0; } /* converts to internal representation of mac address @@ -78,81 +77,72 @@ static uint8_t convertchartohexa (uint8_t *hexa, int *error) * format accepted: AA:BB:CC:DD:EE:FF * if mac parameter is null, then check only */ -int -str2mac (const char *str, char *mac) +int str2mac(const char *str, char *mac) { - unsigned int k=0, i, j; - uint8_t *ptr, *ptr2; - size_t len; - uint8_t car; + unsigned int k = 0, i, j; + uint8_t *ptr, *ptr2; + size_t len; + uint8_t car; - if (!str) - return 0; + if (!str) + return 0; - if (str[0] == ':' && str[1] == '\0') - return 1; + if (str[0] == ':' && str[1] == '\0') + return 1; - i = 0; - ptr = (uint8_t *)str; - while (i < 6) - { - uint8_t temp[5]; - int error = 0; - ptr2 = (uint8_t *)strchr((const char *)ptr, ':'); - if (ptr2 == NULL) - { - /* if last occurence return ok */ - if(i != 5) - { - zlog_err("[%s]: format non recognized",mac); - return 0; - } - len = strlen((char *)ptr); - } - else - { - len = ptr2 - ptr; - } - if(len > 5) - { - zlog_err("[%s]: format non recognized",mac); - return 0; - } - memcpy(temp, ptr, len); - for(j=0;j< len;j++) - { - if (k >= MAC_LEN) - return 0; - if(mac) - mac[k] = 0; - car = convertchartohexa (&temp[j], &error); - if (error) - return 0; - if(mac) - mac[k] = car << 4; - j++; - if(j == len) - return 0; - car = convertchartohexa (&temp[j], &error) & 0xf; - if (error) - return 0; - if(mac) - mac[k] |= car & 0xf; - k++; - i++; + i = 0; + ptr = (uint8_t *) str; + while (i < 6) { + uint8_t temp[5]; + int error = 0; + ptr2 = (uint8_t *) strchr((const char *)ptr, ':'); + if (ptr2 == NULL) { + /* if last occurence return ok */ + if (i != 5) { + zlog_err("[%s]: format non recognized", mac); + return 0; + } + len = strlen((char *)ptr); + } else { + len = ptr2 - ptr; + } + if (len > 5) { + zlog_err("[%s]: format non recognized", mac); + return 0; + } + memcpy(temp, ptr, len); + for (j = 0; j < len; j++) { + if (k >= MAC_LEN) + return 0; + if (mac) + mac[k] = 0; + car = convertchartohexa(&temp[j], &error); + if (error) + return 0; + if (mac) + mac[k] = car << 4; + j++; + if (j == len) + return 0; + car = convertchartohexa(&temp[j], &error) & 0xf; + if (error) + return 0; + if (mac) + mac[k] |= car & 0xf; + k++; + i++; + } + ptr = ptr2; + if (ptr == NULL) + break; + ptr++; + } + if (mac && 0) { + zlog_err("leave correct : %02x:%02x:%02x:%02x:%02x:%02x", + mac[0] & 0xff, mac[1] & 0xff, mac[2] & 0xff, + mac[3] & 0xff, mac[4] & 0xff, mac[5] & 0xff); } - ptr = ptr2; - if(ptr == NULL) - break; - ptr++; - } - if(mac && 0) - { - zlog_err("leave correct : %02x:%02x:%02x:%02x:%02x:%02x", - mac[0] & 0xff, mac[1] & 0xff, mac[2] & 0xff, - mac[3] & 0xff, mac[4] & 0xff, mac[5] & 0xff); - } - return 1; + return 1; } /* converts to an esi @@ -160,162 +150,151 @@ str2mac (const char *str, char *mac) * format accepted: AA:BB:CC:DD:EE:FF:GG:HH:II:JJ * if id is null, check only is done */ -int -str2esi (const char *str, struct eth_segment_id *id) +int str2esi(const char *str, struct eth_segment_id *id) { - unsigned int k=0, i, j; - uint8_t *ptr, *ptr2; - size_t len; - uint8_t car; + unsigned int k = 0, i, j; + uint8_t *ptr, *ptr2; + size_t len; + uint8_t car; - if (!str) - return 0; - if (str[0] == ':' && str[1] == '\0') - return 1; + if (!str) + return 0; + if (str[0] == ':' && str[1] == '\0') + return 1; - i = 0; - ptr = (uint8_t *)str; - while (i < 10) - { - uint8_t temp[5]; - int error = 0; - ptr2 = (uint8_t *)strchr((const char *)ptr, ':'); - if (ptr2 == NULL) - { - /* if last occurence return ok */ - if(i != 9) - { - zlog_err("[%s]: format non recognized",str); - return 0; - } - len = strlen((char *)ptr); + i = 0; + ptr = (uint8_t *) str; + while (i < 10) { + uint8_t temp[5]; + int error = 0; + ptr2 = (uint8_t *) strchr((const char *)ptr, ':'); + if (ptr2 == NULL) { + /* if last occurence return ok */ + if (i != 9) { + zlog_err("[%s]: format non recognized", str); + return 0; + } + len = strlen((char *)ptr); + } else { + len = ptr2 - ptr; + } + memcpy(temp, ptr, len); + if (len > 5) { + zlog_err("[%s]: format non recognized", str); + return 0; + } + for (j = 0; j < len; j++) { + if (k >= ESI_LEN) + return 0; + if (id) + id->val[k] = 0; + car = convertchartohexa(&temp[j], &error); + if (error) + return 0; + if (id) + id->val[k] = car << 4; + j++; + if (j == len) + return 0; + car = convertchartohexa(&temp[j], &error) & 0xf; + if (error) + return 0; + if (id) + id->val[k] |= car & 0xf; + k++; + i++; + } + ptr = ptr2; + if (ptr == NULL) + break; + ptr++; } - else - { - len = ptr2 - ptr; - } - memcpy(temp, ptr, len); - if(len > 5) - { - zlog_err("[%s]: format non recognized",str); - return 0; - } - for(j=0;j< len;j++) - { - if (k >= ESI_LEN) - return 0; - if(id) - id->val[k] = 0; - car = convertchartohexa (&temp[j], &error); - if (error) - return 0; - if(id) - id->val[k] = car << 4; - j++; - if(j == len) - return 0; - car = convertchartohexa (&temp[j], &error) & 0xf; - if (error) - return 0; - if(id) - id->val[k] |= car & 0xf; - k++; - i++; + if (id && 0) { + zlog_err("leave correct : %02x:%02x:%02x:%02x:%02x", + id->val[0], id->val[1], id->val[2], id->val[3], + id->val[4]); + zlog_err("%02x:%02x:%02x:%02x:%02x", id->val[5], id->val[6], + id->val[7], id->val[8], id->val[9]); } - ptr = ptr2; - if(ptr == NULL) - break; - ptr++; - } - if(id && 0) - { - zlog_err("leave correct : %02x:%02x:%02x:%02x:%02x", - id->val[0], id->val[1], id->val[2], id->val[3], id->val[4]); - zlog_err("%02x:%02x:%02x:%02x:%02x", - id->val[5], id->val[6], id->val[7], id->val[8], id->val[9]); - } - return 1; + return 1; } -char * -esi2str (struct eth_segment_id *id) +char *esi2str(struct eth_segment_id *id) { - char *ptr; - u_char *val; + char *ptr; + u_char *val; - if(!id) - return NULL; + if (!id) + return NULL; - val = id->val; - ptr = (char *) malloc ((ESI_LEN*2+ESI_LEN-1+1)*sizeof(char)); + val = id->val; + ptr = (char *)malloc((ESI_LEN * 2 + ESI_LEN - 1 + 1) * sizeof(char)); - snprintf (ptr, (ESI_LEN*2+ESI_LEN-1+1), - "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", - val[0], val[1], val[2], val[3], val[4], - val[5], val[6], val[7], val[8], val[9]); + snprintf(ptr, (ESI_LEN * 2 + ESI_LEN - 1 + 1), + "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + val[0], val[1], val[2], val[3], val[4], + val[5], val[6], val[7], val[8], val[9]); - return ptr; + return ptr; } -char * -mac2str (char *mac) +char *mac2str(char *mac) { - char *ptr; + char *ptr; - if(!mac) - return NULL; + if (!mac) + return NULL; - ptr = (char *) malloc ((MAC_LEN*2+MAC_LEN-1+1)*sizeof(char)); + ptr = (char *)malloc((MAC_LEN * 2 + MAC_LEN - 1 + 1) * sizeof(char)); - snprintf (ptr, (MAC_LEN*2+MAC_LEN-1+1), "%02x:%02x:%02x:%02x:%02x:%02x", - (uint8_t) mac[0], (uint8_t)mac[1], (uint8_t)mac[2], (uint8_t)mac[3], - (uint8_t)mac[4], (uint8_t)mac[5]); + snprintf(ptr, (MAC_LEN * 2 + MAC_LEN - 1 + 1), + "%02x:%02x:%02x:%02x:%02x:%02x", (uint8_t) mac[0], + (uint8_t) mac[1], (uint8_t) mac[2], (uint8_t) mac[3], + (uint8_t) mac[4], (uint8_t) mac[5]); - return ptr; + return ptr; } char *ecom_mac2str(char *ecom_mac) { - char *en; + char *en; - en = ecom_mac; - en+=2; - return mac2str(en); + en = 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) +extern int +bgp_build_evpn_prefix(int evpn_type, uint32_t eth_tag, struct prefix *dst) { - struct evpn_addr *p_evpn_p; - struct prefix p2; - struct prefix *src = &p2; + 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; + 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; } diff --git a/bgpd/bgp_attr_evpn.h b/bgpd/bgp_attr_evpn.h index 89a666ba2..aff0ae414 100644 --- a/bgpd/bgp_attr_evpn.h +++ b/bgpd/bgp_attr_evpn.h @@ -22,12 +22,12 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #define _QUAGGA_BGP_ATTR_EVPN_H /* value of first byte of ESI */ -#define ESI_TYPE_ARBITRARY 0 /* */ -#define ESI_TYPE_LACP 1 /* <> */ -#define ESI_TYPE_BRIDGE 2 /* <Root bridge Mac-6B>:<Root Br Priority-2B>:00 */ -#define ESI_TYPE_MAC 3 /* <Syst Mac Add-6B>:<Local Discriminator Value-3B> */ -#define ESI_TYPE_ROUTER 4 /* <RouterId-4B>:<Local Discriminator Value-4B> */ -#define ESI_TYPE_AS 5 /* <AS-4B>:<Local Discriminator Value-4B> */ +#define ESI_TYPE_ARBITRARY 0 /* */ +#define ESI_TYPE_LACP 1 /* <> */ +#define ESI_TYPE_BRIDGE 2 /* <Root bridge Mac-6B>:<Root Br Priority-2B>:00 */ +#define ESI_TYPE_MAC 3 /* <Syst Mac Add-6B>:<Local Discriminator Value-3B> */ +#define ESI_TYPE_ROUTER 4 /* <RouterId-4B>:<Local Discriminator Value-4B> */ +#define ESI_TYPE_AS 5 /* <AS-4B>:<Local Discriminator Value-4B> */ #define MAX_ESI {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff} #define ESI_LEN 10 @@ -35,30 +35,29 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA u_long eth_tag_id; struct attr; -struct eth_segment_id -{ - u_char val[ESI_LEN]; +struct eth_segment_id { + u_char val[ESI_LEN]; }; #define MAC_LEN 6 union gw_addr { - struct in_addr ipv4; - struct in6_addr ipv6; + struct in_addr ipv4; + struct in6_addr ipv6; }; -struct bgp_route_evpn -{ - struct eth_segment_id eth_s_id; - union gw_addr gw_ip; +struct bgp_route_evpn { + struct eth_segment_id eth_s_id; + union gw_addr gw_ip; }; -extern int str2esi (const char *str, struct eth_segment_id *id); -extern int str2mac (const char *str, char *mac); -extern char *esi2str (struct eth_segment_id *id); -extern char *mac2str (char *mac); +extern int str2esi(const char *str, struct eth_segment_id *id); +extern int str2mac(const char *str, char *mac); +extern char *esi2str(struct eth_segment_id *id); +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 */ +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_evpn.c b/bgpd/bgp_evpn.c index b0b33c0b5..b9acbbed0 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -18,7 +18,6 @@ along with Free Range Routing; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - #include <zebra.h> #include "command.h" @@ -37,199 +36,190 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #include "bgpd/bgp_evpn.h" int -bgp_nlri_parse_evpn (struct peer *peer, struct attr *attr, - struct bgp_nlri *packet, int withdraw) +bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr, + struct bgp_nlri *packet, int withdraw) { - u_char *pnt; - u_char *lim; - struct prefix p; - struct prefix_rd prd; - struct evpn_addr *p_evpn_p; - struct bgp_route_evpn evpn; - uint8_t route_type, route_length; - u_char *pnt_label; - u_int32_t addpath_id = 0; - - /* Check peer status. */ - if (peer->status != Established) - return 0; - - /* Make prefix_rd */ - prd.family = AF_UNSPEC; - prd.prefixlen = 64; - - p_evpn_p = &p.u.prefix_evpn; - pnt = packet->nlri; - lim = pnt + packet->length; - while (pnt < lim) - { - /* clear evpn structure */ - memset (&evpn, 0, sizeof (evpn)); - - /* Clear prefix structure. */ - memset (&p, 0, sizeof (struct prefix)); - memset(&evpn.gw_ip, 0, sizeof(union gw_addr)); - memset(&evpn.eth_s_id, 0, sizeof(struct eth_segment_id)); - - /* Fetch Route Type */ - route_type = *pnt++; - route_length = *pnt++; - /* simply ignore. goto next route type if any */ - if(route_type != EVPN_IP_PREFIX) - { - if (pnt + route_length > lim) - { - zlog_err ("not enough bytes for New Route Type left in NLRI?"); - return -1; - } - pnt += route_length; - continue; + u_char *pnt; + u_char *lim; + struct prefix p; + struct prefix_rd prd; + struct evpn_addr *p_evpn_p; + struct bgp_route_evpn evpn; + uint8_t route_type, route_length; + u_char *pnt_label; + u_int32_t addpath_id = 0; + + /* Check peer status. */ + if (peer->status != Established) + return 0; + + /* Make prefix_rd */ + prd.family = AF_UNSPEC; + prd.prefixlen = 64; + + p_evpn_p = &p.u.prefix_evpn; + pnt = packet->nlri; + lim = pnt + packet->length; + while (pnt < lim) { + /* clear evpn structure */ + memset(&evpn, 0, sizeof(evpn)); + + /* Clear prefix structure. */ + memset(&p, 0, sizeof(struct prefix)); + memset(&evpn.gw_ip, 0, sizeof(union gw_addr)); + memset(&evpn.eth_s_id, 0, sizeof(struct eth_segment_id)); + + /* Fetch Route Type */ + route_type = *pnt++; + route_length = *pnt++; + /* simply ignore. goto next route type if any */ + if (route_type != EVPN_IP_PREFIX) { + if (pnt + route_length > lim) { + zlog_err + ("not enough bytes for New Route Type left in NLRI?"); + return -1; + } + pnt += route_length; + continue; + } + + /* Fetch RD */ + if (pnt + 8 > lim) { + zlog_err("not enough bytes for RD left in NLRI?"); + return -1; + } + + /* Copy routing distinguisher to rd. */ + memcpy(&prd.val, pnt, 8); + pnt += 8; + + /* Fetch ESI */ + if (pnt + 10 > lim) { + zlog_err("not enough bytes for ESI left in NLRI?"); + return -1; + } + memcpy(&evpn.eth_s_id.val, pnt, 10); + pnt += 10; + + /* Fetch Ethernet Tag */ + if (pnt + 4 > lim) { + zlog_err("not enough bytes for Eth Tag left in NLRI?"); + return -1; + } + + if (route_type == EVPN_IP_PREFIX) { + p_evpn_p->route_type = route_type; + memcpy(&(p_evpn_p->eth_tag), pnt, 4); + p_evpn_p->eth_tag = ntohl(p_evpn_p->eth_tag); + pnt += 4; + + /* Fetch IP prefix length. */ + p_evpn_p->ip_prefix_length = *pnt++; + + if (p_evpn_p->ip_prefix_length > 128) { + zlog_err("invalid prefixlen %d in EVPN NLRI?", + p.prefixlen); + return -1; + } + /* determine IPv4 or IPv6 prefix */ + if (route_length - 4 - 10 - 8 - + 3 /* label to be read */ >= 32) { + p_evpn_p->flags = IP_PREFIX_V6; + memcpy(&(p_evpn_p->ip.v4_addr), pnt, 16); + pnt += 16; + memcpy(&evpn.gw_ip.ipv6, pnt, 16); + pnt += 16; + } else { + p_evpn_p->flags = IP_PREFIX_V4; + memcpy(&(p_evpn_p->ip.v4_addr), pnt, 4); + pnt += 4; + memcpy(&evpn.gw_ip.ipv4, pnt, 4); + pnt += 4; + } + p.family = AFI_L2VPN; + if (p_evpn_p->flags == IP_PREFIX_V4) + p.prefixlen = + (u_char) PREFIX_LEN_ROUTE_TYPE_5_IPV4; + else + p.prefixlen = PREFIX_LEN_ROUTE_TYPE_5_IPV6; + p.family = AF_ETHERNET; + } + + /* Fetch Label */ + if (pnt + 3 > lim) { + zlog_err("not enough bytes for Label left in NLRI?"); + return -1; + } + pnt_label = pnt; + + pnt += 3; + + if (!withdraw) { + bgp_update(peer, &p, addpath_id, attr, AFI_L2VPN, + SAFI_EVPN, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, + &prd, pnt_label, 0, &evpn); + } else { + bgp_withdraw(peer, &p, addpath_id, attr, AFI_L2VPN, + SAFI_EVPN, ZEBRA_ROUTE_BGP, + BGP_ROUTE_NORMAL, &prd, pnt_label, &evpn); + } } - /* Fetch RD */ - if (pnt + 8 > lim) - { - zlog_err ("not enough bytes for RD left in NLRI?"); - return -1; - } - - /* Copy routing distinguisher to rd. */ - memcpy (&prd.val, pnt, 8); - pnt += 8; - - /* Fetch ESI */ - if (pnt + 10 > lim) - { - zlog_err ("not enough bytes for ESI left in NLRI?"); - return -1; - } - memcpy(&evpn.eth_s_id.val, pnt, 10); - pnt += 10; - - /* Fetch Ethernet Tag */ - if (pnt + 4 > lim) - { - zlog_err ("not enough bytes for Eth Tag left in NLRI?"); - return -1; - } - - if (route_type == EVPN_IP_PREFIX) - { - p_evpn_p->route_type = route_type; - memcpy (&(p_evpn_p->eth_tag), pnt, 4); - p_evpn_p->eth_tag = ntohl(p_evpn_p->eth_tag); - pnt += 4; - - /* Fetch IP prefix length. */ - p_evpn_p->ip_prefix_length = *pnt++; - - if (p_evpn_p->ip_prefix_length > 128) - { - zlog_err ("invalid prefixlen %d in EVPN NLRI?", p.prefixlen); - return -1; - } - /* determine IPv4 or IPv6 prefix */ - if(route_length - 4 - 10 - 8 - 3 /* label to be read */ >= 32) - { - p_evpn_p->flags = IP_PREFIX_V6; - memcpy (&(p_evpn_p->ip.v4_addr), pnt, 16); - pnt += 16; - memcpy(&evpn.gw_ip.ipv6, pnt, 16); - pnt += 16; - } - else - { - p_evpn_p->flags = IP_PREFIX_V4; - memcpy (&(p_evpn_p->ip.v4_addr), pnt, 4); - pnt += 4; - memcpy(&evpn.gw_ip.ipv4, pnt, 4); - pnt += 4; - } - p.family = AFI_L2VPN; - if (p_evpn_p->flags == IP_PREFIX_V4) - p.prefixlen = (u_char)PREFIX_LEN_ROUTE_TYPE_5_IPV4; - else - p.prefixlen = PREFIX_LEN_ROUTE_TYPE_5_IPV6; - p.family = AF_ETHERNET; - } - - /* Fetch Label */ - if (pnt + 3 > lim) - { - zlog_err ("not enough bytes for Label left in NLRI?"); - return -1; - } - pnt_label = pnt; - - pnt += 3; - - if (!withdraw) - { - bgp_update (peer, &p, addpath_id, attr, AFI_L2VPN, SAFI_EVPN, - ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, - pnt_label, 0, &evpn); - } - else - { - bgp_withdraw (peer, &p, addpath_id, attr, AFI_L2VPN, SAFI_EVPN, - ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, - &prd, pnt_label, &evpn); - } - } - - /* Packet length consistency check. */ - if (pnt != lim) - return -1; - return 0; + /* Packet length consistency check. */ + if (pnt != lim) + return -1; + return 0; } void -bgp_packet_mpattr_route_type_5 (struct stream *s, - struct prefix *p, struct prefix_rd *prd, - u_char *label, struct attr *attr) +bgp_packet_mpattr_route_type_5(struct stream *s, + struct prefix *p, struct prefix_rd *prd, + u_char * label, struct attr *attr) { - int len; - char temp[16]; - struct evpn_addr *p_evpn_p; - - memset(&temp, 0, 16); - if(p->family != AF_ETHERNET) - return; - p_evpn_p = &(p->u.prefix_evpn); - if (p_evpn_p->flags & IP_PREFIX_V4) - len = 8; /* ipv4 */ - else - len = 32; /* ipv6 */ - stream_putc (s, EVPN_IP_PREFIX); - stream_putc (s, 8 /* RD */ + 10 /* ESI */ + 4 /* EthTag */ + 1 + len + 3 /* label */); - stream_put (s, prd->val, 8); - if(attr && attr->extra) - stream_put (s, &(attr->extra->evpn_overlay.eth_s_id), 10); - else - stream_put (s, &temp, 10); - stream_putl (s, p_evpn_p->eth_tag); - stream_putc (s, p_evpn_p->ip_prefix_length); - if (p_evpn_p->flags & IP_PREFIX_V4) - stream_put_ipv4(s, p_evpn_p->ip.v4_addr.s_addr); - else - stream_put(s, &p_evpn_p->ip.v6_addr, 16); - if(attr && attr->extra) - { - if (p_evpn_p->flags & IP_PREFIX_V4) - stream_put_ipv4(s, attr->extra->evpn_overlay.gw_ip.ipv4.s_addr); - else - stream_put(s, &(attr->extra->evpn_overlay.gw_ip.ipv6), 16); - } - else - { - if (p_evpn_p->flags & IP_PREFIX_V4) - stream_put_ipv4(s, 0); - else - stream_put(s, &temp, 16); - } - if(label) - stream_put (s, label, 3); - else - stream_put3 (s, 0); - return; + int len; + char temp[16]; + struct evpn_addr *p_evpn_p; + + memset(&temp, 0, 16); + if (p->family != AF_ETHERNET) + return; + p_evpn_p = &(p->u.prefix_evpn); + if (p_evpn_p->flags & IP_PREFIX_V4) + len = 8; /* ipv4 */ + else + len = 32; /* ipv6 */ + stream_putc(s, EVPN_IP_PREFIX); + stream_putc(s, + 8 /* RD */ + 10 /* ESI */ + 4 /* EthTag */ + 1 + len + + 3 /* label */ ); + stream_put(s, prd->val, 8); + if (attr && attr->extra) + stream_put(s, &(attr->extra->evpn_overlay.eth_s_id), 10); + else + stream_put(s, &temp, 10); + stream_putl(s, p_evpn_p->eth_tag); + stream_putc(s, p_evpn_p->ip_prefix_length); + if (p_evpn_p->flags & IP_PREFIX_V4) + stream_put_ipv4(s, p_evpn_p->ip.v4_addr.s_addr); + else + stream_put(s, &p_evpn_p->ip.v6_addr, 16); + if (attr && attr->extra) { + if (p_evpn_p->flags & IP_PREFIX_V4) + stream_put_ipv4(s, + attr->extra->evpn_overlay.gw_ip.ipv4. + s_addr); + else + stream_put(s, &(attr->extra->evpn_overlay.gw_ip.ipv6), + 16); + } else { + if (p_evpn_p->flags & IP_PREFIX_V4) + stream_put_ipv4(s, 0); + else + stream_put(s, &temp, 16); + } + if (label) + stream_put(s, label, 3); + else + stream_put3(s, 0); + return; } diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h index d23509304..63c1a766e 100644 --- a/bgpd/bgp_evpn.h +++ b/bgpd/bgp_evpn.h @@ -21,13 +21,13 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #ifndef _QUAGGA_BGP_EVPN_H #define _QUAGGA_BGP_EVPN_H -extern int bgp_nlri_parse_evpn (struct peer *peer, struct attr *attr, - struct bgp_nlri *packet, int withdraw); +extern int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr, + struct bgp_nlri *packet, int withdraw); extern void -bgp_packet_mpattr_route_type_5 (struct stream *s, - struct prefix *p, struct prefix_rd *prd, - u_char *label, struct attr *attr); +bgp_packet_mpattr_route_type_5(struct stream *s, + struct prefix *p, struct prefix_rd *prd, + u_char * label, struct attr *attr); /* EVPN route types as per RFC7432 and * as per draft-ietf-bess-evpn-prefix-advertisement-02 */ @@ -37,4 +37,4 @@ bgp_packet_mpattr_route_type_5 (struct stream *s, #define EVPN_ETHERNET_SEGMENT 4 #define EVPN_IP_PREFIX 5 -#endif /* _QUAGGA_BGP_EVPN_H */ +#endif /* _QUAGGA_BGP_EVPN_H */ diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index bb144bfe4..ed67a61f6 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -37,626 +37,714 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #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, u_char use_json) +bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd, + enum bgp_show_type type, void *output_arg, int option, + u_char use_json) { - afi_t afi = AFI_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; - json_object *json = NULL; - json_object *json_nroute = NULL; - json_object *json_array = NULL; - json_object *json_scode = NULL; - json_object *json_ocode = NULL; - - bgp = bgp_get_default (); - if (bgp == NULL) - { - if (!use_json) - vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE); - return CMD_WARNING; - } - - if (use_json) - { - json_scode = json_object_new_object(); - json_ocode = json_object_new_object(); - json = json_object_new_object(); - json_nroute = json_object_new_object(); - - json_object_string_add(json_scode, "suppressed", "s"); - json_object_string_add(json_scode, "damped", "d"); - json_object_string_add(json_scode, "history", "h"); - json_object_string_add(json_scode, "valid", "*"); - json_object_string_add(json_scode, "best", ">"); - json_object_string_add(json_scode, "internal", "i"); - - json_object_string_add(json_ocode, "igp", "i"); - json_object_string_add(json_ocode, "egp", "e"); - json_object_string_add(json_ocode, "incomplete", "?"); - } - - for (rn = bgp_table_top (bgp->rib[afi][SAFI_EVPN]); rn; rn = bgp_route_next (rn)) - { - if (use_json) - continue; /* XXX json TODO */ - - 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 == 0) - { - if (use_json) - { - if (option == SHOW_DISPLAY_TAGS) - { - json_object_int_add(json, "bgpTableVersion", 0); - json_object_string_add(json, "bgpLocalRouterId", inet_ntoa (bgp->router_id)); - json_object_object_add(json, "bgpStatusCodes", json_scode); - json_object_object_add(json, "bgpOriginCodes", json_ocode); - } - } - else - { - 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); - if (use_json) - { - char buffer[BUFSIZ]; - if (type == RD_TYPE_AS || type == RD_TYPE_AS4) - sprintf (buffer, "%u:%d", rd_as.as, rd_as.val); - else if (type == RD_TYPE_IP) - sprintf (buffer, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val); - json_object_string_add(json_nroute, "routeDistinguisher", buffer); - } - else - { - 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 (use_json) - json_array = json_object_new_array(); - else - json_array = NULL; - if (option == SHOW_DISPLAY_TAGS) - route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_EVPN, json_array); - else if (option == SHOW_DISPLAY_OVERLAY) - route_vty_out_overlay (vty, &rm->p, ri, 0, json_array); - else - route_vty_out (vty, &rm->p, ri, 0, SAFI_EVPN, json_array); - output_count++; - } - /* XXX json */ - } - } - 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; + afi_t afi = AFI_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; + json_object *json = NULL; + json_object *json_nroute = NULL; + json_object *json_array = NULL; + json_object *json_scode = NULL; + json_object *json_ocode = NULL; + + bgp = bgp_get_default(); + if (bgp == NULL) { + if (!use_json) + vty_out(vty, "No BGP process is configured%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + if (use_json) { + json_scode = json_object_new_object(); + json_ocode = json_object_new_object(); + json = json_object_new_object(); + json_nroute = json_object_new_object(); + + json_object_string_add(json_scode, "suppressed", "s"); + json_object_string_add(json_scode, "damped", "d"); + json_object_string_add(json_scode, "history", "h"); + json_object_string_add(json_scode, "valid", "*"); + json_object_string_add(json_scode, "best", ">"); + json_object_string_add(json_scode, "internal", "i"); + + json_object_string_add(json_ocode, "igp", "i"); + json_object_string_add(json_ocode, "egp", "e"); + json_object_string_add(json_ocode, "incomplete", "?"); + } + + for (rn = bgp_table_top(bgp->rib[afi][SAFI_EVPN]); rn; + rn = bgp_route_next(rn)) { + if (use_json) + continue; /* XXX json TODO */ + + 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 == 0) { + if (use_json) { + if (option == + SHOW_DISPLAY_TAGS) { + json_object_int_add + (json, + "bgpTableVersion", + 0); + json_object_string_add + (json, + "bgpLocalRouterId", + inet_ntoa + (bgp-> + router_id)); + json_object_object_add + (json, + "bgpStatusCodes", + json_scode); + json_object_object_add + (json, + "bgpOriginCodes", + json_ocode); + } + } else { + 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); + if (use_json) { + char buffer[BUFSIZ]; + if (type == RD_TYPE_AS + || type == + RD_TYPE_AS4) + sprintf(buffer, + "%u:%d", + rd_as. + as, + rd_as. + val); + else if (type == + RD_TYPE_IP) + sprintf(buffer, + "%s:%d", + inet_ntoa + (rd_ip. + ip), + rd_ip. + val); + json_object_string_add + (json_nroute, + "routeDistinguisher", + buffer); + } else { + 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 (use_json) + json_array = + json_object_new_array(); + else + json_array = NULL; + if (option == SHOW_DISPLAY_TAGS) + route_vty_out_tag(vty, &rm->p, + ri, 0, + SAFI_EVPN, + json_array); + else if (option == SHOW_DISPLAY_OVERLAY) + route_vty_out_overlay(vty, + &rm->p, + ri, 0, + json_array); + else + route_vty_out(vty, &rm->p, ri, + 0, SAFI_EVPN, + json_array); + output_count++; + } + /* XXX json */ + } + } + 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_ip_bgp_l2vpn_evpn, - show_ip_bgp_l2vpn_evpn_cmd, - "show [ip] bgp l2vpn evpn [json]", - SHOW_STR - IP_STR - BGP_STR - L2VPN_HELP_STR - EVPN_HELP_STR - JSON_STR) +DEFUN(show_ip_bgp_l2vpn_evpn, + show_ip_bgp_l2vpn_evpn_cmd, + "show [ip] bgp l2vpn evpn [json]", + SHOW_STR IP_STR BGP_STR L2VPN_HELP_STR EVPN_HELP_STR JSON_STR) { - return bgp_show_ethernet_vpn (vty, NULL, bgp_show_type_normal, NULL, 0, use_json (argc, argv)); + return bgp_show_ethernet_vpn(vty, NULL, bgp_show_type_normal, NULL, 0, + use_json(argc, argv)); } -DEFUN (show_ip_bgp_l2vpn_evpn_rd, - show_ip_bgp_l2vpn_evpn_rd_cmd, - "show [ip] bgp l2vpn evpn rd ASN:nn_or_IP-address:nn [json]", - SHOW_STR - IP_STR - BGP_STR - L2VPN_HELP_STR - EVPN_HELP_STR - "Display information for a route distinguisher\n" - "VPN Route Distinguisher\n" - JSON_STR) +DEFUN(show_ip_bgp_l2vpn_evpn_rd, + show_ip_bgp_l2vpn_evpn_rd_cmd, + "show [ip] bgp l2vpn evpn rd ASN:nn_or_IP-address:nn [json]", + SHOW_STR + IP_STR + BGP_STR + L2VPN_HELP_STR + EVPN_HELP_STR + "Display information for a route distinguisher\n" + "VPN Route Distinguisher\n" JSON_STR) { - int idx_ext_community = 6; - int ret; - struct prefix_rd prd; - - ret = str2prefix_rd (argv[idx_ext_community]->arg, &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, 0, use_json (argc, argv)); + int idx_ext_community = 6; + int ret; + struct prefix_rd prd; + + ret = str2prefix_rd(argv[idx_ext_community]->arg, &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, 0, + use_json(argc, argv)); } -DEFUN (show_ip_bgp_l2vpn_evpn_all_tags, - show_ip_bgp_l2vpn_evpn_all_tags_cmd, - "show [ip] bgp l2vpn evpn all tags", - SHOW_STR - IP_STR - BGP_STR - L2VPN_HELP_STR - EVPN_HELP_STR - "Display information about all EVPN NLRIs\n" - "Display BGP tags for prefixes\n") +DEFUN(show_ip_bgp_l2vpn_evpn_all_tags, + show_ip_bgp_l2vpn_evpn_all_tags_cmd, + "show [ip] bgp l2vpn evpn all tags", + SHOW_STR + IP_STR + BGP_STR + L2VPN_HELP_STR + EVPN_HELP_STR + "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, 1, 0); + return bgp_show_ethernet_vpn(vty, NULL, bgp_show_type_normal, NULL, 1, + 0); } -DEFUN (show_ip_bgp_l2vpn_evpn_rd_tags, - show_ip_bgp_l2vpn_evpn_rd_tags_cmd, - "show [ip] bgp l2vpn evpn rd ASN:nn_or_IP-address:nn tags", - SHOW_STR - IP_STR - BGP_STR - L2VPN_HELP_STR - EVPN_HELP_STR - "Display information for a route distinguisher\n" - "VPN Route Distinguisher\n" - "Display BGP tags for prefixes\n") +DEFUN(show_ip_bgp_l2vpn_evpn_rd_tags, + show_ip_bgp_l2vpn_evpn_rd_tags_cmd, + "show [ip] bgp l2vpn evpn rd ASN:nn_or_IP-address:nn tags", + SHOW_STR + IP_STR + BGP_STR + L2VPN_HELP_STR + EVPN_HELP_STR + "Display information for a route distinguisher\n" + "VPN Route Distinguisher\n" "Display BGP tags for prefixes\n") { - int idx_ext_community = 6; - int ret; - struct prefix_rd prd; - - ret = str2prefix_rd (argv[idx_ext_community]->arg, &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, 1, 0); + int idx_ext_community = 6; + int ret; + struct prefix_rd prd; + + ret = str2prefix_rd(argv[idx_ext_community]->arg, &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, 1, + 0); } -DEFUN (show_ip_bgp_l2vpn_evpn_all_neighbor_routes, - show_ip_bgp_l2vpn_evpn_all_neighbor_routes_cmd, - "show [ip] bgp l2vpn evpn all neighbors A.B.C.D routes [json]", - SHOW_STR - IP_STR - BGP_STR - L2VPN_HELP_STR - EVPN_HELP_STR - "Display information about all EVPN NLRIs\n" - "Detailed information on TCP and BGP neighbor connections\n" - "Neighbor to display information about\n" - "Display routes learned from neighbor\n" - JSON_STR) +DEFUN(show_ip_bgp_l2vpn_evpn_all_neighbor_routes, + show_ip_bgp_l2vpn_evpn_all_neighbor_routes_cmd, + "show [ip] bgp l2vpn evpn all neighbors A.B.C.D routes [json]", + SHOW_STR + IP_STR + BGP_STR + L2VPN_HELP_STR + EVPN_HELP_STR + "Display information about all EVPN NLRIs\n" + "Detailed information on TCP and BGP neighbor connections\n" + "Neighbor to display information about\n" + "Display routes learned from neighbor\n" JSON_STR) { - int idx_ipv4 = 6; - union sockunion su; - struct peer *peer; - int ret; - u_char uj = use_json(argc, argv); - - ret = str2sockunion (argv[idx_ipv4]->arg, &su); - if (ret < 0) - { - if (uj) - { - json_object *json_no = NULL; - json_no = json_object_new_object(); - json_object_string_add(json_no, "warning", "Malformed address"); - vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); - json_object_free(json_no); - } - else - vty_out (vty, "Malformed address: %s%s", argv[idx_ipv4]->arg, VTY_NEWLINE); - return CMD_WARNING; - } - - peer = peer_lookup (NULL, &su); - if (! peer || ! peer->afc[AFI_L2VPN][SAFI_EVPN]) - { - if (uj) - { - json_object *json_no = NULL; - json_no = json_object_new_object(); - json_object_string_add(json_no, "warning", "No such neighbor or address family"); - vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); - json_object_free(json_no); - } - else - 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, 0, uj); + int idx_ipv4 = 6; + union sockunion su; + struct peer *peer; + int ret; + u_char uj = use_json(argc, argv); + + ret = str2sockunion(argv[idx_ipv4]->arg, &su); + if (ret < 0) { + if (uj) { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", + "Malformed address"); + vty_out(vty, "%s%s", + json_object_to_json_string(json_no), + VTY_NEWLINE); + json_object_free(json_no); + } else + vty_out(vty, "Malformed address: %s%s", + argv[idx_ipv4]->arg, VTY_NEWLINE); + return CMD_WARNING; + } + + peer = peer_lookup(NULL, &su); + if (!peer || !peer->afc[AFI_L2VPN][SAFI_EVPN]) { + if (uj) { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", + "No such neighbor or address family"); + vty_out(vty, "%s%s", + json_object_to_json_string(json_no), + VTY_NEWLINE); + json_object_free(json_no); + } else + 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, 0, + uj); } -DEFUN (show_ip_bgp_l2vpn_evpn_rd_neighbor_routes, - show_ip_bgp_l2vpn_evpn_rd_neighbor_routes_cmd, - "show [ip] bgp l2vpn evpn rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes [json]", - SHOW_STR - IP_STR - BGP_STR - L2VPN_HELP_STR - EVPN_HELP_STR - "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" - JSON_STR) +DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_routes, + show_ip_bgp_l2vpn_evpn_rd_neighbor_routes_cmd, + "show [ip] bgp l2vpn evpn rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes [json]", + SHOW_STR + IP_STR + BGP_STR + L2VPN_HELP_STR + EVPN_HELP_STR + "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" JSON_STR) { - int idx_ext_community = 6; - int idx_ipv4 = 8; - int ret; - union sockunion su; - struct peer *peer; - struct prefix_rd prd; - u_char uj = use_json(argc, argv); - - ret = str2prefix_rd (argv[idx_ext_community]->arg, &prd); - if (! ret) - { - if (uj) - { - json_object *json_no = NULL; - json_no = json_object_new_object(); - json_object_string_add(json_no, "warning", "Malformed Route Distinguisher"); - vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); - json_object_free(json_no); - } - else - vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); - return CMD_WARNING; - } - - ret = str2sockunion (argv[idx_ipv4]->arg, &su); - if (ret < 0) - { - if (uj) - { - json_object *json_no = NULL; - json_no = json_object_new_object(); - json_object_string_add(json_no, "warning", "Malformed address"); - vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); - json_object_free(json_no); - } - else - vty_out (vty, "Malformed address: %s%s", argv[idx_ext_community]->arg, VTY_NEWLINE); - return CMD_WARNING; - } - - peer = peer_lookup (NULL, &su); - if (! peer || ! peer->afc[AFI_L2VPN][SAFI_EVPN]) - { - if (uj) - { - json_object *json_no = NULL; - json_no = json_object_new_object(); - json_object_string_add(json_no, "warning", "No such neighbor or address family"); - vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); - json_object_free(json_no); - } - else - 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, 0, uj); + int idx_ext_community = 6; + int idx_ipv4 = 8; + int ret; + union sockunion su; + struct peer *peer; + struct prefix_rd prd; + u_char uj = use_json(argc, argv); + + ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd); + if (!ret) { + if (uj) { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", + "Malformed Route Distinguisher"); + vty_out(vty, "%s%s", + json_object_to_json_string(json_no), + VTY_NEWLINE); + json_object_free(json_no); + } else + vty_out(vty, "%% Malformed Route Distinguisher%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + ret = str2sockunion(argv[idx_ipv4]->arg, &su); + if (ret < 0) { + if (uj) { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", + "Malformed address"); + vty_out(vty, "%s%s", + json_object_to_json_string(json_no), + VTY_NEWLINE); + json_object_free(json_no); + } else + vty_out(vty, "Malformed address: %s%s", + argv[idx_ext_community]->arg, VTY_NEWLINE); + return CMD_WARNING; + } + + peer = peer_lookup(NULL, &su); + if (!peer || !peer->afc[AFI_L2VPN][SAFI_EVPN]) { + if (uj) { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", + "No such neighbor or address family"); + vty_out(vty, "%s%s", + json_object_to_json_string(json_no), + VTY_NEWLINE); + json_object_free(json_no); + } else + 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, 0, + uj); } -DEFUN (show_ip_bgp_l2vpn_evpn_all_neighbor_advertised_routes, - show_ip_bgp_l2vpn_evpn_all_neighbor_advertised_routes_cmd, - "show [ip] bgp l2vpn evpn all neighbors A.B.C.D advertised-routes [json]", - SHOW_STR - IP_STR - BGP_STR - L2VPN_HELP_STR - EVPN_HELP_STR - "Display information about all EVPN NLRIs\n" - "Detailed information on TCP and BGP neighbor connections\n" - "Neighbor to display information about\n" - "Display the routes advertised to a BGP neighbor\n" - JSON_STR) +DEFUN(show_ip_bgp_l2vpn_evpn_all_neighbor_advertised_routes, + show_ip_bgp_l2vpn_evpn_all_neighbor_advertised_routes_cmd, + "show [ip] bgp l2vpn evpn all neighbors A.B.C.D advertised-routes [json]", + SHOW_STR + IP_STR + BGP_STR + L2VPN_HELP_STR + EVPN_HELP_STR + "Display information about all EVPN NLRIs\n" + "Detailed information on TCP and BGP neighbor connections\n" + "Neighbor to display information about\n" + "Display the routes advertised to a BGP neighbor\n" JSON_STR) { - int idx_ipv4 = 7; - int ret; - struct peer *peer; - union sockunion su; - u_char uj = use_json(argc, argv); - - ret = str2sockunion (argv[idx_ipv4]->arg, &su); - if (ret < 0) - { - if (uj) - { - json_object *json_no = NULL; - json_no = json_object_new_object(); - json_object_string_add(json_no, "warning", "Malformed address"); - vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); - json_object_free(json_no); - } - else - vty_out (vty, "Malformed address: %s%s", argv[idx_ipv4]->arg, VTY_NEWLINE); - return CMD_WARNING; - } - peer = peer_lookup (NULL, &su); - if (! peer || ! peer->afc[AFI_L2VPN][SAFI_EVPN]) - { - if (uj) - { - json_object *json_no = NULL; - json_no = json_object_new_object(); - json_object_string_add(json_no, "warning", "No such neighbor or address family"); - vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); - json_object_free(json_no); - } - else - vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); - return CMD_WARNING; - } - - return show_adj_route_vpn (vty, peer, NULL, AFI_L2VPN, SAFI_EVPN, uj); + int idx_ipv4 = 7; + int ret; + struct peer *peer; + union sockunion su; + u_char uj = use_json(argc, argv); + + ret = str2sockunion(argv[idx_ipv4]->arg, &su); + if (ret < 0) { + if (uj) { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", + "Malformed address"); + vty_out(vty, "%s%s", + json_object_to_json_string(json_no), + VTY_NEWLINE); + json_object_free(json_no); + } else + vty_out(vty, "Malformed address: %s%s", + argv[idx_ipv4]->arg, VTY_NEWLINE); + return CMD_WARNING; + } + peer = peer_lookup(NULL, &su); + if (!peer || !peer->afc[AFI_L2VPN][SAFI_EVPN]) { + if (uj) { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", + "No such neighbor or address family"); + vty_out(vty, "%s%s", + json_object_to_json_string(json_no), + VTY_NEWLINE); + json_object_free(json_no); + } else + vty_out(vty, "%% No such neighbor or address family%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + return show_adj_route_vpn(vty, peer, NULL, AFI_L2VPN, SAFI_EVPN, uj); } -DEFUN (show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes, - show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes_cmd, - "show [ip] bgp l2vpn evpn rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes [json]", - SHOW_STR - IP_STR - BGP_STR - L2VPN_HELP_STR - EVPN_HELP_STR - "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" - JSON_STR) +DEFUN(show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes, + show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes_cmd, + "show [ip] bgp l2vpn evpn rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes [json]", + SHOW_STR + IP_STR + BGP_STR + L2VPN_HELP_STR + EVPN_HELP_STR + "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" JSON_STR) { - int idx_ext_community = 6; - int idx_ipv4 = 8; - int ret; - struct peer *peer; - struct prefix_rd prd; - union sockunion su; - u_char uj = use_json(argc, argv); - - ret = str2sockunion (argv[idx_ipv4]->arg, &su); - if (ret < 0) - { - if (uj) - { - json_object *json_no = NULL; - json_no = json_object_new_object(); - json_object_string_add(json_no, "warning", "Malformed address"); - vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); - json_object_free(json_no); - } - else - vty_out (vty, "Malformed address: %s%s", argv[idx_ext_community]->arg, VTY_NEWLINE); - return CMD_WARNING; - } - peer = peer_lookup (NULL, &su); - if (! peer || ! peer->afc[AFI_L2VPN][SAFI_EVPN]) - { - if (uj) - { - json_object *json_no = NULL; - json_no = json_object_new_object(); - json_object_string_add(json_no, "warning", "No such neighbor or address family"); - vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); - json_object_free(json_no); - } - else - vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); - return CMD_WARNING; - } - - ret = str2prefix_rd (argv[idx_ext_community]->arg, &prd); - if (! ret) - { - if (uj) - { - json_object *json_no = NULL; - json_no = json_object_new_object(); - json_object_string_add(json_no, "warning", "Malformed Route Distinguisher"); - vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); - json_object_free(json_no); - } - else - vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); - return CMD_WARNING; - } - - return show_adj_route_vpn (vty, peer, &prd, AFI_L2VPN, SAFI_EVPN, uj); + int idx_ext_community = 6; + int idx_ipv4 = 8; + int ret; + struct peer *peer; + struct prefix_rd prd; + union sockunion su; + u_char uj = use_json(argc, argv); + + ret = str2sockunion(argv[idx_ipv4]->arg, &su); + if (ret < 0) { + if (uj) { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", + "Malformed address"); + vty_out(vty, "%s%s", + json_object_to_json_string(json_no), + VTY_NEWLINE); + json_object_free(json_no); + } else + vty_out(vty, "Malformed address: %s%s", + argv[idx_ext_community]->arg, VTY_NEWLINE); + return CMD_WARNING; + } + peer = peer_lookup(NULL, &su); + if (!peer || !peer->afc[AFI_L2VPN][SAFI_EVPN]) { + if (uj) { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", + "No such neighbor or address family"); + vty_out(vty, "%s%s", + json_object_to_json_string(json_no), + VTY_NEWLINE); + json_object_free(json_no); + } else + vty_out(vty, "%% No such neighbor or address family%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + ret = str2prefix_rd(argv[idx_ext_community]->arg, &prd); + if (!ret) { + if (uj) { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", + "Malformed Route Distinguisher"); + vty_out(vty, "%s%s", + json_object_to_json_string(json_no), + VTY_NEWLINE); + json_object_free(json_no); + } else + vty_out(vty, "%% Malformed Route Distinguisher%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + return show_adj_route_vpn(vty, peer, &prd, AFI_L2VPN, SAFI_EVPN, uj); } -DEFUN (show_ip_bgp_l2vpn_evpn_all_overlay, - show_ip_bgp_l2vpn_evpn_all_overlay_cmd, - "show [ip] bgp l2vpn evpn all overlay", - SHOW_STR - IP_STR - BGP_STR - L2VPN_HELP_STR - EVPN_HELP_STR - "Display information about all EVPN NLRIs\n" - "Display BGP Overlay Information for prefixes\n") +DEFUN(show_ip_bgp_l2vpn_evpn_all_overlay, + show_ip_bgp_l2vpn_evpn_all_overlay_cmd, + "show [ip] bgp l2vpn evpn all overlay", + SHOW_STR + IP_STR + BGP_STR + L2VPN_HELP_STR + EVPN_HELP_STR + "Display information about all EVPN NLRIs\n" + "Display BGP Overlay Information for prefixes\n") { - return bgp_show_ethernet_vpn (vty, NULL, bgp_show_type_normal, NULL, - SHOW_DISPLAY_OVERLAY, use_json (argc, argv)); + return bgp_show_ethernet_vpn(vty, NULL, bgp_show_type_normal, NULL, + SHOW_DISPLAY_OVERLAY, use_json(argc, + argv)); } -DEFUN (show_ip_bgp_evpn_rd_overlay, - show_ip_bgp_evpn_rd_overlay_cmd, - "show [ip] bgp l2vpn evpn rd ASN:nn_or_IP-address:nn overlay", - SHOW_STR - IP_STR - BGP_STR - L2VPN_HELP_STR - EVPN_HELP_STR - "Display information for a route distinguisher\n" - "VPN Route Distinguisher\n" - "Display BGP Overlay Information for prefixes\n") +DEFUN(show_ip_bgp_evpn_rd_overlay, + show_ip_bgp_evpn_rd_overlay_cmd, + "show [ip] bgp l2vpn evpn rd ASN:nn_or_IP-address:nn overlay", + SHOW_STR + IP_STR + BGP_STR + L2VPN_HELP_STR + EVPN_HELP_STR + "Display information for a route distinguisher\n" + "VPN Route Distinguisher\n" + "Display BGP Overlay Information for prefixes\n") { - int idx_ext_community = 6; - int ret; - struct prefix_rd prd; - - ret = str2prefix_rd (argv[idx_ext_community]->arg, &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, use_json (argc, argv)); + int idx_ext_community = 6; + int ret; + struct prefix_rd prd; + + ret = str2prefix_rd(argv[idx_ext_community]->arg, &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, 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") +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); + 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") +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); + 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) +void bgp_ethernetvpn_init(void) { - install_element (VIEW_NODE, &show_ip_bgp_l2vpn_evpn_cmd); - install_element (VIEW_NODE, &show_ip_bgp_l2vpn_evpn_rd_cmd); - install_element (VIEW_NODE, &show_ip_bgp_l2vpn_evpn_all_tags_cmd); - install_element (VIEW_NODE, &show_ip_bgp_l2vpn_evpn_rd_tags_cmd); - install_element (VIEW_NODE, &show_ip_bgp_l2vpn_evpn_all_neighbor_routes_cmd); - install_element (VIEW_NODE, &show_ip_bgp_l2vpn_evpn_rd_neighbor_routes_cmd); - install_element (VIEW_NODE, &show_ip_bgp_l2vpn_evpn_all_neighbor_advertised_routes_cmd); - 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); + install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_cmd); + install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_rd_cmd); + install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_all_tags_cmd); + install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_rd_tags_cmd); + install_element(VIEW_NODE, + &show_ip_bgp_l2vpn_evpn_all_neighbor_routes_cmd); + install_element(VIEW_NODE, + &show_ip_bgp_l2vpn_evpn_rd_neighbor_routes_cmd); + install_element(VIEW_NODE, + &show_ip_bgp_l2vpn_evpn_all_neighbor_advertised_routes_cmd); + 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_evpn_vty.h b/bgpd/bgp_evpn_vty.h index ed654d90b..11e93a528 100644 --- a/bgpd/bgp_evpn_vty.h +++ b/bgpd/bgp_evpn_vty.h @@ -21,11 +21,9 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #ifndef _FRR_BGP_EVPN_VTY_H #define _FRR_BGP_EVPN_VTY_H -extern void -bgp_ethernetvpn_init (void); +extern void bgp_ethernetvpn_init(void); #define L2VPN_HELP_STR "Layer 2 Virtual Private Network\n" #define EVPN_HELP_STR "Ethernet Virtual Private Network\n" - -#endif /* _QUAGGA_BGP_EVPN_VTY_H */ +#endif /* _QUAGGA_BGP_EVPN_VTY_H */ |