bgpd: rmac ext comm

Signed-off-by: Mitesh Kanjariya <mitesh@cumulusnetworks.com>
This commit is contained in:
Mitesh Kanjariya 2017-10-09 04:55:57 -07:00 committed by Mitesh Kanjariya
parent 23a06e1170
commit bc59a6720c
7 changed files with 69 additions and 11 deletions

View File

@ -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->mm_seqnum = bgp_attr_mac_mobility_seqnum(attr, &sticky);
attr->sticky = sticky; attr->sticky = sticky;
/* Extract the Rmac, if any */
bgp_attr_rmac(attr, &attr->rmac);
return BGP_ATTR_PARSE_PROCEED; return BGP_ATTR_PARSE_PROCEED;
} }

View File

@ -182,6 +182,9 @@ struct attr {
/* EVPN MAC Mobility sequence number, if any. */ /* EVPN MAC Mobility sequence number, if any. */
u_int32_t mm_seqnum; u_int32_t mm_seqnum;
/* EVPN local router-mac */
struct ethaddr rmac;
}; };
/* rmap_change_flags definition */ /* rmap_change_flags definition */

View File

@ -105,6 +105,35 @@ char *ecom_mac2str(char *ecom_mac)
return prefix_mac2str((struct ethaddr *)en, NULL, 0); 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 * Fetch and return the sequence number from MAC Mobility extended
* community, if present, else 0. * community, if present, else 0.

View File

@ -59,7 +59,7 @@ extern void bgp_add_routermac_ecom(struct attr *attr,
struct ethaddr *routermac); struct ethaddr *routermac);
extern int bgp_build_evpn_prefix(int type, uint32_t eth_tag, extern int bgp_build_evpn_prefix(int type, uint32_t eth_tag,
struct prefix *dst); 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, extern u_int32_t bgp_attr_mac_mobility_seqnum(struct attr *attr,
u_char *sticky); u_char *sticky);

View File

@ -695,19 +695,19 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
} else if (type == ECOMMUNITY_ENCODE_EVPN) { } else if (type == ECOMMUNITY_ENCODE_EVPN) {
if (filter == ECOMMUNITY_ROUTE_TARGET) if (filter == ECOMMUNITY_ROUTE_TARGET)
continue; continue;
if (*pnt == ECOMMUNITY_SITE_ORIGIN) { if (*pnt == ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC) {
char macaddr[6]; struct ethaddr rmac;
pnt++; pnt++;
memcpy(&macaddr, pnt, 6); memcpy(&rmac, pnt, ETH_ALEN);
len = sprintf( len = sprintf(
str_buf + str_pnt, str_buf + str_pnt,
"EVPN:%02x:%02x:%02x:%02x:%02x:%02x", "Rmac:%02x:%02x:%02x:%02x:%02x:%02x",
(uint8_t)macaddr[0], (uint8_t)rmac.octet[0],
(uint8_t)macaddr[1], (uint8_t)rmac.octet[1],
(uint8_t)macaddr[2], (uint8_t)rmac.octet[2],
(uint8_t)macaddr[3], (uint8_t)rmac.octet[3],
(uint8_t)macaddr[4], (uint8_t)rmac.octet[4],
(uint8_t)macaddr[5]); (uint8_t)rmac.octet[5]);
} else if (*pnt } else if (*pnt
== ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY) { == ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY) {
u_int32_t seqnum; u_int32_t seqnum;

View File

@ -433,8 +433,10 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr)
{ {
struct ecommunity ecom_encap; struct ecommunity ecom_encap;
struct ecommunity ecom_sticky; struct ecommunity ecom_sticky;
struct ecommunity ecom_rmac;
struct ecommunity_val eval; struct ecommunity_val eval;
struct ecommunity_val eval_sticky; struct ecommunity_val eval_sticky;
struct ecommunity_val eval_rmac;
bgp_encap_types tnl_type; bgp_encap_types tnl_type;
struct listnode *node, *nnode; struct listnode *node, *nnode;
struct ecommunity *ecom; 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); 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); 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_global_in = vpn->originator_ip;
attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
attr.sticky = CHECK_FLAG(flags, ZEBRA_MAC_TYPE_STICKY) ? 1 : 0; attr.sticky = CHECK_FLAG(flags, ZEBRA_MAC_TYPE_STICKY) ? 1 : 0;
bgpevpn_get_rmac(vpn, &attr.rmac);
/* Set up RT and ENCAP extended community. */ /* Set up RT and ENCAP extended community. */
build_evpn_route_extcomm(vpn, &attr); 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.nexthop = vpn->originator_ip;
attr.mp_nexthop_global_in = vpn->originator_ip; attr.mp_nexthop_global_in = vpn->originator_ip;
attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
bgpevpn_get_rmac(vpn, &attr.rmac);
attr_sticky.nexthop = vpn->originator_ip; attr_sticky.nexthop = vpn->originator_ip;
attr_sticky.mp_nexthop_global_in = vpn->originator_ip; attr_sticky.mp_nexthop_global_in = vpn->originator_ip;
attr_sticky.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; attr_sticky.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
attr_sticky.sticky = 1; attr_sticky.sticky = 1;
bgpevpn_get_rmac(vpn, &attr_sticky.rmac);
/* Set up RT, ENCAP and sticky MAC extended community. */ /* Set up RT, ENCAP and sticky MAC extended community. */
build_evpn_route_extcomm(vpn, &attr); build_evpn_route_extcomm(vpn, &attr);

View File

@ -222,6 +222,15 @@ static inline vni_t label2vni(mpls_label_t *label)
return vni; 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, static inline void encode_mac_mobility_extcomm(int static_mac, u_int32_t seq,
struct ecommunity_val *eval) struct ecommunity_val *eval)
{ {