Home | History | Annotate | Download | only in bpf
      1 /* SPDX-License-Identifier: GPL-2.0
      2  * Copyright (c) 2018 Jesper Dangaard Brouer, Red Hat Inc.
      3  */
      4 static const char *__doc__ =
      5 	"Libbpf test program for loading BPF ELF object files";
      6 
      7 #include <stdlib.h>
      8 #include <stdio.h>
      9 #include <string.h>
     10 #include <stdarg.h>
     11 #include <bpf/libbpf.h>
     12 #include <getopt.h>
     13 
     14 static const struct option long_options[] = {
     15 	{"help",	no_argument,		NULL, 'h' },
     16 	{"debug",	no_argument,		NULL, 'D' },
     17 	{"quiet",	no_argument,		NULL, 'q' },
     18 	{0, 0, NULL,  0 }
     19 };
     20 
     21 static void usage(char *argv[])
     22 {
     23 	int i;
     24 
     25 	printf("\nDOCUMENTATION:\n%s\n\n", __doc__);
     26 	printf(" Usage: %s (options-see-below) BPF_FILE\n", argv[0]);
     27 	printf(" Listing options:\n");
     28 	for (i = 0; long_options[i].name != 0; i++) {
     29 		printf(" --%-12s", long_options[i].name);
     30 		printf(" short-option: -%c",
     31 		       long_options[i].val);
     32 		printf("\n");
     33 	}
     34 	printf("\n");
     35 }
     36 
     37 #define DEFINE_PRINT_FN(name, enabled) \
     38 static int libbpf_##name(const char *fmt, ...)  	\
     39 {							\
     40         va_list args;					\
     41         int ret;					\
     42 							\
     43         va_start(args, fmt);				\
     44 	if (enabled) {					\
     45 		fprintf(stderr, "[" #name "] ");	\
     46 		ret = vfprintf(stderr, fmt, args);	\
     47 	}						\
     48         va_end(args);					\
     49         return ret;					\
     50 }
     51 DEFINE_PRINT_FN(warning, 1)
     52 DEFINE_PRINT_FN(info, 1)
     53 DEFINE_PRINT_FN(debug, 1)
     54 
     55 #define EXIT_FAIL_LIBBPF EXIT_FAILURE
     56 #define EXIT_FAIL_OPTION 2
     57 
     58 int test_walk_progs(struct bpf_object *obj, bool verbose)
     59 {
     60 	struct bpf_program *prog;
     61 	int cnt = 0;
     62 
     63 	bpf_object__for_each_program(prog, obj) {
     64 		cnt++;
     65 		if (verbose)
     66 			printf("Prog (count:%d) section_name: %s\n", cnt,
     67 			       bpf_program__title(prog, false));
     68 	}
     69 	return 0;
     70 }
     71 
     72 int test_walk_maps(struct bpf_object *obj, bool verbose)
     73 {
     74 	struct bpf_map *map;
     75 	int cnt = 0;
     76 
     77 	bpf_map__for_each(map, obj) {
     78 		cnt++;
     79 		if (verbose)
     80 			printf("Map (count:%d) name: %s\n", cnt,
     81 			       bpf_map__name(map));
     82 	}
     83 	return 0;
     84 }
     85 
     86 int test_open_file(char *filename, bool verbose)
     87 {
     88 	struct bpf_object *bpfobj = NULL;
     89 	long err;
     90 
     91 	if (verbose)
     92 		printf("Open BPF ELF-file with libbpf: %s\n", filename);
     93 
     94 	/* Load BPF ELF object file and check for errors */
     95 	bpfobj = bpf_object__open(filename);
     96 	err = libbpf_get_error(bpfobj);
     97 	if (err) {
     98 		char err_buf[128];
     99 		libbpf_strerror(err, err_buf, sizeof(err_buf));
    100 		if (verbose)
    101 			printf("Unable to load eBPF objects in file '%s': %s\n",
    102 			       filename, err_buf);
    103 		return EXIT_FAIL_LIBBPF;
    104 	}
    105 	test_walk_progs(bpfobj, verbose);
    106 	test_walk_maps(bpfobj, verbose);
    107 
    108 	if (verbose)
    109 		printf("Close BPF ELF-file with libbpf: %s\n",
    110 		       bpf_object__name(bpfobj));
    111 	bpf_object__close(bpfobj);
    112 
    113 	return 0;
    114 }
    115 
    116 int main(int argc, char **argv)
    117 {
    118 	char filename[1024] = { 0 };
    119 	bool verbose = 1;
    120 	int longindex = 0;
    121 	int opt;
    122 
    123 	libbpf_set_print(libbpf_warning, libbpf_info, NULL);
    124 
    125 	/* Parse commands line args */
    126 	while ((opt = getopt_long(argc, argv, "hDq",
    127 				  long_options, &longindex)) != -1) {
    128 		switch (opt) {
    129 		case 'D':
    130 			libbpf_set_print(libbpf_warning, libbpf_info,
    131 					 libbpf_debug);
    132 			break;
    133 		case 'q': /* Use in scripting mode */
    134 			verbose = 0;
    135 			break;
    136 		case 'h':
    137 		default:
    138 			usage(argv);
    139 			return EXIT_FAIL_OPTION;
    140 		}
    141 	}
    142 	if (optind >= argc) {
    143 		usage(argv);
    144 		printf("ERROR: Expected BPF_FILE argument after options\n");
    145 		return EXIT_FAIL_OPTION;
    146 	}
    147 	snprintf(filename, sizeof(filename), "%s", argv[optind]);
    148 
    149 	return test_open_file(filename, verbose);
    150 }
    151