summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2017-01-24 17:43:35 +0100
committerJason A. Donenfeld <Jason@zx2c4.com>2017-02-13 21:55:18 +0100
commitbdc0caee9cf2dfa40f46d0e96f9c944463d77830 (patch)
treee804e8ac7f2537c73117b5c785da752254e96c0f
parent95507a57344431b890c12f3132a019f31d824b01 (diff)
socket: enable setting of fwmark
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r--src/config.c6
-rw-r--r--src/device.h1
-rw-r--r--src/socket.c3
-rw-r--r--src/uapi.h6
4 files changed, 13 insertions, 3 deletions
diff --git a/src/config.c b/src/config.c
index 172287a..30c876e 100644
--- a/src/config.c
+++ b/src/config.c
@@ -125,6 +125,11 @@ int config_set_device(struct wireguard_device *wg, void __user *user_device)
goto out;
}
+ if (in_device.fwmark || (!in_device.fwmark && (in_device.flags & WGDEVICE_REMOVE_FWMARK))) {
+ wg->fwmark = in_device.fwmark;
+ peer_for_each_unlocked(wg, clear_peer_endpoint_src, NULL);
+ }
+
if (in_device.port) {
ret = set_device_port(wg, in_device.port);
if (ret)
@@ -287,6 +292,7 @@ int config_get_device(struct wireguard_device *wg, void __user *udevice)
}
out_device.port = wg->incoming_port;
+ out_device.fwmark = wg->fwmark;
strncpy(out_device.interface, dev->name, IFNAMSIZ - 1);
out_device.interface[IFNAMSIZ - 1] = 0;
diff --git a/src/device.h b/src/device.h
index 3cbbbaa..855ec27 100644
--- a/src/device.h
+++ b/src/device.h
@@ -19,6 +19,7 @@
struct wireguard_device {
struct sock __rcu *sock4, *sock6;
u16 incoming_port;
+ u32 fwmark;
struct net *creating_net;
struct workqueue_struct *workqueue;
struct workqueue_struct *parallelqueue;
diff --git a/src/socket.c b/src/socket.c
index e26504d..f799d91 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -20,6 +20,7 @@ static inline int send4(struct wireguard_device *wg, struct sk_buff *skb, struct
.daddr = endpoint->addr4.sin_addr.s_addr,
.fl4_dport = endpoint->addr4.sin_port,
.fl4_sport = htons(wg->incoming_port),
+ .flowi4_mark = wg->fwmark,
.flowi4_proto = IPPROTO_UDP
};
struct rtable *rt = NULL;
@@ -62,7 +63,6 @@ static inline int send4(struct wireguard_device *wg, struct sk_buff *skb, struct
if (cache)
dst_cache_set_ip4(cache, &rt->dst, fl.saddr);
}
-
udp_tunnel_xmit_skb(rt, sock, skb,
fl.saddr, fl.daddr,
ds, ip4_dst_hoplimit(&rt->dst), 0,
@@ -85,6 +85,7 @@ static inline int send6(struct wireguard_device *wg, struct sk_buff *skb, struct
.daddr = endpoint->addr6.sin6_addr,
.fl6_dport = endpoint->addr6.sin6_port,
.fl6_sport = htons(wg->incoming_port),
+ .flowi6_mark = wg->fwmark,
.flowi6_oif = endpoint->addr6.sin6_scope_id,
.flowi6_proto = IPPROTO_UDP
/* TODO: addr->sin6_flowinfo */
diff --git a/src/uapi.h b/src/uapi.h
index eb8d9d3..9cf9b2c 100644
--- a/src/uapi.h
+++ b/src/uapi.h
@@ -121,7 +121,8 @@ struct wgpeer {
enum {
WGDEVICE_REPLACE_PEERS = (1 << 0),
WGDEVICE_REMOVE_PRIVATE_KEY = (1 << 1),
- WGDEVICE_REMOVE_PRESHARED_KEY = (1 << 2)
+ WGDEVICE_REMOVE_PRESHARED_KEY = (1 << 2),
+ WGDEVICE_REMOVE_FWMARK = (1 << 3)
};
struct wgdevice {
char interface[IFNAMSIZ]; /* Get */
@@ -130,11 +131,12 @@ struct wgdevice {
__u8 public_key[WG_KEY_LEN]; /* Get */
__u8 private_key[WG_KEY_LEN]; /* Get/Set */
__u8 preshared_key[WG_KEY_LEN]; /* Get/Set */
+ __u32 fwmark; /* Get/Set */
__u16 port; /* Get/Set */
union {
__u16 num_peers; /* Get/Set */
- __u64 peers_size; /* Get */
+ __u32 peers_size; /* Get */
};
};