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

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/prog_tests/tc_redirect.c
Extension
.c
Size
35981 bytes
Lines
1304
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 netns_setup_result {
	enum dev_mode dev_mode;
	int ifindex_src;
	int ifindex_src_fwd;
	int ifindex_dst;
	int ifindex_dst_fwd;
};

static int get_ifaddr(const char *name, char *ifaddr)
{
	char path[PATH_MAX];
	FILE *f;
	int ret;

	snprintf(path, PATH_MAX, "/sys/class/net/%s/address", name);
	f = fopen(path, "r");
	if (!ASSERT_OK_PTR(f, path))
		return -1;

	ret = fread(ifaddr, 1, IFADDR_STR_LEN, f);
	if (!ASSERT_EQ(ret, IFADDR_STR_LEN, "fread ifaddr")) {
		fclose(f);
		return -1;
	}
	fclose(f);
	return 0;
}

static int create_netkit(int mode, char *prim, char *peer)
{
	struct rtattr *linkinfo, *data, *peer_info;
	struct rtnl_handle rth = { .fd = -1 };
	const char *type = "netkit";
	struct {
		struct nlmsghdr n;
		struct ifinfomsg i;
		char buf[1024];
	} 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 ifinfomsg));
	req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
	req.n.nlmsg_type = RTM_NEWLINK;
	req.i.ifi_family = AF_UNSPEC;

	addattr_l(&req.n, sizeof(req), IFLA_IFNAME, prim, strlen(prim));
	linkinfo = addattr_nest(&req.n, sizeof(req), IFLA_LINKINFO);
	addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, type, strlen(type));
	data = addattr_nest(&req.n, sizeof(req), IFLA_INFO_DATA);
	addattr32(&req.n, sizeof(req), IFLA_NETKIT_MODE, mode);
	peer_info = addattr_nest(&req.n, sizeof(req), IFLA_NETKIT_PEER_INFO);
	req.n.nlmsg_len += sizeof(struct ifinfomsg);
	addattr_l(&req.n, sizeof(req), IFLA_IFNAME, peer, strlen(peer));
	addattr_nest_end(&req.n, peer_info);
	addattr_nest_end(&req.n, data);
	addattr_nest_end(&req.n, linkinfo);

	err = rtnl_talk(&rth, &req.n, NULL);
	ASSERT_OK(err, "talk_rtnetlink");
	rtnl_close(&rth);
	return err;
}

static int netns_setup_links_and_routes(struct netns_setup_result *result)
{
	struct nstoken *nstoken = NULL;
	char src_fwd_addr[IFADDR_STR_LEN+1] = {};
	char src_addr[IFADDR_STR_LEN + 1] = {};
	int err;

	if (result->dev_mode == MODE_VETH) {
		SYS(fail, "ip link add src address " MAC_SRC " type veth "
			  "peer name src_fwd address " MAC_SRC_FWD);
		SYS(fail, "ip link add dst address " MAC_DST " type veth "
			  "peer name dst_fwd address " MAC_DST_FWD);
	} else if (result->dev_mode == MODE_NETKIT) {
		err = create_netkit(NETKIT_L3, "src", "src_fwd");
		if (!ASSERT_OK(err, "create_ifindex_src"))
			goto fail;
		err = create_netkit(NETKIT_L3, "dst", "dst_fwd");
		if (!ASSERT_OK(err, "create_ifindex_dst"))
			goto fail;
	}

	if (get_ifaddr("src_fwd", src_fwd_addr))

Annotation

Implementation Notes