diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/netns_linux.c | 56 | ||||
-rw-r--r-- | lib/netns_other.c | 5 | ||||
-rw-r--r-- | lib/ns.h | 10 | ||||
-rw-r--r-- | lib/vrf.c | 12 | ||||
-rw-r--r-- | lib/vrf.h | 3 |
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; @@ -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 @@ -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 @@ -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 |