From 44bc8ae5508975f216ad1cbb42884579896e7258 Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Mon, 28 Jan 2019 15:37:03 -0800 Subject: [PATCH] zebra: probe local inactive neigh 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 --- zebra/zebra_vxlan.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 49af4a9205..9bd959fb8c 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -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; } -- 2.39.5