diff options
Diffstat (limited to 'zebra/zebra_evpn_mac.c')
| -rw-r--r-- | zebra/zebra_evpn_mac.c | 58 |
1 files changed, 35 insertions, 23 deletions
diff --git a/zebra/zebra_evpn_mac.c b/zebra/zebra_evpn_mac.c index e38766bc6b..46d789bc34 100644 --- a/zebra/zebra_evpn_mac.c +++ b/zebra/zebra_evpn_mac.c @@ -1141,14 +1141,6 @@ int zebra_evpn_mac_del(struct zebra_evpn *zevpn, struct zebra_mac *mac) sizeof(mac_buf))); } - /* If the MAC is freed before the neigh we will end up - * with a stale pointer against the neigh - */ - if (!list_isempty(mac->neigh_list)) - zlog_warn("%s: MAC %pEA flags 0x%x neigh list not empty %d", - __func__, &mac->macaddr, mac->flags, - listcount(mac->neigh_list)); - /* force de-ref any ES entry linked to the MAC */ zebra_evpn_es_mac_deref_entry(mac); @@ -1161,6 +1153,26 @@ int zebra_evpn_mac_del(struct zebra_evpn *zevpn, struct zebra_mac *mac) /* Cancel auto recovery */ THREAD_OFF(mac->dad_mac_auto_recovery_timer); + /* If the MAC is freed before the neigh we will end up + * with a stale pointer against the neigh. + * The situation can arise when a MAC is in remote state + * and its associated neigh is local state. + * zebra_evpn_cfg_cleanup() cleans up remote neighs and MACs. + * Instead of deleting remote MAC, if its neigh list is non-empty + * (associated to local neighs), mark the MAC as AUTO. + */ + if (!list_isempty(mac->neigh_list)) { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug( + "MAC %pEA (flags 0x%x vni %u) has non-empty neigh list " + "count %u, mark MAC as AUTO", + &mac->macaddr, mac->flags, zevpn->vni, + listcount(mac->neigh_list)); + + SET_FLAG(mac->flags, ZEBRA_MAC_AUTO); + return 0; + } + list_delete(&mac->neigh_list); /* Free the VNI hash entry and allocated memory. */ @@ -2452,11 +2464,12 @@ int zebra_evpn_del_local_mac(struct zebra_evpn *zevpn, struct zebra_mac *mac, return 0; } -int zebra_evpn_mac_gw_macip_add(struct interface *ifp, struct zebra_evpn *zevpn, - const struct ipaddr *ip, - struct zebra_mac **macp, - const struct ethaddr *macaddr, vlanid_t vlan_id, - bool def_gw) +void zebra_evpn_mac_gw_macip_add(struct interface *ifp, + struct zebra_evpn *zevpn, + const struct ipaddr *ip, + struct zebra_mac **macp, + const struct ethaddr *macaddr, + vlanid_t vlan_id, bool def_gw) { struct zebra_mac *mac; ns_id_t local_ns_id = NS_DEFAULT; @@ -2466,9 +2479,13 @@ int zebra_evpn_mac_gw_macip_add(struct interface *ifp, struct zebra_evpn *zevpn, if (zvrf && zvrf->zns) local_ns_id = zvrf->zns->ns_id; - mac = zebra_evpn_mac_lookup(zevpn, macaddr); - if (!mac) - mac = zebra_evpn_mac_add(zevpn, macaddr); + if (!*macp) { + mac = zebra_evpn_mac_lookup(zevpn, macaddr); + if (!mac) + mac = zebra_evpn_mac_add(zevpn, macaddr); + *macp = mac; + } else + mac = *macp; /* Set "local" forwarding info. */ zebra_evpn_mac_clear_fwd_info(mac); @@ -2476,13 +2493,11 @@ int zebra_evpn_mac_gw_macip_add(struct interface *ifp, struct zebra_evpn *zevpn, SET_FLAG(mac->flags, ZEBRA_MAC_AUTO); if (def_gw) SET_FLAG(mac->flags, ZEBRA_MAC_DEF_GW); + else + SET_FLAG(mac->flags, ZEBRA_MAC_SVI); mac->fwd_info.local.ifindex = ifp->ifindex; mac->fwd_info.local.ns_id = local_ns_id; mac->fwd_info.local.vid = vlan_id; - - *macp = mac; - - return 0; } void zebra_evpn_mac_svi_del(struct interface *ifp, struct zebra_evpn *zevpn) @@ -2535,10 +2550,7 @@ void zebra_evpn_mac_svi_add(struct interface *ifp, struct zebra_evpn *zevpn) ? true : false; - mac = NULL; zebra_evpn_mac_gw_macip_add(ifp, zevpn, NULL, &mac, &macaddr, 0, false); - if (mac) - SET_FLAG(mac->flags, ZEBRA_MAC_SVI); new_bgp_ready = zebra_evpn_mac_is_ready_for_bgp(mac->flags); zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready, |
