2020-01-15 13:15:39 +00:00
// SPDX-License-Identifier: GPL-2.0
# include <test_progs.h>
2020-05-08 10:46:09 -07:00
# include <network_helpers.h>
2020-01-15 13:15:39 +00:00
# include <net/if.h>
# include "test_xdp.skel.h"
# include "test_xdp_bpf2bpf.skel.h"
2020-03-06 08:59:23 +00:00
struct meta {
int ifindex ;
int pkt_len ;
} ;
static void on_sample ( void * ctx , int cpu , void * data , __u32 size )
{
int duration = 0 ;
struct meta * meta = ( struct meta * ) data ;
struct ipv4_packet * trace_pkt_v4 = data + sizeof ( * meta ) ;
if ( CHECK ( size < sizeof ( pkt_v4 ) + sizeof ( * meta ) ,
" check_size " , " size %u < %zu \n " ,
size , sizeof ( pkt_v4 ) + sizeof ( * meta ) ) )
return ;
if ( CHECK ( meta - > ifindex ! = if_nametoindex ( " lo " ) , " check_meta_ifindex " ,
" meta->ifindex = %d \n " , meta - > ifindex ) )
return ;
if ( CHECK ( meta - > pkt_len ! = sizeof ( pkt_v4 ) , " check_meta_pkt_len " ,
" meta->pkt_len = %zd \n " , sizeof ( pkt_v4 ) ) )
return ;
if ( CHECK ( memcmp ( trace_pkt_v4 , & pkt_v4 , sizeof ( pkt_v4 ) ) ,
" check_packet_content " , " content not the same \n " ) )
return ;
* ( bool * ) ctx = true ;
}
2020-01-15 13:15:39 +00:00
void test_xdp_bpf2bpf ( void )
{
__u32 duration = 0 , retval , size ;
char buf [ 128 ] ;
int err , pkt_fd , map_fd ;
2020-03-06 08:59:23 +00:00
bool passed = false ;
2020-01-15 13:15:39 +00:00
struct iphdr * iph = ( void * ) buf + sizeof ( struct ethhdr ) ;
struct iptnl_info value4 = { . family = AF_INET } ;
struct test_xdp * pkt_skel = NULL ;
struct test_xdp_bpf2bpf * ftrace_skel = NULL ;
struct vip key4 = { . protocol = 6 , . family = AF_INET } ;
2020-02-20 13:26:45 +00:00
struct bpf_program * prog ;
2020-03-06 08:59:23 +00:00
struct perf_buffer * pb = NULL ;
struct perf_buffer_opts pb_opts = { } ;
2020-01-15 13:15:39 +00:00
/* Load XDP program to introspect */
pkt_skel = test_xdp__open_and_load ( ) ;
if ( CHECK ( ! pkt_skel , " pkt_skel_load " , " test_xdp skeleton failed \n " ) )
return ;
pkt_fd = bpf_program__fd ( pkt_skel - > progs . _xdp_tx_iptunnel ) ;
map_fd = bpf_map__fd ( pkt_skel - > maps . vip2tnl ) ;
bpf_map_update_elem ( map_fd , & key4 , & value4 , 0 ) ;
/* Load trace program */
2020-02-20 13:26:45 +00:00
ftrace_skel = test_xdp_bpf2bpf__open ( ) ;
2020-01-15 13:15:39 +00:00
if ( CHECK ( ! ftrace_skel , " __open " , " ftrace skeleton failed \n " ) )
goto out ;
2020-02-20 13:26:45 +00:00
/* Demonstrate the bpf_program__set_attach_target() API rather than
* the load with options , i . e . opts . attach_prog_fd .
*/
prog = ftrace_skel - > progs . trace_on_entry ;
bpf_program__set_expected_attach_type ( prog , BPF_TRACE_FENTRY ) ;
bpf_program__set_attach_target ( prog , pkt_fd , " _xdp_tx_iptunnel " ) ;
prog = ftrace_skel - > progs . trace_on_exit ;
bpf_program__set_expected_attach_type ( prog , BPF_TRACE_FEXIT ) ;
bpf_program__set_attach_target ( prog , pkt_fd , " _xdp_tx_iptunnel " ) ;
2020-01-15 13:15:39 +00:00
err = test_xdp_bpf2bpf__load ( ftrace_skel ) ;
if ( CHECK ( err , " __load " , " ftrace skeleton failed \n " ) )
goto out ;
err = test_xdp_bpf2bpf__attach ( ftrace_skel ) ;
if ( CHECK ( err , " ftrace_attach " , " ftrace attach failed: %d \n " , err ) )
goto out ;
2020-03-06 08:59:23 +00:00
/* Set up perf buffer */
pb_opts . sample_cb = on_sample ;
pb_opts . ctx = & passed ;
pb = perf_buffer__new ( bpf_map__fd ( ftrace_skel - > maps . perf_buf_map ) ,
1 , & pb_opts ) ;
if ( CHECK ( IS_ERR ( pb ) , " perf_buf__new " , " err %ld \n " , PTR_ERR ( pb ) ) )
goto out ;
2020-01-15 13:15:39 +00:00
/* Run test program */
err = bpf_prog_test_run ( pkt_fd , 1 , & pkt_v4 , sizeof ( pkt_v4 ) ,
buf , & size , & retval , & duration ) ;
if ( CHECK ( err | | retval ! = XDP_TX | | size ! = 74 | |
iph - > protocol ! = IPPROTO_IPIP , " ipv4 " ,
" err %d errno %d retval %d size %d \n " ,
err , errno , retval , size ) )
goto out ;
2020-03-06 08:59:23 +00:00
/* Make sure bpf_xdp_output() was triggered and it sent the expected
* data to the perf ring buffer .
*/
err = perf_buffer__poll ( pb , 100 ) ;
if ( CHECK ( err < 0 , " perf_buffer__poll " , " err %d \n " , err ) )
goto out ;
CHECK_FAIL ( ! passed ) ;
2020-01-15 13:15:39 +00:00
/* Verify test results */
if ( CHECK ( ftrace_skel - > bss - > test_result_fentry ! = if_nametoindex ( " lo " ) ,
" result " , " fentry failed err %llu \n " ,
ftrace_skel - > bss - > test_result_fentry ) )
goto out ;
CHECK ( ftrace_skel - > bss - > test_result_fexit ! = XDP_TX , " result " ,
" fexit failed err %llu \n " , ftrace_skel - > bss - > test_result_fexit ) ;
out :
2020-03-06 08:59:23 +00:00
if ( pb )
perf_buffer__free ( pb ) ;
2020-01-15 13:15:39 +00:00
test_xdp__destroy ( pkt_skel ) ;
test_xdp_bpf2bpf__destroy ( ftrace_skel ) ;
}