wireguard.lists.zx2c4.com archive mirror
 help / color / mirror / Atom feed
From: Julian Orth <ju.orth@gmail.com>
To: wireguard@lists.zx2c4.com
Subject: [PATCH v2 06/10] tools: allow modification of transit net
Date: Sun,  9 Sep 2018 17:13:58 +0200	[thread overview]
Message-ID: <20180909151402.6033-7-ju.orth@gmail.com> (raw)
In-Reply-To: <20180909151402.6033-1-ju.orth@gmail.com>

The command is

wg set <device> [...] transit-netns <pid|file-path> [...]

For example:

wg set wg0 transit-netns 1
wg set wg0 transit-netns /proc/1/ns/net
---
 src/tools/config.c     | 32 ++++++++++++++++++++++++++++++++
 src/tools/containers.h |  6 +++++-
 src/tools/ipc.c        |  4 ++++
 src/tools/man/wg.8     |  9 +++++++--
 src/tools/set.c        |  2 +-
 5 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/src/tools/config.c b/src/tools/config.c
index 93525fb..dffec76 100644
--- a/src/tools/config.c
+++ b/src/tools/config.c
@@ -14,6 +14,7 @@
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <errno.h>
+#include <fcntl.h>
 
 #include "config.h"
 #include "containers.h"
@@ -74,6 +75,30 @@ static inline bool parse_port(uint16_t *port, uint32_t *flags, const char *value
 	return ret == 0;
 }
 
+static bool parse_transit_netns(struct wgdevice *device, const char *arg)
+{
+	/* U32 arg -> PID */
+	if (isdigit(*arg)) {
+		char *end;
+		unsigned long pid = strtoul(arg, &end, 10);
+		if (!*end && pid <= UINT32_MAX) {
+			device->transit_netns_pid = pid;
+			device->flags |= WGDEVICE_HAS_TRANSIT_NETNS_PID;
+			return true;
+		}
+	}
+
+	/* Otherwise -> file path */
+	device->transit_netns_fd = open(arg, O_RDONLY);
+	if (device->transit_netns_fd >= 0) {
+		device->flags |= WGDEVICE_HAS_TRANSIT_NETNS_FD;
+		return true;
+	}
+
+	perror("open");
+	return false;
+}
+
 static inline bool parse_fwmark(uint32_t *fwmark, uint32_t *flags, const char *value)
 {
 	unsigned long ret;
@@ -392,6 +417,8 @@ static bool process_line(struct config_ctx *ctx, const char *line)
 	if (ctx->is_device_section) {
 		if (key_match("ListenPort"))
 			ret = parse_port(&ctx->device->listen_port, &ctx->device->flags, value);
+		else if (key_match("TransitNetns"))
+			ret = parse_transit_netns(ctx->device, value);
 		else if (key_match("FwMark"))
 			ret = parse_fwmark(&ctx->device->fwmark, &ctx->device->flags, value);
 		else if (key_match("PrivateKey")) {
@@ -525,6 +552,11 @@ struct wgdevice *config_read_cmd(char *argv[], int argc)
 				goto error;
 			argv += 2;
 			argc -= 2;
+		} else if (!strcmp(argv[0], "transit-netns") && argc >= 2 && !peer) {
+			if (!parse_transit_netns(device, argv[1]))
+				goto error;
+			argv += 2;
+			argc -= 2;
 		} else if (!strcmp(argv[0], "fwmark") && argc >= 2 && !peer) {
 			if (!parse_fwmark(&device->fwmark, &device->flags, argv[1]))
 				goto error;
diff --git a/src/tools/containers.h b/src/tools/containers.h
index 455d998..c6dd6fe 100644
--- a/src/tools/containers.h
+++ b/src/tools/containers.h
@@ -58,7 +58,9 @@ enum {
 	WGDEVICE_HAS_PRIVATE_KEY = 1U << 1,
 	WGDEVICE_HAS_PUBLIC_KEY = 1U << 2,
 	WGDEVICE_HAS_LISTEN_PORT = 1U << 3,
-	WGDEVICE_HAS_FWMARK = 1U << 4
+	WGDEVICE_HAS_FWMARK = 1U << 4,
+	WGDEVICE_HAS_TRANSIT_NETNS_PID = 1U << 5,
+	WGDEVICE_HAS_TRANSIT_NETNS_FD = 1U << 6,
 };
 
 struct wgdevice {
@@ -72,6 +74,8 @@ struct wgdevice {
 
 	uint32_t fwmark;
 	uint16_t listen_port;
+	uint32_t transit_netns_pid;
+	int transit_netns_fd;
 
 	struct wgpeer *first_peer, *last_peer;
 };
diff --git a/src/tools/ipc.c b/src/tools/ipc.c
index e3ef789..aa82cb3 100644
--- a/src/tools/ipc.c
+++ b/src/tools/ipc.c
@@ -569,6 +569,10 @@ again:
 			mnl_attr_put(nlh, WGDEVICE_A_PRIVATE_KEY, sizeof(dev->private_key), dev->private_key);
 		if (dev->flags & WGDEVICE_HAS_LISTEN_PORT)
 			mnl_attr_put_u16(nlh, WGDEVICE_A_LISTEN_PORT, dev->listen_port);
+		if (dev->flags & WGDEVICE_HAS_TRANSIT_NETNS_PID)
+			mnl_attr_put_u32(nlh, WGDEVICE_A_TRANSIT_NETNS_PID, dev->transit_netns_pid);
+		if (dev->flags & WGDEVICE_HAS_TRANSIT_NETNS_FD)
+			mnl_attr_put_u32(nlh, WGDEVICE_A_TRANSIT_NETNS_FD, (uint32_t)dev->transit_netns_fd);
 		if (dev->flags & WGDEVICE_HAS_FWMARK)
 			mnl_attr_put_u32(nlh, WGDEVICE_A_FWMARK, dev->fwmark);
 		if (dev->flags & WGDEVICE_REPLACE_PEERS)
diff --git a/src/tools/man/wg.8 b/src/tools/man/wg.8
index 5bae7ca..d1f95f7 100644
--- a/src/tools/man/wg.8
+++ b/src/tools/man/wg.8
@@ -55,12 +55,17 @@ transfer-rx, transfer-tx, persistent-keepalive.
 Shows the current configuration of \fI<interface>\fP in the format described
 by \fICONFIGURATION FILE FORMAT\fP below.
 .TP
-\fBset\fP \fI<interface>\fP [\fIlisten-port\fP \fI<port>\fP] [\fIfwmark\fP \fI<fwmark>\fP] [\fIprivate-key\fP \fI<file-path>\fP] [\fIpeer\fP \fI<base64-public-key>\fP [\fIremove\fP] [\fIpreshared-key\fP \fI<file-path>\fP] [\fIendpoint\fP \fI<ip>:<port>\fP] [\fIpersistent-keepalive\fP \fI<interval seconds>\fP] [\fIallowed-ips\fP \fI<ip1>/<cidr1>\fP[,\fI<ip2>/<cidr2>\fP]...] ]...
+\fBset\fP \fI<interface>\fP [\fIlisten-port\fP \fI<port>\fP] [\fItransit-netns\fP \fI<pid|file-path>\fP] [\fIfwmark\fP \fI<fwmark>\fP] [\fIprivate-key\fP \fI<file-path>\fP] [\fIpeer\fP \fI<base64-public-key>\fP [\fIremove\fP] [\fIpreshared-key\fP \fI<file-path>\fP] [\fIendpoint\fP \fI<ip>:<port>\fP] [\fIpersistent-keepalive\fP \fI<interval seconds>\fP] [\fIallowed-ips\fP \fI<ip1>/<cidr1>\fP[,\fI<ip2>/<cidr2>\fP]...] ]...
 Sets configuration values for the specified \fI<interface>\fP. Multiple
 \fIpeer\fPs may be specified, and if the \fIremove\fP argument is given
 for a peer, that peer is removed, not configured. If \fIlisten-port\fP
 is not specified, the port will be chosen randomly when the
-interface comes up. Both \fIprivate-key\fP and \fIpreshared-key\fP must
+interface comes up. If transit-netns is not specified, the network namespace
+through which encrypted packets are routed is the one in which the device
+was created. Otherwise the network namespace through which encrypted packets are
+routed is the one specified by the argument. If the argument is an unsigned
+32-bit integer, it is interpeted as a process id, otherwise it is interpreted as
+a file path. Both \fIprivate-key\fP and \fIpreshared-key\fP must
 be a files, because command line arguments are not considered private on
 most systems but if you are using
 .BR bash (1),
diff --git a/src/tools/set.c b/src/tools/set.c
index d44fed9..37be9a0 100644
--- a/src/tools/set.c
+++ b/src/tools/set.c
@@ -18,7 +18,7 @@ int set_main(int argc, char *argv[])
 	int ret = 1;
 
 	if (argc < 3) {
-		fprintf(stderr, "Usage: %s %s <interface> [listen-port <port>] [fwmark <mark>] [private-key <file path>] [peer <base64 public key> [remove] [preshared-key <file path>] [endpoint <ip>:<port>] [persistent-keepalive <interval seconds>] [allowed-ips <ip1>/<cidr1>[,<ip2>/<cidr2>]...] ]...\n", PROG_NAME, argv[0]);
+		fprintf(stderr, "Usage: %s %s <interface> [listen-port <port>] [transit-netns <pid|file path>] [fwmark <mark>] [private-key <file path>] [peer <base64 public key> [remove] [preshared-key <file path>] [endpoint <ip>:<port>] [persistent-keepalive <interval seconds>] [allowed-ips <ip1>/<cidr1>[,<ip2>/<cidr2>]...] ]...\n", PROG_NAME, argv[0]);
 		return 1;
 	}
 
-- 
2.18.0

  parent reply	other threads:[~2018-09-09 15:13 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-09 15:13 [PATCH v2 00/10] Allow changing the transit namespace Julian Orth
2018-09-09 15:13 ` [PATCH v2 01/10] device: protect socket_init with device_update_lock Julian Orth
2018-09-09 15:13 ` [PATCH v2 02/10] device: rename creating_net to transit_net Julian Orth
2018-09-09 15:13 ` [PATCH v2 03/10] device: store a copy of the device net Julian Orth
2018-09-09 15:13 ` [PATCH v2 04/10] socket: allow modification of transit_net Julian Orth
2018-09-09 15:13 ` [PATCH v2 05/10] netlink: allow modification of transit net Julian Orth
2018-09-09 15:13 ` Julian Orth [this message]
2018-09-09 15:13 ` [PATCH v2 07/10] tests: add test for transit-net Julian Orth
2018-09-09 15:14 ` [PATCH v2 08/10] netlink: require CAP_NET_ADMIN for socket changes Julian Orth
2018-09-09 15:14 ` [PATCH v2 09/10] netlink: allow bypassing CAP_NET_ADMIN Julian Orth
2018-09-09 15:14 ` [PATCH v2 10/10] tools: add support for transit-credentials Julian Orth

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180909151402.6033-7-ju.orth@gmail.com \
    --to=ju.orth@gmail.com \
    --cc=wireguard@lists.zx2c4.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).