summaryrefslogtreecommitdiff
path: root/zebra/zebra_vxlan.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/zebra_vxlan.c')
-rw-r--r--zebra/zebra_vxlan.c66
1 files changed, 61 insertions, 5 deletions
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index 49af4a9205..069da82850 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -50,7 +50,7 @@
#include "zebra/zebra_vrf.h"
#include "zebra/zebra_vxlan.h"
#include "zebra/zebra_vxlan_private.h"
-#include "zebra/zserv.h"
+#include "zebra/zebra_router.h"
DEFINE_MTYPE_STATIC(ZEBRA, HOST_PREFIX, "host prefix");
DEFINE_MTYPE_STATIC(ZEBRA, ZVNI, "VNI hash");
@@ -100,6 +100,7 @@ static int zvni_neigh_send_del_to_client(vni_t vni, struct ipaddr *ip,
uint8_t flags, int state);
static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n);
static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n);
+static int zvni_neigh_probe(zebra_vni_t *zvni, zebra_neigh_t *n);
static zebra_vni_t *zvni_from_svi(struct interface *ifp,
struct interface *br_if);
static struct interface *zvni_map_to_svi(vlanid_t vid, struct interface *br_if);
@@ -510,7 +511,7 @@ static void zebra_vxlan_dup_addr_detect_for_mac(struct zebra_vrf *zvrf,
sizeof(buf)),
mac->flags, zvrf->dad_freeze_time);
- thread_add_timer(zebrad.master,
+ thread_add_timer(zrouter.master,
zebra_vxlan_dad_mac_auto_recovery_exp,
mac, zvrf->dad_freeze_time,
&mac->dad_mac_auto_recovery_timer);
@@ -643,7 +644,7 @@ static void zebra_vxlan_dup_addr_detect_for_neigh(struct zebra_vrf *zvrf,
ipaddr2str(&nbr->ip, buf1, sizeof(buf1)),
nbr->flags, zvrf->dad_freeze_time);
- thread_add_timer(zebrad.master,
+ thread_add_timer(zrouter.master,
zebra_vxlan_dad_ip_auto_recovery_exp,
nbr, zvrf->dad_freeze_time,
&nbr->dad_ip_auto_recovery_timer);
@@ -2404,6 +2405,18 @@ static void zvni_process_neigh_on_remote_mac_del(zebra_vni_t *zvni,
/* NOTE: Currently a NO-OP. */
}
+static void zvni_probe_neigh_on_mac_add(zebra_vni_t *zvni, zebra_mac_t *zmac)
+{
+ zebra_neigh_t *nbr = NULL;
+ struct listnode *node = NULL;
+
+ for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, nbr)) {
+ if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL) &&
+ IS_ZEBRA_NEIGH_INACTIVE(nbr))
+ zvni_neigh_probe(zvni, nbr);
+ }
+}
+
/*
* Inform BGP about local neighbor addition.
*/
@@ -2501,6 +2514,32 @@ static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n)
}
/*
+ * Probe neighbor from the kernel.
+ */
+static int zvni_neigh_probe(zebra_vni_t *zvni, zebra_neigh_t *n)
+{
+ struct zebra_if *zif;
+ struct zebra_l2info_vxlan *vxl;
+ struct interface *vlan_if;
+
+ zif = zvni->vxlan_if->info;
+ if (!zif)
+ return -1;
+ vxl = &zif->l2info.vxl;
+
+ vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
+ if (!vlan_if)
+ return -1;
+
+#ifdef GNU_LINUX
+ return kernel_upd_neigh(vlan_if, &n->ip, &n->emac,
+ 0, NUD_PROBE);
+#else
+ return 0;
+#endif
+}
+
+/*
* Install neighbor hash entry - called upon access VLAN change.
*/
static void zvni_install_neigh_hash(struct hash_backet *backet, void *ctxt)
@@ -5329,6 +5368,8 @@ static void process_remote_macip_add(vni_t vni,
zvni_neigh_install(zvni, n);
}
+ zvni_probe_neigh_on_mac_add(zvni, mac);
+
/* Update seq number. */
n->rem_seq = seq;
}
@@ -7029,6 +7070,7 @@ int zebra_vxlan_handle_kernel_neigh_del(struct interface *ifp,
zebra_vni_t *zvni = NULL;
zebra_mac_t *zmac = NULL;
zebra_l3vni_t *zl3vni = NULL;
+ struct zebra_vrf *zvrf;
/* check if this is a remote neigh entry corresponding to remote
* next-hop
@@ -7081,9 +7123,23 @@ int zebra_vxlan_handle_kernel_neigh_del(struct interface *ifp,
return 0;
}
+ zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id);
+ if (!zvrf) {
+ zlog_debug("%s: VNI %u vrf lookup failed.",
+ __PRETTY_FUNCTION__, zvni->vni);
+ return -1;
+ }
+
+ /* In case of feeze action, if local neigh is in duplicate state,
+ * Mark the Neigh as inactive before sending delete request to BGPd,
+ * If BGPd has remote entry, it will re-install
+ */
+ if (zvrf->dad_freeze &&
+ CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE))
+ ZEBRA_NEIGH_SET_INACTIVE(n);
+
/* Remove neighbor from BGP. */
- zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac,
- 0, n->state);
+ zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac, 0, n->state);
/* Delete this neighbor entry. */
zvni_neigh_del(zvni, n);