diff options
| author | David Ahern <dsa@cumulusnetworks.com> | 2016-12-01 11:48:05 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2016-12-02 13:46:08 -0500 |
| commit | ad2805dc79e647ec2aee931a51924fda9d03b2fc (patch) | |
| tree | 29fbf69d8d6f5f3067a5febb1ad862c1c1f32611 /samples | |
| parent | 61023658760032e97869b07d54be9681d2529e77 (diff) | |
samples: bpf: add userspace example for modifying sk_bound_dev_if
Add a simple program to demonstrate the ability to attach a bpf program
to a cgroup that sets sk_bound_dev_if for AF_INET{6} sockets when they
are created.
Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'samples')
| -rw-r--r-- | samples/bpf/Makefile | 2 | ||||
| -rw-r--r-- | samples/bpf/test_cgrp2_sock.c | 83 | ||||
| -rwxr-xr-x | samples/bpf/test_cgrp2_sock.sh | 47 |
3 files changed, 132 insertions, 0 deletions
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index 44532fbe4cae..e1700c8e0f66 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile | |||
| @@ -23,6 +23,7 @@ hostprogs-y += map_perf_test | |||
| 23 | hostprogs-y += test_overhead | 23 | hostprogs-y += test_overhead |
| 24 | hostprogs-y += test_cgrp2_array_pin | 24 | hostprogs-y += test_cgrp2_array_pin |
| 25 | hostprogs-y += test_cgrp2_attach | 25 | hostprogs-y += test_cgrp2_attach |
| 26 | hostprogs-y += test_cgrp2_sock | ||
| 26 | hostprogs-y += xdp1 | 27 | hostprogs-y += xdp1 |
| 27 | hostprogs-y += xdp2 | 28 | hostprogs-y += xdp2 |
| 28 | hostprogs-y += test_current_task_under_cgroup | 29 | hostprogs-y += test_current_task_under_cgroup |
| @@ -52,6 +53,7 @@ map_perf_test-objs := bpf_load.o libbpf.o map_perf_test_user.o | |||
| 52 | test_overhead-objs := bpf_load.o libbpf.o test_overhead_user.o | 53 | test_overhead-objs := bpf_load.o libbpf.o test_overhead_user.o |
| 53 | test_cgrp2_array_pin-objs := libbpf.o test_cgrp2_array_pin.o | 54 | test_cgrp2_array_pin-objs := libbpf.o test_cgrp2_array_pin.o |
| 54 | test_cgrp2_attach-objs := libbpf.o test_cgrp2_attach.o | 55 | test_cgrp2_attach-objs := libbpf.o test_cgrp2_attach.o |
| 56 | test_cgrp2_sock-objs := libbpf.o test_cgrp2_sock.o | ||
| 55 | xdp1-objs := bpf_load.o libbpf.o xdp1_user.o | 57 | xdp1-objs := bpf_load.o libbpf.o xdp1_user.o |
| 56 | # reuse xdp1 source intentionally | 58 | # reuse xdp1 source intentionally |
| 57 | xdp2-objs := bpf_load.o libbpf.o xdp1_user.o | 59 | xdp2-objs := bpf_load.o libbpf.o xdp1_user.o |
diff --git a/samples/bpf/test_cgrp2_sock.c b/samples/bpf/test_cgrp2_sock.c new file mode 100644 index 000000000000..d467b3c1c55c --- /dev/null +++ b/samples/bpf/test_cgrp2_sock.c | |||
| @@ -0,0 +1,83 @@ | |||
| 1 | /* eBPF example program: | ||
| 2 | * | ||
| 3 | * - Loads eBPF program | ||
| 4 | * | ||
| 5 | * The eBPF program sets the sk_bound_dev_if index in new AF_INET{6} | ||
| 6 | * sockets opened by processes in the cgroup. | ||
| 7 | * | ||
| 8 | * - Attaches the new program to a cgroup using BPF_PROG_ATTACH | ||
| 9 | */ | ||
| 10 | |||
| 11 | #define _GNU_SOURCE | ||
| 12 | |||
| 13 | #include <stdio.h> | ||
| 14 | #include <stdlib.h> | ||
| 15 | #include <stddef.h> | ||
| 16 | #include <string.h> | ||
| 17 | #include <unistd.h> | ||
| 18 | #include <assert.h> | ||
| 19 | #include <errno.h> | ||
| 20 | #include <fcntl.h> | ||
| 21 | #include <net/if.h> | ||
| 22 | #include <linux/bpf.h> | ||
| 23 | |||
| 24 | #include "libbpf.h" | ||
| 25 | |||
| 26 | static int prog_load(int idx) | ||
| 27 | { | ||
| 28 | struct bpf_insn prog[] = { | ||
| 29 | BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), | ||
| 30 | BPF_MOV64_IMM(BPF_REG_3, idx), | ||
| 31 | BPF_MOV64_IMM(BPF_REG_2, offsetof(struct bpf_sock, bound_dev_if)), | ||
| 32 | BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_3, offsetof(struct bpf_sock, bound_dev_if)), | ||
| 33 | BPF_MOV64_IMM(BPF_REG_0, 1), /* r0 = verdict */ | ||
| 34 | BPF_EXIT_INSN(), | ||
| 35 | }; | ||
| 36 | |||
| 37 | return bpf_prog_load(BPF_PROG_TYPE_CGROUP_SOCK, prog, sizeof(prog), | ||
| 38 | "GPL", 0); | ||
| 39 | } | ||
| 40 | |||
| 41 | static int usage(const char *argv0) | ||
| 42 | { | ||
| 43 | printf("Usage: %s cg-path device-index\n", argv0); | ||
| 44 | return EXIT_FAILURE; | ||
| 45 | } | ||
| 46 | |||
| 47 | int main(int argc, char **argv) | ||
| 48 | { | ||
| 49 | int cg_fd, prog_fd, ret; | ||
| 50 | unsigned int idx; | ||
| 51 | |||
| 52 | if (argc < 2) | ||
| 53 | return usage(argv[0]); | ||
| 54 | |||
| 55 | idx = if_nametoindex(argv[2]); | ||
| 56 | if (!idx) { | ||
| 57 | printf("Invalid device name\n"); | ||
| 58 | return EXIT_FAILURE; | ||
| 59 | } | ||
| 60 | |||
| 61 | cg_fd = open(argv[1], O_DIRECTORY | O_RDONLY); | ||
| 62 | if (cg_fd < 0) { | ||
| 63 | printf("Failed to open cgroup path: '%s'\n", strerror(errno)); | ||
| 64 | return EXIT_FAILURE; | ||
| 65 | } | ||
| 66 | |||
| 67 | prog_fd = prog_load(idx); | ||
| 68 | printf("Output from kernel verifier:\n%s\n-------\n", bpf_log_buf); | ||
| 69 | |||
| 70 | if (prog_fd < 0) { | ||
| 71 | printf("Failed to load prog: '%s'\n", strerror(errno)); | ||
| 72 | return EXIT_FAILURE; | ||
| 73 | } | ||
| 74 | |||
| 75 | ret = bpf_prog_attach(prog_fd, cg_fd, BPF_CGROUP_INET_SOCK_CREATE); | ||
| 76 | if (ret < 0) { | ||
| 77 | printf("Failed to attach prog to cgroup: '%s'\n", | ||
| 78 | strerror(errno)); | ||
| 79 | return EXIT_FAILURE; | ||
| 80 | } | ||
| 81 | |||
| 82 | return EXIT_SUCCESS; | ||
| 83 | } | ||
diff --git a/samples/bpf/test_cgrp2_sock.sh b/samples/bpf/test_cgrp2_sock.sh new file mode 100755 index 000000000000..925fd467c7cc --- /dev/null +++ b/samples/bpf/test_cgrp2_sock.sh | |||
| @@ -0,0 +1,47 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | |||
| 3 | function config_device { | ||
| 4 | ip netns add at_ns0 | ||
| 5 | ip link add veth0 type veth peer name veth0b | ||
| 6 | ip link set veth0b up | ||
| 7 | ip link set veth0 netns at_ns0 | ||
| 8 | ip netns exec at_ns0 ip addr add 172.16.1.100/24 dev veth0 | ||
| 9 | ip netns exec at_ns0 ip addr add 2401:db00::1/64 dev veth0 nodad | ||
| 10 | ip netns exec at_ns0 ip link set dev veth0 up | ||
| 11 | ip link add foo type vrf table 1234 | ||
| 12 | ip link set foo up | ||
| 13 | ip addr add 172.16.1.101/24 dev veth0b | ||
| 14 | ip addr add 2401:db00::2/64 dev veth0b nodad | ||
| 15 | ip link set veth0b master foo | ||
| 16 | } | ||
| 17 | |||
| 18 | function attach_bpf { | ||
| 19 | rm -rf /tmp/cgroupv2 | ||
| 20 | mkdir -p /tmp/cgroupv2 | ||
| 21 | mount -t cgroup2 none /tmp/cgroupv2 | ||
| 22 | mkdir -p /tmp/cgroupv2/foo | ||
| 23 | test_cgrp2_sock /tmp/cgroupv2/foo foo | ||
| 24 | echo $$ >> /tmp/cgroupv2/foo/cgroup.procs | ||
| 25 | } | ||
| 26 | |||
| 27 | function cleanup { | ||
| 28 | set +ex | ||
| 29 | ip netns delete at_ns0 | ||
| 30 | ip link del veth0 | ||
| 31 | ip link del foo | ||
| 32 | umount /tmp/cgroupv2 | ||
| 33 | rm -rf /tmp/cgroupv2 | ||
| 34 | set -ex | ||
| 35 | } | ||
| 36 | |||
| 37 | function do_test { | ||
| 38 | ping -c1 -w1 172.16.1.100 | ||
| 39 | ping6 -c1 -w1 2401:db00::1 | ||
| 40 | } | ||
| 41 | |||
| 42 | cleanup 2>/dev/null | ||
| 43 | config_device | ||
| 44 | attach_bpf | ||
| 45 | do_test | ||
| 46 | cleanup | ||
| 47 | echo "*** PASS ***" | ||
