diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 42bb5974f8..ed9d007c4c 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -3300,6 +3300,8 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id) bool is_ext; bool is_router; bool local_inactive; + uint32_t ext_flags = 0; + bool dp_static = false; ndm = NLMSG_DATA(h); @@ -3391,9 +3393,15 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id) is_ext = !!(ndm->ndm_flags & NTF_EXT_LEARNED); is_router = !!(ndm->ndm_flags & NTF_ROUTER); + if (tb[NDA_EXT_FLAGS]) { + ext_flags = *(uint32_t *)RTA_DATA(tb[NDA_EXT_FLAGS]); + if (ext_flags & NTF_E_MH_PEER_SYNC) + dp_static = true; + } + if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug( - "Rx %s family %s IF %s(%u) vrf %s(%u) IP %s MAC %s state 0x%x flags 0x%x", + "Rx %s family %s IF %s(%u) vrf %s(%u) IP %s MAC %s state 0x%x flags 0x%x ext_flags 0x%x", nl_msg_type_to_str(h->nlmsg_type), nl_family_to_str(ndm->ndm_family), ifp->name, ndm->ndm_ifindex, VRF_LOGNAME(vrf), ifp->vrf_id, @@ -3401,7 +3409,7 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id) mac_present ? prefix_mac2str(&mac, buf, sizeof(buf)) : "", - ndm->ndm_state, ndm->ndm_flags); + ndm->ndm_state, ndm->ndm_flags, ext_flags); /* If the neighbor state is valid for use, process as an add or * update @@ -3420,13 +3428,9 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id) */ local_inactive = false; - /* XXX - populate dp-static based on the sync flags - * in the kernel - */ return zebra_vxlan_handle_kernel_neigh_update( - ifp, link_if, &ip, &mac, ndm->ndm_state, - is_ext, is_router, local_inactive, - false /* dp_static */); + ifp, link_if, &ip, &mac, ndm->ndm_state, is_ext, + is_router, local_inactive, dp_static); } return zebra_vxlan_handle_kernel_neigh_del(ifp, link_if, &ip); diff --git a/zebra/zebra_evpn_neigh.c b/zebra/zebra_evpn_neigh.c index 6d72bc570e..d6de60cc22 100644 --- a/zebra/zebra_evpn_neigh.c +++ b/zebra/zebra_evpn_neigh.c @@ -1453,6 +1453,9 @@ int zebra_evpn_local_neigh_update(zebra_evpn_t *zevpn, struct interface *ifp, new_bgp_ready = zebra_evpn_neigh_is_ready_for_bgp(n); + if (dp_static != new_static) + inform_dataplane = true; + /* Neigh is in freeze state and freeze action * is enabled, do not send update to client. */ @@ -1467,6 +1470,12 @@ int zebra_evpn_local_neigh_update(zebra_evpn_t *zevpn, struct interface *ifp, old_bgp_ready, new_bgp_ready, false, false, "flag-update"); + if (inform_dataplane) + zebra_evpn_sync_neigh_dp_install( + n, false /* set_inactive */, + false /* force_clear_static */, + __func__); + /* if the neigh can no longer be advertised * remove it from bgp */ @@ -1578,15 +1587,11 @@ int zebra_evpn_local_neigh_update(zebra_evpn_t *zevpn, struct interface *ifp, else UNSET_FLAG(n->flags, ZEBRA_NEIGH_ROUTER_FLAG); - /* if the dataplane thinks that this is a sync entry but - * zebra doesn't we need to re-concile the diff - * by re-installing the dataplane entry - */ - if (dp_static) { - new_static = zebra_evpn_neigh_is_static(n); - if (!new_static) - inform_dataplane = true; - } + /* if zebra and dataplane don't agree this is a sync entry + * re-install in the dataplane */ + new_static = zebra_evpn_neigh_is_static(n); + if (dp_static != new_static) + inform_dataplane = true; /* Check old and/or new MAC detected as duplicate mark * the neigh as duplicate diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 28bed846cf..c22766cad5 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -3678,13 +3678,13 @@ int zebra_vxlan_handle_kernel_neigh_update(struct interface *ifp, if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_NEIGH) zlog_debug( - "Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x %s%s%s-> L2-VNI %u", + "Add/Update neighbor %s MAC %s intf %s(%u) state 0x%x %s%s%s%s-> L2-VNI %u", ipaddr2str(ip, buf2, sizeof(buf2)), prefix_mac2str(macaddr, buf, sizeof(buf)), ifp->name, ifp->ifindex, state, is_ext ? "ext-learned " : "", is_router ? "router " : "", local_inactive ? "local_inactive " : "", - zevpn->vni); + dp_static ? "peer_sync " : "", zevpn->vni); /* Is this about a local neighbor or a remote one? */ if (!is_ext)