2019-05-28 20:10:09 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2017-08-05 02:00:10 +03:00
/* Copyright (c) 2017 Facebook
*/
# include <stdio.h>
# include <unistd.h>
# include <fcntl.h>
# include <stdlib.h>
# include <string.h>
# include <linux/perf_event.h>
# include <errno.h>
2020-08-23 11:53:34 +03:00
# include <bpf/libbpf.h>
2018-05-15 08:35:02 +03:00
# include <bpf/bpf.h>
2017-08-05 02:00:10 +03:00
/* This program verifies bpf attachment to tracepoint sys_enter_* and sys_exit_*.
* This requires kernel CONFIG_FTRACE_SYSCALLS to be set .
*/
2017-10-24 09:53:09 +03:00
static void usage ( const char * cmd )
{
printf ( " USAGE: %s [-i num_progs] [-h] \n " , cmd ) ;
printf ( " -i num_progs # number of progs of the test \n " ) ;
printf ( " -h # help \n " ) ;
}
2017-08-05 02:00:10 +03:00
static void verify_map ( int map_id )
{
__u32 key = 0 ;
__u32 val ;
if ( bpf_map_lookup_elem ( map_id , & key , & val ) ! = 0 ) {
fprintf ( stderr , " map_lookup failed: %s \n " , strerror ( errno ) ) ;
return ;
}
2017-10-24 09:53:09 +03:00
if ( val = = 0 ) {
2017-08-05 02:00:10 +03:00
fprintf ( stderr , " failed: map #%d returns value 0 \n " , map_id ) ;
2017-10-24 09:53:09 +03:00
return ;
}
2022-04-02 11:57:08 +03:00
printf ( " verify map:%d val: %d \n " , map_id , val ) ;
2017-10-24 09:53:09 +03:00
val = 0 ;
if ( bpf_map_update_elem ( map_id , & key , & val , BPF_ANY ) ! = 0 ) {
fprintf ( stderr , " map_update failed: %s \n " , strerror ( errno ) ) ;
return ;
}
2017-08-05 02:00:10 +03:00
}
2017-10-24 09:53:09 +03:00
static int test ( char * filename , int num_progs )
2017-08-05 02:00:10 +03:00
{
2020-08-23 11:53:34 +03:00
int map0_fds [ num_progs ] , map1_fds [ num_progs ] , fd , i , j = 0 ;
struct bpf_link * links [ num_progs * 4 ] ;
struct bpf_object * objs [ num_progs ] ;
struct bpf_program * prog ;
2017-08-05 02:00:10 +03:00
2017-10-24 09:53:09 +03:00
for ( i = 0 ; i < num_progs ; i + + ) {
2020-08-23 11:53:34 +03:00
objs [ i ] = bpf_object__open_file ( filename , NULL ) ;
if ( libbpf_get_error ( objs [ i ] ) ) {
fprintf ( stderr , " opening BPF object file failed \n " ) ;
objs [ i ] = NULL ;
goto cleanup ;
2017-10-24 09:53:09 +03:00
}
2020-08-23 11:53:34 +03:00
/* load BPF program */
if ( bpf_object__load ( objs [ i ] ) ) {
fprintf ( stderr , " loading BPF object file failed \n " ) ;
goto cleanup ;
}
map0_fds [ i ] = bpf_object__find_map_fd_by_name ( objs [ i ] ,
" enter_open_map " ) ;
map1_fds [ i ] = bpf_object__find_map_fd_by_name ( objs [ i ] ,
" exit_open_map " ) ;
if ( map0_fds [ i ] < 0 | | map1_fds [ i ] < 0 ) {
fprintf ( stderr , " finding a map in obj file failed \n " ) ;
goto cleanup ;
}
bpf_object__for_each_program ( prog , objs [ i ] ) {
links [ j ] = bpf_program__attach ( prog ) ;
if ( libbpf_get_error ( links [ j ] ) ) {
fprintf ( stderr , " bpf_program__attach failed \n " ) ;
links [ j ] = NULL ;
goto cleanup ;
}
j + + ;
}
printf ( " prog #%d: map ids %d %d \n " , i , map0_fds [ i ] , map1_fds [ i ] ) ;
2017-08-05 02:00:10 +03:00
}
/* current load_bpf_file has perf_event_open default pid = -1
* and cpu = 0 , which permits attached bpf execution on
* all cpus for all pid ' s . bpf program execution ignores
* cpu affinity .
*/
/* trigger some "open" operations */
fd = open ( filename , O_RDONLY ) ;
if ( fd < 0 ) {
fprintf ( stderr , " open failed: %s \n " , strerror ( errno ) ) ;
return 1 ;
}
close ( fd ) ;
/* verify the map */
2017-10-24 09:53:09 +03:00
for ( i = 0 ; i < num_progs ; i + + ) {
verify_map ( map0_fds [ i ] ) ;
verify_map ( map1_fds [ i ] ) ;
}
2017-08-05 02:00:10 +03:00
2020-08-23 11:53:34 +03:00
cleanup :
for ( j - - ; j > = 0 ; j - - )
bpf_link__destroy ( links [ j ] ) ;
for ( i - - ; i > = 0 ; i - - )
bpf_object__close ( objs [ i ] ) ;
2017-08-05 02:00:10 +03:00
return 0 ;
}
2017-10-24 09:53:09 +03:00
int main ( int argc , char * * argv )
{
int opt , num_progs = 1 ;
char filename [ 256 ] ;
while ( ( opt = getopt ( argc , argv , " i:h " ) ) ! = - 1 ) {
switch ( opt ) {
case ' i ' :
num_progs = atoi ( optarg ) ;
break ;
case ' h ' :
default :
usage ( argv [ 0 ] ) ;
return 0 ;
}
}
snprintf ( filename , sizeof ( filename ) , " %s_kern.o " , argv [ 0 ] ) ;
return test ( filename , num_progs ) ;
}