All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net 00/10] wireguard/siphash patches for 5.16-rc6
@ 2021-11-29 15:39 Jason A. Donenfeld
  2021-11-29 15:39 ` [PATCH net 01/10] wireguard: allowedips: add missing __rcu annotation to satisfy sparse Jason A. Donenfeld
                   ` (10 more replies)
  0 siblings, 11 replies; 14+ messages in thread
From: Jason A. Donenfeld @ 2021-11-29 15:39 UTC (permalink / raw)
  To: netdev, davem; +Cc: Jason A. Donenfeld

Hi Dave/Jakub,

Here's quite a largeish set of stable patches I've had queued up and
testing for a number of months now:

  - Patch (1) squelches a sparse warning by fixing an annotation.
  - Patches (2), (3), and (5) are minor improvements and fixes to the
    test suite.
  - Patch (4) is part of a tree-wide cleanup to have module-specific
    init and exit functions.
  - Patch (6) fixes a an issue with dangling dst references, by having a
    function to release references immediately rather than deferring,
    and adds an associated test case to prevent this from regressing.
  - Patches (7) and (8) help mitigate somewhat a potential DoS on the
    ingress path due to the use of skb_list's locking hitting contention
    on multiple cores by switching to using a ring buffer and dropping
    packets on contention rather than locking up another core spinning.
  - Patch (9) switches kvzalloc to kvcalloc for better form.
  - Patch (10) fixes alignment traps in siphash with clang-13 (and maybe
    other compilers) on armv6, by switching to using the unaligned
    functions by default instead of the aligned functions by default.

Thanks,
Jason

Arnd Bergmann (1):
  siphash: use _unaligned version by default

Gustavo A. R. Silva (1):
  wireguard: ratelimiter: use kvcalloc() instead of kvzalloc()

Jason A. Donenfeld (6):
  wireguard: allowedips: add missing __rcu annotation to satisfy sparse
  wireguard: selftests: increase default dmesg log size
  wireguard: selftests: actually test for routing loops
  wireguard: device: reset peer src endpoint when netns exits
  wireguard: receive: use ring buffer for incoming handshakes
  wireguard: receive: drop handshakes if queue lock is contended

Li Zhijian (1):
  wireguard: selftests: rename DEBUG_PI_LIST to DEBUG_PLIST

Randy Dunlap (1):
  wireguard: main: rename 'mod_init' & 'mod_exit' functions to be
    module-specific

 drivers/net/wireguard/allowedips.c            |  2 +-
 drivers/net/wireguard/device.c                | 39 ++++++++++---------
 drivers/net/wireguard/device.h                |  9 ++---
 drivers/net/wireguard/main.c                  |  8 ++--
 drivers/net/wireguard/queueing.c              |  6 +--
 drivers/net/wireguard/queueing.h              |  2 +-
 drivers/net/wireguard/ratelimiter.c           |  4 +-
 drivers/net/wireguard/receive.c               | 39 +++++++++++--------
 drivers/net/wireguard/socket.c                |  2 +-
 include/linux/siphash.h                       | 14 ++-----
 include/net/dst_cache.h                       | 11 ++++++
 lib/siphash.c                                 | 12 +++---
 net/core/dst_cache.c                          | 19 +++++++++
 tools/testing/selftests/wireguard/netns.sh    | 30 +++++++++++++-
 .../selftests/wireguard/qemu/debug.config     |  2 +-
 .../selftests/wireguard/qemu/kernel.config    |  1 +
 16 files changed, 129 insertions(+), 71 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH net 01/10] wireguard: allowedips: add missing __rcu annotation to satisfy sparse
  2021-11-29 15:39 [PATCH net 00/10] wireguard/siphash patches for 5.16-rc6 Jason A. Donenfeld
@ 2021-11-29 15:39 ` Jason A. Donenfeld
  2021-11-29 15:39 ` [PATCH net 02/10] wireguard: selftests: increase default dmesg log size Jason A. Donenfeld
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Jason A. Donenfeld @ 2021-11-29 15:39 UTC (permalink / raw)
  To: netdev, davem; +Cc: Jason A. Donenfeld, stable

A __rcu annotation got lost during refactoring, which caused sparse to
become enraged.

Fixes: bf7b042dc62a ("wireguard: allowedips: free empty intermediate nodes when removing single node")
Cc: stable@vger.kernel.org
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 drivers/net/wireguard/allowedips.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireguard/allowedips.c b/drivers/net/wireguard/allowedips.c
index b7197e80f226..9a4c8ff32d9d 100644
--- a/drivers/net/wireguard/allowedips.c
+++ b/drivers/net/wireguard/allowedips.c
@@ -163,7 +163,7 @@ static bool node_placement(struct allowedips_node __rcu *trie, const u8 *key,
 	return exact;
 }
 
-static inline void connect_node(struct allowedips_node **parent, u8 bit, struct allowedips_node *node)
+static inline void connect_node(struct allowedips_node __rcu **parent, u8 bit, struct allowedips_node *node)
 {
 	node->parent_bit_packed = (unsigned long)parent | bit;
 	rcu_assign_pointer(*parent, node);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net 02/10] wireguard: selftests: increase default dmesg log size
  2021-11-29 15:39 [PATCH net 00/10] wireguard/siphash patches for 5.16-rc6 Jason A. Donenfeld
  2021-11-29 15:39 ` [PATCH net 01/10] wireguard: allowedips: add missing __rcu annotation to satisfy sparse Jason A. Donenfeld
@ 2021-11-29 15:39 ` Jason A. Donenfeld
  2021-11-29 15:39 ` [PATCH net 03/10] wireguard: selftests: actually test for routing loops Jason A. Donenfeld
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Jason A. Donenfeld @ 2021-11-29 15:39 UTC (permalink / raw)
  To: netdev, davem; +Cc: Jason A. Donenfeld, stable

The selftests currently parse the kernel log at the end to track
potential memory leaks. With these tests now reading off the end of the
buffer, due to recent optimizations, some creation messages were lost,
making the tests think that there was a free without an alloc. Fix this
by increasing the kernel log size.

Fixes: 24b70eeeb4f4 ("wireguard: use synchronize_net rather than synchronize_rcu")
Cc: stable@vger.kernel.org
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 tools/testing/selftests/wireguard/qemu/kernel.config | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/testing/selftests/wireguard/qemu/kernel.config b/tools/testing/selftests/wireguard/qemu/kernel.config
index 74db83a0aedd..a9b5a520a1d2 100644
--- a/tools/testing/selftests/wireguard/qemu/kernel.config
+++ b/tools/testing/selftests/wireguard/qemu/kernel.config
@@ -66,6 +66,7 @@ CONFIG_PROC_SYSCTL=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 CONFIG_CONSOLE_LOGLEVEL_DEFAULT=15
+CONFIG_LOG_BUF_SHIFT=18
 CONFIG_PRINTK_TIME=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_LEGACY_VSYSCALL_NONE=y
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net 03/10] wireguard: selftests: actually test for routing loops
  2021-11-29 15:39 [PATCH net 00/10] wireguard/siphash patches for 5.16-rc6 Jason A. Donenfeld
  2021-11-29 15:39 ` [PATCH net 01/10] wireguard: allowedips: add missing __rcu annotation to satisfy sparse Jason A. Donenfeld
  2021-11-29 15:39 ` [PATCH net 02/10] wireguard: selftests: increase default dmesg log size Jason A. Donenfeld
@ 2021-11-29 15:39 ` Jason A. Donenfeld
  2021-11-29 15:39 ` [PATCH net 04/10] wireguard: main: rename 'mod_init' & 'mod_exit' functions to be module-specific Jason A. Donenfeld
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Jason A. Donenfeld @ 2021-11-29 15:39 UTC (permalink / raw)
  To: netdev, davem; +Cc: Jason A. Donenfeld

We previously removed the restriction on looping to self, and then added
a test to make sure the kernel didn't blow up during a routing loop. The
kernel didn't blow up, thankfully, but on certain architectures where
skb fragmentation is easier, such as ppc64, the skbs weren't actually
being discarded after a few rounds through. But the test wasn't catching
this. So actually test explicitly for massive increases in tx to see if
we have a routing loop. Note that the actual loop problem will need to
be addressed in a different commit.

Fixes: b673e24aad36 ("wireguard: socket: remove errant restriction on looping to self")
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 tools/testing/selftests/wireguard/netns.sh | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/wireguard/netns.sh b/tools/testing/selftests/wireguard/netns.sh
index ebc4ee0fe179..2e5c1630885e 100755
--- a/tools/testing/selftests/wireguard/netns.sh
+++ b/tools/testing/selftests/wireguard/netns.sh
@@ -276,7 +276,11 @@ n0 ping -W 1 -c 1 192.168.241.2
 n1 wg set wg0 peer "$pub2" endpoint 192.168.241.2:7
 ip2 link del wg0
 ip2 link del wg1
-! n0 ping -W 1 -c 10 -f 192.168.241.2 || false # Should not crash kernel
+read _ _ tx_bytes_before < <(n0 wg show wg1 transfer)
+! n0 ping -W 1 -c 10 -f 192.168.241.2 || false
+sleep 1
+read _ _ tx_bytes_after < <(n0 wg show wg1 transfer)
+(( tx_bytes_after - tx_bytes_before < 70000 ))
 
 ip0 link del wg1
 ip1 link del wg0
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net 04/10] wireguard: main: rename 'mod_init' & 'mod_exit' functions to be module-specific
  2021-11-29 15:39 [PATCH net 00/10] wireguard/siphash patches for 5.16-rc6 Jason A. Donenfeld
                   ` (2 preceding siblings ...)
  2021-11-29 15:39 ` [PATCH net 03/10] wireguard: selftests: actually test for routing loops Jason A. Donenfeld
@ 2021-11-29 15:39 ` Jason A. Donenfeld
  2021-11-29 15:39 ` [PATCH net 05/10] wireguard: selftests: rename DEBUG_PI_LIST to DEBUG_PLIST Jason A. Donenfeld
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Jason A. Donenfeld @ 2021-11-29 15:39 UTC (permalink / raw)
  To: netdev, davem; +Cc: Randy Dunlap, Jason A . Donenfeld

From: Randy Dunlap <rdunlap@infradead.org>

Rename module_init & module_exit functions that are named
"mod_init" and "mod_exit" so that they are unique in both the
System.map file and in initcall_debug output instead of showing
up as almost anonymous "mod_init".

This is helpful for debugging and in determining how long certain
module_init calls take to execute.

Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 drivers/net/wireguard/main.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireguard/main.c b/drivers/net/wireguard/main.c
index 75dbe77b0b4b..ee4da9ab8013 100644
--- a/drivers/net/wireguard/main.c
+++ b/drivers/net/wireguard/main.c
@@ -17,7 +17,7 @@
 #include <linux/genetlink.h>
 #include <net/rtnetlink.h>
 
-static int __init mod_init(void)
+static int __init wg_mod_init(void)
 {
 	int ret;
 
@@ -60,7 +60,7 @@ static int __init mod_init(void)
 	return ret;
 }
 
-static void __exit mod_exit(void)
+static void __exit wg_mod_exit(void)
 {
 	wg_genetlink_uninit();
 	wg_device_uninit();
@@ -68,8 +68,8 @@ static void __exit mod_exit(void)
 	wg_allowedips_slab_uninit();
 }
 
-module_init(mod_init);
-module_exit(mod_exit);
+module_init(wg_mod_init);
+module_exit(wg_mod_exit);
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("WireGuard secure network tunnel");
 MODULE_AUTHOR("Jason A. Donenfeld <Jason@zx2c4.com>");
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net 05/10] wireguard: selftests: rename DEBUG_PI_LIST to DEBUG_PLIST
  2021-11-29 15:39 [PATCH net 00/10] wireguard/siphash patches for 5.16-rc6 Jason A. Donenfeld
                   ` (3 preceding siblings ...)
  2021-11-29 15:39 ` [PATCH net 04/10] wireguard: main: rename 'mod_init' & 'mod_exit' functions to be module-specific Jason A. Donenfeld
@ 2021-11-29 15:39 ` Jason A. Donenfeld
  2021-11-29 15:39 ` [PATCH net 06/10] wireguard: device: reset peer src endpoint when netns exits Jason A. Donenfeld
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Jason A. Donenfeld @ 2021-11-29 15:39 UTC (permalink / raw)
  To: netdev, davem; +Cc: Li Zhijian, stable, Jason A . Donenfeld

From: Li Zhijian <lizhijian@cn.fujitsu.com>

DEBUG_PI_LIST was renamed to DEBUG_PLIST since 8e18faeac3 ("lib/plist:
rename DEBUG_PI_LIST to DEBUG_PLIST").

Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
Fixes: 8e18faeac3 ("lib/plist: rename DEBUG_PI_LIST to DEBUG_PLIST")
Cc: stable@vger.kernel.org
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 tools/testing/selftests/wireguard/qemu/debug.config | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/testing/selftests/wireguard/qemu/debug.config b/tools/testing/selftests/wireguard/qemu/debug.config
index fe07d97df9fa..2b321b8a96cf 100644
--- a/tools/testing/selftests/wireguard/qemu/debug.config
+++ b/tools/testing/selftests/wireguard/qemu/debug.config
@@ -47,7 +47,7 @@ CONFIG_DEBUG_ATOMIC_SLEEP=y
 CONFIG_TRACE_IRQFLAGS=y
 CONFIG_DEBUG_BUGVERBOSE=y
 CONFIG_DEBUG_LIST=y
-CONFIG_DEBUG_PI_LIST=y
+CONFIG_DEBUG_PLIST=y
 CONFIG_PROVE_RCU=y
 CONFIG_SPARSE_RCU_POINTER=y
 CONFIG_RCU_CPU_STALL_TIMEOUT=21
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net 06/10] wireguard: device: reset peer src endpoint when netns exits
  2021-11-29 15:39 [PATCH net 00/10] wireguard/siphash patches for 5.16-rc6 Jason A. Donenfeld
                   ` (4 preceding siblings ...)
  2021-11-29 15:39 ` [PATCH net 05/10] wireguard: selftests: rename DEBUG_PI_LIST to DEBUG_PLIST Jason A. Donenfeld
@ 2021-11-29 15:39 ` Jason A. Donenfeld
  2021-11-30 16:00   ` Toke Høiland-Jørgensen
  2021-11-29 15:39 ` [PATCH net 07/10] wireguard: receive: use ring buffer for incoming handshakes Jason A. Donenfeld
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 14+ messages in thread
From: Jason A. Donenfeld @ 2021-11-29 15:39 UTC (permalink / raw)
  To: netdev, davem
  Cc: Jason A. Donenfeld, Hangbin Liu, Xiumei Mu,
	Toke Høiland-Jørgensen, Paolo Abeni, stable

Each peer's endpoint contains a dst_cache entry that takes a reference
to another netdev. When the containing namespace exits, we take down the
socket and prevent future sockets from being created (by setting
creating_net to NULL), which removes that potential reference on the
netns. However, it doesn't release references to the netns that a netdev
cached in dst_cache might be taking, so the netns still might fail to
exit. Since the socket is gimped anyway, we can simply clear all the
dst_caches (by way of clearing the endpoint src), which will release all
references.

However, the current dst_cache_reset function only releases those
references lazily. But it turns out that all of our usages of
wg_socket_clear_peer_endpoint_src are called from contexts that are not
exactly high-speed or bottle-necked. For example, when there's
connection difficulty, or when userspace is reconfiguring the interface.
And in particular for this patch, when the netns is exiting. So for
those cases, it makes more sense to call dst_release immediately. For
that, we add a small helper function to dst_cache.

This patch also adds a test to netns.sh from Hangbin Liu to ensure this
doesn't regress.

Test-by: Hangbin Liu <liuhangbin@gmail.com>
Reported-by: Xiumei Mu <xmu@redhat.com>
Cc: Hangbin Liu <liuhangbin@gmail.com>
Cc: Toke Høiland-Jørgensen <toke@redhat.com>
Cc: Paolo Abeni <pabeni@redhat.com>
Fixes: 900575aa33a3 ("wireguard: device: avoid circular netns references")
Cc: stable@vger.kernel.org
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 drivers/net/wireguard/device.c             |  3 +++
 drivers/net/wireguard/socket.c             |  2 +-
 include/net/dst_cache.h                    | 11 ++++++++++
 net/core/dst_cache.c                       | 19 +++++++++++++++++
 tools/testing/selftests/wireguard/netns.sh | 24 +++++++++++++++++++++-
 5 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireguard/device.c b/drivers/net/wireguard/device.c
index 551ddaaaf540..77e64ea6be67 100644
--- a/drivers/net/wireguard/device.c
+++ b/drivers/net/wireguard/device.c
@@ -398,6 +398,7 @@ static struct rtnl_link_ops link_ops __read_mostly = {
 static void wg_netns_pre_exit(struct net *net)
 {
 	struct wg_device *wg;
+	struct wg_peer *peer;
 
 	rtnl_lock();
 	list_for_each_entry(wg, &device_list, device_list) {
@@ -407,6 +408,8 @@ static void wg_netns_pre_exit(struct net *net)
 			mutex_lock(&wg->device_update_lock);
 			rcu_assign_pointer(wg->creating_net, NULL);
 			wg_socket_reinit(wg, NULL, NULL);
+			list_for_each_entry(peer, &wg->peer_list, peer_list)
+				wg_socket_clear_peer_endpoint_src(peer);
 			mutex_unlock(&wg->device_update_lock);
 		}
 	}
diff --git a/drivers/net/wireguard/socket.c b/drivers/net/wireguard/socket.c
index 8c496b747108..6f07b949cb81 100644
--- a/drivers/net/wireguard/socket.c
+++ b/drivers/net/wireguard/socket.c
@@ -308,7 +308,7 @@ void wg_socket_clear_peer_endpoint_src(struct wg_peer *peer)
 {
 	write_lock_bh(&peer->endpoint_lock);
 	memset(&peer->endpoint.src6, 0, sizeof(peer->endpoint.src6));
-	dst_cache_reset(&peer->endpoint_cache);
+	dst_cache_reset_now(&peer->endpoint_cache);
 	write_unlock_bh(&peer->endpoint_lock);
 }
 
diff --git a/include/net/dst_cache.h b/include/net/dst_cache.h
index 67634675e919..df6622a5fe98 100644
--- a/include/net/dst_cache.h
+++ b/include/net/dst_cache.h
@@ -79,6 +79,17 @@ static inline void dst_cache_reset(struct dst_cache *dst_cache)
 	dst_cache->reset_ts = jiffies;
 }
 
+/**
+ *	dst_cache_reset_now - invalidate the cache contents immediately
+ *	@dst_cache: the cache
+ *
+ *	The caller must be sure there are no concurrent users, as this frees
+ *	all dst_cache users immediately, rather than waiting for the next
+ *	per-cpu usage like dst_cache_reset does. Most callers should use the
+ *	higher speed lazily-freed dst_cache_reset function instead.
+ */
+void dst_cache_reset_now(struct dst_cache *dst_cache);
+
 /**
  *	dst_cache_init - initialize the cache, allocating the required storage
  *	@dst_cache: the cache
diff --git a/net/core/dst_cache.c b/net/core/dst_cache.c
index be74ab4551c2..0ccfd5fa5cb9 100644
--- a/net/core/dst_cache.c
+++ b/net/core/dst_cache.c
@@ -162,3 +162,22 @@ void dst_cache_destroy(struct dst_cache *dst_cache)
 	free_percpu(dst_cache->cache);
 }
 EXPORT_SYMBOL_GPL(dst_cache_destroy);
+
+void dst_cache_reset_now(struct dst_cache *dst_cache)
+{
+	int i;
+
+	if (!dst_cache->cache)
+		return;
+
+	dst_cache->reset_ts = jiffies;
+	for_each_possible_cpu(i) {
+		struct dst_cache_pcpu *idst = per_cpu_ptr(dst_cache->cache, i);
+		struct dst_entry *dst = idst->dst;
+
+		idst->cookie = 0;
+		idst->dst = NULL;
+		dst_release(dst);
+	}
+}
+EXPORT_SYMBOL_GPL(dst_cache_reset_now);
diff --git a/tools/testing/selftests/wireguard/netns.sh b/tools/testing/selftests/wireguard/netns.sh
index 2e5c1630885e..8a9461aa0878 100755
--- a/tools/testing/selftests/wireguard/netns.sh
+++ b/tools/testing/selftests/wireguard/netns.sh
@@ -613,6 +613,28 @@ ip0 link set wg0 up
 kill $ncat_pid
 ip0 link del wg0
 
+# Ensure that dst_cache references don't outlive netns lifetime
+ip1 link add dev wg0 type wireguard
+ip2 link add dev wg0 type wireguard
+configure_peers
+ip1 link add veth1 type veth peer name veth2
+ip1 link set veth2 netns $netns2
+ip1 addr add fd00:aa::1/64 dev veth1
+ip2 addr add fd00:aa::2/64 dev veth2
+ip1 link set veth1 up
+ip2 link set veth2 up
+waitiface $netns1 veth1
+waitiface $netns2 veth2
+ip1 -6 route add default dev veth1 via fd00:aa::2
+ip2 -6 route add default dev veth2 via fd00:aa::1
+n1 wg set wg0 peer "$pub2" endpoint [fd00:aa::2]:2
+n2 wg set wg0 peer "$pub1" endpoint [fd00:aa::1]:1
+n1 ping6 -c 1 fd00::2
+pp ip netns delete $netns1
+pp ip netns delete $netns2
+pp ip netns add $netns1
+pp ip netns add $netns2
+
 # Ensure there aren't circular reference loops
 ip1 link add wg1 type wireguard
 ip2 link add wg2 type wireguard
@@ -631,7 +653,7 @@ while read -t 0.1 -r line 2>/dev/null || [[ $? -ne 142 ]]; do
 done < /dev/kmsg
 alldeleted=1
 for object in "${!objects[@]}"; do
-	if [[ ${objects["$object"]} != *createddestroyed ]]; then
+	if [[ ${objects["$object"]} != *createddestroyed && ${objects["$object"]} != *createdcreateddestroyeddestroyed ]]; then
 		echo "Error: $object: merely ${objects["$object"]}" >&3
 		alldeleted=0
 	fi
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net 07/10] wireguard: receive: use ring buffer for incoming handshakes
  2021-11-29 15:39 [PATCH net 00/10] wireguard/siphash patches for 5.16-rc6 Jason A. Donenfeld
                   ` (5 preceding siblings ...)
  2021-11-29 15:39 ` [PATCH net 06/10] wireguard: device: reset peer src endpoint when netns exits Jason A. Donenfeld
@ 2021-11-29 15:39 ` Jason A. Donenfeld
  2021-11-29 15:39 ` [PATCH net 08/10] wireguard: receive: drop handshakes if queue lock is contended Jason A. Donenfeld
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Jason A. Donenfeld @ 2021-11-29 15:39 UTC (permalink / raw)
  To: netdev, davem; +Cc: Jason A. Donenfeld, Streun Fabio, Joel Wanner, stable

Apparently the spinlock on incoming_handshake's skb_queue is highly
contended, and a torrent of handshake or cookie packets can bring the
data plane to its knees, simply by virtue of enqueueing the handshake
packets to be processed asynchronously. So, we try switching this to a
ring buffer to hopefully have less lock contention. This alleviates the
problem somewhat, though it still isn't perfect, so future patches will
have to improve this further. However, it at least doesn't completely
diminish the data plane.

Reported-by: Streun Fabio <fstreun@student.ethz.ch>
Reported-by: Joel Wanner <joel.wanner@inf.ethz.ch>
Cc: stable@vger.kernel.org
Fixes: e7096c131e51 ("net: WireGuard secure network tunnel")
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 drivers/net/wireguard/device.c   | 36 ++++++++++++++++----------------
 drivers/net/wireguard/device.h   |  9 +++-----
 drivers/net/wireguard/queueing.c |  6 +++---
 drivers/net/wireguard/queueing.h |  2 +-
 drivers/net/wireguard/receive.c  | 27 +++++++++++-------------
 5 files changed, 37 insertions(+), 43 deletions(-)

diff --git a/drivers/net/wireguard/device.c b/drivers/net/wireguard/device.c
index 77e64ea6be67..a46067c38bf5 100644
--- a/drivers/net/wireguard/device.c
+++ b/drivers/net/wireguard/device.c
@@ -98,6 +98,7 @@ static int wg_stop(struct net_device *dev)
 {
 	struct wg_device *wg = netdev_priv(dev);
 	struct wg_peer *peer;
+	struct sk_buff *skb;
 
 	mutex_lock(&wg->device_update_lock);
 	list_for_each_entry(peer, &wg->peer_list, peer_list) {
@@ -108,7 +109,9 @@ static int wg_stop(struct net_device *dev)
 		wg_noise_reset_last_sent_handshake(&peer->last_sent_handshake);
 	}
 	mutex_unlock(&wg->device_update_lock);
-	skb_queue_purge(&wg->incoming_handshakes);
+	while ((skb = ptr_ring_consume(&wg->handshake_queue.ring)) != NULL)
+		kfree_skb(skb);
+	atomic_set(&wg->handshake_queue_len, 0);
 	wg_socket_reinit(wg, NULL, NULL);
 	return 0;
 }
@@ -235,14 +238,13 @@ static void wg_destruct(struct net_device *dev)
 	destroy_workqueue(wg->handshake_receive_wq);
 	destroy_workqueue(wg->handshake_send_wq);
 	destroy_workqueue(wg->packet_crypt_wq);
-	wg_packet_queue_free(&wg->decrypt_queue);
-	wg_packet_queue_free(&wg->encrypt_queue);
+	wg_packet_queue_free(&wg->handshake_queue, true);
+	wg_packet_queue_free(&wg->decrypt_queue, false);
+	wg_packet_queue_free(&wg->encrypt_queue, false);
 	rcu_barrier(); /* Wait for all the peers to be actually freed. */
 	wg_ratelimiter_uninit();
 	memzero_explicit(&wg->static_identity, sizeof(wg->static_identity));
-	skb_queue_purge(&wg->incoming_handshakes);
 	free_percpu(dev->tstats);
-	free_percpu(wg->incoming_handshakes_worker);
 	kvfree(wg->index_hashtable);
 	kvfree(wg->peer_hashtable);
 	mutex_unlock(&wg->device_update_lock);
@@ -298,7 +300,6 @@ static int wg_newlink(struct net *src_net, struct net_device *dev,
 	init_rwsem(&wg->static_identity.lock);
 	mutex_init(&wg->socket_update_lock);
 	mutex_init(&wg->device_update_lock);
-	skb_queue_head_init(&wg->incoming_handshakes);
 	wg_allowedips_init(&wg->peer_allowedips);
 	wg_cookie_checker_init(&wg->cookie_checker, wg);
 	INIT_LIST_HEAD(&wg->peer_list);
@@ -316,16 +317,10 @@ static int wg_newlink(struct net *src_net, struct net_device *dev,
 	if (!dev->tstats)
 		goto err_free_index_hashtable;
 
-	wg->incoming_handshakes_worker =
-		wg_packet_percpu_multicore_worker_alloc(
-				wg_packet_handshake_receive_worker, wg);
-	if (!wg->incoming_handshakes_worker)
-		goto err_free_tstats;
-
 	wg->handshake_receive_wq = alloc_workqueue("wg-kex-%s",
 			WQ_CPU_INTENSIVE | WQ_FREEZABLE, 0, dev->name);
 	if (!wg->handshake_receive_wq)
-		goto err_free_incoming_handshakes;
+		goto err_free_tstats;
 
 	wg->handshake_send_wq = alloc_workqueue("wg-kex-%s",
 			WQ_UNBOUND | WQ_FREEZABLE, 0, dev->name);
@@ -347,10 +342,15 @@ static int wg_newlink(struct net *src_net, struct net_device *dev,
 	if (ret < 0)
 		goto err_free_encrypt_queue;
 
-	ret = wg_ratelimiter_init();
+	ret = wg_packet_queue_init(&wg->handshake_queue, wg_packet_handshake_receive_worker,
+				   MAX_QUEUED_INCOMING_HANDSHAKES);
 	if (ret < 0)
 		goto err_free_decrypt_queue;
 
+	ret = wg_ratelimiter_init();
+	if (ret < 0)
+		goto err_free_handshake_queue;
+
 	ret = register_netdevice(dev);
 	if (ret < 0)
 		goto err_uninit_ratelimiter;
@@ -367,18 +367,18 @@ static int wg_newlink(struct net *src_net, struct net_device *dev,
 
 err_uninit_ratelimiter:
 	wg_ratelimiter_uninit();
+err_free_handshake_queue:
+	wg_packet_queue_free(&wg->handshake_queue, false);
 err_free_decrypt_queue:
-	wg_packet_queue_free(&wg->decrypt_queue);
+	wg_packet_queue_free(&wg->decrypt_queue, false);
 err_free_encrypt_queue:
-	wg_packet_queue_free(&wg->encrypt_queue);
+	wg_packet_queue_free(&wg->encrypt_queue, false);
 err_destroy_packet_crypt:
 	destroy_workqueue(wg->packet_crypt_wq);
 err_destroy_handshake_send:
 	destroy_workqueue(wg->handshake_send_wq);
 err_destroy_handshake_receive:
 	destroy_workqueue(wg->handshake_receive_wq);
-err_free_incoming_handshakes:
-	free_percpu(wg->incoming_handshakes_worker);
 err_free_tstats:
 	free_percpu(dev->tstats);
 err_free_index_hashtable:
diff --git a/drivers/net/wireguard/device.h b/drivers/net/wireguard/device.h
index 854bc3d97150..43c7cebbf50b 100644
--- a/drivers/net/wireguard/device.h
+++ b/drivers/net/wireguard/device.h
@@ -39,21 +39,18 @@ struct prev_queue {
 
 struct wg_device {
 	struct net_device *dev;
-	struct crypt_queue encrypt_queue, decrypt_queue;
+	struct crypt_queue encrypt_queue, decrypt_queue, handshake_queue;
 	struct sock __rcu *sock4, *sock6;
 	struct net __rcu *creating_net;
 	struct noise_static_identity static_identity;
-	struct workqueue_struct *handshake_receive_wq, *handshake_send_wq;
-	struct workqueue_struct *packet_crypt_wq;
-	struct sk_buff_head incoming_handshakes;
-	int incoming_handshake_cpu;
-	struct multicore_worker __percpu *incoming_handshakes_worker;
+	struct workqueue_struct *packet_crypt_wq,*handshake_receive_wq, *handshake_send_wq;
 	struct cookie_checker cookie_checker;
 	struct pubkey_hashtable *peer_hashtable;
 	struct index_hashtable *index_hashtable;
 	struct allowedips peer_allowedips;
 	struct mutex device_update_lock, socket_update_lock;
 	struct list_head device_list, peer_list;
+	atomic_t handshake_queue_len;
 	unsigned int num_peers, device_update_gen;
 	u32 fwmark;
 	u16 incoming_port;
diff --git a/drivers/net/wireguard/queueing.c b/drivers/net/wireguard/queueing.c
index 48e7b982a307..1de413b19e34 100644
--- a/drivers/net/wireguard/queueing.c
+++ b/drivers/net/wireguard/queueing.c
@@ -38,11 +38,11 @@ int wg_packet_queue_init(struct crypt_queue *queue, work_func_t function,
 	return 0;
 }
 
-void wg_packet_queue_free(struct crypt_queue *queue)
+void wg_packet_queue_free(struct crypt_queue *queue, bool purge)
 {
 	free_percpu(queue->worker);
-	WARN_ON(!__ptr_ring_empty(&queue->ring));
-	ptr_ring_cleanup(&queue->ring, NULL);
+	WARN_ON(!purge && !__ptr_ring_empty(&queue->ring));
+	ptr_ring_cleanup(&queue->ring, purge ? (void(*)(void*))kfree_skb : NULL);
 }
 
 #define NEXT(skb) ((skb)->prev)
diff --git a/drivers/net/wireguard/queueing.h b/drivers/net/wireguard/queueing.h
index 4ef2944a68bc..e2388107f7fd 100644
--- a/drivers/net/wireguard/queueing.h
+++ b/drivers/net/wireguard/queueing.h
@@ -23,7 +23,7 @@ struct sk_buff;
 /* queueing.c APIs: */
 int wg_packet_queue_init(struct crypt_queue *queue, work_func_t function,
 			 unsigned int len);
-void wg_packet_queue_free(struct crypt_queue *queue);
+void wg_packet_queue_free(struct crypt_queue *queue, bool purge);
 struct multicore_worker __percpu *
 wg_packet_percpu_multicore_worker_alloc(work_func_t function, void *ptr);
 
diff --git a/drivers/net/wireguard/receive.c b/drivers/net/wireguard/receive.c
index 7dc84bcca261..f4e537e3e8ec 100644
--- a/drivers/net/wireguard/receive.c
+++ b/drivers/net/wireguard/receive.c
@@ -116,8 +116,8 @@ static void wg_receive_handshake_packet(struct wg_device *wg,
 		return;
 	}
 
-	under_load = skb_queue_len(&wg->incoming_handshakes) >=
-		     MAX_QUEUED_INCOMING_HANDSHAKES / 8;
+	under_load = atomic_read(&wg->handshake_queue_len) >=
+			MAX_QUEUED_INCOMING_HANDSHAKES / 8;
 	if (under_load) {
 		last_under_load = ktime_get_coarse_boottime_ns();
 	} else if (last_under_load) {
@@ -212,13 +212,14 @@ static void wg_receive_handshake_packet(struct wg_device *wg,
 
 void wg_packet_handshake_receive_worker(struct work_struct *work)
 {
-	struct wg_device *wg = container_of(work, struct multicore_worker,
-					    work)->ptr;
+	struct crypt_queue *queue = container_of(work, struct multicore_worker, work)->ptr;
+	struct wg_device *wg = container_of(queue, struct wg_device, handshake_queue);
 	struct sk_buff *skb;
 
-	while ((skb = skb_dequeue(&wg->incoming_handshakes)) != NULL) {
+	while ((skb = ptr_ring_consume_bh(&queue->ring)) != NULL) {
 		wg_receive_handshake_packet(wg, skb);
 		dev_kfree_skb(skb);
+		atomic_dec(&wg->handshake_queue_len);
 		cond_resched();
 	}
 }
@@ -554,21 +555,17 @@ void wg_packet_receive(struct wg_device *wg, struct sk_buff *skb)
 	case cpu_to_le32(MESSAGE_HANDSHAKE_RESPONSE):
 	case cpu_to_le32(MESSAGE_HANDSHAKE_COOKIE): {
 		int cpu;
-
-		if (skb_queue_len(&wg->incoming_handshakes) >
-			    MAX_QUEUED_INCOMING_HANDSHAKES ||
-		    unlikely(!rng_is_initialized())) {
+		if (unlikely(!rng_is_initialized() ||
+			     ptr_ring_produce_bh(&wg->handshake_queue.ring, skb))) {
 			net_dbg_skb_ratelimited("%s: Dropping handshake packet from %pISpfsc\n",
 						wg->dev->name, skb);
 			goto err;
 		}
-		skb_queue_tail(&wg->incoming_handshakes, skb);
-		/* Queues up a call to packet_process_queued_handshake_
-		 * packets(skb):
-		 */
-		cpu = wg_cpumask_next_online(&wg->incoming_handshake_cpu);
+		atomic_inc(&wg->handshake_queue_len);
+		cpu = wg_cpumask_next_online(&wg->handshake_queue.last_cpu);
+		/* Queues up a call to packet_process_queued_handshake_packets(skb): */
 		queue_work_on(cpu, wg->handshake_receive_wq,
-			&per_cpu_ptr(wg->incoming_handshakes_worker, cpu)->work);
+			      &per_cpu_ptr(wg->handshake_queue.worker, cpu)->work);
 		break;
 	}
 	case cpu_to_le32(MESSAGE_DATA):
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net 08/10] wireguard: receive: drop handshakes if queue lock is contended
  2021-11-29 15:39 [PATCH net 00/10] wireguard/siphash patches for 5.16-rc6 Jason A. Donenfeld
                   ` (6 preceding siblings ...)
  2021-11-29 15:39 ` [PATCH net 07/10] wireguard: receive: use ring buffer for incoming handshakes Jason A. Donenfeld
@ 2021-11-29 15:39 ` Jason A. Donenfeld
  2021-11-29 15:39 ` [PATCH net 09/10] wireguard: ratelimiter: use kvcalloc() instead of kvzalloc() Jason A. Donenfeld
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 14+ messages in thread
From: Jason A. Donenfeld @ 2021-11-29 15:39 UTC (permalink / raw)
  To: netdev, davem; +Cc: Jason A. Donenfeld, Streun Fabio, stable

If we're being delivered packets from multiple CPUs so quickly that the
ring lock is contended for CPU tries, then it's safe to assume that the
queue is near capacity anyway, so just drop the packet rather than
spinning. This helps deal with multicore DoS that can interfere with
data path performance. It _still_ does not completely fix the issue, but
it again chips away at it.

Reported-by: Streun Fabio <fstreun@student.ethz.ch>
Cc: stable@vger.kernel.org
Fixes: e7096c131e51 ("net: WireGuard secure network tunnel")
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 drivers/net/wireguard/receive.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireguard/receive.c b/drivers/net/wireguard/receive.c
index f4e537e3e8ec..7b8df406c773 100644
--- a/drivers/net/wireguard/receive.c
+++ b/drivers/net/wireguard/receive.c
@@ -554,9 +554,19 @@ void wg_packet_receive(struct wg_device *wg, struct sk_buff *skb)
 	case cpu_to_le32(MESSAGE_HANDSHAKE_INITIATION):
 	case cpu_to_le32(MESSAGE_HANDSHAKE_RESPONSE):
 	case cpu_to_le32(MESSAGE_HANDSHAKE_COOKIE): {
-		int cpu;
-		if (unlikely(!rng_is_initialized() ||
-			     ptr_ring_produce_bh(&wg->handshake_queue.ring, skb))) {
+		int cpu, ret = -EBUSY;
+
+		if (unlikely(!rng_is_initialized()))
+			goto drop;
+		if (atomic_read(&wg->handshake_queue_len) > MAX_QUEUED_INCOMING_HANDSHAKES / 2) {
+			if (spin_trylock_bh(&wg->handshake_queue.ring.producer_lock)) {
+				ret = __ptr_ring_produce(&wg->handshake_queue.ring, skb);
+				spin_unlock_bh(&wg->handshake_queue.ring.producer_lock);
+			}
+		} else
+			ret = ptr_ring_produce_bh(&wg->handshake_queue.ring, skb);
+		if (ret) {
+	drop:
 			net_dbg_skb_ratelimited("%s: Dropping handshake packet from %pISpfsc\n",
 						wg->dev->name, skb);
 			goto err;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net 09/10] wireguard: ratelimiter: use kvcalloc() instead of kvzalloc()
  2021-11-29 15:39 [PATCH net 00/10] wireguard/siphash patches for 5.16-rc6 Jason A. Donenfeld
                   ` (7 preceding siblings ...)
  2021-11-29 15:39 ` [PATCH net 08/10] wireguard: receive: drop handshakes if queue lock is contended Jason A. Donenfeld
@ 2021-11-29 15:39 ` Jason A. Donenfeld
  2021-11-29 15:39 ` [PATCH net 10/10] siphash: use _unaligned version by default Jason A. Donenfeld
  2021-11-29 18:17 ` [PATCH net 00/10] wireguard/siphash patches for 5.16-rc6 Jakub Kicinski
  10 siblings, 0 replies; 14+ messages in thread
From: Jason A. Donenfeld @ 2021-11-29 15:39 UTC (permalink / raw)
  To: netdev, davem; +Cc: Gustavo A. R. Silva, stable, Jason A . Donenfeld

From: "Gustavo A. R. Silva" <gustavoars@kernel.org>

Use 2-factor argument form kvcalloc() instead of kvzalloc().

Link: https://github.com/KSPP/linux/issues/162
Cc: stable@vger.kernel.org
Fixes: e7096c131e51 ("net: WireGuard secure network tunnel")
Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
[Jason: Gustavo's link above is for KSPP, but this isn't actually a
 security fix, as table_size is bounded to 8192 anyway, and gcc realizes
 this, so the codegen comes out to be about the same.]
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 drivers/net/wireguard/ratelimiter.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireguard/ratelimiter.c b/drivers/net/wireguard/ratelimiter.c
index 3fedd1d21f5e..dd55e5c26f46 100644
--- a/drivers/net/wireguard/ratelimiter.c
+++ b/drivers/net/wireguard/ratelimiter.c
@@ -176,12 +176,12 @@ int wg_ratelimiter_init(void)
 			(1U << 14) / sizeof(struct hlist_head)));
 	max_entries = table_size * 8;
 
-	table_v4 = kvzalloc(table_size * sizeof(*table_v4), GFP_KERNEL);
+	table_v4 = kvcalloc(table_size, sizeof(*table_v4), GFP_KERNEL);
 	if (unlikely(!table_v4))
 		goto err_kmemcache;
 
 #if IS_ENABLED(CONFIG_IPV6)
-	table_v6 = kvzalloc(table_size * sizeof(*table_v6), GFP_KERNEL);
+	table_v6 = kvcalloc(table_size, sizeof(*table_v6), GFP_KERNEL);
 	if (unlikely(!table_v6)) {
 		kvfree(table_v4);
 		goto err_kmemcache;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net 10/10] siphash: use _unaligned version by default
  2021-11-29 15:39 [PATCH net 00/10] wireguard/siphash patches for 5.16-rc6 Jason A. Donenfeld
                   ` (8 preceding siblings ...)
  2021-11-29 15:39 ` [PATCH net 09/10] wireguard: ratelimiter: use kvcalloc() instead of kvzalloc() Jason A. Donenfeld
@ 2021-11-29 15:39 ` Jason A. Donenfeld
  2021-11-29 18:17 ` [PATCH net 00/10] wireguard/siphash patches for 5.16-rc6 Jakub Kicinski
  10 siblings, 0 replies; 14+ messages in thread
From: Jason A. Donenfeld @ 2021-11-29 15:39 UTC (permalink / raw)
  To: netdev, davem
  Cc: Arnd Bergmann, Ard Biesheuvel, stable, Jason A . Donenfeld,
	Ard Biesheuvel

From: Arnd Bergmann <arnd@arndb.de>

On ARM v6 and later, we define CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
because the ordinary load/store instructions (ldr, ldrh, ldrb) can
tolerate any misalignment of the memory address. However, load/store
double and load/store multiple instructions (ldrd, ldm) may still only
be used on memory addresses that are 32-bit aligned, and so we have to
use the CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS macro with care, or we
may end up with a severe performance hit due to alignment traps that
require fixups by the kernel. Testing shows that this currently happens
with clang-13 but not gcc-11. In theory, any compiler version can
produce this bug or other problems, as we are dealing with undefined
behavior in C99 even on architectures that support this in hardware,
see also https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100363.

Fortunately, the get_unaligned() accessors do the right thing: when
building for ARMv6 or later, the compiler will emit unaligned accesses
using the ordinary load/store instructions (but avoid the ones that
require 32-bit alignment). When building for older ARM, those accessors
will emit the appropriate sequence of ldrb/mov/orr instructions. And on
architectures that can truly tolerate any kind of misalignment, the
get_unaligned() accessors resolve to the leXX_to_cpup accessors that
operate on aligned addresses.

Since the compiler will in fact emit ldrd or ldm instructions when
building this code for ARM v6 or later, the solution is to use the
unaligned accessors unconditionally on architectures where this is
known to be fast. The _aligned version of the hash function is
however still needed to get the best performance on architectures
that cannot do any unaligned access in hardware.

This new version avoids the undefined behavior and should produce
the fastest hash on all architectures we support.

Link: https://lore.kernel.org/linux-arm-kernel/20181008211554.5355-4-ard.biesheuvel@linaro.org/
Link: https://lore.kernel.org/linux-crypto/CAK8P3a2KfmmGDbVHULWevB0hv71P2oi2ZCHEAqT=8dQfa0=cqQ@mail.gmail.com/
Reported-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Fixes: 2c956a60778c ("siphash: add cryptographically secure PRF")
Cc: stable@vger.kernel.org
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 include/linux/siphash.h | 14 ++++----------
 lib/siphash.c           | 12 ++++++------
 2 files changed, 10 insertions(+), 16 deletions(-)

diff --git a/include/linux/siphash.h b/include/linux/siphash.h
index bf21591a9e5e..0cda61855d90 100644
--- a/include/linux/siphash.h
+++ b/include/linux/siphash.h
@@ -27,9 +27,7 @@ static inline bool siphash_key_is_zero(const siphash_key_t *key)
 }
 
 u64 __siphash_aligned(const void *data, size_t len, const siphash_key_t *key);
-#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
 u64 __siphash_unaligned(const void *data, size_t len, const siphash_key_t *key);
-#endif
 
 u64 siphash_1u64(const u64 a, const siphash_key_t *key);
 u64 siphash_2u64(const u64 a, const u64 b, const siphash_key_t *key);
@@ -82,10 +80,9 @@ static inline u64 ___siphash_aligned(const __le64 *data, size_t len,
 static inline u64 siphash(const void *data, size_t len,
 			  const siphash_key_t *key)
 {
-#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
-	if (!IS_ALIGNED((unsigned long)data, SIPHASH_ALIGNMENT))
+	if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) ||
+	    !IS_ALIGNED((unsigned long)data, SIPHASH_ALIGNMENT))
 		return __siphash_unaligned(data, len, key);
-#endif
 	return ___siphash_aligned(data, len, key);
 }
 
@@ -96,10 +93,8 @@ typedef struct {
 
 u32 __hsiphash_aligned(const void *data, size_t len,
 		       const hsiphash_key_t *key);
-#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
 u32 __hsiphash_unaligned(const void *data, size_t len,
 			 const hsiphash_key_t *key);
-#endif
 
 u32 hsiphash_1u32(const u32 a, const hsiphash_key_t *key);
 u32 hsiphash_2u32(const u32 a, const u32 b, const hsiphash_key_t *key);
@@ -135,10 +130,9 @@ static inline u32 ___hsiphash_aligned(const __le32 *data, size_t len,
 static inline u32 hsiphash(const void *data, size_t len,
 			   const hsiphash_key_t *key)
 {
-#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
-	if (!IS_ALIGNED((unsigned long)data, HSIPHASH_ALIGNMENT))
+	if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) ||
+	    !IS_ALIGNED((unsigned long)data, HSIPHASH_ALIGNMENT))
 		return __hsiphash_unaligned(data, len, key);
-#endif
 	return ___hsiphash_aligned(data, len, key);
 }
 
diff --git a/lib/siphash.c b/lib/siphash.c
index a90112ee72a1..72b9068ab57b 100644
--- a/lib/siphash.c
+++ b/lib/siphash.c
@@ -49,6 +49,7 @@
 	SIPROUND; \
 	return (v0 ^ v1) ^ (v2 ^ v3);
 
+#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
 u64 __siphash_aligned(const void *data, size_t len, const siphash_key_t *key)
 {
 	const u8 *end = data + len - (len % sizeof(u64));
@@ -80,8 +81,8 @@ u64 __siphash_aligned(const void *data, size_t len, const siphash_key_t *key)
 	POSTAMBLE
 }
 EXPORT_SYMBOL(__siphash_aligned);
+#endif
 
-#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
 u64 __siphash_unaligned(const void *data, size_t len, const siphash_key_t *key)
 {
 	const u8 *end = data + len - (len % sizeof(u64));
@@ -113,7 +114,6 @@ u64 __siphash_unaligned(const void *data, size_t len, const siphash_key_t *key)
 	POSTAMBLE
 }
 EXPORT_SYMBOL(__siphash_unaligned);
-#endif
 
 /**
  * siphash_1u64 - compute 64-bit siphash PRF value of a u64
@@ -250,6 +250,7 @@ EXPORT_SYMBOL(siphash_3u32);
 	HSIPROUND; \
 	return (v0 ^ v1) ^ (v2 ^ v3);
 
+#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
 u32 __hsiphash_aligned(const void *data, size_t len, const hsiphash_key_t *key)
 {
 	const u8 *end = data + len - (len % sizeof(u64));
@@ -280,8 +281,8 @@ u32 __hsiphash_aligned(const void *data, size_t len, const hsiphash_key_t *key)
 	HPOSTAMBLE
 }
 EXPORT_SYMBOL(__hsiphash_aligned);
+#endif
 
-#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
 u32 __hsiphash_unaligned(const void *data, size_t len,
 			 const hsiphash_key_t *key)
 {
@@ -313,7 +314,6 @@ u32 __hsiphash_unaligned(const void *data, size_t len,
 	HPOSTAMBLE
 }
 EXPORT_SYMBOL(__hsiphash_unaligned);
-#endif
 
 /**
  * hsiphash_1u32 - compute 64-bit hsiphash PRF value of a u32
@@ -418,6 +418,7 @@ EXPORT_SYMBOL(hsiphash_4u32);
 	HSIPROUND; \
 	return v1 ^ v3;
 
+#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
 u32 __hsiphash_aligned(const void *data, size_t len, const hsiphash_key_t *key)
 {
 	const u8 *end = data + len - (len % sizeof(u32));
@@ -438,8 +439,8 @@ u32 __hsiphash_aligned(const void *data, size_t len, const hsiphash_key_t *key)
 	HPOSTAMBLE
 }
 EXPORT_SYMBOL(__hsiphash_aligned);
+#endif
 
-#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
 u32 __hsiphash_unaligned(const void *data, size_t len,
 			 const hsiphash_key_t *key)
 {
@@ -461,7 +462,6 @@ u32 __hsiphash_unaligned(const void *data, size_t len,
 	HPOSTAMBLE
 }
 EXPORT_SYMBOL(__hsiphash_unaligned);
-#endif
 
 /**
  * hsiphash_1u32 - compute 32-bit hsiphash PRF value of a u32
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH net 00/10] wireguard/siphash patches for 5.16-rc6
  2021-11-29 15:39 [PATCH net 00/10] wireguard/siphash patches for 5.16-rc6 Jason A. Donenfeld
                   ` (9 preceding siblings ...)
  2021-11-29 15:39 ` [PATCH net 10/10] siphash: use _unaligned version by default Jason A. Donenfeld
@ 2021-11-29 18:17 ` Jakub Kicinski
  2021-11-29 18:18   ` Jason A. Donenfeld
  10 siblings, 1 reply; 14+ messages in thread
From: Jakub Kicinski @ 2021-11-29 18:17 UTC (permalink / raw)
  To: Jason A. Donenfeld; +Cc: netdev, davem

On Mon, 29 Nov 2021 10:39:19 -0500 Jason A. Donenfeld wrote:
> Here's quite a largeish set of stable patches I've had queued up and
> testing for a number of months now:
> 
>   - Patch (1) squelches a sparse warning by fixing an annotation.
>   - Patches (2), (3), and (5) are minor improvements and fixes to the
>     test suite.
>   - Patch (4) is part of a tree-wide cleanup to have module-specific
>     init and exit functions.
>   - Patch (6) fixes a an issue with dangling dst references, by having a
>     function to release references immediately rather than deferring,
>     and adds an associated test case to prevent this from regressing.
>   - Patches (7) and (8) help mitigate somewhat a potential DoS on the
>     ingress path due to the use of skb_list's locking hitting contention
>     on multiple cores by switching to using a ring buffer and dropping
>     packets on contention rather than locking up another core spinning.
>   - Patch (9) switches kvzalloc to kvcalloc for better form.
>   - Patch (10) fixes alignment traps in siphash with clang-13 (and maybe
>     other compilers) on armv6, by switching to using the unaligned
>     functions by default instead of the aligned functions by default.

Typo in the subject, right? No particular connection to -rc6 here?
Just checking.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH net 00/10] wireguard/siphash patches for 5.16-rc6
  2021-11-29 18:17 ` [PATCH net 00/10] wireguard/siphash patches for 5.16-rc6 Jakub Kicinski
@ 2021-11-29 18:18   ` Jason A. Donenfeld
  0 siblings, 0 replies; 14+ messages in thread
From: Jason A. Donenfeld @ 2021-11-29 18:18 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: Netdev, David Miller

On Mon, Nov 29, 2021 at 1:17 PM Jakub Kicinski <kuba@kernel.org> wrote:
>
> On Mon, 29 Nov 2021 10:39:19 -0500 Jason A. Donenfeld wrote:
> > Here's quite a largeish set of stable patches I've had queued up and
> > testing for a number of months now:
> >
> >   - Patch (1) squelches a sparse warning by fixing an annotation.
> >   - Patches (2), (3), and (5) are minor improvements and fixes to the
> >     test suite.
> >   - Patch (4) is part of a tree-wide cleanup to have module-specific
> >     init and exit functions.
> >   - Patch (6) fixes a an issue with dangling dst references, by having a
> >     function to release references immediately rather than deferring,
> >     and adds an associated test case to prevent this from regressing.
> >   - Patches (7) and (8) help mitigate somewhat a potential DoS on the
> >     ingress path due to the use of skb_list's locking hitting contention
> >     on multiple cores by switching to using a ring buffer and dropping
> >     packets on contention rather than locking up another core spinning.
> >   - Patch (9) switches kvzalloc to kvcalloc for better form.
> >   - Patch (10) fixes alignment traps in siphash with clang-13 (and maybe
> >     other compilers) on armv6, by switching to using the unaligned
> >     functions by default instead of the aligned functions by default.
>
> Typo in the subject, right? No particular connection to -rc6 here?
> Just checking.

I definitely meant to type 5.16-rc4, yes, sorry. Noticed this after it
was too late.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH net 06/10] wireguard: device: reset peer src endpoint when netns exits
  2021-11-29 15:39 ` [PATCH net 06/10] wireguard: device: reset peer src endpoint when netns exits Jason A. Donenfeld
@ 2021-11-30 16:00   ` Toke Høiland-Jørgensen
  0 siblings, 0 replies; 14+ messages in thread
From: Toke Høiland-Jørgensen @ 2021-11-30 16:00 UTC (permalink / raw)
  To: Jason A. Donenfeld, netdev, davem
  Cc: Jason A. Donenfeld, Hangbin Liu, Xiumei Mu, Paolo Abeni, stable

"Jason A. Donenfeld" <Jason@zx2c4.com> writes:

> Each peer's endpoint contains a dst_cache entry that takes a reference
> to another netdev. When the containing namespace exits, we take down the
> socket and prevent future sockets from being created (by setting
> creating_net to NULL), which removes that potential reference on the
> netns. However, it doesn't release references to the netns that a netdev
> cached in dst_cache might be taking, so the netns still might fail to
> exit. Since the socket is gimped anyway, we can simply clear all the
> dst_caches (by way of clearing the endpoint src), which will release all
> references.
>
> However, the current dst_cache_reset function only releases those
> references lazily. But it turns out that all of our usages of
> wg_socket_clear_peer_endpoint_src are called from contexts that are not
> exactly high-speed or bottle-necked. For example, when there's
> connection difficulty, or when userspace is reconfiguring the interface.
> And in particular for this patch, when the netns is exiting. So for
> those cases, it makes more sense to call dst_release immediately. For
> that, we add a small helper function to dst_cache.
>
> This patch also adds a test to netns.sh from Hangbin Liu to ensure this
> doesn't regress.
>
> Test-by: Hangbin Liu <liuhangbin@gmail.com>
> Reported-by: Xiumei Mu <xmu@redhat.com>
> Cc: Hangbin Liu <liuhangbin@gmail.com>
> Cc: Toke Høiland-Jørgensen <toke@redhat.com>
> Cc: Paolo Abeni <pabeni@redhat.com>
> Fixes: 900575aa33a3 ("wireguard: device: avoid circular netns references")
> Cc: stable@vger.kernel.org
> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>

Acked-by: Toke Høiland-Jørgensen <toke@redhat.com>


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2021-11-30 16:00 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-29 15:39 [PATCH net 00/10] wireguard/siphash patches for 5.16-rc6 Jason A. Donenfeld
2021-11-29 15:39 ` [PATCH net 01/10] wireguard: allowedips: add missing __rcu annotation to satisfy sparse Jason A. Donenfeld
2021-11-29 15:39 ` [PATCH net 02/10] wireguard: selftests: increase default dmesg log size Jason A. Donenfeld
2021-11-29 15:39 ` [PATCH net 03/10] wireguard: selftests: actually test for routing loops Jason A. Donenfeld
2021-11-29 15:39 ` [PATCH net 04/10] wireguard: main: rename 'mod_init' & 'mod_exit' functions to be module-specific Jason A. Donenfeld
2021-11-29 15:39 ` [PATCH net 05/10] wireguard: selftests: rename DEBUG_PI_LIST to DEBUG_PLIST Jason A. Donenfeld
2021-11-29 15:39 ` [PATCH net 06/10] wireguard: device: reset peer src endpoint when netns exits Jason A. Donenfeld
2021-11-30 16:00   ` Toke Høiland-Jørgensen
2021-11-29 15:39 ` [PATCH net 07/10] wireguard: receive: use ring buffer for incoming handshakes Jason A. Donenfeld
2021-11-29 15:39 ` [PATCH net 08/10] wireguard: receive: drop handshakes if queue lock is contended Jason A. Donenfeld
2021-11-29 15:39 ` [PATCH net 09/10] wireguard: ratelimiter: use kvcalloc() instead of kvzalloc() Jason A. Donenfeld
2021-11-29 15:39 ` [PATCH net 10/10] siphash: use _unaligned version by default Jason A. Donenfeld
2021-11-29 18:17 ` [PATCH net 00/10] wireguard/siphash patches for 5.16-rc6 Jakub Kicinski
2021-11-29 18:18   ` Jason A. Donenfeld

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.