2017-06-30 20:02:41 -07:00
/* 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>
2018-05-14 22:35:02 -07:00
# include <bpf/bpf.h>
2017-06-30 20:02:41 -07:00
# 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 ( " \t Load and attach a sock_ops program to the specified "
" cgroup \n " ) ;
printf ( " \t If \" -l \" is used, the program will continue to run \n " ) ;
printf ( " \t printing the BPF log buffer \n " ) ;
printf ( " \t If the specified filename does not end in \" .o \" , it \n " ) ;
printf ( " \t appends \" _kern.o \" to the name \n " ) ;
printf ( " \n " ) ;
printf ( " %s -r <cg-path> \n " , pname ) ;
printf ( " \t Detaches the currently attached sock_ops program \n " ) ;
printf ( " \t from 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 ;
}