diff options
author | Alexei Starovoitov <ast@fb.com> | 2017-03-30 21:45:42 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-04-01 12:45:57 -0700 |
commit | 8d48f5e427923fa6f6482c716082d310b7f3bcd5 (patch) | |
tree | 99977dea886502e8240b4030b5b29512d9827458 /tools/testing/selftests/bpf/test_progs.c | |
parent | 6882804c916beaa945bae90dfd3295e635f6b78f (diff) |
selftests/bpf: add a test for basic XDP functionality
add C test for xdp_adjust_head(), packet rewrite and map lookups
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'tools/testing/selftests/bpf/test_progs.c')
-rw-r--r-- | tools/testing/selftests/bpf/test_progs.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c index 1d9a310e71e5..defcb273242e 100644 --- a/tools/testing/selftests/bpf/test_progs.c +++ b/tools/testing/selftests/bpf/test_progs.c @@ -27,6 +27,7 @@ typedef __u16 __sum16; #include <linux/err.h> #include <bpf/bpf.h> #include <bpf/libbpf.h> +#include "test_iptunnel_common.h" #define _htons __builtin_bswap16 @@ -100,6 +101,20 @@ static int bpf_prog_load(const char *file, enum bpf_prog_type type, return 0; } +static int bpf_find_map(const char *test, struct bpf_object *obj, + const char *name) +{ + struct bpf_map *map; + + map = bpf_object__find_map_by_name(obj, name); + if (!map) { + printf("%s:FAIL:map '%s' not found\n", test, name); + error_cnt++; + return -1; + } + return bpf_map__fd(map); +} + static void test_pkt_access(void) { const char *file = "./test_pkt_access.o"; @@ -125,6 +140,48 @@ static void test_pkt_access(void) bpf_object__close(obj); } +static void test_xdp(void) +{ + struct vip key4 = {.protocol = 6, .family = AF_INET}; + struct vip key6 = {.protocol = 6, .family = AF_INET6}; + struct iptnl_info value4 = {.family = AF_INET}; + struct iptnl_info value6 = {.family = AF_INET6}; + const char *file = "./test_xdp.o"; + struct bpf_object *obj; + char buf[128]; + struct ipv6hdr *iph6 = (void *)buf + sizeof(struct ethhdr); + struct iphdr *iph = (void *)buf + sizeof(struct ethhdr); + __u32 duration, retval, size; + int err, prog_fd, map_fd; + + err = bpf_prog_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd); + if (err) + return; + + map_fd = bpf_find_map(__func__, obj, "vip2tnl"); + if (map_fd < 0) + goto out; + bpf_map_update_elem(map_fd, &key4, &value4, 0); + bpf_map_update_elem(map_fd, &key6, &value6, 0); + + err = bpf_prog_test_run(prog_fd, 1, &pkt_v4, sizeof(pkt_v4), + buf, &size, &retval, &duration); + + CHECK(err || errno || retval != XDP_TX || size != 74 || + iph->protocol != IPPROTO_IPIP, "ipv4", + "err %d errno %d retval %d size %d\n", + err, errno, retval, size); + + err = bpf_prog_test_run(prog_fd, 1, &pkt_v6, sizeof(pkt_v6), + buf, &size, &retval, &duration); + CHECK(err || errno || retval != XDP_TX || size != 114 || + iph6->nexthdr != IPPROTO_IPV6, "ipv6", + "err %d errno %d retval %d size %d\n", + err, errno, retval, size); +out: + bpf_object__close(obj); +} + int main(void) { struct rlimit rinf = { RLIM_INFINITY, RLIM_INFINITY }; @@ -132,6 +189,7 @@ int main(void) setrlimit(RLIMIT_MEMLOCK, &rinf); test_pkt_access(); + test_xdp(); printf("Summary: %d PASSED, %d FAILED\n", pass_cnt, error_cnt); return 0; |