From: Mitesh Kanjariya Date: Mon, 9 Oct 2017 11:55:57 +0000 (-0700) Subject: bgpd: rmac ext comm X-Git-Tag: frr-4.0-dev~58^2~65 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=bc59a6720c51482ff41f0f1f903ef9370dcd01cf;p=matthieu%2Ffrr.git bgpd: rmac ext comm Signed-off-by: Mitesh Kanjariya --- diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index e80889500f..da6042d340 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1879,6 +1879,9 @@ bgp_attr_ext_communities(struct bgp_attr_parser_args *args) attr->mm_seqnum = bgp_attr_mac_mobility_seqnum(attr, &sticky); attr->sticky = sticky; + /* Extract the Rmac, if any */ + bgp_attr_rmac(attr, &attr->rmac); + return BGP_ATTR_PARSE_PROCEED; } diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h index f694f01adb..1de1bee0f9 100644 --- a/bgpd/bgp_attr.h +++ b/bgpd/bgp_attr.h @@ -182,6 +182,9 @@ struct attr { /* EVPN MAC Mobility sequence number, if any. */ u_int32_t mm_seqnum; + + /* EVPN local router-mac */ + struct ethaddr rmac; }; /* rmap_change_flags definition */ diff --git a/bgpd/bgp_attr_evpn.c b/bgpd/bgp_attr_evpn.c index 300c9ddb50..eaa4e329d4 100644 --- a/bgpd/bgp_attr_evpn.c +++ b/bgpd/bgp_attr_evpn.c @@ -105,6 +105,35 @@ char *ecom_mac2str(char *ecom_mac) return prefix_mac2str((struct ethaddr *)en, NULL, 0); } +/* Fetch router-mac from extended community */ +void bgp_attr_rmac(struct attr *attr, + struct ethaddr *rmac) +{ + int i = 0; + struct ecommunity *ecom; + + ecom = attr->ecommunity; + if (!ecom || !ecom->size) + return; + + /* If there is a router mac extended community, set RMAC in attr */ + for (i = 0; i < ecom->size; i++) { + u_char *pnt = NULL; + u_char type = 0; + u_char sub_type = 0; + + pnt = (ecom->val + (i * ECOMMUNITY_SIZE)); + type = *pnt++; + sub_type = *pnt++; + + if (!(type == ECOMMUNITY_ENCODE_EVPN && + sub_type == ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC)) + continue; + + memcpy(rmac, pnt, ETH_ALEN); + } +} + /* * Fetch and return the sequence number from MAC Mobility extended * community, if present, else 0. diff --git a/bgpd/bgp_attr_evpn.h b/bgpd/bgp_attr_evpn.h index 15d9e126e4..8b55cb3002 100644 --- a/bgpd/bgp_attr_evpn.h +++ b/bgpd/bgp_attr_evpn.h @@ -59,7 +59,7 @@ extern void bgp_add_routermac_ecom(struct attr *attr, struct ethaddr *routermac); extern int bgp_build_evpn_prefix(int type, uint32_t eth_tag, struct prefix *dst); - +extern void bgp_attr_rmac(struct attr *attr, struct ethaddr *rmac); extern u_int32_t bgp_attr_mac_mobility_seqnum(struct attr *attr, u_char *sticky); diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c index e19f516505..9caf38d569 100644 --- a/bgpd/bgp_ecommunity.c +++ b/bgpd/bgp_ecommunity.c @@ -695,19 +695,19 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter) } else if (type == ECOMMUNITY_ENCODE_EVPN) { if (filter == ECOMMUNITY_ROUTE_TARGET) continue; - if (*pnt == ECOMMUNITY_SITE_ORIGIN) { - char macaddr[6]; + if (*pnt == ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC) { + struct ethaddr rmac; pnt++; - memcpy(&macaddr, pnt, 6); + memcpy(&rmac, pnt, ETH_ALEN); len = sprintf( str_buf + str_pnt, - "EVPN:%02x:%02x:%02x:%02x:%02x:%02x", - (uint8_t)macaddr[0], - (uint8_t)macaddr[1], - (uint8_t)macaddr[2], - (uint8_t)macaddr[3], - (uint8_t)macaddr[4], - (uint8_t)macaddr[5]); + "Rmac:%02x:%02x:%02x:%02x:%02x:%02x", + (uint8_t)rmac.octet[0], + (uint8_t)rmac.octet[1], + (uint8_t)rmac.octet[2], + (uint8_t)rmac.octet[3], + (uint8_t)rmac.octet[4], + (uint8_t)rmac.octet[5]); } else if (*pnt == ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY) { u_int32_t seqnum; diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index b625297ac1..64b2501705 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -433,8 +433,10 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr) { struct ecommunity ecom_encap; struct ecommunity ecom_sticky; + struct ecommunity ecom_rmac; struct ecommunity_val eval; struct ecommunity_val eval_sticky; + struct ecommunity_val eval_rmac; bgp_encap_types tnl_type; struct listnode *node, *nnode; struct ecommunity *ecom; @@ -473,6 +475,15 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr) ecommunity_merge(attr->ecommunity, &ecom_sticky); } + if (!is_zero_mac(&attr->rmac)) { + memset(&ecom_rmac, 0, sizeof(ecom_rmac)); + encode_rmac_extcomm(&eval_rmac, &attr->rmac); + ecom_rmac.size = 1; + ecom_rmac.val = (uint8_t *)eval_rmac.val; + attr->ecommunity = ecommunity_merge(attr->ecommunity, + &ecom_rmac); + } + attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES); } @@ -843,6 +854,7 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn, attr.mp_nexthop_global_in = vpn->originator_ip; attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; attr.sticky = CHECK_FLAG(flags, ZEBRA_MAC_TYPE_STICKY) ? 1 : 0; + bgpevpn_get_rmac(vpn, &attr.rmac); /* Set up RT and ENCAP extended community. */ build_evpn_route_extcomm(vpn, &attr); @@ -989,10 +1001,12 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn) attr.nexthop = vpn->originator_ip; attr.mp_nexthop_global_in = vpn->originator_ip; attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; + bgpevpn_get_rmac(vpn, &attr.rmac); attr_sticky.nexthop = vpn->originator_ip; attr_sticky.mp_nexthop_global_in = vpn->originator_ip; attr_sticky.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; attr_sticky.sticky = 1; + bgpevpn_get_rmac(vpn, &attr_sticky.rmac); /* Set up RT, ENCAP and sticky MAC extended community. */ build_evpn_route_extcomm(vpn, &attr); diff --git a/bgpd/bgp_evpn_private.h b/bgpd/bgp_evpn_private.h index e11f99f099..b983a00a76 100644 --- a/bgpd/bgp_evpn_private.h +++ b/bgpd/bgp_evpn_private.h @@ -222,6 +222,15 @@ static inline vni_t label2vni(mpls_label_t *label) return vni; } +static inline void encode_rmac_extcomm(struct ecommunity_val *eval, + struct ethaddr *rmac) +{ + memset(eval, 0, sizeof(*eval)); + eval->val[0] = ECOMMUNITY_ENCODE_EVPN; + eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC; + memcpy(&eval->val[2], rmac, ETH_ALEN); +} + static inline void encode_mac_mobility_extcomm(int static_mac, u_int32_t seq, struct ecommunity_val *eval) {