summaryrefslogtreecommitdiff
path: root/zebra/zebra_vxlan.c
diff options
context:
space:
mode:
authorPhilippe Guibert <philippe.guibert@6wind.com>2019-09-26 18:49:59 +0200
committerPhilippe Guibert <philippe.guibert@6wind.com>2020-05-18 14:11:03 +0200
commit28254125d06f65cc4344b6156eec76a37ec6aede (patch)
tree61550bd2d0a769c2b7052713f2bc4fe0f813dc26 /zebra/zebra_vxlan.c
parent14ddb3d9c42a9845d1a7443b9231f92bc80b4f2d (diff)
zebra: importation of bgp evpn rt5 from vni with other netns
With vrf-lite mechanisms, it is possible to create layer 3 vnis by creating a bridge interface in default vr, by creating a vxlan interface that is attached to that bridge interface, then by moving the vxlan interface to the wished vrf. With vrf-netns mechanism, it is slightly different since bridged interfaces can not be separated in different network namespaces. To make it work, the setup consists in : - creating a vxlan interface on default vrf. - move the vxlan interface to the wished vrf ( with an other netns) - create a bridge interface in the wished vrf - attach the vxlan interface to that bridged interface from that point, if BGP is enabled to advertise vnis in default vrf, then vxlan interfaces are discovered appropriately in other vrfs, provided that the link interface still resides in the vrf where l2vpn is advertised. to import ipv4 entries from a separate vrf, into the l2vpn, the configuration of vni in the dedicated vrf + the advertisement of ipv4 entries in bgp vrf will import the entries in the bgp l2vpn. the modification consists in parsing the vxlan interfaces in all network namespaces, where the link resides in the same network namespace as the bgp core instance where bgp l2vpn is enabled. Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Diffstat (limited to 'zebra/zebra_vxlan.c')
-rw-r--r--zebra/zebra_vxlan.c88
1 files changed, 72 insertions, 16 deletions
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index d85f48e570..863eef17a3 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -4115,18 +4115,20 @@ static int zvni_send_del_to_client(vni_t vni)
return zserv_send_message(client, s);
}
-/*
- * Build the VNI hash table by going over the VxLAN interfaces. This
- * is called when EVPN (advertise-all-vni) is enabled.
- */
-static void zvni_build_hash_table(void)
+static int zvni_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 VNI hash. */
- zns = zebra_ns_lookup(NS_DEFAULT);
for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
vni_t vni;
zebra_vni_t *zvni = NULL;
@@ -4143,7 +4145,15 @@ static void zvni_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) {
@@ -4212,7 +4222,7 @@ static void zvni_build_hash_table(void)
zlog_debug(
"Failed to add VNI hash, IF %s(%u) L2-VNI %u",
ifp->name, ifp->ifindex, vni);
- return;
+ return ZNS_WALK_CONTINUE;
}
if (zvni->local_vtep_ip.s_addr !=
@@ -4249,6 +4259,19 @@ static void zvni_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 zvni_build_hash_table(void)
+{
+ zebra_ns_list_walk(zvni_build_hash_table_zns,
+ (void *)NULL,
+ (void **)NULL);
}
/*
@@ -5033,14 +5056,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;
@@ -5055,13 +5085,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)