diff options
Diffstat (limited to 'zebra/zebra_vxlan.c')
| -rw-r--r-- | zebra/zebra_vxlan.c | 66 |
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); |
