Development discussion of WireGuard
 help / color / mirror / Atom feed
* [PATCH 0/1] Add support to send/receive tunnel packets via Linux VRFs
@ 2021-11-15 15:57 Maximilian Wilhelm
  2021-11-15 16:04 ` [PATCH 1/1] wireguard: Add support to bind socket(s) to device Maximilian Wilhelm
  0 siblings, 1 reply; 2+ messages in thread
From: Maximilian Wilhelm @ 2021-11-15 15:57 UTC (permalink / raw)
  To: wireguard

Hi,

this patch adds support to bind the listening/sending UDP sockets to a
specific network interface on Linux to allow sending/receiving encrypted
tunnel packets via a given VRF.

The motivation behind this is to put any external interface(s) of a host
into a VRF (e.g. "vrf_external") and have the rest of the interface in the
main VRF, so all tools and services can be used normally and can't directly
reach/leak to the Internet.  This way different island can be connected
easily and securely without the fear of leaking any communication into the
Internet.  See my blog article on VRF support for OpenVPN [0] for a more
detailed description.

Using VRFs is much simpler than setting up Network Namespaces, shoving
interfaces around and having to care about which processes should run
where.

This patch is very similar to the patch "Basic support for binding the
transport socket to a device" sent in June this year, but adds two more
settings in send4() and send6() without VRF support didn't work for me.

I'm unsure wether it would be better to use the name "bind_dev" within
the kernel or clearly denote that an ifindex is used, as it is now.

The user-space part of this change is available as a PR to the 
wireguard-linux
repo on GitHub [1], but can be sent as patches to the list as well.

Best
Max

[0] https://blog.sdn.clinic/2018/12/openvpn-and-vrfs/
[1] https://github.com/WireGuard/wireguard-tools/pull/12

Maximilian Wilhelm (1):
   wireguard: Add support to bind socket(s) to device

  drivers/net/wireguard/device.h  |  1 +
  drivers/net/wireguard/netlink.c |  7 ++++++-
  drivers/net/wireguard/socket.c  | 13 +++++++++++++
  include/uapi/linux/wireguard.h  |  2 ++
  4 files changed, 22 insertions(+), 1 deletion(-)

-- 
2.20.1

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [PATCH 1/1] wireguard: Add support to bind socket(s) to device
  2021-11-15 15:57 [PATCH 0/1] Add support to send/receive tunnel packets via Linux VRFs Maximilian Wilhelm
@ 2021-11-15 16:04 ` Maximilian Wilhelm
  0 siblings, 0 replies; 2+ messages in thread
From: Maximilian Wilhelm @ 2021-11-15 16:04 UTC (permalink / raw)
  To: wireguard

From: Maximilian Wilhelm <max@sdn.clinic>

   This introduces support for binding Wireguards UDP socket(s) to a
   given interface allowing to send/receive encapsulated packets via
   a VRF.

Signed-off-by: Maximilian Wilhelm <max@sdn.clinic>
---
  drivers/net/wireguard/device.h  |  1 +
  drivers/net/wireguard/netlink.c |  7 ++++++-
  drivers/net/wireguard/socket.c  | 13 +++++++++++++
  include/uapi/linux/wireguard.h  |  2 ++
  4 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireguard/device.h b/drivers/net/wireguard/device.h
index 854bc3d97150..85f9fe687cb8 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 bind_ifindex;
  	u16 incoming_port;
  };

diff --git a/drivers/net/wireguard/netlink.c 
b/drivers/net/wireguard/netlink.c
index d0f3b6d7f408..064402a11eb3 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_BIND_IFINDEX]	= { .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_BIND_IFINDEX, wg->bind_ifindex) ||
  		    nla_put_u32(skb, WGDEVICE_A_IFINDEX, wg->dev->ifindex) ||
  		    nla_put_string(skb, WGDEVICE_A_IFNAME, wg->dev->name))
  			goto out;
@@ -531,6 +533,9 @@ static int wg_set_device(struct sk_buff *skb, struct 
genl_info *info)
  			wg_socket_clear_peer_endpoint_src(peer);
  	}

+	if (info->attrs[WGDEVICE_A_BIND_IFINDEX])
+		wg->bind_ifindex = nla_get_u32(info->attrs[WGDEVICE_A_BIND_IFINDEX]);
+
  	if (info->attrs[WGDEVICE_A_LISTEN_PORT]) {
  		ret = set_port(wg,
  			nla_get_u16(info->attrs[WGDEVICE_A_LISTEN_PORT]));
diff --git a/drivers/net/wireguard/socket.c b/drivers/net/wireguard/socket.c
index 8c496b747108..d319288a8f3b 100644
--- a/drivers/net/wireguard/socket.c
+++ b/drivers/net/wireguard/socket.c
@@ -35,6 +35,9 @@ static int send4(struct wg_device *wg, struct sk_buff 
*skb,
  	skb->dev = wg->dev;
  	skb->mark = wg->fwmark;

+	if (wg->bind_ifindex)
+		fl.flowi4_oif = wg->bind_ifindex;
+
  	rcu_read_lock_bh();
  	sock = rcu_dereference_bh(wg->sock4);

@@ -115,6 +118,9 @@ static int send6(struct wg_device *wg, struct 
sk_buff *skb,
  	skb->dev = wg->dev;
  	skb->mark = wg->fwmark;

+	if (wg->bind_ifindex)
+		fl.flowi6_oif = wg->bind_ifindex;
+
  	rcu_read_lock_bh();
  	sock = rcu_dereference_bh(wg->sock6);

@@ -379,6 +385,13 @@ int wg_socket_init(struct wg_device *wg, u16 port)
  	if (unlikely(!net))
  		return -ENONET;

+	if (wg->bind_ifindex) {
+		port4.bind_ifindex = wg->bind_ifindex;
+#if IS_ENABLED(CONFIG_IPV6)
+		port6.bind_ifindex = wg->bind_ifindex;
+#endif
+	}
+
  #if IS_ENABLED(CONFIG_IPV6)
  retry:
  #endif
diff --git a/include/uapi/linux/wireguard.h b/include/uapi/linux/wireguard.h
index ae88be14c947..5c49919596b8 100644
--- a/include/uapi/linux/wireguard.h
+++ b/include/uapi/linux/wireguard.h
@@ -114,6 +114,7 @@
   *        0: NLA_NESTED
   *            ...
   *        ...
+ *    WGDEVICE_A_BIND_IFINDEX: NLA_U32
   *
   * It is possible that the amount of configuration data exceeds that of
   * the maximum message length accepted by the kernel. In that case, 
several
@@ -157,6 +158,7 @@ enum wgdevice_attribute {
  	WGDEVICE_A_LISTEN_PORT,
  	WGDEVICE_A_FWMARK,
  	WGDEVICE_A_PEERS,
+	WGDEVICE_A_BIND_IFINDEX,
  	__WGDEVICE_A_LAST
  };
  #define WGDEVICE_A_MAX (__WGDEVICE_A_LAST - 1)
-- 
2.20.1


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-11-15 16:06 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-15 15:57 [PATCH 0/1] Add support to send/receive tunnel packets via Linux VRFs Maximilian Wilhelm
2021-11-15 16:04 ` [PATCH 1/1] wireguard: Add support to bind socket(s) to device Maximilian Wilhelm

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).