-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add wireguard patches from Unifi GPL sources
Wireguard patches allow module to work better with teleport and other Ubiquiti specific kernel changes. Also add UDM base module, and upgrade UDR sources to 3.0.13
- Loading branch information
Showing
71 changed files
with
9,223 additions
and
3,127 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
Git LFS file not shown
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
...1.11.0/patches/wireguard-linux-compat/0001-exclude-skb_put_data-for-kernel-v4.4.198.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
--- a/src/compat/compat.h | ||
+++ b/src/compat/compat.h | ||
@@ -664,7 +664,8 @@ struct __compat_dummy_container { char dev; }; | ||
#define genl_dump_check_consistent(a, b) genl_dump_check_consistent(a, b, &genl_family) | ||
#endif | ||
|
||
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) && !defined(ISRHEL7) | ||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) && !defined(ISRHEL7) && \ | ||
+ LINUX_VERSION_CODE != KERNEL_VERSION(4, 4, 198) | ||
static inline void *skb_put_data(struct sk_buff *skb, const void *data, unsigned int len) | ||
{ | ||
void *tmp = skb_put(skb, len); | ||
|
||
|
14 changes: 14 additions & 0 deletions
14
...-1.11.0/patches/wireguard-linux-compat/0002-exclude-skb_put_data-for-kernel-v4.4.60.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
diff --git a/src/compat/compat.h b/src/compat/compat.h | ||
index 7acbfc6..845238c 100644 | ||
--- a/src/compat/compat.h | ||
+++ b/src/compat/compat.h | ||
@@ -665,7 +665,8 @@ struct __compat_dummy_container { char dev; }; | ||
#endif | ||
|
||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) && !defined(ISRHEL7) && \ | ||
- LINUX_VERSION_CODE != KERNEL_VERSION(4, 4, 198) | ||
+ LINUX_VERSION_CODE != KERNEL_VERSION(4, 4, 198) && \ | ||
+ LINUX_VERSION_CODE != KERNEL_VERSION(4, 4, 60) | ||
static inline void *skb_put_data(struct sk_buff *skb, const void *data, unsigned int len) | ||
{ | ||
void *tmp = skb_put(skb, len); |
73 changes: 73 additions & 0 deletions
73
...m-1.11.0/patches/wireguard-linux-compat/021-ubnt-reuse-addr-and-port-for-udp-tunnel.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
diff --git a/src/compat/udp_tunnel/udp_tunnel_partial_compat.h b/src/compat/udp_tunnel/udp_tunnel_partial_compat.h | ||
index 0605896..ca810fd 100644 | ||
--- a/src/compat/udp_tunnel/udp_tunnel_partial_compat.h | ||
+++ b/src/compat/udp_tunnel/udp_tunnel_partial_compat.h | ||
@@ -168,15 +168,15 @@ struct __compat_udp_port_cfg { | ||
struct in_addr peer_ip; | ||
#if IS_ENABLED(CONFIG_IPV6) | ||
struct in6_addr peer_ip6; | ||
#endif | ||
}; | ||
__be16 local_udp_port; | ||
__be16 peer_udp_port; | ||
- unsigned int use_udp_checksums:1, use_udp6_tx_checksums:1, use_udp6_rx_checksums:1, ipv6_v6only:1; | ||
+ unsigned int use_udp_checksums:1, use_udp6_tx_checksums:1, use_udp6_rx_checksums:1, reuse_addr:1, reuse_port:1, ipv6_v6only:1; | ||
}; | ||
static inline int __maybe_unused __compat_udp_sock_create(struct net *net, struct __compat_udp_port_cfg *cfg, struct socket **sockp) | ||
{ | ||
struct udp_port_cfg old_cfg = { | ||
.family = cfg->family, | ||
.local_ip = cfg->local_ip, | ||
#if IS_ENABLED(CONFIG_IPV6) | ||
@@ -186,15 +186,17 @@ static inline int __maybe_unused __compat_udp_sock_create(struct net *net, struc | ||
#if IS_ENABLED(CONFIG_IPV6) | ||
.peer_ip6 = cfg->peer_ip6, | ||
#endif | ||
.local_udp_port = cfg->local_udp_port, | ||
.peer_udp_port = cfg->peer_udp_port, | ||
.use_udp_checksums = cfg->use_udp_checksums, | ||
.use_udp6_tx_checksums = cfg->use_udp6_tx_checksums, | ||
- .use_udp6_rx_checksums = cfg->use_udp6_rx_checksums | ||
+ .use_udp6_rx_checksums = cfg->use_udp6_rx_checksums, | ||
+ .reuse_addr = cfg->reuse_addr, | ||
+ .reuse_port = cfg->reuse_port | ||
}; | ||
if (cfg->family == AF_INET) | ||
return udp_sock_create4(net, &old_cfg, sockp); | ||
|
||
#if IS_ENABLED(CONFIG_IPV6) | ||
if (cfg->family == AF_INET6) { | ||
int ret; | ||
diff --git a/src/socket.c b/src/socket.c | ||
index e8eceeb..dcc4088 100644 | ||
--- a/src/socket.c | ||
+++ b/src/socket.c | ||
@@ -355,23 +355,27 @@ int wg_socket_init(struct wg_device *wg, u16 port) | ||
.encap_rcv = wg_receive | ||
}; | ||
struct socket *new4 = NULL, *new6 = NULL; | ||
struct udp_port_cfg port4 = { | ||
.family = AF_INET, | ||
.local_ip.s_addr = htonl(INADDR_ANY), | ||
.local_udp_port = htons(port), | ||
- .use_udp_checksums = true | ||
+ .use_udp_checksums = true, | ||
+ .reuse_addr = true, | ||
+ .reuse_port = true | ||
}; | ||
#if IS_ENABLED(CONFIG_IPV6) | ||
int retries = 0; | ||
struct udp_port_cfg port6 = { | ||
.family = AF_INET6, | ||
.local_ip6 = IN6ADDR_ANY_INIT, | ||
.use_udp6_tx_checksums = true, | ||
.use_udp6_rx_checksums = true, | ||
+ .reuse_addr = true, | ||
+ .reuse_port = true, | ||
.ipv6_v6only = true | ||
}; | ||
#endif | ||
|
||
rcu_read_lock(); | ||
net = rcu_dereference(wg->creating_net); | ||
net = net ? maybe_get_net(net) : NULL; |
31 changes: 31 additions & 0 deletions
31
...es/udm-1.11.0/patches/wireguard-linux-compat/041-ubnt-protection-from-routing-loops.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
diff --git a/src/device.c b/src/device.c | ||
index c673446..25aac06 100644 | ||
--- a/src/device.c | ||
+++ b/src/device.c | ||
@@ -127,14 +127,26 @@ static netdev_tx_t wg_xmit(struct sk_buff *skb, struct net_device *dev) | ||
struct sk_buff_head packets; | ||
struct wg_peer *peer; | ||
struct sk_buff *next; | ||
sa_family_t family; | ||
u32 mtu; | ||
int ret; | ||
|
||
+ if (unlikely(skb->mark & wg->fwmark)) { | ||
+ ret = -ENETDOWN; | ||
+ net_crit_ratelimited("%s: loop detected, dropping skb of length %u\n", dev->name, skb->len); | ||
+ goto err; | ||
+ } | ||
+ | ||
+ if (unlikely(skb_end_offset(skb) > 33000)) { | ||
+ ret = -ENETDOWN; | ||
+ net_crit_ratelimited("%s: possible loop detected, dropping skb of size %u\n", dev->name, skb_end_offset(skb)); | ||
+ goto err; | ||
+ } | ||
+ | ||
if (unlikely(!wg_check_packet_protocol(skb))) { | ||
ret = -EPROTONOSUPPORT; | ||
net_dbg_ratelimited("%s: Invalid IP packet\n", dev->name); | ||
goto err; | ||
} | ||
|
||
peer = wg_allowedips_lookup_dst(&wg->peer_allowedips, skb); |
233 changes: 233 additions & 0 deletions
233
...ses/udm-1.11.0/patches/wireguard-linux-compat/099-ubnt-add-get-last-receive-timeout.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,233 @@ | ||
--- a/src/netlink.c | ||
+++ b/src/netlink.c | ||
@@ -34,15 +34,17 @@ static const struct nla_policy peer_poli | ||
[WGPEER_A_FLAGS] = { .type = NLA_U32 }, | ||
[WGPEER_A_ENDPOINT] = NLA_POLICY_MIN_LEN(sizeof(struct sockaddr)), | ||
[WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL] = { .type = NLA_U16 }, | ||
[WGPEER_A_LAST_HANDSHAKE_TIME] = NLA_POLICY_EXACT_LEN(sizeof(struct __kernel_timespec)), | ||
[WGPEER_A_RX_BYTES] = { .type = NLA_U64 }, | ||
[WGPEER_A_TX_BYTES] = { .type = NLA_U64 }, | ||
[WGPEER_A_ALLOWEDIPS] = { .type = NLA_NESTED }, | ||
- [WGPEER_A_PROTOCOL_VERSION] = { .type = NLA_U32 } | ||
+ [WGPEER_A_PROTOCOL_VERSION] = { .type = NLA_U32 }, | ||
+ [WGPEER_A_FORCED_HANDSHAKE_INTERVAL] = { .type = NLA_U16 }, | ||
+ [WGPEER_A_LAST_RECEIVE_TIME] = NLA_POLICY_EXACT_LEN(sizeof(struct __kernel_timespec)), | ||
}; | ||
|
||
static const struct nla_policy allowedip_policy[WGALLOWEDIP_A_MAX + 1] = { | ||
[WGALLOWEDIP_A_FAMILY] = { .type = NLA_U16 }, | ||
[WGALLOWEDIP_A_IPADDR] = NLA_POLICY_MIN_LEN(sizeof(struct in_addr)), | ||
[WGALLOWEDIP_A_CIDR_MASK] = { .type = NLA_U8 } | ||
}; | ||
@@ -119,31 +121,39 @@ get_peer(struct wg_peer *peer, struct sk | ||
goto err; | ||
|
||
if (!allowedips_node) { | ||
const struct __kernel_timespec last_handshake = { | ||
.tv_sec = peer->walltime_last_handshake.tv_sec, | ||
.tv_nsec = peer->walltime_last_handshake.tv_nsec | ||
}; | ||
+ const struct __kernel_timespec last_receive = { | ||
+ .tv_sec = peer->walltime_last_receive.tv_sec, | ||
+ .tv_nsec = peer->walltime_last_receive.tv_nsec | ||
+ }; | ||
|
||
down_read(&peer->handshake.lock); | ||
fail = nla_put(skb, WGPEER_A_PRESHARED_KEY, | ||
NOISE_SYMMETRIC_KEY_LEN, | ||
peer->handshake.preshared_key); | ||
up_read(&peer->handshake.lock); | ||
if (fail) | ||
goto err; | ||
|
||
if (nla_put(skb, WGPEER_A_LAST_HANDSHAKE_TIME, | ||
sizeof(last_handshake), &last_handshake) || | ||
+ nla_put(skb, WGPEER_A_LAST_RECEIVE_TIME, | ||
+ sizeof(last_receive), &last_receive) || | ||
nla_put_u16(skb, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL, | ||
peer->persistent_keepalive_interval) || | ||
nla_put_u64_64bit(skb, WGPEER_A_TX_BYTES, peer->tx_bytes, | ||
WGPEER_A_UNSPEC) || | ||
nla_put_u64_64bit(skb, WGPEER_A_RX_BYTES, peer->rx_bytes, | ||
WGPEER_A_UNSPEC) || | ||
+ nla_put_u16(skb, WGPEER_A_FORCED_HANDSHAKE_INTERVAL, | ||
+ peer->forced_handshake_interval) || | ||
nla_put_u32(skb, WGPEER_A_PROTOCOL_VERSION, 1)) | ||
goto err; | ||
|
||
read_lock_bh(&peer->endpoint_lock); | ||
if (peer->endpoint.addr.sa_family == AF_INET) | ||
fail = nla_put(skb, WGPEER_A_ENDPOINT, | ||
sizeof(peer->endpoint.addr4), | ||
@@ -474,14 +484,19 @@ static int set_peer(struct wg_device *wg | ||
netif_running(wg->dev); | ||
|
||
peer->persistent_keepalive_interval = persistent_keepalive_interval; | ||
if (send_keepalive) | ||
wg_packet_send_keepalive(peer); | ||
} | ||
|
||
+ if (attrs[WGPEER_A_FORCED_HANDSHAKE_INTERVAL]) { | ||
+ peer->forced_handshake_interval = nla_get_u16( | ||
+ attrs[WGPEER_A_FORCED_HANDSHAKE_INTERVAL]); | ||
+ } | ||
+ | ||
if (netif_running(wg->dev)) | ||
wg_packet_send_staged_packets(peer); | ||
|
||
out: | ||
wg_peer_put(peer); | ||
if (attrs[WGPEER_A_PRESHARED_KEY]) | ||
memzero_explicit(nla_data(attrs[WGPEER_A_PRESHARED_KEY]), | ||
--- a/src/peer.h | ||
+++ b/src/peer.h | ||
@@ -60,14 +60,17 @@ struct wg_peer { | ||
struct timespec64 walltime_last_handshake; | ||
struct kref refcount; | ||
struct rcu_head rcu; | ||
struct list_head peer_list; | ||
struct list_head allowedips_list; | ||
struct napi_struct napi; | ||
u64 internal_id; | ||
+ u16 forced_handshake_interval; | ||
+ struct timer_list timer_forced_handshake; | ||
+ struct timespec64 walltime_last_receive; | ||
}; | ||
|
||
struct wg_peer *wg_peer_create(struct wg_device *wg, | ||
const u8 public_key[NOISE_PUBLIC_KEY_LEN], | ||
const u8 preshared_key[NOISE_SYMMETRIC_KEY_LEN]); | ||
|
||
struct wg_peer *__must_check wg_peer_get_maybe_zero(struct wg_peer *peer); | ||
--- a/src/timers.c | ||
+++ b/src/timers.c | ||
@@ -137,14 +137,31 @@ static void wg_expired_send_persistent_k | ||
struct wg_peer *peer = from_timer(peer, timer, | ||
timer_persistent_keepalive); | ||
|
||
if (likely(peer->persistent_keepalive_interval)) | ||
wg_packet_send_keepalive(peer); | ||
} | ||
|
||
+static void wg_expired_forced_handshake(struct timer_list *timer) | ||
+{ | ||
+ struct wg_peer *peer = from_timer(peer, timer, timer_forced_handshake); | ||
+ | ||
+ if (!likely(peer->forced_handshake_interval)) | ||
+ return; | ||
+ | ||
+ pr_debug("%s: Retrying handshake with peer %llu (%pISpfsc) because we stopped hearing back after forced handshake timeout %d seconds\n", | ||
+ peer->device->dev->name, peer->internal_id, | ||
+ &peer->endpoint.addr, peer->forced_handshake_interval); | ||
+ /* We clear the endpoint address src address, in case this is the cause | ||
+ * of trouble. | ||
+ */ | ||
+ wg_socket_clear_peer_endpoint_src(peer); | ||
+ wg_packet_send_queued_handshake_initiation(peer, false); | ||
+} | ||
+ | ||
/* Should be called after an authenticated data packet is sent. */ | ||
void wg_timers_data_sent(struct wg_peer *peer) | ||
{ | ||
if (!timer_pending(&peer->timer_new_handshake)) | ||
mod_peer_timer(peer, &peer->timer_new_handshake, | ||
jiffies + (KEEPALIVE_TIMEOUT + REKEY_TIMEOUT) * HZ + | ||
prandom_u32_max(REKEY_TIMEOUT_JITTER_MAX_JIFFIES)); | ||
@@ -172,14 +189,19 @@ void wg_timers_any_authenticated_packet_ | ||
|
||
/* Should be called after any type of authenticated packet is received, whether | ||
* keepalive, data, or handshake. | ||
*/ | ||
void wg_timers_any_authenticated_packet_received(struct wg_peer *peer) | ||
{ | ||
del_timer(&peer->timer_new_handshake); | ||
+ ktime_get_real_ts64(&peer->walltime_last_receive); | ||
+ if (likely(peer->forced_handshake_interval)) { | ||
+ mod_peer_timer(peer, &peer->timer_forced_handshake, | ||
+ jiffies + peer->forced_handshake_interval * HZ); | ||
+ } | ||
} | ||
|
||
/* Should be called after a handshake initiation message is sent. */ | ||
void wg_timers_handshake_initiated(struct wg_peer *peer) | ||
{ | ||
mod_peer_timer(peer, &peer->timer_retransmit_handshake, | ||
jiffies + REKEY_TIMEOUT * HZ + | ||
@@ -222,22 +244,25 @@ void wg_timers_init(struct wg_peer *peer | ||
wg_expired_retransmit_handshake, 0); | ||
timer_setup(&peer->timer_send_keepalive, wg_expired_send_keepalive, 0); | ||
timer_setup(&peer->timer_new_handshake, wg_expired_new_handshake, 0); | ||
timer_setup(&peer->timer_zero_key_material, | ||
wg_expired_zero_key_material, 0); | ||
timer_setup(&peer->timer_persistent_keepalive, | ||
wg_expired_send_persistent_keepalive, 0); | ||
+ timer_setup(&peer->timer_forced_handshake, | ||
+ wg_expired_forced_handshake, 0); | ||
INIT_WORK(&peer->clear_peer_work, wg_queued_expired_zero_key_material); | ||
peer->timer_handshake_attempts = 0; | ||
peer->sent_lastminute_handshake = false; | ||
peer->timer_need_another_keepalive = false; | ||
} | ||
|
||
void wg_timers_stop(struct wg_peer *peer) | ||
{ | ||
del_timer_sync(&peer->timer_retransmit_handshake); | ||
del_timer_sync(&peer->timer_send_keepalive); | ||
del_timer_sync(&peer->timer_new_handshake); | ||
+ del_timer_sync(&peer->timer_forced_handshake); | ||
del_timer_sync(&peer->timer_zero_key_material); | ||
del_timer_sync(&peer->timer_persistent_keepalive); | ||
flush_work(&peer->clear_peer_work); | ||
} | ||
--- a/src/uapi/wireguard.h | ||
+++ b/src/uapi/wireguard.h | ||
@@ -45,14 +45,16 @@ | ||
* WGALLOWEDIP_A_CIDR_MASK: NLA_U8 | ||
* 0: NLA_NESTED | ||
* ... | ||
* 0: NLA_NESTED | ||
* ... | ||
* ... | ||
* WGPEER_A_PROTOCOL_VERSION: NLA_U32 | ||
+ * WGPEER_A_FORCED_HANDSHAKE_INTERVAL: NLA_U16 | ||
+ * WGPEER_A_LAST_RECEIVE_TIME: NLA_EXACT_LEN, struct __kernel_timespec | ||
* 0: NLA_NESTED | ||
* ... | ||
* ... | ||
* | ||
* It is possible that all of the allowed IPs of a single peer will not | ||
* fit within a single netlink message. In that case, the same peer will | ||
* be written in the following message, except it will only contain | ||
@@ -107,14 +109,15 @@ | ||
* ... | ||
* ... | ||
* WGPEER_A_PROTOCOL_VERSION: NLA_U32, should not be set or used at | ||
* all by most users of this API, as the | ||
* most recent protocol will be used when | ||
* this is unset. Otherwise, must be set | ||
* to 1. | ||
+ * WGPEER_A_FORCED_HANDSHAKE_INTERVAL: NLA_U16, 0 to disable | ||
* 0: NLA_NESTED | ||
* ... | ||
* ... | ||
* | ||
* It is possible that the amount of configuration data exceeds that of | ||
* the maximum message length accepted by the kernel. In that case, several | ||
* messages should be sent one after another, with each successive one | ||
@@ -176,14 +179,16 @@ enum wgpeer_attribute { | ||
WGPEER_A_ENDPOINT, | ||
WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL, | ||
WGPEER_A_LAST_HANDSHAKE_TIME, | ||
WGPEER_A_RX_BYTES, | ||
WGPEER_A_TX_BYTES, | ||
WGPEER_A_ALLOWEDIPS, | ||
WGPEER_A_PROTOCOL_VERSION, | ||
+ WGPEER_A_FORCED_HANDSHAKE_INTERVAL, | ||
+ WGPEER_A_LAST_RECEIVE_TIME, | ||
__WGPEER_A_LAST | ||
}; | ||
#define WGPEER_A_MAX (__WGPEER_A_LAST - 1) | ||
|
||
enum wgallowedip_attribute { | ||
WGALLOWEDIP_A_UNSPEC, | ||
WGALLOWEDIP_A_FAMILY, |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.