Commit e562d086 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'mptcp-refactor-token-container'



Paolo Abeni says:

====================
mptcp: refactor token container

Currently the msk sockets are stored in a single radix tree, protected by a
global spin_lock. This series moves to an hash table, allocated at boot time,
with per bucker spin_lock - alike inet_hashtables, but using a different key:
the token itself.

The above improves scalability, as write operations will have a far later chance
to compete for lock acquisition, allows lockless lookup, and will allow
easier msk traversing - e.g. for diag interface implementation's sake.

This also introduces trivial, related, kunit tests and move the existing in
kernel's one to kunit.

v1 -> v2:
 - fixed a few extra and sparse warns
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents be7aa9fa a8ee9c9b
Loading
Loading
Loading
Loading
+14 −6
Original line number Diff line number Diff line
@@ -18,12 +18,20 @@ config MPTCP_IPV6
	select IPV6
	default y

config MPTCP_HMAC_TEST
	bool "Tests for MPTCP HMAC implementation"
endif

config MPTCP_KUNIT_TESTS
	tristate "This builds the MPTCP KUnit tests" if !KUNIT_ALL_TESTS
	select MPTCP
	depends on KUNIT
	default KUNIT_ALL_TESTS
	help
	  This option enable boot time self-test for the HMAC implementation
	  used by the MPTCP code
	  Currently covers the MPTCP crypto and token helpers.
	  Only useful for kernel devs running KUnit test harness and are not
	  for inclusion into a production build.

	  Say N if you are unsure.
	  For more information on KUnit and unit tests in general please refer
	  to the KUnit documentation in Documentation/dev-tools/kunit/.

	  If unsure, say N.
endif
+4 −0
Original line number Diff line number Diff line
@@ -3,3 +3,7 @@ obj-$(CONFIG_MPTCP) += mptcp.o

mptcp-y := protocol.o subflow.o options.o token.o crypto.o ctrl.o pm.o diag.o \
	   mib.o pm_netlink.o

mptcp_crypto_test-objs := crypto_test.o
mptcp_token_test-objs := token_test.o
obj-$(CONFIG_MPTCP_KUNIT_TESTS) += mptcp_crypto_test.o mptcp_token_test.o
+2 −61
Original line number Diff line number Diff line
@@ -87,65 +87,6 @@ void mptcp_crypto_hmac_sha(u64 key1, u64 key2, u8 *msg, int len, void *hmac)
	sha256_final(&state, (u8 *)hmac);
}

#ifdef CONFIG_MPTCP_HMAC_TEST
struct test_cast {
	char *key;
	char *msg;
	char *result;
};

/* we can't reuse RFC 4231 test vectors, as we have constraint on the
 * input and key size.
 */
static struct test_cast tests[] = {
	{
		.key = "0b0b0b0b0b0b0b0b",
		.msg = "48692054",
		.result = "8385e24fb4235ac37556b6b886db106284a1da671699f46db1f235ec622dcafa",
	},
	{
		.key = "aaaaaaaaaaaaaaaa",
		.msg = "dddddddd",
		.result = "2c5e219164ff1dca1c4a92318d847bb6b9d44492984e1eb71aff9022f71046e9",
	},
	{
		.key = "0102030405060708",
		.msg = "cdcdcdcd",
		.result = "e73b9ba9969969cefb04aa0d6df18ec2fcc075b6f23b4d8c4da736a5dbbc6e7d",
	},
};

static int __init test_mptcp_crypto(void)
{
	char hmac[32], hmac_hex[65];
	u32 nonce1, nonce2;
	u64 key1, key2;
	u8 msg[8];
	int i, j;

	for (i = 0; i < ARRAY_SIZE(tests); ++i) {
		/* mptcp hmap will convert to be before computing the hmac */
		key1 = be64_to_cpu(*((__be64 *)&tests[i].key[0]));
		key2 = be64_to_cpu(*((__be64 *)&tests[i].key[8]));
		nonce1 = be32_to_cpu(*((__be32 *)&tests[i].msg[0]));
		nonce2 = be32_to_cpu(*((__be32 *)&tests[i].msg[4]));

		put_unaligned_be32(nonce1, &msg[0]);
		put_unaligned_be32(nonce2, &msg[4]);

		mptcp_crypto_hmac_sha(key1, key2, msg, 8, hmac);
		for (j = 0; j < 32; ++j)
			sprintf(&hmac_hex[j << 1], "%02x", hmac[j] & 0xff);
		hmac_hex[64] = 0;

		if (memcmp(hmac_hex, tests[i].result, 64))
			pr_err("test %d failed, got %s expected %s", i,
			       hmac_hex, tests[i].result);
		else
			pr_info("test %d [ ok ]", i);
	}
	return 0;
}

late_initcall(test_mptcp_crypto);
#if IS_MODULE(CONFIG_MPTCP_KUNIT_TESTS)
EXPORT_SYMBOL_GPL(mptcp_crypto_hmac_sha);
#endif
+72 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
#include <kunit/test.h>

#include "protocol.h"

struct test_case {
	char *key;
	char *msg;
	char *result;
};

/* we can't reuse RFC 4231 test vectors, as we have constraint on the
 * input and key size.
 */
static struct test_case tests[] = {
	{
		.key = "0b0b0b0b0b0b0b0b",
		.msg = "48692054",
		.result = "8385e24fb4235ac37556b6b886db106284a1da671699f46db1f235ec622dcafa",
	},
	{
		.key = "aaaaaaaaaaaaaaaa",
		.msg = "dddddddd",
		.result = "2c5e219164ff1dca1c4a92318d847bb6b9d44492984e1eb71aff9022f71046e9",
	},
	{
		.key = "0102030405060708",
		.msg = "cdcdcdcd",
		.result = "e73b9ba9969969cefb04aa0d6df18ec2fcc075b6f23b4d8c4da736a5dbbc6e7d",
	},
};

static void mptcp_crypto_test_basic(struct kunit *test)
{
	char hmac[32], hmac_hex[65];
	u32 nonce1, nonce2;
	u64 key1, key2;
	u8 msg[8];
	int i, j;

	for (i = 0; i < ARRAY_SIZE(tests); ++i) {
		/* mptcp hmap will convert to be before computing the hmac */
		key1 = be64_to_cpu(*((__be64 *)&tests[i].key[0]));
		key2 = be64_to_cpu(*((__be64 *)&tests[i].key[8]));
		nonce1 = be32_to_cpu(*((__be32 *)&tests[i].msg[0]));
		nonce2 = be32_to_cpu(*((__be32 *)&tests[i].msg[4]));

		put_unaligned_be32(nonce1, &msg[0]);
		put_unaligned_be32(nonce2, &msg[4]);

		mptcp_crypto_hmac_sha(key1, key2, msg, 8, hmac);
		for (j = 0; j < 32; ++j)
			sprintf(&hmac_hex[j << 1], "%02x", hmac[j] & 0xff);
		hmac_hex[64] = 0;

		KUNIT_EXPECT_STREQ(test, &hmac_hex[0], tests[i].result);
	}
}

static struct kunit_case mptcp_crypto_test_cases[] = {
	KUNIT_CASE(mptcp_crypto_test_basic),
	{}
};

static struct kunit_suite mptcp_crypto_suite = {
	.name = "mptcp-crypto",
	.test_cases = mptcp_crypto_test_cases,
};

kunit_test_suite(mptcp_crypto_suite);

MODULE_LICENSE("GPL");
+1 −1
Original line number Diff line number Diff line
@@ -234,7 +234,7 @@ void mptcp_pm_close(struct mptcp_sock *msk)
		sock_put((struct sock *)msk);
}

void mptcp_pm_init(void)
void __init mptcp_pm_init(void)
{
	pm_wq = alloc_workqueue("pm_wq", WQ_UNBOUND | WQ_MEM_RECLAIM, 8);
	if (!pm_wq)
Loading