2020-05-09 20:59:20 +03:00
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
// Copyright (C) 2020 Facebook
# define _GNU_SOURCE
2020-07-23 21:41:19 +03:00
# include <unistd.h>
2020-05-09 20:59:20 +03:00
# include <linux/err.h>
# include <bpf/libbpf.h>
# include "main.h"
static int do_pin ( int argc , char * * argv )
{
2020-07-23 21:41:19 +03:00
DECLARE_LIBBPF_OPTS ( bpf_iter_attach_opts , iter_opts ) ;
2020-08-05 08:50:58 +03:00
union bpf_iter_link_info linfo ;
2020-05-09 20:59:20 +03:00
const char * objfile , * path ;
struct bpf_program * prog ;
struct bpf_object * obj ;
struct bpf_link * link ;
2020-07-23 21:41:19 +03:00
int err = - 1 , map_fd = - 1 ;
2020-05-09 20:59:20 +03:00
if ( ! REQ_ARGS ( 2 ) )
usage ( ) ;
objfile = GET_ARG ( ) ;
path = GET_ARG ( ) ;
2020-07-23 21:41:19 +03:00
/* optional arguments */
if ( argc ) {
if ( is_prefix ( * argv , " map " ) ) {
NEXT_ARG ( ) ;
if ( ! REQ_ARGS ( 2 ) ) {
p_err ( " incorrect map spec " ) ;
return - 1 ;
}
map_fd = map_parse_fd ( & argc , & argv ) ;
if ( map_fd < 0 )
return - 1 ;
2020-08-05 08:50:58 +03:00
memset ( & linfo , 0 , sizeof ( linfo ) ) ;
linfo . map . map_fd = map_fd ;
iter_opts . link_info = & linfo ;
iter_opts . link_info_len = sizeof ( linfo ) ;
2020-07-23 21:41:19 +03:00
}
}
2020-05-09 20:59:20 +03:00
obj = bpf_object__open ( objfile ) ;
2021-11-15 04:24:36 +03:00
err = libbpf_get_error ( obj ) ;
if ( err ) {
2020-05-09 20:59:20 +03:00
p_err ( " can't open objfile %s " , objfile ) ;
2020-07-23 21:41:19 +03:00
goto close_map_fd ;
2020-05-09 20:59:20 +03:00
}
err = bpf_object__load ( obj ) ;
if ( err ) {
p_err ( " can't load objfile %s " , objfile ) ;
goto close_obj ;
}
2021-10-03 19:58:44 +03:00
prog = bpf_object__next_program ( obj , NULL ) ;
2020-05-09 20:59:20 +03:00
if ( ! prog ) {
p_err ( " can't find bpf program in objfile %s " , objfile ) ;
goto close_obj ;
}
2020-07-23 21:41:19 +03:00
link = bpf_program__attach_iter ( prog , & iter_opts ) ;
2021-11-15 04:24:36 +03:00
err = libbpf_get_error ( link ) ;
if ( err ) {
2020-05-09 20:59:20 +03:00
p_err ( " attach_iter failed for program %s " ,
bpf_program__name ( prog ) ) ;
goto close_obj ;
}
err = mount_bpffs_for_pin ( path ) ;
if ( err )
goto close_link ;
err = bpf_link__pin ( link , path ) ;
if ( err ) {
p_err ( " pin_iter failed for program %s to path %s " ,
bpf_program__name ( prog ) , path ) ;
goto close_link ;
}
close_link :
bpf_link__destroy ( link ) ;
close_obj :
bpf_object__close ( obj ) ;
2020-07-23 21:41:19 +03:00
close_map_fd :
if ( map_fd > = 0 )
close ( map_fd ) ;
2020-05-09 20:59:20 +03:00
return err ;
}
static int do_help ( int argc , char * * argv )
{
fprintf ( stderr ,
2020-07-23 21:41:19 +03:00
" Usage: %1$s %2$s pin OBJ PATH [map MAP] \n "
2020-05-23 04:07:51 +03:00
" %1$s %2$s help \n "
2021-07-31 00:54:32 +03:00
" \n "
2020-07-23 21:41:19 +03:00
" " HELP_SPEC_MAP " \n "
2021-07-31 00:54:32 +03:00
" " HELP_SPEC_OPTIONS " } \n "
2020-05-23 04:07:51 +03:00
" " ,
bin_name , " iter " ) ;
2020-05-09 20:59:20 +03:00
return 0 ;
}
static const struct cmd cmds [ ] = {
{ " help " , do_help } ,
{ " pin " , do_pin } ,
{ 0 }
} ;
int do_iter ( int argc , char * * argv )
{
return cmd_select ( cmds , argc , argv , do_help ) ;
}