aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/tools/ipc.c
diff options
context:
space:
mode:
authorJulian Orth <ju.orth@gmail.com>2018-09-11 20:14:55 +0200
committerJulian Orth <ju.orth@gmail.com>2018-12-17 15:39:45 +0100
commit21e5f1bcc352af8a2ed8b4212872688d214ae464 (patch)
tree6e2a9c46e38e5829f49fc7be39943b5cffc6e2e2 /src/tools/ipc.c
parenttools: add framework for shared options (diff)
downloadwireguard-monolithic-historical-21e5f1bcc352af8a2ed8b4212872688d214ae464.tar.xz
wireguard-monolithic-historical-21e5f1bcc352af8a2ed8b4212872688d214ae464.zip
tools: allow specifying the device namespace
The user can now use wg --netns <pid|file-path> <subcommand> to specify the network namespace in which wg should act. This sets the attribute WGDEVICE_A_DEV_NETNS_PID or WGDEVICE_A_DEV_NETNS_FD. In the case of wg --netns <pid|file-path> show all we have to try to enter the network namespace because the kernel interface does not allow us to list devices in a network namespace referenced by pid or fd. Since entering a network namespace requires CAP_SYS_ADMIN in the current user namespace and the target user namespace, this is almost useless. TODO: Add the missing functionality to the kernel.
Diffstat (limited to 'src/tools/ipc.c')
-rw-r--r--src/tools/ipc.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/src/tools/ipc.c b/src/tools/ipc.c
index 5879109..2c16897 100644
--- a/src/tools/ipc.c
+++ b/src/tools/ipc.c
@@ -551,7 +551,7 @@ cleanup:
return ret;
}
-static int kernel_set_device(struct wgdevice *dev)
+static int kernel_set_device(struct wgnetns *dev_netns, struct wgdevice *dev)
{
int ret = 0;
struct wgpeer *peer = NULL;
@@ -579,6 +579,10 @@ again:
mnl_attr_put_u32(nlh, WGDEVICE_A_FWMARK, dev->fwmark);
if (dev->flags & WGDEVICE_REPLACE_PEERS)
flags |= WGDEVICE_F_REPLACE_PEERS;
+ if (dev_netns->flags & WGNETNS_HAS_PID)
+ mnl_attr_put_u32(nlh, WGDEVICE_A_DEV_NETNS_PID, dev_netns->pid);
+ if (dev_netns->flags & WGNETNS_HAS_FD)
+ mnl_attr_put_u32(nlh, WGDEVICE_A_DEV_NETNS_FD, (uint32_t)dev_netns->fd);
if (flags)
mnl_attr_put_u32(nlh, WGDEVICE_A_FLAGS, flags);
}
@@ -885,7 +889,8 @@ static void coalesce_peers(struct wgdevice *device)
}
}
-static int kernel_get_device(struct wgdevice **device, const char *interface)
+static int kernel_get_device(struct wgnetns *dev_netns,
+ struct wgdevice **device, const char *interface)
{
int ret = 0;
struct nlmsghdr *nlh;
@@ -905,6 +910,10 @@ try_again:
nlh = mnlg_msg_prepare(nlg, WG_CMD_GET_DEVICE, NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP);
mnl_attr_put_strz(nlh, WGDEVICE_A_IFNAME, interface);
+ if (dev_netns->flags & WGNETNS_HAS_PID)
+ mnl_attr_put_u32(nlh, WGDEVICE_A_DEV_NETNS_PID, dev_netns->pid);
+ if (dev_netns->flags & WGNETNS_HAS_FD)
+ mnl_attr_put_u32(nlh, WGDEVICE_A_DEV_NETNS_FD, (uint32_t)dev_netns->fd);
if (mnlg_socket_send(nlg, nlh) < 0) {
ret = -errno;
goto out;
@@ -959,23 +968,24 @@ cleanup:
return buffer.buffer;
}
-int ipc_get_device(struct wgdevice **dev, const char *interface)
+int ipc_get_device(struct wgnetns *dev_netns, struct wgdevice **dev,
+ const char *interface)
{
#ifdef __linux__
if (userspace_has_wireguard_interface(interface))
return userspace_get_device(dev, interface);
- return kernel_get_device(dev, interface);
+ return kernel_get_device(dev_netns, dev, interface);
#else
return userspace_get_device(dev, interface);
#endif
}
-int ipc_set_device(struct wgdevice *dev)
+int ipc_set_device(struct wgnetns *dev_netns, struct wgdevice *dev)
{
#ifdef __linux__
if (userspace_has_wireguard_interface(dev->name))
return userspace_set_device(dev);
- return kernel_set_device(dev);
+ return kernel_set_device(dev_netns, dev);
#else
return userspace_set_device(dev);
#endif