pespin submitted this change.
build: keep netns API public and gate features with HAVE_*
The netns API was previously guarded by platform-specific preprocessor
conditions (e.g. !EMBEDDED and defined(__linux__)), which caused the
netns headers and implementation to be entirely excluded from non-Linux
builds such as Emscripten. This in turn led to build failures in code
depending on the netns API, as the symbols and declarations were not
available at all.
Always build netns.c and keep the public declarations available
for non-embedded builds. Move platform/feature conditionals into the
implementation: guard the netns code paths with HAVE_SETNS/HAVE_UNSHARE/
HAVE_MOUNT and HAVE_CLONE_NEWNET, and return -ENOTSUP when the required
functionality is not available.
Add configure-time checks for the required headers/functions and for the
CLONE_NEWNET declaration, defining the
corresponding HAVE_* macros.
No functional changes intended for platforms where netns is available.
Change-Id: I2322eb2936bea35596f1fd6b6a713ea5f997b1ea
---
M configure.ac
M include/osmocom/core/netns.h
M src/core/netns.c
3 files changed, 35 insertions(+), 11 deletions(-)
diff --git a/configure.ac b/configure.ac
index 4a6a474..5d1bdec 100644
--- a/configure.ac
+++ b/configure.ac
@@ -145,6 +145,18 @@
AC_CHECK_FUNCS(localtime_r)
+# Check for network namespace related functions and macros
+AC_CHECK_HEADERS([sched.h sys/mount.h sys/param.h])
+AC_CHECK_FUNCS([setns unshare mount])
+
+dnl Check whether CLONE_NEWNET is available
+AC_CHECK_DECL([CLONE_NEWNET],
+ [AC_DEFINE([HAVE_CLONE_NEWNET], [1],
+ [Define if CLONE_NEWNET is available])],
+ [],
+ [[#define _GNU_SOURCE
+ #include <sched.h>]])
+
AC_DEFUN([CHECK_TM_INCLUDES_TM_GMTOFF], [
AC_CACHE_CHECK(
[whether struct tm has tm_gmtoff member],
diff --git a/include/osmocom/core/netns.h b/include/osmocom/core/netns.h
index 5bbf224..5f1b17e 100644
--- a/include/osmocom/core/netns.h
+++ b/include/osmocom/core/netns.h
@@ -2,9 +2,6 @@
* Network namespace convenience functions. */
#pragma once
-#if (!EMBEDDED)
-
-#if defined(__linux__)
#include <signal.h>
@@ -17,8 +14,4 @@
int osmo_netns_switch_enter(int nsfd, struct osmo_netns_switch_state *state);
int osmo_netns_switch_exit(struct osmo_netns_switch_state *state);
-
-#endif /* defined(__linux__) */
-
-#endif /* (!EMBEDDED) */
/*! @} */
diff --git a/src/core/netns.c b/src/core/netns.c
index c1d75b1..1177030 100644
--- a/src/core/netns.c
+++ b/src/core/netns.c
@@ -26,8 +26,6 @@
*
* \file netns.c */
-#if defined(__linux__)
-
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
@@ -36,13 +34,21 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#ifdef HAVE_SCHED_H
#include <sched.h>
+#endif
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
+#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_MOUNT_H
#include <sys/mount.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
+#endif
#include <fcntl.h>
#include <errno.h>
@@ -52,6 +58,8 @@
#define NETNS_PREFIX_PATH "/var/run/netns"
#define NETNS_CURRENT_PATH "/proc/self/ns/net"
+// To prevent unused function errors when neither setns nor CLONE_NEWNET are available
+#if (HAVE_SETNS && HAVE_CLONE_NEWNET)
/*! Open a file descriptor for the current network namespace.
* \returns fd of the current network namespace on success; negative in case of error
*/
@@ -63,6 +71,7 @@
return -errno;
return fd;
}
+#endif /* HAVE_SETNS && HAVE_CLONE_NEWNET */
/*! switch to a (non-default) namespace, store existing signal mask in oldmask.
* \param[in] nsfd file descriptor representing the namespace to which we shall switch
@@ -70,6 +79,7 @@
* \returns 0 on success; negative on error */
int osmo_netns_switch_enter(int nsfd, struct osmo_netns_switch_state *state)
{
+#if (HAVE_SETNS && HAVE_CLONE_NEWNET)
sigset_t intmask;
int rc;
@@ -89,6 +99,9 @@
return -errno;
}
return 0;
+#else
+ return -ENOTSUP;
+#endif /* HAVE_SETNS && HAVE_CLONE_NEWNET */
}
/*! switch back to the previous namespace, restoring signal mask.
@@ -96,6 +109,7 @@
* \returns 0 on successs; negative on error */
int osmo_netns_switch_exit(struct osmo_netns_switch_state *state)
{
+#if (HAVE_SETNS && HAVE_CLONE_NEWNET)
if (state->prev_nsfd < 0)
return -EINVAL;
@@ -109,10 +123,14 @@
if ((rc = sigprocmask(SIG_SETMASK, &state->prev_sigmask, NULL)) != 0)
return -rc;
return 0;
+#else
+ return -ENOTSUP;
+#endif /* HAVE_SETNS && HAVE_CLONE_NEWNET */
}
static int create_netns(const char *name)
{
+#if (HAVE_UNSHARE && HAVE_MOUNT && HAVE_SETNS && HAVE_CLONE_NEWNET)
char path[MAXPATHLEN];
sigset_t intmask, oldmask;
int fd, prev_nsfd;
@@ -175,6 +193,9 @@
return -errno;
return fd;
+#else
+ return -ENOTSUP;
+#endif /* HAVE_UNSHARE && HAVE_MOUNT && HAVE_SETNS && HAVE_CLONE_NEWNET */
}
/*! Open a file descriptor for the network namespace with provided name.
@@ -203,6 +224,4 @@
return fd;
}
-#endif /* defined(__linux__) */
-
/*! @} */
To view, visit change 41878. To unsubscribe, or for help writing mail filters, visit settings.