wireguard.lists.zx2c4.com archive mirror
 help / color / mirror / Atom feed
From: Maximilian Wilhelm <max@sdn.clinic>
To: wireguard@lists.zx2c4.com
Subject: [PATCH 1/1] wireguard: Add support to bind socket(s) to device
Date: Mon, 15 Nov 2021 17:04:29 +0100	[thread overview]
Message-ID: <80d36571-9345-5855-1710-ca5a796e2fe9@sdn.clinic> (raw)
In-Reply-To: <d1c0a3e8-c461-3d70-e23f-fceac21cbd43@sdn.clinic>

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


      reply	other threads:[~2021-11-15 16:06 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]

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=80d36571-9345-5855-1710-ca5a796e2fe9@sdn.clinic \
    --to=max@sdn.clinic \
    --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).