2018-09-14 07:46:22 -07:00
// SPDX-License-Identifier: GPL-2.0
# include <error.h>
# include <errno.h>
# include <getopt.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <sys/stat.h>
# include <fcntl.h>
# include <unistd.h>
# include <bpf/bpf.h>
# include <bpf/libbpf.h>
2019-01-28 08:53:55 -08:00
# include "flow_dissector_load.h"
2018-10-29 14:56:48 -07:00
2018-09-14 07:46:22 -07:00
const char * cfg_pin_path = " /sys/fs/bpf/flow_dissector " ;
const char * cfg_map_name = " jmp_table " ;
bool cfg_attach = true ;
2021-10-21 14:48:14 -07:00
char * cfg_prog_name ;
2018-09-14 07:46:22 -07:00
char * cfg_path_name ;
static void load_and_attach_program ( void )
{
2019-01-28 08:53:55 -08:00
int prog_fd , ret ;
2018-09-14 07:46:22 -07:00
struct bpf_object * obj ;
2022-04-09 12:59:56 +00:00
/* Use libbpf 1.0 API mode */
libbpf_set_strict_mode ( LIBBPF_STRICT_ALL ) ;
2021-10-21 14:48:14 -07:00
ret = bpf_flow_load ( & obj , cfg_path_name , cfg_prog_name ,
2019-04-22 08:55:50 -07:00
cfg_map_name , NULL , & prog_fd , NULL ) ;
2018-09-14 07:46:22 -07:00
if ( ret )
2019-01-28 08:53:55 -08:00
error ( 1 , 0 , " bpf_flow_load %s " , cfg_path_name ) ;
2018-09-14 07:46:22 -07:00
ret = bpf_prog_attach ( prog_fd , 0 /* Ignore */ , BPF_FLOW_DISSECTOR , 0 ) ;
if ( ret )
error ( 1 , 0 , " bpf_prog_attach %s " , cfg_path_name ) ;
ret = bpf_object__pin ( obj , cfg_pin_path ) ;
if ( ret )
error ( 1 , 0 , " bpf_object__pin %s " , cfg_pin_path ) ;
}
static void detach_program ( void )
{
char command [ 64 ] ;
int ret ;
ret = bpf_prog_detach ( 0 , BPF_FLOW_DISSECTOR ) ;
if ( ret )
error ( 1 , 0 , " bpf_prog_detach " ) ;
/* To unpin, it is necessary and sufficient to just remove this dir */
sprintf ( command , " rm -r %s " , cfg_pin_path ) ;
ret = system ( command ) ;
if ( ret )
2019-04-02 10:08:33 -07:00
error ( 1 , errno , " %s " , command ) ;
2018-09-14 07:46:22 -07:00
}
static void parse_opts ( int argc , char * * argv )
{
bool attach = false ;
bool detach = false ;
int c ;
while ( ( c = getopt ( argc , argv , " adp:s: " ) ) ! = - 1 ) {
switch ( c ) {
case ' a ' :
if ( detach )
error ( 1 , 0 , " attach/detach are exclusive " ) ;
attach = true ;
break ;
case ' d ' :
if ( attach )
error ( 1 , 0 , " attach/detach are exclusive " ) ;
detach = true ;
break ;
case ' p ' :
if ( cfg_path_name )
2021-10-21 14:48:14 -07:00
error ( 1 , 0 , " only one path can be given " ) ;
2018-09-14 07:46:22 -07:00
cfg_path_name = optarg ;
break ;
case ' s ' :
2021-10-21 14:48:14 -07:00
if ( cfg_prog_name )
error ( 1 , 0 , " only one prog can be given " ) ;
2018-09-14 07:46:22 -07:00
2021-10-21 14:48:14 -07:00
cfg_prog_name = optarg ;
2018-09-14 07:46:22 -07:00
break ;
}
}
if ( detach )
cfg_attach = false ;
if ( cfg_attach & & ! cfg_path_name )
error ( 1 , 0 , " must provide a path to the BPF program " ) ;
2021-10-21 14:48:14 -07:00
if ( cfg_attach & & ! cfg_prog_name )
2018-09-14 07:46:22 -07:00
error ( 1 , 0 , " must provide a section name " ) ;
}
int main ( int argc , char * * argv )
{
parse_opts ( argc , argv ) ;
if ( cfg_attach )
load_and_attach_program ( ) ;
else
detach_program ( ) ;
return 0 ;
}