Commit 6cda0e2c authored by Amery Hung's avatar Amery Hung Committed by Martin KaFai Lau
Browse files

selftests/bpf: Test attaching a bpf qdisc with incomplete operators



Implement .destroy in bpf_fq and bpf_fifo as it is now mandatory.

Test attaching a bpf qdisc with a missing operator .init. This is not
allowed as bpf qdisc qdisc_watchdog_cancel() could have been called with
an uninitialized timer.

Signed-off-by: default avatarAmery Hung <ameryhung@gmail.com>
Signed-off-by: default avatarMartin KaFai Lau <martin.lau@kernel.org>
parent 64d6e3b9
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
#include "network_helpers.h"
#include "bpf_qdisc_fifo.skel.h"
#include "bpf_qdisc_fq.skel.h"
#include "bpf_qdisc_fail__incompl_ops.skel.h"

#define LO_IFINDEX 1

@@ -159,6 +160,22 @@ static void test_qdisc_attach_to_non_root(void)
	bpf_qdisc_fifo__destroy(fifo_skel);
}

static void test_incompl_ops(void)
{
	struct bpf_qdisc_fail__incompl_ops *skel;
	struct bpf_link *link;

	skel = bpf_qdisc_fail__incompl_ops__open_and_load();
	if (!ASSERT_OK_PTR(skel, "bpf_qdisc_fifo__open_and_load"))
		return;

	link = bpf_map__attach_struct_ops(skel->maps.test);
	if (!ASSERT_ERR_PTR(link, "bpf_map__attach_struct_ops"))
		bpf_link__destroy(link);

	bpf_qdisc_fail__incompl_ops__destroy(skel);
}

static int get_default_qdisc(char *qdisc_name)
{
	FILE *f;
@@ -230,6 +247,8 @@ void test_bpf_qdisc(void)
		test_qdisc_attach_to_mq();
	if (test__start_subtest("attach to non root"))
		test_qdisc_attach_to_non_root();
	if (test__start_subtest("incompl_ops"))
		test_incompl_ops();

	netns_free(netns);
}
+41 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0

#include <vmlinux.h>
#include "bpf_experimental.h"
#include "bpf_qdisc_common.h"

char _license[] SEC("license") = "GPL";

SEC("struct_ops")
int BPF_PROG(bpf_qdisc_test_enqueue, struct sk_buff *skb, struct Qdisc *sch,
	     struct bpf_sk_buff_ptr *to_free)
{
	bpf_qdisc_skb_drop(skb, to_free);
	return NET_XMIT_DROP;
}

SEC("struct_ops")
struct sk_buff *BPF_PROG(bpf_qdisc_test_dequeue, struct Qdisc *sch)
{
	return NULL;
}

SEC("struct_ops")
void BPF_PROG(bpf_qdisc_test_reset, struct Qdisc *sch)
{
}

SEC("struct_ops")
void BPF_PROG(bpf_qdisc_test_destroy, struct Qdisc *sch)
{
}

SEC(".struct_ops")
struct Qdisc_ops test = {
	.enqueue   = (void *)bpf_qdisc_test_enqueue,
	.dequeue   = (void *)bpf_qdisc_test_dequeue,
	.reset     = (void *)bpf_qdisc_test_reset,
	.destroy   = (void *)bpf_qdisc_test_destroy,
	.id        = "bpf_qdisc_test",
};
+6 −0
Original line number Diff line number Diff line
@@ -109,12 +109,18 @@ void BPF_PROG(bpf_fifo_reset, struct Qdisc *sch)
	sch->q.qlen = 0;
}

SEC("struct_ops")
void BPF_PROG(bpf_fifo_destroy, struct Qdisc *sch)
{
}

SEC(".struct_ops")
struct Qdisc_ops fifo = {
	.enqueue   = (void *)bpf_fifo_enqueue,
	.dequeue   = (void *)bpf_fifo_dequeue,
	.init      = (void *)bpf_fifo_init,
	.reset     = (void *)bpf_fifo_reset,
	.destroy   = (void *)bpf_fifo_destroy,
	.id        = "bpf_fifo",
};
+6 −0
Original line number Diff line number Diff line
@@ -740,11 +740,17 @@ int BPF_PROG(bpf_fq_init, struct Qdisc *sch, struct nlattr *opt,
	return 0;
}

SEC("struct_ops")
void BPF_PROG(bpf_fq_destroy, struct Qdisc *sch)
{
}

SEC(".struct_ops")
struct Qdisc_ops fq = {
	.enqueue   = (void *)bpf_fq_enqueue,
	.dequeue   = (void *)bpf_fq_dequeue,
	.reset     = (void *)bpf_fq_reset,
	.init      = (void *)bpf_fq_init,
	.destroy   = (void *)bpf_fq_destroy,
	.id        = "bpf_fq",
};