summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/netns_linux.c2
-rw-r--r--lib/netns_other.c2
-rw-r--r--lib/ns.h2
-rw-r--r--zebra/zebra_ns.c22
-rw-r--r--zebra/zebra_ns.h8
-rw-r--r--zebra/zebra_vxlan.c89
6 files changed, 107 insertions, 18 deletions
diff --git a/lib/netns_linux.c b/lib/netns_linux.c
index 98f359401e..09a42b850b 100644
--- a/lib/netns_linux.c
+++ b/lib/netns_linux.c
@@ -51,7 +51,7 @@ static struct ns *ns_lookup_name_internal(const char *name);
RB_GENERATE(ns_head, ns, entry, ns_compare)
-static struct ns_head ns_tree = RB_INITIALIZER(&ns_tree);
+struct ns_head ns_tree = RB_INITIALIZER(&ns_tree);
static struct ns *default_ns;
static int ns_current_ns_fd;
diff --git a/lib/netns_other.c b/lib/netns_other.c
index 740d2b621e..b0aae4f8df 100644
--- a/lib/netns_other.c
+++ b/lib/netns_other.c
@@ -34,7 +34,7 @@ static inline int ns_compare(const struct ns *ns, const struct ns *ns2);
RB_GENERATE(ns_head, ns, entry, ns_compare)
-static struct ns_head ns_tree = RB_INITIALIZER(&ns_tree);
+struct ns_head ns_tree = RB_INITIALIZER(&ns_tree);
static inline int ns_compare(const struct ns *a, const struct ns *b)
{
diff --git a/lib/ns.h b/lib/ns.h
index 20e0a38e3b..1963b8a359 100644
--- a/lib/ns.h
+++ b/lib/ns.h
@@ -71,6 +71,8 @@ struct ns {
RB_HEAD(ns_head, ns);
RB_PROTOTYPE(ns_head, ns, entry, ns_compare)
+extern struct ns_head ns_tree;
+
/*
* API for managing NETNS. eg from zebra daemon
* one want to manage the list of NETNS, etc...
diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c
index 4e51437337..4e23ca2f03 100644
--- a/zebra/zebra_ns.c
+++ b/zebra/zebra_ns.c
@@ -229,3 +229,25 @@ int zebra_ns_config_write(struct vty *vty, struct ns *ns)
vty_out(vty, " netns %s\n", ns->name);
return 0;
}
+
+void zebra_ns_list_walk(int (*exec_for_each_zns)(struct zebra_ns *zns,
+ void *param_in,
+ void **param_out),
+ void *param_in,
+ void **param_out)
+{
+ struct ns *ns;
+ struct zebra_ns *zns;
+ int ret;
+
+ RB_FOREACH (ns, ns_head, &ns_tree) {
+ zns = (struct zebra_ns *)ns->info;
+ if (!zns && ns->ns_id == NS_DEFAULT)
+ zns = zebra_ns_lookup(ns->ns_id);
+ if (!zns)
+ continue;
+ ret = exec_for_each_zns(zns, param_in, param_out);
+ if (ret == ZNS_WALK_STOP)
+ return;
+ }
+}
diff --git a/zebra/zebra_ns.h b/zebra/zebra_ns.h
index dc79a83db0..fa2fd47c25 100644
--- a/zebra/zebra_ns.h
+++ b/zebra/zebra_ns.h
@@ -72,6 +72,14 @@ int zebra_ns_final_shutdown(struct ns *ns);
int zebra_ns_config_write(struct vty *vty, struct ns *ns);
+#define ZNS_WALK_CONTINUE 0
+#define ZNS_WALK_STOP 1
+void zebra_ns_list_walk(int (*exec_for_each_zns)(struct zebra_ns *zns,
+ void *param_in,
+ void **param_out),
+ void *param_in,
+ void **param_out);
+
#ifdef __cplusplus
}
#endif
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index 13a58bc34a..7079184a34 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -846,18 +846,21 @@ static int zebra_evpn_vxlan_del(zebra_evpn_t *zevpn)
return zebra_evpn_del(zevpn);
}
-/*
- * Build the VNI hash table by going over the VxLAN interfaces. This
- * is called when EVPN (advertise-all-vni) is enabled.
- */
-static void zevpn_build_hash_table(void)
+
+static int zevpn_build_hash_table_zns(struct zebra_ns *zns,
+ void *param_in __attribute__((unused)),
+ void **param_out __attribute__((unused)))
{
- struct zebra_ns *zns;
struct route_node *rn;
struct interface *ifp;
+ struct zebra_vrf *zvrf;
+
+ zvrf = zebra_vrf_get_evpn();
+
+ if (!zvrf)
+ return ZNS_WALK_STOP;
/* Walk VxLAN interfaces and create EVPN hash. */
- zns = zebra_ns_lookup(NS_DEFAULT);
for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
vni_t vni;
zebra_evpn_t *zevpn = NULL;
@@ -874,7 +877,15 @@ static void zevpn_build_hash_table(void)
vxl = &zif->l2info.vxl;
vni = vxl->vni;
-
+ /* 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);
+ continue;
+ }
/* L3-VNI and L2-VNI are handled seperately */
zl3vni = zl3vni_lookup(vni);
if (zl3vni) {
@@ -943,7 +954,7 @@ static void zevpn_build_hash_table(void)
zlog_debug(
"Failed to add EVPN hash, IF %s(%u) L2-VNI %u",
ifp->name, ifp->ifindex, vni);
- return;
+ return ZNS_WALK_CONTINUE;
}
if (zevpn->local_vtep_ip.s_addr !=
@@ -985,6 +996,19 @@ static void zevpn_build_hash_table(void)
}
}
}
+ return ZNS_WALK_CONTINUE;
+}
+
+/*
+ * Build the VNI hash table by going over the VxLAN interfaces. This
+ * is called when EVPN (advertise-all-vni) is enabled.
+ */
+
+static void zevpn_build_hash_table(void)
+{
+ zebra_ns_list_walk(zevpn_build_hash_table_zns,
+ (void *)NULL,
+ (void **)NULL);
}
/*
@@ -1617,14 +1641,21 @@ static int zl3vni_del(zebra_l3vni_t *zl3vni)
return 0;
}
-struct interface *zl3vni_map_to_vxlan_if(zebra_l3vni_t *zl3vni)
+static int zl3vni_map_to_vxlan_if_zns(struct zebra_ns *zns,
+ void *_zl3vni,
+ void **_pifp)
{
- struct zebra_ns *zns = NULL;
+ zebra_l3vni_t *zl3vni = (zebra_l3vni_t *)_zl3vni;
struct route_node *rn = NULL;
struct interface *ifp = NULL;
+ struct zebra_vrf *zvrf;
+
+ zvrf = zebra_vrf_get_evpn();
+
+ if (!zvrf)
+ return ZNS_WALK_STOP;
/* loop through all vxlan-interface */
- zns = zebra_ns_lookup(NS_DEFAULT);
for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
struct zebra_if *zif = NULL;
@@ -1639,13 +1670,39 @@ struct interface *zl3vni_map_to_vxlan_if(zebra_l3vni_t *zl3vni)
continue;
vxl = &zif->l2info.vxl;
- if (vxl->vni == zl3vni->vni) {
- zl3vni->local_vtep_ip = vxl->vtep_ip;
- return ifp;
+ if (vxl->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, vxl->vni);
+ continue;
}
+
+
+ zl3vni->local_vtep_ip = vxl->vtep_ip;
+ if (_pifp)
+ *_pifp = (void *)ifp;
+ return ZNS_WALK_STOP;
}
- return NULL;
+ return ZNS_WALK_CONTINUE;
+}
+
+struct interface *zl3vni_map_to_vxlan_if(zebra_l3vni_t *zl3vni)
+{
+ struct interface **p_ifp;
+ struct interface *ifp = NULL;
+
+ p_ifp = &ifp;
+
+ zebra_ns_list_walk(zl3vni_map_to_vxlan_if_zns,
+ (void *)zl3vni, (void **)p_ifp);
+ return ifp;
}
struct interface *zl3vni_map_to_svi_if(zebra_l3vni_t *zl3vni)