From 17a90a78847324b1a34b0de833492cbd2366361d Mon Sep 17 00:00:00 2001 From: Peter Oskolkov Date: Mon, 4 Mar 2019 16:27:09 -0800 Subject: selftests/bpf: test that GSO works in lwt_ip_encap Add a test on egress that a large TCP packet successfully goes through the lwt+bpf encap tunnel. Although there is no direct evidence that GSO worked, as opposed to e.g. TCP segmentation or IP fragmentation (maybe a kernel stats counter should be added to track the number of failed GSO attempts?), without the previous patch in the patchset this test fails, and printk-debugging showed that software-based GSO succeeded here (veth is not compatible with SKB_GSO_DODGY, so GSO happens in the software stack). Also removed an unnecessary nodad and added a missed failed flag. Signed-off-by: Peter Oskolkov Acked-by: Song Liu Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/test_lwt_ip_encap.sh | 54 +++++++++++++++++++++++- 1 file changed, 52 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/test_lwt_ip_encap.sh b/tools/testing/selftests/bpf/test_lwt_ip_encap.sh index 612632c1425f..d4d3391cc13a 100755 --- a/tools/testing/selftests/bpf/test_lwt_ip_encap.sh +++ b/tools/testing/selftests/bpf/test_lwt_ip_encap.sh @@ -78,6 +78,8 @@ TEST_STATUS=0 TESTS_SUCCEEDED=0 TESTS_FAILED=0 +TMPFILE="" + process_test_results() { if [[ "${TEST_STATUS}" -eq 0 ]] ; then @@ -147,7 +149,6 @@ setup() ip -netns ${NS2} -6 addr add ${IPv6_7}/128 nodad dev veth7 ip -netns ${NS3} -6 addr add ${IPv6_8}/128 nodad dev veth8 - ip -netns ${NS1} link set dev veth1 up ip -netns ${NS2} link set dev veth2 up ip -netns ${NS2} link set dev veth3 up @@ -205,7 +206,7 @@ setup() # configure IPv4 GRE device in NS3, and a route to it via the "bottom" route ip -netns ${NS3} tunnel add gre_dev mode gre remote ${IPv4_1} local ${IPv4_GRE} ttl 255 ip -netns ${NS3} link set gre_dev up - ip -netns ${NS3} addr add ${IPv4_GRE} nodad dev gre_dev + ip -netns ${NS3} addr add ${IPv4_GRE} dev gre_dev ip -netns ${NS1} route add ${IPv4_GRE}/32 dev veth5 via ${IPv4_6} ip -netns ${NS2} route add ${IPv4_GRE}/32 dev veth7 via ${IPv4_8} @@ -222,12 +223,18 @@ setup() ip netns exec ${NS2} sysctl -wq net.ipv4.conf.all.rp_filter=0 ip netns exec ${NS3} sysctl -wq net.ipv4.conf.all.rp_filter=0 + TMPFILE=$(mktemp /tmp/test_lwt_ip_encap.XXXXXX) + sleep 1 # reduce flakiness set +e } cleanup() { + if [ -f ${TMPFILE} ] ; then + rm ${TMPFILE} + fi + ip netns del ${NS1} 2> /dev/null ip netns del ${NS2} 2> /dev/null ip netns del ${NS3} 2> /dev/null @@ -278,6 +285,46 @@ test_ping() fi } +test_gso() +{ + local readonly PROTO=$1 + local readonly PKT_SZ=5000 + local IP_DST="" + : > ${TMPFILE} # trim the capture file + + # check that nc is present + command -v nc >/dev/null 2>&1 || \ + { echo >&2 "nc is not available: skipping TSO tests"; return; } + + # listen on IPv*_DST, capture TCP into $TMPFILE + if [ "${PROTO}" == "IPv4" ] ; then + IP_DST=${IPv4_DST} + ip netns exec ${NS3} bash -c \ + "nc -4 -l -s ${IPv4_DST} -p 9000 > ${TMPFILE} &" + elif [ "${PROTO}" == "IPv6" ] ; then + IP_DST=${IPv6_DST} + ip netns exec ${NS3} bash -c \ + "nc -6 -l -s ${IPv6_DST} -p 9000 > ${TMPFILE} &" + RET=$? + else + echo " test_gso: unknown PROTO: ${PROTO}" + TEST_STATUS=1 + fi + sleep 1 # let nc start listening + + # send a packet larger than MTU + ip netns exec ${NS1} bash -c \ + "dd if=/dev/zero bs=$PKT_SZ count=1 > /dev/tcp/${IP_DST}/9000 2>/dev/null" + sleep 2 # let the packet get delivered + + # verify we received all expected bytes + SZ=$(stat -c %s ${TMPFILE}) + if [ "$SZ" != "$PKT_SZ" ] ; then + echo " test_gso failed: ${PROTO}" + TEST_STATUS=1 + fi +} + test_egress() { local readonly ENCAP=$1 @@ -307,6 +354,8 @@ test_egress() fi test_ping IPv4 0 test_ping IPv6 0 + test_gso IPv4 + test_gso IPv6 # a negative test: remove routes to GRE devices: ping fails remove_routes_to_gredev @@ -350,6 +399,7 @@ test_ingress() ip -netns ${NS2} -6 route add ${IPv6_DST} encap bpf in obj test_lwt_ip_encap.o sec encap_gre6 dev veth2 else echo "FAIL: unknown encap ${ENCAP}" + TEST_STATUS=1 fi test_ping IPv4 0 test_ping IPv6 0 -- cgit v1.2.3-59-g8ed1b From e78e00bd478a43ee01db726ce488424a371e8684 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Wed, 6 Mar 2019 11:59:26 -0800 Subject: selftests: bpf: fix compilation with out-of-tree $(OUTPUT) A bunch of related changes lumped together: * Create prog_tests and verifier output directories; these don't exist with out-of-tree $(OUTPUT) * Add missing -I (via separate TEST_{PROGS,VERIFIER}_CFLAGS) for the main tree ($(PWD) != $(OUTPUT) for out-of-tree) * Add libbpf.a dependency for test_progs_32 (parallel make fails otherwise) * Add missing "; \" after "cd" when generating test.h headers Tested by: $ alias m="make -s -j$(nproc)" $ m -C tools/testing/selftests/bpf/ clean $ m -C tools/lib/bpf/ clean $ rm -rf xxx; mkdir xxx; m -C tools/testing/selftests/bpf/ OUTPUT=$PWD/xxx $ m -C tools/testing/selftests/bpf/ Fixes: 3f30658830f3 ("selftests: bpf: break up test_progs - preparations") Fixes: 2dfb40121ee8 ("selftests: bpf: prepare for break up of verifier tests") Fixes: 3ef84346c561 ("selftests: bpf: makefile support sub-register code-gen test mode") Signed-off-by: Stanislav Fomichev Acked-by: Yonghong Song Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/Makefile | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index 518cd587cd63..2aed37ea61a4 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -153,6 +153,9 @@ endif endif endif +TEST_PROGS_CFLAGS := -I. -I$(OUTPUT) +TEST_VERIFIER_CFLAGS := -I. -I$(OUTPUT) -Iverifier + ifneq ($(SUBREG_CODEGEN),) ALU32_BUILD_DIR = $(OUTPUT)/alu32 TEST_CUSTOM_PROGS += $(ALU32_BUILD_DIR)/test_progs_32 @@ -162,13 +165,15 @@ $(ALU32_BUILD_DIR): $(ALU32_BUILD_DIR)/urandom_read: $(OUTPUT)/urandom_read cp $< $@ -$(ALU32_BUILD_DIR)/test_progs_32: test_progs.c $(ALU32_BUILD_DIR) \ +$(ALU32_BUILD_DIR)/test_progs_32: test_progs.c $(OUTPUT)/libbpf.a\ + $(ALU32_BUILD_DIR) \ $(ALU32_BUILD_DIR)/urandom_read - $(CC) $(CFLAGS) -o $(ALU32_BUILD_DIR)/test_progs_32 $< \ - trace_helpers.c prog_tests/*.c $(OUTPUT)/libbpf.a $(LDLIBS) + $(CC) $(TEST_PROGS_CFLAGS) $(CFLAGS) \ + -o $(ALU32_BUILD_DIR)/test_progs_32 \ + test_progs.c trace_helpers.c prog_tests/*.c \ + $(OUTPUT)/libbpf.a $(LDLIBS) $(ALU32_BUILD_DIR)/test_progs_32: $(PROG_TESTS_H) -$(ALU32_BUILD_DIR)/test_progs_32: CFLAGS += -I$(OUTPUT) $(ALU32_BUILD_DIR)/test_progs_32: prog_tests/*.c $(ALU32_BUILD_DIR)/%.o: progs/%.c $(ALU32_BUILD_DIR) \ @@ -202,12 +207,16 @@ endif PROG_TESTS_H := $(OUTPUT)/prog_tests/tests.h $(OUTPUT)/test_progs: $(PROG_TESTS_H) -$(OUTPUT)/test_progs: CFLAGS += -I$(OUTPUT) +$(OUTPUT)/test_progs: CFLAGS += $(TEST_PROGS_CFLAGS) $(OUTPUT)/test_progs: prog_tests/*.c +PROG_TESTS_DIR = $(OUTPUT)/prog_tests +$(PROG_TESTS_DIR): + mkdir -p $@ + PROG_TESTS_FILES := $(wildcard prog_tests/*.c) -$(PROG_TESTS_H): $(PROG_TESTS_FILES) - $(shell ( cd prog_tests/ +$(PROG_TESTS_H): $(PROG_TESTS_DIR) $(PROG_TESTS_FILES) + $(shell ( cd prog_tests/; \ echo '/* Generated header, do not edit */'; \ echo '#ifdef DECLARE'; \ ls *.c 2> /dev/null | \ @@ -221,11 +230,15 @@ $(PROG_TESTS_H): $(PROG_TESTS_FILES) VERIFIER_TESTS_H := $(OUTPUT)/verifier/tests.h $(OUTPUT)/test_verifier: $(VERIFIER_TESTS_H) -$(OUTPUT)/test_verifier: CFLAGS += -I$(OUTPUT) +$(OUTPUT)/test_verifier: CFLAGS += $(TEST_VERIFIER_CFLAGS) + +VERIFIER_TESTS_DIR = $(OUTPUT)/verifier +$(VERIFIER_TESTS_DIR): + mkdir -p $@ VERIFIER_TEST_FILES := $(wildcard verifier/*.c) -$(OUTPUT)/verifier/tests.h: $(VERIFIER_TEST_FILES) - $(shell ( cd verifier/ +$(OUTPUT)/verifier/tests.h: $(VERIFIER_TESTS_DIR) $(VERIFIER_TEST_FILES) + $(shell ( cd verifier/; \ echo '/* Generated header, do not edit */'; \ echo '#ifdef FILL_ARRAY'; \ ls *.c 2> /dev/null | \ -- cgit v1.2.3-59-g8ed1b From 8e2688876c7f7073d925e1f150e86b8ed3338f52 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Wed, 6 Mar 2019 11:59:27 -0800 Subject: libbpf: force fixdep compilation at the start of the build libbpf targets don't explicitly depend on fixdep target, so when we do 'make -j$(nproc)', there is a high probability, that some objects will be built before fixdep binary is available. Fix this by running sub-make; this makes sure that fixdep dependency is properly accounted for. For the same issue in perf, see commit abb26210a395 ("perf tools: Force fixdep compilation at the start of the build"). Before: $ rm -rf /tmp/bld; mkdir /tmp/bld; make -j$(nproc) O=/tmp/bld -C tools/lib/bpf/ Auto-detecting system features: ... libelf: [ on ] ... bpf: [ on ] HOSTCC /tmp/bld/fixdep.o CC /tmp/bld/libbpf.o CC /tmp/bld/bpf.o CC /tmp/bld/btf.o CC /tmp/bld/nlattr.o CC /tmp/bld/libbpf_errno.o CC /tmp/bld/str_error.o CC /tmp/bld/netlink.o CC /tmp/bld/bpf_prog_linfo.o CC /tmp/bld/libbpf_probes.o CC /tmp/bld/xsk.o HOSTLD /tmp/bld/fixdep-in.o LINK /tmp/bld/fixdep LD /tmp/bld/libbpf-in.o LINK /tmp/bld/libbpf.a LINK /tmp/bld/libbpf.so LINK /tmp/bld/test_libbpf $ head /tmp/bld/.libbpf.o.cmd # cannot find fixdep (/usr/local/google/home/sdf/src/linux/xxx//fixdep) # using basic dep data /tmp/bld/libbpf.o: libbpf.c /usr/include/stdc-predef.h \ /usr/include/stdlib.h /usr/include/features.h \ /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ /usr/include/x86_64-linux-gnu/gnu/stubs.h \ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ /usr/lib/gcc/x86_64-linux-gnu/7/include/stddef.h \ After: $ rm -rf /tmp/bld; mkdir /tmp/bld; make -j$(nproc) O=/tmp/bld -C tools/lib/bpf/ Auto-detecting system features: ... libelf: [ on ] ... bpf: [ on ] HOSTCC /tmp/bld/fixdep.o HOSTLD /tmp/bld/fixdep-in.o LINK /tmp/bld/fixdep CC /tmp/bld/libbpf.o CC /tmp/bld/bpf.o CC /tmp/bld/nlattr.o CC /tmp/bld/btf.o CC /tmp/bld/libbpf_errno.o CC /tmp/bld/str_error.o CC /tmp/bld/netlink.o CC /tmp/bld/bpf_prog_linfo.o CC /tmp/bld/libbpf_probes.o CC /tmp/bld/xsk.o LD /tmp/bld/libbpf-in.o LINK /tmp/bld/libbpf.a LINK /tmp/bld/libbpf.so LINK /tmp/bld/test_libbpf $ head /tmp/bld/.libbpf.o.cmd cmd_/tmp/bld/libbpf.o := gcc -Wp,-MD,/tmp/bld/.libbpf.o.d -Wp,-MT,/tmp/bld/libbpf.o -g -Wall -DHAVE_LIBELF_MMAP_SUPPORT -DCOMPAT_NEED_REALLOCARRAY -Wbad-function-cast -Wdeclaration-after-statement -Wformat-security -Wformat-y2k -Winit-self -Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Wno-system-headers -Wold-style-definition -Wpacked -Wredundant-decls -Wshadow -Wstrict-prototypes -Wswitch-default -Wswitch-enum -Wundef -Wwrite-strings -Wformat -Wstrict-aliasing=3 -Werror -Wall -fPIC -I. -I/usr/local/google/home/sdf/src/linux/tools/include -I/usr/local/google/home/sdf/src/linux/tools/arch/x86/include/uapi -I/usr/local/google/home/sdf/src/linux/tools/include/uapi -fvisibility=hidden -D"BUILD_STR(s)=$(pound)s" -c -o /tmp/bld/libbpf.o libbpf.c source_/tmp/bld/libbpf.o := libbpf.c deps_/tmp/bld/libbpf.o := \ /usr/include/stdc-predef.h \ /usr/include/stdlib.h \ /usr/include/features.h \ /usr/include/x86_64-linux-gnu/sys/cdefs.h \ /usr/include/x86_64-linux-gnu/bits/wordsize.h \ Fixes: 7c422f557266 ("tools build: Build fixdep helper from perf and basic libs") Reported-by: Eric Dumazet Signed-off-by: Stanislav Fomichev Acked-by: Yonghong Song Signed-off-by: Daniel Borkmann --- tools/lib/bpf/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile index a05c43468bd0..61aaacf0cfa1 100644 --- a/tools/lib/bpf/Makefile +++ b/tools/lib/bpf/Makefile @@ -147,7 +147,8 @@ endif TARGETS = $(CMD_TARGETS) -all: fixdep all_cmd +all: fixdep + $(Q)$(MAKE) all_cmd all_cmd: $(CMD_TARGETS) check -- cgit v1.2.3-59-g8ed1b From 69b09175d68241cb96ff9433d8e7a17382d720d6 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Wed, 6 Mar 2019 15:25:26 -0800 Subject: selftests: bpf: test_progs: initialize duration in singal_pending test CHECK macro implicitly uses duration. We call CHECK() a couple of times before duration is initialized from bpf_prog_test_run(). Explicitly set duration to 0 to avoid compiler warnings. Fixes: 740f8a657221 ("selftests/bpf: make sure signal interrupts BPF_PROG_TEST_RUN") Signed-off-by: Stanislav Fomichev Acked-by: Yonghong Song Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/prog_tests/signal_pending.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/testing/selftests/bpf/prog_tests/signal_pending.c b/tools/testing/selftests/bpf/prog_tests/signal_pending.c index f2a37bbf91ab..996e808f43a2 100644 --- a/tools/testing/selftests/bpf/prog_tests/signal_pending.c +++ b/tools/testing/selftests/bpf/prog_tests/signal_pending.c @@ -12,7 +12,7 @@ static void test_signal_pending_by_type(enum bpf_prog_type prog_type) struct itimerval timeo = { .it_value.tv_usec = 100000, /* 100ms */ }; - __u32 duration, retval; + __u32 duration = 0, retval; int prog_fd; int err; int i; -- cgit v1.2.3-59-g8ed1b From 20182390c4134478d795a096ddb8dddcc648e28a Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Mon, 4 Mar 2019 21:08:53 +0100 Subject: bpf: fix replace_map_fd_with_map_ptr's ldimm64 second imm field Non-zero imm value in the second part of the ldimm64 instruction for BPF_PSEUDO_MAP_FD is invalid, and thus must be rejected. The map fd only ever sits in the first instructions' imm field. None of the BPF loaders known to us are using it, so risk of regression is minimal. For clarity and consistency, the few insn->{src_reg,imm} occurrences are rewritten into insn[0].{src_reg,imm}. Add a test case to the BPF selftest suite as well. Fixes: 0246e64d9a5f ("bpf: handle pseudo BPF_LD_IMM64 insn") Signed-off-by: Daniel Borkmann Acked-by: Song Liu Signed-off-by: Alexei Starovoitov --- kernel/bpf/verifier.c | 10 +++++----- tools/testing/selftests/bpf/verifier/ld_imm64.c | 15 ++++++++++++++- 2 files changed, 19 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index a7b96bf0e654..ce166a002d16 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -6678,17 +6678,17 @@ static int replace_map_fd_with_map_ptr(struct bpf_verifier_env *env) /* valid generic load 64-bit imm */ goto next_insn; - if (insn->src_reg != BPF_PSEUDO_MAP_FD) { - verbose(env, - "unrecognized bpf_ld_imm64 insn\n"); + if (insn[0].src_reg != BPF_PSEUDO_MAP_FD || + insn[1].imm != 0) { + verbose(env, "unrecognized bpf_ld_imm64 insn\n"); return -EINVAL; } - f = fdget(insn->imm); + f = fdget(insn[0].imm); map = __bpf_map_get(f); if (IS_ERR(map)) { verbose(env, "fd %d is not pointing to valid bpf_map\n", - insn->imm); + insn[0].imm); return PTR_ERR(map); } diff --git a/tools/testing/selftests/bpf/verifier/ld_imm64.c b/tools/testing/selftests/bpf/verifier/ld_imm64.c index 28b8c805a293..3856dba733e9 100644 --- a/tools/testing/selftests/bpf/verifier/ld_imm64.c +++ b/tools/testing/selftests/bpf/verifier/ld_imm64.c @@ -122,7 +122,7 @@ .insns = { BPF_MOV64_IMM(BPF_REG_1, 0), BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, BPF_REG_1, 0, 1), - BPF_RAW_INSN(0, 0, 0, 0, 1), + BPF_RAW_INSN(0, 0, 0, 0, 0), BPF_EXIT_INSN(), }, .errstr = "not pointing to valid bpf_map", @@ -139,3 +139,16 @@ .errstr = "invalid bpf_ld_imm64 insn", .result = REJECT, }, +{ + "test14 ld_imm64: reject 2nd imm != 0", + .insns = { + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_1, + BPF_PSEUDO_MAP_FD, 0, 0), + BPF_RAW_INSN(0, 0, 0, 0, 0xfefefe), + BPF_EXIT_INSN(), + }, + .fixup_map_hash_48b = { 1 }, + .errstr = "unrecognized bpf_ld_imm64 insn", + .result = REJECT, +}, -- cgit v1.2.3-59-g8ed1b From 243b4cdab981d7004bee56c38e18a29da32ef104 Mon Sep 17 00:00:00 2001 From: "Nikita V. Shirokov" Date: Fri, 8 Mar 2019 05:18:14 +0000 Subject: bpf, libbpf: fixing leak when kernel does not support btf We could end up in situation when we have object file w/ all btf info, but kernel does not support btf yet. In this situation currently libbpf just set obj->btf to NULL w/o freeing it first. This patch is fixing it by making sure to run btf__free first. Fixes: d29d87f7e612 ("btf: separate btf creation and loading") Signed-off-by: Nikita V. Shirokov Acked-by: Yonghong Song Signed-off-by: Daniel Borkmann --- tools/lib/bpf/libbpf.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index f5eb60379c8d..d5b830d60601 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -838,6 +838,8 @@ static int bpf_object__elf_collect(struct bpf_object *obj, int flags) if (IS_ERR(obj->btf) || btf__load(obj->btf)) { pr_warning("Error loading ELF section %s: %ld. Ignored and continue.\n", BTF_ELF_SEC, PTR_ERR(obj->btf)); + if (!IS_ERR(obj->btf)) + btf__free(obj->btf); obj->btf = NULL; } } else if (strcmp(name, BTF_EXT_ELF_SEC) == 0) { -- cgit v1.2.3-59-g8ed1b