aboutsummaryrefslogtreecommitdiffstats
path: root/lib/netns.c
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2020-02-25 12:17:29 +0100
committerPau Espin Pedrol <pespin@sysmocom.de>2020-03-02 09:41:43 +0100
commitad6eaa28811f96ebc39b5723cc37abb144ae82e6 (patch)
tree713694b49877d045cd9110e9294bd420d9a82578 /lib/netns.c
parentb629240a352c4455e410c32aec1d67a00e2995db (diff)
netns: Improve error checking
Diffstat (limited to 'lib/netns.c')
-rw-r--r--lib/netns.c142
1 files changed, 88 insertions, 54 deletions
diff --git a/lib/netns.c b/lib/netns.c
index 6734b5d..bd2076b 100644
--- a/lib/netns.c
+++ b/lib/netns.c
@@ -49,99 +49,133 @@ static int default_nsfd;
int switch_ns(int nsfd, sigset_t *oldmask)
{
sigset_t intmask;
+ int rc;
- sigfillset(&intmask);
- sigprocmask(SIG_BLOCK, &intmask, oldmask);
+ if (sigfillset(&intmask) < 0)
+ return -errno;
+ if ((rc = sigprocmask(SIG_BLOCK, &intmask, oldmask)) != 0)
+ return -rc;
- return setns(nsfd, CLONE_NEWNET);
+ if (setns(nsfd, CLONE_NEWNET) < 0)
+ return -errno;
+ return 0;
}
-void restore_ns(sigset_t *oldmask)
+int restore_ns(sigset_t *oldmask)
{
- setns(default_nsfd, CLONE_NEWNET);
+ int rc;
+ if (setns(default_nsfd, CLONE_NEWNET) < 0)
+ return -errno;
- sigprocmask(SIG_SETMASK, oldmask, NULL);
+ if ((rc = sigprocmask(SIG_SETMASK, oldmask, NULL)) != 0)
+ return -rc;
+ return 0;
}
int open_ns(int nsfd, const char *pathname, int flags)
{
sigset_t intmask, oldmask;
int fd;
- int errsv;
-
- sigfillset(&intmask);
- sigprocmask(SIG_BLOCK, &intmask, &oldmask);
-
- setns(nsfd, CLONE_NEWNET);
- fd = open(pathname, flags);
- errsv = errno;
- setns(default_nsfd, CLONE_NEWNET);
-
- sigprocmask(SIG_SETMASK, &oldmask, NULL);
+ int rc;
+
+ if (sigfillset(&intmask) < 0)
+ return -errno;
+ if ((rc = sigprocmask(SIG_BLOCK, &intmask, &oldmask)) != 0)
+ return -rc;
+
+ if (setns(nsfd, CLONE_NEWNET) < 0)
+ return -errno;
+ if ((fd = open(pathname, flags)) < 0)
+ return -errno;
+ if (setns(default_nsfd, CLONE_NEWNET) < 0) {
+ close(fd);
+ return -errno;
+ }
+ if ((rc = sigprocmask(SIG_SETMASK, &oldmask, NULL)) != 0) {
+ close(fd);
+ return -rc;
+ }
- errno = errsv;
- return fd;
+ return 0;
}
int socket_ns(int nsfd, int domain, int type, int protocol)
{
sigset_t intmask, oldmask;
int sk;
- int errsv;
-
- sigfillset(&intmask);
- sigprocmask(SIG_BLOCK, &intmask, &oldmask);
-
- setns(nsfd, CLONE_NEWNET);
- sk = socket(domain, type, protocol);
- errsv = errno;
- setns(default_nsfd, CLONE_NEWNET);
-
- sigprocmask(SIG_SETMASK, &oldmask, NULL);
+ int rc;
+
+ if (sigfillset(&intmask) < 0)
+ return -errno;
+ if ((rc = sigprocmask(SIG_BLOCK, &intmask, &oldmask)) != 0)
+ return -rc;
+
+ if (setns(nsfd, CLONE_NEWNET) < 0)
+ return -errno;
+ if ((sk = socket(domain, type, protocol)) < 0)
+ return -errno;
+ if (setns(default_nsfd, CLONE_NEWNET) < 0) {
+ close(sk);
+ return -errno;
+ }
- errno = errsv;
+ if ((rc = sigprocmask(SIG_SETMASK, &oldmask, NULL)) != 0) {
+ close(sk);
+ return -rc;
+ }
return sk;
}
-void init_netns()
+int init_netns()
{
- if ((default_nsfd = open("/proc/self/ns/net", O_RDONLY)) < 0) {
- perror("init_netns");
- exit(EXIT_FAILURE);
- }
+ if ((default_nsfd = open("/proc/self/ns/net", O_RDONLY)) < 0)
+ return -errno;
+ return 0;
}
int get_nsfd(const char *name)
{
- int r;
+ int rc;
+ int fd;
sigset_t intmask, oldmask;
char path[MAXPATHLEN] = NETNS_PATH;
- r = mkdir(path, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
- if (r < 0 && errno != EEXIST)
- return r;
+ rc = mkdir(path, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
+ if (rc < 0 && errno != EEXIST)
+ return rc;
snprintf(path, sizeof(path), "%s/%s", NETNS_PATH, name);
- r = open(path, O_RDONLY|O_CREAT|O_EXCL, 0);
- if (r < 0) {
- if (errno == EEXIST)
- return open(path, O_RDONLY);
-
- return r;
+ fd = open(path, O_RDONLY|O_CREAT|O_EXCL, 0);
+ if (fd < 0) {
+ if (errno == EEXIST) {
+ if ((fd = open(path, O_RDONLY)) < 0)
+ return -errno;
+ return fd;
+ }
+ return -errno;
}
- close(r);
+ if (close(fd) < 0)
+ return -errno;
- sigfillset(&intmask);
- sigprocmask(SIG_BLOCK, &intmask, &oldmask);
+ if (sigfillset(&intmask) < 0)
+ return -errno;
+ if ((rc = sigprocmask(SIG_BLOCK, &intmask, &oldmask)) != 0)
+ return -rc;
- unshare(CLONE_NEWNET);
- mount("/proc/self/ns/net", path, "none", MS_BIND, NULL);
+ if (unshare(CLONE_NEWNET) < 0)
+ return -errno;
+ if (mount("/proc/self/ns/net", path, "none", MS_BIND, NULL) < 0)
+ return -errno;
- setns(default_nsfd, CLONE_NEWNET);
+ if (setns(default_nsfd, CLONE_NEWNET) < 0)
+ return -errno;
- sigprocmask(SIG_SETMASK, &oldmask, NULL);
+ if ((rc = sigprocmask(SIG_SETMASK, &oldmask, NULL)) != 0)
+ return -rc;
- return open(path, O_RDONLY);
+ if ((fd = open(path, O_RDONLY)) < 0)
+ return -errno;
+ return fd;
}
#endif