summaryrefslogtreecommitdiff
path: root/zebra/zebra_evpn.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/zebra_evpn.c')
-rw-r--r--zebra/zebra_evpn.c124
1 files changed, 80 insertions, 44 deletions
diff --git a/zebra/zebra_evpn.c b/zebra/zebra_evpn.c
index 6f2765284b..8e204cd547 100644
--- a/zebra/zebra_evpn.c
+++ b/zebra/zebra_evpn.c
@@ -44,6 +44,7 @@
#include "zebra/rt_netlink.h"
#include "zebra/zebra_errors.h"
#include "zebra/zebra_l2.h"
+#include "zebra/zebra_l2_bridge_if.h"
#include "zebra/zebra_ns.h"
#include "zebra/zebra_vrf.h"
#include "zebra/zebra_vxlan.h"
@@ -117,6 +118,9 @@ void zebra_evpn_print(struct zebra_evpn *zevpn, void **ctxt)
if (json == NULL) {
vty_out(vty, "VNI: %u\n", zevpn->vni);
vty_out(vty, " Type: %s\n", "L2");
+ vty_out(vty, " Vlan: %u\n", zevpn->vid);
+ vty_out(vty, " Bridge: %s\n",
+ zevpn->bridge_if ? zevpn->bridge_if->name : "-");
vty_out(vty, " Tenant VRF: %s\n", vrf_id_to_name(zevpn->vrf_id));
} else {
json_object_int_add(json, "vni", zevpn->vni);
@@ -663,6 +667,7 @@ static int zebra_evpn_map_vlan_ns(struct ns *ns,
void *_in_param,
void **_p_zevpn)
{
+ int found = 0;
struct zebra_ns *zns = ns->info;
struct route_node *rn;
struct interface *br_if;
@@ -670,43 +675,58 @@ static int zebra_evpn_map_vlan_ns(struct ns *ns,
struct zebra_evpn *zevpn;
struct interface *tmp_if = NULL;
struct zebra_if *zif;
- struct zebra_vxlan_vni *vni;
struct zebra_from_svi_param *in_param =
(struct zebra_from_svi_param *)_in_param;
+ vlanid_t vid;
+ vni_t vni_id = 0;
+ uint8_t bridge_vlan_aware;
assert(p_zevpn && in_param);
br_if = in_param->br_if;
+ assert(br_if);
zif = in_param->zif;
assert(zif);
- assert(br_if);
+ vid = in_param->vid;
+ bridge_vlan_aware = in_param->bridge_vlan_aware;
- /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
- /* 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)
- continue;
-
- vni = zebra_vxlan_if_access_vlan_find(
- zif, in_param->bridge_vlan_aware, in_param->vid);
+ if (bridge_vlan_aware) {
+ vni_id = zebra_l2_bridge_if_vni_find(zif, vid);
+ if (vni_id)
+ found = 1;
+ } else {
+ /* See if this interface (or interface plus VLAN Id) maps to a
+ * VxLAN */
+ /* 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)
+ continue;
+
+ vni_id = zebra_vxlan_if_access_vlan_vni_find(zif, vid,
+ br_if);
+ if (vni_id) {
+ found = 1;
+ break;
+ }
- if (!in_param->bridge_vlan_aware || vni) {
- zevpn = zebra_evpn_lookup(vni->vni);
- *p_zevpn = zevpn;
- return NS_WALK_STOP;
}
}
- return NS_WALK_CONTINUE;
+ if (!found)
+ return NS_WALK_CONTINUE;
+
+ zevpn = zebra_evpn_lookup(vni_id);
+ *p_zevpn = zevpn;
+ return NS_WALK_STOP;
}
/*
@@ -747,35 +767,51 @@ static int zebra_evpn_from_svi_ns(struct ns *ns,
struct zebra_evpn *zevpn;
struct interface *tmp_if = NULL;
struct zebra_if *zif;
- struct zebra_vxlan_vni *vni;
+ struct zebra_if *br_zif;
+ struct zebra_l2_bridge_vlan *bvlan;
struct zebra_from_svi_param *in_param =
(struct zebra_from_svi_param *)_in_param;
int found = 0;
+ vni_t vni_id = 0;
+ vlanid_t vid = 0;
+ uint8_t bridge_vlan_aware;
if (!in_param)
return NS_WALK_STOP;
+
br_if = in_param->br_if;
zif = in_param->zif;
assert(zif);
-
- /* 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)
- continue;
-
- vni = zebra_vxlan_if_access_vlan_find(
- zif, in_param->bridge_vlan_aware, in_param->vid);
- if (!in_param->bridge_vlan_aware || vni) {
+ bridge_vlan_aware = in_param->bridge_vlan_aware;
+ vid = in_param->vid;
+ br_zif = br_if->info;
+ assert(br_zif);
+
+ if (bridge_vlan_aware) {
+ bvlan = zebra_l2_bridge_if_vlan_find(br_zif, vid);
+ if (bvlan && bvlan->access_bd && bvlan->access_bd->vni) {
found = 1;
+ vni_id = bvlan->access_bd->vni;
+ }
+ } else {
+ /* 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)
+ continue;
+
+ vni_id = zebra_vxlan_if_access_vlan_vni_find(zif, vid,
+ br_if);
+ if (vni_id)
+ found = 1;
break;
}
}
@@ -783,7 +819,7 @@ static int zebra_evpn_from_svi_ns(struct ns *ns,
if (!found)
return NS_WALK_CONTINUE;
- zevpn = zebra_evpn_lookup(vni->vni);
+ zevpn = zebra_evpn_lookup(vni_id);
if (p_zevpn)
*p_zevpn = zevpn;
return NS_WALK_STOP;