mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 13:37:17 +02:00
zebra: use new per-NS ifp iterators in vxlan code
Replace use of the old if_table with the new per-NS ifp iterator apis in the zebra vxlan code. Signed-off-by: Mark Stapp <mjs@cisco.com>
This commit is contained in:
parent
c1160538ea
commit
8353cf5d4c
|
@ -119,6 +119,7 @@ struct zebra_from_svi_param {
|
||||||
struct interface *ret_ifp;
|
struct interface *ret_ifp;
|
||||||
struct zebra_if *zif;
|
struct zebra_if *zif;
|
||||||
struct zebra_evpn *zevpn;
|
struct zebra_evpn *zevpn;
|
||||||
|
struct zebra_l3vni *zl3vni;
|
||||||
uint8_t bridge_vlan_aware;
|
uint8_t bridge_vlan_aware;
|
||||||
vlanid_t vid;
|
vlanid_t vid;
|
||||||
};
|
};
|
||||||
|
|
|
@ -859,39 +859,30 @@ static void zl3vni_print_hash_detail(struct hash_bucket *bucket, void *data)
|
||||||
vty_out(vty, "\n");
|
vty_out(vty, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int zvni_map_to_svi_ns(struct ns *ns,
|
static int zvni_map_to_svi_ns(struct interface *tmp_if, void *_in_param)
|
||||||
void *_in_param,
|
|
||||||
void **_p_ifp)
|
|
||||||
{
|
{
|
||||||
struct zebra_ns *zns = ns->info;
|
struct zebra_from_svi_param *in_param = _in_param;
|
||||||
struct route_node *rn;
|
|
||||||
struct zebra_from_svi_param *in_param =
|
|
||||||
(struct zebra_from_svi_param *)_in_param;
|
|
||||||
struct zebra_l2info_vlan *vl;
|
struct zebra_l2info_vlan *vl;
|
||||||
struct interface *tmp_if = NULL;
|
|
||||||
struct interface **p_ifp = (struct interface **)_p_ifp;
|
|
||||||
struct zebra_if *zif;
|
struct zebra_if *zif;
|
||||||
|
|
||||||
assert(in_param && p_ifp);
|
assert(in_param);
|
||||||
|
|
||||||
/* TODO: Optimize with a hash. */
|
/* TODO: Optimize with a hash. */
|
||||||
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_VLAN
|
|
||||||
|| zif->link != in_param->br_if)
|
|
||||||
continue;
|
|
||||||
vl = (struct zebra_l2info_vlan *)&zif->l2info.vl;
|
|
||||||
|
|
||||||
if (vl->vid == in_param->vid) {
|
/* Check oper status of the SVI. */
|
||||||
*p_ifp = tmp_if;
|
if (!tmp_if || !if_is_operative(tmp_if))
|
||||||
route_unlock_node(rn);
|
goto done;
|
||||||
return NS_WALK_STOP;
|
zif = tmp_if->info;
|
||||||
}
|
if (!zif || zif->zif_type != ZEBRA_IF_VLAN || zif->link != in_param->br_if)
|
||||||
|
goto done;
|
||||||
|
vl = (struct zebra_l2info_vlan *)&zif->l2info.vl;
|
||||||
|
|
||||||
|
if (vl->vid == in_param->vid) {
|
||||||
|
in_param->ret_ifp = tmp_if;
|
||||||
|
return NS_WALK_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
return NS_WALK_CONTINUE;
|
return NS_WALK_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -904,10 +895,9 @@ static int zvni_map_to_svi_ns(struct ns *ns,
|
||||||
*/
|
*/
|
||||||
struct interface *zvni_map_to_svi(vlanid_t vid, struct interface *br_if)
|
struct interface *zvni_map_to_svi(vlanid_t vid, struct interface *br_if)
|
||||||
{
|
{
|
||||||
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 = {};
|
||||||
struct interface **p_ifp;
|
|
||||||
/* 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;
|
||||||
|
@ -922,12 +912,11 @@ struct interface *zvni_map_to_svi(vlanid_t vid, struct interface *br_if)
|
||||||
|
|
||||||
in_param.vid = vid;
|
in_param.vid = vid;
|
||||||
in_param.br_if = br_if;
|
in_param.br_if = br_if;
|
||||||
in_param.zif = NULL;
|
|
||||||
p_ifp = &tmp_if;
|
|
||||||
/* Identify corresponding VLAN interface. */
|
/* Identify corresponding VLAN interface. */
|
||||||
ns_walk_func(zvni_map_to_svi_ns, (void *)&in_param,
|
zebra_ns_ifp_walk_all(zvni_map_to_svi_ns, &in_param);
|
||||||
(void **)p_ifp);
|
|
||||||
return tmp_if;
|
return in_param.ret_ifp;
|
||||||
}
|
}
|
||||||
|
|
||||||
int zebra_evpn_vxlan_del(struct zebra_evpn *zevpn)
|
int zebra_evpn_vxlan_del(struct zebra_evpn *zevpn)
|
||||||
|
@ -1007,9 +996,9 @@ static int zevpn_build_vni_hash_table(struct zebra_if *zif,
|
||||||
*/
|
*/
|
||||||
zevpn = zebra_evpn_lookup(vni);
|
zevpn = zebra_evpn_lookup(vni);
|
||||||
if (zevpn) {
|
if (zevpn) {
|
||||||
zlog_debug(
|
if (IS_ZEBRA_DEBUG_VXLAN)
|
||||||
"EVPN hash already present for IF %s(%u) L2-VNI %u",
|
zlog_debug("EVPN hash already present for IF %s(%u) L2-VNI %u",
|
||||||
ifp->name, ifp->ifindex, vni);
|
ifp->name, ifp->ifindex, vni);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Inform BGP if intf is up and mapped to
|
* Inform BGP if intf is up and mapped to
|
||||||
|
@ -1072,48 +1061,32 @@ static int zevpn_build_vni_hash_table(struct zebra_if *zif,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int zevpn_build_hash_table_zns(struct ns *ns,
|
static int zevpn_build_hash_table_zns(struct interface *ifp, void *arg)
|
||||||
void *param_in __attribute__((unused)),
|
|
||||||
void **param_out __attribute__((unused)))
|
|
||||||
{
|
{
|
||||||
struct zebra_ns *zns = ns->info;
|
struct zebra_vrf *zvrf = arg;
|
||||||
struct route_node *rn;
|
struct zebra_if *zif;
|
||||||
struct interface *ifp;
|
struct zebra_l2info_vxlan *vxl;
|
||||||
struct zebra_vrf *zvrf;
|
|
||||||
|
|
||||||
zvrf = zebra_vrf_get_evpn();
|
zif = ifp->info;
|
||||||
|
if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
|
||||||
/* Walk VxLAN interfaces and create EVPN hash. */
|
goto done;
|
||||||
for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
|
|
||||||
struct zebra_if *zif;
|
|
||||||
struct zebra_l2info_vxlan *vxl;
|
|
||||||
|
|
||||||
ifp = (struct interface *)rn->info;
|
|
||||||
if (!ifp)
|
|
||||||
continue;
|
|
||||||
zif = ifp->info;
|
|
||||||
if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
vxl = &zif->l2info.vxl;
|
|
||||||
/* link of VXLAN interface should be in zebra_evpn_vrf */
|
|
||||||
if (zvrf->zns->ns_id != vxl->link_nsid) {
|
|
||||||
if (IS_ZEBRA_DEBUG_VXLAN)
|
|
||||||
zlog_debug(
|
|
||||||
"Intf %s(%u) link not in same "
|
|
||||||
"namespace than BGP EVPN core instance ",
|
|
||||||
ifp->name, ifp->ifindex);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
vxl = &zif->l2info.vxl;
|
||||||
|
/* link of VXLAN interface should be in zebra_evpn_vrf */
|
||||||
|
if (zvrf->zns->ns_id != vxl->link_nsid) {
|
||||||
if (IS_ZEBRA_DEBUG_VXLAN)
|
if (IS_ZEBRA_DEBUG_VXLAN)
|
||||||
zlog_debug("Building vni table for %s-if %s",
|
zlog_debug("Intf %s(%u) link not in same namespace as BGP EVPN core instance",
|
||||||
IS_ZEBRA_VXLAN_IF_VNI(zif) ? "vni" : "svd",
|
ifp->name, ifp->ifindex);
|
||||||
ifp->name);
|
goto done;
|
||||||
|
|
||||||
zebra_vxlan_if_vni_iterate(zif, zevpn_build_vni_hash_table,
|
|
||||||
NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IS_ZEBRA_DEBUG_VXLAN)
|
||||||
|
zlog_debug("Building vni table for %s-if %s",
|
||||||
|
IS_ZEBRA_VXLAN_IF_VNI(zif) ? "vni" : "svd", ifp->name);
|
||||||
|
|
||||||
|
zebra_vxlan_if_vni_iterate(zif, zevpn_build_vni_hash_table, NULL);
|
||||||
|
|
||||||
|
done:
|
||||||
return NS_WALK_CONTINUE;
|
return NS_WALK_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1124,7 +1097,13 @@ static int zevpn_build_hash_table_zns(struct ns *ns,
|
||||||
|
|
||||||
static void zevpn_build_hash_table(void)
|
static void zevpn_build_hash_table(void)
|
||||||
{
|
{
|
||||||
ns_walk_func(zevpn_build_hash_table_zns, NULL, NULL);
|
struct zebra_vrf *zvrf;
|
||||||
|
|
||||||
|
zvrf = zebra_vrf_get_evpn();
|
||||||
|
if (zvrf == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
zebra_ns_ifp_walk_all(zevpn_build_hash_table_zns, zvrf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1968,70 +1947,63 @@ static int zl3vni_del(struct zebra_l3vni *zl3vni)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int zl3vni_map_to_vxlan_if_ns(struct ns *ns,
|
/* Context arg for zl3vni map iteration */
|
||||||
void *_zl3vni,
|
struct zl3vni_map_arg {
|
||||||
void **_pifp)
|
|
||||||
{
|
|
||||||
struct zebra_ns *zns = ns->info;
|
|
||||||
struct zebra_l3vni *zl3vni = (struct zebra_l3vni *)_zl3vni;
|
|
||||||
struct route_node *rn = NULL;
|
|
||||||
struct interface *ifp = NULL;
|
|
||||||
struct zebra_vrf *zvrf;
|
struct zebra_vrf *zvrf;
|
||||||
|
struct zebra_l3vni *zl3vni;
|
||||||
|
struct interface *ret_ifp;
|
||||||
|
};
|
||||||
|
|
||||||
zvrf = zebra_vrf_get_evpn();
|
static int zl3vni_map_to_vxlan_if_ns(struct interface *ifp, void *arg)
|
||||||
|
{
|
||||||
|
struct zl3vni_map_arg *ctx = arg;
|
||||||
|
struct zebra_l3vni *zl3vni = ctx->zl3vni;
|
||||||
|
struct zebra_vrf *zvrf = ctx->zvrf;
|
||||||
|
struct zebra_if *zif = NULL;
|
||||||
|
struct zebra_l2info_vxlan *vxl;
|
||||||
|
struct zebra_vxlan_vni *vni = NULL;
|
||||||
|
|
||||||
assert(_pifp);
|
/* look for vxlan-interface */
|
||||||
|
|
||||||
/* loop through all vxlan-interface */
|
zif = ifp->info;
|
||||||
for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
|
if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
|
||||||
|
goto done;
|
||||||
|
|
||||||
struct zebra_if *zif = NULL;
|
vxl = &zif->l2info.vxl;
|
||||||
struct zebra_l2info_vxlan *vxl;
|
vni = zebra_vxlan_if_vni_find(zif, zl3vni->vni);
|
||||||
struct zebra_vxlan_vni *vni = NULL;
|
if (!vni || vni->vni != zl3vni->vni)
|
||||||
|
goto done;
|
||||||
|
|
||||||
ifp = (struct interface *)rn->info;
|
/* link of VXLAN interface should be in zebra_evpn_vrf */
|
||||||
if (!ifp)
|
if (zvrf->zns->ns_id != vxl->link_nsid) {
|
||||||
continue;
|
if (IS_ZEBRA_DEBUG_VXLAN)
|
||||||
|
zlog_debug("Intf %s(%u) VNI %u, link not in same namespace as BGP EVPN core instance",
|
||||||
zif = ifp->info;
|
ifp->name, ifp->ifindex, vni->vni);
|
||||||
if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
|
goto done;
|
||||||
continue;
|
|
||||||
|
|
||||||
vxl = &zif->l2info.vxl;
|
|
||||||
vni = zebra_vxlan_if_vni_find(zif, zl3vni->vni);
|
|
||||||
if (!vni || vni->vni != zl3vni->vni)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* link of VXLAN interface should be in zebra_evpn_vrf */
|
|
||||||
if (zvrf->zns->ns_id != vxl->link_nsid) {
|
|
||||||
if (IS_ZEBRA_DEBUG_VXLAN)
|
|
||||||
zlog_debug(
|
|
||||||
"Intf %s(%u) VNI %u, link not in same "
|
|
||||||
"namespace than BGP EVPN core instance ",
|
|
||||||
ifp->name, ifp->ifindex, vni->vni);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
zl3vni->local_vtep_ip = zif->l2info.vxl.vtep_ip;
|
|
||||||
*_pifp = (void *)ifp;
|
|
||||||
route_unlock_node(rn);
|
|
||||||
return NS_WALK_STOP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
zl3vni->local_vtep_ip = zif->l2info.vxl.vtep_ip;
|
||||||
|
ctx->ret_ifp = ifp;
|
||||||
|
|
||||||
|
return NS_WALK_STOP;
|
||||||
|
|
||||||
|
done:
|
||||||
return NS_WALK_CONTINUE;
|
return NS_WALK_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct interface *zl3vni_map_to_vxlan_if(struct zebra_l3vni *zl3vni)
|
struct interface *zl3vni_map_to_vxlan_if(struct zebra_l3vni *zl3vni)
|
||||||
{
|
{
|
||||||
struct interface **p_ifp;
|
struct zl3vni_map_arg arg = {};
|
||||||
struct interface *ifp = NULL;
|
|
||||||
|
|
||||||
p_ifp = &ifp;
|
arg.zl3vni = zl3vni;
|
||||||
|
arg.zvrf = zebra_vrf_get_evpn();
|
||||||
|
|
||||||
ns_walk_func(zl3vni_map_to_vxlan_if_ns,
|
if (arg.zvrf == NULL)
|
||||||
(void *)zl3vni, (void **)p_ifp);
|
return NULL;
|
||||||
return ifp;
|
|
||||||
|
zebra_ns_ifp_walk_all(zl3vni_map_to_vxlan_if_ns, &arg);
|
||||||
|
|
||||||
|
return arg.ret_ifp;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct interface *zl3vni_map_to_svi_if(struct zebra_l3vni *zl3vni)
|
struct interface *zl3vni_map_to_svi_if(struct zebra_l3vni *zl3vni)
|
||||||
|
@ -2086,57 +2058,35 @@ struct zebra_l3vni *zl3vni_from_vrf(vrf_id_t vrf_id)
|
||||||
return zl3vni_lookup(zvrf->l3vni);
|
return zl3vni_lookup(zvrf->l3vni);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int zl3vni_from_svi_ns(struct ns *ns, void *_in_param, void **_p_zl3vni)
|
/* loop through all vxlan-interface */
|
||||||
|
static int zl3vni_from_svi_ns(struct interface *tmp_if, void *_in_param)
|
||||||
{
|
{
|
||||||
int found = 0;
|
int found = 0;
|
||||||
vni_t vni_id = 0;
|
vni_t vni_id = 0;
|
||||||
struct zebra_ns *zns = ns->info;
|
struct zebra_from_svi_param *in_param = _in_param;
|
||||||
struct zebra_l3vni **p_zl3vni = (struct zebra_l3vni **)_p_zl3vni;
|
|
||||||
struct zebra_from_svi_param *in_param =
|
|
||||||
(struct zebra_from_svi_param *)_in_param;
|
|
||||||
struct route_node *rn = NULL;
|
|
||||||
struct interface *tmp_if = NULL;
|
|
||||||
struct zebra_if *zif = NULL;
|
struct zebra_if *zif = NULL;
|
||||||
struct zebra_if *br_zif = NULL;
|
|
||||||
|
|
||||||
assert(in_param && p_zl3vni);
|
assert(in_param);
|
||||||
|
|
||||||
br_zif = in_param->br_if->info;
|
zif = tmp_if->info;
|
||||||
assert(br_zif);
|
if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
|
||||||
|
goto done;
|
||||||
|
if (!if_is_operative(tmp_if))
|
||||||
|
goto done;
|
||||||
|
|
||||||
if (in_param->bridge_vlan_aware) {
|
if (zif->brslave_info.br_if != in_param->br_if)
|
||||||
vni_id = zebra_l2_bridge_if_vni_find(br_zif, in_param->vid);
|
goto done;
|
||||||
if (vni_id)
|
|
||||||
found = 1;
|
|
||||||
} else {
|
|
||||||
/* loop through all vxlan-interface */
|
|
||||||
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 != in_param->br_if)
|
vni_id = zebra_vxlan_if_access_vlan_vni_find(zif, in_param->br_if);
|
||||||
continue;
|
if (vni_id) {
|
||||||
|
in_param->zl3vni = zl3vni_lookup(vni_id);
|
||||||
vni_id = zebra_vxlan_if_access_vlan_vni_find(
|
found = 1;
|
||||||
zif, in_param->br_if);
|
|
||||||
if (vni_id) {
|
|
||||||
found = 1;
|
|
||||||
route_unlock_node(rn);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
if (!found)
|
if (!found)
|
||||||
return NS_WALK_CONTINUE;
|
return NS_WALK_CONTINUE;
|
||||||
|
|
||||||
*p_zl3vni = zl3vni_lookup(vni_id);
|
|
||||||
return NS_WALK_STOP;
|
return NS_WALK_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2147,10 +2097,11 @@ static int zl3vni_from_svi_ns(struct ns *ns, void *_in_param, void **_p_zl3vni)
|
||||||
static struct zebra_l3vni *zl3vni_from_svi(struct interface *ifp,
|
static struct zebra_l3vni *zl3vni_from_svi(struct interface *ifp,
|
||||||
struct interface *br_if)
|
struct interface *br_if)
|
||||||
{
|
{
|
||||||
struct zebra_l3vni *zl3vni = NULL;
|
|
||||||
struct zebra_if *zif = NULL;
|
struct zebra_if *zif = NULL;
|
||||||
|
vni_t vni_id = 0;
|
||||||
|
struct zebra_if *br_zif = NULL;
|
||||||
struct zebra_from_svi_param in_param = {};
|
struct zebra_from_svi_param in_param = {};
|
||||||
struct zebra_l3vni **p_zl3vni;
|
struct zebra_l2info_vlan *vl;
|
||||||
|
|
||||||
if (!br_if)
|
if (!br_if)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2158,15 +2109,15 @@ static struct zebra_l3vni *zl3vni_from_svi(struct interface *ifp,
|
||||||
/* 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))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
in_param.br_if = br_if;
|
in_param.br_if = br_if;
|
||||||
|
|
||||||
/* Determine if bridge is VLAN-aware or not */
|
/* Determine if bridge is VLAN-aware or not */
|
||||||
zif = br_if->info;
|
br_zif = br_if->info;
|
||||||
assert(zif);
|
assert(br_zif);
|
||||||
in_param.bridge_vlan_aware = IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(zif);
|
|
||||||
if (in_param.bridge_vlan_aware) {
|
|
||||||
struct zebra_l2info_vlan *vl;
|
|
||||||
|
|
||||||
|
in_param.bridge_vlan_aware = IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif);
|
||||||
|
if (in_param.bridge_vlan_aware) {
|
||||||
if (!IS_ZEBRA_IF_VLAN(ifp))
|
if (!IS_ZEBRA_IF_VLAN(ifp))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -2174,15 +2125,18 @@ static struct zebra_l3vni *zl3vni_from_svi(struct interface *ifp,
|
||||||
assert(zif);
|
assert(zif);
|
||||||
vl = &zif->l2info.vl;
|
vl = &zif->l2info.vl;
|
||||||
in_param.vid = vl->vid;
|
in_param.vid = vl->vid;
|
||||||
|
|
||||||
|
vni_id = zebra_l2_bridge_if_vni_find(br_zif, in_param.vid);
|
||||||
|
if (vni_id)
|
||||||
|
return zl3vni_lookup(vni_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
|
/* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
|
||||||
/* TODO: Optimize with a hash. */
|
/* TODO: Optimize with a hash. */
|
||||||
|
|
||||||
p_zl3vni = &zl3vni;
|
zebra_ns_ifp_walk_all(zl3vni_from_svi_ns, &in_param);
|
||||||
|
|
||||||
ns_walk_func(zl3vni_from_svi_ns, (void *)&in_param, (void **)p_zl3vni);
|
return in_param.zl3vni;
|
||||||
return zl3vni;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vni_t vni_id_from_svi(struct interface *ifp, struct interface *br_if)
|
vni_t vni_id_from_svi(struct interface *ifp, struct interface *br_if)
|
||||||
|
@ -2336,6 +2290,36 @@ static void zevpn_add_to_l3vni_list(struct hash_bucket *bucket, void *ctxt)
|
||||||
listnode_add_sort(zl3vni->l2vnis, zevpn);
|
listnode_add_sort(zl3vni->l2vnis, zevpn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Helper for vni transition iterator */
|
||||||
|
|
||||||
|
struct vni_trans_ctx {
|
||||||
|
vni_t vni;
|
||||||
|
struct zebra_vxlan_vni *vnip;
|
||||||
|
struct interface *ret_ifp;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int vni_trans_cb(struct interface *ifp, void *arg)
|
||||||
|
{
|
||||||
|
struct vni_trans_ctx *ctx = arg;
|
||||||
|
struct zebra_if *zif;
|
||||||
|
struct zebra_vxlan_vni *vnip;
|
||||||
|
|
||||||
|
/* Find VxLAN interface for this VNI. */
|
||||||
|
zif = ifp->info;
|
||||||
|
if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
vnip = zebra_vxlan_if_vni_find(zif, ctx->vni);
|
||||||
|
if (vnip) {
|
||||||
|
ctx->ret_ifp = ifp;
|
||||||
|
ctx->vnip = vnip;
|
||||||
|
return NS_WALK_STOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
return NS_WALK_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle transition of vni from l2 to l3 and vice versa.
|
* Handle transition of vni from l2 to l3 and vice versa.
|
||||||
* This function handles only the L2VNI add/delete part of
|
* This function handles only the L2VNI add/delete part of
|
||||||
|
@ -2386,39 +2370,25 @@ static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf, vni_t vni,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
struct zebra_ns *zns;
|
|
||||||
struct route_node *rn;
|
|
||||||
struct interface *ifp;
|
|
||||||
struct zebra_if *zif;
|
|
||||||
struct zebra_vxlan_vni *vnip;
|
struct zebra_vxlan_vni *vnip;
|
||||||
struct zebra_l2info_vxlan *vxl;
|
struct zebra_l2info_vxlan *vxl;
|
||||||
struct interface *vlan_if;
|
struct interface *vlan_if;
|
||||||
bool found = false;
|
struct zebra_if *zif;
|
||||||
|
struct zebra_ns *zns;
|
||||||
|
struct vni_trans_ctx ctx = {};
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_VXLAN)
|
if (IS_ZEBRA_DEBUG_VXLAN)
|
||||||
zlog_debug("Adding L2-VNI %u - transition from L3-VNI",
|
zlog_debug("Adding L2-VNI %u - transition from L3-VNI",
|
||||||
vni);
|
vni);
|
||||||
|
|
||||||
/* Find VxLAN interface for this VNI. */
|
|
||||||
zns = zebra_ns_lookup(NS_DEFAULT);
|
zns = zebra_ns_lookup(NS_DEFAULT);
|
||||||
for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
|
|
||||||
ifp = (struct interface *)rn->info;
|
|
||||||
if (!ifp)
|
|
||||||
continue;
|
|
||||||
zif = ifp->info;
|
|
||||||
if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
vxl = &zif->l2info.vxl;
|
ctx.vni = vni;
|
||||||
vnip = zebra_vxlan_if_vni_find(zif, vni);
|
|
||||||
if (vnip) {
|
|
||||||
found = true;
|
|
||||||
route_unlock_node(rn);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found) {
|
/* Find VxLAN interface for this VNI. */
|
||||||
|
zebra_ns_ifp_walk(zns, vni_trans_cb, &ctx);
|
||||||
|
|
||||||
|
if (ctx.ret_ifp == NULL) {
|
||||||
if (IS_ZEBRA_DEBUG_VXLAN)
|
if (IS_ZEBRA_DEBUG_VXLAN)
|
||||||
zlog_err(
|
zlog_err(
|
||||||
"Adding L2-VNI - Failed to find VxLAN interface for VNI %u",
|
"Adding L2-VNI - Failed to find VxLAN interface for VNI %u",
|
||||||
|
@ -2431,6 +2401,10 @@ static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf, vni_t vni,
|
||||||
if (zevpn)
|
if (zevpn)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
zif = ctx.ret_ifp->info;
|
||||||
|
vnip = ctx.vnip;
|
||||||
|
vxl = &zif->l2info.vxl;
|
||||||
|
|
||||||
zevpn = zebra_evpn_add(vni);
|
zevpn = zebra_evpn_add(vni);
|
||||||
|
|
||||||
/* Find bridge interface for the VNI */
|
/* Find bridge interface for the VNI */
|
||||||
|
@ -2443,13 +2417,13 @@ static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf, vni_t vni,
|
||||||
listnode_add_sort_nodup(zl3vni->l2vnis, zevpn);
|
listnode_add_sort_nodup(zl3vni->l2vnis, zevpn);
|
||||||
}
|
}
|
||||||
|
|
||||||
zevpn->vxlan_if = ifp;
|
zevpn->vxlan_if = ctx.ret_ifp;
|
||||||
zevpn->local_vtep_ip = vxl->vtep_ip;
|
zevpn->local_vtep_ip = vxl->vtep_ip;
|
||||||
|
|
||||||
/* Inform BGP if the VNI is up and mapped to a bridge. */
|
/* Inform BGP if the VNI is up and mapped to a bridge. */
|
||||||
if (if_is_operative(ifp) && zif->brslave_info.br_if) {
|
if (if_is_operative(ctx.ret_ifp) && zif->brslave_info.br_if) {
|
||||||
zebra_evpn_send_add_to_client(zevpn);
|
zebra_evpn_send_add_to_client(zevpn);
|
||||||
zebra_evpn_read_mac_neigh(zevpn, ifp);
|
zebra_evpn_read_mac_neigh(zevpn, ctx.ret_ifp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue