summaryrefslogtreecommitdiff
path: root/samples
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-11-21 08:11:04 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2024-11-21 08:11:04 -0800
commit6e95ef0258ff4ee23ae3b06bf6b00b33dbbd5ef7 (patch)
tree07f66723c602ab3b085d890d7fef898a61bb539c /samples
parent43fb83c17ba2d63dfb798f0be7453ed55ca3f9c2 (diff)
parent2c8b09ac2537299511c898bc71b1a5f2756c831c (diff)
downloadlinux-6e95ef0258ff4ee23ae3b06bf6b00b33dbbd5ef7.tar.gz
linux-6e95ef0258ff4ee23ae3b06bf6b00b33dbbd5ef7.tar.bz2
linux-6e95ef0258ff4ee23ae3b06bf6b00b33dbbd5ef7.zip
Merge tag 'bpf-next-6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next
Pull bpf updates from Alexei Starovoitov: - Add BPF uprobe session support (Jiri Olsa) - Optimize uprobe performance (Andrii Nakryiko) - Add bpf_fastcall support to helpers and kfuncs (Eduard Zingerman) - Avoid calling free_htab_elem() under hash map bucket lock (Hou Tao) - Prevent tailcall infinite loop caused by freplace (Leon Hwang) - Mark raw_tracepoint arguments as nullable (Kumar Kartikeya Dwivedi) - Introduce uptr support in the task local storage map (Martin KaFai Lau) - Stringify errno log messages in libbpf (Mykyta Yatsenko) - Add kmem_cache BPF iterator for perf's lock profiling (Namhyung Kim) - Support BPF objects of either endianness in libbpf (Tony Ambardar) - Add ksym to struct_ops trampoline to fix stack trace (Xu Kuohai) - Introduce private stack for eligible BPF programs (Yonghong Song) - Migrate samples/bpf tests to selftests/bpf test_progs (Daniel T. Lee) - Migrate test_sock to selftests/bpf test_progs (Jordan Rife) * tag 'bpf-next-6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next: (152 commits) libbpf: Change hash_combine parameters from long to unsigned long selftests/bpf: Fix build error with llvm 19 libbpf: Fix memory leak in bpf_program__attach_uprobe_multi bpf: use common instruction history across all states bpf: Add necessary migrate_disable to range_tree. bpf: Do not alloc arena on unsupported arches selftests/bpf: Set test path for token/obj_priv_implicit_token_envvar selftests/bpf: Add a test for arena range tree algorithm bpf: Introduce range_tree data structure and use it in bpf arena samples/bpf: Remove unused variable in xdp2skb_meta_kern.c samples/bpf: Remove unused variables in tc_l2_redirect_kern.c bpftool: Cast variable `var` to long long bpf, x86: Propagate tailcall info only for subprogs bpf: Add kernel symbol for struct_ops trampoline bpf: Use function pointers count as struct_ops links count bpf: Remove unused member rcu from bpf_struct_ops_map selftests/bpf: Add struct_ops prog private stack tests bpf: Support private stack for struct_ops progs selftests/bpf: Add tracing prog private stack tests bpf, x86: Support private stack in jit ...
Diffstat (limited to 'samples')
-rw-r--r--samples/bpf/Makefile25
-rw-r--r--samples/bpf/sock_flags.bpf.c47
-rw-r--r--samples/bpf/syscall_nrs.c5
-rw-r--r--samples/bpf/tc_l2_redirect_kern.c6
-rw-r--r--samples/bpf/test_cgrp2_array_pin.c106
-rw-r--r--samples/bpf/test_cgrp2_attach.c177
-rw-r--r--samples/bpf/test_cgrp2_sock.c294
-rwxr-xr-xsamples/bpf/test_cgrp2_sock.sh137
-rw-r--r--samples/bpf/test_cgrp2_sock2.c95
-rwxr-xr-xsamples/bpf/test_cgrp2_sock2.sh103
-rw-r--r--samples/bpf/test_cgrp2_tc.bpf.c56
-rwxr-xr-xsamples/bpf/test_cgrp2_tc.sh187
-rw-r--r--samples/bpf/test_current_task_under_cgroup.bpf.c43
-rw-r--r--samples/bpf/test_current_task_under_cgroup_user.c115
-rw-r--r--samples/bpf/test_overhead_kprobe.bpf.c41
-rw-r--r--samples/bpf/test_overhead_raw_tp.bpf.c17
-rw-r--r--samples/bpf/test_overhead_tp.bpf.c23
-rw-r--r--samples/bpf/test_overhead_user.c225
-rwxr-xr-xsamples/bpf/test_override_return.sh16
-rw-r--r--samples/bpf/test_probe_write_user.bpf.c52
-rw-r--r--samples/bpf/test_probe_write_user_user.c108
-rw-r--r--samples/bpf/tracex7.bpf.c15
-rw-r--r--samples/bpf/tracex7_user.c56
-rw-r--r--samples/bpf/xdp2skb_meta_kern.c2
-rw-r--r--samples/bpf/xdp_adjust_tail_kern.c1
25 files changed, 7 insertions, 1945 deletions
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index 7afe040cf43b..bcf103a4c14f 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -17,20 +17,12 @@ 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_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
tprogs-y += trace_event
tprogs-y += sampleip
tprogs-y += tc_l2_redirect
@@ -66,20 +58,12 @@ 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)
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_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
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
@@ -107,9 +91,6 @@ 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
@@ -117,12 +98,7 @@ 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 += 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
@@ -195,7 +171,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/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/syscall_nrs.c b/samples/bpf/syscall_nrs.c
index 88f940052450..a6e600f3d477 100644
--- a/samples/bpf/syscall_nrs.c
+++ b/samples/bpf/syscall_nrs.c
@@ -2,6 +2,9 @@
#include <uapi/linux/unistd.h>
#include <linux/kbuild.h>
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmissing-prototypes"
+
#define SYSNR(_NR) DEFINE(SYS ## _NR, _NR)
void syscall_defines(void)
@@ -17,3 +20,5 @@ void syscall_defines(void)
#endif
}
+
+#pragma GCC diagnostic pop
diff --git a/samples/bpf/tc_l2_redirect_kern.c b/samples/bpf/tc_l2_redirect_kern.c
index fd2fa0004330..b19fa9b88fe0 100644
--- a/samples/bpf/tc_l2_redirect_kern.c
+++ b/samples/bpf/tc_l2_redirect_kern.c
@@ -58,14 +58,11 @@ static __always_inline bool is_vip_addr(__be16 eth_proto, __be32 daddr)
SEC("l2_to_iptun_ingress_forward")
int _l2_to_iptun_ingress_forward(struct __sk_buff *skb)
{
- struct bpf_tunnel_key tkey = {};
void *data = (void *)(long)skb->data;
struct eth_hdr *eth = data;
void *data_end = (void *)(long)skb->data_end;
int key = 0, *ifindex;
- int ret;
-
if (data + sizeof(*eth) > data_end)
return TC_ACT_OK;
@@ -115,8 +112,6 @@ int _l2_to_iptun_ingress_redirect(struct __sk_buff *skb)
void *data_end = (void *)(long)skb->data_end;
int key = 0, *ifindex;
- int ret;
-
if (data + sizeof(*eth) > data_end)
return TC_ACT_OK;
@@ -205,7 +200,6 @@ int _l2_to_ip6tun_ingress_redirect(struct __sk_buff *skb)
SEC("drop_non_tun_vip")
int _drop_non_tun_vip(struct __sk_buff *skb)
{
- struct bpf_tunnel_key tkey = {};
void *data = (void *)(long)skb->data;
struct eth_hdr *eth = data;
void *data_end = (void *)(long)skb->data_end;
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_sock.c b/samples/bpf/test_cgrp2_sock.c
deleted file mode 100644
index a0811df888f4..000000000000
--- a/samples/bpf/test_cgrp2_sock.c
+++ /dev/null
@@ -1,294 +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)
- 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, priori