]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: accept bgp remote mac-ip update if the higher-seq-local mac is not bgp-ready
authorAnuradha Karuppiah <anuradhak@cumulusnetworks.com>
Thu, 1 Oct 2020 21:19:52 +0000 (14:19 -0700)
committerAnuradha Karuppiah <anuradhak@nvidia.com>
Mon, 21 Dec 2020 16:41:17 +0000 (08:41 -0800)
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>
zebra/zebra_evpn.c
zebra/zebra_evpn_mac.c
zebra/zebra_evpn_neigh.c
zebra/zebra_evpn_neigh.h

index 477e046dd82ec5335d3a3d0032d96f4faa755899..b232c664bc828e47777a3830e3f294efbf07f8a8 100644 (file)
@@ -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;
        }
 
index d72f7058625e62b284cc726a5f70c812b13bae60..376721f83ad589bfbddbc00e3742f668eaa85da8 100644 (file)
@@ -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);
                }
index d6de60cc22549d35802616350736b6179409b772..1f45b72e3aaba6e950a9aa1f8436103dc32b2195 100644 (file)
@@ -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)
index 50efdc0e0d41b66871eef67e0065035c35808334..eac17a09b4d432676eb86031af6555ff9a84195f 100644 (file)
@@ -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 *