mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 23:53:28 +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->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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
|
@ -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.
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user