@@ -44,6 +44,12 @@ static const char *__doc__ =
4444#define MON_TO_REAL_UPDATE_FREQ \
4545 (1 * NS_PER_SECOND) // Update offset between CLOCK_MONOTONIC and CLOCK_REALTIME once per second
4646
47+ enum PPING_OUTPUT_FORMAT {
48+ PPING_OUTPUT_STANDARD ,
49+ PPING_OUTPUT_JSON ,
50+ PPING_OUTPUT_PPVIZ
51+ };
52+
4753/*
4854 * BPF implementation of pping using libbpf
4955 * Uses TC-BPF for egress and XDP for ingress
@@ -71,8 +77,8 @@ struct pping_config {
7177 struct bpf_tc_opts tc_egress_opts ;
7278 __u64 cleanup_interval ;
7379 char * object_path ;
74- char * ingress_sec ;
75- char * egress_sec ;
80+ char * ingress_prog ;
81+ char * egress_prog ;
7682 char * packet_map ;
7783 char * flow_map ;
7884 char * event_map ;
@@ -81,8 +87,7 @@ struct pping_config {
8187 int ingress_prog_id ;
8288 int egress_prog_id ;
8389 char ifname [IF_NAMESIZE ];
84- bool json_format ;
85- bool ppviz_format ;
90+ enum PPING_OUTPUT_FORMAT output_format ;
8691 bool force ;
8792 bool created_tc_hook ;
8893};
@@ -164,8 +169,6 @@ static int parse_arguments(int argc, char *argv[], struct pping_config *config)
164169
165170 config -> ifindex = 0 ;
166171 config -> force = false;
167- config -> json_format = false;
168- config -> ppviz_format = false;
169172
170173 while ((opt = getopt_long (argc , argv , "hfi:r:c:F:I:" , long_options ,
171174 NULL )) != -1 ) {
@@ -207,20 +210,22 @@ static int parse_arguments(int argc, char *argv[], struct pping_config *config)
207210 cleanup_interval_s * NS_PER_SECOND ;
208211 break ;
209212 case 'F' :
210- if (strcmp (optarg , "json" ) == 0 ) {
211- config -> json_format = true;
213+ if (strcmp (optarg , "standard" ) == 0 ) {
214+ config -> output_format = PPING_OUTPUT_STANDARD ;
215+ } else if (strcmp (optarg , "json" ) == 0 ) {
216+ config -> output_format = PPING_OUTPUT_JSON ;
212217 } else if (strcmp (optarg , "ppviz" ) == 0 ) {
213- config -> ppviz_format = true ;
214- } else if ( strcmp ( optarg , "standard" ) != 0 ) {
218+ config -> output_format = PPING_OUTPUT_PPVIZ ;
219+ } else {
215220 fprintf (stderr , "format must be \"standard\", \"json\" or \"ppviz\"\n" );
216221 return - EINVAL ;
217222 }
218223 break ;
219224 case 'I' :
220225 if (strcmp (optarg , "xdp" ) == 0 ) {
221- config -> ingress_sec = SEC_INGRESS_XDP ;
226+ config -> ingress_prog = "pping_xdp_ingress" ;
222227 } else if (strcmp (optarg , "tc" ) == 0 ) {
223- config -> ingress_sec = SEC_INGRESS_TC ;
228+ config -> ingress_prog = "pping_tc_ingress" ;
224229 } else {
225230 fprintf (stderr , "ingress-hook must be \"xdp\" or \"tc\"\n" );
226231 return - EINVAL ;
@@ -281,17 +286,17 @@ static int init_rodata(struct bpf_object *obj, void *src, size_t size)
281286 * If sucessful, will return the positive program id of the attached.
282287 * On failure, will return a negative error code.
283288 */
284- static int xdp_attach (struct bpf_object * obj , const char * sec , int ifindex ,
285- __u32 xdp_flags )
289+ static int xdp_attach (struct bpf_object * obj , const char * prog_name ,
290+ int ifindex , __u32 xdp_flags )
286291{
287292 struct bpf_program * prog ;
288293 int prog_fd , err ;
289294 __u32 prog_id ;
290295
291- if (sec )
292- prog = bpf_object__find_program_by_title (obj , sec );
296+ if (prog_name )
297+ prog = bpf_object__find_program_by_name (obj , prog_name );
293298 else
294- prog = bpf_program__next ( NULL , obj );
299+ prog = bpf_object__next_program ( obj , NULL );
295300
296301 prog_fd = bpf_program__fd (prog );
297302 if (prog_fd < 0 )
@@ -338,7 +343,7 @@ static int xdp_detach(int ifindex, __u32 xdp_flags, __u32 expected_prog_id)
338343 */
339344static int tc_attach (struct bpf_object * obj , int ifindex ,
340345 enum bpf_tc_attach_point attach_point ,
341- const char * sec , struct bpf_tc_opts * opts ,
346+ const char * prog_name , struct bpf_tc_opts * opts ,
342347 bool * new_hook )
343348{
344349 int err ;
@@ -354,7 +359,7 @@ static int tc_attach(struct bpf_object *obj, int ifindex,
354359 return err ;
355360
356361 prog_fd = bpf_program__fd (
357- bpf_object__find_program_by_title (obj , sec ));
362+ bpf_object__find_program_by_name (obj , prog_name ));
358363 if (prog_fd < 0 ) {
359364 err = prog_fd ;
360365 goto err_after_hook ;
@@ -782,11 +787,12 @@ static int set_programs_to_load(struct bpf_object *obj,
782787 struct pping_config * config )
783788{
784789 struct bpf_program * prog ;
785- char * unload_sec = strcmp (SEC_INGRESS_XDP , config -> ingress_sec ) == 0 ?
786- SEC_INGRESS_TC :
787- SEC_INGRESS_XDP ;
790+ char * unload_prog =
791+ strcmp (config -> ingress_prog , "pping_xdp_ingress" ) != 0 ?
792+ "pping_xdp_ingress" :
793+ "pping_tc_ingress" ;
788794
789- prog = bpf_object__find_program_by_title (obj , unload_sec );
795+ prog = bpf_object__find_program_by_name (obj , unload_prog );
790796 if (libbpf_get_error (prog ))
791797 return libbpf_get_error (prog );
792798
@@ -846,7 +852,7 @@ static int load_attach_bpfprogs(struct bpf_object **obj,
846852 // Attach egress prog
847853 config -> egress_prog_id =
848854 tc_attach (* obj , config -> ifindex , BPF_TC_EGRESS ,
849- config -> egress_sec , & config -> tc_egress_opts ,
855+ config -> egress_prog , & config -> tc_egress_opts ,
850856 & config -> created_tc_hook );
851857 if (config -> egress_prog_id < 0 ) {
852858 fprintf (stderr ,
@@ -857,21 +863,21 @@ static int load_attach_bpfprogs(struct bpf_object **obj,
857863 }
858864
859865 // Attach ingress prog
860- if (strcmp (config -> ingress_sec , SEC_INGRESS_XDP ) == 0 )
866+ if (strcmp (config -> ingress_prog , "pping_xdp_ingress" ) == 0 )
861867 config -> ingress_prog_id =
862- xdp_attach (* obj , config -> ingress_sec , config -> ifindex ,
868+ xdp_attach (* obj , config -> ingress_prog , config -> ifindex ,
863869 config -> xdp_flags );
864870 else
865871 config -> ingress_prog_id =
866872 tc_attach (* obj , config -> ifindex , BPF_TC_INGRESS ,
867- config -> ingress_sec , & config -> tc_ingress_opts ,
868- NULL );
873+ config -> ingress_prog ,
874+ & config -> tc_ingress_opts , NULL );
869875 if (config -> ingress_prog_id < 0 ) {
870876 fprintf (stderr ,
871877 "Failed attaching ingress BPF program on interface %s: %s\n" ,
872878 config -> ifname , get_libbpf_strerror (err ));
873879 err = config -> ingress_prog_id ;
874- if (strcmp (config -> ingress_sec , SEC_INGRESS_XDP ) == 0 )
880+ if (strcmp (config -> ingress_prog , "pping_xdp_ingress" ) == 0 )
875881 print_xdp_error_hints (stderr , err );
876882 goto ingress_err ;
877883 }
@@ -936,10 +942,6 @@ int main(int argc, char *argv[])
936942 int err = 0 , detach_err ;
937943 struct bpf_object * obj = NULL ;
938944 struct perf_buffer * pb = NULL ;
939- struct perf_buffer_opts pb_opts = {
940- .sample_cb = print_event_standard ,
941- .lost_cb = handle_missed_rtt_event ,
942- };
943945
944946 DECLARE_LIBBPF_OPTS (bpf_tc_opts , tc_ingress_opts );
945947 DECLARE_LIBBPF_OPTS (bpf_tc_opts , tc_egress_opts );
@@ -948,18 +950,17 @@ int main(int argc, char *argv[])
948950 .bpf_config = { .rate_limit = 100 * NS_PER_MS },
949951 .cleanup_interval = 1 * NS_PER_SECOND ,
950952 .object_path = "pping_kern.o" ,
951- .ingress_sec = SEC_INGRESS_XDP ,
952- .egress_sec = SEC_EGRESS_TC ,
953+ .ingress_prog = "pping_xdp_ingress" ,
954+ .egress_prog = "pping_tc_egress" ,
953955 .packet_map = "packet_ts" ,
954956 .flow_map = "flow_state" ,
955957 .event_map = "events" ,
956958 .xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST ,
957959 .tc_ingress_opts = tc_ingress_opts ,
958960 .tc_egress_opts = tc_egress_opts ,
961+ .output_format = PPING_OUTPUT_STANDARD ,
959962 };
960963
961- print_event_func = print_event_standard ;
962-
963964 // Detect if running as root
964965 if (geteuid () != 0 ) {
965966 printf ("This program must be run as root.\n" );
@@ -982,12 +983,16 @@ int main(int argc, char *argv[])
982983 return EXIT_FAILURE ;
983984 }
984985
985- if (config .json_format ) {
986- pb_opts .sample_cb = print_event_json ;
986+ switch (config .output_format ) {
987+ case PPING_OUTPUT_STANDARD :
988+ print_event_func = print_event_standard ;
989+ break ;
990+ case PPING_OUTPUT_JSON :
987991 print_event_func = print_event_json ;
988- } else if ( config . ppviz_format ) {
989- pb_opts . sample_cb = print_event_ppviz ;
992+ break ;
993+ case PPING_OUTPUT_PPVIZ :
990994 print_event_func = print_event_ppviz ;
995+ break ;
991996 }
992997
993998 err = load_attach_bpfprogs (& obj , & config );
@@ -1008,7 +1013,8 @@ int main(int argc, char *argv[])
10081013 // Set up perf buffer
10091014 pb = perf_buffer__new (bpf_object__find_map_fd_by_name (obj ,
10101015 config .event_map ),
1011- PERF_BUFFER_PAGES , & pb_opts );
1016+ PERF_BUFFER_PAGES , print_event_func ,
1017+ handle_missed_rtt_event , NULL , NULL );
10121018 err = libbpf_get_error (pb );
10131019 if (err ) {
10141020 fprintf (stderr , "Failed to open perf buffer %s: %s\n" ,
@@ -1031,15 +1037,15 @@ int main(int argc, char *argv[])
10311037 }
10321038
10331039 // Cleanup
1034- if (config .json_format && json_ctx ) {
1040+ if (config .output_format == PPING_OUTPUT_JSON && json_ctx ) {
10351041 jsonw_end_array (json_ctx );
10361042 jsonw_destroy (& json_ctx );
10371043 }
10381044
10391045 perf_buffer__free (pb );
10401046
10411047cleanup_attached_progs :
1042- if (strcmp (config .ingress_sec , SEC_INGRESS_XDP ) == 0 )
1048+ if (strcmp (config .ingress_prog , "pping_xdp_ingress" ) == 0 )
10431049 detach_err = xdp_detach (config .ifindex , config .xdp_flags ,
10441050 config .ingress_prog_id );
10451051 else
0 commit comments