linux/tools/testing/selftests/bpf/test_xdp_meta.c
Daniel Borkmann 22c8852624 bpf: improve selftests and add tests for meta pointer
Add various test_verifier selftests, and a simple xdp/tc functional
test that is being attached to veths. Also let new versions of clang
use the recently added -mcpu=probe support [1] for the BPF target,
so that it can probe the underlying kernel for BPF insn set extensions.
We could also just set this options always, where older versions just
ignore it and give a note to the user that the -mcpu value is not
supported, but given emitting the note cannot be turned off from clang
side lets not confuse users running selftests with it, thus fallback
to the default generic one when we see that clang doesn't support it.
Also allow CPU option to be overridden in the Makefile from command
line.

  [1] d7276a40d8

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-09-26 13:36:44 -07:00

54 lines
1.2 KiB
C

#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/pkt_cls.h>
#include "bpf_helpers.h"
#define __round_mask(x, y) ((__typeof__(x))((y) - 1))
#define round_up(x, y) ((((x) - 1) | __round_mask(x, y)) + 1)
#define ctx_ptr(ctx, mem) (void *)(unsigned long)ctx->mem
SEC("t")
int ing_cls(struct __sk_buff *ctx)
{
__u8 *data, *data_meta, *data_end;
__u32 diff = 0;
data_meta = ctx_ptr(ctx, data_meta);
data_end = ctx_ptr(ctx, data_end);
data = ctx_ptr(ctx, data);
if (data + ETH_ALEN > data_end ||
data_meta + round_up(ETH_ALEN, 4) > data)
return TC_ACT_SHOT;
diff |= ((__u32 *)data_meta)[0] ^ ((__u32 *)data)[0];
diff |= ((__u16 *)data_meta)[2] ^ ((__u16 *)data)[2];
return diff ? TC_ACT_SHOT : TC_ACT_OK;
}
SEC("x")
int ing_xdp(struct xdp_md *ctx)
{
__u8 *data, *data_meta, *data_end;
int ret;
ret = bpf_xdp_adjust_meta(ctx, -round_up(ETH_ALEN, 4));
if (ret < 0)
return XDP_DROP;
data_meta = ctx_ptr(ctx, data_meta);
data_end = ctx_ptr(ctx, data_end);
data = ctx_ptr(ctx, data);
if (data + ETH_ALEN > data_end ||
data_meta + round_up(ETH_ALEN, 4) > data)
return XDP_DROP;
__builtin_memcpy(data_meta, data, ETH_ALEN);
return XDP_PASS;
}
char _license[] SEC("license") = "GPL";