The BPF testing framework has evolved significantly over time. However, some legacy tests in the samples/bpf directory have not kept up with these changes. These outdated tests can cause confusion and increase maintenance efforts.
This patchset focuses on migrating outdated cgroup and tracing-related tests from samples/bpf to selftests/bpf, ensuring the BPF test suite remains current and efficient. Tests that are already covered by selftests/bpf are removed, while those not yet covered are migrated. This includes cgroup sock create tests for setting socket attributes and blocking socket creation, as well as the removal of redundant cgroup and tracing tests that have been replaced by newer tests.
This patchset covers the following cgroup/tracing tests: - test_overhead: tests the overhead of BPF programs with task_rename, now covered by selftests and benchmark tests (rename-*). [1]
- test_override_return: tests the return override functionality, now handled by kprobe_multi_override in selftests.
- test_probe_write_user: tests the probe_write_user functionality, now replaced by the probe_user test in selftests.
- test_cgrp2_sock: tests cgroup BPF's ability to set sk_bound_dev_if, mark, and priority during socket creation. Migrated to selftests as 'sock_create' since no existing tests fully cover this.
- test_cgrp2_sock2: tests blocking socket creation for specific types (AF_INET{6}, SOCK_DGRAM, IPPROTO_ICMP{V6}). Migrated to selftests in 'sock_create' test for coverage.
- test_current_task_under_cgroup: tests bpf_current_task_under_cgroup() to check if a task belongs to a cgroup. Already covered by task_under_cgroup at selftest and other cgroup ID tests.
- test_cgrp2_tc: tests bpf_skb_under_cgroup() to filter packets based on cgroup. This behavior is now validated by cgroup_skb_sk_lookup, which uses bpf_skb_cgroup_id, making this test redundant.
[1]: https://patchwork.kernel.org/cover/13759916
Daniel T. Lee (4): selftests/bpf: migrate cgroup sock create test for setting iface/mark/prio selftests/bpf: migrate cgroup sock create tests for prohibitig sockets samples/bpf: remove obsolete cgroup related tests samples/bpf: remove obsolete tracing related tests
--- Changes in v2: - commit message fix
samples/bpf/Makefile | 24 -- samples/bpf/sock_flags.bpf.c | 47 --- samples/bpf/test_cgrp2_array_pin.c | 106 ------ samples/bpf/test_cgrp2_attach.c | 177 ---------- samples/bpf/test_cgrp2_sock.c | 296 ---------------- samples/bpf/test_cgrp2_sock.sh | 137 ------- samples/bpf/test_cgrp2_sock2.c | 95 ----- samples/bpf/test_cgrp2_sock2.sh | 103 ------ samples/bpf/test_cgrp2_tc.bpf.c | 56 --- samples/bpf/test_cgrp2_tc.sh | 187 ---------- .../bpf/test_current_task_under_cgroup.bpf.c | 43 --- .../bpf/test_current_task_under_cgroup_user.c | 115 ------ samples/bpf/test_overhead_kprobe.bpf.c | 41 --- samples/bpf/test_overhead_raw_tp.bpf.c | 17 - samples/bpf/test_overhead_tp.bpf.c | 23 -- samples/bpf/test_overhead_user.c | 225 ------------ samples/bpf/test_override_return.sh | 16 - samples/bpf/test_probe_write_user.bpf.c | 52 --- samples/bpf/test_probe_write_user_user.c | 108 ------ samples/bpf/tracex7.bpf.c | 15 - samples/bpf/tracex7_user.c | 56 --- .../selftests/bpf/prog_tests/sock_create.c | 333 ++++++++++++++++++ 22 files changed, 333 insertions(+), 1939 deletions(-) delete mode 100644 samples/bpf/sock_flags.bpf.c delete mode 100644 samples/bpf/test_cgrp2_array_pin.c delete mode 100644 samples/bpf/test_cgrp2_attach.c delete mode 100644 samples/bpf/test_cgrp2_sock.c delete mode 100755 samples/bpf/test_cgrp2_sock.sh delete mode 100644 samples/bpf/test_cgrp2_sock2.c delete mode 100755 samples/bpf/test_cgrp2_sock2.sh delete mode 100644 samples/bpf/test_cgrp2_tc.bpf.c delete mode 100755 samples/bpf/test_cgrp2_tc.sh delete mode 100644 samples/bpf/test_current_task_under_cgroup.bpf.c delete mode 100644 samples/bpf/test_current_task_under_cgroup_user.c delete mode 100644 samples/bpf/test_overhead_kprobe.bpf.c delete mode 100644 samples/bpf/test_overhead_raw_tp.bpf.c delete mode 100644 samples/bpf/test_overhead_tp.bpf.c delete mode 100644 samples/bpf/test_overhead_user.c delete mode 100755 samples/bpf/test_override_return.sh delete mode 100644 samples/bpf/test_probe_write_user.bpf.c delete mode 100644 samples/bpf/test_probe_write_user_user.c delete mode 100644 samples/bpf/tracex7.bpf.c delete mode 100644 samples/bpf/tracex7_user.c create mode 100644 tools/testing/selftests/bpf/prog_tests/sock_create.c
-- 2.43.0
This patch migrates the old test for cgroup BPF that sets sk_bound_dev_if, mark, and priority when AF_INET{6} sockets are created. The most closely related tests under selftests are 'test_sock' and 'sockopt'. However, these existing tests serve different purposes. 'test_sock' focuses mainly on verifying the socket binding process, while 'sockopt' concentrates on testing the behavior of getsockopt and setsockopt operations for various socket options.
Neither of these existing tests directly covers the ability of cgroup BPF to set socket attributes such as sk_bound_dev_if, mark, and priority during socket creation. To address this gap, this patch introduces a migration of the old cgroup socket attribute test, now included as the 'sock_create' test in selftests/bpf. This ensures that the ability to configure these attributes during socket creation is properly tested.
Signed-off-by: Daniel T. Lee danieltimlee@gmail.com --- samples/bpf/Makefile | 2 - samples/bpf/test_cgrp2_sock.c | 296 ------------------ samples/bpf/test_cgrp2_sock.sh | 137 -------- .../selftests/bpf/prog_tests/sock_create.c | 256 +++++++++++++++ 4 files changed, 256 insertions(+), 435 deletions(-) delete mode 100644 samples/bpf/test_cgrp2_sock.c delete mode 100755 samples/bpf/test_cgrp2_sock.sh create mode 100644 tools/testing/selftests/bpf/prog_tests/sock_create.c
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index 7afe040cf43b..f514c6fb1ae2 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile @@ -27,7 +27,6 @@ tprogs-y += map_perf_test tprogs-y += test_overhead tprogs-y += test_cgrp2_array_pin tprogs-y += test_cgrp2_attach -tprogs-y += test_cgrp2_sock tprogs-y += test_cgrp2_sock2 tprogs-y += xdp_router_ipv4 tprogs-y += test_current_task_under_cgroup @@ -76,7 +75,6 @@ map_perf_test-objs := map_perf_test_user.o test_overhead-objs := test_overhead_user.o test_cgrp2_array_pin-objs := test_cgrp2_array_pin.o test_cgrp2_attach-objs := test_cgrp2_attach.o -test_cgrp2_sock-objs := test_cgrp2_sock.o test_cgrp2_sock2-objs := test_cgrp2_sock2.o test_current_task_under_cgroup-objs := $(CGROUP_HELPERS) \ test_current_task_under_cgroup_user.o diff --git a/samples/bpf/test_cgrp2_sock.c b/samples/bpf/test_cgrp2_sock.c deleted file mode 100644 index 8ca2a445ffa1..000000000000 --- a/samples/bpf/test_cgrp2_sock.c +++ /dev/null @@ -1,296 +0,0 @@ -/* eBPF example program: - * - * - Loads eBPF program - * - * The eBPF program sets the sk_bound_dev_if index in new AF_INET{6} - * sockets opened by processes in the cgroup. - * - * - Attaches the new program to a cgroup using BPF_PROG_ATTACH - */ - -#define _GNU_SOURCE - -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <string.h> -#include <unistd.h> -#include <assert.h> -#include <errno.h> -#include <fcntl.h> -#include <net/if.h> -#include <inttypes.h> -#include <linux/bpf.h> -#include <bpf/bpf.h> - -#include "bpf_insn.h" - -char bpf_log_buf[BPF_LOG_BUF_SIZE]; - -static int prog_load(__u32 idx, __u32 mark, __u32 prio) -{ - /* save pointer to context */ - struct bpf_insn prog_start[] = { - BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), - }; - struct bpf_insn prog_end[] = { - BPF_MOV64_IMM(BPF_REG_0, 1), /* r0 = verdict */ - BPF_EXIT_INSN(), - }; - - /* set sk_bound_dev_if on socket */ - struct bpf_insn prog_dev[] = { - BPF_MOV64_IMM(BPF_REG_3, idx), - BPF_MOV64_IMM(BPF_REG_2, offsetof(struct bpf_sock, bound_dev_if)), - BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3, offsetof(struct bpf_sock, bound_dev_if)), - }; - - /* set mark on socket */ - struct bpf_insn prog_mark[] = { - /* get uid of process */ - BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, - BPF_FUNC_get_current_uid_gid), - BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xffffffff), - - /* if uid is 0, use given mark, else use the uid as the mark */ - BPF_MOV64_REG(BPF_REG_3, BPF_REG_0), - BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), - BPF_MOV64_IMM(BPF_REG_3, mark), - - /* set the mark on the new socket */ - BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), - BPF_MOV64_IMM(BPF_REG_2, offsetof(struct bpf_sock, mark)), - BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3, offsetof(struct bpf_sock, mark)), - }; - - /* set priority on socket */ - struct bpf_insn prog_prio[] = { - BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), - BPF_MOV64_IMM(BPF_REG_3, prio), - BPF_MOV64_IMM(BPF_REG_2, offsetof(struct bpf_sock, priority)), - BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3, offsetof(struct bpf_sock, priority)), - }; - LIBBPF_OPTS(bpf_prog_load_opts, opts, - .log_buf = bpf_log_buf, - .log_size = BPF_LOG_BUF_SIZE, - ); - - struct bpf_insn *prog; - size_t insns_cnt; - void *p; - int ret; - - insns_cnt = sizeof(prog_start) + sizeof(prog_end); - if (idx) - insns_cnt += sizeof(prog_dev); - - if (mark) - insns_cnt += sizeof(prog_mark); - - if (prio) - insns_cnt += sizeof(prog_prio); - - p = prog = malloc(insns_cnt); - if (!prog) { - fprintf(stderr, "Failed to allocate memory for instructions\n"); - return EXIT_FAILURE; - } - - memcpy(p, prog_start, sizeof(prog_start)); - p += sizeof(prog_start); - - if (idx) { - memcpy(p, prog_dev, sizeof(prog_dev)); - p += sizeof(prog_dev); - } - - if (mark) { - memcpy(p, prog_mark, sizeof(prog_mark)); - p += sizeof(prog_mark); - } - - if (prio) { - memcpy(p, prog_prio, sizeof(prog_prio)); - p += sizeof(prog_prio); - } - - memcpy(p, prog_end, sizeof(prog_end)); - p += sizeof(prog_end); - - insns_cnt /= sizeof(struct bpf_insn); - - ret = bpf_prog_load(BPF_PROG_TYPE_CGROUP_SOCK, NULL, "GPL", - prog, insns_cnt, &opts); - - free(prog); - - return ret; -} - -static int get_bind_to_device(int sd, char *name, size_t len) -{ - socklen_t optlen = len; - int rc; - - name[0] = '\0'; - rc = getsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, name, &optlen); - if (rc < 0) - perror("setsockopt(SO_BINDTODEVICE)"); - - return rc; -} - -static unsigned int get_somark(int sd) -{ - unsigned int mark = 0; - socklen_t optlen = sizeof(mark); - int rc; - - rc = getsockopt(sd, SOL_SOCKET, SO_MARK, &mark, &optlen); - if (rc < 0) - perror("getsockopt(SO_MARK)"); - - return mark; -} - -static unsigned int get_priority(int sd) -{ - unsigned int prio = 0; - socklen_t optlen = sizeof(prio); - int rc; - - rc = getsockopt(sd, SOL_SOCKET, SO_PRIORITY, &prio, &optlen); - if (rc < 0) - perror("getsockopt(SO_PRIORITY)"); - - return prio; -} - -static int show_sockopts(int family) -{ - unsigned int mark, prio; - char name[16]; - int sd; - - sd = socket(family, SOCK_DGRAM, 17); - if (sd < 0) { - perror("socket"); - return 1; - } - - if (get_bind_to_device(sd, name, sizeof(name)) < 0) { - close(sd); - return 1; - } - - mark = get_somark(sd); - prio = get_priority(sd); - - close(sd); - - printf("sd %d: dev %s, mark %u, priority %u\n", sd, name, mark, prio); - - return 0; -} - -static int usage(const char *argv0) -{ - printf("Usage:\n"); - printf(" Attach a program\n"); - printf(" %s -b bind-to-dev -m mark -p prio cg-path\n", argv0); - printf("\n"); - printf(" Detach a program\n"); - printf(" %s -d cg-path\n", argv0); - printf("\n"); - printf(" Show inherited socket settings (mark, priority, and device)\n"); - printf(" %s [-6]\n", argv0); - return EXIT_FAILURE; -} - -int main(int argc, char **argv) -{ - __u32 idx = 0, mark = 0, prio = 0; - const char *cgrp_path = NULL; - int cg_fd, prog_fd, ret; - int family = PF_INET; - int do_attach = 1; - int rc; - - while ((rc = getopt(argc, argv, "db:m:p:6")) != -1) { - switch (rc) { - case 'd': - do_attach = 0; - break; - case 'b': - idx = if_nametoindex(optarg); - if (!idx) { - idx = strtoumax(optarg, NULL, 0); - if (!idx) { - printf("Invalid device name\n"); - return EXIT_FAILURE; - } - } - break; - case 'm': - mark = strtoumax(optarg, NULL, 0); - break; - case 'p': - prio = strtoumax(optarg, NULL, 0); - break; - case '6': - family = PF_INET6; - break; - default: - return usage(argv[0]); - } - } - - if (optind == argc) - return show_sockopts(family); - - cgrp_path = argv[optind]; - if (!cgrp_path) { - fprintf(stderr, "cgroup path not given\n"); - return EXIT_FAILURE; - } - - if (do_attach && !idx && !mark && !prio) { - fprintf(stderr, - "One of device, mark or priority must be given\n"); - return EXIT_FAILURE; - } - - cg_fd = open(cgrp_path, O_DIRECTORY | O_RDONLY); - if (cg_fd < 0) { - printf("Failed to open cgroup path: '%s'\n", strerror(errno)); - return EXIT_FAILURE; - } - - if (do_attach) { - prog_fd = prog_load(idx, mark, prio); - if (prog_fd < 0) { - printf("Failed to load prog: '%s'\n", strerror(errno)); - printf("Output from kernel verifier:\n%s\n-------\n", - bpf_log_buf); - return EXIT_FAILURE; - } - - ret = bpf_prog_attach(prog_fd, cg_fd, - BPF_CGROUP_INET_SOCK_CREATE, 0); - if (ret < 0) { - printf("Failed to attach prog to cgroup: '%s'\n", - strerror(errno)); - return EXIT_FAILURE; - } - } else { - ret = bpf_prog_detach(cg_fd, BPF_CGROUP_INET_SOCK_CREATE); - if (ret < 0) { - printf("Failed to detach prog from cgroup: '%s'\n", - strerror(errno)); - return EXIT_FAILURE; - } - } - - close(cg_fd); - return EXIT_SUCCESS; -} diff --git a/samples/bpf/test_cgrp2_sock.sh b/samples/bpf/test_cgrp2_sock.sh deleted file mode 100755 index 36bd7cb46f06..000000000000 --- a/samples/bpf/test_cgrp2_sock.sh +++ /dev/null @@ -1,137 +0,0 @@ -#!/bin/sh -# SPDX-License-Identifier: GPL-2.0 - -# Test various socket options that can be set by attaching programs to cgroups. - -MY_DIR=$(dirname $0) -TEST=$MY_DIR/test_cgrp2_sock -CGRP_MNT="/tmp/cgroupv2-test_cgrp2_sock" - -################################################################################ -# -print_result() -{ - local rc=$1 - local status=" OK " - - [ $rc -ne 0 ] && status="FAIL" - - printf "%-50s [%4s]\n" "$2" "$status" -} - -check_sock() -{ - out=$($TEST) - echo $out | grep -q "$1" - if [ $? -ne 0 ]; then - print_result 1 "IPv4: $2" - echo " expected: $1" - echo " have: $out" - rc=1 - else - print_result 0 "IPv4: $2" - fi -} - -check_sock6() -{ - out=$($TEST -6) - echo $out | grep -q "$1" - if [ $? -ne 0 ]; then - print_result 1 "IPv6: $2" - echo " expected: $1" - echo " have: $out" - rc=1 - else - print_result 0 "IPv6: $2" - fi -} - -################################################################################ -# - -cleanup() -{ - echo $$ >> ${CGRP_MNT}/cgroup.procs - rmdir ${CGRP_MNT}/sockopts -} - -cleanup_and_exit() -{ - local rc=$1 - local msg="$2" - - [ -n "$msg" ] && echo "ERROR: $msg" - - $TEST -d ${CGRP_MNT}/sockopts - ip li del cgrp2_sock - umount ${CGRP_MNT} - - exit $rc -} - - -################################################################################ -# main - -rc=0 - -ip li add cgrp2_sock type dummy 2>/dev/null - -set -e -mkdir -p ${CGRP_MNT} -mount -t cgroup2 none ${CGRP_MNT} -set +e - - -# make sure we have a known start point -cleanup 2>/dev/null - -mkdir -p ${CGRP_MNT}/sockopts -[ $? -ne 0 ] && cleanup_and_exit 1 "Failed to create cgroup hierarchy" - - -# set pid into cgroup -echo $$ > ${CGRP_MNT}/sockopts/cgroup.procs - -# no bpf program attached, so socket should show no settings -check_sock "dev , mark 0, priority 0" "No programs attached" -check_sock6 "dev , mark 0, priority 0" "No programs attached" - -# verify device is set -# -$TEST -b cgrp2_sock ${CGRP_MNT}/sockopts -if [ $? -ne 0 ]; then - cleanup_and_exit 1 "Failed to install program to set device" -fi -check_sock "dev cgrp2_sock, mark 0, priority 0" "Device set" -check_sock6 "dev cgrp2_sock, mark 0, priority 0" "Device set" - -# verify mark is set -# -$TEST -m 666 ${CGRP_MNT}/sockopts -if [ $? -ne 0 ]; then - cleanup_and_exit 1 "Failed to install program to set mark" -fi -check_sock "dev , mark 666, priority 0" "Mark set" -check_sock6 "dev , mark 666, priority 0" "Mark set" - -# verify priority is set -# -$TEST -p 123 ${CGRP_MNT}/sockopts -if [ $? -ne 0 ]; then - cleanup_and_exit 1 "Failed to install program to set priority" -fi -check_sock "dev , mark 0, priority 123" "Priority set" -check_sock6 "dev , mark 0, priority 123" "Priority set" - -# all 3 at once -# -$TEST -b cgrp2_sock -m 666 -p 123 ${CGRP_MNT}/sockopts -if [ $? -ne 0 ]; then - cleanup_and_exit 1 "Failed to install program to set device, mark and priority" -fi -check_sock "dev cgrp2_sock, mark 666, priority 123" "Priority set" -check_sock6 "dev cgrp2_sock, mark 666, priority 123" "Priority set" - -cleanup_and_exit $rc diff --git a/tools/testing/selftests/bpf/prog_tests/sock_create.c b/tools/testing/selftests/bpf/prog_tests/sock_create.c new file mode 100644 index 000000000000..072910c05c99 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/sock_create.c @@ -0,0 +1,256 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <linux/bpf.h> +#include <test_progs.h> +#include "cgroup_helpers.h" + +static char bpf_log_buf[4096]; +static bool verbose; + +static struct sock_create_test { + const char *descr; + const struct bpf_insn insns[64]; + enum bpf_attach_type attach_type; + enum bpf_attach_type expected_attach_type; + + int domain; + int type; + + int optname; + int optval; +} tests[] = { + { + .descr = "AF_INET set priority", + .insns = { + /* r3 = 123 (priority) */ + BPF_MOV64_IMM(BPF_REG_3, 123), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3, + offsetof(struct bpf_sock, priority)), + + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .expected_attach_type = BPF_CGROUP_INET_SOCK_CREATE, + .attach_type = BPF_CGROUP_INET_SOCK_CREATE, + + .domain = AF_INET, + .type = SOCK_DGRAM, + + .optname = SO_PRIORITY, + .optval = 123, + }, + { + .descr = "AF_INET6 set priority", + .insns = { + /* r3 = 123 (priority) */ + BPF_MOV64_IMM(BPF_REG_3, 123), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3, + offsetof(struct bpf_sock, priority)), + + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .expected_attach_type = BPF_CGROUP_INET_SOCK_CREATE, + .attach_type = BPF_CGROUP_INET_SOCK_CREATE, + + .domain = AF_INET6, + .type = SOCK_DGRAM, + + .optname = SO_PRIORITY, + .optval = 123, + }, + { + .descr = "AF_INET set mark", + .insns = { + BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), + + /* get uid of process */ + BPF_EMIT_CALL(BPF_FUNC_get_current_uid_gid), + BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xffffffff), + + /* if uid is 0, use given mark(666), else use uid as the mark */ + BPF_MOV64_REG(BPF_REG_3, BPF_REG_0), + BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), + BPF_MOV64_IMM(BPF_REG_3, 666), + + BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3, + offsetof(struct bpf_sock, mark)), + + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .expected_attach_type = BPF_CGROUP_INET_SOCK_CREATE, + .attach_type = BPF_CGROUP_INET_SOCK_CREATE, + + .domain = AF_INET, + .type = SOCK_DGRAM, + + .optname = SO_MARK, + .optval = 666, + }, + { + .descr = "AF_INET6 set mark", + .insns = { + BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), + + /* get uid of process */ + BPF_EMIT_CALL(BPF_FUNC_get_current_uid_gid), + BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xffffffff), + + /* if uid is 0, use given mark(666), else use uid as the mark */ + BPF_MOV64_REG(BPF_REG_3, BPF_REG_0), + BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), + BPF_MOV64_IMM(BPF_REG_3, 666), + + BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3, + offsetof(struct bpf_sock, mark)), + + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .expected_attach_type = BPF_CGROUP_INET_SOCK_CREATE, + .attach_type = BPF_CGROUP_INET_SOCK_CREATE, + + .domain = AF_INET6, + .type = SOCK_DGRAM, + + .optname = SO_MARK, + .optval = 666, + }, + { + .descr = "AF_INET bound to iface", + .insns = { + /* r3 = 1 (lo interface) */ + BPF_MOV64_IMM(BPF_REG_3, 1), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3, + offsetof(struct bpf_sock, bound_dev_if)), + + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .expected_attach_type = BPF_CGROUP_INET_SOCK_CREATE, + .attach_type = BPF_CGROUP_INET_SOCK_CREATE, + + .domain = AF_INET, + .type = SOCK_DGRAM, + + .optname = SO_BINDTOIFINDEX, + .optval = 1, + }, + { + .descr = "AF_INET6 bound to iface", + .insns = { + /* r3 = 1 (lo interface) */ + BPF_MOV64_IMM(BPF_REG_3, 1), + BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3, + offsetof(struct bpf_sock, bound_dev_if)), + + /* return 1 */ + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .expected_attach_type = BPF_CGROUP_INET_SOCK_CREATE, + .attach_type = BPF_CGROUP_INET_SOCK_CREATE, + + .domain = AF_INET6, + .type = SOCK_DGRAM, + + .optname = SO_BINDTOIFINDEX, + .optval = 1, + }, +}; + +static int load_prog(const struct bpf_insn *insns, + enum bpf_attach_type expected_attach_type) +{ + LIBBPF_OPTS(bpf_prog_load_opts, opts, + .expected_attach_type = expected_attach_type, + .log_level = 2, + .log_buf = bpf_log_buf, + .log_size = sizeof(bpf_log_buf), + ); + int fd, insns_cnt = 0; + + for (; + insns[insns_cnt].code != (BPF_JMP | BPF_EXIT); + insns_cnt++) { + } + insns_cnt++; + + fd = bpf_prog_load(BPF_PROG_TYPE_CGROUP_SOCK, NULL, "GPL", insns, + insns_cnt, &opts); + if (verbose && fd < 0) + fprintf(stderr, "%s\n", bpf_log_buf); + + return fd; +} + +static int run_test(int cgroup_fd, struct sock_create_test *test) +{ + int sock_fd, err, prog_fd, optval, ret = -1; + socklen_t optlen = sizeof(optval); + + prog_fd = load_prog(test->insns, test->expected_attach_type); + if (prog_fd < 0) { + log_err("Failed to load BPF program"); + return -1; + } + + err = bpf_prog_attach(prog_fd, cgroup_fd, test->attach_type, 0); + if (err < 0) { + log_err("Failed to attach BPF program"); + goto close_prog_fd; + } + + sock_fd = socket(test->domain, test->type, 0); + if (sock_fd < 0) { + log_err("Failed to create socket"); + goto detach_prog; + } + + err = getsockopt(sock_fd, SOL_SOCKET, test->optname, &optval, &optlen); + if (err) { + log_err("Failed to call getsockopt"); + goto cleanup; + } + + if (optval != test->optval) { + errno = 0; + log_err("getsockopt returned unexpected optval"); + goto cleanup; + } + + ret = 0; + +cleanup: + close(sock_fd); +detach_prog: + bpf_prog_detach2(prog_fd, cgroup_fd, test->attach_type); +close_prog_fd: + close(prog_fd); + return ret; +} + +void test_sock_create(void) +{ + int cgroup_fd, i; + + cgroup_fd = test__join_cgroup("/sock_create"); + if (!ASSERT_GE(cgroup_fd, 0, "join_cgroup")) + return; + + for (i = 0; i < ARRAY_SIZE(tests); i++) { + if (!test__start_subtest(tests[i].descr)) + continue; + + ASSERT_OK(run_test(cgroup_fd, &tests[i]), tests[i].descr); + } + + close(cgroup_fd); +}
This patch continues the migration and removal process for cgroup sock_create tests to selftests.
The test being migrated verifies the ability of cgroup BPF to block the creation of specific types of sockets using a verdict. Specifically, the test denies socket creation when the socket is of type AF_INET{6}, SOCK_DGRAM, and IPPROTO_ICMP{V6}. If the requested socket type matches these attributes, the cgroup BPF verdict blocks the socket creation.
As with the previous commit, this test currently lacks coverage in selftests, so this patch migrates the functionality into the sock_create tests under selftests. This migration ensures that the socket creation blocking behavior with cgroup bpf program is properly tested within the selftest framework.
Signed-off-by: Daniel T. Lee danieltimlee@gmail.com --- Chagnes in V2: - commit message fix
--- samples/bpf/Makefile | 2 - samples/bpf/sock_flags.bpf.c | 47 -------- samples/bpf/test_cgrp2_sock2.c | 95 ---------------- samples/bpf/test_cgrp2_sock2.sh | 103 ------------------ .../selftests/bpf/prog_tests/sock_create.c | 83 +++++++++++++- 5 files changed, 80 insertions(+), 250 deletions(-) delete mode 100644 samples/bpf/sock_flags.bpf.c delete mode 100644 samples/bpf/test_cgrp2_sock2.c delete mode 100755 samples/bpf/test_cgrp2_sock2.sh
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index f514c6fb1ae2..cdfda15e859c 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile @@ -27,7 +27,6 @@ tprogs-y += map_perf_test tprogs-y += test_overhead tprogs-y += test_cgrp2_array_pin tprogs-y += test_cgrp2_attach -tprogs-y += test_cgrp2_sock2 tprogs-y += xdp_router_ipv4 tprogs-y += test_current_task_under_cgroup tprogs-y += trace_event @@ -75,7 +74,6 @@ map_perf_test-objs := map_perf_test_user.o test_overhead-objs := test_overhead_user.o test_cgrp2_array_pin-objs := test_cgrp2_array_pin.o test_cgrp2_attach-objs := test_cgrp2_attach.o -test_cgrp2_sock2-objs := test_cgrp2_sock2.o test_current_task_under_cgroup-objs := $(CGROUP_HELPERS) \ test_current_task_under_cgroup_user.o trace_event-objs := trace_event_user.o $(TRACE_HELPERS) diff --git a/samples/bpf/sock_flags.bpf.c b/samples/bpf/sock_flags.bpf.c deleted file mode 100644 index 0da749f6a9e1..000000000000 --- a/samples/bpf/sock_flags.bpf.c +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "vmlinux.h" -#include "net_shared.h" -#include <bpf/bpf_helpers.h> - -SEC("cgroup/sock") -int bpf_prog1(struct bpf_sock *sk) -{ - char fmt[] = "socket: family %d type %d protocol %d\n"; - char fmt2[] = "socket: uid %u gid %u\n"; - __u64 gid_uid = bpf_get_current_uid_gid(); - __u32 uid = gid_uid & 0xffffffff; - __u32 gid = gid_uid >> 32; - - bpf_trace_printk(fmt, sizeof(fmt), sk->family, sk->type, sk->protocol); - bpf_trace_printk(fmt2, sizeof(fmt2), uid, gid); - - /* block AF_INET6, SOCK_DGRAM, IPPROTO_ICMPV6 sockets - * ie., make ping6 fail - */ - if (sk->family == AF_INET6 && - sk->type == SOCK_DGRAM && - sk->protocol == IPPROTO_ICMPV6) - return 0; - - return 1; -} - -SEC("cgroup/sock") -int bpf_prog2(struct bpf_sock *sk) -{ - char fmt[] = "socket: family %d type %d protocol %d\n"; - - bpf_trace_printk(fmt, sizeof(fmt), sk->family, sk->type, sk->protocol); - - /* block AF_INET, SOCK_DGRAM, IPPROTO_ICMP sockets - * ie., make ping fail - */ - if (sk->family == AF_INET && - sk->type == SOCK_DGRAM && - sk->protocol == IPPROTO_ICMP) - return 0; - - return 1; -} - -char _license[] SEC("license") = "GPL"; diff --git a/samples/bpf/test_cgrp2_sock2.c b/samples/bpf/test_cgrp2_sock2.c deleted file mode 100644 index e7060aaa2f5a..000000000000 --- a/samples/bpf/test_cgrp2_sock2.c +++ /dev/null @@ -1,95 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* eBPF example program: - * - * - Loads eBPF program - * - * The eBPF program loads a filter from file and attaches the - * program to a cgroup using BPF_PROG_ATTACH - */ - -#define _GNU_SOURCE - -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <string.h> -#include <unistd.h> -#include <assert.h> -#include <errno.h> -#include <fcntl.h> -#include <net/if.h> -#include <linux/bpf.h> -#include <bpf/bpf.h> -#include <bpf/libbpf.h> - -#include "bpf_insn.h" - -static int usage(const char *argv0) -{ - printf("Usage: %s cg-path filter-path [filter-id]\n", argv0); - return EXIT_FAILURE; -} - -int main(int argc, char **argv) -{ - int cg_fd, err, ret = EXIT_FAILURE, filter_id = 0, prog_cnt = 0; - const char *link_pin_path = "/sys/fs/bpf/test_cgrp2_sock2"; - struct bpf_link *link = NULL; - struct bpf_program *progs[2]; - struct bpf_program *prog; - struct bpf_object *obj; - - if (argc < 3) - return usage(argv[0]); - - if (argc > 3) - filter_id = atoi(argv[3]); - - cg_fd = open(argv[1], O_DIRECTORY | O_RDONLY); - if (cg_fd < 0) { - printf("Failed to open cgroup path: '%s'\n", strerror(errno)); - return ret; - } - - obj = bpf_object__open_file(argv[2], NULL); - if (libbpf_get_error(obj)) { - printf("ERROR: opening BPF object file failed\n"); - return ret; - } - - bpf_object__for_each_program(prog, obj) { - progs[prog_cnt] = prog; - prog_cnt++; - } - - if (filter_id >= prog_cnt) { - printf("Invalid program id; program not found in file\n"); - goto cleanup; - } - - /* load BPF program */ - if (bpf_object__load(obj)) { - printf("ERROR: loading BPF object file failed\n"); - goto cleanup; - } - - link = bpf_program__attach_cgroup(progs[filter_id], cg_fd); - if (libbpf_get_error(link)) { - printf("ERROR: bpf_program__attach failed\n"); - link = NULL; - goto cleanup; - } - - err = bpf_link__pin(link, link_pin_path); - if (err < 0) { - printf("ERROR: bpf_link__pin failed: %d\n", err); - goto cleanup; - } - - ret = EXIT_SUCCESS; - -cleanup: - bpf_link__destroy(link); - bpf_object__close(obj); - return ret; -} diff --git a/samples/bpf/test_cgrp2_sock2.sh b/samples/bpf/test_cgrp2_sock2.sh deleted file mode 100755 index 82acff93d739..000000000000 --- a/samples/bpf/test_cgrp2_sock2.sh +++ /dev/null @@ -1,103 +0,0 @@ -#!/bin/bash -# SPDX-License-Identifier: GPL-2.0 - -BPFFS=/sys/fs/bpf -MY_DIR=$(dirname $0) -TEST=$MY_DIR/test_cgrp2_sock2 -LINK_PIN=$BPFFS/test_cgrp2_sock2 -BPF_PROG=$MY_DIR/sock_flags.bpf.o - -function config_device { - ip netns add at_ns0 - ip link add veth0 type veth peer name veth0b - ip link set veth0 netns at_ns0 - ip netns exec at_ns0 sysctl -q net.ipv6.conf.veth0.disable_ipv6=0 - ip netns exec at_ns0 ip addr add 172.16.1.100/24 dev veth0 - ip netns exec at_ns0 ip addr add 2401:db00::1/64 dev veth0 nodad - ip netns exec at_ns0 ip link set dev veth0 up - sysctl -q net.ipv6.conf.veth0b.disable_ipv6=0 - ip addr add 172.16.1.101/24 dev veth0b - ip addr add 2401:db00::2/64 dev veth0b nodad - ip link set veth0b up -} - -function config_cgroup { - rm -rf /tmp/cgroupv2 - mkdir -p /tmp/cgroupv2 - mount -t cgroup2 none /tmp/cgroupv2 - mkdir -p /tmp/cgroupv2/foo - echo $$ >> /tmp/cgroupv2/foo/cgroup.procs -} - -function config_bpffs { - if mount | grep $BPFFS > /dev/null; then - echo "bpffs already mounted" - else - echo "bpffs not mounted. Mounting..." - mount -t bpf none $BPFFS - fi -} - -function attach_bpf { - $TEST /tmp/cgroupv2/foo $BPF_PROG $1 - [ $? -ne 0 ] && exit 1 -} - -function cleanup { - rm -rf $LINK_PIN - ip link del veth0b - ip netns delete at_ns0 - umount /tmp/cgroupv2 - rm -rf /tmp/cgroupv2 -} - -cleanup 2>/dev/null - -set -e -config_device -config_cgroup -config_bpffs -set +e - -# -# Test 1 - fail ping6 -# -attach_bpf 0 -ping -c1 -w1 172.16.1.100 -if [ $? -ne 0 ]; then - echo "ping failed when it should succeed" - cleanup - exit 1 -fi - -ping6 -c1 -w1 2401:db00::1 -if [ $? -eq 0 ]; then - echo "ping6 succeeded when it should not" - cleanup - exit 1 -fi - -rm -rf $LINK_PIN -sleep 1 # Wait for link detach - -# -# Test 2 - fail ping -# -attach_bpf 1 -ping6 -c1 -w1 2401:db00::1 -if [ $? -ne 0 ]; then - echo "ping6 failed when it should succeed" - cleanup - exit 1 -fi - -ping -c1 -w1 172.16.1.100 -if [ $? -eq 0 ]; then - echo "ping succeeded when it should not" - cleanup - exit 1 -fi - -cleanup -echo -echo "*** PASS ***" diff --git a/tools/testing/selftests/bpf/prog_tests/sock_create.c b/tools/testing/selftests/bpf/prog_tests/sock_create.c index 072910c05c99..17a3713621dd 100644 --- a/tools/testing/selftests/bpf/prog_tests/sock_create.c +++ b/tools/testing/selftests/bpf/prog_tests/sock_create.c @@ -6,6 +6,11 @@ static char bpf_log_buf[4096]; static bool verbose;
+enum sock_create_test_error { + OK = 0, + DENY_CREATE, +}; + static struct sock_create_test { const char *descr; const struct bpf_insn insns[64]; @@ -14,9 +19,11 @@ static struct sock_create_test {
int domain; int type; + int protocol;
int optname; int optval; + enum sock_create_test_error error; } tests[] = { { .descr = "AF_INET set priority", @@ -164,6 +171,72 @@ static struct sock_create_test { .optname = SO_BINDTOIFINDEX, .optval = 1, }, + { + .descr = "block AF_INET, SOCK_DGRAM, IPPROTO_ICMP socket", + .insns = { + BPF_MOV64_IMM(BPF_REG_0, 1), /* r0 = verdict */ + + /* sock->family == AF_INET */ + BPF_LDX_MEM(BPF_H, BPF_REG_2, BPF_REG_1, + offsetof(struct bpf_sock, family)), + BPF_JMP_IMM(BPF_JNE, BPF_REG_2, AF_INET, 5), + + /* sock->type == SOCK_DGRAM */ + BPF_LDX_MEM(BPF_H, BPF_REG_2, BPF_REG_1, + offsetof(struct bpf_sock, type)), + BPF_JMP_IMM(BPF_JNE, BPF_REG_2, SOCK_DGRAM, 3), + + /* sock->protocol == IPPROTO_ICMP */ + BPF_LDX_MEM(BPF_H, BPF_REG_2, BPF_REG_1, + offsetof(struct bpf_sock, protocol)), + BPF_JMP_IMM(BPF_JNE, BPF_REG_2, IPPROTO_ICMP, 1), + + /* return 0 (block) */ + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, + .expected_attach_type = BPF_CGROUP_INET_SOCK_CREATE, + .attach_type = BPF_CGROUP_INET_SOCK_CREATE, + + .domain = AF_INET, + .type = SOCK_DGRAM, + .protocol = IPPROTO_ICMP, + + .error = DENY_CREATE, + }, + { + .descr = "block AF_INET6, SOCK_DGRAM, IPPROTO_ICMPV6 socket", + .insns = { + BPF_MOV64_IMM(BPF_REG_0, 1), /* r0 = verdict */ + + /* sock->family == AF_INET6 */ + BPF_LDX_MEM(BPF_H, BPF_REG_2, BPF_REG_1, + offsetof(struct bpf_sock, family)), + BPF_JMP_IMM(BPF_JNE, BPF_REG_2, AF_INET6, 5), + + /* sock->type == SOCK_DGRAM */ + BPF_LDX_MEM(BPF_H, BPF_REG_2, BPF_REG_1, + offsetof(struct bpf_sock, type)), + BPF_JMP_IMM(BPF_JNE, BPF_REG_2, SOCK_DGRAM, 3), + + /* sock->protocol == IPPROTO_ICMPV6 */ + BPF_LDX_MEM(BPF_H, BPF_REG_2, BPF_REG_1, + offsetof(struct bpf_sock, protocol)), + BPF_JMP_IMM(BPF_JNE, BPF_REG_2, IPPROTO_ICMPV6, 1), + + /* return 0 (block) */ + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_EXIT_INSN(), + }, + .expected_attach_type = BPF_CGROUP_INET_SOCK_CREATE, + .attach_type = BPF_CGROUP_INET_SOCK_CREATE, + + .domain = AF_INET, + .type = SOCK_DGRAM, + .protocol = IPPROTO_ICMPV6, + + .error = DENY_CREATE, + }, };
static int load_prog(const struct bpf_insn *insns, @@ -208,9 +281,13 @@ static int run_test(int cgroup_fd, struct sock_create_test *test) goto close_prog_fd; }
- sock_fd = socket(test->domain, test->type, 0); + sock_fd = socket(test->domain, test->type, test->protocol); if (sock_fd < 0) { - log_err("Failed to create socket"); + if (test->error == DENY_CREATE) + ret = 0; + else + log_err("Failed to create socket"); + goto detach_prog; }
@@ -226,7 +303,7 @@ static int run_test(int cgroup_fd, struct sock_create_test *test) goto cleanup; }
- ret = 0; + ret = test->error != OK;
cleanup: close(sock_fd); -- 2.43.0
This patch removes the obsolete cgroup related tests. These tests are now redundant because their functionality is already covered by more modern and comprehensive tests under selftests/bpf.
The following files are removed: - test_current_task_under_cgroup: tests bpf_current_task_under_cgroup() to check if a task belongs to a cgroup. Already covered by task_under_cgroup at selftest and other cgroup ID tests.
- test_cgrp2_tc: tests bpf_skb_under_cgroup() to filter packets based on cgroup. This behavior is now validated by cgroup_skb_sk_lookup, which uses bpf_skb_cgroup_id, making this test redundant.
By removing these outdated tests, this patch helps streamline and modernize the test suite, avoiding duplication of test coverage.
Signed-off-by: Daniel T. Lee danieltimlee@gmail.com --- samples/bpf/Makefile | 9 - samples/bpf/test_cgrp2_array_pin.c | 106 ---------- samples/bpf/test_cgrp2_attach.c | 177 ----------------- samples/bpf/test_cgrp2_tc.bpf.c | 56 ------ samples/bpf/test_cgrp2_tc.sh | 187 ------------------ .../bpf/test_current_task_under_cgroup.bpf.c | 43 ---- .../bpf/test_current_task_under_cgroup_user.c | 115 ----------- 7 files changed, 693 deletions(-) delete mode 100644 samples/bpf/test_cgrp2_array_pin.c delete mode 100644 samples/bpf/test_cgrp2_attach.c delete mode 100644 samples/bpf/test_cgrp2_tc.bpf.c delete mode 100755 samples/bpf/test_cgrp2_tc.sh delete mode 100644 samples/bpf/test_current_task_under_cgroup.bpf.c delete mode 100644 samples/bpf/test_current_task_under_cgroup_user.c
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index cdfda15e859c..66827dbb93b3 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile @@ -25,10 +25,8 @@ tprogs-y += offwaketime tprogs-y += spintest tprogs-y += map_perf_test tprogs-y += test_overhead -tprogs-y += test_cgrp2_array_pin tprogs-y += test_cgrp2_attach tprogs-y += xdp_router_ipv4 -tprogs-y += test_current_task_under_cgroup tprogs-y += trace_event tprogs-y += sampleip tprogs-y += tc_l2_redirect @@ -71,11 +69,6 @@ lathist-objs := lathist_user.o offwaketime-objs := offwaketime_user.o $(TRACE_HELPERS) spintest-objs := spintest_user.o $(TRACE_HELPERS) map_perf_test-objs := map_perf_test_user.o -test_overhead-objs := test_overhead_user.o -test_cgrp2_array_pin-objs := test_cgrp2_array_pin.o -test_cgrp2_attach-objs := test_cgrp2_attach.o -test_current_task_under_cgroup-objs := $(CGROUP_HELPERS) \ - test_current_task_under_cgroup_user.o trace_event-objs := trace_event_user.o $(TRACE_HELPERS) sampleip-objs := sampleip_user.o $(TRACE_HELPERS) tc_l2_redirect-objs := tc_l2_redirect_user.o @@ -117,8 +110,6 @@ always-y += test_overhead_tp.bpf.o always-y += test_overhead_raw_tp.bpf.o always-y += test_overhead_kprobe.bpf.o always-y += parse_varlen.o parse_simple.o parse_ldabs.o -always-y += test_cgrp2_tc.bpf.o -always-y += test_current_task_under_cgroup.bpf.o always-y += trace_event_kern.o always-y += sampleip_kern.o always-y += lwt_len_hist.bpf.o diff --git a/samples/bpf/test_cgrp2_array_pin.c b/samples/bpf/test_cgrp2_array_pin.c deleted file mode 100644 index 05e88aa63009..000000000000 --- a/samples/bpf/test_cgrp2_array_pin.c +++ /dev/null @@ -1,106 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2016 Facebook - */ -#include <linux/unistd.h> -#include <linux/bpf.h> - -#include <stdio.h> -#include <stdint.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <fcntl.h> - -#include <bpf/bpf.h> - -static void usage(void) -{ - printf("Usage: test_cgrp2_array_pin [...]\n"); - printf(" -F <file> File to pin an BPF cgroup array\n"); - printf(" -U <file> Update an already pinned BPF cgroup array\n"); - printf(" -v <value> Full path of the cgroup2\n"); - printf(" -h Display this help\n"); -} - -int main(int argc, char **argv) -{ - const char *pinned_file = NULL, *cg2 = NULL; - int create_array = 1; - int array_key = 0; - int array_fd = -1; - int cg2_fd = -1; - int ret = -1; - int opt; - - while ((opt = getopt(argc, argv, "F:U:v:")) != -1) { - switch (opt) { - /* General args */ - case 'F': - pinned_file = optarg; - break; - case 'U': - pinned_file = optarg; - create_array = 0; - break; - case 'v': - cg2 = optarg; - break; - default: - usage(); - goto out; - } - } - - if (!cg2 || !pinned_file) { - usage(); - goto out; - } - - cg2_fd = open(cg2, O_RDONLY); - if (cg2_fd < 0) { - fprintf(stderr, "open(%s,...): %s(%d)\n", - cg2, strerror(errno), errno); - goto out; - } - - if (create_array) { - array_fd = bpf_map_create(BPF_MAP_TYPE_CGROUP_ARRAY, NULL, - sizeof(uint32_t), sizeof(uint32_t), - 1, NULL); - if (array_fd < 0) { - fprintf(stderr, - "bpf_create_map(BPF_MAP_TYPE_CGROUP_ARRAY,...): %s(%d)\n", - strerror(errno), errno); - goto out; - } - } else { - array_fd = bpf_obj_get(pinned_file); - if (array_fd < 0) { - fprintf(stderr, "bpf_obj_get(%s): %s(%d)\n", - pinned_file, strerror(errno), errno); - goto out; - } - } - - ret = bpf_map_update_elem(array_fd, &array_key, &cg2_fd, 0); - if (ret) { - perror("bpf_map_update_elem"); - goto out; - } - - if (create_array) { - ret = bpf_obj_pin(array_fd, pinned_file); - if (ret) { - fprintf(stderr, "bpf_obj_pin(..., %s): %s(%d)\n", - pinned_file, strerror(errno), errno); - goto out; - } - } - -out: - if (array_fd != -1) - close(array_fd); - if (cg2_fd != -1) - close(cg2_fd); - return ret; -} diff --git a/samples/bpf/test_cgrp2_attach.c b/samples/bpf/test_cgrp2_attach.c deleted file mode 100644 index 68ce69457afe..000000000000 --- a/samples/bpf/test_cgrp2_attach.c +++ /dev/null @@ -1,177 +0,0 @@ -/* eBPF example program: - * - * - Creates arraymap in kernel with 4 bytes keys and 8 byte values - * - * - Loads eBPF program - * - * The eBPF program accesses the map passed in to store two pieces of - * information. The number of invocations of the program, which maps - * to the number of packets received, is stored to key 0. Key 1 is - * incremented on each iteration by the number of bytes stored in - * the skb. - * - * - Attaches the new program to a cgroup using BPF_PROG_ATTACH - * - * - Every second, reads map[0] and map[1] to see how many bytes and - * packets were seen on any socket of tasks in the given cgroup. - */ - -#define _GNU_SOURCE - -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <string.h> -#include <unistd.h> -#include <assert.h> -#include <errno.h> -#include <fcntl.h> - -#include <linux/bpf.h> -#include <bpf/bpf.h> - -#include "bpf_insn.h" -#include "bpf_util.h" - -enum { - MAP_KEY_PACKETS, - MAP_KEY_BYTES, -}; - -char bpf_log_buf[BPF_LOG_BUF_SIZE]; - -static int prog_load(int map_fd, int verdict) -{ - struct bpf_insn prog[] = { - BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), /* save r6 so it's not clobbered by BPF_CALL */ - - /* Count packets */ - BPF_MOV64_IMM(BPF_REG_0, MAP_KEY_PACKETS), /* r0 = 0 */ - BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -4), /* *(u32 *)(fp - 4) = r0 */ - BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), - BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4), /* r2 = fp - 4 */ - BPF_LD_MAP_FD(BPF_REG_1, map_fd), /* load map fd to r1 */ - BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), - BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), - BPF_MOV64_IMM(BPF_REG_1, 1), /* r1 = 1 */ - BPF_ATOMIC_OP(BPF_DW, BPF_ADD, BPF_REG_0, BPF_REG_1, 0), - - /* Count bytes */ - BPF_MOV64_IMM(BPF_REG_0, MAP_KEY_BYTES), /* r0 = 1 */ - BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -4), /* *(u32 *)(fp - 4) = r0 */ - BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), - BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4), /* r2 = fp - 4 */ - BPF_LD_MAP_FD(BPF_REG_1, map_fd), - BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), - BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), - BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_6, offsetof(struct __sk_buff, len)), /* r1 = skb->len */ - - BPF_ATOMIC_OP(BPF_DW, BPF_ADD, BPF_REG_0, BPF_REG_1, 0), - - BPF_MOV64_IMM(BPF_REG_0, verdict), /* r0 = verdict */ - BPF_EXIT_INSN(), - }; - size_t insns_cnt = ARRAY_SIZE(prog); - LIBBPF_OPTS(bpf_prog_load_opts, opts, - .log_buf = bpf_log_buf, - .log_size = BPF_LOG_BUF_SIZE, - ); - - return bpf_prog_load(BPF_PROG_TYPE_CGROUP_SKB, NULL, "GPL", - prog, insns_cnt, &opts); -} - -static int usage(const char *argv0) -{ - printf("Usage: %s [-d] [-D] <cg-path> <egress|ingress>\n", argv0); - printf(" -d Drop Traffic\n"); - printf(" -D Detach filter, and exit\n"); - return EXIT_FAILURE; -} - -static int attach_filter(int cg_fd, int type, int verdict) -{ - int prog_fd, map_fd, ret, key; - long long pkt_cnt, byte_cnt; - - map_fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, NULL, - sizeof(key), sizeof(byte_cnt), - 256, NULL); - if (map_fd < 0) { - printf("Failed to create map: '%s'\n", strerror(errno)); - return EXIT_FAILURE; - } - - prog_fd = prog_load(map_fd, verdict); - printf("Output from kernel verifier:\n%s\n-------\n", bpf_log_buf); - - if (prog_fd < 0) { - printf("Failed to load prog: '%s'\n", strerror(errno)); - return EXIT_FAILURE; - } - - ret = bpf_prog_attach(prog_fd, cg_fd, type, 0); - if (ret < 0) { - printf("Failed to attach prog to cgroup: '%s'\n", - strerror(errno)); - return EXIT_FAILURE; - } - while (1) { - key = MAP_KEY_PACKETS; - assert(bpf_map_lookup_elem(map_fd, &key, &pkt_cnt) == 0); - - key = MAP_KEY_BYTES; - assert(bpf_map_lookup_elem(map_fd, &key, &byte_cnt) == 0); - - printf("cgroup received %lld packets, %lld bytes\n", - pkt_cnt, byte_cnt); - sleep(1); - } - - return EXIT_SUCCESS; -} - -int main(int argc, char **argv) -{ - int detach_only = 0, verdict = 1; - enum bpf_attach_type type; - int opt, cg_fd, ret; - - while ((opt = getopt(argc, argv, "Dd")) != -1) { - switch (opt) { - case 'd': - verdict = 0; - break; - case 'D': - detach_only = 1; - break; - default: - return usage(argv[0]); - } - } - - if (argc - optind < 2) - return usage(argv[0]); - - if (strcmp(argv[optind + 1], "ingress") == 0) - type = BPF_CGROUP_INET_INGRESS; - else if (strcmp(argv[optind + 1], "egress") == 0) - type = BPF_CGROUP_INET_EGRESS; - else - return usage(argv[0]); - - cg_fd = open(argv[optind], O_DIRECTORY | O_RDONLY); - if (cg_fd < 0) { - printf("Failed to open cgroup path: '%s'\n", strerror(errno)); - return EXIT_FAILURE; - } - - if (detach_only) { - ret = bpf_prog_detach(cg_fd, type); - printf("bpf_prog_detach() returned '%s' (%d)\n", - strerror(errno), errno); - } else - ret = attach_filter(cg_fd, type, verdict); - - return ret; -} diff --git a/samples/bpf/test_cgrp2_tc.bpf.c b/samples/bpf/test_cgrp2_tc.bpf.c deleted file mode 100644 index c7d2291d676f..000000000000 --- a/samples/bpf/test_cgrp2_tc.bpf.c +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright (c) 2016 Facebook - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - */ -#define KBUILD_MODNAME "foo" -#include "vmlinux.h" -#include "net_shared.h" -#include <bpf/bpf_helpers.h> - -/* copy of 'struct ethhdr' without __packed */ -struct eth_hdr { - unsigned char h_dest[ETH_ALEN]; - unsigned char h_source[ETH_ALEN]; - unsigned short h_proto; -}; - -struct { - __uint(type, BPF_MAP_TYPE_CGROUP_ARRAY); - __type(key, u32); - __type(value, u32); - __uint(pinning, LIBBPF_PIN_BY_NAME); - __uint(max_entries, 1); -} test_cgrp2_array_pin SEC(".maps"); - -SEC("filter") -int handle_egress(struct __sk_buff *skb) -{ - void *data = (void *)(long)skb->data; - struct eth_hdr *eth = data; - struct ipv6hdr *ip6h = data + sizeof(*eth); - void *data_end = (void *)(long)skb->data_end; - char dont_care_msg[] = "dont care %04x %d\n"; - char pass_msg[] = "pass\n"; - char reject_msg[] = "reject\n"; - - /* single length check */ - if (data + sizeof(*eth) + sizeof(*ip6h) > data_end) - return TC_ACT_OK; - - if (eth->h_proto != bpf_htons(ETH_P_IPV6) || - ip6h->nexthdr != IPPROTO_ICMPV6) { - bpf_trace_printk(dont_care_msg, sizeof(dont_care_msg), - eth->h_proto, ip6h->nexthdr); - return TC_ACT_OK; - } else if (bpf_skb_under_cgroup(skb, &test_cgrp2_array_pin, 0) != 1) { - bpf_trace_printk(pass_msg, sizeof(pass_msg)); - return TC_ACT_OK; - } else { - bpf_trace_printk(reject_msg, sizeof(reject_msg)); - return TC_ACT_SHOT; - } -} - -char _license[] SEC("license") = "GPL"; diff --git a/samples/bpf/test_cgrp2_tc.sh b/samples/bpf/test_cgrp2_tc.sh deleted file mode 100755 index 38e8dbc9d16e..000000000000 --- a/samples/bpf/test_cgrp2_tc.sh +++ /dev/null @@ -1,187 +0,0 @@ -#!/bin/bash -# SPDX-License-Identifier: GPL-2.0 - -MY_DIR=$(dirname $0) -# Details on the bpf prog -BPF_CGRP2_ARRAY_NAME='test_cgrp2_array_pin' -BPF_PROG="$MY_DIR/test_cgrp2_tc.bpf.o" -BPF_SECTION='filter' - -[ -z "$TC" ] && TC='tc' -[ -z "$IP" ] && IP='ip' - -# Names of the veth interface, net namespace...etc. -HOST_IFC='ve' -NS_IFC='vens' -NS='ns' - -find_mnt() { - cat /proc/mounts | \ - awk '{ if ($3 == "'$1'" && mnt == "") { mnt = $2 }} END { print mnt }' -} - -# Init cgroup2 vars -init_cgrp2_vars() { - CGRP2_ROOT=$(find_mnt cgroup2) - if [ -z "$CGRP2_ROOT" ] - then - CGRP2_ROOT='/mnt/cgroup2' - MOUNT_CGRP2="yes" - fi - CGRP2_TC="$CGRP2_ROOT/tc" - CGRP2_TC_LEAF="$CGRP2_TC/leaf" -} - -# Init bpf fs vars -init_bpf_fs_vars() { - local bpf_fs_root=$(find_mnt bpf) - [ -n "$bpf_fs_root" ] || return -1 - BPF_FS_TC_SHARE="$bpf_fs_root/tc/globals" -} - -setup_cgrp2() { - case $1 in - start) - if [ "$MOUNT_CGRP2" == 'yes' ] - then - [ -d $CGRP2_ROOT ] || mkdir -p $CGRP2_ROOT - mount -t cgroup2 none $CGRP2_ROOT || return $? - fi - mkdir -p $CGRP2_TC_LEAF - ;; - *) - rmdir $CGRP2_TC_LEAF && rmdir $CGRP2_TC - [ "$MOUNT_CGRP2" == 'yes' ] && umount $CGRP2_ROOT - ;; - esac -} - -setup_bpf_cgrp2_array() { - local bpf_cgrp2_array="$BPF_FS_TC_SHARE/$BPF_CGRP2_ARRAY_NAME" - case $1 in - start) - $MY_DIR/test_cgrp2_array_pin -U $bpf_cgrp2_array -v $CGRP2_TC - ;; - *) - [ -d "$BPF_FS_TC_SHARE" ] && rm -f $bpf_cgrp2_array - ;; - esac -} - -setup_net() { - case $1 in - start) - $IP link add $HOST_IFC type veth peer name $NS_IFC || return $? - $IP link set dev $HOST_IFC up || return $? - sysctl -q net.ipv6.conf.$HOST_IFC.disable_ipv6=0 - sysctl -q net.ipv6.conf.$HOST_IFC.accept_dad=0 - - $IP netns add $NS || return $? - $IP link set dev $NS_IFC netns $NS || return $? - $IP -n $NS link set dev $NS_IFC up || return $? - $IP netns exec $NS sysctl -q net.ipv6.conf.$NS_IFC.disable_ipv6=0 - $IP netns exec $NS sysctl -q net.ipv6.conf.$NS_IFC.accept_dad=0 - $TC qdisc add dev $HOST_IFC clsact || return $? - $TC filter add dev $HOST_IFC egress bpf da obj $BPF_PROG sec $BPF_SECTION || return $? - ;; - *) - $IP netns del $NS - $IP link del $HOST_IFC - ;; - esac -} - -run_in_cgrp() { - # Fork another bash and move it under the specified cgroup. - # It makes the cgroup cleanup easier at the end of the test. - cmd='echo $$ > ' - cmd="$cmd $1/cgroup.procs; exec $2" - bash -c "$cmd" -} - -do_test() { - run_in_cgrp $CGRP2_TC_LEAF "ping -6 -c3 ff02::1%$HOST_IFC >& /dev/null" - local dropped=$($TC -s qdisc show dev $HOST_IFC | tail -3 | \ - awk '/drop/{print substr($7, 0, index($7, ",")-1)}') - if [[ $dropped -eq 0 ]] - then - echo "FAIL" - return 1 - else - echo "Successfully filtered $dropped packets" - return 0 - fi -} - -do_exit() { - if [ "$DEBUG" == "yes" ] && [ "$MODE" != 'cleanuponly' ] - then - echo "------ DEBUG ------" - echo "mount: "; mount | grep -E '(cgroup2|bpf)'; echo - echo "$CGRP2_TC_LEAF: "; ls -l $CGRP2_TC_LEAF; echo - if [ -d "$BPF_FS_TC_SHARE" ] - then - echo "$BPF_FS_TC_SHARE: "; ls -l $BPF_FS_TC_SHARE; echo - fi - echo "Host net:" - $IP netns - $IP link show dev $HOST_IFC - $IP -6 a show dev $HOST_IFC - $TC -s qdisc show dev $HOST_IFC - echo - echo "$NS net:" - $IP -n $NS link show dev $NS_IFC - $IP -n $NS -6 link show dev $NS_IFC - echo "------ DEBUG ------" - echo - fi - - if [ "$MODE" != 'nocleanup' ] - then - setup_net stop - setup_bpf_cgrp2_array stop - setup_cgrp2 stop - fi -} - -init_cgrp2_vars -init_bpf_fs_vars - -while [[ $# -ge 1 ]] -do - a="$1" - case $a in - debug) - DEBUG='yes' - shift 1 - ;; - cleanup-only) - MODE='cleanuponly' - shift 1 - ;; - no-cleanup) - MODE='nocleanup' - shift 1 - ;; - *) - echo "test_cgrp2_tc [debug] [cleanup-only | no-cleanup]" - echo " debug: Print cgrp and network setup details at the end of the test" - echo " cleanup-only: Try to cleanup things from last test. No test will be run" - echo " no-cleanup: Run the test but don't do cleanup at the end" - echo "[Note: If no arg is given, it will run the test and do cleanup at the end]" - echo - exit -1 - ;; - esac -done - -trap do_exit 0 - -[ "$MODE" == 'cleanuponly' ] && exit - -setup_cgrp2 start || exit $? -setup_net start || exit $? -init_bpf_fs_vars || exit $? -setup_bpf_cgrp2_array start || exit $? -do_test -echo diff --git a/samples/bpf/test_current_task_under_cgroup.bpf.c b/samples/bpf/test_current_task_under_cgroup.bpf.c deleted file mode 100644 index 58b9cf7ed659..000000000000 --- a/samples/bpf/test_current_task_under_cgroup.bpf.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (c) 2016 Sargun Dhillon sargun@sargun.me - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - */ - -#include "vmlinux.h" -#include <linux/version.h> -#include <bpf/bpf_helpers.h> -#include <bpf/bpf_tracing.h> -#include <bpf/bpf_core_read.h> - -struct { - __uint(type, BPF_MAP_TYPE_CGROUP_ARRAY); - __uint(key_size, sizeof(u32)); - __uint(value_size, sizeof(u32)); - __uint(max_entries, 1); -} cgroup_map SEC(".maps"); - -struct { - __uint(type, BPF_MAP_TYPE_ARRAY); - __type(key, u32); - __type(value, u64); - __uint(max_entries, 1); -} perf_map SEC(".maps"); - -/* Writes the last PID that called sync to a map at index 0 */ -SEC("ksyscall/sync") -int BPF_KSYSCALL(bpf_prog1) -{ - u64 pid = bpf_get_current_pid_tgid(); - int idx = 0; - - if (!bpf_current_task_under_cgroup(&cgroup_map, 0)) - return 0; - - bpf_map_update_elem(&perf_map, &idx, &pid, BPF_ANY); - return 0; -} - -char _license[] SEC("license") = "GPL"; -u32 _version SEC("version") = LINUX_VERSION_CODE; diff --git a/samples/bpf/test_current_task_under_cgroup_user.c b/samples/bpf/test_current_task_under_cgroup_user.c deleted file mode 100644 index 9726ed2a8a8b..000000000000 --- a/samples/bpf/test_current_task_under_cgroup_user.c +++ /dev/null @@ -1,115 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2016 Sargun Dhillon sargun@sargun.me - */ - -#define _GNU_SOURCE -#include <stdio.h> -#include <unistd.h> -#include <bpf/bpf.h> -#include <bpf/libbpf.h> -#include "cgroup_helpers.h" - -#define CGROUP_PATH "/my-cgroup" - -int main(int argc, char **argv) -{ - pid_t remote_pid, local_pid = getpid(); - int cg2 = -1, idx = 0, rc = 1; - struct bpf_link *link = NULL; - struct bpf_program *prog; - struct bpf_object *obj; - char filename[256]; - int map_fd[2]; - - snprintf(filename, sizeof(filename), "%s.bpf.o", argv[0]); - obj = bpf_object__open_file(filename, NULL); - if (libbpf_get_error(obj)) { - fprintf(stderr, "ERROR: opening BPF object file failed\n"); - return 0; - } - - prog = bpf_object__find_program_by_name(obj, "bpf_prog1"); - if (!prog) { - printf("finding a prog in obj file failed\n"); - goto cleanup; - } - - /* load BPF program */ - if (bpf_object__load(obj)) { - fprintf(stderr, "ERROR: loading BPF object file failed\n"); - goto cleanup; - } - - map_fd[0] = bpf_object__find_map_fd_by_name(obj, "cgroup_map"); - map_fd[1] = bpf_object__find_map_fd_by_name(obj, "perf_map"); - if (map_fd[0] < 0 || map_fd[1] < 0) { - fprintf(stderr, "ERROR: finding a map in obj file failed\n"); - goto cleanup; - } - - link = bpf_program__attach(prog); - if (libbpf_get_error(link)) { - fprintf(stderr, "ERROR: bpf_program__attach failed\n"); - link = NULL; - goto cleanup; - } - - if (setup_cgroup_environment()) - goto err; - - cg2 = create_and_get_cgroup(CGROUP_PATH); - - if (cg2 < 0) - goto err; - - if (bpf_map_update_elem(map_fd[0], &idx, &cg2, BPF_ANY)) { - log_err("Adding target cgroup to map"); - goto err; - } - - if (join_cgroup(CGROUP_PATH)) - goto err; - - /* - * The installed helper program catched the sync call, and should - * write it to the map. - */ - - sync(); - bpf_map_lookup_elem(map_fd[1], &idx, &remote_pid); - - if (local_pid != remote_pid) { - fprintf(stderr, - "BPF Helper didn't write correct PID to map, but: %d\n", - remote_pid); - goto err; - } - - /* Verify the negative scenario; leave the cgroup */ - if (join_cgroup("/")) - goto err; - - remote_pid = 0; - bpf_map_update_elem(map_fd[1], &idx, &remote_pid, BPF_ANY); - - sync(); - bpf_map_lookup_elem(map_fd[1], &idx, &remote_pid); - - if (local_pid == remote_pid) { - fprintf(stderr, "BPF cgroup negative test did not work\n"); - goto err; - } - - rc = 0; - -err: - if (cg2 != -1) - close(cg2); - - cleanup_cgroup_environment(); - -cleanup: - bpf_link__destroy(link); - bpf_object__close(obj); - return rc; -}
The samples/bpf has become outdated and often does not follow up with the latest. This commit removes obsolete tracing-related tests.
Specifically, 'test_overhead' is duplicate with selftests (and bench), and 'test_override_return', 'test_probe_write_user' tests are obsolete since they have been replaced by kprobe_multi_override and probe_user from selftests respectively.
The following files are removed: - test_overhead: tests the overhead of BPF programs with task_rename, now covered by selftests and benchmark tests (rename-*). [1]
- test_override_return: tests the return override functionality, now handled by kprobe_multi_override in selftests.
- test_probe_write_user: tests the probe_write_user functionality, now replaced by the probe_user test in selftests.
This cleanup will help to streamline the testing framework by removing redundant tests.
[1]: https://patchwork.kernel.org/cover/13759916
Signed-off-by: Daniel T. Lee danieltimlee@gmail.com --- samples/bpf/Makefile | 11 -- samples/bpf/test_overhead_kprobe.bpf.c | 41 ----- samples/bpf/test_overhead_raw_tp.bpf.c | 17 -- samples/bpf/test_overhead_tp.bpf.c | 23 --- samples/bpf/test_overhead_user.c | 225 ----------------------- samples/bpf/test_override_return.sh | 16 -- samples/bpf/test_probe_write_user.bpf.c | 52 ------ samples/bpf/test_probe_write_user_user.c | 108 ----------- samples/bpf/tracex7.bpf.c | 15 -- samples/bpf/tracex7_user.c | 56 ------ 10 files changed, 564 deletions(-) delete mode 100644 samples/bpf/test_overhead_kprobe.bpf.c delete mode 100644 samples/bpf/test_overhead_raw_tp.bpf.c delete mode 100644 samples/bpf/test_overhead_tp.bpf.c delete mode 100644 samples/bpf/test_overhead_user.c delete mode 100755 samples/bpf/test_override_return.sh delete mode 100644 samples/bpf/test_probe_write_user.bpf.c delete mode 100644 samples/bpf/test_probe_write_user_user.c delete mode 100644 samples/bpf/tracex7.bpf.c delete mode 100644 samples/bpf/tracex7_user.c
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index 66827dbb93b3..31bf0c665963 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile @@ -17,14 +17,11 @@ tprogs-y += tracex3 tprogs-y += tracex4 tprogs-y += tracex5 tprogs-y += tracex6 -tprogs-y += tracex7 -tprogs-y += test_probe_write_user tprogs-y += trace_output tprogs-y += lathist tprogs-y += offwaketime tprogs-y += spintest tprogs-y += map_perf_test -tprogs-y += test_overhead tprogs-y += test_cgrp2_attach tprogs-y += xdp_router_ipv4 tprogs-y += trace_event @@ -62,8 +59,6 @@ tracex3-objs := tracex3_user.o tracex4-objs := tracex4_user.o tracex5-objs := tracex5_user.o $(TRACE_HELPERS) tracex6-objs := tracex6_user.o -tracex7-objs := tracex7_user.o -test_probe_write_user-objs := test_probe_write_user_user.o trace_output-objs := trace_output_user.o lathist-objs := lathist_user.o offwaketime-objs := offwaketime_user.o $(TRACE_HELPERS) @@ -96,9 +91,7 @@ always-y += tracex3.bpf.o always-y += tracex4.bpf.o always-y += tracex5.bpf.o always-y += tracex6.bpf.o -always-y += tracex7.bpf.o always-y += sock_flags.bpf.o -always-y += test_probe_write_user.bpf.o always-y += trace_output.bpf.o always-y += tcbpf1_kern.o always-y += tc_l2_redirect_kern.o @@ -106,9 +99,6 @@ always-y += lathist_kern.o always-y += offwaketime.bpf.o always-y += spintest.bpf.o always-y += map_perf_test.bpf.o -always-y += test_overhead_tp.bpf.o -always-y += test_overhead_raw_tp.bpf.o -always-y += test_overhead_kprobe.bpf.o always-y += parse_varlen.o parse_simple.o parse_ldabs.o always-y += trace_event_kern.o always-y += sampleip_kern.o @@ -182,7 +172,6 @@ TPROGLDLIBS_xdp_router_ipv4 += -lm -pthread TPROGLDLIBS_tracex4 += -lrt TPROGLDLIBS_trace_output += -lrt TPROGLDLIBS_map_perf_test += -lrt -TPROGLDLIBS_test_overhead += -lrt
# Allows pointing LLC/CLANG to a LLVM backend with bpf support, redefine on cmdline: # make M=samples/bpf LLC=~/git/llvm-project/llvm/build/bin/llc CLANG=~/git/llvm-project/llvm/build/bin/clang diff --git a/samples/bpf/test_overhead_kprobe.bpf.c b/samples/bpf/test_overhead_kprobe.bpf.c deleted file mode 100644 index 668cf5259c60..000000000000 --- a/samples/bpf/test_overhead_kprobe.bpf.c +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright (c) 2016 Facebook - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - */ -#include "vmlinux.h" -#include <linux/version.h> -#include <bpf/bpf_helpers.h> -#include <bpf/bpf_tracing.h> -#include <bpf/bpf_core_read.h> - -SEC("kprobe/__set_task_comm") -int prog(struct pt_regs *ctx) -{ - struct signal_struct *signal; - struct task_struct *tsk; - char oldcomm[TASK_COMM_LEN] = {}; - char newcomm[TASK_COMM_LEN] = {}; - u16 oom_score_adj; - u32 pid; - - tsk = (void *)PT_REGS_PARM1_CORE(ctx); - - pid = BPF_CORE_READ(tsk, pid); - bpf_core_read_str(oldcomm, sizeof(oldcomm), &tsk->comm); - bpf_core_read_str(newcomm, sizeof(newcomm), - (void *)PT_REGS_PARM2(ctx)); - signal = BPF_CORE_READ(tsk, signal); - oom_score_adj = BPF_CORE_READ(signal, oom_score_adj); - return 0; -} - -SEC("kprobe/fib_table_lookup") -int prog2(struct pt_regs *ctx) -{ - return 0; -} - -char _license[] SEC("license") = "GPL"; -u32 _version SEC("version") = LINUX_VERSION_CODE; diff --git a/samples/bpf/test_overhead_raw_tp.bpf.c b/samples/bpf/test_overhead_raw_tp.bpf.c deleted file mode 100644 index 6af39fe3f8dd..000000000000 --- a/samples/bpf/test_overhead_raw_tp.bpf.c +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright (c) 2018 Facebook */ -#include "vmlinux.h" -#include <bpf/bpf_helpers.h> - -SEC("raw_tracepoint/task_rename") -int prog(struct bpf_raw_tracepoint_args *ctx) -{ - return 0; -} - -SEC("raw_tracepoint/fib_table_lookup") -int prog2(struct bpf_raw_tracepoint_args *ctx) -{ - return 0; -} -char _license[] SEC("license") = "GPL"; diff --git a/samples/bpf/test_overhead_tp.bpf.c b/samples/bpf/test_overhead_tp.bpf.c deleted file mode 100644 index 5dc08b587978..000000000000 --- a/samples/bpf/test_overhead_tp.bpf.c +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 2016 Facebook - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - */ -#include "vmlinux.h" -#include <bpf/bpf_helpers.h> - -/* from /sys/kernel/tracing/events/task/task_rename/format */ -SEC("tracepoint/task/task_rename") -int prog(struct trace_event_raw_task_rename *ctx) -{ - return 0; -} - -/* from /sys/kernel/tracing/events/fib/fib_table_lookup/format */ -SEC("tracepoint/fib/fib_table_lookup") -int prog2(struct trace_event_raw_fib_table_lookup *ctx) -{ - return 0; -} -char _license[] SEC("license") = "GPL"; diff --git a/samples/bpf/test_overhead_user.c b/samples/bpf/test_overhead_user.c deleted file mode 100644 index dbd86f7b1473..000000000000 --- a/samples/bpf/test_overhead_user.c +++ /dev/null @@ -1,225 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2016 Facebook - */ -#define _GNU_SOURCE -#include <sched.h> -#include <errno.h> -#include <stdio.h> -#include <sys/types.h> -#include <asm/unistd.h> -#include <fcntl.h> -#include <unistd.h> -#include <assert.h> -#include <sys/wait.h> -#include <sys/socket.h> -#include <arpa/inet.h> -#include <stdlib.h> -#include <signal.h> -#include <linux/bpf.h> -#include <string.h> -#include <time.h> -#include <bpf/bpf.h> -#include <bpf/libbpf.h> - -#define MAX_CNT 1000000 -#define DUMMY_IP "127.0.0.1" -#define DUMMY_PORT 80 - -static struct bpf_link *links[2]; -static struct bpf_object *obj; -static int cnt; - -static __u64 time_get_ns(void) -{ - struct timespec ts; - - clock_gettime(CLOCK_MONOTONIC, &ts); - return ts.tv_sec * 1000000000ull + ts.tv_nsec; -} - -static void test_task_rename(int cpu) -{ - char buf[] = "test\n"; - __u64 start_time; - int i, fd; - - fd = open("/proc/self/comm", O_WRONLY|O_TRUNC); - if (fd < 0) { - printf("couldn't open /proc\n"); - exit(1); - } - start_time = time_get_ns(); - for (i = 0; i < MAX_CNT; i++) { - if (write(fd, buf, sizeof(buf)) < 0) { - printf("task rename failed: %s\n", strerror(errno)); - close(fd); - return; - } - } - printf("task_rename:%d: %lld events per sec\n", - cpu, MAX_CNT * 1000000000ll / (time_get_ns() - start_time)); - close(fd); -} - -static void test_fib_table_lookup(int cpu) -{ - struct sockaddr_in addr; - char buf[] = "test\n"; - __u64 start_time; - int i, fd; - - fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (fd < 0) { - printf("couldn't open socket\n"); - exit(1); - } - memset((char *)&addr, 0, sizeof(addr)); - addr.sin_addr.s_addr = inet_addr(DUMMY_IP); - addr.sin_port = htons(DUMMY_PORT); - addr.sin_family = AF_INET; - start_time = time_get_ns(); - for (i = 0; i < MAX_CNT; i++) { - if (sendto(fd, buf, strlen(buf), 0, - (struct sockaddr *)&addr, sizeof(addr)) < 0) { - printf("failed to start ping: %s\n", strerror(errno)); - close(fd); - return; - } - } - printf("fib_table_lookup:%d: %lld events per sec\n", - cpu, MAX_CNT * 1000000000ll / (time_get_ns() - start_time)); - close(fd); -} - -static void loop(int cpu, int flags) -{ - cpu_set_t cpuset; - - CPU_ZERO(&cpuset); - CPU_SET(cpu, &cpuset); - sched_setaffinity(0, sizeof(cpuset), &cpuset); - - if (flags & 1) - test_task_rename(cpu); - if (flags & 2) - test_fib_table_lookup(cpu); -} - -static void run_perf_test(int tasks, int flags) -{ - pid_t pid[tasks]; - int i; - - for (i = 0; i < tasks; i++) { - pid[i] = fork(); - if (pid[i] == 0) { - loop(i, flags); - exit(0); - } else if (pid[i] == -1) { - printf("couldn't spawn #%d process\n", i); - exit(1); - } - } - for (i = 0; i < tasks; i++) { - int status; - - assert(waitpid(pid[i], &status, 0) == pid[i]); - assert(status == 0); - } -} - -static int load_progs(char *filename) -{ - struct bpf_program *prog; - int err = 0; - - obj = bpf_object__open_file(filename, NULL); - err = libbpf_get_error(obj); - if (err < 0) { - fprintf(stderr, "ERROR: opening BPF object file failed\n"); - return err; - } - - /* load BPF program */ - err = bpf_object__load(obj); - if (err < 0) { - fprintf(stderr, "ERROR: loading BPF object file failed\n"); - return err; - } - - bpf_object__for_each_program(prog, obj) { - links[cnt] = bpf_program__attach(prog); - err = libbpf_get_error(links[cnt]); - if (err < 0) { - fprintf(stderr, "ERROR: bpf_program__attach failed\n"); - links[cnt] = NULL; - return err; - } - cnt++; - } - - return err; -} - -static void unload_progs(void) -{ - while (cnt) - bpf_link__destroy(links[--cnt]); - - bpf_object__close(obj); -} - -int main(int argc, char **argv) -{ - int num_cpu = sysconf(_SC_NPROCESSORS_ONLN); - int test_flags = ~0; - char filename[256]; - int err = 0; - - - if (argc > 1) - test_flags = atoi(argv[1]) ? : test_flags; - if (argc > 2) - num_cpu = atoi(argv[2]) ? : num_cpu; - - if (test_flags & 0x3) { - printf("BASE\n"); - run_perf_test(num_cpu, test_flags); - } - - if (test_flags & 0xC) { - snprintf(filename, sizeof(filename), - "%s_kprobe.bpf.o", argv[0]); - - printf("w/KPROBE\n"); - err = load_progs(filename); - if (!err) - run_perf_test(num_cpu, test_flags >> 2); - - unload_progs(); - } - - if (test_flags & 0x30) { - snprintf(filename, sizeof(filename), - "%s_tp.bpf.o", argv[0]); - printf("w/TRACEPOINT\n"); - err = load_progs(filename); - if (!err) - run_perf_test(num_cpu, test_flags >> 4); - - unload_progs(); - } - - if (test_flags & 0xC0) { - snprintf(filename, sizeof(filename), - "%s_raw_tp.bpf.o", argv[0]); - printf("w/RAW_TRACEPOINT\n"); - err = load_progs(filename); - if (!err) - run_perf_test(num_cpu, test_flags >> 6); - - unload_progs(); - } - - return err; -} diff --git a/samples/bpf/test_override_return.sh b/samples/bpf/test_override_return.sh deleted file mode 100755 index 35db26f736b9..000000000000 --- a/samples/bpf/test_override_return.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -rm -r tmpmnt -rm -f testfile.img -dd if=/dev/zero of=testfile.img bs=1M seek=1000 count=1 -DEVICE=$(losetup --show -f testfile.img) -mkfs.btrfs -f $DEVICE -mkdir tmpmnt -./tracex7 $DEVICE -if [ $? -eq 0 ] -then - echo "SUCCESS!" -else - echo "FAILED!" -fi -losetup -d $DEVICE diff --git a/samples/bpf/test_probe_write_user.bpf.c b/samples/bpf/test_probe_write_user.bpf.c deleted file mode 100644 index a4f3798b7fb0..000000000000 --- a/samples/bpf/test_probe_write_user.bpf.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2016 Sargun Dhillon sargun@sargun.me - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - */ -#include "vmlinux.h" -#include <string.h> -#include <linux/version.h> -#include <bpf/bpf_helpers.h> -#include <bpf/bpf_tracing.h> -#include <bpf/bpf_core_read.h> - -struct { - __uint(type, BPF_MAP_TYPE_HASH); - __type(key, struct sockaddr_in); - __type(value, struct sockaddr_in); - __uint(max_entries, 256); -} dnat_map SEC(".maps"); - -/* kprobe is NOT a stable ABI - * kernel functions can be removed, renamed or completely change semantics. - * Number of arguments and their positions can change, etc. - * In such case this bpf+kprobe example will no longer be meaningful - * - * This example sits on a syscall, and the syscall ABI is relatively stable - * of course, across platforms, and over time, the ABI may change. - */ -SEC("ksyscall/connect") -int BPF_KSYSCALL(bpf_prog1, int fd, struct sockaddr_in *uservaddr, - int addrlen) -{ - struct sockaddr_in new_addr, orig_addr = {}; - struct sockaddr_in *mapped_addr; - - if (addrlen > sizeof(orig_addr)) - return 0; - - if (bpf_probe_read_user(&orig_addr, sizeof(orig_addr), uservaddr) != 0) - return 0; - - mapped_addr = bpf_map_lookup_elem(&dnat_map, &orig_addr); - if (mapped_addr != NULL) { - memcpy(&new_addr, mapped_addr, sizeof(new_addr)); - bpf_probe_write_user(uservaddr, &new_addr, - sizeof(new_addr)); - } - return 0; -} - -char _license[] SEC("license") = "GPL"; -u32 _version SEC("version") = LINUX_VERSION_CODE; diff --git a/samples/bpf/test_probe_write_user_user.c b/samples/bpf/test_probe_write_user_user.c deleted file mode 100644 index 2a539aec4116..000000000000 --- a/samples/bpf/test_probe_write_user_user.c +++ /dev/null @@ -1,108 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include <stdio.h> -#include <assert.h> -#include <unistd.h> -#include <bpf/bpf.h> -#include <bpf/libbpf.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> - -int main(int ac, char **argv) -{ - struct sockaddr_in *serv_addr_in, *mapped_addr_in, *tmp_addr_in; - struct sockaddr serv_addr, mapped_addr, tmp_addr; - int serverfd, serverconnfd, clientfd, map_fd; - struct bpf_link *link = NULL; - struct bpf_program *prog; - struct bpf_object *obj; - socklen_t sockaddr_len; - char filename[256]; - char *ip; - - serv_addr_in = (struct sockaddr_in *)&serv_addr; - mapped_addr_in = (struct sockaddr_in *)&mapped_addr; - tmp_addr_in = (struct sockaddr_in *)&tmp_addr; - - snprintf(filename, sizeof(filename), "%s.bpf.o", argv[0]); - obj = bpf_object__open_file(filename, NULL); - if (libbpf_get_error(obj)) { - fprintf(stderr, "ERROR: opening BPF object file failed\n"); - return 0; - } - - prog = bpf_object__find_program_by_name(obj, "bpf_prog1"); - if (libbpf_get_error(prog)) { - fprintf(stderr, "ERROR: finding a prog in obj file failed\n"); - goto cleanup; - } - - /* load BPF program */ - if (bpf_object__load(obj)) { - fprintf(stderr, "ERROR: loading BPF object file failed\n"); - goto cleanup; - } - - map_fd = bpf_object__find_map_fd_by_name(obj, "dnat_map"); - if (map_fd < 0) { - fprintf(stderr, "ERROR: finding a map in obj file failed\n"); - goto cleanup; - } - - link = bpf_program__attach(prog); - if (libbpf_get_error(link)) { - fprintf(stderr, "ERROR: bpf_program__attach failed\n"); - link = NULL; - goto cleanup; - } - - assert((serverfd = socket(AF_INET, SOCK_STREAM, 0)) > 0); - assert((clientfd = socket(AF_INET, SOCK_STREAM, 0)) > 0); - - /* Bind server to ephemeral port on lo */ - memset(&serv_addr, 0, sizeof(serv_addr)); - serv_addr_in->sin_family = AF_INET; - serv_addr_in->sin_port = 0; - serv_addr_in->sin_addr.s_addr = htonl(INADDR_LOOPBACK); - - assert(bind(serverfd, &serv_addr, sizeof(serv_addr)) == 0); - - sockaddr_len = sizeof(serv_addr); - assert(getsockname(serverfd, &serv_addr, &sockaddr_len) == 0); - ip = inet_ntoa(serv_addr_in->sin_addr); - printf("Server bound to: %s:%d\n", ip, ntohs(serv_addr_in->sin_port)); - - memset(&mapped_addr, 0, sizeof(mapped_addr)); - mapped_addr_in->sin_family = AF_INET; - mapped_addr_in->sin_port = htons(5555); - mapped_addr_in->sin_addr.s_addr = inet_addr("255.255.255.255"); - - assert(!bpf_map_update_elem(map_fd, &mapped_addr, &serv_addr, BPF_ANY)); - - assert(listen(serverfd, 5) == 0); - - ip = inet_ntoa(mapped_addr_in->sin_addr); - printf("Client connecting to: %s:%d\n", - ip, ntohs(mapped_addr_in->sin_port)); - assert(connect(clientfd, &mapped_addr, sizeof(mapped_addr)) == 0); - - sockaddr_len = sizeof(tmp_addr); - ip = inet_ntoa(tmp_addr_in->sin_addr); - assert((serverconnfd = accept(serverfd, &tmp_addr, &sockaddr_len)) > 0); - printf("Server received connection from: %s:%d\n", - ip, ntohs(tmp_addr_in->sin_port)); - - sockaddr_len = sizeof(tmp_addr); - assert(getpeername(clientfd, &tmp_addr, &sockaddr_len) == 0); - ip = inet_ntoa(tmp_addr_in->sin_addr); - printf("Client's peer address: %s:%d\n", - ip, ntohs(tmp_addr_in->sin_port)); - - /* Is the server's getsockname = the socket getpeername */ - assert(memcmp(&serv_addr, &tmp_addr, sizeof(struct sockaddr_in)) == 0); - -cleanup: - bpf_link__destroy(link); - bpf_object__close(obj); - return 0; -} diff --git a/samples/bpf/tracex7.bpf.c b/samples/bpf/tracex7.bpf.c deleted file mode 100644 index ab8d6704a5a4..000000000000 --- a/samples/bpf/tracex7.bpf.c +++ /dev/null @@ -1,15 +0,0 @@ -#include "vmlinux.h" -#include <linux/version.h> -#include <bpf/bpf_helpers.h> - -SEC("kprobe/open_ctree") -int bpf_prog1(struct pt_regs *ctx) -{ - unsigned long rc = -12; - - bpf_override_return(ctx, rc); - return 0; -} - -char _license[] SEC("license") = "GPL"; -u32 _version SEC("version") = LINUX_VERSION_CODE; diff --git a/samples/bpf/tracex7_user.c b/samples/bpf/tracex7_user.c deleted file mode 100644 index b10b5e03a226..000000000000 --- a/samples/bpf/tracex7_user.c +++ /dev/null @@ -1,56 +0,0 @@ -#define _GNU_SOURCE - -#include <stdio.h> -#include <unistd.h> -#include <bpf/libbpf.h> - -int main(int argc, char **argv) -{ - struct bpf_link *link = NULL; - struct bpf_program *prog; - struct bpf_object *obj; - char filename[256]; - char command[256]; - int ret = 0; - FILE *f; - - if (!argv[1]) { - fprintf(stderr, "ERROR: Run with the btrfs device argument!\n"); - return 0; - } - - snprintf(filename, sizeof(filename), "%s.bpf.o", argv[0]); - obj = bpf_object__open_file(filename, NULL); - if (libbpf_get_error(obj)) { - fprintf(stderr, "ERROR: opening BPF object file failed\n"); - return 0; - } - - prog = bpf_object__find_program_by_name(obj, "bpf_prog1"); - if (!prog) { - fprintf(stderr, "ERROR: finding a prog in obj file failed\n"); - goto cleanup; - } - - /* load BPF program */ - if (bpf_object__load(obj)) { - fprintf(stderr, "ERROR: loading BPF object file failed\n"); - goto cleanup; - } - - link = bpf_program__attach(prog); - if (libbpf_get_error(link)) { - fprintf(stderr, "ERROR: bpf_program__attach failed\n"); - link = NULL; - goto cleanup; - } - - snprintf(command, 256, "mount %s tmpmnt/", argv[1]); - f = popen(command, "r"); - ret = pclose(f); - -cleanup: - bpf_link__destroy(link); - bpf_object__close(obj); - return ret ? 0 : 1; -}
linux-kselftest-mirror@lists.linaro.org