bpftool: Match programs by name
[linux-2.6-microblaze.git] / tools / bpf / bpftool / prog.c
1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2 /* Copyright (C) 2017-2018 Netronome Systems, Inc. */
3
4 #define _GNU_SOURCE
5 #include <errno.h>
6 #include <fcntl.h>
7 #include <stdarg.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <time.h>
12 #include <unistd.h>
13 #include <net/if.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16
17 #include <linux/err.h>
18 #include <linux/sizes.h>
19
20 #include <bpf.h>
21 #include <btf.h>
22 #include <libbpf.h>
23
24 #include "cfg.h"
25 #include "main.h"
26 #include "xlated_dumper.h"
27
28 enum dump_mode {
29         DUMP_JITED,
30         DUMP_XLATED,
31 };
32
33 static const char * const attach_type_strings[] = {
34         [BPF_SK_SKB_STREAM_PARSER] = "stream_parser",
35         [BPF_SK_SKB_STREAM_VERDICT] = "stream_verdict",
36         [BPF_SK_MSG_VERDICT] = "msg_verdict",
37         [BPF_FLOW_DISSECTOR] = "flow_dissector",
38         [__MAX_BPF_ATTACH_TYPE] = NULL,
39 };
40
41 static enum bpf_attach_type parse_attach_type(const char *str)
42 {
43         enum bpf_attach_type type;
44
45         for (type = 0; type < __MAX_BPF_ATTACH_TYPE; type++) {
46                 if (attach_type_strings[type] &&
47                     is_prefix(str, attach_type_strings[type]))
48                         return type;
49         }
50
51         return __MAX_BPF_ATTACH_TYPE;
52 }
53
54 static void print_boot_time(__u64 nsecs, char *buf, unsigned int size)
55 {
56         struct timespec real_time_ts, boot_time_ts;
57         time_t wallclock_secs;
58         struct tm load_tm;
59
60         buf[--size] = '\0';
61
62         if (clock_gettime(CLOCK_REALTIME, &real_time_ts) ||
63             clock_gettime(CLOCK_BOOTTIME, &boot_time_ts)) {
64                 perror("Can't read clocks");
65                 snprintf(buf, size, "%llu", nsecs / 1000000000);
66                 return;
67         }
68
69         wallclock_secs = (real_time_ts.tv_sec - boot_time_ts.tv_sec) +
70                 (real_time_ts.tv_nsec - boot_time_ts.tv_nsec + nsecs) /
71                 1000000000;
72
73
74         if (!localtime_r(&wallclock_secs, &load_tm)) {
75                 snprintf(buf, size, "%llu", nsecs / 1000000000);
76                 return;
77         }
78
79         if (json_output)
80                 strftime(buf, size, "%s", &load_tm);
81         else
82                 strftime(buf, size, "%FT%T%z", &load_tm);
83 }
84
85 static int prog_fd_by_nametag(void *nametag, int **fds, bool tag)
86 {
87         unsigned int id = 0;
88         int fd, nb_fds = 0;
89         void *tmp;
90         int err;
91
92         while (true) {
93                 struct bpf_prog_info info = {};
94                 __u32 len = sizeof(info);
95
96                 err = bpf_prog_get_next_id(id, &id);
97                 if (err) {
98                         if (errno != ENOENT) {
99                                 p_err("%s", strerror(errno));
100                                 goto err_close_fds;
101                         }
102                         return nb_fds;
103                 }
104
105                 fd = bpf_prog_get_fd_by_id(id);
106                 if (fd < 0) {
107                         p_err("can't get prog by id (%u): %s",
108                               id, strerror(errno));
109                         goto err_close_fds;
110                 }
111
112                 err = bpf_obj_get_info_by_fd(fd, &info, &len);
113                 if (err) {
114                         p_err("can't get prog info (%u): %s",
115                               id, strerror(errno));
116                         goto err_close_fd;
117                 }
118
119                 if ((tag && memcmp(nametag, info.tag, BPF_TAG_SIZE)) ||
120                     (!tag && strncmp(nametag, info.name, BPF_OBJ_NAME_LEN))) {
121                         close(fd);
122                         continue;
123                 }
124
125                 if (nb_fds > 0) {
126                         tmp = realloc(*fds, (nb_fds + 1) * sizeof(int));
127                         if (!tmp) {
128                                 p_err("failed to realloc");
129                                 goto err_close_fd;
130                         }
131                         *fds = tmp;
132                 }
133                 (*fds)[nb_fds++] = fd;
134         }
135
136 err_close_fd:
137         close(fd);
138 err_close_fds:
139         while (--nb_fds >= 0)
140                 close((*fds)[nb_fds]);
141         return -1;
142 }
143
144 static int prog_parse_fds(int *argc, char ***argv, int **fds)
145 {
146         if (is_prefix(**argv, "id")) {
147                 unsigned int id;
148                 char *endptr;
149
150                 NEXT_ARGP();
151
152                 id = strtoul(**argv, &endptr, 0);
153                 if (*endptr) {
154                         p_err("can't parse %s as ID", **argv);
155                         return -1;
156                 }
157                 NEXT_ARGP();
158
159                 (*fds)[0] = bpf_prog_get_fd_by_id(id);
160                 if ((*fds)[0] < 0) {
161                         p_err("get by id (%u): %s", id, strerror(errno));
162                         return -1;
163                 }
164                 return 1;
165         } else if (is_prefix(**argv, "tag")) {
166                 unsigned char tag[BPF_TAG_SIZE];
167
168                 NEXT_ARGP();
169
170                 if (sscanf(**argv, BPF_TAG_FMT, tag, tag + 1, tag + 2,
171                            tag + 3, tag + 4, tag + 5, tag + 6, tag + 7)
172                     != BPF_TAG_SIZE) {
173                         p_err("can't parse tag");
174                         return -1;
175                 }
176                 NEXT_ARGP();
177
178                 return prog_fd_by_nametag(tag, fds, true);
179         } else if (is_prefix(**argv, "name")) {
180                 char *name;
181
182                 NEXT_ARGP();
183
184                 name = **argv;
185                 if (strlen(name) > BPF_OBJ_NAME_LEN - 1) {
186                         p_err("can't parse name");
187                         return -1;
188                 }
189                 NEXT_ARGP();
190
191                 return prog_fd_by_nametag(name, fds, false);
192         } else if (is_prefix(**argv, "pinned")) {
193                 char *path;
194
195                 NEXT_ARGP();
196
197                 path = **argv;
198                 NEXT_ARGP();
199
200                 (*fds)[0] = open_obj_pinned_any(path, BPF_OBJ_PROG);
201                 if ((*fds)[0] < 0)
202                         return -1;
203                 return 1;
204         }
205
206         p_err("expected 'id', 'tag', 'name' or 'pinned', got: '%s'?", **argv);
207         return -1;
208 }
209
210 int prog_parse_fd(int *argc, char ***argv)
211 {
212         int *fds = NULL;
213         int nb_fds, fd;
214
215         fds = malloc(sizeof(int));
216         if (!fds) {
217                 p_err("mem alloc failed");
218                 return -1;
219         }
220         nb_fds = prog_parse_fds(argc, argv, &fds);
221         if (nb_fds != 1) {
222                 if (nb_fds > 1) {
223                         p_err("several programs match this handle");
224                         while (nb_fds--)
225                                 close(fds[nb_fds]);
226                 }
227                 fd = -1;
228                 goto exit_free;
229         }
230
231         fd = fds[0];
232 exit_free:
233         free(fds);
234         return fd;
235 }
236
237 static void show_prog_maps(int fd, u32 num_maps)
238 {
239         struct bpf_prog_info info = {};
240         __u32 len = sizeof(info);
241         __u32 map_ids[num_maps];
242         unsigned int i;
243         int err;
244
245         info.nr_map_ids = num_maps;
246         info.map_ids = ptr_to_u64(map_ids);
247
248         err = bpf_obj_get_info_by_fd(fd, &info, &len);
249         if (err || !info.nr_map_ids)
250                 return;
251
252         if (json_output) {
253                 jsonw_name(json_wtr, "map_ids");
254                 jsonw_start_array(json_wtr);
255                 for (i = 0; i < info.nr_map_ids; i++)
256                         jsonw_uint(json_wtr, map_ids[i]);
257                 jsonw_end_array(json_wtr);
258         } else {
259                 printf("  map_ids ");
260                 for (i = 0; i < info.nr_map_ids; i++)
261                         printf("%u%s", map_ids[i],
262                                i == info.nr_map_ids - 1 ? "" : ",");
263         }
264 }
265
266 static void print_prog_header_json(struct bpf_prog_info *info)
267 {
268         jsonw_uint_field(json_wtr, "id", info->id);
269         if (info->type < ARRAY_SIZE(prog_type_name))
270                 jsonw_string_field(json_wtr, "type",
271                                    prog_type_name[info->type]);
272         else
273                 jsonw_uint_field(json_wtr, "type", info->type);
274
275         if (*info->name)
276                 jsonw_string_field(json_wtr, "name", info->name);
277
278         jsonw_name(json_wtr, "tag");
279         jsonw_printf(json_wtr, "\"" BPF_TAG_FMT "\"",
280                      info->tag[0], info->tag[1], info->tag[2], info->tag[3],
281                      info->tag[4], info->tag[5], info->tag[6], info->tag[7]);
282
283         jsonw_bool_field(json_wtr, "gpl_compatible", info->gpl_compatible);
284         if (info->run_time_ns) {
285                 jsonw_uint_field(json_wtr, "run_time_ns", info->run_time_ns);
286                 jsonw_uint_field(json_wtr, "run_cnt", info->run_cnt);
287         }
288 }
289
290 static void print_prog_json(struct bpf_prog_info *info, int fd)
291 {
292         char *memlock;
293
294         jsonw_start_object(json_wtr);
295         print_prog_header_json(info);
296         print_dev_json(info->ifindex, info->netns_dev, info->netns_ino);
297
298         if (info->load_time) {
299                 char buf[32];
300
301                 print_boot_time(info->load_time, buf, sizeof(buf));
302
303                 /* Piggy back on load_time, since 0 uid is a valid one */
304                 jsonw_name(json_wtr, "loaded_at");
305                 jsonw_printf(json_wtr, "%s", buf);
306                 jsonw_uint_field(json_wtr, "uid", info->created_by_uid);
307         }
308
309         jsonw_uint_field(json_wtr, "bytes_xlated", info->xlated_prog_len);
310
311         if (info->jited_prog_len) {
312                 jsonw_bool_field(json_wtr, "jited", true);
313                 jsonw_uint_field(json_wtr, "bytes_jited", info->jited_prog_len);
314         } else {
315                 jsonw_bool_field(json_wtr, "jited", false);
316         }
317
318         memlock = get_fdinfo(fd, "memlock");
319         if (memlock)
320                 jsonw_int_field(json_wtr, "bytes_memlock", atoi(memlock));
321         free(memlock);
322
323         if (info->nr_map_ids)
324                 show_prog_maps(fd, info->nr_map_ids);
325
326         if (info->btf_id)
327                 jsonw_int_field(json_wtr, "btf_id", info->btf_id);
328
329         if (!hash_empty(prog_table.table)) {
330                 struct pinned_obj *obj;
331
332                 jsonw_name(json_wtr, "pinned");
333                 jsonw_start_array(json_wtr);
334                 hash_for_each_possible(prog_table.table, obj, hash, info->id) {
335                         if (obj->id == info->id)
336                                 jsonw_string(json_wtr, obj->path);
337                 }
338                 jsonw_end_array(json_wtr);
339         }
340
341         jsonw_end_object(json_wtr);
342 }
343
344 static void print_prog_header_plain(struct bpf_prog_info *info)
345 {
346         printf("%u: ", info->id);
347         if (info->type < ARRAY_SIZE(prog_type_name))
348                 printf("%s  ", prog_type_name[info->type]);
349         else
350                 printf("type %u  ", info->type);
351
352         if (*info->name)
353                 printf("name %s  ", info->name);
354
355         printf("tag ");
356         fprint_hex(stdout, info->tag, BPF_TAG_SIZE, "");
357         print_dev_plain(info->ifindex, info->netns_dev, info->netns_ino);
358         printf("%s", info->gpl_compatible ? "  gpl" : "");
359         if (info->run_time_ns)
360                 printf(" run_time_ns %lld run_cnt %lld",
361                        info->run_time_ns, info->run_cnt);
362         printf("\n");
363 }
364
365 static void print_prog_plain(struct bpf_prog_info *info, int fd)
366 {
367         char *memlock;
368
369         print_prog_header_plain(info);
370
371         if (info->load_time) {
372                 char buf[32];
373
374                 print_boot_time(info->load_time, buf, sizeof(buf));
375
376                 /* Piggy back on load_time, since 0 uid is a valid one */
377                 printf("\tloaded_at %s  uid %u\n", buf, info->created_by_uid);
378         }
379
380         printf("\txlated %uB", info->xlated_prog_len);
381
382         if (info->jited_prog_len)
383                 printf("  jited %uB", info->jited_prog_len);
384         else
385                 printf("  not jited");
386
387         memlock = get_fdinfo(fd, "memlock");
388         if (memlock)
389                 printf("  memlock %sB", memlock);
390         free(memlock);
391
392         if (info->nr_map_ids)
393                 show_prog_maps(fd, info->nr_map_ids);
394
395         if (!hash_empty(prog_table.table)) {
396                 struct pinned_obj *obj;
397
398                 hash_for_each_possible(prog_table.table, obj, hash, info->id) {
399                         if (obj->id == info->id)
400                                 printf("\n\tpinned %s", obj->path);
401                 }
402         }
403
404         if (info->btf_id)
405                 printf("\n\tbtf_id %d", info->btf_id);
406
407         printf("\n");
408 }
409
410 static int show_prog(int fd)
411 {
412         struct bpf_prog_info info = {};
413         __u32 len = sizeof(info);
414         int err;
415
416         err = bpf_obj_get_info_by_fd(fd, &info, &len);
417         if (err) {
418                 p_err("can't get prog info: %s", strerror(errno));
419                 return -1;
420         }
421
422         if (json_output)
423                 print_prog_json(&info, fd);
424         else
425                 print_prog_plain(&info, fd);
426
427         return 0;
428 }
429
430 static int do_show_subset(int argc, char **argv)
431 {
432         int *fds = NULL;
433         int nb_fds, i;
434         int err = -1;
435
436         fds = malloc(sizeof(int));
437         if (!fds) {
438                 p_err("mem alloc failed");
439                 return -1;
440         }
441         nb_fds = prog_parse_fds(&argc, &argv, &fds);
442         if (nb_fds < 1)
443                 goto exit_free;
444
445         if (json_output && nb_fds > 1)
446                 jsonw_start_array(json_wtr);    /* root array */
447         for (i = 0; i < nb_fds; i++) {
448                 err = show_prog(fds[i]);
449                 if (err) {
450                         for (; i < nb_fds; i++)
451                                 close(fds[i]);
452                         break;
453                 }
454                 close(fds[i]);
455         }
456         if (json_output && nb_fds > 1)
457                 jsonw_end_array(json_wtr);      /* root array */
458
459 exit_free:
460         free(fds);
461         return err;
462 }
463
464 static int do_show(int argc, char **argv)
465 {
466         __u32 id = 0;
467         int err;
468         int fd;
469
470         if (show_pinned)
471                 build_pinned_obj_table(&prog_table, BPF_OBJ_PROG);
472
473         if (argc == 2)
474                 return do_show_subset(argc, argv);
475
476         if (argc)
477                 return BAD_ARG();
478
479         if (json_output)
480                 jsonw_start_array(json_wtr);
481         while (true) {
482                 err = bpf_prog_get_next_id(id, &id);
483                 if (err) {
484                         if (errno == ENOENT) {
485                                 err = 0;
486                                 break;
487                         }
488                         p_err("can't get next program: %s%s", strerror(errno),
489                               errno == EINVAL ? " -- kernel too old?" : "");
490                         err = -1;
491                         break;
492                 }
493
494                 fd = bpf_prog_get_fd_by_id(id);
495                 if (fd < 0) {
496                         if (errno == ENOENT)
497                                 continue;
498                         p_err("can't get prog by id (%u): %s",
499                               id, strerror(errno));
500                         err = -1;
501                         break;
502                 }
503
504                 err = show_prog(fd);
505                 close(fd);
506                 if (err)
507                         break;
508         }
509
510         if (json_output)
511                 jsonw_end_array(json_wtr);
512
513         return err;
514 }
515
516 static int
517 prog_dump(struct bpf_prog_info *info, enum dump_mode mode,
518           char *filepath, bool opcodes, bool visual, bool linum)
519 {
520         struct bpf_prog_linfo *prog_linfo = NULL;
521         const char *disasm_opt = NULL;
522         struct dump_data dd = {};
523         void *func_info = NULL;
524         struct btf *btf = NULL;
525         char func_sig[1024];
526         unsigned char *buf;
527         __u32 member_len;
528         ssize_t n;
529         int fd;
530
531         if (mode == DUMP_JITED) {
532                 if (info->jited_prog_len == 0) {
533                         p_info("no instructions returned");
534                         return -1;
535                 }
536                 buf = (unsigned char *)(info->jited_prog_insns);
537                 member_len = info->jited_prog_len;
538         } else {        /* DUMP_XLATED */
539                 if (info->xlated_prog_len == 0) {
540                         p_err("error retrieving insn dump: kernel.kptr_restrict set?");
541                         return -1;
542                 }
543                 buf = (unsigned char *)info->xlated_prog_insns;
544                 member_len = info->xlated_prog_len;
545         }
546
547         if (info->btf_id && btf__get_from_id(info->btf_id, &btf)) {
548                 p_err("failed to get btf");
549                 return -1;
550         }
551
552         func_info = (void *)info->func_info;
553
554         if (info->nr_line_info) {
555                 prog_linfo = bpf_prog_linfo__new(info);
556                 if (!prog_linfo)
557                         p_info("error in processing bpf_line_info.  continue without it.");
558         }
559
560         if (filepath) {
561                 fd = open(filepath, O_WRONLY | O_CREAT | O_TRUNC, 0600);
562                 if (fd < 0) {
563                         p_err("can't open file %s: %s", filepath,
564                               strerror(errno));
565                         return -1;
566                 }
567
568                 n = write(fd, buf, member_len);
569                 close(fd);
570                 if (n != member_len) {
571                         p_err("error writing output file: %s",
572                               n < 0 ? strerror(errno) : "short write");
573                         return -1;
574                 }
575
576                 if (json_output)
577                         jsonw_null(json_wtr);
578         } else if (mode == DUMP_JITED) {
579                 const char *name = NULL;
580
581                 if (info->ifindex) {
582                         name = ifindex_to_bfd_params(info->ifindex,
583                                                      info->netns_dev,
584                                                      info->netns_ino,
585                                                      &disasm_opt);
586                         if (!name)
587                                 return -1;
588                 }
589
590                 if (info->nr_jited_func_lens && info->jited_func_lens) {
591                         struct kernel_sym *sym = NULL;
592                         struct bpf_func_info *record;
593                         char sym_name[SYM_MAX_NAME];
594                         unsigned char *img = buf;
595                         __u64 *ksyms = NULL;
596                         __u32 *lens;
597                         __u32 i;
598                         if (info->nr_jited_ksyms) {
599                                 kernel_syms_load(&dd);
600                                 ksyms = (__u64 *) info->jited_ksyms;
601                         }
602
603                         if (json_output)
604                                 jsonw_start_array(json_wtr);
605
606                         lens = (__u32 *) info->jited_func_lens;
607                         for (i = 0; i < info->nr_jited_func_lens; i++) {
608                                 if (ksyms) {
609                                         sym = kernel_syms_search(&dd, ksyms[i]);
610                                         if (sym)
611                                                 sprintf(sym_name, "%s", sym->name);
612                                         else
613                                                 sprintf(sym_name, "0x%016llx", ksyms[i]);
614                                 } else {
615                                         strcpy(sym_name, "unknown");
616                                 }
617
618                                 if (func_info) {
619                                         record = func_info + i * info->func_info_rec_size;
620                                         btf_dumper_type_only(btf, record->type_id,
621                                                              func_sig,
622                                                              sizeof(func_sig));
623                                 }
624
625                                 if (json_output) {
626                                         jsonw_start_object(json_wtr);
627                                         if (func_info && func_sig[0] != '\0') {
628                                                 jsonw_name(json_wtr, "proto");
629                                                 jsonw_string(json_wtr, func_sig);
630                                         }
631                                         jsonw_name(json_wtr, "name");
632                                         jsonw_string(json_wtr, sym_name);
633                                         jsonw_name(json_wtr, "insns");
634                                 } else {
635                                         if (func_info && func_sig[0] != '\0')
636                                                 printf("%s:\n", func_sig);
637                                         printf("%s:\n", sym_name);
638                                 }
639
640                                 disasm_print_insn(img, lens[i], opcodes,
641                                                   name, disasm_opt, btf,
642                                                   prog_linfo, ksyms[i], i,
643                                                   linum);
644
645                                 img += lens[i];
646
647                                 if (json_output)
648                                         jsonw_end_object(json_wtr);
649                                 else
650                                         printf("\n");
651                         }
652
653                         if (json_output)
654                                 jsonw_end_array(json_wtr);
655                 } else {
656                         disasm_print_insn(buf, member_len, opcodes, name,
657                                           disasm_opt, btf, NULL, 0, 0, false);
658                 }
659         } else if (visual) {
660                 if (json_output)
661                         jsonw_null(json_wtr);
662                 else
663                         dump_xlated_cfg(buf, member_len);
664         } else {
665                 kernel_syms_load(&dd);
666                 dd.nr_jited_ksyms = info->nr_jited_ksyms;
667                 dd.jited_ksyms = (__u64 *) info->jited_ksyms;
668                 dd.btf = btf;
669                 dd.func_info = func_info;
670                 dd.finfo_rec_size = info->func_info_rec_size;
671                 dd.prog_linfo = prog_linfo;
672
673                 if (json_output)
674                         dump_xlated_json(&dd, buf, member_len, opcodes,
675                                          linum);
676                 else
677                         dump_xlated_plain(&dd, buf, member_len, opcodes,
678                                           linum);
679                 kernel_syms_destroy(&dd);
680         }
681
682         return 0;
683 }
684
685 static int do_dump(int argc, char **argv)
686 {
687         struct bpf_prog_info_linear *info_linear;
688         char *filepath = NULL;
689         bool opcodes = false;
690         bool visual = false;
691         enum dump_mode mode;
692         bool linum = false;
693         int *fds = NULL;
694         int nb_fds, i = 0;
695         int err = -1;
696         __u64 arrays;
697
698         if (is_prefix(*argv, "jited")) {
699                 if (disasm_init())
700                         return -1;
701                 mode = DUMP_JITED;
702         } else if (is_prefix(*argv, "xlated")) {
703                 mode = DUMP_XLATED;
704         } else {
705                 p_err("expected 'xlated' or 'jited', got: %s", *argv);
706                 return -1;
707         }
708         NEXT_ARG();
709
710         if (argc < 2)
711                 usage();
712
713         fds = malloc(sizeof(int));
714         if (!fds) {
715                 p_err("mem alloc failed");
716                 return -1;
717         }
718         nb_fds = prog_parse_fds(&argc, &argv, &fds);
719         if (nb_fds < 1)
720                 goto exit_free;
721
722         if (is_prefix(*argv, "file")) {
723                 NEXT_ARG();
724                 if (!argc) {
725                         p_err("expected file path");
726                         goto exit_close;
727                 }
728                 if (nb_fds > 1) {
729                         p_err("several programs matched");
730                         goto exit_close;
731                 }
732
733                 filepath = *argv;
734                 NEXT_ARG();
735         } else if (is_prefix(*argv, "opcodes")) {
736                 opcodes = true;
737                 NEXT_ARG();
738         } else if (is_prefix(*argv, "visual")) {
739                 if (nb_fds > 1) {
740                         p_err("several programs matched");
741                         goto exit_close;
742                 }
743
744                 visual = true;
745                 NEXT_ARG();
746         } else if (is_prefix(*argv, "linum")) {
747                 linum = true;
748                 NEXT_ARG();
749         }
750
751         if (argc) {
752                 usage();
753                 goto exit_close;
754         }
755
756         if (mode == DUMP_JITED)
757                 arrays = 1UL << BPF_PROG_INFO_JITED_INSNS;
758         else
759                 arrays = 1UL << BPF_PROG_INFO_XLATED_INSNS;
760
761         arrays |= 1UL << BPF_PROG_INFO_JITED_KSYMS;
762         arrays |= 1UL << BPF_PROG_INFO_JITED_FUNC_LENS;
763         arrays |= 1UL << BPF_PROG_INFO_FUNC_INFO;
764         arrays |= 1UL << BPF_PROG_INFO_LINE_INFO;
765         arrays |= 1UL << BPF_PROG_INFO_JITED_LINE_INFO;
766
767         if (json_output && nb_fds > 1)
768                 jsonw_start_array(json_wtr);    /* root array */
769         for (i = 0; i < nb_fds; i++) {
770                 info_linear = bpf_program__get_prog_info_linear(fds[i], arrays);
771                 if (IS_ERR_OR_NULL(info_linear)) {
772                         p_err("can't get prog info: %s", strerror(errno));
773                         break;
774                 }
775
776                 if (json_output && nb_fds > 1) {
777                         jsonw_start_object(json_wtr);   /* prog object */
778                         print_prog_header_json(&info_linear->info);
779                         jsonw_name(json_wtr, "insns");
780                 } else if (nb_fds > 1) {
781                         print_prog_header_plain(&info_linear->info);
782                 }
783
784                 err = prog_dump(&info_linear->info, mode, filepath, opcodes,
785                                 visual, linum);
786
787                 if (json_output && nb_fds > 1)
788                         jsonw_end_object(json_wtr);     /* prog object */
789                 else if (i != nb_fds - 1 && nb_fds > 1)
790                         printf("\n");
791
792                 free(info_linear);
793                 if (err)
794                         break;
795                 close(fds[i]);
796         }
797         if (json_output && nb_fds > 1)
798                 jsonw_end_array(json_wtr);      /* root array */
799
800 exit_close:
801         for (; i < nb_fds; i++)
802                 close(fds[i]);
803 exit_free:
804         free(fds);
805         return err;
806 }
807
808 static int do_pin(int argc, char **argv)
809 {
810         int err;
811
812         err = do_pin_any(argc, argv, bpf_prog_get_fd_by_id);
813         if (!err && json_output)
814                 jsonw_null(json_wtr);
815         return err;
816 }
817
818 struct map_replace {
819         int idx;
820         int fd;
821         char *name;
822 };
823
824 static int map_replace_compar(const void *p1, const void *p2)
825 {
826         const struct map_replace *a = p1, *b = p2;
827
828         return a->idx - b->idx;
829 }
830
831 static int parse_attach_detach_args(int argc, char **argv, int *progfd,
832                                     enum bpf_attach_type *attach_type,
833                                     int *mapfd)
834 {
835         if (!REQ_ARGS(3))
836                 return -EINVAL;
837
838         *progfd = prog_parse_fd(&argc, &argv);
839         if (*progfd < 0)
840                 return *progfd;
841
842         *attach_type = parse_attach_type(*argv);
843         if (*attach_type == __MAX_BPF_ATTACH_TYPE) {
844                 p_err("invalid attach/detach type");
845                 return -EINVAL;
846         }
847
848         if (*attach_type == BPF_FLOW_DISSECTOR) {
849                 *mapfd = -1;
850                 return 0;
851         }
852
853         NEXT_ARG();
854         if (!REQ_ARGS(2))
855                 return -EINVAL;
856
857         *mapfd = map_parse_fd(&argc, &argv);
858         if (*mapfd < 0)
859                 return *mapfd;
860
861         return 0;
862 }
863
864 static int do_attach(int argc, char **argv)
865 {
866         enum bpf_attach_type attach_type;
867         int err, progfd;
868         int mapfd;
869
870         err = parse_attach_detach_args(argc, argv,
871                                        &progfd, &attach_type, &mapfd);
872         if (err)
873                 return err;
874
875         err = bpf_prog_attach(progfd, mapfd, attach_type, 0);
876         if (err) {
877                 p_err("failed prog attach to map");
878                 return -EINVAL;
879         }
880
881         if (json_output)
882                 jsonw_null(json_wtr);
883         return 0;
884 }
885
886 static int do_detach(int argc, char **argv)
887 {
888         enum bpf_attach_type attach_type;
889         int err, progfd;
890         int mapfd;
891
892         err = parse_attach_detach_args(argc, argv,
893                                        &progfd, &attach_type, &mapfd);
894         if (err)
895                 return err;
896
897         err = bpf_prog_detach2(progfd, mapfd, attach_type);
898         if (err) {
899                 p_err("failed prog detach from map");
900                 return -EINVAL;
901         }
902
903         if (json_output)
904                 jsonw_null(json_wtr);
905         return 0;
906 }
907
908 static int check_single_stdin(char *file_data_in, char *file_ctx_in)
909 {
910         if (file_data_in && file_ctx_in &&
911             !strcmp(file_data_in, "-") && !strcmp(file_ctx_in, "-")) {
912                 p_err("cannot use standard input for both data_in and ctx_in");
913                 return -1;
914         }
915
916         return 0;
917 }
918
919 static int get_run_data(const char *fname, void **data_ptr, unsigned int *size)
920 {
921         size_t block_size = 256;
922         size_t buf_size = block_size;
923         size_t nb_read = 0;
924         void *tmp;
925         FILE *f;
926
927         if (!fname) {
928                 *data_ptr = NULL;
929                 *size = 0;
930                 return 0;
931         }
932
933         if (!strcmp(fname, "-"))
934                 f = stdin;
935         else
936                 f = fopen(fname, "r");
937         if (!f) {
938                 p_err("failed to open %s: %s", fname, strerror(errno));
939                 return -1;
940         }
941
942         *data_ptr = malloc(block_size);
943         if (!*data_ptr) {
944                 p_err("failed to allocate memory for data_in/ctx_in: %s",
945                       strerror(errno));
946                 goto err_fclose;
947         }
948
949         while ((nb_read += fread(*data_ptr + nb_read, 1, block_size, f))) {
950                 if (feof(f))
951                         break;
952                 if (ferror(f)) {
953                         p_err("failed to read data_in/ctx_in from %s: %s",
954                               fname, strerror(errno));
955                         goto err_free;
956                 }
957                 if (nb_read > buf_size - block_size) {
958                         if (buf_size == UINT32_MAX) {
959                                 p_err("data_in/ctx_in is too long (max: %d)",
960                                       UINT32_MAX);
961                                 goto err_free;
962                         }
963                         /* No space for fread()-ing next chunk; realloc() */
964                         buf_size *= 2;
965                         tmp = realloc(*data_ptr, buf_size);
966                         if (!tmp) {
967                                 p_err("failed to reallocate data_in/ctx_in: %s",
968                                       strerror(errno));
969                                 goto err_free;
970                         }
971                         *data_ptr = tmp;
972                 }
973         }
974         if (f != stdin)
975                 fclose(f);
976
977         *size = nb_read;
978         return 0;
979
980 err_free:
981         free(*data_ptr);
982         *data_ptr = NULL;
983 err_fclose:
984         if (f != stdin)
985                 fclose(f);
986         return -1;
987 }
988
989 static void hex_print(void *data, unsigned int size, FILE *f)
990 {
991         size_t i, j;
992         char c;
993
994         for (i = 0; i < size; i += 16) {
995                 /* Row offset */
996                 fprintf(f, "%07zx\t", i);
997
998                 /* Hexadecimal values */
999                 for (j = i; j < i + 16 && j < size; j++)
1000                         fprintf(f, "%02x%s", *(uint8_t *)(data + j),
1001                                 j % 2 ? " " : "");
1002                 for (; j < i + 16; j++)
1003                         fprintf(f, "  %s", j % 2 ? " " : "");
1004
1005                 /* ASCII values (if relevant), '.' otherwise */
1006                 fprintf(f, "| ");
1007                 for (j = i; j < i + 16 && j < size; j++) {
1008                         c = *(char *)(data + j);
1009                         if (c < ' ' || c > '~')
1010                                 c = '.';
1011                         fprintf(f, "%c%s", c, j == i + 7 ? " " : "");
1012                 }
1013
1014                 fprintf(f, "\n");
1015         }
1016 }
1017
1018 static int
1019 print_run_output(void *data, unsigned int size, const char *fname,
1020                  const char *json_key)
1021 {
1022         size_t nb_written;
1023         FILE *f;
1024
1025         if (!fname)
1026                 return 0;
1027
1028         if (!strcmp(fname, "-")) {
1029                 f = stdout;
1030                 if (json_output) {
1031                         jsonw_name(json_wtr, json_key);
1032                         print_data_json(data, size);
1033                 } else {
1034                         hex_print(data, size, f);
1035                 }
1036                 return 0;
1037         }
1038
1039         f = fopen(fname, "w");
1040         if (!f) {
1041                 p_err("failed to open %s: %s", fname, strerror(errno));
1042                 return -1;
1043         }
1044
1045         nb_written = fwrite(data, 1, size, f);
1046         fclose(f);
1047         if (nb_written != size) {
1048                 p_err("failed to write output data/ctx: %s", strerror(errno));
1049                 return -1;
1050         }
1051
1052         return 0;
1053 }
1054
1055 static int alloc_run_data(void **data_ptr, unsigned int size_out)
1056 {
1057         *data_ptr = calloc(size_out, 1);
1058         if (!*data_ptr) {
1059                 p_err("failed to allocate memory for output data/ctx: %s",
1060                       strerror(errno));
1061                 return -1;
1062         }
1063
1064         return 0;
1065 }
1066
1067 static int do_run(int argc, char **argv)
1068 {
1069         char *data_fname_in = NULL, *data_fname_out = NULL;
1070         char *ctx_fname_in = NULL, *ctx_fname_out = NULL;
1071         struct bpf_prog_test_run_attr test_attr = {0};
1072         const unsigned int default_size = SZ_32K;
1073         void *data_in = NULL, *data_out = NULL;
1074         void *ctx_in = NULL, *ctx_out = NULL;
1075         unsigned int repeat = 1;
1076         int fd, err;
1077
1078         if (!REQ_ARGS(4))
1079                 return -1;
1080
1081         fd = prog_parse_fd(&argc, &argv);
1082         if (fd < 0)
1083                 return -1;
1084
1085         while (argc) {
1086                 if (detect_common_prefix(*argv, "data_in", "data_out",
1087                                          "data_size_out", NULL))
1088                         return -1;
1089                 if (detect_common_prefix(*argv, "ctx_in", "ctx_out",
1090                                          "ctx_size_out", NULL))
1091                         return -1;
1092
1093                 if (is_prefix(*argv, "data_in")) {
1094                         NEXT_ARG();
1095                         if (!REQ_ARGS(1))
1096                                 return -1;
1097
1098                         data_fname_in = GET_ARG();
1099                         if (check_single_stdin(data_fname_in, ctx_fname_in))
1100                                 return -1;
1101                 } else if (is_prefix(*argv, "data_out")) {
1102                         NEXT_ARG();
1103                         if (!REQ_ARGS(1))
1104                                 return -1;
1105
1106                         data_fname_out = GET_ARG();
1107                 } else if (is_prefix(*argv, "data_size_out")) {
1108                         char *endptr;
1109
1110                         NEXT_ARG();
1111                         if (!REQ_ARGS(1))
1112                                 return -1;
1113
1114                         test_attr.data_size_out = strtoul(*argv, &endptr, 0);
1115                         if (*endptr) {
1116                                 p_err("can't parse %s as output data size",
1117                                       *argv);
1118                                 return -1;
1119                         }
1120                         NEXT_ARG();
1121                 } else if (is_prefix(*argv, "ctx_in")) {
1122                         NEXT_ARG();
1123                         if (!REQ_ARGS(1))
1124                                 return -1;
1125
1126                         ctx_fname_in = GET_ARG();
1127                         if (check_single_stdin(data_fname_in, ctx_fname_in))
1128                                 return -1;
1129                 } else if (is_prefix(*argv, "ctx_out")) {
1130                         NEXT_ARG();
1131                         if (!REQ_ARGS(1))
1132                                 return -1;
1133
1134                         ctx_fname_out = GET_ARG();
1135                 } else if (is_prefix(*argv, "ctx_size_out")) {
1136                         char *endptr;
1137
1138                         NEXT_ARG();
1139                         if (!REQ_ARGS(1))
1140                                 return -1;
1141
1142                         test_attr.ctx_size_out = strtoul(*argv, &endptr, 0);
1143                         if (*endptr) {
1144                                 p_err("can't parse %s as output context size",
1145                                       *argv);
1146                                 return -1;
1147                         }
1148                         NEXT_ARG();
1149                 } else if (is_prefix(*argv, "repeat")) {
1150                         char *endptr;
1151
1152                         NEXT_ARG();
1153                         if (!REQ_ARGS(1))
1154                                 return -1;
1155
1156                         repeat = strtoul(*argv, &endptr, 0);
1157                         if (*endptr) {
1158                                 p_err("can't parse %s as repeat number",
1159                                       *argv);
1160                                 return -1;
1161                         }
1162                         NEXT_ARG();
1163                 } else {
1164                         p_err("expected no more arguments, 'data_in', 'data_out', 'data_size_out', 'ctx_in', 'ctx_out', 'ctx_size_out' or 'repeat', got: '%s'?",
1165                               *argv);
1166                         return -1;
1167                 }
1168         }
1169
1170         err = get_run_data(data_fname_in, &data_in, &test_attr.data_size_in);
1171         if (err)
1172                 return -1;
1173
1174         if (data_in) {
1175                 if (!test_attr.data_size_out)
1176                         test_attr.data_size_out = default_size;
1177                 err = alloc_run_data(&data_out, test_attr.data_size_out);
1178                 if (err)
1179                         goto free_data_in;
1180         }
1181
1182         err = get_run_data(ctx_fname_in, &ctx_in, &test_attr.ctx_size_in);
1183         if (err)
1184                 goto free_data_out;
1185
1186         if (ctx_in) {
1187                 if (!test_attr.ctx_size_out)
1188                         test_attr.ctx_size_out = default_size;
1189                 err = alloc_run_data(&ctx_out, test_attr.ctx_size_out);
1190                 if (err)
1191                         goto free_ctx_in;
1192         }
1193
1194         test_attr.prog_fd       = fd;
1195         test_attr.repeat        = repeat;
1196         test_attr.data_in       = data_in;
1197         test_attr.data_out      = data_out;
1198         test_attr.ctx_in        = ctx_in;
1199         test_attr.ctx_out       = ctx_out;
1200
1201         err = bpf_prog_test_run_xattr(&test_attr);
1202         if (err) {
1203                 p_err("failed to run program: %s", strerror(errno));
1204                 goto free_ctx_out;
1205         }
1206
1207         err = 0;
1208
1209         if (json_output)
1210                 jsonw_start_object(json_wtr);   /* root */
1211
1212         /* Do not exit on errors occurring when printing output data/context,
1213          * we still want to print return value and duration for program run.
1214          */
1215         if (test_attr.data_size_out)
1216                 err += print_run_output(test_attr.data_out,
1217                                         test_attr.data_size_out,
1218                                         data_fname_out, "data_out");
1219         if (test_attr.ctx_size_out)
1220                 err += print_run_output(test_attr.ctx_out,
1221                                         test_attr.ctx_size_out,
1222                                         ctx_fname_out, "ctx_out");
1223
1224         if (json_output) {
1225                 jsonw_uint_field(json_wtr, "retval", test_attr.retval);
1226                 jsonw_uint_field(json_wtr, "duration", test_attr.duration);
1227                 jsonw_end_object(json_wtr);     /* root */
1228         } else {
1229                 fprintf(stdout, "Return value: %u, duration%s: %uns\n",
1230                         test_attr.retval,
1231                         repeat > 1 ? " (average)" : "", test_attr.duration);
1232         }
1233
1234 free_ctx_out:
1235         free(ctx_out);
1236 free_ctx_in:
1237         free(ctx_in);
1238 free_data_out:
1239         free(data_out);
1240 free_data_in:
1241         free(data_in);
1242
1243         return err;
1244 }
1245
1246 static int load_with_options(int argc, char **argv, bool first_prog_only)
1247 {
1248         enum bpf_prog_type common_prog_type = BPF_PROG_TYPE_UNSPEC;
1249         DECLARE_LIBBPF_OPTS(bpf_object_open_opts, open_opts,
1250                 .relaxed_maps = relaxed_maps,
1251         );
1252         struct bpf_object_load_attr load_attr = { 0 };
1253         enum bpf_attach_type expected_attach_type;
1254         struct map_replace *map_replace = NULL;
1255         struct bpf_program *prog = NULL, *pos;
1256         unsigned int old_map_fds = 0;
1257         const char *pinmaps = NULL;
1258         struct bpf_object *obj;
1259         struct bpf_map *map;
1260         const char *pinfile;
1261         unsigned int i, j;
1262         __u32 ifindex = 0;
1263         const char *file;
1264         int idx, err;
1265
1266
1267         if (!REQ_ARGS(2))
1268                 return -1;
1269         file = GET_ARG();
1270         pinfile = GET_ARG();
1271
1272         while (argc) {
1273                 if (is_prefix(*argv, "type")) {
1274                         char *type;
1275
1276                         NEXT_ARG();
1277
1278                         if (common_prog_type != BPF_PROG_TYPE_UNSPEC) {
1279                                 p_err("program type already specified");
1280                                 goto err_free_reuse_maps;
1281                         }
1282                         if (!REQ_ARGS(1))
1283                                 goto err_free_reuse_maps;
1284
1285                         /* Put a '/' at the end of type to appease libbpf */
1286                         type = malloc(strlen(*argv) + 2);
1287                         if (!type) {
1288                                 p_err("mem alloc failed");
1289                                 goto err_free_reuse_maps;
1290                         }
1291                         *type = 0;
1292                         strcat(type, *argv);
1293                         strcat(type, "/");
1294
1295                         err = libbpf_prog_type_by_name(type, &common_prog_type,
1296                                                        &expected_attach_type);
1297                         free(type);
1298                         if (err < 0)
1299                                 goto err_free_reuse_maps;
1300
1301                         NEXT_ARG();
1302                 } else if (is_prefix(*argv, "map")) {
1303                         void *new_map_replace;
1304                         char *endptr, *name;
1305                         int fd;
1306
1307                         NEXT_ARG();
1308
1309                         if (!REQ_ARGS(4))
1310                                 goto err_free_reuse_maps;
1311
1312                         if (is_prefix(*argv, "idx")) {
1313                                 NEXT_ARG();
1314
1315                                 idx = strtoul(*argv, &endptr, 0);
1316                                 if (*endptr) {
1317                                         p_err("can't parse %s as IDX", *argv);
1318                                         goto err_free_reuse_maps;
1319                                 }
1320                                 name = NULL;
1321                         } else if (is_prefix(*argv, "name")) {
1322                                 NEXT_ARG();
1323
1324                                 name = *argv;
1325                                 idx = -1;
1326                         } else {
1327                                 p_err("expected 'idx' or 'name', got: '%s'?",
1328                                       *argv);
1329                                 goto err_free_reuse_maps;
1330                         }
1331                         NEXT_ARG();
1332
1333                         fd = map_parse_fd(&argc, &argv);
1334                         if (fd < 0)
1335                                 goto err_free_reuse_maps;
1336
1337                         new_map_replace = reallocarray(map_replace,
1338                                                        old_map_fds + 1,
1339                                                        sizeof(*map_replace));
1340                         if (!new_map_replace) {
1341                                 p_err("mem alloc failed");
1342                                 goto err_free_reuse_maps;
1343                         }
1344                         map_replace = new_map_replace;
1345
1346                         map_replace[old_map_fds].idx = idx;
1347                         map_replace[old_map_fds].name = name;
1348                         map_replace[old_map_fds].fd = fd;
1349                         old_map_fds++;
1350                 } else if (is_prefix(*argv, "dev")) {
1351                         NEXT_ARG();
1352
1353                         if (ifindex) {
1354                                 p_err("offload device already specified");
1355                                 goto err_free_reuse_maps;
1356                         }
1357                         if (!REQ_ARGS(1))
1358                                 goto err_free_reuse_maps;
1359
1360                         ifindex = if_nametoindex(*argv);
1361                         if (!ifindex) {
1362                                 p_err("unrecognized netdevice '%s': %s",
1363                                       *argv, strerror(errno));
1364                                 goto err_free_reuse_maps;
1365                         }
1366                         NEXT_ARG();
1367                 } else if (is_prefix(*argv, "pinmaps")) {
1368                         NEXT_ARG();
1369
1370                         if (!REQ_ARGS(1))
1371                                 goto err_free_reuse_maps;
1372
1373                         pinmaps = GET_ARG();
1374                 } else {
1375                         p_err("expected no more arguments, 'type', 'map' or 'dev', got: '%s'?",
1376                               *argv);
1377                         goto err_free_reuse_maps;
1378                 }
1379         }
1380
1381         set_max_rlimit();
1382
1383         obj = bpf_object__open_file(file, &open_opts);
1384         if (IS_ERR_OR_NULL(obj)) {
1385                 p_err("failed to open object file");
1386                 goto err_free_reuse_maps;
1387         }
1388
1389         bpf_object__for_each_program(pos, obj) {
1390                 enum bpf_prog_type prog_type = common_prog_type;
1391
1392                 if (prog_type == BPF_PROG_TYPE_UNSPEC) {
1393                         const char *sec_name = bpf_program__title(pos, false);
1394
1395                         err = libbpf_prog_type_by_name(sec_name, &prog_type,
1396                                                        &expected_attach_type);
1397                         if (err < 0)
1398                                 goto err_close_obj;
1399                 }
1400
1401                 bpf_program__set_ifindex(pos, ifindex);
1402                 bpf_program__set_type(pos, prog_type);
1403                 bpf_program__set_expected_attach_type(pos, expected_attach_type);
1404         }
1405
1406         qsort(map_replace, old_map_fds, sizeof(*map_replace),
1407               map_replace_compar);
1408
1409         /* After the sort maps by name will be first on the list, because they
1410          * have idx == -1.  Resolve them.
1411          */
1412         j = 0;
1413         while (j < old_map_fds && map_replace[j].name) {
1414                 i = 0;
1415                 bpf_object__for_each_map(map, obj) {
1416                         if (!strcmp(bpf_map__name(map), map_replace[j].name)) {
1417                                 map_replace[j].idx = i;
1418                                 break;
1419                         }
1420                         i++;
1421                 }
1422                 if (map_replace[j].idx == -1) {
1423                         p_err("unable to find map '%s'", map_replace[j].name);
1424                         goto err_close_obj;
1425                 }
1426                 j++;
1427         }
1428         /* Resort if any names were resolved */
1429         if (j)
1430                 qsort(map_replace, old_map_fds, sizeof(*map_replace),
1431                       map_replace_compar);
1432
1433         /* Set ifindex and name reuse */
1434         j = 0;
1435         idx = 0;
1436         bpf_object__for_each_map(map, obj) {
1437                 if (!bpf_map__is_offload_neutral(map))
1438                         bpf_map__set_ifindex(map, ifindex);
1439
1440                 if (j < old_map_fds && idx == map_replace[j].idx) {
1441                         err = bpf_map__reuse_fd(map, map_replace[j++].fd);
1442                         if (err) {
1443                                 p_err("unable to set up map reuse: %d", err);
1444                                 goto err_close_obj;
1445                         }
1446
1447                         /* Next reuse wants to apply to the same map */
1448                         if (j < old_map_fds && map_replace[j].idx == idx) {
1449                                 p_err("replacement for map idx %d specified more than once",
1450                                       idx);
1451                                 goto err_close_obj;
1452                         }
1453                 }
1454
1455                 idx++;
1456         }
1457         if (j < old_map_fds) {
1458                 p_err("map idx '%d' not used", map_replace[j].idx);
1459                 goto err_close_obj;
1460         }
1461
1462         load_attr.obj = obj;
1463         if (verifier_logs)
1464                 /* log_level1 + log_level2 + stats, but not stable UAPI */
1465                 load_attr.log_level = 1 + 2 + 4;
1466
1467         err = bpf_object__load_xattr(&load_attr);
1468         if (err) {
1469                 p_err("failed to load object file");
1470                 goto err_close_obj;
1471         }
1472
1473         err = mount_bpffs_for_pin(pinfile);
1474         if (err)
1475                 goto err_close_obj;
1476
1477         if (first_prog_only) {
1478                 prog = bpf_program__next(NULL, obj);
1479                 if (!prog) {
1480                         p_err("object file doesn't contain any bpf program");
1481                         goto err_close_obj;
1482                 }
1483
1484                 err = bpf_obj_pin(bpf_program__fd(prog), pinfile);
1485                 if (err) {
1486                         p_err("failed to pin program %s",
1487                               bpf_program__title(prog, false));
1488                         goto err_close_obj;
1489                 }
1490         } else {
1491                 err = bpf_object__pin_programs(obj, pinfile);
1492                 if (err) {
1493                         p_err("failed to pin all programs");
1494                         goto err_close_obj;
1495                 }
1496         }
1497
1498         if (pinmaps) {
1499                 err = bpf_object__pin_maps(obj, pinmaps);
1500                 if (err) {
1501                         p_err("failed to pin all maps");
1502                         goto err_unpin;
1503                 }
1504         }
1505
1506         if (json_output)
1507                 jsonw_null(json_wtr);
1508
1509         bpf_object__close(obj);
1510         for (i = 0; i < old_map_fds; i++)
1511                 close(map_replace[i].fd);
1512         free(map_replace);
1513
1514         return 0;
1515
1516 err_unpin:
1517         if (first_prog_only)
1518                 unlink(pinfile);
1519         else
1520                 bpf_object__unpin_programs(obj, pinfile);
1521 err_close_obj:
1522         bpf_object__close(obj);
1523 err_free_reuse_maps:
1524         for (i = 0; i < old_map_fds; i++)
1525                 close(map_replace[i].fd);
1526         free(map_replace);
1527         return -1;
1528 }
1529
1530 static int do_load(int argc, char **argv)
1531 {
1532         return load_with_options(argc, argv, true);
1533 }
1534
1535 static int do_loadall(int argc, char **argv)
1536 {
1537         return load_with_options(argc, argv, false);
1538 }
1539
1540 static int do_help(int argc, char **argv)
1541 {
1542         if (json_output) {
1543                 jsonw_null(json_wtr);
1544                 return 0;
1545         }
1546
1547         fprintf(stderr,
1548                 "Usage: %s %s { show | list } [PROG]\n"
1549                 "       %s %s dump xlated PROG [{ file FILE | opcodes | visual | linum }]\n"
1550                 "       %s %s dump jited  PROG [{ file FILE | opcodes | linum }]\n"
1551                 "       %s %s pin   PROG FILE\n"
1552                 "       %s %s { load | loadall } OBJ  PATH \\\n"
1553                 "                         [type TYPE] [dev NAME] \\\n"
1554                 "                         [map { idx IDX | name NAME } MAP]\\\n"
1555                 "                         [pinmaps MAP_DIR]\n"
1556                 "       %s %s attach PROG ATTACH_TYPE [MAP]\n"
1557                 "       %s %s detach PROG ATTACH_TYPE [MAP]\n"
1558                 "       %s %s run PROG \\\n"
1559                 "                         data_in FILE \\\n"
1560                 "                         [data_out FILE [data_size_out L]] \\\n"
1561                 "                         [ctx_in FILE [ctx_out FILE [ctx_size_out M]]] \\\n"
1562                 "                         [repeat N]\n"
1563                 "       %s %s tracelog\n"
1564                 "       %s %s help\n"
1565                 "\n"
1566                 "       " HELP_SPEC_MAP "\n"
1567                 "       " HELP_SPEC_PROGRAM "\n"
1568                 "       TYPE := { socket | kprobe | kretprobe | classifier | action |\n"
1569                 "                 tracepoint | raw_tracepoint | xdp | perf_event | cgroup/skb |\n"
1570                 "                 cgroup/sock | cgroup/dev | lwt_in | lwt_out | lwt_xmit |\n"
1571                 "                 lwt_seg6local | sockops | sk_skb | sk_msg | lirc_mode2 |\n"
1572                 "                 sk_reuseport | flow_dissector | cgroup/sysctl |\n"
1573                 "                 cgroup/bind4 | cgroup/bind6 | cgroup/post_bind4 |\n"
1574                 "                 cgroup/post_bind6 | cgroup/connect4 | cgroup/connect6 |\n"
1575                 "                 cgroup/sendmsg4 | cgroup/sendmsg6 | cgroup/recvmsg4 |\n"
1576                 "                 cgroup/recvmsg6 | cgroup/getsockopt |\n"
1577                 "                 cgroup/setsockopt }\n"
1578                 "       ATTACH_TYPE := { msg_verdict | stream_verdict | stream_parser |\n"
1579                 "                        flow_dissector }\n"
1580                 "       " HELP_SPEC_OPTIONS "\n"
1581                 "",
1582                 bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2],
1583                 bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2],
1584                 bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2],
1585                 bin_name, argv[-2]);
1586
1587         return 0;
1588 }
1589
1590 static const struct cmd cmds[] = {
1591         { "show",       do_show },
1592         { "list",       do_show },
1593         { "help",       do_help },
1594         { "dump",       do_dump },
1595         { "pin",        do_pin },
1596         { "load",       do_load },
1597         { "loadall",    do_loadall },
1598         { "attach",     do_attach },
1599         { "detach",     do_detach },
1600         { "tracelog",   do_tracelog },
1601         { "run",        do_run },
1602         { 0 }
1603 };
1604
1605 int do_prog(int argc, char **argv)
1606 {
1607         return cmd_select(cmds, argc, argv, do_help);
1608 }