forked from analogdevicesinc/linux
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 <[email protected]> Acked-by: Daniel Borkmann <[email protected]> Signed-off-by: David S. Miller <[email protected]>
- Loading branch information
Showing
2 changed files
with
100 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
/* Copyright (c) 2017 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 <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <linux/bpf.h> | ||
#include "libbpf.h" | ||
#include "bpf_load.h" | ||
#include <unistd.h> | ||
#include <errno.h> | ||
#include <fcntl.h> | ||
#include <linux/unistd.h> | ||
|
||
static void usage(char *pname) | ||
{ | ||
printf("USAGE:\n %s [-l] <cg-path> <prog filename>\n", pname); | ||
printf("\tLoad and attach a sock_ops program to the specified " | ||
"cgroup\n"); | ||
printf("\tIf \"-l\" is used, the program will continue to run\n"); | ||
printf("\tprinting the BPF log buffer\n"); | ||
printf("\tIf the specified filename does not end in \".o\", it\n"); | ||
printf("\tappends \"_kern.o\" to the name\n"); | ||
printf("\n"); | ||
printf(" %s -r <cg-path>\n", pname); | ||
printf("\tDetaches the currently attached sock_ops program\n"); | ||
printf("\tfrom the specified cgroup\n"); | ||
printf("\n"); | ||
exit(1); | ||
} | ||
|
||
int main(int argc, char **argv) | ||
{ | ||
int logFlag = 0; | ||
int error = 0; | ||
char *cg_path; | ||
char fn[500]; | ||
char *prog; | ||
int cg_fd; | ||
|
||
if (argc < 3) | ||
usage(argv[0]); | ||
|
||
if (!strcmp(argv[1], "-r")) { | ||
cg_path = argv[2]; | ||
cg_fd = open(cg_path, O_DIRECTORY, O_RDONLY); | ||
error = bpf_prog_detach(cg_fd, BPF_CGROUP_SOCK_OPS); | ||
if (error) { | ||
printf("ERROR: bpf_prog_detach: %d (%s)\n", | ||
error, strerror(errno)); | ||
return 2; | ||
} | ||
return 0; | ||
} else if (!strcmp(argv[1], "-h")) { | ||
usage(argv[0]); | ||
} else if (!strcmp(argv[1], "-l")) { | ||
logFlag = 1; | ||
if (argc < 4) | ||
usage(argv[0]); | ||
} | ||
|
||
prog = argv[argc - 1]; | ||
cg_path = argv[argc - 2]; | ||
if (strlen(prog) > 480) { | ||
fprintf(stderr, "ERROR: program name too long (> 480 chars)\n"); | ||
return 3; | ||
} | ||
cg_fd = open(cg_path, O_DIRECTORY, O_RDONLY); | ||
|
||
if (!strcmp(prog + strlen(prog)-2, ".o")) | ||
strcpy(fn, prog); | ||
else | ||
sprintf(fn, "%s_kern.o", prog); | ||
if (logFlag) | ||
printf("loading bpf file:%s\n", fn); | ||
if (load_bpf_file(fn)) { | ||
printf("ERROR: load_bpf_file failed for: %s\n", fn); | ||
printf("%s", bpf_log_buf); | ||
return 4; | ||
} | ||
if (logFlag) | ||
printf("TCP BPF Loaded %s\n", fn); | ||
|
||
error = bpf_prog_attach(prog_fd[0], cg_fd, BPF_CGROUP_SOCK_OPS, 0); | ||
if (error) { | ||
printf("ERROR: bpf_prog_attach: %d (%s)\n", | ||
error, strerror(errno)); | ||
return 5; | ||
} else if (logFlag) { | ||
read_trace_pipe(); | ||
} | ||
|
||
return error; | ||
} |