zebra: zvni_map_to_vlan() adaptation for all namespaces

this change is needed when a MAC/IP entry is learned by zebra, and the
entry happens to be in a different namespace. So that the entry be
active, the correct vni match has to be found.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
Philippe Guibert 2019-10-09 13:59:37 +02:00
parent 6265fbe55c
commit 9609fab712

View File

@ -622,32 +622,30 @@ void zebra_evpn_svi_macip_del_for_evpn_hash(struct hash_bucket *bucket,
return; return;
} }
/* static int zebra_evpn_map_vlan_zns(struct zebra_ns *zns,
* Map port or (port, VLAN) to an EVPN. This is invoked upon getting MAC void *_in_param,
* notifications, to see if they are of interest. void **_p_zevpn)
*/
zebra_evpn_t *zebra_evpn_map_vlan(struct interface *ifp,
struct interface *br_if, vlanid_t vid)
{ {
struct zebra_ns *zns;
struct route_node *rn; struct route_node *rn;
struct interface *br_if;
zebra_evpn_t **p_zevpn = (zebra_evpn_t **)_p_zevpn;
zebra_evpn_t *zevpn;
struct interface *tmp_if = NULL; struct interface *tmp_if = NULL;
struct zebra_if *zif; struct zebra_if *zif;
struct zebra_l2info_bridge *br;
struct zebra_l2info_vxlan *vxl = NULL; struct zebra_l2info_vxlan *vxl = NULL;
uint8_t bridge_vlan_aware; struct zebra_from_svi_param *in_param =
zebra_evpn_t *zevpn; (struct zebra_from_svi_param *)_in_param;
int found = 0; int found = 0;
/* Determine if bridge is VLAN-aware or not */ if (!in_param)
zif = br_if->info; return ZNS_WALK_STOP;
br_if = in_param->br_if;
zif = in_param->zif;
assert(zif); assert(zif);
br = &zif->l2info.br; assert(br_if);
bridge_vlan_aware = br->vlan_aware;
/* 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. */
zns = zebra_ns_lookup(NS_DEFAULT);
for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) { for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
tmp_if = (struct interface *)rn->info; tmp_if = (struct interface *)rn->info;
if (!tmp_if) if (!tmp_if)
@ -662,16 +660,47 @@ zebra_evpn_t *zebra_evpn_map_vlan(struct interface *ifp,
if (zif->brslave_info.br_if != br_if) if (zif->brslave_info.br_if != br_if)
continue; continue;
if (!bridge_vlan_aware || vxl->access_vlan == vid) { if (!in_param->bridge_vlan_aware
|| vxl->access_vlan == in_param->vid) {
found = 1; found = 1;
break; break;
} }
} }
if (!found) if (!found)
return NULL; return ZNS_WALK_CONTINUE;
zevpn = zebra_evpn_lookup(vxl->vni); zevpn = zebra_evpn_lookup(vxl->vni);
if (p_zevpn)
*p_zevpn = zevpn;
return ZNS_WALK_STOP;
}
/*
* Map port or (port, VLAN) to an EVPN. This is invoked upon getting MAC
* notifications, to see if they are of interest.
*/
zebra_evpn_t *zebra_evpn_map_vlan(struct interface *ifp,
struct interface *br_if, vlanid_t vid)
{
struct zebra_if *zif;
struct zebra_l2info_bridge *br;
zebra_evpn_t **p_zevpn;
zebra_evpn_t *zevpn = NULL;
struct zebra_from_svi_param in_param;
/* Determine if bridge is VLAN-aware or not */
zif = br_if->info;
assert(zif);
br = &zif->l2info.br;
in_param.bridge_vlan_aware = br->vlan_aware;
in_param.vid = vid;
in_param.br_if = br_if;
in_param.zif = zif;
p_zevpn = &zevpn;
zebra_ns_list_walk(zebra_evpn_map_vlan_zns,
(void *)&in_param,
(void **)p_zevpn);
return zevpn; return zevpn;
} }