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