File Index
Files and directories
Sign in
FILE

kconfig.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/net/tcp_ao/lib/kconfig.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/* Check what features does the kernel support (where the selftest is running).
  3 * Somewhat inspired by CRIU kerndat/kdat kernel features detector.
  4 */
  5#include <pthread.h>
  6#include "aolib.h"
  7
  8struct kconfig_t {
  9	int _error;		/* negative errno if not supported */
 10	int (*check_kconfig)(int *error);
 11};
 12
 13static int has_net_ns(int *err)
 14{
 15	if (access("/proc/self/ns/net", F_OK) < 0) {
 16		*err = errno;
 17		if (errno == ENOENT)
 18			return 0;
 19		test_print("Unable to access /proc/self/ns/net: %m");
 20		return -errno;
 21	}
 22	return *err = errno = 0;
 23}
 24
 25static int has_veth(int *err)
 26{
 27	int orig_netns, ns_a, ns_b;
 28
 29	orig_netns = open_netns();
 30	ns_a = unshare_open_netns();
 31	ns_b = unshare_open_netns();
 32
 33	*err = add_veth("check_veth", ns_a, ns_b);
 34
 35	switch_ns(orig_netns);
 36	close(orig_netns);
 37	close(ns_a);
 38	close(ns_b);
 39	return 0;
 40}
 41
 42static int has_tcp_ao(int *err)
 43{
 44	struct sockaddr_in addr = {
 45		.sin_family = test_family,
 46	};
 47	struct tcp_ao_add tmp = {};
 48	const char *password = DEFAULT_TEST_PASSWORD;
 49	int sk, ret = 0;
 50
 51	sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP);
 52	if (sk < 0) {
 53		test_print("socket(): %m");
 54		return -errno;
 55	}
 56
 57	tmp.sndid = 100;
 58	tmp.rcvid = 100;
 59	tmp.keylen = strlen(password);
 60	memcpy(tmp.key, password, strlen(password));
 61	strcpy(tmp.alg_name, "hmac(sha1)");
 62	memcpy(&tmp.addr, &addr, sizeof(addr));
 63	*err = 0;
 64	if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &tmp, sizeof(tmp)) < 0) {
 65		*err = -errno;
 66		if (errno != ENOPROTOOPT)
 67			ret = -errno;
 68	}
 69	close(sk);
 70	return ret;
 71}
 72
 73static int has_tcp_md5(int *err)
 74{
 75	union tcp_addr addr_any = {};
 76	int sk, ret = 0;
 77
 78	sk = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 79	if (sk < 0) {
 80		test_print("socket(): %m");
 81		return -errno;
 82	}
 83
 84	/*
 85	 * Under CONFIG_CRYPTO_FIPS=y it fails with ENOMEM, rather with
 86	 * anything more descriptive. Oh well.
 87	 */
 88	*err = 0;
 89	if (test_set_md5(sk, addr_any, 0, -1, DEFAULT_TEST_PASSWORD)) {
 90		*err = -errno;
 91		if (errno != ENOPROTOOPT && errno == ENOMEM) {
 92			test_print("setsockopt(TCP_MD5SIG_EXT): %m");
 93			ret = -errno;
 94		}
 95	}
 96	close(sk);
 97	return ret;
 98}
 99
100static int has_vrfs(int *err)
101{
102	int orig_netns, ns_test, ret = 0;
103
104	orig_netns = open_netns();
105	ns_test = unshare_open_netns();
106
107	*err = add_vrf("ksft-check", 55, 101, ns_test);
108	if (*err && *err != -EOPNOTSUPP) {
109		test_print("Failed to add a VRF: %d", *err);
110		ret = *err;
111	}
112
113	switch_ns(orig_netns);
114	close(orig_netns);
115	close(ns_test);
116	return ret;
117}
118
119static int has_ftrace(int *err)
120{
121	*err = test_setup_tracing();
122	return 0;
123}
124
125#define KCONFIG_UNKNOWN			1
126static pthread_mutex_t kconfig_lock = PTHREAD_MUTEX_INITIALIZER;
127static struct kconfig_t kconfig[__KCONFIG_LAST__] = {
128	{ KCONFIG_UNKNOWN, has_net_ns },
129	{ KCONFIG_UNKNOWN, has_veth },
130	{ KCONFIG_UNKNOWN, has_tcp_ao },
131	{ KCONFIG_UNKNOWN, has_tcp_md5 },
132	{ KCONFIG_UNKNOWN, has_vrfs },
133	{ KCONFIG_UNKNOWN, has_ftrace },
134};
135
136const char *tests_skip_reason[__KCONFIG_LAST__] = {
137	"Tests require network namespaces support (CONFIG_NET_NS)",
138	"Tests require veth support (CONFIG_VETH)",
139	"Tests require TCP-AO support (CONFIG_TCP_AO)",
140	"setsockopt(TCP_MD5SIG_EXT) is not supported (CONFIG_TCP_MD5)",
141	"VRFs are not supported (CONFIG_NET_VRF)",
142	"Ftrace points are not supported (CONFIG_TRACEPOINTS)",
143};
144
145bool kernel_config_has(enum test_needs_kconfig k)
146{
147	bool ret;
148
149	pthread_mutex_lock(&kconfig_lock);
150	if (kconfig[k]._error == KCONFIG_UNKNOWN) {
151		if (kconfig[k].check_kconfig(&kconfig[k]._error))
152			test_error("Failed to initialize kconfig %u", k);
153	}
154	ret = kconfig[k]._error == 0;
155	pthread_mutex_unlock(&kconfig_lock);
156	return ret;
157}
~/ Read-only file preview.