From cd246809bbf0d948b5cd25d428a301960b5638d8 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Wed, 1 Nov 2017 21:28:39 +0100 Subject: Allow disabling roaming --- src/netlink.c | 7 +++++++ src/peer.h | 1 + src/socket.c | 15 ++++++++++----- src/uapi/wireguard.h | 3 ++- 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, -- cgit v1.2.3-59-g8ed1b