tools/testing/selftests/bpf/prog_tests/tc_links.c
Source file repositories/reference/linux-study-clean/tools/testing/selftests/bpf/prog_tests/tc_links.c
File Facts
- System
- Linux kernel
- Corpus path
tools/testing/selftests/bpf/prog_tests/tc_links.c- Extension
.c- Size
- 55785 bytes
- Lines
- 1963
- 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.
- Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
uapi/linux/if_link.huapi/linux/pkt_sched.hnet/if.htest_progs.htest_tc_link.skel.hnetlink_helpers.htc_helpers.h
Detected Declarations
struct qdisc_reqfunction test_ns_tc_links_basicfunction test_tc_links_before_targetfunction test_ns_tc_links_beforefunction test_tc_links_after_targetfunction test_ns_tc_links_afterfunction test_tc_links_revision_targetfunction test_ns_tc_links_revisionfunction test_tc_chain_classicfunction test_ns_tc_links_chain_classicfunction test_tc_links_replace_targetfunction test_ns_tc_links_replacefunction test_tc_links_invalid_targetfunction test_ns_tc_links_invalidfunction test_tc_links_prepend_targetfunction test_ns_tc_links_prependfunction test_tc_links_append_targetfunction test_ns_tc_links_appendfunction test_tc_links_dev_cleanup_targetfunction test_ns_tc_links_dev_cleanupfunction test_tc_chain_mixedfunction test_ns_tc_links_chain_mixedfunction test_tc_links_ingressfunction test_ns_tc_links_ingressfunction qdisc_replacefunction test_ns_tc_links_dev_chain0function test_tc_links_dev_mixedfunction test_ns_tc_links_dev_mixed
Annotated Snippet
struct qdisc_req {
struct nlmsghdr n;
struct tcmsg t;
char buf[1024];
};
static int qdisc_replace(int ifindex, const char *kind, bool block)
{
struct rtnl_handle rth = { .fd = -1 };
struct qdisc_req req;
int err;
err = rtnl_open(&rth, 0);
if (!ASSERT_OK(err, "open_rtnetlink"))
return err;
memset(&req, 0, sizeof(req));
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg));
req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REPLACE | NLM_F_REQUEST;
req.n.nlmsg_type = RTM_NEWQDISC;
req.t.tcm_family = AF_UNSPEC;
req.t.tcm_ifindex = ifindex;
req.t.tcm_parent = 0xfffffff1;
addattr_l(&req.n, sizeof(req), TCA_KIND, kind, strlen(kind) + 1);
if (block)
addattr32(&req.n, sizeof(req), TCA_INGRESS_BLOCK, 1);
err = rtnl_talk(&rth, &req.n, NULL);
ASSERT_OK(err, "talk_rtnetlink");
rtnl_close(&rth);
return err;
}
void test_ns_tc_links_dev_chain0(void)
{
int err, ifindex;
ASSERT_OK(system("ip link add dev foo type veth peer name bar"), "add veth");
ifindex = if_nametoindex("foo");
ASSERT_NEQ(ifindex, 0, "non_zero_ifindex");
err = qdisc_replace(ifindex, "ingress", true);
if (!ASSERT_OK(err, "attaching ingress"))
goto cleanup;
ASSERT_OK(system("tc filter add block 1 matchall action skbmod swap mac"), "add block");
err = qdisc_replace(ifindex, "clsact", false);
if (!ASSERT_OK(err, "attaching clsact"))
goto cleanup;
/* Heuristic: kern_sync_rcu() alone does not work; a wait-time of ~5s
* triggered the issue without the fix reliably 100% of the time.
*/
sleep(5);
ASSERT_OK(system("tc filter add dev foo ingress matchall action skbmod swap mac"), "add filter");
cleanup:
ASSERT_OK(system("ip link del dev foo"), "del veth");
ASSERT_EQ(if_nametoindex("foo"), 0, "foo removed");
ASSERT_EQ(if_nametoindex("bar"), 0, "bar removed");
}
static void test_tc_links_dev_mixed(int target)
{
LIBBPF_OPTS(bpf_tc_opts, tc_opts, .handle = 1, .priority = 1);
LIBBPF_OPTS(bpf_tc_hook, tc_hook);
LIBBPF_OPTS(bpf_tcx_opts, optl);
__u32 pid1, pid2, pid3, pid4;
struct test_tc_link *skel;
struct bpf_link *link;
int err, ifindex;
ASSERT_OK(system("ip link add dev tcx_opts1 type veth peer name tcx_opts2"), "add veth");
ifindex = if_nametoindex("tcx_opts1");
ASSERT_NEQ(ifindex, 0, "non_zero_ifindex");
skel = test_tc_link__open();
if (!ASSERT_OK_PTR(skel, "skel_open"))
goto cleanup;
ASSERT_EQ(bpf_program__set_expected_attach_type(skel->progs.tc1, target),
0, "tc1_attach_type");
ASSERT_EQ(bpf_program__set_expected_attach_type(skel->progs.tc2, target),
0, "tc2_attach_type");
ASSERT_EQ(bpf_program__set_expected_attach_type(skel->progs.tc3, target),
0, "tc3_attach_type");
ASSERT_EQ(bpf_program__set_expected_attach_type(skel->progs.tc4, target),
0, "tc4_attach_type");
err = test_tc_link__load(skel);
if (!ASSERT_OK(err, "skel_load"))
goto cleanup;
Annotation
- Immediate include surface: `uapi/linux/if_link.h`, `uapi/linux/pkt_sched.h`, `net/if.h`, `test_progs.h`, `test_tc_link.skel.h`, `netlink_helpers.h`, `tc_helpers.h`.
- Detected declarations: `struct qdisc_req`, `function test_ns_tc_links_basic`, `function test_tc_links_before_target`, `function test_ns_tc_links_before`, `function test_tc_links_after_target`, `function test_ns_tc_links_after`, `function test_tc_links_revision_target`, `function test_ns_tc_links_revision`, `function test_tc_chain_classic`, `function test_ns_tc_links_chain_classic`.
- Atlas domain: Support Tooling And Documentation / tools.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.