diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2017-01-24 17:43:35 +0100 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2017-02-13 21:55:18 +0100 |
commit | bdc0caee9cf2dfa40f46d0e96f9c944463d77830 (patch) | |
tree | e804e8ac7f2537c73117b5c785da752254e96c0f | |
parent | 95507a57344431b890c12f3132a019f31d824b01 (diff) |
socket: enable setting of fwmark
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
-rw-r--r-- | src/config.c | 6 | ||||
-rw-r--r-- | src/device.h | 1 | ||||
-rw-r--r-- | src/socket.c | 3 | ||||
-rw-r--r-- | src/uapi.h | 6 |
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 */ @@ -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 */ }; }; |