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;
#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
}
#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)) {
return ret;
}
+
+ns_id_t ns_get_default_id(void)
+{
+ if (default_ns)
+ return default_ns->ns_id;
+ return NS_UNKNOWN;
+}
+
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;
* 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);
/*
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*/
#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")
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;
+}
#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. */
/*
* 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);
* VRF Debugging
*/
extern void vrf_install_commands(void);
+
+
+/* The default VRF ID */
+#define VRF_DEFAULT vrf_get_default_id()
+
#endif /*_ZEBRA_VRF_H*/
#include <zebra.h>
#include "ns.h"
+#include "vrf.h"
#include "log.h"
#if defined(HAVE_NETLINK)
#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
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 */
+}
+
#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__ */
#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")
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();