diff options
| author | Anuradha Karuppiah <anuradhak@cumulusnetworks.com> | 2020-10-01 14:19:52 -0700 |
|---|---|---|
| committer | Anuradha Karuppiah <anuradhak@nvidia.com> | 2020-12-21 08:41:17 -0800 |
| commit | 16de1338a9c58c6dcbf98e7064c57708d1e91d68 (patch) | |
| tree | 7b1313cb363d2c03a4522e6c0cc1be4ea3f5dc0d | |
| parent | 6c111b51a1647ca994b061c0adc9c65023ea6814 (diff) | |
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>
| -rw-r--r-- | zebra/zebra_evpn.c | 3 | ||||
| -rw-r--r-- | zebra/zebra_evpn_mac.c | 48 | ||||
| -rw-r--r-- | zebra/zebra_evpn_neigh.c | 51 | ||||
| -rw-r--r-- | zebra/zebra_evpn_neigh.h | 3 |
4 files changed, 41 insertions, 64 deletions
diff --git a/zebra/zebra_evpn.c b/zebra/zebra_evpn.c index 477e046dd8..b232c664bc 100644 --- a/zebra/zebra_evpn.c +++ b/zebra/zebra_evpn.c @@ -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; } diff --git a/zebra/zebra_evpn_mac.c b/zebra/zebra_evpn_mac.c index d72f705862..376721f83a 100644 --- a/zebra/zebra_evpn_mac.c +++ b/zebra/zebra_evpn_mac.c @@ -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); } diff --git a/zebra/zebra_evpn_neigh.c b/zebra/zebra_evpn_neigh.c index d6de60cc22..1f45b72e3a 100644 --- a/zebra/zebra_evpn_neigh.c +++ b/zebra/zebra_evpn_neigh.c @@ -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) diff --git a/zebra/zebra_evpn_neigh.h b/zebra/zebra_evpn_neigh.h index 50efdc0e0d..eac17a09b4 100644 --- a/zebra/zebra_evpn_neigh.h +++ b/zebra/zebra_evpn_neigh.h @@ -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 * |
