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

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

File Facts

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

// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2023 Isovalent */
#include <uapi/linux/if_link.h>
#include <test_progs.h>

#include <netinet/tcp.h>
#include <netinet/udp.h>

#include "network_helpers.h"
#include "test_assign_reuse.skel.h"

#define NS_TEST "assign_reuse"
#define LOOPBACK 1
#define PORT 4443

static int attach_reuseport(int sock_fd, int prog_fd)
{
	return setsockopt(sock_fd, SOL_SOCKET, SO_ATTACH_REUSEPORT_EBPF,
			  &prog_fd, sizeof(prog_fd));
}

static __u64 cookie(int fd)
{
	__u64 cookie = 0;
	socklen_t cookie_len = sizeof(cookie);
	int ret;

	ret = getsockopt(fd, SOL_SOCKET, SO_COOKIE, &cookie, &cookie_len);
	ASSERT_OK(ret, "cookie");
	ASSERT_GT(cookie, 0, "cookie_invalid");

	return cookie;
}

static int echo_test_udp(int fd_sv)
{
	struct sockaddr_storage addr = {};
	socklen_t len = sizeof(addr);
	char buff[1] = {};
	int fd_cl = -1, ret;

	fd_cl = connect_to_fd(fd_sv, 100);
	ASSERT_GT(fd_cl, 0, "create_client");
	ASSERT_EQ(getsockname(fd_cl, (void *)&addr, &len), 0, "getsockname");

	ASSERT_EQ(send(fd_cl, buff, sizeof(buff), 0), 1, "send_client");

	ret = recv(fd_sv, buff, sizeof(buff), 0);
	if (ret < 0) {
		close(fd_cl);
		return errno;
	}

	ASSERT_EQ(ret, 1, "recv_server");
	ASSERT_EQ(sendto(fd_sv, buff, sizeof(buff), 0, (void *)&addr, len), 1, "send_server");
	ASSERT_EQ(recv(fd_cl, buff, sizeof(buff), 0), 1, "recv_client");
	close(fd_cl);
	return 0;
}

static int echo_test_tcp(int fd_sv)
{
	char buff[1] = {};
	int fd_cl = -1, fd_sv_cl = -1;

	fd_cl = connect_to_fd(fd_sv, 100);
	if (fd_cl < 0)
		return errno;

	fd_sv_cl = accept(fd_sv, NULL, NULL);
	ASSERT_GE(fd_sv_cl, 0, "accept_fd");

	ASSERT_EQ(send(fd_cl, buff, sizeof(buff), 0), 1, "send_client");
	ASSERT_EQ(recv(fd_sv_cl, buff, sizeof(buff), 0), 1, "recv_server");
	ASSERT_EQ(send(fd_sv_cl, buff, sizeof(buff), 0), 1, "send_server");
	ASSERT_EQ(recv(fd_cl, buff, sizeof(buff), 0), 1, "recv_client");
	close(fd_sv_cl);
	close(fd_cl);
	return 0;
}

void run_assign_reuse(int family, int sotype, const char *ip, __u16 port)
{
	DECLARE_LIBBPF_OPTS(bpf_tc_hook, tc_hook,
		.ifindex = LOOPBACK,
		.attach_point = BPF_TC_INGRESS,
	);
	DECLARE_LIBBPF_OPTS(bpf_tc_opts, tc_opts,
		.handle = 1,
		.priority = 1,

Annotation

Implementation Notes