zebra: use new per-NS iteration in zebra_evpn

Use the new per-NS interface iteration apis in the evpn
module.

Signed-off-by: Mark Stapp <mjs@cisco.com>
This commit is contained in:
Mark Stapp 2024-10-23 12:34:36 -07:00
parent d349877aa5
commit 2b05d34a00
2 changed files with 99 additions and 136 deletions

View File

@ -610,70 +610,47 @@ void zebra_evpn_svi_macip_del_for_evpn_hash(struct hash_bucket *bucket,
return; return;
} }
static int zebra_evpn_map_vlan_ns(struct ns *ns, /* Callback for per-NS ifp walk */
void *_in_param, static int zebra_evpn_map_vlan_ns(struct interface *tmp_if, void *_in_param)
void **_p_zevpn)
{ {
int found = 0; bool found = false;
struct zebra_ns *zns = ns->info;
struct route_node *rn;
struct interface *br_if; struct interface *br_if;
struct zebra_evpn **p_zevpn = (struct zebra_evpn **)_p_zevpn;
struct zebra_evpn *zevpn; struct zebra_evpn *zevpn;
struct interface *tmp_if = NULL;
struct zebra_if *zif; struct zebra_if *zif;
struct zebra_from_svi_param *in_param = struct zebra_from_svi_param *in_param = _in_param;
(struct zebra_from_svi_param *)_in_param;
vlanid_t vid;
vni_t vni_id = 0; vni_t vni_id = 0;
uint8_t bridge_vlan_aware;
assert(p_zevpn && in_param); assert(in_param);
br_if = in_param->br_if; br_if = in_param->br_if;
assert(br_if); assert(br_if);
zif = in_param->zif; zif = in_param->zif;
assert(zif); assert(zif);
vid = in_param->vid;
bridge_vlan_aware = in_param->bridge_vlan_aware;
if (bridge_vlan_aware) { /*
vni_id = zebra_l2_bridge_if_vni_find(zif, vid); * See if this interface (or interface plus VLAN Id) maps to a
if (vni_id) * VxLAN
found = 1; */
} else { /* TODO: Optimize with a hash. */
/* zif = tmp_if->info;
* See if this interface (or interface plus VLAN Id) maps to a if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
* VxLAN goto done;
*/ if (!if_is_operative(tmp_if))
/* TODO: Optimize with a hash. */ goto done;
for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
tmp_if = (struct interface *)rn->info;
if (!tmp_if)
continue;
zif = tmp_if->info;
if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
continue;
if (!if_is_operative(tmp_if))
continue;
if (zif->brslave_info.br_if != br_if) if (zif->brslave_info.br_if != br_if)
continue; goto done;
vni_id = zebra_vxlan_if_access_vlan_vni_find(zif, br_if); vni_id = zebra_vxlan_if_access_vlan_vni_find(zif, br_if);
if (vni_id) { if (vni_id)
found = 1; found = true;
route_unlock_node(rn);
break;
}
}
}
done:
if (!found) if (!found)
return NS_WALK_CONTINUE; return NS_WALK_CONTINUE;
zevpn = zebra_evpn_lookup(vni_id); zevpn = zebra_evpn_lookup(vni_id);
*p_zevpn = zevpn; in_param->zevpn = zevpn;
return NS_WALK_STOP; return NS_WALK_STOP;
} }
@ -685,42 +662,39 @@ struct zebra_evpn *zebra_evpn_map_vlan(struct interface *ifp,
struct interface *br_if, vlanid_t vid) struct interface *br_if, vlanid_t vid)
{ {
struct zebra_if *zif; struct zebra_if *zif;
struct zebra_evpn **p_zevpn; struct zebra_from_svi_param in_param = {};
struct zebra_evpn *zevpn = NULL; vni_t vni_id = 0;
struct zebra_from_svi_param in_param;
/* Determine if bridge is VLAN-aware or not */ /* Determine if bridge is VLAN-aware or not */
zif = br_if->info; zif = br_if->info;
assert(zif); assert(zif);
in_param.bridge_vlan_aware = IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(zif);
/* Special case for vlan */
if (IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(zif)) {
vni_id = zebra_l2_bridge_if_vni_find(zif, vid);
if (vni_id)
return zebra_evpn_lookup(vni_id);
}
in_param.vid = vid; in_param.vid = vid;
in_param.br_if = br_if; in_param.br_if = br_if;
in_param.zif = zif; in_param.zif = zif;
p_zevpn = &zevpn;
ns_walk_func(zebra_evpn_map_vlan_ns, (void *)&in_param, (void **)p_zevpn); zebra_ns_ifp_walk_all(zebra_evpn_map_vlan_ns, &in_param);
return zevpn;
return in_param.zevpn;
} }
static int zebra_evpn_from_svi_ns(struct ns *ns, /* Callback for from_svi ifp walker */
void *_in_param, static int zebra_evpn_from_svi_ns(struct interface *tmp_if, void *_in_param)
void **_p_zevpn)
{ {
struct zebra_ns *zns = ns->info;
struct route_node *rn;
struct interface *br_if; struct interface *br_if;
struct zebra_evpn **p_zevpn = (struct zebra_evpn **)_p_zevpn;
struct zebra_evpn *zevpn; struct zebra_evpn *zevpn;
struct interface *tmp_if = NULL;
struct zebra_if *zif; struct zebra_if *zif;
struct zebra_if *br_zif; struct zebra_if *br_zif;
struct zebra_l2_bridge_vlan *bvlan; struct zebra_from_svi_param *in_param = _in_param;
struct zebra_from_svi_param *in_param = bool found = false;
(struct zebra_from_svi_param *)_in_param;
int found = 0;
vni_t vni_id = 0; vni_t vni_id = 0;
vlanid_t vid = 0;
uint8_t bridge_vlan_aware;
if (!in_param) if (!in_param)
return NS_WALK_STOP; return NS_WALK_STOP;
@ -728,48 +702,30 @@ static int zebra_evpn_from_svi_ns(struct ns *ns,
br_if = in_param->br_if; br_if = in_param->br_if;
zif = in_param->zif; zif = in_param->zif;
assert(zif); assert(zif);
bridge_vlan_aware = in_param->bridge_vlan_aware;
vid = in_param->vid;
br_zif = br_if->info; br_zif = br_if->info;
assert(br_zif); assert(br_zif);
if (bridge_vlan_aware) { if (!tmp_if)
bvlan = zebra_l2_bridge_if_vlan_find(br_zif, vid); goto done;
if (bvlan && bvlan->access_bd && bvlan->access_bd->vni) { zif = tmp_if->info;
found = 1; if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
vni_id = bvlan->access_bd->vni; goto done;
} if (!if_is_operative(tmp_if))
} else { goto done;
/* TODO: Optimize with a hash. */
for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
tmp_if = (struct interface *)rn->info;
if (!tmp_if)
continue;
zif = tmp_if->info;
if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
continue;
if (!if_is_operative(tmp_if))
continue;
if (zif->brslave_info.br_if != br_if) if (zif->brslave_info.br_if != br_if)
continue; goto done;
vni_id = vni_id = zebra_vxlan_if_access_vlan_vni_find(zif, br_if);
zebra_vxlan_if_access_vlan_vni_find(zif, br_if); if (vni_id)
if (vni_id) { found = true;
found = 1;
route_unlock_node(rn);
break;
}
}
}
done:
if (!found) if (!found)
return NS_WALK_CONTINUE; return NS_WALK_CONTINUE;
zevpn = zebra_evpn_lookup(vni_id); zevpn = zebra_evpn_lookup(vni_id);
if (p_zevpn) in_param->zevpn = zevpn;
*p_zevpn = zevpn;
return NS_WALK_STOP; return NS_WALK_STOP;
} }
@ -780,17 +736,21 @@ static int zebra_evpn_from_svi_ns(struct ns *ns,
struct zebra_evpn *zebra_evpn_from_svi(struct interface *ifp, struct zebra_evpn *zebra_evpn_from_svi(struct interface *ifp,
struct interface *br_if) struct interface *br_if)
{ {
struct zebra_evpn *zevpn = NULL;
struct zebra_evpn **p_zevpn;
struct zebra_if *zif; struct zebra_if *zif;
struct zebra_from_svi_param in_param; struct zebra_l2_bridge_vlan *bvlan;
struct zebra_from_svi_param in_param = {};
vni_t vni_id = 0;
struct zebra_evpn *zevpn;
struct zebra_l2info_vlan *vl;
if (!br_if) if (!br_if)
return NULL; return NULL;
/* Make sure the linked interface is a bridge. */ /* Make sure the linked interface is a bridge. */
if (!IS_ZEBRA_IF_BRIDGE(br_if)) if (!IS_ZEBRA_IF_BRIDGE(br_if)) {
zlog_debug("%s: br_if NOT a bridge", __func__);
return NULL; return NULL;
}
/* Determine if bridge is VLAN-aware or not */ /* Determine if bridge is VLAN-aware or not */
zif = br_if->info; zif = br_if->info;
@ -798,57 +758,60 @@ struct zebra_evpn *zebra_evpn_from_svi(struct interface *ifp,
in_param.bridge_vlan_aware = IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(zif); in_param.bridge_vlan_aware = IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(zif);
in_param.vid = 0; in_param.vid = 0;
/* Don't need to search in this case */
if (in_param.bridge_vlan_aware) { if (in_param.bridge_vlan_aware) {
struct zebra_l2info_vlan *vl;
if (!IS_ZEBRA_IF_VLAN(ifp)) if (!IS_ZEBRA_IF_VLAN(ifp))
return NULL; return NULL;
zevpn = NULL;
zif = ifp->info; zif = ifp->info;
assert(zif); assert(zif);
vl = &zif->l2info.vl; vl = &zif->l2info.vl;
in_param.vid = vl->vid; in_param.vid = vl->vid;
bvlan = zebra_l2_bridge_if_vlan_find(br_if->info, vl->vid);
if (bvlan && bvlan->access_bd && bvlan->access_bd->vni) {
vni_id = bvlan->access_bd->vni;
zevpn = zebra_evpn_lookup(vni_id);
}
return zevpn;
} }
/* See if this interface (or interface plus VLAN Id) maps to a VxLAN:
* search all NSes
*/
in_param.br_if = br_if; in_param.br_if = br_if;
in_param.zif = zif; in_param.zif = zif;
p_zevpn = &zevpn; zebra_ns_ifp_walk_all(zebra_evpn_from_svi_ns, &in_param);
/* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
ns_walk_func(zebra_evpn_from_svi_ns, (void *)&in_param, return in_param.zevpn;
(void **)p_zevpn);
return zevpn;
} }
static int zvni_map_to_macvlan_ns(struct ns *ns, void *_in_param, void **_p_ifp) static int zvni_map_to_macvlan_ns(struct interface *tmp_if, void *_in_param)
{ {
struct zebra_ns *zns = ns->info; struct zebra_from_svi_param *in_param = _in_param;
struct zebra_from_svi_param *in_param =
(struct zebra_from_svi_param *)_in_param;
struct interface **p_ifp = (struct interface **)_p_ifp;
struct route_node *rn;
struct interface *tmp_if = NULL;
struct zebra_if *zif; struct zebra_if *zif;
assert(in_param && p_ifp); assert(in_param);
/* Identify corresponding VLAN interface. */ /* Identify corresponding VLAN interface. */
for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
tmp_if = (struct interface *)rn->info;
/* Check oper status of the SVI. */
if (!tmp_if || !if_is_operative(tmp_if))
continue;
zif = tmp_if->info;
if (!zif || zif->zif_type != ZEBRA_IF_MACVLAN) /* Check oper status of the SVI. */
continue; if (!tmp_if || !if_is_operative(tmp_if))
goto done;
if (zif->link == in_param->svi_if) { zif = tmp_if->info;
*p_ifp = tmp_if; if (!zif || zif->zif_type != ZEBRA_IF_MACVLAN)
route_unlock_node(rn); goto done;
return NS_WALK_STOP;
} if (zif->link == in_param->svi_if) {
in_param->ret_ifp = tmp_if;
return NS_WALK_STOP;
} }
done:
return NS_WALK_CONTINUE; return NS_WALK_CONTINUE;
} }
@ -857,17 +820,16 @@ static int zvni_map_to_macvlan_ns(struct ns *ns, void *_in_param, void **_p_ifp)
struct interface *zebra_evpn_map_to_macvlan(struct interface *br_if, struct interface *zebra_evpn_map_to_macvlan(struct interface *br_if,
struct interface *svi_if) struct interface *svi_if)
{ {
struct interface *tmp_if = NULL;
struct zebra_if *zif; struct zebra_if *zif;
struct interface **p_ifp; struct zebra_from_svi_param in_param = {};
struct zebra_from_svi_param in_param;
/* Defensive check, caller expected to invoke only with valid bridge. */ /* Defensive check, caller expected to invoke only with valid bridge. */
if (!br_if) if (!br_if)
return NULL; return NULL;
if (!svi_if) { if (!svi_if) {
zlog_debug("svi_if is not passed."); if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug("%s: svi_if is not passed.", __func__);
return NULL; return NULL;
} }
@ -879,11 +841,10 @@ struct interface *zebra_evpn_map_to_macvlan(struct interface *br_if,
in_param.br_if = br_if; in_param.br_if = br_if;
in_param.zif = NULL; in_param.zif = NULL;
in_param.svi_if = svi_if; in_param.svi_if = svi_if;
p_ifp = &tmp_if;
/* Identify corresponding VLAN interface. */ /* Identify corresponding VLAN interface. */
ns_walk_func(zvni_map_to_macvlan_ns, (void *)&in_param, (void **)p_ifp); zebra_ns_ifp_walk_all(zvni_map_to_macvlan_ns, &in_param);
return tmp_if; return in_param.ret_ifp;
} }
/* /*

View File

@ -116,7 +116,9 @@ struct zebra_evpn {
struct zebra_from_svi_param { struct zebra_from_svi_param {
struct interface *br_if; struct interface *br_if;
struct interface *svi_if; struct interface *svi_if;
struct interface *ret_ifp;
struct zebra_if *zif; struct zebra_if *zif;
struct zebra_evpn *zevpn;
uint8_t bridge_vlan_aware; uint8_t bridge_vlan_aware;
vlanid_t vid; vlanid_t vid;
}; };