tools/testing/selftests/net/tcp_ao/lib/kconfig.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/net/tcp_ao/lib/kconfig.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/net/tcp_ao/lib/kconfig.c
Extension
.c
Size
3597 bytes
Lines
158
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct kconfig_t {
	int _error;		/* negative errno if not supported */
	int (*check_kconfig)(int *error);
};

static int has_net_ns(int *err)
{
	if (access("/proc/self/ns/net", F_OK) < 0) {
		*err = errno;
		if (errno == ENOENT)
			return 0;
		test_print("Unable to access /proc/self/ns/net: %m");
		return -errno;
	}
	return *err = errno = 0;
}

static int has_veth(int *err)
{
	int orig_netns, ns_a, ns_b;

	orig_netns = open_netns();
	ns_a = unshare_open_netns();
	ns_b = unshare_open_netns();

	*err = add_veth("check_veth", ns_a, ns_b);

	switch_ns(orig_netns);
	close(orig_netns);
	close(ns_a);
	close(ns_b);
	return 0;
}

static int has_tcp_ao(int *err)
{
	struct sockaddr_in addr = {
		.sin_family = test_family,
	};
	struct tcp_ao_add tmp = {};
	const char *password = DEFAULT_TEST_PASSWORD;
	int sk, ret = 0;

	sk = socket(test_family, SOCK_STREAM, IPPROTO_TCP);
	if (sk < 0) {
		test_print("socket(): %m");
		return -errno;
	}

	tmp.sndid = 100;
	tmp.rcvid = 100;
	tmp.keylen = strlen(password);
	memcpy(tmp.key, password, strlen(password));
	strcpy(tmp.alg_name, "hmac(sha1)");
	memcpy(&tmp.addr, &addr, sizeof(addr));
	*err = 0;
	if (setsockopt(sk, IPPROTO_TCP, TCP_AO_ADD_KEY, &tmp, sizeof(tmp)) < 0) {
		*err = -errno;
		if (errno != ENOPROTOOPT)
			ret = -errno;
	}
	close(sk);
	return ret;
}

static int has_tcp_md5(int *err)
{
	union tcp_addr addr_any = {};
	int sk, ret = 0;

	sk = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (sk < 0) {
		test_print("socket(): %m");
		return -errno;
	}

	/*
	 * Under CONFIG_CRYPTO_FIPS=y it fails with ENOMEM, rather with
	 * anything more descriptive. Oh well.
	 */
	*err = 0;
	if (test_set_md5(sk, addr_any, 0, -1, DEFAULT_TEST_PASSWORD)) {
		*err = -errno;
		if (errno != ENOPROTOOPT && errno == ENOMEM) {
			test_print("setsockopt(TCP_MD5SIG_EXT): %m");
			ret = -errno;
		}
	}
	close(sk);
	return ret;

Annotation

Implementation Notes