Commit adfeae2d authored by Daniel Borkmann's avatar Daniel Borkmann Committed by Martin KaFai Lau
Browse files

selftests/bpf: Add netkit to tc_redirect selftest



Extend the existing tc_redirect selftest to also cover netkit devices
for exercising the bpf_redirect_peer() code paths, so that we have both
veth as well as netkit covered, all tests still pass after this change.

Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Acked-by: default avatarStanislav Fomichev <sdf@google.com>
Reviewed-by: default avatarNikolay Aleksandrov <razor@blackwall.org>
Link: https://lore.kernel.org/r/20231114004220.6495-9-daniel@iogearbox.net


Signed-off-by: default avatarMartin KaFai Lau <martin.lau@kernel.org>
parent eee82da7
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@

#include "test_progs.h"
#include "network_helpers.h"
#include "netlink_helpers.h"
#include "test_tc_neigh_fib.skel.h"
#include "test_tc_neigh.skel.h"
#include "test_tc_peer.skel.h"
@@ -112,6 +113,7 @@ static void netns_setup_namespaces_nofail(const char *verb)

enum dev_mode {
	MODE_VETH,
	MODE_NETKIT,
};

struct netns_setup_result {
@@ -142,10 +144,51 @@ static int get_ifaddr(const char *name, char *ifaddr)
	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] = {};
	int err;

	if (result->dev_mode == MODE_VETH) {
		SYS(fail, "ip link add src type veth peer name src_fwd");
@@ -153,6 +196,13 @@ static int netns_setup_links_and_routes(struct netns_setup_result *result)

		SYS(fail, "ip link set dst_fwd address " MAC_DST_FWD);
		SYS(fail, "ip link set dst address " MAC_DST);
	} 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))
@@ -1134,7 +1184,9 @@ static void *test_tc_redirect_run_tests(void *arg)
	netns_setup_namespaces_nofail("delete");

	RUN_TEST(tc_redirect_peer, MODE_VETH);
	RUN_TEST(tc_redirect_peer, MODE_NETKIT);
	RUN_TEST(tc_redirect_peer_l3, MODE_VETH);
	RUN_TEST(tc_redirect_peer_l3, MODE_NETKIT);
	RUN_TEST(tc_redirect_neigh, MODE_VETH);
	RUN_TEST(tc_redirect_neigh_fib, MODE_VETH);
	RUN_TEST(tc_redirect_dtime, MODE_VETH);