tools/testing/selftests/bpf/prog_tests/sockopt.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/bpf/prog_tests/sockopt.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/prog_tests/sockopt.c
Extension
.c
Size
29634 bytes
Lines
1221
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

if (test->set_optlen >= PAGE_SIZE) {
			int num_pages = test->set_optlen / PAGE_SIZE;
			int remainder = test->set_optlen % PAGE_SIZE;

			test->set_optlen = num_pages * sysconf(_SC_PAGESIZE) + remainder;
		}

		err = call_setsockopt(use_io_uring, sock_fd, test->set_level,
				      test->set_optname, test->set_optval,
				      test->set_optlen);
		if (err) {
			if (errno == EPERM && test->error == EPERM_SETSOCKOPT)
				goto close_sock_fd;
			if (errno == EFAULT && test->error == EFAULT_SETSOCKOPT)
				goto free_optval;

			log_err("Failed to call setsockopt");
			ret = -1;
			goto close_sock_fd;
		}
	}

	if (test->get_optlen) {
		if (test->get_optlen >= PAGE_SIZE) {
			int num_pages = test->get_optlen / PAGE_SIZE;
			int remainder = test->get_optlen % PAGE_SIZE;

			test->get_optlen = num_pages * sysconf(_SC_PAGESIZE) + remainder;
		}

		optval = malloc(test->get_optlen);
		memset(optval, 0, test->get_optlen);
		socklen_t optlen = test->get_optlen;
		socklen_t expected_get_optlen = test->get_optlen_ret ?:
			test->get_optlen;

		err = call_getsockopt(use_io_uring, sock_fd, test->get_level,
				      test->get_optname, optval, &optlen);
		if (err) {
			if (errno == EOPNOTSUPP && test->error == EOPNOTSUPP_GETSOCKOPT)
				goto free_optval;
			if (errno == EPERM && test->error == EPERM_GETSOCKOPT)
				goto free_optval;
			if (errno == EFAULT && test->error == EFAULT_GETSOCKOPT)
				goto free_optval;

			log_err("Failed to call getsockopt");
			ret = -1;
			goto free_optval;
		}

		if (optlen != expected_get_optlen) {
			errno = 0;
			log_err("getsockopt returned unexpected optlen");
			ret = -1;
			goto free_optval;
		}

		if (memcmp(optval, test->get_optval, optlen) != 0) {
			errno = 0;
			log_err("getsockopt returned unexpected optval");
			ret = -1;
			goto free_optval;
		}
	}

	ret = test->error != OK;

free_optval:
	free(optval);
close_sock_fd:
	close(sock_fd);
detach_prog:
	if (use_link) {
		if (link_fd >= 0)
			close(link_fd);
	} else {
		bpf_prog_detach2(prog_fd, cgroup_fd, test->attach_type);
	}
close_prog_fd:
	close(prog_fd);
	return ret;
}

void test_sockopt(void)
{
	int cgroup_fd, i;

	cgroup_fd = test__join_cgroup("/sockopt");
	if (!ASSERT_GE(cgroup_fd, 0, "join_cgroup"))

Annotation

Implementation Notes