]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/zebra_evpn_neigh.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / zebra / zebra_evpn_neigh.c
index ed224151ba2f6067676d0041ed39e9d8fb2e37b1..acd60aa08f619ed97ccfed87d2114b135381f141 100644 (file)
@@ -1,23 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Zebra EVPN Neighbor code
  * Copyright (C) 2016, 2017 Cumulus Networks, Inc.
- *
- * This file is part of FRR.
- *
- * FRR is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * FRR is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with FRR; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
  */
 
 #include <zebra.h>
@@ -36,6 +20,8 @@
 #include "zebra/rt.h"
 #include "zebra/zebra_errors.h"
 #include "zebra/zebra_vrf.h"
+#include "zebra/zebra_vxlan.h"
+#include "zebra/zebra_vxlan_if.h"
 #include "zebra/zebra_evpn.h"
 #include "zebra/zebra_evpn_mh.h"
 #include "zebra/zebra_evpn_neigh.h"
@@ -501,22 +487,33 @@ bool zebra_evpn_neigh_is_bgp_seq_ok(struct zebra_evpn *zevpn,
 {
        uint32_t tmp_seq;
        const char *n_type;
+       bool is_local = false;
 
        if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)) {
                tmp_seq = n->loc_seq;
                n_type = "local";
+               is_local = true;
        } else {
                tmp_seq = n->rem_seq;
                n_type = "remote";
        }
 
        if (seq < tmp_seq) {
+               if (is_local && !zebra_evpn_neigh_is_ready_for_bgp(n)) {
+                       if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH ||
+                           IS_ZEBRA_DEBUG_VXLAN)
+                               zlog_debug(
+                                       "%s-macip not ready vni %u %s mac %pEA IP %pIA lower seq %u f 0x%x",
+                                       sync ? "sync" : "remote", zevpn->vni,
+                                       n_type, macaddr, &n->ip, tmp_seq,
+                                       n->flags);
+                       return true;
+               }
+
                /* if the neigh was never advertised to bgp we must accept
                 * whatever sequence number bgp sends
-                * XXX - check with Vivek
                 */
-               if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)
-                   && !zebra_evpn_neigh_is_ready_for_bgp(n)) {
+               if (!is_local && zebra_vxlan_get_accept_bgp_seq()) {
                        if (IS_ZEBRA_DEBUG_EVPN_MH_NEIGH
                            || IS_ZEBRA_DEBUG_VXLAN)
                                zlog_debug(
@@ -550,10 +547,9 @@ static struct zebra_neigh *zebra_evpn_neigh_add(struct zebra_evpn *zevpn,
        struct zebra_neigh tmp_n;
        struct zebra_neigh *n = NULL;
 
-       memset(&tmp_n, 0, sizeof(struct zebra_neigh));
+       memset(&tmp_n, 0, sizeof(tmp_n));
        memcpy(&tmp_n.ip, ip, sizeof(struct ipaddr));
        n = hash_get(zevpn->neigh_table, &tmp_n, zebra_evpn_neigh_alloc);
-       assert(n);
 
        n->state = ZEBRA_NEIGH_INACTIVE;
        n->zevpn = zevpn;
@@ -616,11 +612,10 @@ void zebra_evpn_sync_neigh_del(struct zebra_neigh *n)
 struct zebra_neigh *zebra_evpn_proc_sync_neigh_update(
        struct zebra_evpn *zevpn, struct zebra_neigh *n, uint16_t ipa_len,
        const struct ipaddr *ipaddr, uint8_t flags, uint32_t seq,
-       const esi_t *esi, struct sync_mac_ip_ctx *ctx)
+       const esi_t *esi, struct zebra_mac *mac)
 {
        struct interface *ifp = NULL;
        bool is_router;
-       struct zebra_mac *mac = ctx->mac;
        uint32_t tmp_seq;
        bool old_router = false;
        bool old_bgp_ready = false;
@@ -703,11 +698,6 @@ struct zebra_neigh *zebra_evpn_proc_sync_neigh_update(
                        n->flags |= ZEBRA_NEIGH_LOCAL_INACTIVE;
                }
 
-               if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT))
-                       SET_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_PROXY);
-               else
-                       SET_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_ACTIVE);
-
                if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT)) {
                        SET_FLAG(n->flags, ZEBRA_NEIGH_ES_PEER_PROXY);
                        /* if the neigh was peer-active previously we
@@ -786,8 +776,8 @@ struct zebra_neigh *zebra_evpn_proc_sync_neigh_update(
                inform_bgp = true;
 
        new_mac_static = zebra_evpn_mac_is_static(mac);
-       if ((old_mac_static != new_mac_static) || ctx->mac_dp_update_deferred)
-               zebra_evpn_sync_mac_dp_install(mac, ctx->mac_inactive,
+       if (old_mac_static != new_mac_static)
+               zebra_evpn_sync_mac_dp_install(mac, false /* set_inactive */,
                                               false /* force_clear_static */,
                                               __func__);
 
@@ -882,7 +872,7 @@ void zebra_evpn_neigh_del_all(struct zebra_evpn *zevpn, int uninstall,
        if (!zevpn->neigh_table)
                return;
 
-       memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
+       memset(&wctx, 0, sizeof(wctx));
        wctx.zevpn = zevpn;
        wctx.uninstall = uninstall;
        wctx.upd_client = upd_client;
@@ -1281,10 +1271,12 @@ int zebra_evpn_local_neigh_update(struct zebra_evpn *zevpn,
                        zlog_debug("AUTO MAC %pEA created for neigh %pIA on VNI %u",
                                   macaddr, ip, zevpn->vni);
 
-               zmac = zebra_evpn_mac_add(zevpn, macaddr);
-               zebra_evpn_mac_clear_fwd_info(zmac);
-               memset(&zmac->flags, 0, sizeof(uint32_t));
-               SET_FLAG(zmac->flags, ZEBRA_MAC_AUTO);
+               zmac = zebra_evpn_mac_add_auto(zevpn, macaddr);
+               if (!zmac) {
+                       zlog_debug("Failed to add MAC %pEA VNI %u", macaddr,
+                                  zevpn->vni);
+                       return -1;
+               }
        } else {
                if (CHECK_FLAG(zmac->flags, ZEBRA_MAC_REMOTE)) {
                        /*
@@ -1654,7 +1646,7 @@ void zebra_evpn_send_neigh_to_client(struct zebra_evpn *zevpn)
 {
        struct neigh_walk_ctx wctx;
 
-       memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
+       memset(&wctx, 0, sizeof(wctx));
        wctx.zevpn = zevpn;
 
        hash_iterate(zevpn->neigh_table,
@@ -1719,9 +1711,6 @@ void zebra_evpn_print_neigh(struct zebra_neigh *n, void *ctxt,
        char up_str[MONOTIME_STRLEN];
 
        zvrf = zebra_vrf_get_evpn();
-       if (!zvrf)
-               return;
-
        uptime = monotime(NULL);
        uptime -= n->uptime;
 
@@ -2242,6 +2231,12 @@ void zebra_evpn_neigh_remote_uninstall(struct zebra_evpn *zevpn,
                        zebra_evpn_neigh_del(zevpn, n);
                        zebra_evpn_deref_ip2mac(zevpn, mac);
                }
+       } else {
+               if (IS_ZEBRA_DEBUG_VXLAN)
+                       zlog_debug(
+                               "%s: IP %pIA MAC %pEA (flags 0x%x) found doesn't match MAC %pEA, ignoring Neigh DEL",
+                               __func__, ipaddr, &n->emac, n->flags,
+                               &mac->macaddr);
        }
 }