]> git.proxmox.com Git - mirror_frr.git/blobdiff - lib/netns_linux.c
zebra, lib: fix the ZEBRA_INTERFACE_VRF_UPDATE zapi message
[mirror_frr.git] / lib / netns_linux.c
index 3d61cecc03e94d7d9dbc0267fae01d088db04a08..ef2f5dc95326d7ddc2d8f48511632f757ee445df 100644 (file)
 #include "ns.h"
 #include "log.h"
 #include "memory.h"
-
 #include "command.h"
 #include "vty.h"
 #include "vrf.h"
+#include "lib_errors.h"
 
 DEFINE_MTYPE_STATIC(LIB, NS, "NetNS Context")
 DEFINE_MTYPE_STATIC(LIB, NS_NAME, "NetNS Name")
@@ -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) */
@@ -199,14 +219,16 @@ static int ns_enable_internal(struct ns *ns, void (*func)(ns_id_t, void *))
                }
 
                if (!ns_is_enabled(ns)) {
-                       zlog_err("Can not enable NS %u: %s!", ns->ns_id,
-                                safe_strerror(errno));
+                       flog_err_sys(EC_LIB_SYSTEM_CALL,
+                                    "Can not enable NS %u: %s!", ns->ns_id,
+                                    safe_strerror(errno));
                        return 0;
                }
 
                /* Non default NS. leave */
                if (ns->ns_id == NS_UNKNOWN) {
-                       zlog_err("Can not enable NS %s %u: Invalid NSID",
+                       flog_err(EC_LIB_NS,
+                                "Can not enable NS %s %u: Invalid NSID",
                                 ns->name, ns->ns_id);
                        return 0;
                }
@@ -262,6 +284,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 map)
+{
+       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 && !map) {
+               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);
@@ -383,10 +437,13 @@ char *ns_netns_pathname(struct vty *vty, const char *name)
 
        if (!result) {
                if (vty)
-                       vty_out(vty, "Invalid pathname: %s\n",
+                       vty_out(vty, "Invalid pathname for %s: %s\n",
+                               pathname,
                                safe_strerror(errno));
                else
-                       zlog_warn("Invalid pathname: %s", safe_strerror(errno));
+                       flog_warn(EC_LIB_LINUX_NS,
+                                 "Invalid pathname for %s: %s", pathname,
+                                 safe_strerror(errno));
                return NULL;
        }
        check_base = basename(pathname);
@@ -395,7 +452,8 @@ char *ns_netns_pathname(struct vty *vty, const char *name)
                        vty_out(vty, "NS name (%s) invalid: too long (>%d)\n",
                                check_base, NS_NAMSIZ - 1);
                else
-                       zlog_warn("NS name (%s) invalid: too long (>%d)",
+                       flog_warn(EC_LIB_LINUX_NS,
+                                 "NS name (%s) invalid: too long (>%d)",
                                  check_base, NS_NAMSIZ - 1);
                return NULL;
        }
@@ -411,39 +469,34 @@ void ns_init(void)
        if (ns_initialised == 1)
                return;
        errno = 0;
-#ifdef HAVE_NETNS
-       if (have_netns_enabled < 0) {
+       if (have_netns())
                ns_default_ns_fd = open(NS_DEFAULT_NAME, O_RDONLY);
-               if (ns_default_ns_fd == -1)
-                       zlog_err("NS initialization failure %d(%s)",
-                                errno, safe_strerror(errno));
-       } else {
+       else {
                ns_default_ns_fd = -1;
                default_ns = NULL;
        }
-#else
-       ns_default_ns_fd = -1;
-       default_ns = NULL;
-#endif /* HAVE_NETNS */
        ns_current_ns_fd = -1;
        ns_initialised = 1;
 }
 
 /* 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;
 
        ns_init();
        default_ns = ns_get_created_internal(NULL, NULL, default_ns_id);
        if (!default_ns) {
-               zlog_err("%s: failed to create the default NS!", __func__);
+               flog_err(EC_LIB_NS, "%s: failed to create the default NS!",
+                        __func__);
                exit(1);
        }
        if (have_netns()) {
                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)
@@ -452,7 +505,8 @@ void ns_init_management(ns_id_t default_ns_id)
 
        /* Enable the default NS. */
        if (!ns_enable(default_ns, NULL)) {
-               zlog_err("%s: failed to enable the default NS!", __func__);
+               flog_err(EC_LIB_NS, "%s: failed to enable the default NS!",
+                        __func__);
                exit(1);
        }
 }