summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/netns_linux.c56
-rw-r--r--lib/netns_other.c5
-rw-r--r--lib/ns.h10
-rw-r--r--lib/vrf.c12
-rw-r--r--lib/vrf.h3
5 files changed, 80 insertions, 6 deletions
diff --git a/lib/netns_linux.c b/lib/netns_linux.c
index 3d61cecc0..c215b4151 100644
--- a/lib/netns_linux.c
+++ b/lib/netns_linux.c
@@ -59,6 +59,26 @@ static int ns_default_ns_fd;
static int ns_debug;
+struct ns_map_nsid {
+ RB_ENTRY(ns_map_nsid) id_entry;
+ ns_id_t ns_id_external;
+ ns_id_t ns_id;
+};
+
+static __inline int ns_map_compare(const struct ns_map_nsid *a,
+ const struct ns_map_nsid *b)
+{
+ return (a->ns_id - b->ns_id);
+}
+
+RB_HEAD(ns_map_nsid_head, ns_map_nsid);
+RB_PROTOTYPE(ns_map_nsid_head, ns_map_nsid, id_entry, ns_map_compare);
+RB_GENERATE(ns_map_nsid_head, ns_map_nsid, id_entry, ns_map_compare);
+struct ns_map_nsid_head ns_map_nsid_list = RB_INITIALIZER(&ns_map_nsid_list);
+
+static ns_id_t ns_id_external_numbering;
+
+
#ifndef CLONE_NEWNET
#define CLONE_NEWNET 0x40000000
/* New network namespace (lo, device, names sockets, etc) */
@@ -262,6 +282,38 @@ static void ns_disable_internal(struct ns *ns)
}
}
+/* VRF list existance check by name. */
+static struct ns_map_nsid *ns_map_nsid_lookup_by_nsid(ns_id_t ns_id)
+{
+ struct ns_map_nsid ns_map;
+
+ ns_map.ns_id = ns_id;
+ return (RB_FIND(ns_map_nsid_head, &ns_map_nsid_list, &ns_map));
+}
+
+ns_id_t ns_map_nsid_with_external(ns_id_t ns_id, bool maporunmap)
+{
+ struct ns_map_nsid *ns_map;
+ vrf_id_t ns_id_external;
+
+ ns_map = ns_map_nsid_lookup_by_nsid(ns_id);
+ if (ns_map && !maporunmap) {
+ ns_id_external = ns_map->ns_id_external;
+ RB_REMOVE(ns_map_nsid_head, &ns_map_nsid_list, ns_map);
+ return ns_id_external;
+ }
+ if (ns_map)
+ return ns_map->ns_id_external;
+ ns_map = XCALLOC(MTYPE_NS, sizeof(struct ns_map_nsid));
+ /* increase vrf_id
+ * default vrf is the first one : 0
+ */
+ ns_map->ns_id_external = ns_id_external_numbering++;
+ ns_map->ns_id = ns_id;
+ RB_INSERT(ns_map_nsid_head, &ns_map_nsid_list, ns_map);
+ return ns_map->ns_id_external;
+}
+
struct ns *ns_get_created(struct ns *ns, char *name, ns_id_t ns_id)
{
return ns_get_created_internal(ns, name, ns_id);
@@ -430,7 +482,7 @@ void ns_init(void)
}
/* Initialize NS module. */
-void ns_init_management(ns_id_t default_ns_id)
+void ns_init_management(ns_id_t default_ns_id, ns_id_t internal_ns)
{
int fd;
@@ -444,6 +496,8 @@ void ns_init_management(ns_id_t default_ns_id)
fd = open(NS_DEFAULT_NAME, O_RDONLY);
default_ns->fd = fd;
}
+ default_ns->internal_ns_id = internal_ns;
+
/* Set the default NS name. */
default_ns->name = XSTRDUP(MTYPE_NS_NAME, NS_DEFAULT_NAME);
if (ns_debug)
diff --git a/lib/netns_other.c b/lib/netns_other.c
index 2402dd17d..4c7be05fa 100644
--- a/lib/netns_other.c
+++ b/lib/netns_other.c
@@ -153,6 +153,11 @@ int ns_enable(struct ns *ns, int (*func)(ns_id_t, void *))
return 0;
}
+ns_id_t ns_map_nsid_with_external(ns_id_t ns_id, bool maporunmap)
+{
+ return NS_UNKNOWN;
+}
+
struct ns *ns_get_created(struct ns *ns, char *name, ns_id_t ns_id)
{
return NULL;
diff --git a/lib/ns.h b/lib/ns.h
index fac91a40d..ba857b630 100644
--- a/lib/ns.h
+++ b/lib/ns.h
@@ -46,6 +46,9 @@ struct ns {
/* Identifier, same as the vector index */
ns_id_t ns_id;
+ /* Identifier, mapped on the NSID value */
+ ns_id_t internal_ns_id;
+
/* Name */
char *name;
@@ -100,7 +103,7 @@ extern void ns_terminate(void);
/* API to initialize NETNS managerment
* parameter is the default ns_id
*/
-extern void ns_init_management(ns_id_t ns_id);
+extern void ns_init_management(ns_id_t ns_id, ns_id_t internal_ns_idx);
/*
@@ -133,6 +136,11 @@ extern int ns_have_netns(void);
/* API to get context information of a NS */
extern void *ns_info_lookup(ns_id_t ns_id);
+/* API to map internal ns id value with
+ * user friendly ns id external value
+ */
+extern ns_id_t ns_map_nsid_with_external(ns_id_t ns_id, bool maporunmap);
+
/*
* NS init routine
* should be called from backendx
diff --git a/lib/vrf.c b/lib/vrf.c
index 8593cf289..b493f832f 100644
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -539,7 +539,8 @@ void vrf_configure_backend(int vrf_backend_netns)
vrf_backend = vrf_backend_netns;
}
-int vrf_handler_create(struct vty *vty, const char *vrfname, struct vrf **vrf)
+int vrf_handler_create(struct vty *vty, const char *vrfname,
+ struct vrf **vrf)
{
struct vrf *vrfp;
@@ -566,7 +567,7 @@ int vrf_handler_create(struct vty *vty, const char *vrfname, struct vrf **vrf)
}
int vrf_netns_handler_create(struct vty *vty, struct vrf *vrf, char *pathname,
- ns_id_t ns_id)
+ ns_id_t ns_id, ns_id_t internal_ns_id)
{
struct ns *ns = NULL;
@@ -613,6 +614,7 @@ int vrf_netns_handler_create(struct vty *vty, struct vrf *vrf, char *pathname,
return CMD_WARNING_CONFIG_FAILED;
}
ns = ns_get_created(ns, pathname, ns_id);
+ ns->internal_ns_id = internal_ns_id;
ns->vrf_ctxt = (void *)vrf;
vrf->ns_ctxt = (void *)ns;
/* update VRF netns NAME */
@@ -718,7 +720,8 @@ DEFUN_NOSH (vrf_netns,
vrf_daemon_privs->change(ZPRIVS_RAISE))
zlog_err("%s: Can't raise privileges", __func__);
- ret = vrf_netns_handler_create(vty, vrf, pathname, NS_UNKNOWN);
+ ret = vrf_netns_handler_create(vty, vrf, pathname,
+ NS_UNKNOWN, NS_UNKNOWN);
if (vrf_daemon_privs &&
vrf_daemon_privs->change(ZPRIVS_LOWER))
@@ -827,6 +830,9 @@ vrf_id_t vrf_get_default_id(void)
if (vrf)
return vrf->vrf_id;
+ /* backend netns is only known by zebra
+ * for other daemons, we return VRF_DEFAULT_INTERNAL
+ */
if (vrf_is_backend_netns())
return ns_get_default_id();
else
diff --git a/lib/vrf.h b/lib/vrf.h
index 85a530927..8aa0fc221 100644
--- a/lib/vrf.h
+++ b/lib/vrf.h
@@ -272,7 +272,8 @@ extern int vrf_handler_create(struct vty *vty, const char *name,
* should be called from zebra only
*/
extern int vrf_netns_handler_create(struct vty *vty, struct vrf *vrf,
- char *pathname, ns_id_t ns_id);
+ char *pathname, ns_id_t ext_ns_id,
+ ns_id_t ns_id);
/* used internally to enable or disable VRF.
* Notify a change in the VRF ID of the VRF