@@ -26,12 +26,37 @@ static const char *__doc_err_only__=
26
26
#include <net/if.h>
27
27
#include <time.h>
28
28
29
+ #include <signal.h>
29
30
#include <bpf/bpf.h>
30
- #include "bpf_load.h"
31
+ #include <bpf/libbpf.h>
31
32
#include "bpf_util.h"
32
33
34
+ enum map_type {
35
+ REDIRECT_ERR_CNT ,
36
+ EXCEPTION_CNT ,
37
+ CPUMAP_ENQUEUE_CNT ,
38
+ CPUMAP_KTHREAD_CNT ,
39
+ DEVMAP_XMIT_CNT ,
40
+ };
41
+
42
+ static const char * const map_type_strings [] = {
43
+ [REDIRECT_ERR_CNT ] = "redirect_err_cnt" ,
44
+ [EXCEPTION_CNT ] = "exception_cnt" ,
45
+ [CPUMAP_ENQUEUE_CNT ] = "cpumap_enqueue_cnt" ,
46
+ [CPUMAP_KTHREAD_CNT ] = "cpumap_kthread_cnt" ,
47
+ [DEVMAP_XMIT_CNT ] = "devmap_xmit_cnt" ,
48
+ };
49
+
50
+ #define NUM_MAP 5
51
+ #define NUM_TP 8
52
+
53
+ static int tp_cnt ;
54
+ static int map_cnt ;
33
55
static int verbose = 1 ;
34
56
static bool debug = false;
57
+ struct bpf_map * map_data [NUM_MAP ] = {};
58
+ struct bpf_link * tp_links [NUM_TP ] = {};
59
+ struct bpf_object * obj ;
35
60
36
61
static const struct option long_options [] = {
37
62
{"help" , no_argument , NULL , 'h' },
@@ -41,6 +66,16 @@ static const struct option long_options[] = {
41
66
{0 , 0 , NULL , 0 }
42
67
};
43
68
69
+ static void int_exit (int sig )
70
+ {
71
+ /* Detach tracepoints */
72
+ while (tp_cnt )
73
+ bpf_link__destroy (tp_links [-- tp_cnt ]);
74
+
75
+ bpf_object__close (obj );
76
+ exit (0 );
77
+ }
78
+
44
79
/* C standard specifies two constants, EXIT_SUCCESS(0) and EXIT_FAILURE(1) */
45
80
#define EXIT_FAIL_MEM 5
46
81
@@ -483,23 +518,23 @@ static bool stats_collect(struct stats_record *rec)
483
518
* this can happen by someone running perf-record -e
484
519
*/
485
520
486
- fd = map_data [0 ]. fd ; /* map0: redirect_err_cnt */
521
+ fd = bpf_map__fd ( map_data [REDIRECT_ERR_CNT ]);
487
522
for (i = 0 ; i < REDIR_RES_MAX ; i ++ )
488
523
map_collect_record_u64 (fd , i , & rec -> xdp_redirect [i ]);
489
524
490
- fd = map_data [1 ]. fd ; /* map1: exception_cnt */
525
+ fd = bpf_map__fd ( map_data [EXCEPTION_CNT ]);
491
526
for (i = 0 ; i < XDP_ACTION_MAX ; i ++ ) {
492
527
map_collect_record_u64 (fd , i , & rec -> xdp_exception [i ]);
493
528
}
494
529
495
- fd = map_data [2 ]. fd ; /* map2: cpumap_enqueue_cnt */
530
+ fd = bpf_map__fd ( map_data [CPUMAP_ENQUEUE_CNT ]);
496
531
for (i = 0 ; i < MAX_CPUS ; i ++ )
497
532
map_collect_record (fd , i , & rec -> xdp_cpumap_enqueue [i ]);
498
533
499
- fd = map_data [3 ]. fd ; /* map3: cpumap_kthread_cnt */
534
+ fd = bpf_map__fd ( map_data [CPUMAP_KTHREAD_CNT ]);
500
535
map_collect_record (fd , 0 , & rec -> xdp_cpumap_kthread );
501
536
502
- fd = map_data [4 ]. fd ; /* map4: devmap_xmit_cnt */
537
+ fd = bpf_map__fd ( map_data [DEVMAP_XMIT_CNT ]);
503
538
map_collect_record (fd , 0 , & rec -> xdp_devmap_xmit );
504
539
505
540
return true;
@@ -598,8 +633,8 @@ static void stats_poll(int interval, bool err_only)
598
633
599
634
/* TODO Need more advanced stats on error types */
600
635
if (verbose ) {
601
- printf (" - Stats map0: %s\n" , map_data [0 ]. name );
602
- printf (" - Stats map1: %s\n" , map_data [1 ]. name );
636
+ printf (" - Stats map0: %s\n" , bpf_map__name ( map_data [0 ]) );
637
+ printf (" - Stats map1: %s\n" , bpf_map__name ( map_data [1 ]) );
603
638
printf ("\n" );
604
639
}
605
640
fflush (stdout );
@@ -618,44 +653,51 @@ static void stats_poll(int interval, bool err_only)
618
653
619
654
static void print_bpf_prog_info (void )
620
655
{
621
- int i ;
656
+ struct bpf_program * prog ;
657
+ struct bpf_map * map ;
658
+ int i = 0 ;
622
659
623
660
/* Prog info */
624
- printf ("Loaded BPF prog have %d bpf program(s)\n" , prog_cnt );
625
- for (i = 0 ; i < prog_cnt ; i ++ ) {
626
- printf (" - prog_fd[%d] = fd(%d)\n" , i , prog_fd [i ]);
661
+ printf ("Loaded BPF prog have %d bpf program(s)\n" , tp_cnt );
662
+ bpf_object__for_each_program (prog , obj ) {
663
+ printf (" - prog_fd[%d] = fd(%d)\n" , i , bpf_program__fd (prog ));
664
+ i ++ ;
627
665
}
628
666
667
+ i = 0 ;
629
668
/* Maps info */
630
- printf ("Loaded BPF prog have %d map(s)\n" , map_data_count );
631
- for ( i = 0 ; i < map_data_count ; i ++ ) {
632
- char * name = map_data [ i ]. name ;
633
- int fd = map_data [ i ]. fd ;
669
+ printf ("Loaded BPF prog have %d map(s)\n" , map_cnt );
670
+ bpf_object__for_each_map ( map , obj ) {
671
+ const char * name = bpf_map__name ( map ) ;
672
+ int fd = bpf_map__fd ( map ) ;
634
673
635
674
printf (" - map_data[%d] = fd(%d) name:%s\n" , i , fd , name );
675
+ i ++ ;
636
676
}
637
677
638
678
/* Event info */
639
- printf ("Searching for (max:%d) event file descriptor(s)\n" , prog_cnt );
640
- for (i = 0 ; i < prog_cnt ; i ++ ) {
641
- if (event_fd [i ] != -1 )
642
- printf (" - event_fd[%d] = fd(%d)\n" , i , event_fd [i ]);
679
+ printf ("Searching for (max:%d) event file descriptor(s)\n" , tp_cnt );
680
+ for (i = 0 ; i < tp_cnt ; i ++ ) {
681
+ int fd = bpf_link__fd (tp_links [i ]);
682
+
683
+ if (fd != -1 )
684
+ printf (" - event_fd[%d] = fd(%d)\n" , i , fd );
643
685
}
644
686
}
645
687
646
688
int main (int argc , char * * argv )
647
689
{
648
690
struct rlimit r = {RLIM_INFINITY , RLIM_INFINITY };
691
+ struct bpf_program * prog ;
649
692
int longindex = 0 , opt ;
650
- int ret = EXIT_SUCCESS ;
651
- char bpf_obj_file [256 ];
693
+ int ret = EXIT_FAILURE ;
694
+ enum map_type type ;
695
+ char filename [256 ];
652
696
653
697
/* Default settings: */
654
698
bool errors_only = true;
655
699
int interval = 2 ;
656
700
657
- snprintf (bpf_obj_file , sizeof (bpf_obj_file ), "%s_kern.o" , argv [0 ]);
658
-
659
701
/* Parse commands line args */
660
702
while ((opt = getopt_long (argc , argv , "hDSs:" ,
661
703
long_options , & longindex )) != -1 ) {
@@ -672,40 +714,79 @@ int main(int argc, char **argv)
672
714
case 'h' :
673
715
default :
674
716
usage (argv );
675
- return EXIT_FAILURE ;
717
+ return ret ;
676
718
}
677
719
}
678
720
721
+ snprintf (filename , sizeof (filename ), "%s_kern.o" , argv [0 ]);
679
722
if (setrlimit (RLIMIT_MEMLOCK , & r )) {
680
723
perror ("setrlimit(RLIMIT_MEMLOCK)" );
681
- return EXIT_FAILURE ;
724
+ return ret ;
682
725
}
683
726
684
- if (load_bpf_file (bpf_obj_file )) {
685
- printf ("ERROR - bpf_log_buf: %s" , bpf_log_buf );
686
- return EXIT_FAILURE ;
727
+ /* Remove tracepoint program when program is interrupted or killed */
728
+ signal (SIGINT , int_exit );
729
+ signal (SIGTERM , int_exit );
730
+
731
+ obj = bpf_object__open_file (filename , NULL );
732
+ if (libbpf_get_error (obj )) {
733
+ printf ("ERROR: opening BPF object file failed\n" );
734
+ obj = NULL ;
735
+ goto cleanup ;
736
+ }
737
+
738
+ /* load BPF program */
739
+ if (bpf_object__load (obj )) {
740
+ printf ("ERROR: loading BPF object file failed\n" );
741
+ goto cleanup ;
742
+ }
743
+
744
+ for (type = 0 ; type < NUM_MAP ; type ++ ) {
745
+ map_data [type ] =
746
+ bpf_object__find_map_by_name (obj , map_type_strings [type ]);
747
+
748
+ if (libbpf_get_error (map_data [type ])) {
749
+ printf ("ERROR: finding a map in obj file failed\n" );
750
+ goto cleanup ;
751
+ }
752
+ map_cnt ++ ;
687
753
}
688
- if (!prog_fd [0 ]) {
689
- printf ("ERROR - load_bpf_file: %s\n" , strerror (errno ));
690
- return EXIT_FAILURE ;
754
+
755
+ bpf_object__for_each_program (prog , obj ) {
756
+ tp_links [tp_cnt ] = bpf_program__attach (prog );
757
+ if (libbpf_get_error (tp_links [tp_cnt ])) {
758
+ printf ("ERROR: bpf_program__attach failed\n" );
759
+ tp_links [tp_cnt ] = NULL ;
760
+ goto cleanup ;
761
+ }
762
+ tp_cnt ++ ;
691
763
}
692
764
693
765
if (debug ) {
694
766
print_bpf_prog_info ();
695
767
}
696
768
697
- /* Unload/stop tracepoint event by closing fd 's */
769
+ /* Unload/stop tracepoint event by closing bpf_link 's */
698
770
if (errors_only ) {
699
- /* The prog_fd [i] and event_fd[i] depend on the
700
- * order the functions was defined in _kern.c
771
+ /* The bpf_link [i] depend on the order of
772
+ * the functions was defined in _kern.c
701
773
*/
702
- close (event_fd [2 ]); /* tracepoint/xdp/xdp_redirect */
703
- close (prog_fd [2 ]); /* func: trace_xdp_redirect */
704
- close (event_fd [3 ]); /* tracepoint/xdp/xdp_redirect_map */
705
- close (prog_fd [3 ]); /* func: trace_xdp_redirect_map */
774
+ bpf_link__destroy (tp_links [2 ]); /* tracepoint/xdp/xdp_redirect */
775
+ tp_links [2 ] = NULL ;
776
+
777
+ bpf_link__destroy (tp_links [3 ]); /* tracepoint/xdp/xdp_redirect_map */
778
+ tp_links [3 ] = NULL ;
706
779
}
707
780
708
781
stats_poll (interval , errors_only );
709
782
783
+ ret = EXIT_SUCCESS ;
784
+
785
+ cleanup :
786
+ /* Detach tracepoints */
787
+ while (tp_cnt )
788
+ bpf_link__destroy (tp_links [-- tp_cnt ]);
789
+
790
+ bpf_object__close (obj );
710
791
return ret ;
711
792
}
0 commit comments