From: Marvin Gaube <dev@marvingaube.de>
To: wireguard@lists.zx2c4.com
Cc: dev@marvingaube.de
Subject: [PATCH wireguard-linux] Basic support for binding the transport socket to a device
Date: Sun, 6 Jun 2021 11:24:20 +0200 [thread overview]
Message-ID: <20210606092420.85239-1-dev@marvingaube.de> (raw)
This patch depends on da5095d052860baa7fe2932fb1209628dd3e3813 from udp_tunnel module,
and allows to bind the transport socket to a specific interface.
With this patch, it is possible to use wireguard with VRFs:
The transport uses a separate "WAN" VRF, cleanly isolating Local/VPN and WAN Routing.
The userspace API is designed to transmit the device index of the device to listen on.
Listening on a device does only work if the socketdev_index is set/changed before the socket is brought up.
Signed-off-by: Marvin Gaube <dev@marvingaube.de>
---
drivers/net/wireguard/device.h | 1 +
drivers/net/wireguard/netlink.c | 8 +++++++-
drivers/net/wireguard/socket.c | 10 ++++++++++
include/uapi/linux/wireguard.h | 3 +++
4 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireguard/device.h b/drivers/net/wireguard/device.h
index 854bc3d97150..a08f0893f687 100644
--- a/drivers/net/wireguard/device.h
+++ b/drivers/net/wireguard/device.h
@@ -56,6 +56,7 @@ struct wg_device {
struct list_head device_list, peer_list;
unsigned int num_peers, device_update_gen;
u32 fwmark;
+ u32 socketdev_index;
u16 incoming_port;
};
diff --git a/drivers/net/wireguard/netlink.c b/drivers/net/wireguard/netlink.c
index d0f3b6d7f408..c594a7063038 100644
--- a/drivers/net/wireguard/netlink.c
+++ b/drivers/net/wireguard/netlink.c
@@ -27,7 +27,8 @@ static const struct nla_policy device_policy[WGDEVICE_A_MAX + 1] = {
[WGDEVICE_A_FLAGS] = { .type = NLA_U32 },
[WGDEVICE_A_LISTEN_PORT] = { .type = NLA_U16 },
[WGDEVICE_A_FWMARK] = { .type = NLA_U32 },
- [WGDEVICE_A_PEERS] = { .type = NLA_NESTED }
+ [WGDEVICE_A_PEERS] = { .type = NLA_NESTED },
+ [WGDEVICE_A_SOCKETDEV_INDEX] = { .type = NLA_U32 }
};
static const struct nla_policy peer_policy[WGPEER_A_MAX + 1] = {
@@ -232,6 +233,7 @@ static int wg_get_device_dump(struct sk_buff *skb, struct netlink_callback *cb)
if (nla_put_u16(skb, WGDEVICE_A_LISTEN_PORT,
wg->incoming_port) ||
nla_put_u32(skb, WGDEVICE_A_FWMARK, wg->fwmark) ||
+ nla_put_u32(skb, WGDEVICE_A_SOCKETDEV_INDEX, wg->socketdev_index) ||
nla_put_u32(skb, WGDEVICE_A_IFINDEX, wg->dev->ifindex) ||
nla_put_string(skb, WGDEVICE_A_IFNAME, wg->dev->name))
goto out;
@@ -538,6 +540,10 @@ static int wg_set_device(struct sk_buff *skb, struct genl_info *info)
goto out;
}
+ if (info->attrs[WGDEVICE_A_SOCKETDEV_INDEX]) {
+ wg->socketdev_index = nla_get_u32(info->attrs[WGDEVICE_A_SOCKETDEV_INDEX]);
+ }
+
if (flags & WGDEVICE_F_REPLACE_PEERS)
wg_peer_remove_all(wg);
diff --git a/drivers/net/wireguard/socket.c b/drivers/net/wireguard/socket.c
index d9ad850daa79..885d8a890079 100644
--- a/drivers/net/wireguard/socket.c
+++ b/drivers/net/wireguard/socket.c
@@ -370,8 +370,18 @@ int wg_socket_init(struct wg_device *wg, u16 port)
.use_udp6_rx_checksums = true,
.ipv6_v6only = true
};
+ if (wg->socketdev_index > 0) {
+ port6.bind_ifindex = wg->socketdev_index;
+ } else {
+ port6.bind_ifindex = 0;
+ }
#endif
+ if (wg->socketdev_index > 0) {
+ port4.bind_ifindex = wg->socketdev_index;
+ } else {
+ port4.bind_ifindex = 0;
+ }
rcu_read_lock();
net = rcu_dereference(wg->creating_net);
net = net ? maybe_get_net(net) : NULL;
diff --git a/include/uapi/linux/wireguard.h b/include/uapi/linux/wireguard.h
index ae88be14c947..52b1bd422f50 100644
--- a/include/uapi/linux/wireguard.h
+++ b/include/uapi/linux/wireguard.h
@@ -29,6 +29,7 @@
* WGDEVICE_A_PUBLIC_KEY: NLA_EXACT_LEN, len WG_KEY_LEN
* WGDEVICE_A_LISTEN_PORT: NLA_U16
* WGDEVICE_A_FWMARK: NLA_U32
+ * WGDEVICE_A_SOCKETDEV_INDEX: NLA_U32
* WGDEVICE_A_PEERS: NLA_NESTED
* 0: NLA_NESTED
* WGPEER_A_PUBLIC_KEY: NLA_EXACT_LEN, len WG_KEY_LEN
@@ -83,6 +84,7 @@
* WGDEVICE_A_PRIVATE_KEY: len WG_KEY_LEN, all zeros to remove
* WGDEVICE_A_LISTEN_PORT: NLA_U16, 0 to choose randomly
* WGDEVICE_A_FWMARK: NLA_U32, 0 to disable
+ * WGDEVICE_A_SOCKETDEV_INDEX: NLA_U32, 0 to disable
* WGDEVICE_A_PEERS: NLA_NESTED
* 0: NLA_NESTED
* WGPEER_A_PUBLIC_KEY: len WG_KEY_LEN
@@ -157,6 +159,7 @@ enum wgdevice_attribute {
WGDEVICE_A_LISTEN_PORT,
WGDEVICE_A_FWMARK,
WGDEVICE_A_PEERS,
+ WGDEVICE_A_SOCKETDEV_INDEX,
__WGDEVICE_A_LAST
};
#define WGDEVICE_A_MAX (__WGDEVICE_A_LAST - 1)
--
2.25.1
reply other threads:[~2021-06-06 12:39 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20210606092420.85239-1-dev@marvingaube.de \
--to=dev@marvingaube.de \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.