diff options
| author | Lawrence Brakmo <brakmo@fb.com> | 2017-06-30 23:02:41 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2017-07-01 19:15:13 -0400 |
| commit | ae16189efb0fe2bdc5e702bd6221ed6d0ff5babd (patch) | |
| tree | 59dfe86ee7237f06ac230eacc7bf5bddf6dbdb77 /samples | |
| parent | 40304b2a1567fecc321f640ee4239556dd0f3ee0 (diff) | |
bpf: program to load and attach sock_ops BPF progs
The program load_sock_ops can be used to load sock_ops bpf programs and
to attach it to an existing (v2) cgroup. It can also be used to detach
sock_ops programs.
Examples:
load_sock_ops [-l] <cg-path> <prog filename>
Load and attaches a sock_ops program at the specified cgroup.
If "-l" is used, the program will continue to run to output the
BPF log buffer.
If the specified filename does not end in ".o", it appends
"_kern.o" to the name.
load_sock_ops -r <cg-path>
Detaches the currently attached sock_ops program from the
specified cgroup.
Signed-off-by: Lawrence Brakmo <brakmo@fb.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'samples')
| -rw-r--r-- | samples/bpf/Makefile | 3 | ||||
| -rw-r--r-- | samples/bpf/load_sock_ops.c | 97 |
2 files changed, 100 insertions, 0 deletions
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index e7ec9b8539a5..015589b50c37 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile | |||
| @@ -36,6 +36,7 @@ hostprogs-y += lwt_len_hist | |||
| 36 | hostprogs-y += xdp_tx_iptunnel | 36 | hostprogs-y += xdp_tx_iptunnel |
| 37 | hostprogs-y += test_map_in_map | 37 | hostprogs-y += test_map_in_map |
| 38 | hostprogs-y += per_socket_stats_example | 38 | hostprogs-y += per_socket_stats_example |
| 39 | hostprogs-y += load_sock_ops | ||
| 39 | 40 | ||
| 40 | # Libbpf dependencies | 41 | # Libbpf dependencies |
| 41 | LIBBPF := ../../tools/lib/bpf/bpf.o | 42 | LIBBPF := ../../tools/lib/bpf/bpf.o |
| @@ -52,6 +53,7 @@ tracex3-objs := bpf_load.o $(LIBBPF) tracex3_user.o | |||
| 52 | tracex4-objs := bpf_load.o $(LIBBPF) tracex4_user.o | 53 | tracex4-objs := bpf_load.o $(LIBBPF) tracex4_user.o |
| 53 | tracex5-objs := bpf_load.o $(LIBBPF) tracex5_user.o | 54 | tracex5-objs := bpf_load.o $(LIBBPF) tracex5_user.o |
| 54 | tracex6-objs := bpf_load.o $(LIBBPF) tracex6_user.o | 55 | tracex6-objs := bpf_load.o $(LIBBPF) tracex6_user.o |
| 56 | load_sock_ops-objs := bpf_load.o $(LIBBPF) load_sock_ops.o | ||
| 55 | test_probe_write_user-objs := bpf_load.o $(LIBBPF) test_probe_write_user_user.o | 57 | test_probe_write_user-objs := bpf_load.o $(LIBBPF) test_probe_write_user_user.o |
| 56 | trace_output-objs := bpf_load.o $(LIBBPF) trace_output_user.o | 58 | trace_output-objs := bpf_load.o $(LIBBPF) trace_output_user.o |
| 57 | lathist-objs := bpf_load.o $(LIBBPF) lathist_user.o | 59 | lathist-objs := bpf_load.o $(LIBBPF) lathist_user.o |
| @@ -130,6 +132,7 @@ HOSTLOADLIBES_tracex4 += -lelf -lrt | |||
| 130 | HOSTLOADLIBES_tracex5 += -lelf | 132 | HOSTLOADLIBES_tracex5 += -lelf |
| 131 | HOSTLOADLIBES_tracex6 += -lelf | 133 | HOSTLOADLIBES_tracex6 += -lelf |
| 132 | HOSTLOADLIBES_test_cgrp2_sock2 += -lelf | 134 | HOSTLOADLIBES_test_cgrp2_sock2 += -lelf |
| 135 | HOSTLOADLIBES_load_sock_ops += -lelf | ||
| 133 | HOSTLOADLIBES_test_probe_write_user += -lelf | 136 | HOSTLOADLIBES_test_probe_write_user += -lelf |
| 134 | HOSTLOADLIBES_trace_output += -lelf -lrt | 137 | HOSTLOADLIBES_trace_output += -lelf -lrt |
| 135 | HOSTLOADLIBES_lathist += -lelf | 138 | HOSTLOADLIBES_lathist += -lelf |
diff --git a/samples/bpf/load_sock_ops.c b/samples/bpf/load_sock_ops.c new file mode 100644 index 000000000000..e5da6cf71a3e --- /dev/null +++ b/samples/bpf/load_sock_ops.c | |||
| @@ -0,0 +1,97 @@ | |||
| 1 | /* Copyright (c) 2017 Facebook | ||
| 2 | * | ||
| 3 | * This program is free software; you can redistribute it and/or | ||
| 4 | * modify it under the terms of version 2 of the GNU General Public | ||
| 5 | * License as published by the Free Software Foundation. | ||
| 6 | */ | ||
| 7 | #include <stdio.h> | ||
| 8 | #include <stdlib.h> | ||
| 9 | #include <string.h> | ||
| 10 | #include <linux/bpf.h> | ||
| 11 | #include "libbpf.h" | ||
| 12 | #include "bpf_load.h" | ||
| 13 | #include <unistd.h> | ||
| 14 | #include <errno.h> | ||
| 15 | #include <fcntl.h> | ||
| 16 | #include <linux/unistd.h> | ||
| 17 | |||
| 18 | static void usage(char *pname) | ||
| 19 | { | ||
| 20 | printf("USAGE:\n %s [-l] <cg-path> <prog filename>\n", pname); | ||
| 21 | printf("\tLoad and attach a sock_ops program to the specified " | ||
| 22 | "cgroup\n"); | ||
| 23 | printf("\tIf \"-l\" is used, the program will continue to run\n"); | ||
| 24 | printf("\tprinting the BPF log buffer\n"); | ||
| 25 | printf("\tIf the specified filename does not end in \".o\", it\n"); | ||
| 26 | printf("\tappends \"_kern.o\" to the name\n"); | ||
| 27 | printf("\n"); | ||
| 28 | printf(" %s -r <cg-path>\n", pname); | ||
| 29 | printf("\tDetaches the currently attached sock_ops program\n"); | ||
| 30 | printf("\tfrom the specified cgroup\n"); | ||
| 31 | printf("\n"); | ||
| 32 | exit(1); | ||
| 33 | } | ||
| 34 | |||
| 35 | int main(int argc, char **argv) | ||
| 36 | { | ||
| 37 | int logFlag = 0; | ||
| 38 | int error = 0; | ||
| 39 | char *cg_path; | ||
| 40 | char fn[500]; | ||
| 41 | char *prog; | ||
| 42 | int cg_fd; | ||
| 43 | |||
| 44 | if (argc < 3) | ||
| 45 | usage(argv[0]); | ||
| 46 | |||
| 47 | if (!strcmp(argv[1], "-r")) { | ||
| 48 | cg_path = argv[2]; | ||
| 49 | cg_fd = open(cg_path, O_DIRECTORY, O_RDONLY); | ||
| 50 | error = bpf_prog_detach(cg_fd, BPF_CGROUP_SOCK_OPS); | ||
| 51 | if (error) { | ||
| 52 | printf("ERROR: bpf_prog_detach: %d (%s)\n", | ||
| 53 | error, strerror(errno)); | ||
| 54 | return 2; | ||
| 55 | } | ||
| 56 | return 0; | ||
| 57 | } else if (!strcmp(argv[1], "-h")) { | ||
| 58 | usage(argv[0]); | ||
| 59 | } else if (!strcmp(argv[1], "-l")) { | ||
| 60 | logFlag = 1; | ||
| 61 | if (argc < 4) | ||
| 62 | usage(argv[0]); | ||
| 63 | } | ||
| 64 | |||
| 65 | prog = argv[argc - 1]; | ||
| 66 | cg_path = argv[argc - 2]; | ||
| 67 | if (strlen(prog) > 480) { | ||
| 68 | fprintf(stderr, "ERROR: program name too long (> 480 chars)\n"); | ||
| 69 | return 3; | ||
| 70 | } | ||
| 71 | cg_fd = open(cg_path, O_DIRECTORY, O_RDONLY); | ||
| 72 | |||
| 73 | if (!strcmp(prog + strlen(prog)-2, ".o")) | ||
| 74 | strcpy(fn, prog); | ||
| 75 | else | ||
| 76 | sprintf(fn, "%s_kern.o", prog); | ||
| 77 | if (logFlag) | ||
| 78 | printf("loading bpf file:%s\n", fn); | ||
| 79 | if (load_bpf_file(fn)) { | ||
| 80 | printf("ERROR: load_bpf_file failed for: %s\n", fn); | ||
| 81 | printf("%s", bpf_log_buf); | ||
| 82 | return 4; | ||
| 83 | } | ||
| 84 | if (logFlag) | ||
| 85 | printf("TCP BPF Loaded %s\n", fn); | ||
| 86 | |||
| 87 | error = bpf_prog_attach(prog_fd[0], cg_fd, BPF_CGROUP_SOCK_OPS, 0); | ||
| 88 | if (error) { | ||
| 89 | printf("ERROR: bpf_prog_attach: %d (%s)\n", | ||
| 90 | error, strerror(errno)); | ||
| 91 | return 5; | ||
| 92 | } else if (logFlag) { | ||
| 93 | read_trace_pipe(); | ||
| 94 | } | ||
| 95 | |||
| 96 | return error; | ||
| 97 | } | ||
