Merge pull request #16334 from opensourcerouting/fix/move_sticky_default_gw_to_evpn_flags

bgpd: Move sticky, default_gw, router_flag into a single flags variable
This commit is contained in:
Donald Sharp 2024-07-05 08:41:31 -04:00 committed by GitHub
commit 20ec1cce53
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 61 additions and 59 deletions

View File

@ -2575,7 +2575,6 @@ bgp_attr_ext_communities(struct bgp_attr_parser_args *args)
struct peer *const peer = args->peer; struct peer *const peer = args->peer;
struct attr *const attr = args->attr; struct attr *const attr = args->attr;
const bgp_size_t length = args->length; const bgp_size_t length = args->length;
uint8_t sticky = 0;
bool proxy = false; bool proxy = false;
struct ecommunity *ecomm; struct ecommunity *ecomm;
@ -2605,21 +2604,20 @@ bgp_attr_ext_communities(struct bgp_attr_parser_args *args)
attr->df_pref = bgp_attr_df_pref_from_ec(attr, &attr->df_alg); attr->df_pref = bgp_attr_df_pref_from_ec(attr, &attr->df_alg);
/* Extract MAC mobility sequence number, if any. */ /* Extract MAC mobility sequence number, if any. */
attr->mm_seqnum = bgp_attr_mac_mobility_seqnum(attr, &sticky); attr->mm_seqnum = bgp_attr_mac_mobility_seqnum(attr);
attr->sticky = sticky;
/* Check if this is a Gateway MAC-IP advertisement */ /* Check if this is a Gateway MAC-IP advertisement */
attr->default_gw = bgp_attr_default_gw(attr); bgp_attr_default_gw(attr);
/* Handle scenario where router flag ecommunity is not /* Handle scenario where router flag ecommunity is not
* set but default gw ext community is present. * set but default gw ext community is present.
* Use default gateway, set and propogate R-bit. * Use default gateway, set and propogate R-bit.
*/ */
if (attr->default_gw) if (CHECK_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_DEFAULT_GW))
attr->router_flag = 1; SET_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_ROUTER);
/* Check EVPN Neighbor advertisement flags, R-bit */ /* Check EVPN Neighbor advertisement flags, R-bit */
bgp_attr_evpn_na_flag(attr, &attr->router_flag, &proxy); bgp_attr_evpn_na_flag(attr, &proxy);
if (proxy) if (proxy)
attr->es_flags |= ATTR_ES_PROXY_ADVERT; attr->es_flags |= ATTR_ES_PROXY_ADVERT;

View File

@ -197,9 +197,6 @@ struct attr {
#define ATTR_ES_L3_NHG_ACTIVE (1 << 6) #define ATTR_ES_L3_NHG_ACTIVE (1 << 6)
#define ATTR_ES_L3_NHG (ATTR_ES_L3_NHG_USE | ATTR_ES_L3_NHG_ACTIVE) #define ATTR_ES_L3_NHG (ATTR_ES_L3_NHG_USE | ATTR_ES_L3_NHG_ACTIVE)
/* NA router flag (R-bit) support in EVPN */
uint8_t router_flag;
/* Distance as applied by Route map */ /* Distance as applied by Route map */
uint8_t distance; uint8_t distance;
@ -256,11 +253,12 @@ struct attr {
/* MP Nexthop length */ /* MP Nexthop length */
uint8_t mp_nexthop_len; uint8_t mp_nexthop_len;
/* Static MAC for EVPN */ /* EVPN flags */
uint8_t sticky; uint8_t evpn_flags;
#define ATTR_EVPN_FLAG_STICKY (1 << 0)
/* Flag for default gateway extended community in EVPN */ #define ATTR_EVPN_FLAG_DEFAULT_GW (1 << 1)
uint8_t default_gw; /* NA router flag (R-bit) support in EVPN */
#define ATTR_EVPN_FLAG_ROUTER (1 << 2)
/* route tag */ /* route tag */
route_tag_t tag; route_tag_t tag;

View File

@ -115,14 +115,14 @@ bool bgp_attr_rmac(struct attr *attr, struct ethaddr *rmac)
/* /*
* return true if attr contains default gw extended community * return true if attr contains default gw extended community
*/ */
uint8_t bgp_attr_default_gw(struct attr *attr) void bgp_attr_default_gw(struct attr *attr)
{ {
struct ecommunity *ecom; struct ecommunity *ecom;
uint32_t i; uint32_t i;
ecom = bgp_attr_get_ecommunity(attr); ecom = bgp_attr_get_ecommunity(attr);
if (!ecom || !ecom->size) if (!ecom || !ecom->size)
return 0; return;
/* If there is a default gw extendd community return true otherwise /* If there is a default gw extendd community return true otherwise
* return 0 */ * return 0 */
@ -136,10 +136,9 @@ uint8_t bgp_attr_default_gw(struct attr *attr)
if ((type == ECOMMUNITY_ENCODE_OPAQUE if ((type == ECOMMUNITY_ENCODE_OPAQUE
&& sub_type == ECOMMUNITY_EVPN_SUBTYPE_DEF_GW)) && sub_type == ECOMMUNITY_EVPN_SUBTYPE_DEF_GW))
return 1; SET_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_DEFAULT_GW);
} }
UNSET_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_DEFAULT_GW);
return 0;
} }
/* /*
@ -183,7 +182,7 @@ uint16_t bgp_attr_df_pref_from_ec(struct attr *attr, uint8_t *alg)
* 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.
*/ */
uint32_t bgp_attr_mac_mobility_seqnum(struct attr *attr, uint8_t *sticky) uint32_t bgp_attr_mac_mobility_seqnum(struct attr *attr)
{ {
struct ecommunity *ecom; struct ecommunity *ecom;
uint32_t i; uint32_t i;
@ -213,9 +212,9 @@ uint32_t bgp_attr_mac_mobility_seqnum(struct attr *attr, uint8_t *sticky)
flags = *pnt++; flags = *pnt++;
if (flags & ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY_FLAG_STICKY) if (flags & ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY_FLAG_STICKY)
*sticky = 1; SET_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_STICKY);
else else
*sticky = 0; UNSET_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_STICKY);
pnt++; pnt++;
pnt = ptr_get_be32(pnt, &seq_num); pnt = ptr_get_be32(pnt, &seq_num);
@ -229,8 +228,7 @@ uint32_t bgp_attr_mac_mobility_seqnum(struct attr *attr, uint8_t *sticky)
/* /*
* return true if attr contains router flag extended community * return true if attr contains router flag extended community
*/ */
void bgp_attr_evpn_na_flag(struct attr *attr, void bgp_attr_evpn_na_flag(struct attr *attr, bool *proxy)
uint8_t *router_flag, bool *proxy)
{ {
struct ecommunity *ecom; struct ecommunity *ecom;
uint32_t i; uint32_t i;
@ -254,7 +252,8 @@ void bgp_attr_evpn_na_flag(struct attr *attr,
val = *pnt++; val = *pnt++;
if (val & ECOMMUNITY_EVPN_SUBTYPE_ND_ROUTER_FLAG) if (val & ECOMMUNITY_EVPN_SUBTYPE_ND_ROUTER_FLAG)
*router_flag = 1; SET_FLAG(attr->evpn_flags,
ATTR_EVPN_FLAG_ROUTER);
if (val & ECOMMUNITY_EVPN_SUBTYPE_PROXY_FLAG) if (val & ECOMMUNITY_EVPN_SUBTYPE_PROXY_FLAG)
*proxy = true; *proxy = true;

View File

@ -36,12 +36,10 @@ extern void bgp_add_routermac_ecom(struct attr *attr,
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 bool bgp_attr_rmac(struct attr *attr, struct ethaddr *rmac); extern bool bgp_attr_rmac(struct attr *attr, struct ethaddr *rmac);
extern uint32_t bgp_attr_mac_mobility_seqnum(struct attr *attr, extern uint32_t bgp_attr_mac_mobility_seqnum(struct attr *attr);
uint8_t *sticky); extern void bgp_attr_default_gw(struct attr *attr);
extern uint8_t bgp_attr_default_gw(struct attr *attr);
extern void bgp_attr_evpn_na_flag(struct attr *attr, uint8_t *router_flag, extern void bgp_attr_evpn_na_flag(struct attr *attr, bool *proxy);
bool *proxy);
extern uint16_t bgp_attr_df_pref_from_ec(struct attr *attr, uint8_t *alg); extern uint16_t bgp_attr_df_pref_from_ec(struct attr *attr, uint8_t *alg);

View File

@ -1159,7 +1159,7 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,
} }
/* Add MAC mobility (sticky) if needed. */ /* Add MAC mobility (sticky) if needed. */
if (attr->sticky) { if (CHECK_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_STICKY)) {
seqnum = 0; seqnum = 0;
encode_mac_mobility_extcomm(1, seqnum, &eval_sticky); encode_mac_mobility_extcomm(1, seqnum, &eval_sticky);
ecom_sticky.size = 1; ecom_sticky.size = 1;
@ -1178,7 +1178,7 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,
} }
/* Add default gateway, if needed. */ /* Add default gateway, if needed. */
if (attr->default_gw) { if (CHECK_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_DEFAULT_GW)) {
encode_default_gw_extcomm(&eval_default_gw); encode_default_gw_extcomm(&eval_default_gw);
ecom_default_gw.size = 1; ecom_default_gw.size = 1;
ecom_default_gw.unit_size = ECOMMUNITY_SIZE; ecom_default_gw.unit_size = ECOMMUNITY_SIZE;
@ -1189,8 +1189,11 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,
} }
proxy = !!(attr->es_flags & ATTR_ES_PROXY_ADVERT); proxy = !!(attr->es_flags & ATTR_ES_PROXY_ADVERT);
if (attr->router_flag || proxy) { if (CHECK_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_ROUTER) || proxy) {
encode_na_flag_extcomm(&eval_na, attr->router_flag, proxy); encode_na_flag_extcomm(&eval_na,
CHECK_FLAG(attr->evpn_flags,
ATTR_EVPN_FLAG_ROUTER),
proxy);
ecom_na.size = 1; ecom_na.size = 1;
ecom_na.unit_size = ECOMMUNITY_SIZE; ecom_na.unit_size = ECOMMUNITY_SIZE;
ecom_na.val = (uint8_t *)eval_na.val; ecom_na.val = (uint8_t *)eval_na.val;
@ -1275,12 +1278,15 @@ enum zclient_send_status evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn
flags = 0; flags = 0;
if (pi->sub_type == BGP_ROUTE_IMPORTED) { if (pi->sub_type == BGP_ROUTE_IMPORTED) {
if (pi->attr->sticky) if (CHECK_FLAG(pi->attr->evpn_flags,
ATTR_EVPN_FLAG_STICKY))
SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY); SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
if (pi->attr->default_gw) if (CHECK_FLAG(pi->attr->evpn_flags,
ATTR_EVPN_FLAG_DEFAULT_GW))
SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW); SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
if (is_evpn_prefix_ipaddr_v6(p) && if (is_evpn_prefix_ipaddr_v6(p) &&
pi->attr->router_flag) CHECK_FLAG(pi->attr->evpn_flags,
ATTR_EVPN_FLAG_ROUTER))
SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG); SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
seq = mac_mobility_seqnum(pi->attr); seq = mac_mobility_seqnum(pi->attr);
@ -1834,7 +1840,8 @@ static void bgp_evpn_get_sync_info(struct bgp *bgp, esi_t *esi,
*active_on_peer = true; *active_on_peer = true;
} }
if (second_best_path->attr->router_flag) if (CHECK_FLAG(second_best_path->attr->evpn_flags,
ATTR_EVPN_FLAG_ROUTER))
*peer_router = true; *peer_router = true;
/* we use both proxy and non-proxy imports to /* we use both proxy and non-proxy imports to
@ -1934,7 +1941,6 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
struct attr local_attr; struct attr local_attr;
struct bgp_labels bgp_labels = {}; struct bgp_labels bgp_labels = {};
int route_change = 1; int route_change = 1;
uint8_t sticky = 0;
const struct prefix_evpn *evp; const struct prefix_evpn *evp;
*pi = NULL; *pi = NULL;
@ -1966,9 +1972,7 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
local_attr = *attr; local_attr = *attr;
/* Extract MAC mobility sequence number, if any. */ /* Extract MAC mobility sequence number, if any. */
local_attr.mm_seqnum = local_attr.mm_seqnum = bgp_attr_mac_mobility_seqnum(&local_attr);
bgp_attr_mac_mobility_seqnum(&local_attr, &sticky);
local_attr.sticky = sticky;
/* Add (or update) attribute to hash. */ /* Add (or update) attribute to hash. */
attr_new = bgp_attr_intern(&local_attr); attr_new = bgp_attr_intern(&local_attr);
@ -2063,9 +2067,8 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
BGP_PATH_ATTR_CHANGED); BGP_PATH_ATTR_CHANGED);
/* Extract MAC mobility sequence number, if any. */ /* Extract MAC mobility sequence number, if any. */
local_attr.mm_seqnum = bgp_attr_mac_mobility_seqnum( local_attr.mm_seqnum =
&local_attr, &sticky); bgp_attr_mac_mobility_seqnum(&local_attr);
local_attr.sticky = sticky;
attr_new = bgp_attr_intern(&local_attr); attr_new = bgp_attr_intern(&local_attr);
@ -2198,10 +2201,12 @@ static int update_evpn_route(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;
attr.sticky = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY) ? 1 : 0; if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY))
attr.default_gw = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW) ? 1 : 0; SET_FLAG(attr.evpn_flags, ATTR_EVPN_FLAG_STICKY);
attr.router_flag = CHECK_FLAG(flags, if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW))
ZEBRA_MACIP_TYPE_ROUTER_FLAG) ? 1 : 0; SET_FLAG(attr.evpn_flags, ATTR_EVPN_FLAG_DEFAULT_GW);
if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG))
SET_FLAG(attr.evpn_flags, ATTR_EVPN_FLAG_ROUTER);
if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT)) if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT))
attr.es_flags |= ATTR_ES_PROXY_ADVERT; attr.es_flags |= ATTR_ES_PROXY_ADVERT;
@ -2503,13 +2508,12 @@ void bgp_evpn_update_type2_route_entry(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;
attr.sticky = (local_pi->attr->sticky) ? 1 : 0; attr.evpn_flags = local_pi->attr->evpn_flags;
attr.router_flag = (local_pi->attr->router_flag) ? 1 : 0;
attr.es_flags = local_pi->attr->es_flags; attr.es_flags = local_pi->attr->es_flags;
if (local_pi->attr->default_gw) { if (CHECK_FLAG(local_pi->attr->evpn_flags, ATTR_EVPN_FLAG_DEFAULT_GW)) {
attr.default_gw = 1; SET_FLAG(attr.evpn_flags, ATTR_EVPN_FLAG_DEFAULT_GW);
if (is_evpn_prefix_ipaddr_v6(&evp)) if (is_evpn_prefix_ipaddr_v6(&evp))
attr.router_flag = 1; SET_FLAG(attr.evpn_flags, ATTR_EVPN_FLAG_ROUTER);
} }
memcpy(&attr.esi, &local_pi->attr->esi, sizeof(esi_t)); memcpy(&attr.esi, &local_pi->attr->esi, sizeof(esi_t));
bgp_evpn_get_rmac_nexthop(vpn, &evp, &attr, bgp_evpn_get_rmac_nexthop(vpn, &evp, &attr,

View File

@ -382,7 +382,7 @@ static inline void encode_mac_mobility_extcomm(int static_mac, uint32_t seq,
} }
static inline void encode_na_flag_extcomm(struct ecommunity_val *eval, static inline void encode_na_flag_extcomm(struct ecommunity_val *eval,
uint8_t na_flag, bool proxy) bool na_flag, bool proxy)
{ {
memset(eval, 0, sizeof(*eval)); memset(eval, 0, sizeof(*eval));
eval->val[0] = ECOMMUNITY_ENCODE_EVPN; eval->val[0] = ECOMMUNITY_ENCODE_EVPN;

View File

@ -851,8 +851,13 @@ int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
* with the * with the
* sticky flag. * sticky flag.
*/ */
if (newattr->sticky != existattr->sticky) { bool new_sticky = CHECK_FLAG(newattr->evpn_flags,
if (newattr->sticky && !existattr->sticky) { ATTR_EVPN_FLAG_STICKY);
bool exist_sticky = CHECK_FLAG(existattr->evpn_flags,
ATTR_EVPN_FLAG_STICKY);
if (new_sticky != exist_sticky) {
if (new_sticky && !exist_sticky) {
*reason = bgp_path_selection_evpn_sticky_mac; *reason = bgp_path_selection_evpn_sticky_mac;
if (debug) if (debug)
zlog_debug( zlog_debug(
@ -861,7 +866,7 @@ int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
return 1; return 1;
} }
if (!newattr->sticky && existattr->sticky) { if (!new_sticky && exist_sticky) {
*reason = bgp_path_selection_evpn_sticky_mac; *reason = bgp_path_selection_evpn_sticky_mac;
if (debug) if (debug)
zlog_debug( zlog_debug(