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

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/prog_tests/tc_opts.c
Extension
.c
Size
77786 bytes
Lines
2813
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 <net/if.h>
#include <test_progs.h>

#define loopback 1
#define ping_cmd "ping -q -c1 -w1 127.0.0.1 > /dev/null"

#include "test_tc_link.skel.h"
#include "tc_helpers.h"

void test_ns_tc_opts_basic(void)
{
	LIBBPF_OPTS(bpf_prog_attach_opts, opta);
	LIBBPF_OPTS(bpf_prog_detach_opts, optd);
	LIBBPF_OPTS(bpf_prog_query_opts, optq);
	__u32 fd1, fd2, id1, id2;
	struct test_tc_link *skel;
	__u32 prog_ids[2];
	int err;

	skel = test_tc_link__open_and_load();
	if (!ASSERT_OK_PTR(skel, "skel_load"))
		goto cleanup;

	fd1 = bpf_program__fd(skel->progs.tc1);
	fd2 = bpf_program__fd(skel->progs.tc2);

	id1 = id_from_prog_fd(fd1);
	id2 = id_from_prog_fd(fd2);

	ASSERT_NEQ(id1, id2, "prog_ids_1_2");

	assert_mprog_count(BPF_TCX_INGRESS, 0);
	assert_mprog_count(BPF_TCX_EGRESS, 0);

	ASSERT_EQ(skel->bss->seen_tc1, false, "seen_tc1");
	ASSERT_EQ(skel->bss->seen_tc2, false, "seen_tc2");

	err = bpf_prog_attach_opts(fd1, loopback, BPF_TCX_INGRESS, &opta);
	if (!ASSERT_EQ(err, 0, "prog_attach"))
		goto cleanup;

	assert_mprog_count(BPF_TCX_INGRESS, 1);
	assert_mprog_count(BPF_TCX_EGRESS, 0);

	optq.prog_ids = prog_ids;

	memset(prog_ids, 0, sizeof(prog_ids));
	optq.count = ARRAY_SIZE(prog_ids);

	err = bpf_prog_query_opts(loopback, BPF_TCX_INGRESS, &optq);
	if (!ASSERT_OK(err, "prog_query"))
		goto cleanup_in;

	ASSERT_EQ(optq.count, 1, "count");
	ASSERT_EQ(optq.revision, 2, "revision");
	ASSERT_EQ(optq.prog_ids[0], id1, "prog_ids[0]");
	ASSERT_EQ(optq.prog_ids[1], 0, "prog_ids[1]");

	tc_skel_reset_all_seen(skel);
	ASSERT_OK(system(ping_cmd), ping_cmd);

	ASSERT_EQ(skel->bss->seen_tc1, true, "seen_tc1");
	ASSERT_EQ(skel->bss->seen_tc2, false, "seen_tc2");

	err = bpf_prog_attach_opts(fd2, loopback, BPF_TCX_EGRESS, &opta);
	if (!ASSERT_EQ(err, 0, "prog_attach"))
		goto cleanup_in;

	assert_mprog_count(BPF_TCX_INGRESS, 1);
	assert_mprog_count(BPF_TCX_EGRESS, 1);

	memset(prog_ids, 0, sizeof(prog_ids));
	optq.count = ARRAY_SIZE(prog_ids);

	err = bpf_prog_query_opts(loopback, BPF_TCX_EGRESS, &optq);
	if (!ASSERT_OK(err, "prog_query"))
		goto cleanup_eg;

	ASSERT_EQ(optq.count, 1, "count");
	ASSERT_EQ(optq.revision, 2, "revision");
	ASSERT_EQ(optq.prog_ids[0], id2, "prog_ids[0]");
	ASSERT_EQ(optq.prog_ids[1], 0, "prog_ids[1]");

	tc_skel_reset_all_seen(skel);
	ASSERT_OK(system(ping_cmd), ping_cmd);

	ASSERT_EQ(skel->bss->seen_tc1, true, "seen_tc1");

Annotation

Implementation Notes