aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2017-11-01 21:28:39 +0100
committerJason A. Donenfeld <Jason@zx2c4.com>2017-11-01 21:28:39 +0100
commitcd246809bbf0d948b5cd25d428a301960b5638d8 (patch)
treed2703a619fad8dbdd6cae1275a6264c55fdcd92e
parentKconfig: remove trailing whitespace (diff)
downloadWireGuard-jd/fixed-endpoints.tar.xz
WireGuard-jd/fixed-endpoints.zip
Allow disabling roamingjd/fixed-endpoints
-rw-r--r--src/netlink.c7
-rw-r--r--src/peer.h1
-rw-r--r--src/socket.c15
-rw-r--r--src/uapi/wireguard.h3
4 files changed, 20 insertions, 6 deletions
diff --git a/src/netlink.c b/src/netlink.c
index 064fad9..d90f4fb 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -116,6 +116,8 @@ static int get_peer(struct wireguard_peer *peer, unsigned int index, struct rout
fail = nla_put(skb, WGPEER_A_ENDPOINT, sizeof(struct sockaddr_in), &peer->endpoint.addr4);
else if (peer->endpoint.addr.sa_family == AF_INET6)
fail = nla_put(skb, WGPEER_A_ENDPOINT, sizeof(struct sockaddr_in6), &peer->endpoint.addr6);
+ if (peer->endpoint.fixed)
+ nla_put_u32(skb, WGPEER_A_FLAGS, WGPEER_F_FIXED_ENDPOINT);
read_unlock_bh(&peer->endpoint_lock);
if (fail)
goto err;
@@ -347,9 +349,14 @@ static int set_peer(struct wireguard_device *wg, struct nlattr **attrs)
if ((len == sizeof(struct sockaddr_in) && addr->sa_family == AF_INET) || (len == sizeof(struct sockaddr_in6) && addr->sa_family == AF_INET6)) {
struct endpoint endpoint = { { { 0 } } };
+ endpoint.fixed = flags & WGPEER_F_FIXED_ENDPOINT;
memcpy(&endpoint.addr, addr, len);
socket_set_peer_endpoint(peer, &endpoint);
}
+ } else if (flags & WGPEER_F_FIXED_ENDPOINT) {
+ write_lock_bh(&peer->endpoint_lock);
+ peer->endpoint.fixed = peer->endpoint.addr.sa_family == AF_INET || peer->endpoint.addr.sa_family == AF_INET6;
+ write_unlock_bh(&peer->endpoint_lock);
}
if (flags & WGPEER_F_REPLACE_ALLOWEDIPS)
diff --git a/src/peer.h b/src/peer.h
index 49784d1..b8f5053 100644
--- a/src/peer.h
+++ b/src/peer.h
@@ -28,6 +28,7 @@ struct endpoint {
};
struct in6_addr src6;
};
+ bool fixed;
};
struct wireguard_peer {
diff --git a/src/socket.c b/src/socket.c
index 1ce74cd..57ab61e 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -248,12 +248,17 @@ void socket_set_peer_endpoint(struct wireguard_peer *peer, const struct endpoint
return;
write_lock_bh(&peer->endpoint_lock);
if (endpoint->addr.sa_family == AF_INET) {
- peer->endpoint.addr4 = endpoint->addr4;
- peer->endpoint.src4 = endpoint->src4;
- peer->endpoint.src_if4 = endpoint->src_if4;
+ if (!peer->endpoint.fixed)
+ peer->endpoint.addr4 = endpoint->addr4;
+ if (!peer->endpoint.fixed || peer->endpoint.addr.sa_family == AF_INET) {
+ peer->endpoint.src4 = endpoint->src4;
+ peer->endpoint.src_if4 = endpoint->src_if4;
+ }
} else if (endpoint->addr.sa_family == AF_INET6) {
- peer->endpoint.addr6 = endpoint->addr6;
- peer->endpoint.src6 = endpoint->src6;
+ if (!peer->endpoint.fixed)
+ peer->endpoint.addr6 = endpoint->addr6;
+ if (!peer->endpoint.fixed || peer->endpoint.addr.sa_family == AF_INET6)
+ peer->endpoint.src6 = endpoint->src6;
} else
goto out;
dst_cache_reset(&peer->endpoint_cache);
diff --git a/src/uapi/wireguard.h b/src/uapi/wireguard.h
index e776f7c..7f71354 100644
--- a/src/uapi/wireguard.h
+++ b/src/uapi/wireguard.h
@@ -170,7 +170,8 @@ enum wgdevice_attribute {
enum wgpeer_flag {
WGPEER_F_REMOVE_ME = 1U << 0,
- WGPEER_F_REPLACE_ALLOWEDIPS = 1U << 1
+ WGPEER_F_REPLACE_ALLOWEDIPS = 1U << 1,
+ WGPEER_F_FIXED_ENDPOINT = 1U << 2
};
enum wgpeer_attribute {
WGPEER_A_UNSPEC,