summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/ns.c35
-rw-r--r--lib/ns.h14
-rw-r--r--lib/vrf.c15
-rw-r--r--lib/vrf.h10
-rw-r--r--zebra/zebra_netns_id.c41
-rw-r--r--zebra/zebra_netns_id.h1
-rw-r--r--zebra/zebra_ns.c12
7 files changed, 108 insertions, 20 deletions
diff --git a/lib/ns.c b/lib/ns.c
index 9aa3509923..17d70a12fe 100644
--- 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;
+}
+
diff --git a/lib/ns.h b/lib/ns.h
index 73482d4d56..44257ab0c0 100644
--- a/lib/ns.h
+++ b/lib/ns.h
@@ -30,12 +30,17 @@
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*/
diff --git a/lib/vrf.c b/lib/vrf.c
index 7871052352..f4dc237eb3 100644
--- 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;
+}
diff --git a/lib/vrf.h b/lib/vrf.h
index 4bdc183b5c..9553d43808 100644
--- a/lib/vrf.h
+++ b/lib/vrf.h
@@ -27,11 +27,7 @@
#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*/
diff --git a/zebra/zebra_netns_id.c b/zebra/zebra_netns_id.c
index c5e792bd77..966d6ed0d2 100644
--- a/zebra/zebra_netns_id.c
+++ b/zebra/zebra_netns_id.c
@@ -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 */
+}
+
diff --git a/zebra/zebra_netns_id.h b/zebra/zebra_netns_id.h
index 18fdf50cf1..d6530e6694 100644
--- a/zebra/zebra_netns_id.h
+++ b/zebra/zebra_netns_id.h
@@ -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__ */
diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c
index 50551c9b35..da5b22def2 100644
--- a/zebra/zebra_ns.c
+++ b/zebra/zebra_ns.c
@@ -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();