mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-15 05:18:47 +00:00
bgpd: rmac ext comm
Signed-off-by: Mitesh Kanjariya <mitesh@cumulusnetworks.com>
This commit is contained in:
parent
23a06e1170
commit
bc59a6720c
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user