tools/testing/selftests/bpf/progs/setget_sockopt.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/bpf/progs/setget_sockopt.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/progs/setget_sockopt.c
Extension
.c
Size
11466 bytes
Lines
458
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 sockopt_test {
	int opt;
	int new;
	int restore;
	int expected;
	int tcp_expected;
	unsigned int flip:1;
};

static const char not_exist_cc[] = "not_exist";
static const char cubic_cc[] = "cubic";
static const char reno_cc[] = "reno";

static const struct sockopt_test sol_socket_tests[] = {
	{ .opt = SO_REUSEADDR, .flip = 1, },
	{ .opt = SO_SNDBUF, .new = 8123, .expected = 8123 * 2, },
	{ .opt = SO_RCVBUF, .new = 8123, .expected = 8123 * 2, },
	{ .opt = SO_KEEPALIVE, .flip = 1, },
	{ .opt = SO_PRIORITY, .new = 0xeb9f, .expected = 0xeb9f, },
	{ .opt = SO_REUSEPORT, .flip = 1, },
	{ .opt = SO_RCVLOWAT, .new = 8123, .expected = 8123, },
	{ .opt = SO_MARK, .new = 0xeb9f, .expected = 0xeb9f, },
	{ .opt = SO_MAX_PACING_RATE, .new = 0xeb9f, .expected = 0xeb9f, },
	{ .opt = SO_TXREHASH, .flip = 1, },
	{ .opt = 0, },
};

static const struct sockopt_test sol_tcp_tests[] = {
	{ .opt = TCP_NODELAY, .flip = 1, },
	{ .opt = TCP_KEEPIDLE, .new = 123, .expected = 123, .restore = 321, },
	{ .opt = TCP_KEEPINTVL, .new = 123, .expected = 123, .restore = 321, },
	{ .opt = TCP_KEEPCNT, .new = 123, .expected = 123, .restore = 124, },
	{ .opt = TCP_SYNCNT, .new = 123, .expected = 123, .restore = 124, },
	{ .opt = TCP_WINDOW_CLAMP, .new = 8123, .expected = 8123, .restore = 8124, },
	{ .opt = TCP_CONGESTION, },
	{ .opt = TCP_THIN_LINEAR_TIMEOUTS, .flip = 1, },
	{ .opt = TCP_USER_TIMEOUT, .new = 123400, .expected = 123400, },
	{ .opt = TCP_NOTSENT_LOWAT, .new = 1314, .expected = 1314, },
	{ .opt = TCP_BPF_SOCK_OPS_CB_FLAGS, .new = BPF_SOCK_OPS_ALL_CB_FLAGS,
	  .expected = BPF_SOCK_OPS_ALL_CB_FLAGS, },
	{ .opt = TCP_BPF_DELACK_MAX, .new = 30000, .expected = 30000, },
	{ .opt = TCP_BPF_RTO_MIN, .new = 30000, .expected = 30000, },
	{ .opt = TCP_RTO_MAX_MS, .new = 2000, .expected = 2000, },
	{ .opt = 0, },
};

static const struct sockopt_test sol_ip_tests[] = {
	{ .opt = IP_TOS, .new = 0xe1, .expected = 0xe1, .tcp_expected = 0xe0, },
	{ .opt = 0, },
};

static const struct sockopt_test sol_ipv6_tests[] = {
	{ .opt = IPV6_TCLASS, .new = 0xe1, .expected = 0xe1, .tcp_expected = 0xe0, },
	{ .opt = IPV6_AUTOFLOWLABEL, .flip = 1, },
	{ .opt = 0, },
};

struct loop_ctx {
	void *ctx;
	struct sock *sk;
};

static bool sk_is_tcp(struct sock *sk)
{
	return (sk->__sk_common.skc_family == AF_INET ||
		sk->__sk_common.skc_family == AF_INET6) &&
		sk->sk_type == SOCK_STREAM &&
		sk->sk_protocol == IPPROTO_TCP;
}

static int bpf_test_sockopt_flip(void *ctx, struct sock *sk,
				 const struct sockopt_test *t,
				 int level)
{
	int old, tmp, new, opt = t->opt;

	opt = t->opt;

	if (opt == SO_TXREHASH && !sk_is_tcp(sk))
		return 0;

	if (bpf_getsockopt(ctx, level, opt, &old, sizeof(old)))
		return 1;
	/* kernel initialized txrehash to 255 */
	if (level == SOL_SOCKET && opt == SO_TXREHASH && old != 0 && old != 1)
		old = 1;

	new = !old;
	if (bpf_setsockopt(ctx, level, opt, &new, sizeof(new)))
		return 1;

Annotation

Implementation Notes