Daniel Borkmann says: ==================== pull-request: bpf-next 2019-09-16 The following pull-request contains BPF updates for your *net-next* tree. The main changes are: 1) Now that initial BPF backend for gcc has been merged upstream, enable BPF kselftest suite for bpf-gcc. Also fix a BE issue with access to bpf_sysctl.file_pos, from Ilya. 2) Follow-up fix for link-vmlinux.sh to remove bash-specific extensions related to recent work on exposing BTF info through sysfs, from Andrii. 3) AF_XDP zero copy fixes for i40e and ixgbe driver which caused umem headroom to be added twice, from Ciara. 4) Refactoring work to convert sock opt tests into test_progs framework in BPF kselftests, from Stanislav. 5) Fix a general protection fault in dev_map_hash_update_elem(), from Toke. 6) Cleanup to use BPF_PROG_RUN() macro in KCM, from Sami. ====================
Unified · Split
| @@ -197,9 +197,9 @@ static int i40e_run_xdp_zc(struct i40e_ring *rx_ring, struct xdp_buff *xdp) · 196 unmodified lines | |||
| 197 | { | 197 | { |
| 198 | struct xdp_umem *umem = rx_ring->xsk_umem; | 198 | struct xdp_umem *umem = rx_ring->xsk_umem; |
| 199 | int err, result = I40E_XDP_PASS; | 199 | int err, result = I40E_XDP_PASS; |
| 200 | u64 offset = umem->headroom; | ||
| 201 | struct i40e_ring *xdp_ring; | 200 | struct i40e_ring *xdp_ring; |
| 202 | struct bpf_prog *xdp_prog; | 201 | struct bpf_prog *xdp_prog; |
| 202 | u64 offset; | ||
| 203 | u32 act; | 203 | u32 act; |
| 204 | 204 | ||
| 205 | rcu_read_lock(); | 205 | rcu_read_lock(); |
| @@ -208,7 +208,7 @@ static int i40e_run_xdp_zc(struct i40e_ring *rx_ring, struct xdp_buff *xdp) · 2 unmodified lines | |||
| 208 | */ | 208 | */ |
| 209 | xdp_prog = READ_ONCE(rx_ring->xdp_prog); | 209 | xdp_prog = READ_ONCE(rx_ring->xdp_prog); |
| 210 | act = bpf_prog_run_xdp(xdp_prog, xdp); | 210 | act = bpf_prog_run_xdp(xdp_prog, xdp); |
| 211 | offset += xdp->data - xdp->data_hard_start; | 211 | offset = xdp->data - xdp->data_hard_start; |
| 212 | 212 | ||
| 213 | xdp->handle = xsk_umem_adjust_offset(umem, xdp->handle, offset); | 213 | xdp->handle = xsk_umem_adjust_offset(umem, xdp->handle, offset); |
| 214 | 214 | ||
| @@ -145,15 +145,15 @@ static int ixgbe_run_xdp_zc(struct ixgbe_adapter *adapter, · 144 unmodified lines | |||
| 145 | { | 145 | { |
| 146 | struct xdp_umem *umem = rx_ring->xsk_umem; | 146 | struct xdp_umem *umem = rx_ring->xsk_umem; |
| 147 | int err, result = IXGBE_XDP_PASS; | 147 | int err, result = IXGBE_XDP_PASS; |
| 148 | u64 offset = umem->headroom; | ||
| 149 | struct bpf_prog *xdp_prog; | 148 | struct bpf_prog *xdp_prog; |
| 150 | struct xdp_frame *xdpf; | 149 | struct xdp_frame *xdpf; |
| 150 | u64 offset; | ||
| 151 | u32 act; | 151 | u32 act; |
| 152 | 152 | ||
| 153 | rcu_read_lock(); | 153 | rcu_read_lock(); |
| 154 | xdp_prog = READ_ONCE(rx_ring->xdp_prog); | 154 | xdp_prog = READ_ONCE(rx_ring->xdp_prog); |
| 155 | act = bpf_prog_run_xdp(xdp_prog, xdp); | 155 | act = bpf_prog_run_xdp(xdp_prog, xdp); |
| 156 | offset += xdp->data - xdp->data_hard_start; | 156 | offset = xdp->data - xdp->data_hard_start; |
| 157 | 157 | ||
| 158 | xdp->handle = xsk_umem_adjust_offset(umem, xdp->handle, offset); | 158 | xdp->handle = xsk_umem_adjust_offset(umem, xdp->handle, offset); |
| 159 | 159 | ||
| @@ -749,14 +749,14 @@ bpf_ctx_narrow_access_ok(u32 off, u32 size, u32 size_default) · 748 unmodified lines | |||
| 749 | } | 749 | } |
| 750 | 750 | ||
| 751 | static inline u8 | 751 | static inline u8 |
| 752 | bpf_ctx_narrow_load_shift(u32 off, u32 size, u32 size_default) | 752 | bpf_ctx_narrow_access_offset(u32 off, u32 size, u32 size_default) |
| 753 | { | 753 | { |
| 754 | u8 load_off = off & (size_default - 1); | 754 | u8 access_off = off & (size_default - 1); |
| 755 | 755 | ||
| 756 | #ifdef __LITTLE_ENDIAN | 756 | #ifdef __LITTLE_ENDIAN |
| 757 | return load_off * 8; | 757 | return access_off; |
| 758 | #else | 758 | #else |
| 759 | return (size_default - (load_off + size)) * 8; | 759 | return size_default - (access_off + size); |
| 760 | #endif | 760 | #endif |
| 761 | } | 761 | } |
| 762 | 762 | ||
| @@ -1334,6 +1334,7 @@ static u32 sysctl_convert_ctx_access(enum bpf_access_type type, · 1333 unmodified lines | |||
| 1334 | struct bpf_prog *prog, u32 *target_size) | 1334 | struct bpf_prog *prog, u32 *target_size) |
| 1335 | { | 1335 | { |
| 1336 | struct bpf_insn *insn = insn_buf; | 1336 | struct bpf_insn *insn = insn_buf; |
| 1337 | u32 read_size; | ||
| 1337 | 1338 | ||
| 1338 | switch (si->off) { | 1339 | switch (si->off) { |
| 1339 | case offsetof(struct bpf_sysctl, write): | 1340 | case offsetof(struct bpf_sysctl, write): |
| @@ -1365,7 +1366,9 @@ static u32 sysctl_convert_ctx_access(enum bpf_access_type type, · 25 unmodified lines | |||
| 1365 | treg, si->dst_reg, | 1366 | treg, si->dst_reg, |
| 1366 | offsetof(struct bpf_sysctl_kern, ppos)); | 1367 | offsetof(struct bpf_sysctl_kern, ppos)); |
| 1367 | *insn++ = BPF_STX_MEM( | 1368 | *insn++ = BPF_STX_MEM( |
| 1368 | BPF_SIZEOF(u32), treg, si->src_reg, 0); | 1369 | BPF_SIZEOF(u32), treg, si->src_reg, |
| 1370 | bpf_ctx_narrow_access_offset( | ||
| 1371 | 0, sizeof(u32), sizeof(loff_t))); | ||
| 1369 | *insn++ = BPF_LDX_MEM( | 1372 | *insn++ = BPF_LDX_MEM( |
| 1370 | BPF_DW, treg, si->dst_reg, | 1373 | BPF_DW, treg, si->dst_reg, |
| 1371 | offsetof(struct bpf_sysctl_kern, tmp_reg)); | 1374 | offsetof(struct bpf_sysctl_kern, tmp_reg)); |
| @@ -1374,8 +1377,11 @@ static u32 sysctl_convert_ctx_access(enum bpf_access_type type, · 2 unmodified lines | |||
| 1374 | BPF_FIELD_SIZEOF(struct bpf_sysctl_kern, ppos), | 1377 | BPF_FIELD_SIZEOF(struct bpf_sysctl_kern, ppos), |
| 1375 | si->dst_reg, si->src_reg, | 1378 | si->dst_reg, si->src_reg, |
| 1376 | offsetof(struct bpf_sysctl_kern, ppos)); | 1379 | offsetof(struct bpf_sysctl_kern, ppos)); |
| 1380 | read_size = bpf_size_to_bytes(BPF_SIZE(si->code)); | ||
| 1377 | *insn++ = BPF_LDX_MEM( | 1381 | *insn++ = BPF_LDX_MEM( |
| 1378 | BPF_SIZE(si->code), si->dst_reg, si->dst_reg, 0); | 1382 | BPF_SIZE(si->code), si->dst_reg, si->dst_reg, |
| 1383 | bpf_ctx_narrow_access_offset( | ||
| 1384 | 0, read_size, sizeof(loff_t))); | ||
| 1379 | } | 1385 | } |
| 1380 | *target_size = sizeof(u32); | 1386 | *target_size = sizeof(u32); |
| 1381 | break; | 1387 | break; |
| @@ -650,19 +650,22 @@ static int __dev_map_hash_update_elem(struct net *net, struct bpf_map *map, · 649 unmodified lines | |||
| 650 | u32 ifindex = *(u32 *)value; | 650 | u32 ifindex = *(u32 *)value; |
| 651 | u32 idx = *(u32 *)key; | 651 | u32 idx = *(u32 *)key; |
| 652 | unsigned long flags; | 652 | unsigned long flags; |
| 653 | int err = -EEXIST; | ||
| 653 | 654 | ||
| 654 | if (unlikely(map_flags > BPF_EXIST || !ifindex)) | 655 | if (unlikely(map_flags > BPF_EXIST || !ifindex)) |
| 655 | return -EINVAL; | 656 | return -EINVAL; |
| 656 | 657 | ||
| 658 | spin_lock_irqsave(&dtab->index_lock, flags); | ||
| 659 | |||
| 657 | old_dev = __dev_map_hash_lookup_elem(map, idx); | 660 | old_dev = __dev_map_hash_lookup_elem(map, idx); |
| 658 | if (old_dev && (map_flags & BPF_NOEXIST)) | 661 | if (old_dev && (map_flags & BPF_NOEXIST)) |
| 659 | return -EEXIST; | 662 | goto out_err; |
| 660 | 663 | ||
| 661 | dev = __dev_map_alloc_node(net, dtab, ifindex, idx); | 664 | dev = __dev_map_alloc_node(net, dtab, ifindex, idx); |
| 662 | if (IS_ERR(dev)) | 665 | if (IS_ERR(dev)) { |
| 663 | return PTR_ERR(dev); | 666 | err = PTR_ERR(dev); |
| 664 | 667 | goto out_err; | |
| 665 | spin_lock_irqsave(&dtab->index_lock, flags); | 668 | } |
| 666 | 669 | ||
| 667 | if (old_dev) { | 670 | if (old_dev) { |
| 668 | hlist_del_rcu(&old_dev->index_hlist); | 671 | hlist_del_rcu(&old_dev->index_hlist); |
| @@ -683,6 +686,10 @@ static int __dev_map_hash_update_elem(struct net *net, struct bpf_map *map, · 14 unmodified lines | |||
| 683 | call_rcu(&old_dev->rcu, __dev_map_entry_free); | 686 | call_rcu(&old_dev->rcu, __dev_map_entry_free); |
| 684 | 687 | ||
| 685 | return 0; | 688 | return 0; |
| 689 | |||
| 690 | out_err: | ||
| 691 | spin_unlock_irqrestore(&dtab->index_lock, flags); | ||
| 692 | return err; | ||
| 686 | } | 693 | } |
| 687 | 694 | ||
| 688 | static int dev_map_hash_update_elem(struct bpf_map *map, void *key, void *value, | 695 | static int dev_map_hash_update_elem(struct bpf_map *map, void *key, void *value, |
| @@ -8624,8 +8624,8 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env) · 8623 unmodified lines | |||
| 8624 | } | 8624 | } |
| 8625 | 8625 | ||
| 8626 | if (is_narrower_load && size < target_size) { | 8626 | if (is_narrower_load && size < target_size) { |
| 8627 | u8 shift = bpf_ctx_narrow_load_shift(off, size, | 8627 | u8 shift = bpf_ctx_narrow_access_offset( |
| 8628 | size_default); | 8628 | off, size, size_default) * 8; |
| 8629 | if (ctx_field_size <= 4) { | 8629 | if (ctx_field_size <= 4) { |
| 8630 | if (shift) | 8630 | if (shift) |
| 8631 | insn_buf[cnt++] = BPF_ALU32_IMM(BPF_RSH, | 8631 | insn_buf[cnt++] = BPF_ALU32_IMM(BPF_RSH, |
| @@ -379,7 +379,7 @@ static int kcm_parse_func_strparser(struct strparser *strp, struct sk_buff *skb) · 378 unmodified lines | |||
| 379 | struct kcm_psock *psock = container_of(strp, struct kcm_psock, strp); | 379 | struct kcm_psock *psock = container_of(strp, struct kcm_psock, strp); |
| 380 | struct bpf_prog *prog = psock->bpf_prog; | 380 | struct bpf_prog *prog = psock->bpf_prog; |
| 381 | 381 | ||
| 382 | return (*prog->bpf_func)(skb, prog->insnsi); | 382 | return BPF_PROG_RUN(prog, skb); |
| 383 | } | 383 | } |
| 384 | 384 | ||
| 385 | static int kcm_read_sock_done(struct strparser *strp, int err) | 385 | static int kcm_read_sock_done(struct strparser *strp, int err) |
| @@ -685,7 +685,7 @@ static void l2fwd(struct xsk_socket_info *xsk, struct pollfd *fds) · 684 unmodified lines | |||
| 685 | for (i = 0; i < rcvd; i++) { | 685 | for (i = 0; i < rcvd; i++) { |
| 686 | u64 addr = xsk_ring_cons__rx_desc(&xsk->rx, idx_rx)->addr; | 686 | u64 addr = xsk_ring_cons__rx_desc(&xsk->rx, idx_rx)->addr; |
| 687 | u32 len = xsk_ring_cons__rx_desc(&xsk->rx, idx_rx++)->len; | 687 | u32 len = xsk_ring_cons__rx_desc(&xsk->rx, idx_rx++)->len; |
| 688 | u64 orig = xsk_umem__extract_addr(addr); | 688 | u64 orig = addr; |
| 689 | 689 | ||
| 690 | addr = xsk_umem__add_offset_to_addr(addr); | 690 | addr = xsk_umem__add_offset_to_addr(addr); |
| 691 | char *pkt = xsk_umem__get_data(xsk->umem->buffer, addr); | 691 | char *pkt = xsk_umem__get_data(xsk->umem->buffer, addr); |
| @@ -57,12 +57,16 @@ modpost_link() · 56 unmodified lines | |||
| 57 | 57 | ||
| 58 | # Link of vmlinux | 58 | # Link of vmlinux |
| 59 | # ${1} - output file | 59 | # ${1} - output file |
| 60 | # ${@:2} - optional extra .o files | 60 | # ${2}, ${3}, ... - optional extra .o files |
| 61 | vmlinux_link() | 61 | vmlinux_link() |
| 62 | { | 62 | { |
| 63 | local lds="${objtree}/${KBUILD_LDS}" | 63 | local lds="${objtree}/${KBUILD_LDS}" |
| 64 | local output=${1} | ||
| 64 | local objects | 65 | local objects |
| 65 | 66 | ||
| 67 | # skip output file argument | ||
| 68 | shift | ||
| 69 | |||
| 66 | if [ "${SRCARCH}" != "um" ]; then | 70 | if [ "${SRCARCH}" != "um" ]; then |
| 67 | objects="--whole-archive \ | 71 | objects="--whole-archive \ |
| 68 | ${KBUILD_VMLINUX_OBJS} \ | 72 | ${KBUILD_VMLINUX_OBJS} \ |
| @@ -70,9 +74,10 @@ vmlinux_link() · 1 unmodified line | |||
| 70 | --start-group \ | 74 | --start-group \ |
| 71 | ${KBUILD_VMLINUX_LIBS} \ | 75 | ${KBUILD_VMLINUX_LIBS} \ |
| 72 | --end-group \ | 76 | --end-group \ |
| 73 | ${@:2}" | 77 | ${@}" |
| 74 | 78 | ||
| 75 | ${LD} ${KBUILD_LDFLAGS} ${LDFLAGS_vmlinux} -o ${1} \ | 79 | ${LD} ${KBUILD_LDFLAGS} ${LDFLAGS_vmlinux} \ |
| 80 | -o ${output} \ | ||
| 76 | -T ${lds} ${objects} | 81 | -T ${lds} ${objects} |
| 77 | else | 82 | else |
| 78 | objects="-Wl,--whole-archive \ | 83 | objects="-Wl,--whole-archive \ |
| @@ -81,9 +86,10 @@ vmlinux_link() · 2 unmodified lines | |||
| 81 | -Wl,--start-group \ | 86 | -Wl,--start-group \ |
| 82 | ${KBUILD_VMLINUX_LIBS} \ | 87 | ${KBUILD_VMLINUX_LIBS} \ |
| 83 | -Wl,--end-group \ | 88 | -Wl,--end-group \ |
| 84 | ${@:2}" | 89 | ${@}" |
| 85 | 90 | ||
| 86 | ${CC} ${CFLAGS_vmlinux} -o ${1} \ | 91 | ${CC} ${CFLAGS_vmlinux} \ |
| 92 | -o ${output} \ | ||
| 87 | -Wl,-T,${lds} \ | 93 | -Wl,-T,${lds} \ |
| 88 | ${objects} \ | 94 | ${objects} \ |
| 89 | -lutil -lrt -lpthread | 95 | -lutil -lrt -lpthread |
| @@ -39,8 +39,3 @@ libbpf.so.* · 38 unmodified lines | |||
| 39 | test_hashmap | 39 | test_hashmap |
| 40 | test_btf_dump | 40 | test_btf_dump |
| 41 | xdping | 41 | xdping |
| 42 | test_sockopt | ||
| 43 | test_sockopt_sk | ||
| 44 | test_sockopt_multi | ||
| 45 | test_sockopt_inherit | ||
| 46 | test_tcp_rtt | ||
| @@ -17,6 +17,7 @@ LLC ?= llc · 16 unmodified lines | |||
| 17 | LLVM_OBJCOPY ?= llvm-objcopy | 17 | LLVM_OBJCOPY ?= llvm-objcopy |
| 18 | LLVM_READELF ?= llvm-readelf | 18 | LLVM_READELF ?= llvm-readelf |
| 19 | BTF_PAHOLE ?= pahole | 19 | BTF_PAHOLE ?= pahole |
| 20 | BPF_GCC ?= $(shell command -v bpf-gcc;) | ||
| 20 | CFLAGS += -g -Wall -O2 -I$(APIDIR) -I$(LIBDIR) -I$(BPFDIR) -I$(GENDIR) $(GENFLAGS) -I../../../include \ | 21 | CFLAGS += -g -Wall -O2 -I$(APIDIR) -I$(LIBDIR) -I$(BPFDIR) -I$(GENDIR) $(GENFLAGS) -I../../../include \ |
| 21 | -Dbpf_prog_load=bpf_prog_test_load \ | 22 | -Dbpf_prog_load=bpf_prog_test_load \ |
| 22 | -Dbpf_load_program=bpf_test_load_program | 23 | -Dbpf_load_program=bpf_test_load_program |
| @@ -28,8 +29,7 @@ TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test · 5 unmodified lines | |||
| 28 | test_sock test_btf test_sockmap get_cgroup_id_user test_socket_cookie \ | 29 | test_sock test_btf test_sockmap get_cgroup_id_user test_socket_cookie \ |
| 29 | test_cgroup_storage test_select_reuseport test_section_names \ | 30 | test_cgroup_storage test_select_reuseport test_section_names \ |
| 30 | test_netcnt test_tcpnotify_user test_sock_fields test_sysctl test_hashmap \ | 31 | test_netcnt test_tcpnotify_user test_sock_fields test_sysctl test_hashmap \ |
| 31 | test_btf_dump test_cgroup_attach xdping test_sockopt test_sockopt_sk \ | 32 | test_btf_dump test_cgroup_attach xdping |
| 32 | test_sockopt_multi test_sockopt_inherit test_tcp_rtt | ||
| 33 | 33 | ||
| 34 | BPF_OBJ_FILES = $(patsubst %.c,%.o, $(notdir $(wildcard progs/*.c))) | 34 | BPF_OBJ_FILES = $(patsubst %.c,%.o, $(notdir $(wildcard progs/*.c))) |
| 35 | TEST_GEN_FILES = $(BPF_OBJ_FILES) | 35 | TEST_GEN_FILES = $(BPF_OBJ_FILES) |
| @@ -47,6 +47,10 @@ ifneq ($(SUBREG_CODEGEN),) · 11 unmodified lines | |||
| 47 | TEST_GEN_FILES += $(patsubst %.o,alu32/%.o, $(BPF_OBJ_FILES)) | 47 | TEST_GEN_FILES += $(patsubst %.o,alu32/%.o, $(BPF_OBJ_FILES)) |
| 48 | endif | 48 | endif |
| 49 | 49 | ||
| 50 | ifneq ($(BPF_GCC),) | ||
| 51 | TEST_GEN_FILES += $(patsubst %.o,bpf_gcc/%.o, $(BPF_OBJ_FILES)) | ||
| 52 | endif | ||
| 53 | |||
| 50 | # Order correspond to 'make run_tests' order | 54 | # Order correspond to 'make run_tests' order |
| 51 | TEST_PROGS := test_kmod.sh \ | 55 | TEST_PROGS := test_kmod.sh \ |
| 52 | test_libbpf.sh \ | 56 | test_libbpf.sh \ |
| @@ -106,18 +110,13 @@ $(OUTPUT)/test_socket_cookie: cgroup_helpers.c · 53 unmodified lines | |||
| 106 | $(OUTPUT)/test_sockmap: cgroup_helpers.c | 110 | $(OUTPUT)/test_sockmap: cgroup_helpers.c |
| 107 | $(OUTPUT)/test_tcpbpf_user: cgroup_helpers.c | 111 | $(OUTPUT)/test_tcpbpf_user: cgroup_helpers.c |
| 108 | $(OUTPUT)/test_tcpnotify_user: cgroup_helpers.c trace_helpers.c | 112 | $(OUTPUT)/test_tcpnotify_user: cgroup_helpers.c trace_helpers.c |
| 109 | $(OUTPUT)/test_progs: trace_helpers.c | 113 | $(OUTPUT)/test_progs: cgroup_helpers.c trace_helpers.c |
| 110 | $(OUTPUT)/get_cgroup_id_user: cgroup_helpers.c | 114 | $(OUTPUT)/get_cgroup_id_user: cgroup_helpers.c |
| 111 | $(OUTPUT)/test_cgroup_storage: cgroup_helpers.c | 115 | $(OUTPUT)/test_cgroup_storage: cgroup_helpers.c |
| 112 | $(OUTPUT)/test_netcnt: cgroup_helpers.c | 116 | $(OUTPUT)/test_netcnt: cgroup_helpers.c |
| 113 | $(OUTPUT)/test_sock_fields: cgroup_helpers.c | 117 | $(OUTPUT)/test_sock_fields: cgroup_helpers.c |
| 114 | $(OUTPUT)/test_sysctl: cgroup_helpers.c | 118 | $(OUTPUT)/test_sysctl: cgroup_helpers.c |
| 115 | $(OUTPUT)/test_cgroup_attach: cgroup_helpers.c | 119 | $(OUTPUT)/test_cgroup_attach: cgroup_helpers.c |
| 116 | $(OUTPUT)/test_sockopt: cgroup_helpers.c | ||
| 117 | $(OUTPUT)/test_sockopt_sk: cgroup_helpers.c | ||
| 118 | $(OUTPUT)/test_sockopt_multi: cgroup_helpers.c | ||
| 119 | $(OUTPUT)/test_sockopt_inherit: cgroup_helpers.c | ||
| 120 | $(OUTPUT)/test_tcp_rtt: cgroup_helpers.c | ||
| 121 | 120 | ||
| 122 | .PHONY: force | 121 | .PHONY: force |
| 123 | 122 | ||
| @@ -143,16 +142,19 @@ endif · 19 unmodified lines | |||
| 143 | # | 142 | # |
| 144 | # Use '-idirafter': Don't interfere with include mechanics except where the | 143 | # Use '-idirafter': Don't interfere with include mechanics except where the |
| 145 | # build would have failed anyways. | 144 | # build would have failed anyways. |
| 146 | CLANG_SYS_INCLUDES := $(shell $(CLANG) -v -E - </dev/null 2>&1 \ | 145 | define get_sys_includes |
| 146 | $(shell $(1) -v -E - </dev/null 2>&1 \ | ||
| 147 | | sed -n '/<...> search starts here:/,/End of search list./{ s| \(/.*\)|-idirafter \1|p }') | 147 | | sed -n '/<...> search starts here:/,/End of search list./{ s| \(/.*\)|-idirafter \1|p }') |
| 148 | endef | ||
| 149 | CLANG_SYS_INCLUDES = $(call get_sys_includes,$(CLANG)) | ||
| 150 | BPF_CFLAGS = -I. -I./include/uapi -I../../../include/uapi \ | ||
| 151 | -I$(OUTPUT)/../usr/include -D__TARGET_ARCH_$(SRCARCH) | ||
| 148 | 152 | ||
| 149 | CLANG_FLAGS = -I. -I./include/uapi -I../../../include/uapi \ | 153 | CLANG_CFLAGS = $(CLANG_SYS_INCLUDES) \ |
| 150 | $(CLANG_SYS_INCLUDES) \ | 154 | -Wno-compare-distinct-pointer-types |
| 151 | -Wno-compare-distinct-pointer-types \ | ||
| 152 | -D__TARGET_ARCH_$(SRCARCH) | ||
| 153 | 155 | ||
| 154 | $(OUTPUT)/test_l4lb_noinline.o: CLANG_FLAGS += -fno-inline | 156 | $(OUTPUT)/test_l4lb_noinline.o: BPF_CFLAGS += -fno-inline |
| 155 | $(OUTPUT)/test_xdp_noinline.o: CLANG_FLAGS += -fno-inline | 157 | $(OUTPUT)/test_xdp_noinline.o: BPF_CFLAGS += -fno-inline |
| 156 | 158 | ||
| 157 | $(OUTPUT)/test_queue_map.o: test_queue_stack_map.h | 159 | $(OUTPUT)/test_queue_map.o: test_queue_stack_map.h |
| 158 | $(OUTPUT)/test_stack_map.o: test_queue_stack_map.h | 160 | $(OUTPUT)/test_stack_map.o: test_queue_stack_map.h |
| @@ -169,12 +171,12 @@ BTF_LLVM_PROBE := $(shell echo "int main() { return 0; }" | \ · 10 unmodified lines | |||
| 169 | /bin/rm -f ./llvm_btf_verify.o) | 171 | /bin/rm -f ./llvm_btf_verify.o) |
| 170 | 172 | ||
| 171 | ifneq ($(BTF_LLVM_PROBE),) | 173 | ifneq ($(BTF_LLVM_PROBE),) |
| 172 | CLANG_FLAGS += -g | 174 | BPF_CFLAGS += -g |
| 173 | else | 175 | else |
| 174 | ifneq ($(BTF_LLC_PROBE),) | 176 | ifneq ($(BTF_LLC_PROBE),) |
| 175 | ifneq ($(BTF_PAHOLE_PROBE),) | 177 | ifneq ($(BTF_PAHOLE_PROBE),) |
| 176 | ifneq ($(BTF_OBJCOPY_PROBE),) | 178 | ifneq ($(BTF_OBJCOPY_PROBE),) |
| 177 | CLANG_FLAGS += -g | 179 | BPF_CFLAGS += -g |
| 178 | LLC_FLAGS += -mattr=dwarfris | 180 | LLC_FLAGS += -mattr=dwarfris |
| 179 | DWARF2BTF = y | 181 | DWARF2BTF = y |
| 180 | endif | 182 | endif |
| @@ -200,7 +202,7 @@ $(ALU32_BUILD_DIR)/test_progs_32: test_progs.c $(OUTPUT)/libbpf.a\ · 19 unmodified lines | |||
| 200 | | $(ALU32_BUILD_DIR) | 202 | | $(ALU32_BUILD_DIR) |
| 201 | $(CC) $(TEST_PROGS_CFLAGS) $(CFLAGS) \ | 203 | $(CC) $(TEST_PROGS_CFLAGS) $(CFLAGS) \ |
| 202 | -o $(ALU32_BUILD_DIR)/test_progs_32 \ | 204 | -o $(ALU32_BUILD_DIR)/test_progs_32 \ |
| 203 | test_progs.c test_stub.c trace_helpers.c prog_tests/*.c \ | 205 | test_progs.c test_stub.c cgroup_helpers.c trace_helpers.c prog_tests/*.c \ |
| 204 | $(OUTPUT)/libbpf.a $(LDLIBS) | 206 | $(OUTPUT)/libbpf.a $(LDLIBS) |
| 205 | 207 | ||
| 206 | $(ALU32_BUILD_DIR)/test_progs_32: $(PROG_TESTS_H) | 208 | $(ALU32_BUILD_DIR)/test_progs_32: $(PROG_TESTS_H) |
| @@ -208,8 +210,8 @@ $(ALU32_BUILD_DIR)/test_progs_32: prog_tests/*.c · 1 unmodified line | |||
| 208 | 210 | ||
| 209 | $(ALU32_BUILD_DIR)/%.o: progs/%.c $(ALU32_BUILD_DIR)/test_progs_32 \ | 211 | $(ALU32_BUILD_DIR)/%.o: progs/%.c $(ALU32_BUILD_DIR)/test_progs_32 \ |
| 210 | | $(ALU32_BUILD_DIR) | 212 | | $(ALU32_BUILD_DIR) |
| 211 | ($(CLANG) $(CLANG_FLAGS) -O2 -target bpf -emit-llvm -c $< -o - || \ | 213 | ($(CLANG) $(BPF_CFLAGS) $(CLANG_CFLAGS) -O2 -target bpf -emit-llvm \ |
| 212 | echo "clang failed") | \ | 214 | -c $< -o - || echo "clang failed") | \ |
| 213 | $(LLC) -march=bpf -mattr=+alu32 -mcpu=$(CPU) $(LLC_FLAGS) \ | 215 | $(LLC) -march=bpf -mattr=+alu32 -mcpu=$(CPU) $(LLC_FLAGS) \ |
| 214 | -filetype=obj -o $@ | 216 | -filetype=obj -o $@ |
| 215 | ifeq ($(DWARF2BTF),y) | 217 | ifeq ($(DWARF2BTF),y) |
| @@ -217,10 +219,37 @@ ifeq ($(DWARF2BTF),y) · 1 unmodified line | |||
| 217 | endif | 219 | endif |
| 218 | endif | 220 | endif |
| 219 | 221 | ||
| 222 | ifneq ($(BPF_GCC),) | ||
| 223 | GCC_SYS_INCLUDES = $(call get_sys_includes,gcc) | ||
| 224 | IS_LITTLE_ENDIAN = $(shell $(CC) -dM -E - </dev/null | \ | ||
| 225 | grep 'define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__') | ||
| 226 | ifeq ($(IS_LITTLE_ENDIAN),) | ||
| 227 | MENDIAN=-mbig-endian | ||
| 228 | else | ||
| 229 | MENDIAN=-mlittle-endian | ||
| 230 | endif | ||
| 231 | BPF_GCC_CFLAGS = $(GCC_SYS_INCLUDES) $(MENDIAN) | ||
| 232 | BPF_GCC_BUILD_DIR = $(OUTPUT)/bpf_gcc | ||
| 233 | TEST_CUSTOM_PROGS += $(BPF_GCC_BUILD_DIR)/test_progs_bpf_gcc | ||
| 234 | $(BPF_GCC_BUILD_DIR): | ||
| 235 | mkdir -p $@ | ||
| 236 | |||
| 237 | $(BPF_GCC_BUILD_DIR)/urandom_read: $(OUTPUT)/urandom_read | $(BPF_GCC_BUILD_DIR) | ||
| 238 | cp $< $@ | ||
| 239 | |||
| 240 | $(BPF_GCC_BUILD_DIR)/test_progs_bpf_gcc: $(OUTPUT)/test_progs \ | ||
| 241 | | $(BPF_GCC_BUILD_DIR) | ||
| 242 | cp $< $@ | ||
| 243 | |||
| 244 | $(BPF_GCC_BUILD_DIR)/%.o: progs/%.c $(BPF_GCC_BUILD_DIR)/test_progs_bpf_gcc \ | ||
| 245 | | $(BPF_GCC_BUILD_DIR) | ||
| 246 | $(BPF_GCC) $(BPF_CFLAGS) $(BPF_GCC_CFLAGS) -O2 -c $< -o $@ | ||
| 247 | endif | ||
| 248 | |||
| 220 | # Have one program compiled without "-target bpf" to test whether libbpf loads | 249 | # Have one program compiled without "-target bpf" to test whether libbpf loads |
| 221 | # it successfully | 250 | # it successfully |
| 222 | $(OUTPUT)/test_xdp.o: progs/test_xdp.c | 251 | $(OUTPUT)/test_xdp.o: progs/test_xdp.c |
| 223 | ($(CLANG) $(CLANG_FLAGS) -O2 -emit-llvm -c $< -o - || \ | 252 | ($(CLANG) $(BPF_CFLAGS) $(CLANG_CFLAGS) -O2 -emit-llvm -c $< -o - || \ |
| 224 | echo "clang failed") | \ | 253 | echo "clang failed") | \ |
| 225 | $(LLC) -march=bpf -mcpu=$(CPU) $(LLC_FLAGS) -filetype=obj -o $@ | 254 | $(LLC) -march=bpf -mcpu=$(CPU) $(LLC_FLAGS) -filetype=obj -o $@ |
| 226 | ifeq ($(DWARF2BTF),y) | 255 | ifeq ($(DWARF2BTF),y) |
| @@ -228,8 +257,8 @@ ifeq ($(DWARF2BTF),y) · 1 unmodified line | |||
| 228 | endif | 257 | endif |
| 229 | 258 | ||
| 230 | $(OUTPUT)/%.o: progs/%.c | 259 | $(OUTPUT)/%.o: progs/%.c |
| 231 | ($(CLANG) $(CLANG_FLAGS) -O2 -target bpf -emit-llvm -c $< -o - || \ | 260 | ($(CLANG) $(BPF_CFLAGS) $(CLANG_CFLAGS) -O2 -target bpf -emit-llvm \ |
| 232 | echo "clang failed") | \ | 261 | -c $< -o - || echo "clang failed") | \ |
| 233 | $(LLC) -march=bpf -mcpu=$(CPU) $(LLC_FLAGS) -filetype=obj -o $@ | 262 | $(LLC) -march=bpf -mcpu=$(CPU) $(LLC_FLAGS) -filetype=obj -o $@ |
| 234 | ifeq ($(DWARF2BTF),y) | 263 | ifeq ($(DWARF2BTF),y) |
| 235 | $(BTF_PAHOLE) -J $@ | 264 | $(BTF_PAHOLE) -J $@ |
| @@ -288,6 +317,6 @@ $(VERIFIER_TESTS_H): $(VERIFIER_TEST_FILES) | $(VERIFIER_TESTS_DIR) · 52 unmodified lines | |||
| 288 | echo '#endif' \ | 317 | echo '#endif' \ |
| 289 | ) > $(VERIFIER_TESTS_H)) | 318 | ) > $(VERIFIER_TESTS_H)) |
| 290 | 319 | ||
| 291 | EXTRA_CLEAN := $(TEST_CUSTOM_PROGS) $(ALU32_BUILD_DIR) \ | 320 | EXTRA_CLEAN := $(TEST_CUSTOM_PROGS) $(ALU32_BUILD_DIR) $(BPF_GCC_BUILD_DIR) \ |
| 292 | $(VERIFIER_TESTS_H) $(PROG_TESTS_H) $(MAP_TESTS_H) \ | 321 | $(VERIFIER_TESTS_H) $(PROG_TESTS_H) $(MAP_TESTS_H) \ |
| 293 | feature | 322 | feature |
| @@ -1,12 +1,6 @@ | |||
| 1 | /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ | 1 | /* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ |
| 2 | #ifndef __BPF_HELPERS_H | 2 | #ifndef __BPF_HELPERS__ |
| 3 | #define __BPF_HELPERS_H | 3 | #define __BPF_HELPERS__ |
| 4 | |||
| 5 | /* helper macro to place programs, maps, license in | ||
| 6 | * different sections in elf_bpf file. Section names | ||
| 7 | * are interpreted by elf_bpf loader | ||
| 8 | */ | ||
| 9 | #define SEC(NAME) __attribute__((section(NAME), used)) | ||
| 10 | 4 | ||
| 11 | #define __uint(name, val) int (*name)[val] | 5 | #define __uint(name, val) int (*name)[val] |
| 12 | #define __type(name, val) val *name | 6 | #define __type(name, val) val *name |
| @@ -19,6 +13,14 @@ · 6 unmodified lines | |||
| 19 | ##__VA_ARGS__); \ | 13 | ##__VA_ARGS__); \ |
| 20 | }) | 14 | }) |
| 21 | 15 | ||
| 16 | #ifdef __clang__ | ||
| 17 | |||
| 18 | /* helper macro to place programs, maps, license in | ||
| 19 | * different sections in elf_bpf file. Section names | ||
| 20 | * are interpreted by elf_bpf loader | ||
| 21 | */ | ||
| 22 | #define SEC(NAME) __attribute__((section(NAME), used)) | ||
| 23 | |||
| 22 | /* helper functions called from eBPF programs written in C */ | 24 | /* helper functions called from eBPF programs written in C */ |
| 23 | static void *(*bpf_map_lookup_elem)(void *map, const void *key) = | 25 | static void *(*bpf_map_lookup_elem)(void *map, const void *key) = |
| 24 | (void *) BPF_FUNC_map_lookup_elem; | 26 | (void *) BPF_FUNC_map_lookup_elem; |
| @@ -256,6 +258,12 @@ struct bpf_map_def { · 231 unmodified lines | |||
| 256 | unsigned int numa_node; | 258 | unsigned int numa_node; |
| 257 | }; | 259 | }; |
| 258 | 260 | ||
| 261 | #else | ||
| 262 | |||
| 263 | #include <bpf-helpers.h> | ||
| 264 | |||
| 265 | #endif | ||
| 266 | |||
| 259 | #define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val) \ | 267 | #define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val) \ |
| 260 | struct ____btf_map_##name { \ | 268 | struct ____btf_map_##name { \ |
| 261 | type_key key; \ | 269 | type_key key; \ |
| @@ -1,22 +1,7 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | #include <test_progs.h> | |
| 3 | #include <errno.h> | ||
| 4 | #include <stdio.h> | ||
| 5 | #include <unistd.h> | ||
| 6 | #include <sys/types.h> | ||
| 7 | #include <sys/socket.h> | ||
| 8 | #include <netinet/in.h> | ||
| 9 | |||
| 10 | #include <linux/filter.h> | ||
| 11 | #include <bpf/bpf.h> | ||
| 12 | #include <bpf/libbpf.h> | ||
| 13 | |||
| 14 | #include "bpf_rlimit.h" | ||
| 15 | #include "bpf_util.h" | ||
| 16 | #include "cgroup_helpers.h" | 3 | #include "cgroup_helpers.h" |
| 17 | 4 | ||
| 18 | #define CG_PATH "/sockopt" | ||
| 19 | |||
| 20 | static char bpf_log_buf[4096]; | 5 | static char bpf_log_buf[4096]; |
| 21 | static bool verbose; | 6 | static bool verbose; |
| 22 | 7 | ||
| @@ -983,39 +968,18 @@ close_prog_fd: · 960 unmodified lines | |||
| 983 | return ret; | 968 | return ret; |
| 984 | } | 969 | } |
| 985 | 970 | ||
| 986 | int main(int args, char **argv) | 971 | void test_sockopt(void) |
| 987 | { | 972 | { |
| 988 | int err = EXIT_FAILURE, error_cnt = 0; | ||
| 989 | int cgroup_fd, i; | 973 | int cgroup_fd, i; |
| 990 | 974 | ||
| 991 | if (setup_cgroup_environment()) | 975 | cgroup_fd = test__join_cgroup("/sockopt"); |
| 992 | goto cleanup_obj; | 976 | if (CHECK_FAIL(cgroup_fd < 0)) |
| 993 | 977 | return; | |
| 994 | cgroup_fd = create_and_get_cgroup(CG_PATH); | ||
| 995 | if (cgroup_fd < 0) | ||
| 996 | goto cleanup_cgroup_env; | ||
| 997 | |||
| 998 | if (join_cgroup(CG_PATH)) | ||
| 999 | goto cleanup_cgroup; | ||
| 1000 | 978 | ||
| 1001 | for (i = 0; i < ARRAY_SIZE(tests); i++) { | 979 | for (i = 0; i < ARRAY_SIZE(tests); i++) { |
| 1002 | int err = run_test(cgroup_fd, &tests[i]); | 980 | test__start_subtest(tests[i].descr); |
| 1003 | 981 | CHECK_FAIL(run_test(cgroup_fd, &tests[i])); | |
| 1004 | if (err) | ||
| 1005 | error_cnt++; | ||
| 1006 | |||
| 1007 | printf("#%d %s: %s\n", i, err ? "FAIL" : "PASS", | ||
| 1008 | tests[i].descr); | ||
| 1009 | } | 982 | } |
| 1010 | 983 | ||
| 1011 | printf("Summary: %ld PASSED, %d FAILED\n", | ||
| 1012 | ARRAY_SIZE(tests) - error_cnt, error_cnt); | ||
| 1013 | err = error_cnt ? EXIT_FAILURE : EXIT_SUCCESS; | ||
| 1014 | |||
| 1015 | cleanup_cgroup: | ||
| 1016 | close(cgroup_fd); | 984 | close(cgroup_fd); |
| 1017 | cleanup_cgroup_env: | ||
| 1018 | cleanup_cgroup_environment(); | ||
| 1019 | cleanup_obj: | ||
| 1020 | return err; | ||
| 1021 | } | 985 | } |
| @@ -1,22 +1,7 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | #include <error.h> | 2 | #include <test_progs.h> |
| 3 | #include <errno.h> | ||
| 4 | #include <stdio.h> | ||
| 5 | #include <unistd.h> | ||
| 6 | #include <sys/types.h> | ||
| 7 | #include <sys/socket.h> | ||
| 8 | #include <netinet/in.h> | ||
| 9 | #include <pthread.h> | ||
| 10 | |||
| 11 | #include <linux/filter.h> | ||
| 12 | #include <bpf/bpf.h> | ||
| 13 | #include <bpf/libbpf.h> | ||
| 14 | |||
| 15 | #include "bpf_rlimit.h" | ||
| 16 | #include "bpf_util.h" | ||
| 17 | #include "cgroup_helpers.h" | 3 | #include "cgroup_helpers.h" |
| 18 | 4 | ||
| 19 | #define CG_PATH "/sockopt_inherit" | ||
| 20 | #define SOL_CUSTOM 0xdeadbeef | 5 | #define SOL_CUSTOM 0xdeadbeef |
| 21 | #define CUSTOM_INHERIT1 0 | 6 | #define CUSTOM_INHERIT1 0 |
| 22 | #define CUSTOM_INHERIT2 1 | 7 | #define CUSTOM_INHERIT2 1 |
| @@ -74,6 +59,9 @@ static int verify_sockopt(int fd, int optname, const char *msg, char expected) · 51 unmodified lines | |||
| 74 | return 0; | 59 | return 0; |
| 75 | } | 60 | } |
| 76 | 61 | ||
| 62 | static pthread_mutex_t server_started_mtx = PTHREAD_MUTEX_INITIALIZER; | ||
| 63 | static pthread_cond_t server_started = PTHREAD_COND_INITIALIZER; | ||
| 64 | |||
| 77 | static void *server_thread(void *arg) | 65 | static void *server_thread(void *arg) |
| 78 | { | 66 | { |
| 79 | struct sockaddr_storage addr; | 67 | struct sockaddr_storage addr; |
| @@ -82,16 +70,26 @@ static void *server_thread(void *arg) · 2 unmodified lines | |||
| 82 | int client_fd; | 70 | int client_fd; |
| 83 | int err = 0; | 71 | int err = 0; |
| 84 | 72 | ||
| 85 | if (listen(fd, 1) < 0) | 73 | err = listen(fd, 1); |
| 86 | error(1, errno, "Failed to listed on socket"); | 74 | |
| 75 | pthread_mutex_lock(&server_started_mtx); | ||
| 76 | pthread_cond_signal(&server_started); | ||
| 77 | pthread_mutex_unlock(&server_started_mtx); | ||
| 78 | |||
| 79 | if (CHECK_FAIL(err < 0)) { | ||
| 80 | perror("Failed to listed on socket"); | ||
| 81 | return NULL; | ||
| 82 | } | ||
| 87 | 83 | ||
| 88 | err += verify_sockopt(fd, CUSTOM_INHERIT1, "listen", 1); | 84 | err += verify_sockopt(fd, CUSTOM_INHERIT1, "listen", 1); |
| 89 | err += verify_sockopt(fd, CUSTOM_INHERIT2, "listen", 1); | 85 | err += verify_sockopt(fd, CUSTOM_INHERIT2, "listen", 1); |
| 90 | err += verify_sockopt(fd, CUSTOM_LISTENER, "listen", 1); | 86 | err += verify_sockopt(fd, CUSTOM_LISTENER, "listen", 1); |
| 91 | 87 | ||
| 92 | client_fd = accept(fd, (struct sockaddr *)&addr, &len); | 88 | client_fd = accept(fd, (struct sockaddr *)&addr, &len); |
| 93 | if (client_fd < 0) | 89 | if (CHECK_FAIL(client_fd < 0)) { |
| 94 | error(1, errno, "Failed to accept client"); | 90 | perror("Failed to accept client"); |
| 91 | return NULL; | ||
| 92 | } | ||
| 95 | 93 | ||
| 96 | err += verify_sockopt(client_fd, CUSTOM_INHERIT1, "accept", 1); | 94 | err += verify_sockopt(client_fd, CUSTOM_INHERIT1, "accept", 1); |
| 97 | err += verify_sockopt(client_fd, CUSTOM_INHERIT2, "accept", 1); | 95 | err += verify_sockopt(client_fd, CUSTOM_INHERIT2, "accept", 1); |
| @@ -167,7 +165,7 @@ static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title) · 69 unmodified lines | |||
| 167 | return 0; | 165 | return 0; |
| 168 | } | 166 | } |
| 169 | 167 | ||
| 170 | static int run_test(int cgroup_fd) | 168 | static void run_test(int cgroup_fd) |
| 171 | { | 169 | { |
| 172 | struct bpf_prog_load_attr attr = { | 170 | struct bpf_prog_load_attr attr = { |
| 173 | .file = "./sockopt_inherit.o", | 171 | .file = "./sockopt_inherit.o", |
| @@ -180,40 +178,41 @@ static int run_test(int cgroup_fd) · 6 unmodified lines | |||
| 180 | int err; | 178 | int err; |
| 181 | 179 | ||
| 182 | err = bpf_prog_load_xattr(&attr, &obj, &ignored); | 180 | err = bpf_prog_load_xattr(&attr, &obj, &ignored); |
| 183 | if (err) { | 181 | if (CHECK_FAIL(err)) |
| 184 | log_err("Failed to load BPF object"); | 182 | return; |
| 185 | return -1; | ||
| 186 | } | ||
| 187 | 183 | ||
| 188 | err = prog_attach(obj, cgroup_fd, "cgroup/getsockopt"); | 184 | err = prog_attach(obj, cgroup_fd, "cgroup/getsockopt"); |
| 189 | if (err) | 185 | if (CHECK_FAIL(err)) |
| 190 | goto close_bpf_object; | 186 | goto close_bpf_object; |
| 191 | 187 | ||
| 192 | err = prog_attach(obj, cgroup_fd, "cgroup/setsockopt"); | 188 | err = prog_attach(obj, cgroup_fd, "cgroup/setsockopt"); |
| 193 | if (err) | 189 | if (CHECK_FAIL(err)) |
| 194 | goto close_bpf_object; | 190 | goto close_bpf_object; |
| 195 | 191 | ||
| 196 | server_fd = start_server(); | 192 | server_fd = start_server(); |
| 197 | if (server_fd < 0) { | 193 | if (CHECK_FAIL(server_fd < 0)) |
| 198 | err = -1; | 194 | goto close_bpf_object; |
| 195 | |||
| 196 | if (CHECK_FAIL(pthread_create(&tid, NULL, server_thread, | ||
| 197 | (void *)&server_fd))) | ||
| 199 | goto close_bpf_object; | 198 | goto close_bpf_object; |
| 200 | } | ||
| 201 | 199 | ||
| 202 | pthread_create(&tid, NULL, server_thread, (void *)&server_fd); | 200 | pthread_mutex_lock(&server_started_mtx); |
| 201 | pthread_cond_wait(&server_started, &server_started_mtx); | ||
| 202 | pthread_mutex_unlock(&server_started_mtx); | ||
| 203 | 203 | ||
| 204 | client_fd = connect_to_server(server_fd); | 204 | client_fd = connect_to_server(server_fd); |
| 205 | if (client_fd < 0) { | 205 | if (CHECK_FAIL(client_fd < 0)) |
| 206 | err = -1; | ||
| 207 | goto close_server_fd; | 206 | goto close_server_fd; |
| 208 | } | ||
| 209 | 207 | ||
| 210 | err += verify_sockopt(client_fd, CUSTOM_INHERIT1, "connect", 0); | 208 | CHECK_FAIL(verify_sockopt(client_fd, CUSTOM_INHERIT1, "connect", 0)); |
| 211 | err += verify_sockopt(client_fd, CUSTOM_INHERIT2, "connect", 0); | 209 | CHECK_FAIL(verify_sockopt(client_fd, CUSTOM_INHERIT2, "connect", 0)); |
| 212 | err += verify_sockopt(client_fd, CUSTOM_LISTENER, "connect", 0); | 210 | CHECK_FAIL(verify_sockopt(client_fd, CUSTOM_LISTENER, "connect", 0)); |
| 213 | 211 | ||
| 214 | pthread_join(tid, &server_err); | 212 | pthread_join(tid, &server_err); |
| 215 | 213 | ||
| 216 | err += (int)(long)server_err; | 214 | err = (int)(long)server_err; |
| 215 | CHECK_FAIL(err); | ||
| 217 | 216 | ||
| 218 | close(client_fd); | 217 | close(client_fd); |
| 219 | 218 | ||
| @@ -221,33 +220,16 @@ close_server_fd: · 1 unmodified line | |||
| 221 | close(server_fd); | 220 | close(server_fd); |
| 222 | close_bpf_object: | 221 | close_bpf_object: |
| 223 | bpf_object__close(obj); | 222 | bpf_object__close(obj); |
| 224 | return err; | ||
| 225 | } | 223 | } |
| 226 | 224 | ||
| 227 | int main(int args, char **argv) | 225 | void test_sockopt_inherit(void) |
| 228 | { | 226 | { |
| 229 | int cgroup_fd; | 227 | int cgroup_fd; |
| 230 | int err = EXIT_SUCCESS; | ||
| 231 | |||
| 232 | if (setup_cgroup_environment()) | ||
| 233 | return err; | ||
| 234 | |||
| 235 | cgroup_fd = create_and_get_cgroup(CG_PATH); | ||
| 236 | if (cgroup_fd < 0) | ||
| 237 | goto cleanup_cgroup_env; | ||
| 238 | |||
| 239 | if (join_cgroup(CG_PATH)) | ||
| 240 | goto cleanup_cgroup; | ||
| 241 | |||
| 242 | if (run_test(cgroup_fd)) | ||
| 243 | err = EXIT_FAILURE; | ||
| 244 | 228 | ||
| 245 | printf("test_sockopt_inherit: %s\n", | 229 | cgroup_fd = test__join_cgroup("/sockopt_inherit"); |
| 246 | err == EXIT_SUCCESS ? "PASSED" : "FAILED"); | 230 | if (CHECK_FAIL(cgroup_fd < 0)) |
| 231 | return; | ||
| 247 | 232 | ||
| 248 | cleanup_cgroup: | 233 | run_test(cgroup_fd); |
| 249 | close(cgroup_fd); | 234 | close(cgroup_fd); |
| 250 | cleanup_cgroup_env: | ||
| 251 | cleanup_cgroup_environment(); | ||
| 252 | return err; | ||
| 253 | } | 235 | } |
| @@ -1,19 +1,5 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | #include <test_progs.h> | |
| 3 | #include <error.h> | ||
| 4 | #include <errno.h> | ||
| 5 | #include <stdio.h> | ||
| 6 | #include <unistd.h> | ||
| 7 | #include <sys/types.h> | ||
| 8 | #include <sys/socket.h> | ||
| 9 | #include <netinet/in.h> | ||
| 10 | |||
| 11 | #include <linux/filter.h> | ||
| 12 | #include <bpf/bpf.h> | ||
| 13 | #include <bpf/libbpf.h> | ||
| 14 | |||
| 15 | #include "bpf_rlimit.h" | ||
| 16 | #include "bpf_util.h" | ||
| 17 | #include "cgroup_helpers.h" | 3 | #include "cgroup_helpers.h" |
| 18 | 4 | ||
| 19 | static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title) | 5 | static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title) |
| @@ -308,7 +294,7 @@ detach: · 288 unmodified lines | |||
| 308 | return err; | 294 | return err; |
| 309 | } | 295 | } |
| 310 | 296 | ||
| 311 | int main(int argc, char **argv) | 297 | void test_sockopt_multi(void) |
| 312 | { | 298 | { |
| 313 | struct bpf_prog_load_attr attr = { | 299 | struct bpf_prog_load_attr attr = { |
| 314 | .file = "./sockopt_multi.o", | 300 | .file = "./sockopt_multi.o", |
| @@ -319,56 +305,28 @@ int main(int argc, char **argv) · 4 unmodified lines | |||
| 319 | int err = -1; | 305 | int err = -1; |
| 320 | int ignored; | 306 | int ignored; |
| 321 | 307 | ||
| 322 | if (setup_cgroup_environment()) { | 308 | cg_parent = test__join_cgroup("/parent"); |
| 323 | log_err("Failed to setup cgroup environment\n"); | 309 | if (CHECK_FAIL(cg_parent < 0)) |
| 324 | goto out; | ||
| 325 | } | ||
| 326 | |||
| 327 | cg_parent = create_and_get_cgroup("/parent"); | ||
| 328 | if (cg_parent < 0) { | ||
| 329 | log_err("Failed to create cgroup /parent\n"); | ||
| 330 | goto out; | ||
| 331 | } | ||
| 332 | |||
| 333 | cg_child = create_and_get_cgroup("/parent/child"); | ||
| 334 | if (cg_child < 0) { | ||
| 335 | log_err("Failed to create cgroup /parent/child\n"); | ||
| 336 | goto out; | 310 | goto out; |
| 337 | } | ||
| 338 | 311 | ||
| 339 | if (join_cgroup("/parent/child")) { | 312 | cg_child = test__join_cgroup("/parent/child"); |
| 340 | log_err("Failed to join cgroup /parent/child\n"); | 313 | if (CHECK_FAIL(cg_child < 0)) |
| 341 | goto out; | 314 | goto out; |
| 342 | } | ||
| 343 | 315 | ||
| 344 | err = bpf_prog_load_xattr(&attr, &obj, &ignored); | 316 | err = bpf_prog_load_xattr(&attr, &obj, &ignored); |
| 345 | if (err) { | 317 | if (CHECK_FAIL(err)) |
| 346 | log_err("Failed to load BPF object"); | ||
| 347 | goto out; | 318 | goto out; |
| 348 | } | ||
| 349 | 319 | ||
| 350 | sock_fd = socket(AF_INET, SOCK_STREAM, 0); | 320 | sock_fd = socket(AF_INET, SOCK_STREAM, 0); |
| 351 | if (sock_fd < 0) { | 321 | if (CHECK_FAIL(sock_fd < 0)) |
| 352 | log_err("Failed to create socket"); | ||
| 353 | goto out; | 322 | goto out; |
| 354 | } | ||
| 355 | 323 | ||
| 356 | if (run_getsockopt_test(obj, cg_parent, cg_child, sock_fd)) | 324 | CHECK_FAIL(run_getsockopt_test(obj, cg_parent, cg_child, sock_fd)); |
| 357 | err = -1; | 325 | CHECK_FAIL(run_setsockopt_test(obj, cg_parent, cg_child, sock_fd)); |
| 358 | printf("test_sockopt_multi: getsockopt %s\n", | ||
| 359 | err ? "FAILED" : "PASSED"); | ||
| 360 | |||
| 361 | if (run_setsockopt_test(obj, cg_parent, cg_child, sock_fd)) | ||
| 362 | err = -1; | ||
| 363 | printf("test_sockopt_multi: setsockopt %s\n", | ||
| 364 | err ? "FAILED" : "PASSED"); | ||
| 365 | 326 | ||
| 366 | out: | 327 | out: |
| 367 | close(sock_fd); | 328 | close(sock_fd); |
| 368 | bpf_object__close(obj); | 329 | bpf_object__close(obj); |
| 369 | close(cg_child); | 330 | close(cg_child); |
| 370 | close(cg_parent); | 331 | close(cg_parent); |
| 371 | |||
| 372 | printf("test_sockopt_multi: %s\n", err ? "FAILED" : "PASSED"); | ||
| 373 | return err ? EXIT_FAILURE : EXIT_SUCCESS; | ||
| 374 | } | 332 | } |
| @@ -1,23 +1,7 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | #include <test_progs.h> | |
| 3 | #include <errno.h> | ||
| 4 | #include <stdio.h> | ||
| 5 | #include <unistd.h> | ||
| 6 | #include <sys/types.h> | ||
| 7 | #include <sys/socket.h> | ||
| 8 | #include <netinet/in.h> | ||
| 9 | #include <netinet/tcp.h> | ||
| 10 | |||
| 11 | #include <linux/filter.h> | ||
| 12 | #include <bpf/bpf.h> | ||
| 13 | #include <bpf/libbpf.h> | ||
| 14 | |||
| 15 | #include "bpf_rlimit.h" | ||
| 16 | #include "bpf_util.h" | ||
| 17 | #include "cgroup_helpers.h" | 3 | #include "cgroup_helpers.h" |
| 18 | 4 | ||
| 19 | #define CG_PATH "/sockopt" | ||
| 20 | |||
| 21 | #define SOL_CUSTOM 0xdeadbeef | 5 | #define SOL_CUSTOM 0xdeadbeef |
| 22 | 6 | ||
| 23 | static int getsetsockopt(void) | 7 | static int getsetsockopt(void) |
| @@ -176,7 +160,7 @@ static int prog_attach(struct bpf_object *obj, int cgroup_fd, const char *title) · 152 unmodified lines | |||
| 176 | return 0; | 160 | return 0; |
| 177 | } | 161 | } |
| 178 | 162 | ||
| 179 | static int run_test(int cgroup_fd) | 163 | static void run_test(int cgroup_fd) |
| 180 | { | 164 | { |
| 181 | struct bpf_prog_load_attr attr = { | 165 | struct bpf_prog_load_attr attr = { |
| 182 | .file = "./sockopt_sk.o", | 166 | .file = "./sockopt_sk.o", |
| @@ -186,51 +170,31 @@ static int run_test(int cgroup_fd) · 3 unmodified lines | |||
| 186 | int err; | 170 | int err; |
| 187 | 171 | ||
| 188 | err = bpf_prog_load_xattr(&attr, &obj, &ignored); | 172 | err = bpf_prog_load_xattr(&attr, &obj, &ignored); |
| 189 | if (err) { | 173 | if (CHECK_FAIL(err)) |
| 190 | log_err("Failed to load BPF object"); | 174 | return; |
| 191 | return -1; | ||
| 192 | } | ||
| 193 | 175 | ||
| 194 | err = prog_attach(obj, cgroup_fd, "cgroup/getsockopt"); | 176 | err = prog_attach(obj, cgroup_fd, "cgroup/getsockopt"); |
| 195 | if (err) | 177 | if (CHECK_FAIL(err)) |
| 196 | goto close_bpf_object; | 178 | goto close_bpf_object; |
| 197 | 179 | ||
| 198 | err = prog_attach(obj, cgroup_fd, "cgroup/setsockopt"); | 180 | err = prog_attach(obj, cgroup_fd, "cgroup/setsockopt"); |
| 199 | if (err) | 181 | if (CHECK_FAIL(err)) |
| 200 | goto close_bpf_object; | 182 | goto close_bpf_object; |
| 201 | 183 | ||
| 202 | err = getsetsockopt(); | 184 | CHECK_FAIL(getsetsockopt()); |
| 203 | 185 | ||
| 204 | close_bpf_object: | 186 | close_bpf_object: |
| 205 | bpf_object__close(obj); | 187 | bpf_object__close(obj); |
| 206 | return err; | ||
| 207 | } | 188 | } |
| 208 | 189 | ||
| 209 | int main(int args, char **argv) | 190 | void test_sockopt_sk(void) |
| 210 | { | 191 | { |
| 211 | int cgroup_fd; | 192 | int cgroup_fd; |
| 212 | int err = EXIT_SUCCESS; | ||
| 213 | |||
| 214 | if (setup_cgroup_environment()) | ||
| 215 | goto cleanup_obj; | ||
| 216 | |||
| 217 | cgroup_fd = create_and_get_cgroup(CG_PATH); | ||
| 218 | if (cgroup_fd < 0) | ||
| 219 | goto cleanup_cgroup_env; | ||
| 220 | |||
| 221 | if (join_cgroup(CG_PATH)) | ||
| 222 | goto cleanup_cgroup; | ||
| 223 | |||
| 224 | if (run_test(cgroup_fd)) | ||
| 225 | err = EXIT_FAILURE; | ||
| 226 | 193 | ||
| 227 | printf("test_sockopt_sk: %s\n", | 194 | cgroup_fd = test__join_cgroup("/sockopt_sk"); |
| 228 | err == EXIT_SUCCESS ? "PASSED" : "FAILED"); | 195 | if (CHECK_FAIL(cgroup_fd < 0)) |
| 196 | return; | ||
| 229 | 197 | ||
| 230 | cleanup_cgroup: | 198 | run_test(cgroup_fd); |
| 231 | close(cgroup_fd); | 199 | close(cgroup_fd); |
| 232 | cleanup_cgroup_env: | ||
| 233 | cleanup_cgroup_environment(); | ||
| 234 | cleanup_obj: | ||
| 235 | return err; | ||
| 236 | } | 200 | } |
| @@ -1,24 +1,7 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | #include <error.h> | 2 | #include <test_progs.h> |
| 3 | #include <errno.h> | ||
| 4 | #include <stdio.h> | ||
| 5 | #include <unistd.h> | ||
| 6 | #include <sys/types.h> | ||
| 7 | #include <sys/socket.h> | ||
| 8 | #include <netinet/in.h> | ||
| 9 | #include <netinet/tcp.h> | ||
| 10 | #include <pthread.h> | ||
| 11 | |||
| 12 | #include <linux/filter.h> | ||
| 13 | #include <bpf/bpf.h> | ||
| 14 | #include <bpf/libbpf.h> | ||
| 15 | |||
| 16 | #include "bpf_rlimit.h" | ||
| 17 | #include "bpf_util.h" | ||
| 18 | #include "cgroup_helpers.h" | 3 | #include "cgroup_helpers.h" |
| 19 | 4 | ||
| 20 | #define CG_PATH "/tcp_rtt" | ||
| 21 | |||
| 22 | struct tcp_rtt_storage { | 5 | struct tcp_rtt_storage { |
| 23 | __u32 invoked; | 6 | __u32 invoked; |
| 24 | __u32 dsack_dups; | 7 | __u32 dsack_dups; |
| @@ -31,8 +14,8 @@ static void send_byte(int fd) · 6 unmodified lines | |||
| 31 | { | 14 | { |
| 32 | char b = 0x55; | 15 | char b = 0x55; |
| 33 | 16 | ||
| 34 | if (write(fd, &b, sizeof(b)) != 1) | 17 | if (CHECK_FAIL(write(fd, &b, sizeof(b)) != 1)) |
| 35 | error(1, errno, "Failed to send single byte"); | 18 | perror("Failed to send single byte"); |
| 36 | } | 19 | } |
| 37 | 20 | ||
| 38 | static int wait_for_ack(int fd, int retries) | 21 | static int wait_for_ack(int fd, int retries) |
| @@ -66,8 +49,10 @@ static int verify_sk(int map_fd, int client_fd, const char *msg, __u32 invoked, · 27 unmodified lines | |||
| 66 | int err = 0; | 49 | int err = 0; |
| 67 | struct tcp_rtt_storage val; | 50 | struct tcp_rtt_storage val; |
| 68 | 51 | ||
| 69 | if (bpf_map_lookup_elem(map_fd, &client_fd, &val) < 0) | 52 | if (CHECK_FAIL(bpf_map_lookup_elem(map_fd, &client_fd, &val) < 0)) { |
| 70 | error(1, errno, "Failed to read socket storage"); | 53 | perror("Failed to read socket storage"); |
| 54 | return -1; | ||
| 55 | } | ||
| 71 | 56 | ||
| 72 | if (val.invoked != invoked) { | 57 | if (val.invoked != invoked) { |
| 73 | log_err("%s: unexpected bpf_tcp_sock.invoked %d != %d", | 58 | log_err("%s: unexpected bpf_tcp_sock.invoked %d != %d", |
| @@ -225,61 +210,47 @@ static void *server_thread(void *arg) · 151 unmodified lines | |||
| 225 | int fd = *(int *)arg; | 210 | int fd = *(int *)arg; |
| 226 | int client_fd; | 211 | int client_fd; |
| 227 | 212 | ||
| 228 | if (listen(fd, 1) < 0) | 213 | if (CHECK_FAIL(listen(fd, 1)) < 0) { |
| 229 | error(1, errno, "Failed to listed on socket"); | 214 | perror("Failed to listed on socket"); |
| 215 | return NULL; | ||
| 216 | } | ||
| 230 | 217 | ||
| 231 | client_fd = accept(fd, (struct sockaddr *)&addr, &len); | 218 | client_fd = accept(fd, (struct sockaddr *)&addr, &len); |
| 232 | if (client_fd < 0) | 219 | if (CHECK_FAIL(client_fd < 0)) { |
| 233 | error(1, errno, "Failed to accept client"); | 220 | perror("Failed to accept client"); |
| 221 | return NULL; | ||
| 222 | } | ||
| 234 | 223 | ||
| 235 | /* Wait for the next connection (that never arrives) | 224 | /* Wait for the next connection (that never arrives) |
| 236 | * to keep this thread alive to prevent calling | 225 | * to keep this thread alive to prevent calling |
| 237 | * close() on client_fd. | 226 | * close() on client_fd. |
| 238 | */ | 227 | */ |
| 239 | if (accept(fd, (struct sockaddr *)&addr, &len) >= 0) | 228 | if (CHECK_FAIL(accept(fd, (struct sockaddr *)&addr, &len) >= 0)) { |
| 240 | error(1, errno, "Unexpected success in second accept"); | 229 | perror("Unexpected success in second accept"); |
| 230 | return NULL; | ||
| 231 | } | ||
| 241 | 232 | ||
| 242 | close(client_fd); | 233 | close(client_fd); |
| 243 | 234 | ||
| 244 | return NULL; | 235 | return NULL; |
| 245 | } | 236 | } |
| 246 | 237 | ||
| 247 | int main(int args, char **argv) | 238 | void test_tcp_rtt(void) |
| 248 | { | 239 | { |
| 249 | int server_fd, cgroup_fd; | 240 | int server_fd, cgroup_fd; |
| 250 | int err = EXIT_SUCCESS; | ||
| 251 | pthread_t tid; | 241 | pthread_t tid; |
| 252 | 242 | ||
| 253 | if (setup_cgroup_environment()) | 243 | cgroup_fd = test__join_cgroup("/tcp_rtt"); |
| 254 | goto cleanup_obj; | 244 | if (CHECK_FAIL(cgroup_fd < 0)) |
| 255 | 245 | return; | |
| 256 | cgroup_fd = create_and_get_cgroup(CG_PATH); | ||
| 257 | if (cgroup_fd < 0) | ||
| 258 | goto cleanup_cgroup_env; | ||
| 259 | |||
| 260 | if (join_cgroup(CG_PATH)) | ||
| 261 | goto cleanup_cgroup; | ||
| 262 | 246 | ||
| 263 | server_fd = start_server(); | 247 | server_fd = start_server(); |
| 264 | if (server_fd < 0) { | 248 | if (CHECK_FAIL(server_fd < 0)) |
| 265 | err = EXIT_FAILURE; | 249 | goto close_cgroup_fd; |
| 266 | goto cleanup_cgroup; | ||
| 267 | } | ||
| 268 | 250 | ||
| 269 | pthread_create(&tid, NULL, server_thread, (void *)&server_fd); | 251 | pthread_create(&tid, NULL, server_thread, (void *)&server_fd); |
| 270 | 252 | CHECK_FAIL(run_test(cgroup_fd, server_fd)); | |
| 271 | if (run_test(cgroup_fd, server_fd)) | ||
| 272 | err = EXIT_FAILURE; | ||
| 273 | |||
| 274 | close(server_fd); | 253 | close(server_fd); |
| 275 | 254 | close_cgroup_fd: | |
| 276 | printf("test_sockopt_sk: %s\n", | ||
| 277 | err == EXIT_SUCCESS ? "PASSED" : "FAILED"); | ||
| 278 | |||
| 279 | cleanup_cgroup: | ||
| 280 | close(cgroup_fd); | 255 | close(cgroup_fd); |
| 281 | cleanup_cgroup_env: | ||
| 282 | cleanup_cgroup_environment(); | ||
| 283 | cleanup_obj: | ||
| 284 | return err; | ||
| 285 | } | 256 | } |
| @@ -2,6 +2,7 @@ · 1 unmodified line | |||
| 2 | #include <stdint.h> | 2 | #include <stdint.h> |
| 3 | #include <linux/bpf.h> | 3 | #include <linux/bpf.h> |
| 4 | #include <linux/if_ether.h> | 4 | #include <linux/if_ether.h> |
| 5 | #include <linux/stddef.h> | ||
| 5 | #include <linux/in.h> | 6 | #include <linux/in.h> |
| 6 | #include <linux/ip.h> | 7 | #include <linux/ip.h> |
| 7 | #include <linux/pkt_cls.h> | 8 | #include <linux/pkt_cls.h> |
| @@ -2,6 +2,7 @@ · 1 unmodified line | |||
| 2 | /* Copyright (c) 2017 Facebook | 2 | /* Copyright (c) 2017 Facebook |
| 3 | */ | 3 | */ |
| 4 | #include "test_progs.h" | 4 | #include "test_progs.h" |
| 5 | #include "cgroup_helpers.h" | ||
| 5 | #include "bpf_rlimit.h" | 6 | #include "bpf_rlimit.h" |
| 6 | #include <argp.h> | 7 | #include <argp.h> |
| 7 | #include <string.h> | 8 | #include <string.h> |
| @@ -17,6 +18,7 @@ struct prog_test_def { · 9 unmodified lines | |||
| 17 | int error_cnt; | 18 | int error_cnt; |
| 18 | int skip_cnt; | 19 | int skip_cnt; |
| 19 | bool tested; | 20 | bool tested; |
| 21 | bool need_cgroup_cleanup; | ||
| 20 | 22 | ||
| 21 | const char *subtest_name; | 23 | const char *subtest_name; |
| 22 | int subtest_num; | 24 | int subtest_num; |
| @@ -122,6 +124,39 @@ void test__fail(void) · 99 unmodified lines | |||
| 122 | env.test->error_cnt++; | 124 | env.test->error_cnt++; |
| 123 | } | 125 | } |
| 124 | 126 | ||
| 127 | int test__join_cgroup(const char *path) | ||
| 128 | { | ||
| 129 | int fd; | ||
| 130 | |||
| 131 | if (!env.test->need_cgroup_cleanup) { | ||
| 132 | if (setup_cgroup_environment()) { | ||
| 133 | fprintf(stderr, | ||
| 134 | "#%d %s: Failed to setup cgroup environment\n", | ||
| 135 | env.test->test_num, env.test->test_name); | ||
| 136 | return -1; | ||
| 137 | } | ||
| 138 | |||
| 139 | env.test->need_cgroup_cleanup = true; | ||
| 140 | } | ||
| 141 | |||
| 142 | fd = create_and_get_cgroup(path); | ||
| 143 | if (fd < 0) { | ||
| 144 | fprintf(stderr, | ||
| 145 | "#%d %s: Failed to create cgroup '%s' (errno=%d)\n", | ||
| 146 | env.test->test_num, env.test->test_name, path, errno); | ||
| 147 | return fd; | ||
| 148 | } | ||
| 149 | |||
| 150 | if (join_cgroup(path)) { | ||
| 151 | fprintf(stderr, | ||
| 152 | "#%d %s: Failed to join cgroup '%s' (errno=%d)\n", | ||
| 153 | env.test->test_num, env.test->test_name, path, errno); | ||
| 154 | return -1; | ||
| 155 | } | ||
| 156 | |||
| 157 | return fd; | ||
| 158 | } | ||
| 159 | |||
| 125 | struct ipv4_packet pkt_v4 = { | 160 | struct ipv4_packet pkt_v4 = { |
| 126 | .eth.h_proto = __bpf_constant_htons(ETH_P_IP), | 161 | .eth.h_proto = __bpf_constant_htons(ETH_P_IP), |
| 127 | .iph.ihl = 5, | 162 | .iph.ihl = 5, |
| @@ -530,6 +565,9 @@ int main(int argc, char **argv) · 402 unmodified lines | |||
| 530 | fprintf(env.stdout, "#%d %s:%s\n", | 565 | fprintf(env.stdout, "#%d %s:%s\n", |
| 531 | test->test_num, test->test_name, | 566 | test->test_num, test->test_name, |
| 532 | test->error_cnt ? "FAIL" : "OK"); | 567 | test->error_cnt ? "FAIL" : "OK"); |
| 568 | |||
| 569 | if (test->need_cgroup_cleanup) | ||
| 570 | cleanup_cgroup_environment(); | ||
| 533 | } | 571 | } |
| 534 | stdio_restore(); | 572 | stdio_restore(); |
| 535 | printf("Summary: %d/%d PASSED, %d SKIPPED, %d FAILED\n", | 573 | printf("Summary: %d/%d PASSED, %d SKIPPED, %d FAILED\n", |
| @@ -16,9 +16,10 @@ typedef __u16 __sum16; · 15 unmodified lines | |||
| 16 | #include <linux/if_packet.h> | 16 | #include <linux/if_packet.h> |
| 17 | #include <linux/ip.h> | 17 | #include <linux/ip.h> |
| 18 | #include <linux/ipv6.h> | 18 | #include <linux/ipv6.h> |
| 19 | #include <linux/tcp.h> | 19 | #include <netinet/tcp.h> |
| 20 | #include <linux/filter.h> | 20 | #include <linux/filter.h> |
| 21 | #include <linux/perf_event.h> | 21 | #include <linux/perf_event.h> |
| 22 | #include <linux/socket.h> | ||
| 22 | #include <linux/unistd.h> | 23 | #include <linux/unistd.h> |
| 23 | 24 | ||
| 24 | #include <sys/ioctl.h> | 25 | #include <sys/ioctl.h> |
| @@ -71,6 +72,7 @@ extern void test__force_log(); · 46 unmodified lines | |||
| 71 | extern bool test__start_subtest(const char *name); | 72 | extern bool test__start_subtest(const char *name); |
| 72 | extern void test__skip(void); | 73 | extern void test__skip(void); |
| 73 | extern void test__fail(void); | 74 | extern void test__fail(void); |
| 75 | extern int test__join_cgroup(const char *path); | ||
| 74 | 76 | ||
| 75 | #define MAGIC_BYTES 123 | 77 | #define MAGIC_BYTES 123 |
| 76 | 78 | ||
| @@ -32,6 +32,7 @@ struct sysctl_test { · 31 unmodified lines | |||
| 32 | enum bpf_attach_type attach_type; | 32 | enum bpf_attach_type attach_type; |
| 33 | const char *sysctl; | 33 | const char *sysctl; |
| 34 | int open_flags; | 34 | int open_flags; |
| 35 | int seek; | ||
| 35 | const char *newval; | 36 | const char *newval; |
| 36 | const char *oldval; | 37 | const char *oldval; |
| 37 | enum { | 38 | enum { |
| @@ -140,7 +141,7 @@ static struct sysctl_test tests[] = { · 102 unmodified lines | |||
| 140 | /* If (file_pos == X) */ | 141 | /* If (file_pos == X) */ |
| 141 | BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1, | 142 | BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1, |
| 142 | offsetof(struct bpf_sysctl, file_pos)), | 143 | offsetof(struct bpf_sysctl, file_pos)), |
| 143 | BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 2), | 144 | BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 3, 2), |
| 144 | 145 | ||
| 145 | /* return ALLOW; */ | 146 | /* return ALLOW; */ |
| 146 | BPF_MOV64_IMM(BPF_REG_0, 1), | 147 | BPF_MOV64_IMM(BPF_REG_0, 1), |
| @@ -153,6 +154,7 @@ static struct sysctl_test tests[] = { · 6 unmodified lines | |||
| 153 | .attach_type = BPF_CGROUP_SYSCTL, | 154 | .attach_type = BPF_CGROUP_SYSCTL, |
| 154 | .sysctl = "kernel/ostype", | 155 | .sysctl = "kernel/ostype", |
| 155 | .open_flags = O_RDONLY, | 156 | .open_flags = O_RDONLY, |
| 157 | .seek = 3, | ||
| 156 | .result = SUCCESS, | 158 | .result = SUCCESS, |
| 157 | }, | 159 | }, |
| 158 | { | 160 | { |
| @@ -1481,6 +1483,11 @@ static int access_sysctl(const char *sysctl_path, · 1322 unmodified lines | |||
| 1481 | if (fd < 0) | 1483 | if (fd < 0) |
| 1482 | return fd; | 1484 | return fd; |
| 1483 | 1485 | ||
| 1486 | if (test->seek && lseek(fd, test->seek, SEEK_SET) == -1) { | ||
| 1487 | log_err("lseek(%d) failed", test->seek); | ||
| 1488 | goto err; | ||
| 1489 | } | ||
| 1490 | |||
| 1484 | if (test->open_flags == O_RDONLY) { | 1491 | if (test->open_flags == O_RDONLY) { |
| 1485 | char buf[128]; | 1492 | char buf[128]; |
| 1486 | 1493 | ||