]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: probe local inactive neigh 3688/head
authorChirag Shah <chirag@cumulusnetworks.com>
Mon, 28 Jan 2019 23:37:03 +0000 (15:37 -0800)
committerChirag Shah <chirag@cumulusnetworks.com>
Tue, 29 Jan 2019 18:23:19 +0000 (10:23 -0800)
In extended-mobility case ({IP1, MAC} binding),
when a MAC moves from local to remote, binding
changes to {IP2, MAC}, local neigh (IP1) marked
as inactive in frr.
The evpn draft recommends to probe the entry once
local binding changes from local to remote.
Once the probe is set for the local neigh entry,
kernel will attempt refresh the entry via sending
unicast address resolution message, if host does not
reply, it will mark FAILED state.
For FAILED entry, kernel triggers delete neigh
request, which result in frr to remove inactive entry.

In absence of probing and aging out entry,
if MAC moves back to local with {IP3, MAC},
frr will mark both IP1 and IP3 as active and sends
type-2 update for both.
The IP1 may not be active host and still frr advertises
the route.

Ticket:CM-22864
Testing Done:

Validate the MAC mobilty in extended mobility scenario,
where local inactive entry gets removed once MAC moves
to remote state.
Once probe is set to the local entry, kernel triggers
reachability of the neigh/arp entry, since MAC moved remote,
ARP request goes to remote VTEP where host is not residing,
thus local neigh entry goes to failed state.
Frr receives neighbor delete faster and removes the entry.

Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
zebra/zebra_vxlan.c

index 49af4a9205c7971c2ac1b61b52028d7e3f4caca7..9bd959fb8ccc4a3dfec6dd7cbf71d3f39eebf999 100644 (file)
@@ -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);
@@ -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.
  */
@@ -2500,6 +2513,32 @@ static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n)
        return kernel_del_neigh(vlan_if, &n->ip);
 }
 
+/*
+ * 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.
  */
@@ -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;
 }