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.
Unified · Split
| @@ -36,6 +36,7 @@ hostprogs-y += lwt_len_hist · 35 unmodified lines | ||
| 36 | 36 | hostprogs-y += xdp_tx_iptunnel |
| 37 | 37 | hostprogs-y += test_map_in_map |
| 38 | 38 | hostprogs-y += per_socket_stats_example |
| 39 | +hostprogs-y += load_sock_ops | |
| 39 | 40 | |
| 40 | 41 | # Libbpf dependencies |
| 41 | 42 | LIBBPF := ../../tools/lib/bpf/bpf.o |
| @@ -52,6 +53,7 @@ tracex3-objs := bpf_load.o $(LIBBPF) tracex3_user.o · 10 unmodified lines | ||
| 52 | 53 | tracex4-objs := bpf_load.o $(LIBBPF) tracex4_user.o |
| 53 | 54 | tracex5-objs := bpf_load.o $(LIBBPF) tracex5_user.o |
| 54 | 55 | tracex6-objs := bpf_load.o $(LIBBPF) tracex6_user.o |
| 56 | +load_sock_ops-objs := bpf_load.o $(LIBBPF) load_sock_ops.o | |
| 55 | 57 | test_probe_write_user-objs := bpf_load.o $(LIBBPF) test_probe_write_user_user.o |
| 56 | 58 | trace_output-objs := bpf_load.o $(LIBBPF) trace_output_user.o |
| 57 | 59 | lathist-objs := bpf_load.o $(LIBBPF) lathist_user.o |
| @@ -130,6 +132,7 @@ HOSTLOADLIBES_tracex4 += -lelf -lrt · 72 unmodified lines | ||
| 130 | 132 | HOSTLOADLIBES_tracex5 += -lelf |
| 131 | 133 | HOSTLOADLIBES_tracex6 += -lelf |
| 132 | 134 | HOSTLOADLIBES_test_cgrp2_sock2 += -lelf |
| 135 | +HOSTLOADLIBES_load_sock_ops += -lelf | |
| 133 | 136 | HOSTLOADLIBES_test_probe_write_user += -lelf |
| 134 | 137 | HOSTLOADLIBES_trace_output += -lelf -lrt |
| 135 | 138 | HOSTLOADLIBES_lathist += -lelf |
| @@ -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 | +} | |