Version 1.8.0.0
[socat.git] / xio-namespaces.c
blobb44ee4339e7b29c0d845460f612faca46393c3e5
1 /* Source: xio-namespaces.c */
2 /* Copyright Gerhard Rieger and contributors (see file CHANGES) */
3 /* Published under the GNU General Public License V.2, see file COPYING */
5 /* This file contains Linux namespace related code */
7 #include "xiosysincludes.h"
8 #include "xioopen.h"
10 #include "xio-namespaces.h"
12 #if WITH_NAMESPACES
14 const struct optdesc opt_set_netns = { "netns", NULL, OPT_SET_NETNS, GROUP_PROCESS, PH_INIT, TYPE_STRING, OFUNC_SET_NAMESPACE, 0, 0, 0 };
17 /* Set the given namespace. Requires root or the appropriate CAP_*-
18 Returns 0 on success, or -1 on error. */
19 int xio_set_namespace(
20 const char *nstype,
21 const char *nsname)
23 char nspath[PATH_MAX];
24 int nsfd;
25 int rc;
27 if (!xioparms.experimental) {
28 Error1("option \"%s\" requires use of --experimental", nstype);
31 snprintf(nspath, sizeof(nspath)-1, "/run/%s/%s", nstype, nsname);
32 Info1("switching to net namespace \"%s\"", nsname);
33 nsfd = Open(nspath, O_RDONLY|O_CLOEXEC, 000);
34 if (nsfd < 0) {
35 Error2("open(%s, O_RDONLY|O_CLOEXEC): %s", nspath, strerror(errno));
36 return -1;
38 rc = Setns(nsfd, CLONE_NEWNET);
39 if (rc < 0) {
40 Error2("setns(%d, CLONE_NEWNET): %s", nsfd, strerror(errno));
41 Close(nsfd);
43 Close(nsfd);
44 return 0;
47 int xio_apply_namespace(
48 struct opt *opts)
50 int old_netfd;
51 char *netns_name;
52 char old_nspath[PATH_MAX];
53 int rc;
55 if (retropt_string(opts, OPT_SET_NETNS, &netns_name) < 0)
56 return 0;
58 /* Get path describing current namespace */
59 snprintf(old_nspath, sizeof(old_nspath)-1, "/proc/"F_pid"/ns/net",
60 Getpid());
62 /* Get a file descriptor to current ns for later reset */
63 old_netfd = Open(old_nspath, O_RDONLY|O_CLOEXEC, 000);
64 if (old_netfd < 0) {
65 Error2("open(%s, O_RDONLY|O_CLOEXEC): %s",
66 old_nspath, strerror(errno));
67 free(netns_name);
68 return -1;
70 if (old_netfd == 0) {
71 /* 0 means not netns option, oops */
72 Error1("%s(): INTERNAL", __func__);
73 free(netns_name);
74 Close(old_netfd);
75 return -1;
77 rc = xio_set_namespace("netns", netns_name);
78 free(netns_name);
79 if (rc < 0) {
80 Close(old_netfd);
81 return -1;
84 return old_netfd;
87 /* Sets the given namespace to that of process 1, this is assumed to be the
88 systems default.
89 Returns 0 on success, or -1 on error. */
90 int xio_reset_namespace(
91 int saved_netfd)
93 int rc;
95 rc = Setns(saved_netfd, CLONE_NEWNET);
96 if (rc < 0) {
97 Error2("xio_reset_namespace(%d): %s", saved_netfd, strerror(errno));
98 Close(saved_netfd);
99 return STAT_NORETRY;
101 Close(saved_netfd);
102 return 0;
105 #endif /* WITH_NAMESPACES */