Commit b109398a authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'bonding-fix'

Jussi Maki says:

====================
bonding: Fix negative jump count reported by syzbot

This patch set fixes a negative jump count warning encountered by
syzbot [1] and extends the tests to cover nested bonding devices.

[1]: https://lore.kernel.org/lkml/0000000000000a9f3605cb1d2455@google.com/


====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents e0b6417b 4a9c93dc
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -2169,7 +2169,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
			res = -EOPNOTSUPP;
			goto err_sysfs_del;
		}
	} else {
	} else if (bond->xdp_prog) {
		struct netdev_bpf xdp = {
			.command = XDP_SETUP_PROG,
			.flags   = 0,
@@ -5224,13 +5224,12 @@ static int bond_xdp_set(struct net_device *dev, struct bpf_prog *prog,
			bpf_prog_inc(prog);
	}

	if (old_prog)
		bpf_prog_put(old_prog);

	if (prog)
	if (prog) {
		static_branch_inc(&bpf_master_redirect_enabled_key);
	else
	} else if (old_prog) {
		bpf_prog_put(old_prog);
		static_branch_dec(&bpf_master_redirect_enabled_key);
	}

	return 0;

+64 −10
Original line number Diff line number Diff line
@@ -384,8 +384,7 @@ static void test_xdp_bonding_attach(struct skeletons *skeletons)
{
	struct bpf_link *link = NULL;
	struct bpf_link *link2 = NULL;
	int veth, bond;
	int err;
	int veth, bond, err;

	if (!ASSERT_OK(system("ip link add veth type veth"), "add veth"))
		goto out;
@@ -399,22 +398,18 @@ static void test_xdp_bonding_attach(struct skeletons *skeletons)
	if (!ASSERT_GE(bond, 0, "if_nametoindex bond"))
		goto out;

	/* enslaving with a XDP program loaded fails */
	/* enslaving with a XDP program loaded is allowed */
	link = bpf_program__attach_xdp(skeletons->xdp_dummy->progs.xdp_dummy_prog, veth);
	if (!ASSERT_OK_PTR(link, "attach program to veth"))
		goto out;

	err = system("ip link set veth master bond");
	if (!ASSERT_NEQ(err, 0, "attaching slave with xdp program expected to fail"))
	if (!ASSERT_OK(err, "set veth master"))
		goto out;

	bpf_link__destroy(link);
	link = NULL;

	err = system("ip link set veth master bond");
	if (!ASSERT_OK(err, "set veth master"))
		goto out;

	/* attaching to slave when master has no program is allowed */
	link = bpf_program__attach_xdp(skeletons->xdp_dummy->progs.xdp_dummy_prog, veth);
	if (!ASSERT_OK_PTR(link, "attach program to slave when enslaved"))
@@ -434,8 +429,26 @@ static void test_xdp_bonding_attach(struct skeletons *skeletons)
		goto out;

	/* attaching to slave not allowed when master has program loaded */
	link2 = bpf_program__attach_xdp(skeletons->xdp_dummy->progs.xdp_dummy_prog, bond);
	ASSERT_ERR_PTR(link2, "attach program to slave when master has program");
	link2 = bpf_program__attach_xdp(skeletons->xdp_dummy->progs.xdp_dummy_prog, veth);
	if (!ASSERT_ERR_PTR(link2, "attach program to slave when master has program"))
		goto out;

	bpf_link__destroy(link);
	link = NULL;

	/* test program unwinding with a non-XDP slave */
	if (!ASSERT_OK(system("ip link add vxlan type vxlan id 1 remote 1.2.3.4 dstport 0 dev lo"),
		       "add vxlan"))
		goto out;

	err = system("ip link set vxlan master bond");
	if (!ASSERT_OK(err, "set vxlan master"))
		goto out;

	/* attaching not allowed when one slave does not support XDP */
	link = bpf_program__attach_xdp(skeletons->xdp_dummy->progs.xdp_dummy_prog, bond);
	if (!ASSERT_ERR_PTR(link, "attach program to master when slave does not support XDP"))
		goto out;

out:
	bpf_link__destroy(link);
@@ -443,6 +456,44 @@ static void test_xdp_bonding_attach(struct skeletons *skeletons)

	system("ip link del veth");
	system("ip link del bond");
	system("ip link del vxlan");
}

/* Test with nested bonding devices to catch issue with negative jump label count */
static void test_xdp_bonding_nested(struct skeletons *skeletons)
{
	struct bpf_link *link = NULL;
	int bond, err;

	if (!ASSERT_OK(system("ip link add bond type bond"), "add bond"))
		goto out;

	bond = if_nametoindex("bond");
	if (!ASSERT_GE(bond, 0, "if_nametoindex bond"))
		goto out;

	if (!ASSERT_OK(system("ip link add bond_nest1 type bond"), "add bond_nest1"))
		goto out;

	err = system("ip link set bond_nest1 master bond");
	if (!ASSERT_OK(err, "set bond_nest1 master"))
		goto out;

	if (!ASSERT_OK(system("ip link add bond_nest2 type bond"), "add bond_nest1"))
		goto out;

	err = system("ip link set bond_nest2 master bond_nest1");
	if (!ASSERT_OK(err, "set bond_nest2 master"))
		goto out;

	link = bpf_program__attach_xdp(skeletons->xdp_dummy->progs.xdp_dummy_prog, bond);
	ASSERT_OK_PTR(link, "attach program to master");

out:
	bpf_link__destroy(link);
	system("ip link del bond");
	system("ip link del bond_nest1");
	system("ip link del bond_nest2");
}

static int libbpf_debug_print(enum libbpf_print_level level,
@@ -496,6 +547,9 @@ void test_xdp_bonding(void)
	if (test__start_subtest("xdp_bonding_attach"))
		test_xdp_bonding_attach(&skeletons);

	if (test__start_subtest("xdp_bonding_nested"))
		test_xdp_bonding_nested(&skeletons);

	for (i = 0; i < ARRAY_SIZE(bond_test_cases); i++) {
		struct bond_test_case *test_case = &bond_test_cases[i];