Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf

Daniel Borkmann says:

====================
pull-request: bpf 2021-11-05

We've added 15 non-merge commits during the last 3 day(s) which contain
a total of 14 files changed, 199 insertions(+), 90 deletions(-).

The main changes are:

1) Fix regression from stack spill/fill of <8 byte scalars, from Martin KaFai Lau.

2) Fix perf's build of bpftool's bootstrap version due to missing libbpf
headers, from Quentin Monnet.

3) Fix riscv{32,64} BPF exception tables build errors and warnings, from Björn Töpel.

4) Fix bpf fs to allow RENAME_EXCHANGE support for atomic upgrades on sk_lookup
control planes, from Lorenz Bauer.

5) Fix libbpf's error reporting in bpf_map_lookup_and_delete_elem_flags() due to
missing libbpf_err_errno(), from Mehrdad Arshad Rad.

6) Various fixes to make xdp_redirect_multi selftest more reliable, from Hangbin Liu.

7) Fix netcnt selftest to make it run serial and thus avoid conflicts with other
cgroup/skb selftests run in parallel that could cause flakes, from Andrii Nakryiko.

8) Fix reuseport_bpf_numa networking selftest to skip unavailable NUMA nodes,
from Kleber Sacilotto de Souza.

* https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf:
riscv, bpf: Fix RV32 broken build, and silence RV64 warning
selftests/bpf/xdp_redirect_multi: Limit the tests in netns
selftests/bpf/xdp_redirect_multi: Give tcpdump a chance to terminate cleanly
selftests/bpf/xdp_redirect_multi: Use arping to accurate the arp number
selftests/bpf/xdp_redirect_multi: Put the logs to tmp folder
libbpf: Fix lookup_and_delete_elem_flags error reporting
bpftool: Install libbpf headers for the bootstrap version, too
selftests/net: Fix reuseport_bpf_numa by skipping unavailable nodes
selftests/bpf: Verifier test on refill from a smaller spill
bpf: Do not reject when the stack read size is different from the tracked scalar size
selftests/bpf: Make netcnt selftests serial to avoid spurious failures
selftests/bpf: Test RENAME_EXCHANGE and RENAME_NOREPLACE on bpffs
selftests/bpf: Convert test_bpffs to ASSERT macros
libfs: Support RENAME_EXCHANGE in simple_rename()
libfs: Move shmem_exchange to simple_rename_exchange
====================

Link: https://lore.kernel.org/r/20211105165803.29372-1-daniel@iogearbox.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+199 -90
+2 -2
arch/riscv/mm/extable.c
··· 11 11 #include <linux/module.h> 12 12 #include <linux/uaccess.h> 13 13 14 - #ifdef CONFIG_BPF_JIT 14 + #if defined(CONFIG_BPF_JIT) && defined(CONFIG_ARCH_RV64I) 15 15 int rv_bpf_fixup_exception(const struct exception_table_entry *ex, struct pt_regs *regs); 16 16 #endif 17 17 ··· 23 23 if (!fixup) 24 24 return 0; 25 25 26 - #ifdef CONFIG_BPF_JIT 26 + #if defined(CONFIG_BPF_JIT) && defined(CONFIG_ARCH_RV64I) 27 27 if (regs->epc >= BPF_JIT_REGION_START && regs->epc < BPF_JIT_REGION_END) 28 28 return rv_bpf_fixup_exception(fixup, regs); 29 29 #endif
+2
arch/riscv/net/bpf_jit_comp64.c
··· 460 460 #define BPF_FIXUP_REG_MASK GENMASK(31, 27) 461 461 462 462 int rv_bpf_fixup_exception(const struct exception_table_entry *ex, 463 + struct pt_regs *regs); 464 + int rv_bpf_fixup_exception(const struct exception_table_entry *ex, 463 465 struct pt_regs *regs) 464 466 { 465 467 off_t offset = FIELD_GET(BPF_FIXUP_OFFSET_MASK, ex->fixup);
+28 -1
fs/libfs.c
··· 448 448 } 449 449 EXPORT_SYMBOL(simple_rmdir); 450 450 451 + int simple_rename_exchange(struct inode *old_dir, struct dentry *old_dentry, 452 + struct inode *new_dir, struct dentry *new_dentry) 453 + { 454 + bool old_is_dir = d_is_dir(old_dentry); 455 + bool new_is_dir = d_is_dir(new_dentry); 456 + 457 + if (old_dir != new_dir && old_is_dir != new_is_dir) { 458 + if (old_is_dir) { 459 + drop_nlink(old_dir); 460 + inc_nlink(new_dir); 461 + } else { 462 + drop_nlink(new_dir); 463 + inc_nlink(old_dir); 464 + } 465 + } 466 + old_dir->i_ctime = old_dir->i_mtime = 467 + new_dir->i_ctime = new_dir->i_mtime = 468 + d_inode(old_dentry)->i_ctime = 469 + d_inode(new_dentry)->i_ctime = current_time(old_dir); 470 + 471 + return 0; 472 + } 473 + EXPORT_SYMBOL_GPL(simple_rename_exchange); 474 + 451 475 int simple_rename(struct user_namespace *mnt_userns, struct inode *old_dir, 452 476 struct dentry *old_dentry, struct inode *new_dir, 453 477 struct dentry *new_dentry, unsigned int flags) ··· 479 455 struct inode *inode = d_inode(old_dentry); 480 456 int they_are_dirs = d_is_dir(old_dentry); 481 457 482 - if (flags & ~RENAME_NOREPLACE) 458 + if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE)) 483 459 return -EINVAL; 460 + 461 + if (flags & RENAME_EXCHANGE) 462 + return simple_rename_exchange(old_dir, old_dentry, new_dir, new_dentry); 484 463 485 464 if (!simple_empty(new_dentry)) 486 465 return -ENOTEMPTY;
+2
include/linux/fs.h
··· 3383 3383 extern int simple_link(struct dentry *, struct inode *, struct dentry *); 3384 3384 extern int simple_unlink(struct inode *, struct dentry *); 3385 3385 extern int simple_rmdir(struct inode *, struct dentry *); 3386 + extern int simple_rename_exchange(struct inode *old_dir, struct dentry *old_dentry, 3387 + struct inode *new_dir, struct dentry *new_dentry); 3386 3388 extern int simple_rename(struct user_namespace *, struct inode *, 3387 3389 struct dentry *, struct inode *, struct dentry *, 3388 3390 unsigned int);
+6 -12
kernel/bpf/verifier.c
··· 3088 3088 reg = &reg_state->stack[spi].spilled_ptr; 3089 3089 3090 3090 if (is_spilled_reg(&reg_state->stack[spi])) { 3091 - if (size != BPF_REG_SIZE) { 3092 - u8 scalar_size = 0; 3091 + u8 spill_size = 1; 3093 3092 3093 + for (i = BPF_REG_SIZE - 1; i > 0 && stype[i - 1] == STACK_SPILL; i--) 3094 + spill_size++; 3095 + 3096 + if (size != BPF_REG_SIZE || spill_size != BPF_REG_SIZE) { 3094 3097 if (reg->type != SCALAR_VALUE) { 3095 3098 verbose_linfo(env, env->insn_idx, "; "); 3096 3099 verbose(env, "invalid size of register fill\n"); ··· 3104 3101 if (dst_regno < 0) 3105 3102 return 0; 3106 3103 3107 - for (i = BPF_REG_SIZE; i > 0 && stype[i - 1] == STACK_SPILL; i--) 3108 - scalar_size++; 3109 - 3110 - if (!(off % BPF_REG_SIZE) && size == scalar_size) { 3104 + if (!(off % BPF_REG_SIZE) && size == spill_size) { 3111 3105 /* The earlier check_reg_arg() has decided the 3112 3106 * subreg_def for this insn. Save it first. 3113 3107 */ ··· 3127 3127 } 3128 3128 state->regs[dst_regno].live |= REG_LIVE_WRITTEN; 3129 3129 return 0; 3130 - } 3131 - for (i = 1; i < BPF_REG_SIZE; i++) { 3132 - if (stype[(slot - i) % BPF_REG_SIZE] != STACK_SPILL) { 3133 - verbose(env, "corrupted spill memory\n"); 3134 - return -EACCES; 3135 - } 3136 3130 } 3137 3131 3138 3132 if (dst_regno >= 0) {
+1 -23
mm/shmem.c
··· 2947 2947 return shmem_unlink(dir, dentry); 2948 2948 } 2949 2949 2950 - static int shmem_exchange(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry) 2951 - { 2952 - bool old_is_dir = d_is_dir(old_dentry); 2953 - bool new_is_dir = d_is_dir(new_dentry); 2954 - 2955 - if (old_dir != new_dir && old_is_dir != new_is_dir) { 2956 - if (old_is_dir) { 2957 - drop_nlink(old_dir); 2958 - inc_nlink(new_dir); 2959 - } else { 2960 - drop_nlink(new_dir); 2961 - inc_nlink(old_dir); 2962 - } 2963 - } 2964 - old_dir->i_ctime = old_dir->i_mtime = 2965 - new_dir->i_ctime = new_dir->i_mtime = 2966 - d_inode(old_dentry)->i_ctime = 2967 - d_inode(new_dentry)->i_ctime = current_time(old_dir); 2968 - 2969 - return 0; 2970 - } 2971 - 2972 2950 static int shmem_whiteout(struct user_namespace *mnt_userns, 2973 2951 struct inode *old_dir, struct dentry *old_dentry) 2974 2952 { ··· 2992 3014 return -EINVAL; 2993 3015 2994 3016 if (flags & RENAME_EXCHANGE) 2995 - return shmem_exchange(old_dir, old_dentry, new_dir, new_dentry); 3017 + return simple_rename_exchange(old_dir, old_dentry, new_dir, new_dentry); 2996 3018 2997 3019 if (!simple_empty(new_dentry)) 2998 3020 return -ENOTEMPTY;
+22 -10
tools/bpf/bpftool/Makefile
··· 22 22 _OUTPUT := $(CURDIR) 23 23 endif 24 24 BOOTSTRAP_OUTPUT := $(_OUTPUT)/bootstrap/ 25 + 25 26 LIBBPF_OUTPUT := $(_OUTPUT)/libbpf/ 26 27 LIBBPF_DESTDIR := $(LIBBPF_OUTPUT) 27 28 LIBBPF_INCLUDE := $(LIBBPF_DESTDIR)/include 28 29 LIBBPF_HDRS_DIR := $(LIBBPF_INCLUDE)/bpf 30 + LIBBPF := $(LIBBPF_OUTPUT)libbpf.a 29 31 30 - LIBBPF = $(LIBBPF_OUTPUT)libbpf.a 31 - LIBBPF_BOOTSTRAP_OUTPUT = $(BOOTSTRAP_OUTPUT)libbpf/ 32 - LIBBPF_BOOTSTRAP = $(LIBBPF_BOOTSTRAP_OUTPUT)libbpf.a 32 + LIBBPF_BOOTSTRAP_OUTPUT := $(BOOTSTRAP_OUTPUT)libbpf/ 33 + LIBBPF_BOOTSTRAP_DESTDIR := $(LIBBPF_BOOTSTRAP_OUTPUT) 34 + LIBBPF_BOOTSTRAP_INCLUDE := $(LIBBPF_BOOTSTRAP_DESTDIR)/include 35 + LIBBPF_BOOTSTRAP_HDRS_DIR := $(LIBBPF_BOOTSTRAP_INCLUDE)/bpf 36 + LIBBPF_BOOTSTRAP := $(LIBBPF_BOOTSTRAP_OUTPUT)libbpf.a 33 37 34 38 # We need to copy hashmap.h and nlattr.h which is not otherwise exported by 35 39 # libbpf, but still required by bpftool. 36 40 LIBBPF_INTERNAL_HDRS := $(addprefix $(LIBBPF_HDRS_DIR)/,hashmap.h nlattr.h) 41 + LIBBPF_BOOTSTRAP_INTERNAL_HDRS := $(addprefix $(LIBBPF_BOOTSTRAP_HDRS_DIR)/,hashmap.h) 37 42 38 43 ifeq ($(BPFTOOL_VERSION),) 39 44 BPFTOOL_VERSION := $(shell make -rR --no-print-directory -sC ../../.. kernelversion) 40 45 endif 41 46 42 - $(LIBBPF_OUTPUT) $(BOOTSTRAP_OUTPUT) $(LIBBPF_BOOTSTRAP_OUTPUT) $(LIBBPF_HDRS_DIR): 47 + $(LIBBPF_OUTPUT) $(BOOTSTRAP_OUTPUT) $(LIBBPF_BOOTSTRAP_OUTPUT) $(LIBBPF_HDRS_DIR) $(LIBBPF_BOOTSTRAP_HDRS_DIR): 43 48 $(QUIET_MKDIR)mkdir -p $@ 44 49 45 50 $(LIBBPF): $(wildcard $(BPF_DIR)/*.[ch] $(BPF_DIR)/Makefile) | $(LIBBPF_OUTPUT) ··· 57 52 58 53 $(LIBBPF_BOOTSTRAP): $(wildcard $(BPF_DIR)/*.[ch] $(BPF_DIR)/Makefile) | $(LIBBPF_BOOTSTRAP_OUTPUT) 59 54 $(Q)$(MAKE) -C $(BPF_DIR) OUTPUT=$(LIBBPF_BOOTSTRAP_OUTPUT) \ 60 - ARCH= CC=$(HOSTCC) LD=$(HOSTLD) $@ 55 + DESTDIR=$(LIBBPF_BOOTSTRAP_DESTDIR) prefix= \ 56 + ARCH= CC=$(HOSTCC) LD=$(HOSTLD) $@ install_headers 57 + 58 + $(LIBBPF_BOOTSTRAP_INTERNAL_HDRS): $(LIBBPF_BOOTSTRAP_HDRS_DIR)/%.h: $(BPF_DIR)/%.h | $(LIBBPF_BOOTSTRAP_HDRS_DIR) 59 + $(call QUIET_INSTALL, $@) 60 + $(Q)install -m 644 -t $(LIBBPF_BOOTSTRAP_HDRS_DIR) $< 61 61 62 62 $(LIBBPF)-clean: FORCE | $(LIBBPF_OUTPUT) 63 63 $(call QUIET_CLEAN, libbpf) ··· 182 172 $(Q)cp "$(VMLINUX_H)" $@ 183 173 endif 184 174 185 - $(OUTPUT)%.bpf.o: skeleton/%.bpf.c $(OUTPUT)vmlinux.h $(LIBBPF) 175 + $(OUTPUT)%.bpf.o: skeleton/%.bpf.c $(OUTPUT)vmlinux.h $(LIBBPF_BOOTSTRAP) 186 176 $(QUIET_CLANG)$(CLANG) \ 187 177 -I$(if $(OUTPUT),$(OUTPUT),.) \ 188 178 -I$(srctree)/tools/include/uapi/ \ 189 - -I$(LIBBPF_INCLUDE) \ 179 + -I$(LIBBPF_BOOTSTRAP_INCLUDE) \ 190 180 -g -O2 -Wall -target bpf -c $< -o $@ && $(LLVM_STRIP) -g $@ 191 181 192 182 $(OUTPUT)%.skel.h: $(OUTPUT)%.bpf.o $(BPFTOOL_BOOTSTRAP) ··· 219 209 $(OUTPUT)bpftool: $(OBJS) $(LIBBPF) 220 210 $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) 221 211 222 - $(BOOTSTRAP_OUTPUT)%.o: %.c $(LIBBPF_INTERNAL_HDRS) | $(BOOTSTRAP_OUTPUT) 223 - $(QUIET_CC)$(HOSTCC) $(CFLAGS) -c -MMD -o $@ $< 212 + $(BOOTSTRAP_OUTPUT)%.o: %.c $(LIBBPF_BOOTSTRAP_INTERNAL_HDRS) | $(BOOTSTRAP_OUTPUT) 213 + $(QUIET_CC)$(HOSTCC) \ 214 + $(subst -I$(LIBBPF_INCLUDE),-I$(LIBBPF_BOOTSTRAP_INCLUDE),$(CFLAGS)) \ 215 + -c -MMD -o $@ $< 224 216 225 217 $(OUTPUT)%.o: %.c 226 218 $(QUIET_CC)$(CC) $(CFLAGS) -c -MMD -o $@ $< ··· 269 257 FORCE: 270 258 271 259 .SECONDARY: 272 - .PHONY: all FORCE clean install-bin install uninstall 260 + .PHONY: all FORCE bootstrap clean install-bin install uninstall 273 261 .PHONY: doc doc-clean doc-install doc-uninstall 274 262 .DEFAULT_GOAL := all
+3 -1
tools/lib/bpf/bpf.c
··· 515 515 int bpf_map_lookup_and_delete_elem_flags(int fd, const void *key, void *value, __u64 flags) 516 516 { 517 517 union bpf_attr attr; 518 + int ret; 518 519 519 520 memset(&attr, 0, sizeof(attr)); 520 521 attr.map_fd = fd; ··· 523 522 attr.value = ptr_to_u64(value); 524 523 attr.flags = flags; 525 524 526 - return sys_bpf(BPF_MAP_LOOKUP_AND_DELETE_ELEM, &attr, sizeof(attr)); 525 + ret = sys_bpf(BPF_MAP_LOOKUP_AND_DELETE_ELEM, &attr, sizeof(attr)); 526 + return libbpf_err_errno(ret); 527 527 } 528 528 529 529 int bpf_map_delete_elem(int fd, const void *key)
+1 -1
tools/testing/selftests/bpf/prog_tests/netcnt.c
··· 8 8 9 9 #define CG_NAME "/netcnt" 10 10 11 - void test_netcnt(void) 11 + void serial_test_netcnt(void) 12 12 { 13 13 union percpu_net_cnt *percpu_netcnt = NULL; 14 14 struct bpf_cgroup_storage_key key;
+74 -11
tools/testing/selftests/bpf/prog_tests/test_bpffs.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* Copyright (c) 2020 Facebook */ 3 3 #define _GNU_SOURCE 4 + #include <stdio.h> 4 5 #include <sched.h> 5 6 #include <sys/mount.h> 6 7 #include <sys/stat.h> ··· 30 29 31 30 static int fn(void) 32 31 { 33 - int err, duration = 0; 32 + struct stat a, b, c; 33 + int err, map; 34 34 35 35 err = unshare(CLONE_NEWNS); 36 - if (CHECK(err, "unshare", "failed: %d\n", errno)) 36 + if (!ASSERT_OK(err, "unshare")) 37 37 goto out; 38 38 39 39 err = mount("", "/", "", MS_REC | MS_PRIVATE, NULL); 40 - if (CHECK(err, "mount /", "failed: %d\n", errno)) 40 + if (!ASSERT_OK(err, "mount /")) 41 41 goto out; 42 42 43 43 err = umount(TDIR); 44 - if (CHECK(err, "umount " TDIR, "failed: %d\n", errno)) 44 + if (!ASSERT_OK(err, "umount " TDIR)) 45 45 goto out; 46 46 47 47 err = mount("none", TDIR, "tmpfs", 0, NULL); 48 - if (CHECK(err, "mount", "mount root failed: %d\n", errno)) 48 + if (!ASSERT_OK(err, "mount tmpfs")) 49 49 goto out; 50 50 51 51 err = mkdir(TDIR "/fs1", 0777); 52 - if (CHECK(err, "mkdir "TDIR"/fs1", "failed: %d\n", errno)) 52 + if (!ASSERT_OK(err, "mkdir " TDIR "/fs1")) 53 53 goto out; 54 54 err = mkdir(TDIR "/fs2", 0777); 55 - if (CHECK(err, "mkdir "TDIR"/fs2", "failed: %d\n", errno)) 55 + if (!ASSERT_OK(err, "mkdir " TDIR "/fs2")) 56 56 goto out; 57 57 58 58 err = mount("bpf", TDIR "/fs1", "bpf", 0, NULL); 59 - if (CHECK(err, "mount bpffs "TDIR"/fs1", "failed: %d\n", errno)) 59 + if (!ASSERT_OK(err, "mount bpffs " TDIR "/fs1")) 60 60 goto out; 61 61 err = mount("bpf", TDIR "/fs2", "bpf", 0, NULL); 62 - if (CHECK(err, "mount bpffs " TDIR "/fs2", "failed: %d\n", errno)) 62 + if (!ASSERT_OK(err, "mount bpffs " TDIR "/fs2")) 63 63 goto out; 64 64 65 65 err = read_iter(TDIR "/fs1/maps.debug"); 66 - if (CHECK(err, "reading " TDIR "/fs1/maps.debug", "failed\n")) 66 + if (!ASSERT_OK(err, "reading " TDIR "/fs1/maps.debug")) 67 67 goto out; 68 68 err = read_iter(TDIR "/fs2/progs.debug"); 69 - if (CHECK(err, "reading " TDIR "/fs2/progs.debug", "failed\n")) 69 + if (!ASSERT_OK(err, "reading " TDIR "/fs2/progs.debug")) 70 70 goto out; 71 + 72 + err = mkdir(TDIR "/fs1/a", 0777); 73 + if (!ASSERT_OK(err, "creating " TDIR "/fs1/a")) 74 + goto out; 75 + err = mkdir(TDIR "/fs1/a/1", 0777); 76 + if (!ASSERT_OK(err, "creating " TDIR "/fs1/a/1")) 77 + goto out; 78 + err = mkdir(TDIR "/fs1/b", 0777); 79 + if (!ASSERT_OK(err, "creating " TDIR "/fs1/b")) 80 + goto out; 81 + 82 + map = bpf_create_map(BPF_MAP_TYPE_ARRAY, 4, 4, 1, 0); 83 + if (!ASSERT_GT(map, 0, "create_map(ARRAY)")) 84 + goto out; 85 + err = bpf_obj_pin(map, TDIR "/fs1/c"); 86 + if (!ASSERT_OK(err, "pin map")) 87 + goto out; 88 + close(map); 89 + 90 + /* Check that RENAME_EXCHANGE works for directories. */ 91 + err = stat(TDIR "/fs1/a", &a); 92 + if (!ASSERT_OK(err, "stat(" TDIR "/fs1/a)")) 93 + goto out; 94 + err = renameat2(0, TDIR "/fs1/a", 0, TDIR "/fs1/b", RENAME_EXCHANGE); 95 + if (!ASSERT_OK(err, "renameat2(/fs1/a, /fs1/b, RENAME_EXCHANGE)")) 96 + goto out; 97 + err = stat(TDIR "/fs1/b", &b); 98 + if (!ASSERT_OK(err, "stat(" TDIR "/fs1/b)")) 99 + goto out; 100 + if (!ASSERT_EQ(a.st_ino, b.st_ino, "b should have a's inode")) 101 + goto out; 102 + err = access(TDIR "/fs1/b/1", F_OK); 103 + if (!ASSERT_OK(err, "access(" TDIR "/fs1/b/1)")) 104 + goto out; 105 + 106 + /* Check that RENAME_EXCHANGE works for mixed file types. */ 107 + err = stat(TDIR "/fs1/c", &c); 108 + if (!ASSERT_OK(err, "stat(" TDIR "/fs1/map)")) 109 + goto out; 110 + err = renameat2(0, TDIR "/fs1/c", 0, TDIR "/fs1/b", RENAME_EXCHANGE); 111 + if (!ASSERT_OK(err, "renameat2(/fs1/c, /fs1/b, RENAME_EXCHANGE)")) 112 + goto out; 113 + err = stat(TDIR "/fs1/b", &b); 114 + if (!ASSERT_OK(err, "stat(" TDIR "/fs1/b)")) 115 + goto out; 116 + if (!ASSERT_EQ(c.st_ino, b.st_ino, "b should have c's inode")) 117 + goto out; 118 + err = access(TDIR "/fs1/c/1", F_OK); 119 + if (!ASSERT_OK(err, "access(" TDIR "/fs1/c/1)")) 120 + goto out; 121 + 122 + /* Check that RENAME_NOREPLACE works. */ 123 + err = renameat2(0, TDIR "/fs1/b", 0, TDIR "/fs1/a", RENAME_NOREPLACE); 124 + if (!ASSERT_ERR(err, "renameat2(RENAME_NOREPLACE)")) { 125 + err = -EINVAL; 126 + goto out; 127 + } 128 + err = access(TDIR "/fs1/b", F_OK); 129 + if (!ASSERT_OK(err, "access(" TDIR "/fs1/b)")) 130 + goto out; 131 + 71 132 out: 72 133 umount(TDIR "/fs1"); 73 134 umount(TDIR "/fs2");
+35 -27
tools/testing/selftests/bpf/test_xdp_redirect_multi.sh
··· 2 2 # SPDX-License-Identifier: GPL-2.0 3 3 # 4 4 # Test topology: 5 - # - - - - - - - - - - - - - - - - - - - - - - - - - 6 - # | veth1 veth2 veth3 | ... init net 5 + # - - - - - - - - - - - - - - - - - - - 6 + # | veth1 veth2 veth3 | ns0 7 7 # - -| - - - - - - | - - - - - - | - - 8 8 # --------- --------- --------- 9 - # | veth0 | | veth0 | | veth0 | ... 9 + # | veth0 | | veth0 | | veth0 | 10 10 # --------- --------- --------- 11 11 # ns1 ns2 ns3 12 12 # ··· 31 31 DRV_MODE="xdpgeneric xdpdrv xdpegress" 32 32 PASS=0 33 33 FAIL=0 34 + LOG_DIR=$(mktemp -d) 34 35 35 36 test_pass() 36 37 { ··· 51 50 ip link del veth$i 2> /dev/null 52 51 ip netns del ns$i 2> /dev/null 53 52 done 53 + ip netns del ns0 2> /dev/null 54 54 } 55 55 56 56 # Kselftest framework requirement - SKIP code is 4. ··· 79 77 mode="xdpdrv" 80 78 fi 81 79 80 + ip netns add ns0 82 81 for i in $(seq $NUM); do 83 82 ip netns add ns$i 84 - ip link add veth$i type veth peer name veth0 netns ns$i 85 - ip link set veth$i up 83 + ip -n ns$i link add veth0 index 2 type veth \ 84 + peer name veth$i netns ns0 index $((1 + $i)) 85 + ip -n ns0 link set veth$i up 86 86 ip -n ns$i link set veth0 up 87 87 88 88 ip -n ns$i addr add 192.0.2.$i/24 dev veth0 ··· 95 91 xdp_dummy.o sec xdp &> /dev/null || \ 96 92 { test_fail "Unable to load dummy xdp" && exit 1; } 97 93 IFACES="$IFACES veth$i" 98 - veth_mac[$i]=$(ip link show veth$i | awk '/link\/ether/ {print $2}') 94 + veth_mac[$i]=$(ip -n ns0 link show veth$i | awk '/link\/ether/ {print $2}') 99 95 done 100 96 } 101 97 ··· 104 100 local mode=$1 105 101 106 102 # mac test 107 - ip netns exec ns2 tcpdump -e -i veth0 -nn -l -e &> mac_ns1-2_${mode}.log & 108 - ip netns exec ns3 tcpdump -e -i veth0 -nn -l -e &> mac_ns1-3_${mode}.log & 103 + ip netns exec ns2 tcpdump -e -i veth0 -nn -l -e &> ${LOG_DIR}/mac_ns1-2_${mode}.log & 104 + ip netns exec ns3 tcpdump -e -i veth0 -nn -l -e &> ${LOG_DIR}/mac_ns1-3_${mode}.log & 109 105 sleep 0.5 110 106 ip netns exec ns1 ping 192.0.2.254 -i 0.1 -c 4 &> /dev/null 111 107 sleep 0.5 112 - pkill -9 tcpdump 108 + pkill tcpdump 113 109 114 110 # mac check 115 - grep -q "${veth_mac[2]} > ff:ff:ff:ff:ff:ff" mac_ns1-2_${mode}.log && \ 111 + grep -q "${veth_mac[2]} > ff:ff:ff:ff:ff:ff" ${LOG_DIR}/mac_ns1-2_${mode}.log && \ 116 112 test_pass "$mode mac ns1-2" || test_fail "$mode mac ns1-2" 117 - grep -q "${veth_mac[3]} > ff:ff:ff:ff:ff:ff" mac_ns1-3_${mode}.log && \ 113 + grep -q "${veth_mac[3]} > ff:ff:ff:ff:ff:ff" ${LOG_DIR}/mac_ns1-3_${mode}.log && \ 118 114 test_pass "$mode mac ns1-3" || test_fail "$mode mac ns1-3" 119 115 } 120 116 ··· 125 121 # ping6 test: echo request should be redirect back to itself, not others 126 122 ip netns exec ns1 ip neigh add 2001:db8::2 dev veth0 lladdr 00:00:00:00:00:02 127 123 128 - ip netns exec ns1 tcpdump -i veth0 -nn -l -e &> ns1-1_${mode}.log & 129 - ip netns exec ns2 tcpdump -i veth0 -nn -l -e &> ns1-2_${mode}.log & 130 - ip netns exec ns3 tcpdump -i veth0 -nn -l -e &> ns1-3_${mode}.log & 124 + ip netns exec ns1 tcpdump -i veth0 -nn -l -e &> ${LOG_DIR}/ns1-1_${mode}.log & 125 + ip netns exec ns2 tcpdump -i veth0 -nn -l -e &> ${LOG_DIR}/ns1-2_${mode}.log & 126 + ip netns exec ns3 tcpdump -i veth0 -nn -l -e &> ${LOG_DIR}/ns1-3_${mode}.log & 131 127 sleep 0.5 132 128 # ARP test 133 - ip netns exec ns1 ping 192.0.2.254 -i 0.1 -c 4 &> /dev/null 129 + ip netns exec ns1 arping -q -c 2 -I veth0 192.0.2.254 134 130 # IPv4 test 135 131 ip netns exec ns1 ping 192.0.2.253 -i 0.1 -c 4 &> /dev/null 136 132 # IPv6 test 137 133 ip netns exec ns1 ping6 2001:db8::2 -i 0.1 -c 2 &> /dev/null 138 134 sleep 0.5 139 - pkill -9 tcpdump 135 + pkill tcpdump 140 136 141 137 # All netns should receive the redirect arp requests 142 - [ $(grep -c "who-has 192.0.2.254" ns1-1_${mode}.log) -gt 4 ] && \ 138 + [ $(grep -cF "who-has 192.0.2.254" ${LOG_DIR}/ns1-1_${mode}.log) -eq 4 ] && \ 143 139 test_pass "$mode arp(F_BROADCAST) ns1-1" || \ 144 140 test_fail "$mode arp(F_BROADCAST) ns1-1" 145 - [ $(grep -c "who-has 192.0.2.254" ns1-2_${mode}.log) -le 4 ] && \ 141 + [ $(grep -cF "who-has 192.0.2.254" ${LOG_DIR}/ns1-2_${mode}.log) -eq 2 ] && \ 146 142 test_pass "$mode arp(F_BROADCAST) ns1-2" || \ 147 143 test_fail "$mode arp(F_BROADCAST) ns1-2" 148 - [ $(grep -c "who-has 192.0.2.254" ns1-3_${mode}.log) -le 4 ] && \ 144 + [ $(grep -cF "who-has 192.0.2.254" ${LOG_DIR}/ns1-3_${mode}.log) -eq 2 ] && \ 149 145 test_pass "$mode arp(F_BROADCAST) ns1-3" || \ 150 146 test_fail "$mode arp(F_BROADCAST) ns1-3" 151 147 152 148 # ns1 should not receive the redirect echo request, others should 153 - [ $(grep -c "ICMP echo request" ns1-1_${mode}.log) -eq 4 ] && \ 149 + [ $(grep -c "ICMP echo request" ${LOG_DIR}/ns1-1_${mode}.log) -eq 4 ] && \ 154 150 test_pass "$mode IPv4 (F_BROADCAST|F_EXCLUDE_INGRESS) ns1-1" || \ 155 151 test_fail "$mode IPv4 (F_BROADCAST|F_EXCLUDE_INGRESS) ns1-1" 156 - [ $(grep -c "ICMP echo request" ns1-2_${mode}.log) -eq 4 ] && \ 152 + [ $(grep -c "ICMP echo request" ${LOG_DIR}/ns1-2_${mode}.log) -eq 4 ] && \ 157 153 test_pass "$mode IPv4 (F_BROADCAST|F_EXCLUDE_INGRESS) ns1-2" || \ 158 154 test_fail "$mode IPv4 (F_BROADCAST|F_EXCLUDE_INGRESS) ns1-2" 159 - [ $(grep -c "ICMP echo request" ns1-3_${mode}.log) -eq 4 ] && \ 155 + [ $(grep -c "ICMP echo request" ${LOG_DIR}/ns1-3_${mode}.log) -eq 4 ] && \ 160 156 test_pass "$mode IPv4 (F_BROADCAST|F_EXCLUDE_INGRESS) ns1-3" || \ 161 157 test_fail "$mode IPv4 (F_BROADCAST|F_EXCLUDE_INGRESS) ns1-3" 162 158 163 159 # ns1 should receive the echo request, ns2 should not 164 - [ $(grep -c "ICMP6, echo request" ns1-1_${mode}.log) -eq 4 ] && \ 160 + [ $(grep -c "ICMP6, echo request" ${LOG_DIR}/ns1-1_${mode}.log) -eq 4 ] && \ 165 161 test_pass "$mode IPv6 (no flags) ns1-1" || \ 166 162 test_fail "$mode IPv6 (no flags) ns1-1" 167 - [ $(grep -c "ICMP6, echo request" ns1-2_${mode}.log) -eq 0 ] && \ 163 + [ $(grep -c "ICMP6, echo request" ${LOG_DIR}/ns1-2_${mode}.log) -eq 0 ] && \ 168 164 test_pass "$mode IPv6 (no flags) ns1-2" || \ 169 165 test_fail "$mode IPv6 (no flags) ns1-2" 170 166 } ··· 180 176 xdpgeneric) drv_p="-S";; 181 177 esac 182 178 183 - ./xdp_redirect_multi $drv_p $IFACES &> xdp_redirect_${mode}.log & 179 + ip netns exec ns0 ./xdp_redirect_multi $drv_p $IFACES &> ${LOG_DIR}/xdp_redirect_${mode}.log & 184 180 xdp_pid=$! 185 181 sleep 1 182 + if ! ps -p $xdp_pid > /dev/null; then 183 + test_fail "$mode xdp_redirect_multi start failed" 184 + return 1 185 + fi 186 186 187 187 if [ "$mode" = "xdpegress" ]; then 188 188 do_egress_tests $mode ··· 197 189 kill $xdp_pid 198 190 } 199 191 200 - trap clean_up 0 2 3 6 9 192 + trap clean_up EXIT 201 193 202 194 check_env 203 - rm -f xdp_redirect_*.log ns*.log mac_ns*.log 204 195 205 196 for mode in ${DRV_MODE}; do 206 197 setup_ns $mode 207 198 do_tests $mode 208 199 clean_up 209 200 done 201 + rm -rf ${LOG_DIR} 210 202 211 203 echo "Summary: PASS $PASS, FAIL $FAIL" 212 204 [ $FAIL -eq 0 ] && exit 0 || exit 1
+17
tools/testing/selftests/bpf/verifier/spill_fill.c
··· 265 265 .result = ACCEPT, 266 266 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 267 267 }, 268 + { 269 + "Spill a u32 scalar at fp-4 and then at fp-8", 270 + .insns = { 271 + /* r4 = 4321 */ 272 + BPF_MOV32_IMM(BPF_REG_4, 4321), 273 + /* *(u32 *)(r10 -4) = r4 */ 274 + BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_4, -4), 275 + /* *(u32 *)(r10 -8) = r4 */ 276 + BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_4, -8), 277 + /* r4 = *(u64 *)(r10 -8) */ 278 + BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8), 279 + BPF_MOV64_IMM(BPF_REG_0, 0), 280 + BPF_EXIT_INSN(), 281 + }, 282 + .result = ACCEPT, 283 + .prog_type = BPF_PROG_TYPE_SCHED_CLS, 284 + },
+2 -2
tools/testing/selftests/bpf/xdp_redirect_multi.c
··· 129 129 goto err_out; 130 130 } 131 131 132 - printf("Get interfaces"); 132 + printf("Get interfaces:"); 133 133 for (i = 0; i < MAX_IFACE_NUM && argv[optind + i]; i++) { 134 134 ifaces[i] = if_nametoindex(argv[optind + i]); 135 135 if (!ifaces[i]) ··· 139 139 goto err_out; 140 140 } 141 141 if (ifaces[i] > MAX_INDEX_NUM) { 142 - printf("Interface index to large\n"); 142 + printf(" interface index too large\n"); 143 143 goto err_out; 144 144 } 145 145 printf(" %d", ifaces[i]);
+4
tools/testing/selftests/net/reuseport_bpf_numa.c
··· 211 211 212 212 /* Forward iterate */ 213 213 for (node = 0; node < len; ++node) { 214 + if (!numa_bitmask_isbitset(numa_nodes_ptr, node)) 215 + continue; 214 216 send_from_node(node, family, proto); 215 217 receive_on_node(rcv_fd, len, epfd, node, proto); 216 218 } 217 219 218 220 /* Reverse iterate */ 219 221 for (node = len - 1; node >= 0; --node) { 222 + if (!numa_bitmask_isbitset(numa_nodes_ptr, node)) 223 + continue; 220 224 send_from_node(node, family, proto); 221 225 receive_on_node(rcv_fd, len, epfd, node, proto); 222 226 }