2019-11-14 21:57:20 +03:00
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2019 Facebook */
# include <test_progs.h>
2020-05-08 20:46:09 +03:00
# include <network_helpers.h>
2019-11-14 21:57:20 +03:00
2019-12-05 04:06:07 +03:00
static void test_fexit_bpf2bpf_common ( const char * obj_file ,
const char * target_obj_file ,
int prog_cnt ,
2020-04-24 16:34:28 +03:00
const char * * prog_name ,
bool run_prog )
2019-11-14 21:57:20 +03:00
{
struct bpf_object * obj = NULL , * pkt_obj ;
int err , pkt_fd , i ;
2019-12-05 04:06:07 +03:00
struct bpf_link * * link = NULL ;
struct bpf_program * * prog = NULL ;
selftests/bpf: Initialize duration variable before using
The 'duration' variable is referenced in the CHECK() macro, and there are
some uses of the macro before 'duration' is set. The clang compiler
(validly) complains about this.
Sample error:
.../selftests/bpf/prog_tests/fexit_test.c:23:6: warning: variable 'duration' is uninitialized when used here [-Wuninitialized]
if (CHECK(err, "prog_load sched cls", "err %d errno %d\n", err, errno))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.../selftests/bpf/test_progs.h:134:25: note: expanded from macro 'CHECK'
if (CHECK(err, "prog_load sched cls", "err %d errno %d\n", err, errno))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
_CHECK(condition, tag, duration, format)
^~~~~~~~
Signed-off-by: John Sperbeck <jsperbeck@google.com>
Signed-off-by: Stanislav Fomichev <sdf@google.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Martin KaFai Lau <kafai@fb.com>
Link: https://lore.kernel.org/bpf/20200123235144.93610-1-sdf@google.com
2020-01-24 02:51:44 +03:00
__u32 duration = 0 , retval ;
2019-11-14 21:57:20 +03:00
struct bpf_map * data_map ;
const int zero = 0 ;
2020-08-13 23:49:38 +03:00
__u64 * result = NULL ;
2019-11-14 21:57:20 +03:00
2019-12-05 04:06:07 +03:00
err = bpf_prog_load ( target_obj_file , BPF_PROG_TYPE_UNSPEC ,
2019-11-14 21:57:20 +03:00
& pkt_obj , & pkt_fd ) ;
2020-04-24 16:34:28 +03:00
if ( CHECK ( err , " tgt_prog_load " , " file %s err %d errno %d \n " ,
target_obj_file , err , errno ) )
2019-11-14 21:57:20 +03:00
return ;
DECLARE_LIBBPF_OPTS ( bpf_object_open_opts , opts ,
. attach_prog_fd = pkt_fd ,
) ;
2019-12-05 04:06:07 +03:00
link = calloc ( sizeof ( struct bpf_link * ) , prog_cnt ) ;
prog = calloc ( sizeof ( struct bpf_program * ) , prog_cnt ) ;
2020-08-13 23:49:38 +03:00
result = malloc ( ( prog_cnt + 32 /* spare */ ) * sizeof ( __u64 ) ) ;
2019-12-05 04:06:07 +03:00
if ( CHECK ( ! link | | ! prog | | ! result , " alloc_memory " ,
" failed to alloc memory " ) )
goto close_prog ;
obj = bpf_object__open_file ( obj_file , & opts ) ;
2019-11-14 21:57:20 +03:00
if ( CHECK ( IS_ERR_OR_NULL ( obj ) , " obj_open " ,
2020-04-24 16:34:28 +03:00
" failed to open %s: %ld \n " , obj_file ,
2019-11-14 21:57:20 +03:00
PTR_ERR ( obj ) ) )
goto close_prog ;
err = bpf_object__load ( obj ) ;
if ( CHECK ( err , " obj_load " , " err %d \n " , err ) )
goto close_prog ;
2019-12-05 04:06:07 +03:00
for ( i = 0 ; i < prog_cnt ; i + + ) {
2019-11-14 21:57:20 +03:00
prog [ i ] = bpf_object__find_program_by_title ( obj , prog_name [ i ] ) ;
if ( CHECK ( ! prog [ i ] , " find_prog " , " prog %s not found \n " , prog_name [ i ] ) )
goto close_prog ;
link [ i ] = bpf_program__attach_trace ( prog [ i ] ) ;
if ( CHECK ( IS_ERR ( link [ i ] ) , " attach_trace " , " failed to link \n " ) )
goto close_prog ;
}
2020-04-24 16:34:28 +03:00
if ( ! run_prog )
goto close_prog ;
2019-11-14 21:57:20 +03:00
data_map = bpf_object__find_map_by_name ( obj , " fexit_bp.bss " ) ;
if ( CHECK ( ! data_map , " find_data_map " , " data map not found \n " ) )
goto close_prog ;
err = bpf_prog_test_run ( pkt_fd , 1 , & pkt_v6 , sizeof ( pkt_v6 ) ,
NULL , NULL , & retval , & duration ) ;
CHECK ( err | | retval , " ipv6 " ,
" err %d errno %d retval %d duration %d \n " ,
err , errno , retval , duration ) ;
2019-12-05 04:06:07 +03:00
err = bpf_map_lookup_elem ( bpf_map__fd ( data_map ) , & zero , result ) ;
2019-11-14 21:57:20 +03:00
if ( CHECK ( err , " get_result " ,
" failed to get output data: %d \n " , err ) )
goto close_prog ;
2019-12-05 04:06:07 +03:00
for ( i = 0 ; i < prog_cnt ; i + + )
2020-08-13 23:49:38 +03:00
if ( CHECK ( result [ i ] ! = 1 , " result " , " fexit_bpf2bpf failed err %llu \n " ,
2019-11-14 21:57:20 +03:00
result [ i ] ) )
goto close_prog ;
close_prog :
2019-12-05 04:06:07 +03:00
for ( i = 0 ; i < prog_cnt ; i + + )
2019-11-14 21:57:20 +03:00
if ( ! IS_ERR_OR_NULL ( link [ i ] ) )
bpf_link__destroy ( link [ i ] ) ;
if ( ! IS_ERR_OR_NULL ( obj ) )
bpf_object__close ( obj ) ;
bpf_object__close ( pkt_obj ) ;
2019-12-05 04:06:07 +03:00
free ( link ) ;
free ( prog ) ;
free ( result ) ;
}
static void test_target_no_callees ( void )
{
const char * prog_name [ ] = {
" fexit/test_pkt_md_access " ,
} ;
test_fexit_bpf2bpf_common ( " ./fexit_bpf2bpf_simple.o " ,
" ./test_pkt_md_access.o " ,
ARRAY_SIZE ( prog_name ) ,
2020-04-24 16:34:28 +03:00
prog_name , true ) ;
2019-12-05 04:06:07 +03:00
}
static void test_target_yes_callees ( void )
{
const char * prog_name [ ] = {
" fexit/test_pkt_access " ,
" fexit/test_pkt_access_subprog1 " ,
" fexit/test_pkt_access_subprog2 " ,
2020-01-10 09:41:21 +03:00
" fexit/test_pkt_access_subprog3 " ,
2019-12-05 04:06:07 +03:00
} ;
test_fexit_bpf2bpf_common ( " ./fexit_bpf2bpf.o " ,
" ./test_pkt_access.o " ,
ARRAY_SIZE ( prog_name ) ,
2020-04-24 16:34:28 +03:00
prog_name , true ) ;
2019-12-05 04:06:07 +03:00
}
2020-01-21 03:53:48 +03:00
static void test_func_replace ( void )
{
const char * prog_name [ ] = {
" fexit/test_pkt_access " ,
" fexit/test_pkt_access_subprog1 " ,
" fexit/test_pkt_access_subprog2 " ,
" fexit/test_pkt_access_subprog3 " ,
" freplace/get_skb_len " ,
" freplace/get_skb_ifindex " ,
" freplace/get_constant " ,
2020-08-26 02:20:01 +03:00
" freplace/test_pkt_write_access_subprog " ,
2020-01-21 03:53:48 +03:00
} ;
test_fexit_bpf2bpf_common ( " ./fexit_bpf2bpf.o " ,
" ./test_pkt_access.o " ,
ARRAY_SIZE ( prog_name ) ,
2020-04-24 16:34:28 +03:00
prog_name , true ) ;
}
static void test_func_replace_verify ( void )
{
const char * prog_name [ ] = {
" freplace/do_bind " ,
} ;
test_fexit_bpf2bpf_common ( " ./freplace_connect4.o " ,
" ./connect4_prog.o " ,
ARRAY_SIZE ( prog_name ) ,
prog_name , false ) ;
2020-01-21 03:53:48 +03:00
}
2019-12-05 04:06:07 +03:00
void test_fexit_bpf2bpf ( void )
{
test_target_no_callees ( ) ;
test_target_yes_callees ( ) ;
2020-01-21 03:53:48 +03:00
test_func_replace ( ) ;
2020-04-24 16:34:28 +03:00
test_func_replace_verify ( ) ;
2019-11-14 21:57:20 +03:00
}