mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 02:30:38 +00:00
zebra: extract local mac add code from vxlan
extract the local mac add code from zebra_vxlan_local_mac_add_update and create a new generic local mac add function zebra_evpn_add_update_local_mac Signed-off-by: Pat Ruddy <pat@voltanet.io>
This commit is contained in:
parent
19fdd1be29
commit
d9d3455e09
@ -226,8 +226,9 @@ void zebra_evpn_deref_ip2mac(zebra_evpn_t *zevpn, zebra_mac_t *mac)
|
||||
zebra_evpn_mac_del(zevpn, mac);
|
||||
}
|
||||
|
||||
void zebra_evpn_mac_get_access_info(zebra_mac_t *mac, struct interface **ifpP,
|
||||
vlanid_t *vid)
|
||||
static void zebra_evpn_mac_get_access_info(zebra_mac_t *mac,
|
||||
struct interface **ifpP,
|
||||
vlanid_t *vid)
|
||||
{
|
||||
/* if the mac is associated with an ES we must get the access
|
||||
* info from the ES
|
||||
@ -329,10 +330,11 @@ static int zebra_evpn_dad_mac_auto_recovery_exp(struct thread *t)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void zebra_evpn_dup_addr_detect_for_mac(struct zebra_vrf *zvrf,
|
||||
zebra_mac_t *mac,
|
||||
struct in_addr vtep_ip, bool do_dad,
|
||||
bool *is_dup_detect, bool is_local)
|
||||
static void zebra_evpn_dup_addr_detect_for_mac(struct zebra_vrf *zvrf,
|
||||
zebra_mac_t *mac,
|
||||
struct in_addr vtep_ip,
|
||||
bool do_dad, bool *is_dup_detect,
|
||||
bool is_local)
|
||||
{
|
||||
zebra_neigh_t *nbr;
|
||||
struct listnode *node = NULL;
|
||||
@ -1602,8 +1604,9 @@ zebra_evpn_proc_sync_mac_update(zebra_evpn_t *zevpn, struct ethaddr *macaddr,
|
||||
/* update local fowarding info. return true if a dest-ES change
|
||||
* is detected
|
||||
*/
|
||||
bool zebra_evpn_local_mac_update_fwd_info(zebra_mac_t *mac,
|
||||
struct interface *ifp, vlanid_t vid)
|
||||
static bool zebra_evpn_local_mac_update_fwd_info(zebra_mac_t *mac,
|
||||
struct interface *ifp,
|
||||
vlanid_t vid)
|
||||
{
|
||||
struct zebra_if *zif = ifp->info;
|
||||
bool es_change;
|
||||
@ -1877,3 +1880,240 @@ int process_mac_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf,
|
||||
*macp = mac;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, zebra_evpn_t *zevpn,
|
||||
struct interface *ifp,
|
||||
struct ethaddr *macaddr, vlanid_t vid,
|
||||
bool sticky, bool local_inactive,
|
||||
bool dp_static)
|
||||
{
|
||||
zebra_mac_t *mac;
|
||||
char buf[ETHER_ADDR_STRLEN];
|
||||
bool mac_sticky = false;
|
||||
bool inform_client = false;
|
||||
bool upd_neigh = false;
|
||||
bool is_dup_detect = false;
|
||||
struct in_addr vtep_ip = {.s_addr = 0};
|
||||
bool es_change = false;
|
||||
bool new_bgp_ready;
|
||||
/* assume inactive if not present or if not local */
|
||||
bool old_local_inactive = true;
|
||||
bool old_bgp_ready = false;
|
||||
bool inform_dataplane = false;
|
||||
bool new_static = false;
|
||||
|
||||
/* Check if we need to create or update or it is a NO-OP. */
|
||||
mac = zebra_evpn_mac_lookup(zevpn, macaddr);
|
||||
if (!mac) {
|
||||
if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
|
||||
zlog_debug(
|
||||
"ADD %sMAC %s intf %s(%u) VID %u -> VNI %u%s",
|
||||
sticky ? "sticky " : "",
|
||||
prefix_mac2str(macaddr, buf, sizeof(buf)),
|
||||
ifp->name, ifp->ifindex, vid, zevpn->vni,
|
||||
local_inactive ? " local-inactive" : "");
|
||||
|
||||
mac = zebra_evpn_mac_add(zevpn, macaddr);
|
||||
if (!mac) {
|
||||
flog_err(
|
||||
EC_ZEBRA_MAC_ADD_FAILED,
|
||||
"Failed to add MAC %s intf %s(%u) VID %u VNI %u",
|
||||
prefix_mac2str(macaddr, buf, sizeof(buf)),
|
||||
ifp->name, ifp->ifindex, vid, zevpn->vni);
|
||||
return -1;
|
||||
}
|
||||
SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
|
||||
es_change = zebra_evpn_local_mac_update_fwd_info(mac, ifp, vid);
|
||||
if (sticky)
|
||||
SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
|
||||
inform_client = true;
|
||||
} else {
|
||||
if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
|
||||
zlog_debug(
|
||||
"UPD %sMAC %s intf %s(%u) VID %u -> VNI %u %scurFlags 0x%x",
|
||||
sticky ? "sticky " : "",
|
||||
prefix_mac2str(macaddr, buf, sizeof(buf)),
|
||||
ifp->name, ifp->ifindex, vid, zevpn->vni,
|
||||
local_inactive ? "local-inactive " : "",
|
||||
mac->flags);
|
||||
|
||||
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
|
||||
struct interface *old_ifp;
|
||||
vlanid_t old_vid;
|
||||
bool old_static;
|
||||
|
||||
zebra_evpn_mac_get_access_info(mac, &old_ifp, &old_vid);
|
||||
old_bgp_ready =
|
||||
zebra_evpn_mac_is_ready_for_bgp(mac->flags);
|
||||
old_local_inactive =
|
||||
!!(mac->flags & ZEBRA_MAC_LOCAL_INACTIVE);
|
||||
old_static = zebra_evpn_mac_is_static(mac);
|
||||
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY))
|
||||
mac_sticky = true;
|
||||
|
||||
/*
|
||||
* Update any changes and if changes are relevant to
|
||||
* BGP, note it.
|
||||
*/
|
||||
if (mac_sticky == sticky && old_ifp == ifp
|
||||
&& old_vid == vid
|
||||
&& old_local_inactive == local_inactive
|
||||
&& dp_static == old_static) {
|
||||
if (IS_ZEBRA_DEBUG_VXLAN)
|
||||
zlog_debug(
|
||||
" Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u%s, "
|
||||
"entry exists and has not changed ",
|
||||
sticky ? "sticky " : "",
|
||||
prefix_mac2str(macaddr, buf,
|
||||
sizeof(buf)),
|
||||
ifp->name, ifp->ifindex, vid,
|
||||
zevpn->vni,
|
||||
local_inactive
|
||||
? " local_inactive"
|
||||
: "");
|
||||
return 0;
|
||||
}
|
||||
if (mac_sticky != sticky) {
|
||||
if (sticky)
|
||||
SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
|
||||
else
|
||||
UNSET_FLAG(mac->flags,
|
||||
ZEBRA_MAC_STICKY);
|
||||
inform_client = true;
|
||||
}
|
||||
|
||||
es_change = zebra_evpn_local_mac_update_fwd_info(
|
||||
mac, ifp, vid);
|
||||
/* If an es_change is detected we need to advertise
|
||||
* the route with a sequence that is one
|
||||
* greater. This is need to indicate a mac-move
|
||||
* to the ES peers
|
||||
*/
|
||||
if (es_change) {
|
||||
mac->loc_seq = mac->loc_seq + 1;
|
||||
/* force drop the peer/sync info as it is
|
||||
* simply no longer relevant
|
||||
*/
|
||||
if (CHECK_FLAG(mac->flags,
|
||||
ZEBRA_MAC_ALL_PEER_FLAGS)) {
|
||||
zebra_evpn_mac_clear_sync_info(mac);
|
||||
new_static =
|
||||
zebra_evpn_mac_is_static(mac);
|
||||
/* if we clear peer-flags we
|
||||
* also need to notify the dataplane
|
||||
* to drop the static flag
|
||||
*/
|
||||
if (old_static != new_static)
|
||||
inform_dataplane = true;
|
||||
}
|
||||
}
|
||||
} else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)
|
||||
|| CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) {
|
||||
bool do_dad = false;
|
||||
|
||||
/*
|
||||
* MAC has either moved or was "internally" created due
|
||||
* to a neighbor learn and is now actually learnt. If
|
||||
* it was learnt as a remote sticky MAC, this is an
|
||||
* operator error.
|
||||
*/
|
||||
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)) {
|
||||
flog_warn(
|
||||
EC_ZEBRA_STICKY_MAC_ALREADY_LEARNT,
|
||||
"MAC %s already learnt as remote sticky MAC behind VTEP %s VNI %u",
|
||||
prefix_mac2str(macaddr, buf,
|
||||
sizeof(buf)),
|
||||
inet_ntoa(mac->fwd_info.r_vtep_ip),
|
||||
zevpn->vni);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If an actual move, compute MAC's seq number */
|
||||
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
|
||||
mac->loc_seq =
|
||||
MAX(mac->rem_seq + 1, mac->loc_seq);
|
||||
vtep_ip = mac->fwd_info.r_vtep_ip;
|
||||
/* Trigger DAD for remote MAC */
|
||||
do_dad = true;
|
||||
}
|
||||
|
||||
UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
|
||||
UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
|
||||
SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
|
||||
es_change = zebra_evpn_local_mac_update_fwd_info(
|
||||
mac, ifp, vid);
|
||||
if (sticky)
|
||||
SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
|
||||
else
|
||||
UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
|
||||
/*
|
||||
* We have to inform BGP of this MAC as well as process
|
||||
* all neighbors.
|
||||
*/
|
||||
inform_client = true;
|
||||
upd_neigh = true;
|
||||
|
||||
zebra_evpn_dup_addr_detect_for_mac(
|
||||
zvrf, mac, vtep_ip, do_dad, &is_dup_detect,
|
||||
true);
|
||||
if (is_dup_detect) {
|
||||
inform_client = false;
|
||||
upd_neigh = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if the dataplane thinks the entry is sync but it is
|
||||
* not sync in zebra we need to re-install to fixup
|
||||
*/
|
||||
if (dp_static) {
|
||||
new_static = zebra_evpn_mac_is_static(mac);
|
||||
if (!new_static)
|
||||
inform_dataplane = true;
|
||||
}
|
||||
|
||||
if (local_inactive)
|
||||
SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL_INACTIVE);
|
||||
else
|
||||
UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL_INACTIVE);
|
||||
|
||||
new_bgp_ready = zebra_evpn_mac_is_ready_for_bgp(mac->flags);
|
||||
/* if local-activity has changed we need update bgp
|
||||
* even if bgp already knows about the mac
|
||||
*/
|
||||
if ((old_local_inactive != local_inactive)
|
||||
|| (new_bgp_ready != old_bgp_ready)) {
|
||||
if (IS_ZEBRA_DEBUG_EVPN_MH_MAC)
|
||||
zlog_debug(
|
||||
"local mac vni %u mac %s es %s seq %d f 0x%x%s",
|
||||
zevpn->vni,
|
||||
prefix_mac2str(macaddr, buf, sizeof(buf)),
|
||||
mac->es ? mac->es->esi_str : "", mac->loc_seq,
|
||||
mac->flags,
|
||||
local_inactive ? " local-inactive" : "");
|
||||
inform_client = true;
|
||||
}
|
||||
|
||||
if (es_change) {
|
||||
inform_client = true;
|
||||
upd_neigh = true;
|
||||
}
|
||||
|
||||
/* Inform dataplane if required. */
|
||||
if (inform_dataplane)
|
||||
zebra_evpn_sync_mac_dp_install(mac, false /* set_inactive */,
|
||||
false /* force_clear_static */,
|
||||
__func__);
|
||||
|
||||
/* Inform BGP if required. */
|
||||
if (inform_client)
|
||||
zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready,
|
||||
new_bgp_ready);
|
||||
|
||||
/* Process all neighbors associated with this MAC, if required. */
|
||||
if (upd_neigh)
|
||||
zebra_evpn_process_neigh_on_local_mac_change(zevpn, mac, 0,
|
||||
es_change);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -205,8 +205,6 @@ int zebra_evpn_rem_mac_uninstall(zebra_evpn_t *zevi, zebra_mac_t *mac);
|
||||
int zebra_evpn_rem_mac_install(zebra_evpn_t *zevi, zebra_mac_t *mac,
|
||||
bool was_static);
|
||||
void zebra_evpn_deref_ip2mac(zebra_evpn_t *zevi, zebra_mac_t *mac);
|
||||
void zebra_evpn_mac_get_access_info(zebra_mac_t *mac, struct interface **ifpP,
|
||||
vlanid_t *vid);
|
||||
zebra_mac_t *zebra_evpn_mac_lookup(zebra_evpn_t *zevi, struct ethaddr *mac);
|
||||
zebra_mac_t *zebra_evpn_mac_add(zebra_evpn_t *zevi, struct ethaddr *macaddr);
|
||||
int zebra_evpn_mac_del(zebra_evpn_t *zevi, zebra_mac_t *mac);
|
||||
@ -214,18 +212,14 @@ int zebra_evpn_macip_send_msg_to_client(uint32_t id, struct ethaddr *macaddr,
|
||||
struct ipaddr *ip, uint8_t flags,
|
||||
uint32_t seq, int state,
|
||||
struct zebra_evpn_es *es, uint16_t cmd);
|
||||
void zebra_evpn_mac_send_add_del_to_client(zebra_mac_t *mac, bool old_bgp_ready,
|
||||
bool new_bgp_ready);
|
||||
void zebra_evpn_dup_addr_detect_for_mac(struct zebra_vrf *zvrf,
|
||||
zebra_mac_t *mac,
|
||||
struct in_addr vtep_ip, bool do_dad,
|
||||
bool *is_dup_detect, bool is_local);
|
||||
void zebra_evpn_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json);
|
||||
void zebra_evpn_print_mac_hash(struct hash_bucket *bucket, void *ctxt);
|
||||
void zebra_evpn_print_mac_hash_detail(struct hash_bucket *bucket, void *ctxt);
|
||||
void zebra_evpn_sync_mac_dp_install(zebra_mac_t *mac, bool set_inactive,
|
||||
bool force_clear_static,
|
||||
const char *caller);
|
||||
void zebra_evpn_mac_send_add_del_to_client(zebra_mac_t *mac, bool old_bgp_ready,
|
||||
bool new_bgp_ready);
|
||||
|
||||
void zebra_evpn_mac_del_all(zebra_evpn_t *zevi, int uninstall, int upd_client,
|
||||
uint32_t flags);
|
||||
@ -251,12 +245,11 @@ int process_mac_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf,
|
||||
struct in_addr vtep_ip, uint8_t flags,
|
||||
uint32_t seq, esi_t *esi);
|
||||
|
||||
// remove later
|
||||
void zebra_evpn_mac_send_add_del_to_client(zebra_mac_t *mac, bool old_bgp_ready,
|
||||
bool new_bgp_ready);
|
||||
bool zebra_evpn_local_mac_update_fwd_info(zebra_mac_t *mac,
|
||||
struct interface *ifp, vlanid_t vid);
|
||||
|
||||
int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, zebra_evpn_t *zevpn,
|
||||
struct interface *ifp,
|
||||
struct ethaddr *macaddr, vlanid_t vid,
|
||||
bool sticky, bool local_inactive,
|
||||
bool dp_static);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -7998,21 +7998,8 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp,
|
||||
bool dp_static)
|
||||
{
|
||||
zebra_evpn_t *zevpn;
|
||||
zebra_mac_t *mac;
|
||||
struct zebra_vrf *zvrf;
|
||||
char buf[ETHER_ADDR_STRLEN];
|
||||
bool mac_sticky = false;
|
||||
bool inform_client = false;
|
||||
bool upd_neigh = false;
|
||||
bool is_dup_detect = false;
|
||||
struct in_addr vtep_ip = {.s_addr = 0};
|
||||
bool es_change = false;
|
||||
bool new_bgp_ready;
|
||||
/* assume inactive if not present or if not local */
|
||||
bool old_local_inactive = true;
|
||||
bool old_bgp_ready = false;
|
||||
bool inform_dataplane = false;
|
||||
bool new_static = false;
|
||||
|
||||
if (ifp == NULL)
|
||||
return -1;
|
||||
@ -8047,222 +8034,9 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check if we need to create or update or it is a NO-OP. */
|
||||
mac = zebra_evpn_mac_lookup(zevpn, macaddr);
|
||||
if (!mac) {
|
||||
if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
|
||||
zlog_debug(
|
||||
"ADD %sMAC %s intf %s(%u) VID %u -> VNI %u%s",
|
||||
sticky ? "sticky " : "",
|
||||
prefix_mac2str(macaddr, buf, sizeof(buf)),
|
||||
ifp->name, ifp->ifindex, vid, zevpn->vni,
|
||||
local_inactive ? " local-inactive" : "");
|
||||
|
||||
mac = zebra_evpn_mac_add(zevpn, macaddr);
|
||||
if (!mac) {
|
||||
flog_err(
|
||||
EC_ZEBRA_MAC_ADD_FAILED,
|
||||
"Failed to add MAC %s intf %s(%u) VID %u VNI %u",
|
||||
prefix_mac2str(macaddr, buf, sizeof(buf)),
|
||||
ifp->name, ifp->ifindex, vid, zevpn->vni);
|
||||
return -1;
|
||||
}
|
||||
SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
|
||||
es_change = zebra_evpn_local_mac_update_fwd_info(mac, ifp, vid);
|
||||
if (sticky)
|
||||
SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
|
||||
inform_client = true;
|
||||
} else {
|
||||
if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC)
|
||||
zlog_debug(
|
||||
"UPD %sMAC %s intf %s(%u) VID %u -> VNI %u %scurFlags 0x%x",
|
||||
sticky ? "sticky " : "",
|
||||
prefix_mac2str(macaddr, buf, sizeof(buf)),
|
||||
ifp->name, ifp->ifindex, vid, zevpn->vni,
|
||||
local_inactive ? "local-inactive " : "",
|
||||
mac->flags);
|
||||
|
||||
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
|
||||
struct interface *old_ifp;
|
||||
vlanid_t old_vid;
|
||||
bool old_static;
|
||||
|
||||
zebra_evpn_mac_get_access_info(mac, &old_ifp, &old_vid);
|
||||
old_bgp_ready =
|
||||
zebra_evpn_mac_is_ready_for_bgp(mac->flags);
|
||||
old_local_inactive = !!(mac->flags &
|
||||
ZEBRA_MAC_LOCAL_INACTIVE);
|
||||
old_static = zebra_evpn_mac_is_static(mac);
|
||||
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY))
|
||||
mac_sticky = true;
|
||||
|
||||
/*
|
||||
* Update any changes and if changes are relevant to
|
||||
* BGP, note it.
|
||||
*/
|
||||
if (mac_sticky == sticky
|
||||
&& old_ifp == ifp
|
||||
&& old_vid == vid
|
||||
&& old_local_inactive == local_inactive
|
||||
&& dp_static == old_static) {
|
||||
if (IS_ZEBRA_DEBUG_VXLAN)
|
||||
zlog_debug(
|
||||
" Add/Update %sMAC %s intf %s(%u) VID %u -> VNI %u%s, entry exists and has not changed ",
|
||||
sticky ? "sticky " : "",
|
||||
prefix_mac2str(macaddr, buf,
|
||||
sizeof(buf)),
|
||||
ifp->name, ifp->ifindex, vid,
|
||||
zevpn->vni,
|
||||
local_inactive ?
|
||||
" local_inactive" : "");
|
||||
return 0;
|
||||
}
|
||||
if (mac_sticky != sticky) {
|
||||
if (sticky)
|
||||
SET_FLAG(mac->flags,
|
||||
ZEBRA_MAC_STICKY);
|
||||
else
|
||||
UNSET_FLAG(mac->flags,
|
||||
ZEBRA_MAC_STICKY);
|
||||
inform_client = true;
|
||||
}
|
||||
|
||||
es_change = zebra_evpn_local_mac_update_fwd_info(
|
||||
mac, ifp, vid);
|
||||
/* If an es_change is detected we need to advertise
|
||||
* the route with a sequence that is one
|
||||
* greater. This is need to indicate a mac-move
|
||||
* to the ES peers
|
||||
*/
|
||||
if (es_change) {
|
||||
mac->loc_seq = mac->loc_seq + 1;
|
||||
/* force drop the peer/sync info as it is
|
||||
* simply no longer relevant
|
||||
*/
|
||||
if (CHECK_FLAG(mac->flags,
|
||||
ZEBRA_MAC_ALL_PEER_FLAGS)) {
|
||||
zebra_evpn_mac_clear_sync_info(mac);
|
||||
new_static =
|
||||
zebra_evpn_mac_is_static(mac);
|
||||
/* if we clear peer-flags we
|
||||
* also need to notify the dataplane
|
||||
* to drop the static flag
|
||||
*/
|
||||
if (old_static != new_static)
|
||||
inform_dataplane = true;
|
||||
}
|
||||
}
|
||||
} else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) ||
|
||||
CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) {
|
||||
bool do_dad = false;
|
||||
|
||||
/*
|
||||
* MAC has either moved or was "internally" created due
|
||||
* to a neighbor learn and is now actually learnt. If
|
||||
* it was learnt as a remote sticky MAC, this is an
|
||||
* operator error.
|
||||
*/
|
||||
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)) {
|
||||
flog_warn(
|
||||
EC_ZEBRA_STICKY_MAC_ALREADY_LEARNT,
|
||||
"MAC %s already learnt as remote sticky MAC behind VTEP %s VNI %u",
|
||||
prefix_mac2str(macaddr, buf,
|
||||
sizeof(buf)),
|
||||
inet_ntoa(mac->fwd_info.r_vtep_ip),
|
||||
zevpn->vni);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If an actual move, compute MAC's seq number */
|
||||
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
|
||||
mac->loc_seq = MAX(mac->rem_seq + 1,
|
||||
mac->loc_seq);
|
||||
vtep_ip = mac->fwd_info.r_vtep_ip;
|
||||
/* Trigger DAD for remote MAC */
|
||||
do_dad = true;
|
||||
}
|
||||
|
||||
UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
|
||||
UNSET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
|
||||
SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
|
||||
es_change = zebra_evpn_local_mac_update_fwd_info(
|
||||
mac, ifp, vid);
|
||||
if (sticky)
|
||||
SET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
|
||||
else
|
||||
UNSET_FLAG(mac->flags, ZEBRA_MAC_STICKY);
|
||||
/*
|
||||
* We have to inform BGP of this MAC as well as process
|
||||
* all neighbors.
|
||||
*/
|
||||
inform_client = true;
|
||||
upd_neigh = true;
|
||||
|
||||
zebra_evpn_dup_addr_detect_for_mac(
|
||||
zvrf, mac, vtep_ip, do_dad, &is_dup_detect,
|
||||
true);
|
||||
if (is_dup_detect) {
|
||||
inform_client = false;
|
||||
upd_neigh = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if the dataplane thinks the entry is sync but it is
|
||||
* not sync in zebra we need to re-install to fixup
|
||||
*/
|
||||
if (dp_static) {
|
||||
new_static = zebra_evpn_mac_is_static(mac);
|
||||
if (!new_static)
|
||||
inform_dataplane = true;
|
||||
}
|
||||
|
||||
if (local_inactive)
|
||||
SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL_INACTIVE);
|
||||
else
|
||||
UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL_INACTIVE);
|
||||
|
||||
new_bgp_ready = zebra_evpn_mac_is_ready_for_bgp(mac->flags);
|
||||
/* if local-activity has changed we need update bgp
|
||||
* even if bgp already knows about the mac
|
||||
*/
|
||||
if ((old_local_inactive != local_inactive) ||
|
||||
(new_bgp_ready != old_bgp_ready)) {
|
||||
if (IS_ZEBRA_DEBUG_EVPN_MH_MAC)
|
||||
zlog_debug("local mac vni %u mac %s es %s seq %d f 0x%x%s",
|
||||
zevpn->vni,
|
||||
prefix_mac2str(macaddr,
|
||||
buf, sizeof(buf)),
|
||||
mac->es ? mac->es->esi_str : "",
|
||||
mac->loc_seq,
|
||||
mac->flags,
|
||||
local_inactive ?
|
||||
" local-inactive" : "");
|
||||
inform_client = true;
|
||||
}
|
||||
|
||||
if (es_change) {
|
||||
inform_client = true;
|
||||
upd_neigh = true;
|
||||
}
|
||||
|
||||
/* Inform dataplane if required. */
|
||||
if (inform_dataplane)
|
||||
zebra_evpn_sync_mac_dp_install(mac, false /* set_inactive */,
|
||||
false /* force_clear_static */,
|
||||
__func__);
|
||||
|
||||
/* Inform BGP if required. */
|
||||
if (inform_client)
|
||||
zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready,
|
||||
new_bgp_ready);
|
||||
|
||||
/* Process all neighbors associated with this MAC, if required. */
|
||||
if (upd_neigh)
|
||||
zebra_evpn_process_neigh_on_local_mac_change(zevpn, mac, 0,
|
||||
es_change);
|
||||
|
||||
return 0;
|
||||
return zebra_evpn_add_update_local_mac(zvrf, zevpn, ifp, macaddr, vid,
|
||||
sticky, local_inactive,
|
||||
dp_static);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user