mirror of
https://git.proxmox.com/git/mirror_frr
synced 2026-01-08 19:06:09 +00:00
zebra: accept bgp remote mac-ip update if the higher-seq-local mac is not bgp-ready
If a local-MAC or local-neigh is not active locally it is not sent to BGP. At this point if BGP rxes a remote route it accepts it and installs in zebra. Zebra was rejecting BGP's update if it had a higher seq local (inactive) entry. This would result in bgp and zebra falling out of sync. In some cases zebra would delete the local-inactive entries in sometime (as a part of the dplane/kernel garbage collection). This would leave zebra with missing remote entries (which were still present in bgpd). This change allows lower-seq BGP updates to overwrite zebra's local entry if that entry happens to be local-inactive. Note: This logic was already in use for sync-mac-ip updates. Extended the same logic to remote-mac-ip updates. Ticket: CM-31626 Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
This commit is contained in:
parent
6c111b51a1
commit
16de1338a9
@ -1336,7 +1336,8 @@ zebra_evpn_process_sync_macip_add(zebra_evpn_t *zevpn, struct ethaddr *macaddr,
|
||||
if (ipa_len) {
|
||||
n = zebra_evpn_neigh_lookup(zevpn, ipaddr);
|
||||
if (n
|
||||
&& !zebra_evpn_neigh_is_bgp_seq_ok(zevpn, n, macaddr, seq))
|
||||
&& !zebra_evpn_neigh_is_bgp_seq_ok(zevpn, n, macaddr, seq,
|
||||
true))
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -1395,16 +1395,21 @@ void zebra_evpn_sync_mac_del(zebra_mac_t *mac)
|
||||
static inline bool zebra_evpn_mac_is_bgp_seq_ok(zebra_evpn_t *zevpn,
|
||||
zebra_mac_t *mac, uint32_t seq,
|
||||
uint16_t ipa_len,
|
||||
struct ipaddr *ipaddr)
|
||||
struct ipaddr *ipaddr,
|
||||
bool sync)
|
||||
{
|
||||
char macbuf[ETHER_ADDR_STRLEN];
|
||||
char ipbuf[INET6_ADDRSTRLEN];
|
||||
uint32_t tmp_seq;
|
||||
const char *n_type;
|
||||
|
||||
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
|
||||
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
|
||||
tmp_seq = mac->loc_seq;
|
||||
else
|
||||
n_type = "local";
|
||||
} else {
|
||||
tmp_seq = mac->rem_seq;
|
||||
n_type = "remote";
|
||||
}
|
||||
|
||||
if (seq < tmp_seq) {
|
||||
/* if the mac was never advertised to bgp we must accept
|
||||
@ -1413,10 +1418,11 @@ static inline bool zebra_evpn_mac_is_bgp_seq_ok(zebra_evpn_t *zevpn,
|
||||
*/
|
||||
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)
|
||||
&& !zebra_evpn_mac_is_ready_for_bgp(mac->flags)) {
|
||||
if (IS_ZEBRA_DEBUG_EVPN_MH_MAC)
|
||||
if (IS_ZEBRA_DEBUG_EVPN_MH_MAC || IS_ZEBRA_DEBUG_VXLAN)
|
||||
zlog_debug(
|
||||
"sync-macip accept vni %u mac %s%s%s lower seq %u f 0x%x",
|
||||
zevpn->vni,
|
||||
"%s-macip accept vni %u %s-mac %s%s%s lower seq %u f 0x%x",
|
||||
sync ? "sync" : "rem", zevpn->vni,
|
||||
n_type,
|
||||
prefix_mac2str(&mac->macaddr, macbuf,
|
||||
sizeof(macbuf)),
|
||||
ipa_len ? " IP " : "",
|
||||
@ -1427,10 +1433,10 @@ static inline bool zebra_evpn_mac_is_bgp_seq_ok(zebra_evpn_t *zevpn,
|
||||
return true;
|
||||
}
|
||||
|
||||
if (IS_ZEBRA_DEBUG_EVPN_MH_MAC)
|
||||
if (IS_ZEBRA_DEBUG_EVPN_MH_MAC || IS_ZEBRA_DEBUG_VXLAN)
|
||||
zlog_debug(
|
||||
"sync-macip ignore vni %u mac %s%s%s as existing has higher seq %u f 0x%x",
|
||||
zevpn->vni,
|
||||
"%s-macip ignore vni %u %s-mac %s%s%s as existing has higher seq %u f 0x%x",
|
||||
sync ? "sync" : "rem", zevpn->vni, n_type,
|
||||
prefix_mac2str(&mac->macaddr, macbuf,
|
||||
sizeof(macbuf)),
|
||||
ipa_len ? " IP " : "",
|
||||
@ -1518,7 +1524,7 @@ zebra_evpn_proc_sync_mac_update(zebra_evpn_t *zevpn, struct ethaddr *macaddr,
|
||||
return NULL;
|
||||
}
|
||||
if (!zebra_evpn_mac_is_bgp_seq_ok(zevpn, mac, seq, ipa_len,
|
||||
ipaddr)) {
|
||||
ipaddr, true)) {
|
||||
ctx->ignore_macip = true;
|
||||
return NULL;
|
||||
}
|
||||
@ -1768,7 +1774,6 @@ int process_mac_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf,
|
||||
{
|
||||
char buf[ETHER_ADDR_STRLEN];
|
||||
char buf1[INET6_ADDRSTRLEN];
|
||||
uint32_t tmp_seq;
|
||||
bool sticky;
|
||||
bool remote_gw;
|
||||
int update_mac = 0;
|
||||
@ -1836,26 +1841,9 @@ int process_mac_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf,
|
||||
* the sequence number and ignore this update
|
||||
* if appropriate.
|
||||
*/
|
||||
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
|
||||
tmp_seq = mac->loc_seq;
|
||||
else
|
||||
tmp_seq = mac->rem_seq;
|
||||
|
||||
if (seq < tmp_seq) {
|
||||
if (IS_ZEBRA_DEBUG_VXLAN)
|
||||
zlog_debug(
|
||||
"Ignore remote MACIP ADD VNI %u MAC %s%s%s as existing MAC has higher seq %u flags 0x%x",
|
||||
zevpn->vni,
|
||||
prefix_mac2str(macaddr, buf,
|
||||
sizeof(buf)),
|
||||
ipa_len ? " IP " : "",
|
||||
ipa_len ? ipaddr2str(
|
||||
ipaddr, buf1,
|
||||
sizeof(buf1))
|
||||
: "",
|
||||
tmp_seq, mac->flags);
|
||||
if (!zebra_evpn_mac_is_bgp_seq_ok(
|
||||
zevpn, mac, seq, ipa_len, ipaddr, false))
|
||||
return -1;
|
||||
}
|
||||
|
||||
zebra_evpn_es_mac_ref(mac, esi);
|
||||
}
|
||||
|
||||
@ -529,16 +529,21 @@ static void zebra_evpn_local_neigh_deref_mac(zebra_neigh_t *n,
|
||||
}
|
||||
|
||||
bool zebra_evpn_neigh_is_bgp_seq_ok(zebra_evpn_t *zevpn, zebra_neigh_t *n,
|
||||
struct ethaddr *macaddr, uint32_t seq)
|
||||
struct ethaddr *macaddr, uint32_t seq,
|
||||
bool sync)
|
||||
{
|
||||
char macbuf[ETHER_ADDR_STRLEN];
|
||||
char ipbuf[INET6_ADDRSTRLEN];
|
||||
uint32_t tmp_seq;
|
||||
const char *n_type;
|
||||
|
||||
if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL))
|
||||
if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
|
||||
tmp_seq = n->loc_seq;
|
||||
else
|
||||
n_type = "local";
|
||||
} else {
|
||||
tmp_seq = n->rem_seq;
|
||||
n_type = "remote";
|
||||
}
|
||||
|
||||
if (seq < tmp_seq) {
|
||||
/* if the neigh was never advertised to bgp we must accept
|
||||
@ -547,10 +552,12 @@ bool zebra_evpn_neigh_is_bgp_seq_ok(zebra_evpn_t *zevpn, zebra_neigh_t *n,
|
||||
*/
|
||||
if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)
|
||||
&& !zebra_evpn_neigh_is_ready_for_bgp(n)) {
|
||||
if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
|
||||
if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH
|
||||
|| IS_ZEBRA_DEBUG_VXLAN)
|
||||
zlog_debug(
|
||||
"sync-macip accept vni %u mac %s IP %s lower seq %u f 0x%x",
|
||||
zevpn->vni,
|
||||
"%s-macip accept vni %u %s mac %s IP %s lower seq %u f 0x%x",
|
||||
sync ? "sync" : "remote", zevpn->vni,
|
||||
n_type,
|
||||
prefix_mac2str(macaddr, macbuf,
|
||||
sizeof(macbuf)),
|
||||
ipaddr2str(&n->ip, ipbuf,
|
||||
@ -559,10 +566,10 @@ bool zebra_evpn_neigh_is_bgp_seq_ok(zebra_evpn_t *zevpn, zebra_neigh_t *n,
|
||||
return true;
|
||||
}
|
||||
|
||||
if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
|
||||
if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH || IS_ZEBRA_DEBUG_VXLAN)
|
||||
zlog_debug(
|
||||
"sync-macip ignore vni %u mac %s IP %s as existing has higher seq %u f 0x%x",
|
||||
zevpn->vni,
|
||||
"%s-macip ignore vni %u %s mac %s IP %s as existing has higher seq %u f 0x%x",
|
||||
sync ? "sync" : "remote", zevpn->vni, n_type,
|
||||
prefix_mac2str(macaddr, macbuf, sizeof(macbuf)),
|
||||
ipaddr2str(&n->ip, ipbuf, sizeof(ipbuf)),
|
||||
tmp_seq, n->flags);
|
||||
@ -2133,7 +2140,6 @@ void process_neigh_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf,
|
||||
{
|
||||
zebra_neigh_t *n;
|
||||
int update_neigh = 0;
|
||||
uint32_t tmp_seq;
|
||||
char buf[ETHER_ADDR_STRLEN];
|
||||
char buf1[INET6_ADDRSTRLEN];
|
||||
zebra_mac_t *old_mac = NULL;
|
||||
@ -2170,8 +2176,6 @@ void process_neigh_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf,
|
||||
}
|
||||
|
||||
} else {
|
||||
const char *n_type;
|
||||
|
||||
/* When host moves but changes its (MAC,IP)
|
||||
* binding, BGP may install a MACIP entry that
|
||||
* corresponds to "older" location of the host
|
||||
@ -2180,27 +2184,10 @@ void process_neigh_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf,
|
||||
* the sequence number and ignore this update
|
||||
* if appropriate.
|
||||
*/
|
||||
if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
|
||||
tmp_seq = n->loc_seq;
|
||||
n_type = "local";
|
||||
} else {
|
||||
tmp_seq = n->rem_seq;
|
||||
n_type = "remote";
|
||||
}
|
||||
if (seq < tmp_seq) {
|
||||
if (IS_ZEBRA_DEBUG_VXLAN)
|
||||
zlog_debug(
|
||||
"Ignore remote MACIP ADD VNI %u MAC %s%s%s as existing %s Neigh has higher seq %u",
|
||||
zevpn->vni,
|
||||
prefix_mac2str(&mac->macaddr,
|
||||
buf,
|
||||
sizeof(buf)),
|
||||
" IP ",
|
||||
ipaddr2str(ipaddr, buf1,
|
||||
sizeof(buf1)),
|
||||
n_type, tmp_seq);
|
||||
|
||||
if (!zebra_evpn_neigh_is_bgp_seq_ok(
|
||||
zevpn, n, &mac->macaddr, seq, false))
|
||||
return;
|
||||
}
|
||||
if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
|
||||
old_static = zebra_evpn_neigh_is_static(n);
|
||||
if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH)
|
||||
|
||||
@ -237,7 +237,8 @@ int zebra_evpn_neigh_send_del_to_client(vni_t vni, struct ipaddr *ip,
|
||||
struct ethaddr *macaddr, uint32_t flags,
|
||||
int state, bool force);
|
||||
bool zebra_evpn_neigh_is_bgp_seq_ok(zebra_evpn_t *zevpn, zebra_neigh_t *n,
|
||||
struct ethaddr *macaddr, uint32_t seq);
|
||||
struct ethaddr *macaddr, uint32_t seq,
|
||||
bool sync);
|
||||
int zebra_evpn_neigh_del(zebra_evpn_t *zevpn, zebra_neigh_t *n);
|
||||
void zebra_evpn_sync_neigh_del(zebra_neigh_t *n);
|
||||
zebra_neigh_t *
|
||||
|
||||
Loading…
Reference in New Issue
Block a user