diff options
Diffstat (limited to 'bgpd/bgp_attr_evpn.c')
| -rw-r--r-- | bgpd/bgp_attr_evpn.c | 236 |
1 files changed, 117 insertions, 119 deletions
diff --git a/bgpd/bgp_attr_evpn.c b/bgpd/bgp_attr_evpn.c index aa175bcf51..cd6b87b299 100644 --- a/bgpd/bgp_attr_evpn.c +++ b/bgpd/bgp_attr_evpn.c @@ -37,16 +37,16 @@ void bgp_add_routermac_ecom(struct attr *attr, struct ethaddr *routermac) { - struct ecommunity_val routermac_ecom; - - 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->octet, ETHER_ADDR_LEN); - if (!attr->ecommunity) - attr->ecommunity = ecommunity_new(); - ecommunity_add_val(attr->ecommunity, &routermac_ecom); - ecommunity_str (attr->ecommunity); + struct ecommunity_val routermac_ecom; + + 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->octet, ETHER_ADDR_LEN); + if (!attr->ecommunity) + attr->ecommunity = ecommunity_new(); + ecommunity_add_val(attr->ecommunity, &routermac_ecom); + ecommunity_str(attr->ecommunity); } /* converts to an esi @@ -56,138 +56,136 @@ void bgp_add_routermac_ecom(struct attr *attr, struct ethaddr *routermac) */ int str2esi(const char *str, struct eth_segment_id *id) { - unsigned int a[ESI_LEN]; - int i; - - if (!str) - return 0; - if (sscanf (str, "%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x", - a + 0, a + 1, a + 2, a + 3, a + 4, a + 5, - a + 6, a + 7, a + 8, a + 9) != ESI_LEN) - { - /* error in incoming str length */ - return 0; - } - /* valid mac address */ - if (!id) - return 1; - for (i = 0; i < ESI_LEN; ++i) - id->val[i] = a[i] & 0xff; - return 1; + unsigned int a[ESI_LEN]; + int i; + + if (!str) + return 0; + if (sscanf(str, "%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x:%2x", a + 0, a + 1, + a + 2, a + 3, a + 4, a + 5, a + 6, a + 7, a + 8, a + 9) + != ESI_LEN) { + /* error in incoming str length */ + return 0; + } + /* valid mac address */ + if (!id) + return 1; + for (i = 0; i < ESI_LEN; ++i) + id->val[i] = a[i] & 0xff; + return 1; } 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 *)XMALLOC(MTYPE_TMP, (ESI_LEN * 2 + ESI_LEN - 1 + 1) * sizeof(char)); + val = id->val; + ptr = (char *)XMALLOC(MTYPE_TMP, + (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 *ecom_mac2str(char *ecom_mac) { - char *en; + char *en; - en = ecom_mac; - en += 2; + en = ecom_mac; + en += 2; - return prefix_mac2str((struct ethaddr *)en, NULL, 0); + return prefix_mac2str((struct ethaddr *)en, NULL, 0); } /* * Fetch and return the sequence number from MAC Mobility extended * community, if present, else 0. */ -u_int32_t -bgp_attr_mac_mobility_seqnum (struct attr *attr, u_char *sticky) +u_int32_t bgp_attr_mac_mobility_seqnum(struct attr *attr, u_char *sticky) { - struct ecommunity *ecom; - int i; - u_char flags = 0; - - ecom = attr->ecommunity; - if (!ecom || !ecom->size) - return 0; - - /* If there is a MAC Mobility extended community, return its - * sequence number. - * TODO: RFC is silent on handling of multiple MAC mobility extended - * communities for the same route. We will bail out upon the first - * one. - */ - for (i = 0; i < ecom->size; i++) - { - u_char *pnt; - u_char type, sub_type; - u_int32_t seq_num; - - pnt = (ecom->val + (i * ECOMMUNITY_SIZE)); - type = *pnt++; - sub_type = *pnt++; - if (!(type == ECOMMUNITY_ENCODE_EVPN && - sub_type == ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY)) - continue; - flags = *pnt++; - - if (flags & ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY_FLAG_STICKY) - *sticky = 1; - else - *sticky = 0; - - pnt++; - seq_num = (*pnt++ << 24); - seq_num |= (*pnt++ << 16); - seq_num |= (*pnt++ << 8); - seq_num |= (*pnt++); - - return seq_num; - } - - return 0; + struct ecommunity *ecom; + int i; + u_char flags = 0; + + ecom = attr->ecommunity; + if (!ecom || !ecom->size) + return 0; + + /* If there is a MAC Mobility extended community, return its + * sequence number. + * TODO: RFC is silent on handling of multiple MAC mobility extended + * communities for the same route. We will bail out upon the first + * one. + */ + for (i = 0; i < ecom->size; i++) { + u_char *pnt; + u_char type, sub_type; + u_int32_t seq_num; + + pnt = (ecom->val + (i * ECOMMUNITY_SIZE)); + type = *pnt++; + sub_type = *pnt++; + if (!(type == ECOMMUNITY_ENCODE_EVPN + && sub_type == ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY)) + continue; + flags = *pnt++; + + if (flags & ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY_FLAG_STICKY) + *sticky = 1; + else + *sticky = 0; + + pnt++; + seq_num = (*pnt++ << 24); + seq_num |= (*pnt++ << 16); + seq_num |= (*pnt++ << 8); + seq_num |= (*pnt++); + + return seq_num; + } + + return 0; } /* 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; - - 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 == BGP_EVPN_IP_PREFIX_ROUTE) { - p_evpn_p->eth_tag = eth_tag; - p_evpn_p->ip_prefix_length = p2.prefixlen; - if (src->family == AF_INET) { - SET_IPADDR_V4 (&p_evpn_p->ip); - memcpy(&p_evpn_p->ip.ipaddr_v4, &src->u.prefix4, - sizeof(struct in_addr)); - dst->prefixlen = (u_char) PREFIX_LEN_ROUTE_TYPE_5_IPV4; - } else { - SET_IPADDR_V6 (&p_evpn_p->ip); - memcpy(&p_evpn_p->ip.ipaddr_v6, &src->u.prefix6, - sizeof(struct in6_addr)); - dst->prefixlen = (u_char) PREFIX_LEN_ROUTE_TYPE_5_IPV6; - } - } else - return -1; - return 0; + 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 == BGP_EVPN_IP_PREFIX_ROUTE) { + p_evpn_p->eth_tag = eth_tag; + p_evpn_p->ip_prefix_length = p2.prefixlen; + if (src->family == AF_INET) { + SET_IPADDR_V4(&p_evpn_p->ip); + memcpy(&p_evpn_p->ip.ipaddr_v4, &src->u.prefix4, + sizeof(struct in_addr)); + dst->prefixlen = (u_char)PREFIX_LEN_ROUTE_TYPE_5_IPV4; + } else { + SET_IPADDR_V6(&p_evpn_p->ip); + memcpy(&p_evpn_p->ip.ipaddr_v6, &src->u.prefix6, + sizeof(struct in6_addr)); + dst->prefixlen = (u_char)PREFIX_LEN_ROUTE_TYPE_5_IPV6; + } + } else + return -1; + return 0; } |
