2019-03-20 00:11:49 +03:00
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2021-05-23 18:14:08 +03:00
/*
2019-03-20 00:11:49 +03:00
* ibumad BPF sample user side
*
* 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 .
*
* Copyright ( c ) 2018 Ira Weiny , Intel Corporation
*/
# include <linux/bpf.h>
# include <signal.h>
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <unistd.h>
# include <sys/types.h>
# include <limits.h>
# include <getopt.h>
# include <net/if.h>
2020-11-24 12:03:07 +03:00
# include <bpf/bpf.h>
2019-03-20 00:11:49 +03:00
# include "bpf_util.h"
2020-01-20 16:06:49 +03:00
# include <bpf/libbpf.h>
2019-03-20 00:11:49 +03:00
2020-11-24 12:03:07 +03:00
static struct bpf_link * tp_links [ 3 ] ;
static struct bpf_object * obj ;
static int map_fd [ 2 ] ;
static int tp_cnt ;
2019-03-20 00:11:49 +03:00
static void dump_counts ( int fd )
{
__u32 key ;
__u64 value ;
for ( key = 0 ; key < 256 ; key + + ) {
if ( bpf_map_lookup_elem ( fd , & key , & value ) ) {
printf ( " failed to read key %u \n " , key ) ;
continue ;
}
if ( value )
printf ( " 0x%02x : %llu \n " , key , value ) ;
}
}
static void dump_all_counts ( void )
{
printf ( " Read 'Class : count' \n " ) ;
dump_counts ( map_fd [ 0 ] ) ;
printf ( " Write 'Class : count' \n " ) ;
dump_counts ( map_fd [ 1 ] ) ;
}
static void dump_exit ( int sig )
{
dump_all_counts ( ) ;
2020-11-24 12:03:07 +03:00
/* Detach tracepoints */
while ( tp_cnt )
bpf_link__destroy ( tp_links [ - - tp_cnt ] ) ;
bpf_object__close ( obj ) ;
2019-03-20 00:11:49 +03:00
exit ( 0 ) ;
}
static const struct option long_options [ ] = {
{ " help " , no_argument , NULL , ' h ' } ,
{ " delay " , required_argument , NULL , ' d ' } ,
} ;
static void usage ( char * cmd )
{
printf ( " eBPF test program to count packets from various IP addresses \n "
" Usage: %s <options> \n "
" --help, -h this menu \n "
" --delay, -d <delay> wait <delay> sec between prints [1 - 1000000] \n "
, cmd
) ;
}
int main ( int argc , char * * argv )
{
2020-11-24 12:03:07 +03:00
struct bpf_program * prog ;
2019-03-20 00:11:49 +03:00
unsigned long delay = 5 ;
2020-11-24 12:03:07 +03:00
char filename [ 256 ] ;
2019-03-20 00:11:49 +03:00
int longindex = 0 ;
2020-11-24 12:03:07 +03:00
int opt , err = - 1 ;
2019-03-20 00:11:49 +03:00
while ( ( opt = getopt_long ( argc , argv , " hd:rSw " ,
long_options , & longindex ) ) ! = - 1 ) {
switch ( opt ) {
case ' d ' :
delay = strtoul ( optarg , NULL , 0 ) ;
if ( delay = = ULONG_MAX | | delay < 0 | |
delay > 1000000 ) {
fprintf ( stderr , " ERROR: invalid delay : %s \n " ,
optarg ) ;
usage ( argv [ 0 ] ) ;
return 1 ;
}
break ;
default :
case ' h ' :
usage ( argv [ 0 ] ) ;
return 1 ;
}
}
2020-11-24 12:03:07 +03:00
/* Do one final dump when exiting */
signal ( SIGINT , dump_exit ) ;
signal ( SIGTERM , dump_exit ) ;
snprintf ( filename , sizeof ( filename ) , " %s_kern.o " , argv [ 0 ] ) ;
obj = bpf_object__open_file ( filename , NULL ) ;
if ( libbpf_get_error ( obj ) ) {
fprintf ( stderr , " ERROR: opening BPF object file failed \n " ) ;
return err ;
}
/* load BPF program */
if ( bpf_object__load ( obj ) ) {
fprintf ( stderr , " ERROR: loading BPF object file failed \n " ) ;
goto cleanup ;
}
map_fd [ 0 ] = bpf_object__find_map_fd_by_name ( obj , " read_count " ) ;
map_fd [ 1 ] = bpf_object__find_map_fd_by_name ( obj , " write_count " ) ;
if ( map_fd [ 0 ] < 0 | | map_fd [ 1 ] < 0 ) {
fprintf ( stderr , " ERROR: finding a map in obj file failed \n " ) ;
goto cleanup ;
}
bpf_object__for_each_program ( prog , obj ) {
tp_links [ tp_cnt ] = bpf_program__attach ( prog ) ;
if ( libbpf_get_error ( tp_links [ tp_cnt ] ) ) {
fprintf ( stderr , " ERROR: bpf_program__attach failed \n " ) ;
tp_links [ tp_cnt ] = NULL ;
goto cleanup ;
}
tp_cnt + + ;
2019-03-20 00:11:49 +03:00
}
while ( 1 ) {
sleep ( delay ) ;
dump_all_counts ( ) ;
}
2020-11-24 12:03:07 +03:00
err = 0 ;
cleanup :
/* Detach tracepoints */
while ( tp_cnt )
bpf_link__destroy ( tp_links [ - - tp_cnt ] ) ;
2019-03-20 00:11:49 +03:00
2020-11-24 12:03:07 +03:00
bpf_object__close ( obj ) ;
return err ;
2019-03-20 00:11:49 +03:00
}