1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00
linux/tools/testing/selftests/bpf/prog_tests/skb_ctx.c
Dmitry Yakunin 21594c4408 bpf: Allow to specify ifindex for skb in bpf_prog_test_run_skb
Now skb->dev is unconditionally set to the loopback device in current net
namespace. But if we want to test bpf program which contains code branch
based on ifindex condition (eg filters out localhost packets) it is useful
to allow specifying of ifindex from userspace. This patch adds such option
through ctx_in (__sk_buff) parameter.

Signed-off-by: Dmitry Yakunin <zeil@yandex-team.ru>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20200803090545.82046-3-zeil@yandex-team.ru
2020-08-03 23:32:23 +02:00

108 lines
2.7 KiB
C

// SPDX-License-Identifier: GPL-2.0
#include <test_progs.h>
#include <network_helpers.h>
void test_skb_ctx(void)
{
struct __sk_buff skb = {
.cb[0] = 1,
.cb[1] = 2,
.cb[2] = 3,
.cb[3] = 4,
.cb[4] = 5,
.priority = 6,
.ifindex = 1,
.tstamp = 7,
.wire_len = 100,
.gso_segs = 8,
.mark = 9,
.gso_size = 10,
};
struct bpf_prog_test_run_attr tattr = {
.data_in = &pkt_v4,
.data_size_in = sizeof(pkt_v4),
.ctx_in = &skb,
.ctx_size_in = sizeof(skb),
.ctx_out = &skb,
.ctx_size_out = sizeof(skb),
};
struct bpf_object *obj;
int err;
int i;
err = bpf_prog_load("./test_skb_ctx.o", BPF_PROG_TYPE_SCHED_CLS, &obj,
&tattr.prog_fd);
if (CHECK_ATTR(err, "load", "err %d errno %d\n", err, errno))
return;
/* ctx_in != NULL, ctx_size_in == 0 */
tattr.ctx_size_in = 0;
err = bpf_prog_test_run_xattr(&tattr);
CHECK_ATTR(err == 0, "ctx_size_in", "err %d errno %d\n", err, errno);
tattr.ctx_size_in = sizeof(skb);
/* ctx_out != NULL, ctx_size_out == 0 */
tattr.ctx_size_out = 0;
err = bpf_prog_test_run_xattr(&tattr);
CHECK_ATTR(err == 0, "ctx_size_out", "err %d errno %d\n", err, errno);
tattr.ctx_size_out = sizeof(skb);
/* non-zero [len, tc_index] fields should be rejected*/
skb.len = 1;
err = bpf_prog_test_run_xattr(&tattr);
CHECK_ATTR(err == 0, "len", "err %d errno %d\n", err, errno);
skb.len = 0;
skb.tc_index = 1;
err = bpf_prog_test_run_xattr(&tattr);
CHECK_ATTR(err == 0, "tc_index", "err %d errno %d\n", err, errno);
skb.tc_index = 0;
/* non-zero [hash, sk] fields should be rejected */
skb.hash = 1;
err = bpf_prog_test_run_xattr(&tattr);
CHECK_ATTR(err == 0, "hash", "err %d errno %d\n", err, errno);
skb.hash = 0;
skb.sk = (struct bpf_sock *)1;
err = bpf_prog_test_run_xattr(&tattr);
CHECK_ATTR(err == 0, "sk", "err %d errno %d\n", err, errno);
skb.sk = 0;
err = bpf_prog_test_run_xattr(&tattr);
CHECK_ATTR(err != 0 || tattr.retval,
"run",
"err %d errno %d retval %d\n",
err, errno, tattr.retval);
CHECK_ATTR(tattr.ctx_size_out != sizeof(skb),
"ctx_size_out",
"incorrect output size, want %lu have %u\n",
sizeof(skb), tattr.ctx_size_out);
for (i = 0; i < 5; i++)
CHECK_ATTR(skb.cb[i] != i + 2,
"ctx_out_cb",
"skb->cb[i] == %d, expected %d\n",
skb.cb[i], i + 2);
CHECK_ATTR(skb.priority != 7,
"ctx_out_priority",
"skb->priority == %d, expected %d\n",
skb.priority, 7);
CHECK_ATTR(skb.ifindex != 1,
"ctx_out_ifindex",
"skb->ifindex == %d, expected %d\n",
skb.ifindex, 1);
CHECK_ATTR(skb.tstamp != 8,
"ctx_out_tstamp",
"skb->tstamp == %lld, expected %d\n",
skb.tstamp, 8);
CHECK_ATTR(skb.mark != 10,
"ctx_out_mark",
"skb->mark == %u, expected %d\n",
skb.mark, 10);
}