]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: upon startup, a NSID is assigned to default netns
authorPhilippe Guibert <philippe.guibert@6wind.com>
Tue, 16 Jan 2018 12:59:58 +0000 (13:59 +0100)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Tue, 27 Feb 2018 10:11:24 +0000 (11:11 +0100)
when the netns backend is selected for VRF, the default VRF is being
assigned a NSID. This avoids the need to handle the case where if the
incoming NSID was 0 for a non default VRF, then a specific handling had
to be done to keep 0 value for default VRF.
In most cases, as the first NETNS to get a NSID will be the default VRF,
most probably the default VRF will be assigned to 0, while the other
ones will have their value incremented. On some cases, where the NSID is
already assigned for NETNS, including default VRF, then the default VRF
value will be the one derived from the NSID of default VRF, thus keeping
consistency between VRF IDs and NETNS IDs.
Default NS is attempted to be created. Actually, some VMs may have the
netns feature, but the NS initialisation fails because that folder is
not present.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
lib/ns.c
lib/ns.h
lib/vrf.c
lib/vrf.h
zebra/zebra_netns_id.c
zebra/zebra_netns_id.h
zebra/zebra_ns.c

index 9aa35099236ebf86785f3814bc794c95ac9cfd39..17d70a12fe51e2c3a823b0aa89f5a1fc84b777c0 100644 (file)
--- a/lib/ns.c
+++ b/lib/ns.c
@@ -51,6 +51,7 @@ RB_GENERATE(ns_head, ns, entry, ns_compare)
 
 struct ns_head ns_tree = RB_INITIALIZER(&ns_tree);
 
+static struct ns *default_ns;
 static int ns_current_ns_fd;
 static int ns_default_ns_fd;
 
@@ -71,16 +72,12 @@ static inline int setns(int fd, int nstype)
 #endif /* HAVE_SETNS */
 
 #ifdef HAVE_NETNS
-
-#define NS_DEFAULT_NAME    "/proc/self/ns/net"
 static int have_netns_enabled = -1;
-
-#else  /* !HAVE_NETNS */
-
-#define NS_DEFAULT_NAME    "Default-logical-router"
-
 #endif /* HAVE_NETNS */
 
+/* default NS ID value used when VRF backend is not NETNS */
+#define NS_DEFAULT_INTERNAL 0
+
 static int have_netns(void)
 {
 #ifdef HAVE_NETNS
@@ -625,24 +622,28 @@ void ns_init(void)
        }
 #endif /* HAVE_NETNS */
        ns_default_ns_fd = -1;
+       default_ns = NULL;
 }
 
 /* Initialize NS module. */
-void ns_init_zebra(void)
+void ns_init_zebra(ns_id_t default_ns_id)
 {
-       struct ns *default_ns;
+       int fd;
 
        ns_init();
-       /* The default NS always exists. */
-       default_ns = ns_get(NS_DEFAULT);
-       ns_current_ns_fd = -1;
+       default_ns = ns_get(default_ns_id);
        if (!default_ns) {
                zlog_err("ns_init: failed to create the default NS!");
                exit(1);
        }
-
+       if (have_netns()) {
+               fd = open(NS_DEFAULT_NAME, O_RDONLY);
+               default_ns->fd = fd;
+       }
+       ns_current_ns_fd = -1;
        /* Set the default NS name. */
        default_ns->name = XSTRDUP(MTYPE_NS_NAME, NS_DEFAULT_NAME);
+       zlog_info("ns_init: default NSID is %u", default_ns->ns_id);
 
        /* Enable the default NS. */
        if (!ns_enable(default_ns)) {
@@ -739,3 +740,11 @@ int ns_socket(int domain, int type, int protocol, ns_id_t ns_id)
 
        return ret;
 }
+
+ns_id_t ns_get_default_id(void)
+{
+       if (default_ns)
+               return default_ns->ns_id;
+       return NS_UNKNOWN;
+}
+
index 73482d4d5648a2f799b5ad43fadc083f4c9e33fa..44257ab0c0108456f18620fdaecbf14b9e79a28d 100644 (file)
--- a/lib/ns.h
+++ b/lib/ns.h
 typedef u_int32_t ns_id_t;
 
 /* the default NS ID */
-#define NS_DEFAULT 0
 #define NS_UNKNOWN UINT32_MAX
 
 /* Default netns directory (Linux) */
 #define NS_RUN_DIR         "/var/run/netns"
 
+#ifdef HAVE_NETNS
+#define NS_DEFAULT_NAME    "/proc/self/ns/net"
+#else  /* !HAVE_NETNS */
+#define NS_DEFAULT_NAME    "Default-logical-router"
+#endif /* HAVE_NETNS */
+
 struct ns {
        RB_ENTRY(ns) entry;
 
@@ -85,7 +90,7 @@ extern void ns_add_hook(int type, int (*)(struct ns *));
  * NS initializer/destructor
  */
 extern void ns_init(void);
-extern void ns_init_zebra(void);
+extern void ns_init_zebra(ns_id_t ns_id);
 extern void ns_terminate(void);
 
 /*
@@ -101,10 +106,15 @@ extern char *ns_netns_pathname(struct vty *vty, const char *name);
 extern void *ns_info_lookup(ns_id_t ns_id);
 extern void ns_walk_func(int (*func)(struct ns *));
 extern const char *ns_get_name(struct ns *ns);
+extern ns_id_t ns_get_default_id(void);
 
 /* API that can be used by all daemons */
 extern int ns_switchback_to_initial(void);
 extern int ns_switch_to_netns(const char *netns_name);
 extern void ns_init(void);
 
+
+/* The default NS ID */
+#define NS_DEFAULT ns_get_default_id()
+
 #endif /*_ZEBRA_NS_H*/
index 787105235225b956c7cf63438f48d13b4c895754..f4dc237eb3d289e67c44b6b3c7cadf1cb726465d 100644 (file)
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -34,6 +34,9 @@
 #include "command.h"
 #include "ns.h"
 
+/* default VRF ID value used when VRF backend is not NETNS */
+#define VRF_DEFAULT_INTERNAL 0
+
 DEFINE_MTYPE_STATIC(LIB, VRF, "VRF")
 DEFINE_MTYPE_STATIC(LIB, VRF_BITMAP, "VRF bit-map")
 
@@ -646,3 +649,15 @@ void vrf_cmd_init(int (*writefunc)(struct vty *vty))
        install_default(VRF_NODE);
        ns_cmd_init();
 }
+
+vrf_id_t vrf_get_default_id(void)
+{
+       struct vrf *vrf = vrf_lookup_by_name(VRF_DEFAULT_NAME);
+
+       if (vrf)
+               return vrf->vrf_id;
+       if (vrf_is_backend_netns())
+               return ns_get_default_id();
+       else
+               return VRF_DEFAULT_INTERNAL;
+}
index 4bdc183b5ce9c052a208fa3fd7e9b30b1deef81f..9553d43808ef3779f36dddefe9ee97947c389c8a 100644 (file)
--- a/lib/vrf.h
+++ b/lib/vrf.h
 #include "qobj.h"
 #include "vty.h"
 
-/* The default NS ID */
-#define NS_DEFAULT 0
-
 /* The default VRF ID */
-#define VRF_DEFAULT 0
 #define VRF_UNKNOWN UINT32_MAX
 
 /* Pending: May need to refine this. */
@@ -208,6 +204,7 @@ extern void vrf_cmd_init(int (*writefunc)(struct vty *vty));
 /*
  * VRF utilities
  */
+extern vrf_id_t vrf_get_default_id(void);
 
 /* Create a socket serving for the given VRF */
 extern int vrf_socket(int, int, int, vrf_id_t);
@@ -236,4 +233,9 @@ extern int vrf_enable(struct vrf *vrf);
  * VRF Debugging
  */
 extern void vrf_install_commands(void);
+
+
+/* The default VRF ID */
+#define VRF_DEFAULT vrf_get_default_id()
+
 #endif /*_ZEBRA_VRF_H*/
index c5e792bd772f4836a1c27561089d4bbf4f11b97f..966d6ed0d24d2202c3d0545fb9ecd7f5c5144730 100644 (file)
@@ -20,6 +20,7 @@
 #include <zebra.h>
 
 #include "ns.h"
+#include "vrf.h"
 #include "log.h"
 
 #if defined(HAVE_NETLINK)
@@ -35,6 +36,9 @@
 
 #include "zebra_netns_id.h"
 
+/* default NS ID value used when VRF backend is not NETNS */
+#define NS_DEFAULT_INTERNAL 0
+
 /* in case NEWNSID not available, the NSID will be locally obtained
  */
 #define NS_BASE_NSID 0
@@ -312,3 +316,40 @@ ns_id_t zebra_ns_id_get(const char *netnspath)
        return zebra_ns_id_get_fallback(netnspath);
 }
 #endif /* ! defined(HAVE_NETLINK) */
+
+#ifdef HAVE_NETNS
+static void zebra_ns_create_netns_directory(void)
+{
+       /* check that /var/run/netns is created */
+       /* S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH */
+       if (mkdir(NS_RUN_DIR, 0755)) {
+               if (errno != EEXIST) {
+                       zlog_warn("NS check: failed to access %s", NS_RUN_DIR);
+                       return;
+               }
+       }
+}
+#endif
+
+ns_id_t zebra_ns_id_get_default(void)
+{
+#ifdef HAVE_NETNS
+       int fd;
+#endif /* !HAVE_NETNS */
+
+#ifdef HAVE_NETNS
+       if (vrf_is_backend_netns())
+               zebra_ns_create_netns_directory();
+       fd = open(NS_DEFAULT_NAME, O_RDONLY);
+
+       if (fd == -1)
+               return NS_DEFAULT_INTERNAL;
+       if (!vrf_is_backend_netns())
+               return NS_DEFAULT_INTERNAL;
+       close(fd);
+       return zebra_ns_id_get((char *)NS_DEFAULT_NAME);
+#else /* HAVE_NETNS */
+       return NS_DEFAULT_INTERNAL;
+#endif /* !HAVE_NETNS */
+}
+
index 18fdf50cf1b572d0dcb845c9c99e2073f7dd04e1..d6530e6694877d7bdbf6c0fceadafeff0f58bf67 100644 (file)
@@ -21,5 +21,6 @@
 #include "ns.h"
 
 extern ns_id_t zebra_ns_id_get(const char *netnspath);
+extern ns_id_t zebra_ns_id_get_default(void);
 
 #endif /* __ZEBRA_NS_ID_H__ */
index 50551c9b350d7c2ac23500e18f694343515ad3f3..da5b22def25f05279832b67e14cab6b0d4f689ae 100644 (file)
@@ -34,6 +34,9 @@
 #include "zebra_vxlan.h"
 #include "debug.h"
 #include "zebra_netns_notify.h"
+#include "zebra_netns_id.h"
+
+extern struct zebra_privs_t zserv_privs;
 
 DEFINE_MTYPE(ZEBRA, ZEBRA_NS, "Zebra Name Space")
 
@@ -229,9 +232,16 @@ int zebra_ns_disable(ns_id_t ns_id, void **info)
 
 int zebra_ns_init(void)
 {
+       ns_id_t ns_id;
+
        dzns = zebra_ns_alloc();
 
-       ns_init_zebra();
+       if (zserv_privs.change(ZPRIVS_RAISE))
+               zlog_err("Can't raise privileges");
+       ns_id = zebra_ns_id_get_default();
+       if (zserv_privs.change(ZPRIVS_LOWER))
+               zlog_err("Can't lower privileges");
+       ns_init_zebra(ns_id);
 
        ns_init();