Merge tag 'fixes-v5.9a' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris...
[linux-2.6-microblaze.git] / tools / bpf / bpftool / map.c
1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2 /* Copyright (C) 2017-2018 Netronome Systems, Inc. */
3
4 #include <assert.h>
5 #include <errno.h>
6 #include <fcntl.h>
7 #include <linux/err.h>
8 #include <linux/kernel.h>
9 #include <net/if.h>
10 #include <stdbool.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <unistd.h>
15 #include <sys/types.h>
16 #include <sys/stat.h>
17
18 #include <bpf/bpf.h>
19 #include <bpf/btf.h>
20
21 #include "json_writer.h"
22 #include "main.h"
23
24 const char * const map_type_name[] = {
25         [BPF_MAP_TYPE_UNSPEC]                   = "unspec",
26         [BPF_MAP_TYPE_HASH]                     = "hash",
27         [BPF_MAP_TYPE_ARRAY]                    = "array",
28         [BPF_MAP_TYPE_PROG_ARRAY]               = "prog_array",
29         [BPF_MAP_TYPE_PERF_EVENT_ARRAY]         = "perf_event_array",
30         [BPF_MAP_TYPE_PERCPU_HASH]              = "percpu_hash",
31         [BPF_MAP_TYPE_PERCPU_ARRAY]             = "percpu_array",
32         [BPF_MAP_TYPE_STACK_TRACE]              = "stack_trace",
33         [BPF_MAP_TYPE_CGROUP_ARRAY]             = "cgroup_array",
34         [BPF_MAP_TYPE_LRU_HASH]                 = "lru_hash",
35         [BPF_MAP_TYPE_LRU_PERCPU_HASH]          = "lru_percpu_hash",
36         [BPF_MAP_TYPE_LPM_TRIE]                 = "lpm_trie",
37         [BPF_MAP_TYPE_ARRAY_OF_MAPS]            = "array_of_maps",
38         [BPF_MAP_TYPE_HASH_OF_MAPS]             = "hash_of_maps",
39         [BPF_MAP_TYPE_DEVMAP]                   = "devmap",
40         [BPF_MAP_TYPE_DEVMAP_HASH]              = "devmap_hash",
41         [BPF_MAP_TYPE_SOCKMAP]                  = "sockmap",
42         [BPF_MAP_TYPE_CPUMAP]                   = "cpumap",
43         [BPF_MAP_TYPE_XSKMAP]                   = "xskmap",
44         [BPF_MAP_TYPE_SOCKHASH]                 = "sockhash",
45         [BPF_MAP_TYPE_CGROUP_STORAGE]           = "cgroup_storage",
46         [BPF_MAP_TYPE_REUSEPORT_SOCKARRAY]      = "reuseport_sockarray",
47         [BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE]    = "percpu_cgroup_storage",
48         [BPF_MAP_TYPE_QUEUE]                    = "queue",
49         [BPF_MAP_TYPE_STACK]                    = "stack",
50         [BPF_MAP_TYPE_SK_STORAGE]               = "sk_storage",
51         [BPF_MAP_TYPE_STRUCT_OPS]               = "struct_ops",
52         [BPF_MAP_TYPE_RINGBUF]                  = "ringbuf",
53 };
54
55 const size_t map_type_name_size = ARRAY_SIZE(map_type_name);
56
57 static bool map_is_per_cpu(__u32 type)
58 {
59         return type == BPF_MAP_TYPE_PERCPU_HASH ||
60                type == BPF_MAP_TYPE_PERCPU_ARRAY ||
61                type == BPF_MAP_TYPE_LRU_PERCPU_HASH ||
62                type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE;
63 }
64
65 static bool map_is_map_of_maps(__u32 type)
66 {
67         return type == BPF_MAP_TYPE_ARRAY_OF_MAPS ||
68                type == BPF_MAP_TYPE_HASH_OF_MAPS;
69 }
70
71 static bool map_is_map_of_progs(__u32 type)
72 {
73         return type == BPF_MAP_TYPE_PROG_ARRAY;
74 }
75
76 static int map_type_from_str(const char *type)
77 {
78         unsigned int i;
79
80         for (i = 0; i < ARRAY_SIZE(map_type_name); i++)
81                 /* Don't allow prefixing in case of possible future shadowing */
82                 if (map_type_name[i] && !strcmp(map_type_name[i], type))
83                         return i;
84         return -1;
85 }
86
87 static void *alloc_value(struct bpf_map_info *info)
88 {
89         if (map_is_per_cpu(info->type))
90                 return malloc(round_up(info->value_size, 8) *
91                               get_possible_cpus());
92         else
93                 return malloc(info->value_size);
94 }
95
96 static int do_dump_btf(const struct btf_dumper *d,
97                        struct bpf_map_info *map_info, void *key,
98                        void *value)
99 {
100         __u32 value_id;
101         int ret;
102
103         /* start of key-value pair */
104         jsonw_start_object(d->jw);
105
106         if (map_info->btf_key_type_id) {
107                 jsonw_name(d->jw, "key");
108
109                 ret = btf_dumper_type(d, map_info->btf_key_type_id, key);
110                 if (ret)
111                         goto err_end_obj;
112         }
113
114         value_id = map_info->btf_vmlinux_value_type_id ?
115                 : map_info->btf_value_type_id;
116
117         if (!map_is_per_cpu(map_info->type)) {
118                 jsonw_name(d->jw, "value");
119                 ret = btf_dumper_type(d, value_id, value);
120         } else {
121                 unsigned int i, n, step;
122
123                 jsonw_name(d->jw, "values");
124                 jsonw_start_array(d->jw);
125                 n = get_possible_cpus();
126                 step = round_up(map_info->value_size, 8);
127                 for (i = 0; i < n; i++) {
128                         jsonw_start_object(d->jw);
129                         jsonw_int_field(d->jw, "cpu", i);
130                         jsonw_name(d->jw, "value");
131                         ret = btf_dumper_type(d, value_id, value + i * step);
132                         jsonw_end_object(d->jw);
133                         if (ret)
134                                 break;
135                 }
136                 jsonw_end_array(d->jw);
137         }
138
139 err_end_obj:
140         /* end of key-value pair */
141         jsonw_end_object(d->jw);
142
143         return ret;
144 }
145
146 static json_writer_t *get_btf_writer(void)
147 {
148         json_writer_t *jw = jsonw_new(stdout);
149
150         if (!jw)
151                 return NULL;
152         jsonw_pretty(jw, true);
153
154         return jw;
155 }
156
157 static void print_entry_json(struct bpf_map_info *info, unsigned char *key,
158                              unsigned char *value, struct btf *btf)
159 {
160         jsonw_start_object(json_wtr);
161
162         if (!map_is_per_cpu(info->type)) {
163                 jsonw_name(json_wtr, "key");
164                 print_hex_data_json(key, info->key_size);
165                 jsonw_name(json_wtr, "value");
166                 print_hex_data_json(value, info->value_size);
167                 if (btf) {
168                         struct btf_dumper d = {
169                                 .btf = btf,
170                                 .jw = json_wtr,
171                                 .is_plain_text = false,
172                         };
173
174                         jsonw_name(json_wtr, "formatted");
175                         do_dump_btf(&d, info, key, value);
176                 }
177         } else {
178                 unsigned int i, n, step;
179
180                 n = get_possible_cpus();
181                 step = round_up(info->value_size, 8);
182
183                 jsonw_name(json_wtr, "key");
184                 print_hex_data_json(key, info->key_size);
185
186                 jsonw_name(json_wtr, "values");
187                 jsonw_start_array(json_wtr);
188                 for (i = 0; i < n; i++) {
189                         jsonw_start_object(json_wtr);
190
191                         jsonw_int_field(json_wtr, "cpu", i);
192
193                         jsonw_name(json_wtr, "value");
194                         print_hex_data_json(value + i * step,
195                                             info->value_size);
196
197                         jsonw_end_object(json_wtr);
198                 }
199                 jsonw_end_array(json_wtr);
200                 if (btf) {
201                         struct btf_dumper d = {
202                                 .btf = btf,
203                                 .jw = json_wtr,
204                                 .is_plain_text = false,
205                         };
206
207                         jsonw_name(json_wtr, "formatted");
208                         do_dump_btf(&d, info, key, value);
209                 }
210         }
211
212         jsonw_end_object(json_wtr);
213 }
214
215 static void print_entry_error(struct bpf_map_info *info, unsigned char *key,
216                               const char *error_msg)
217 {
218         int msg_size = strlen(error_msg);
219         bool single_line, break_names;
220
221         break_names = info->key_size > 16 || msg_size > 16;
222         single_line = info->key_size + msg_size <= 24 && !break_names;
223
224         printf("key:%c", break_names ? '\n' : ' ');
225         fprint_hex(stdout, key, info->key_size, " ");
226
227         printf(single_line ? "  " : "\n");
228
229         printf("value:%c%s", break_names ? '\n' : ' ', error_msg);
230
231         printf("\n");
232 }
233
234 static void print_entry_plain(struct bpf_map_info *info, unsigned char *key,
235                               unsigned char *value)
236 {
237         if (!map_is_per_cpu(info->type)) {
238                 bool single_line, break_names;
239
240                 break_names = info->key_size > 16 || info->value_size > 16;
241                 single_line = info->key_size + info->value_size <= 24 &&
242                         !break_names;
243
244                 if (info->key_size) {
245                         printf("key:%c", break_names ? '\n' : ' ');
246                         fprint_hex(stdout, key, info->key_size, " ");
247
248                         printf(single_line ? "  " : "\n");
249                 }
250
251                 if (info->value_size) {
252                         printf("value:%c", break_names ? '\n' : ' ');
253                         fprint_hex(stdout, value, info->value_size, " ");
254                 }
255
256                 printf("\n");
257         } else {
258                 unsigned int i, n, step;
259
260                 n = get_possible_cpus();
261                 step = round_up(info->value_size, 8);
262
263                 if (info->key_size) {
264                         printf("key:\n");
265                         fprint_hex(stdout, key, info->key_size, " ");
266                         printf("\n");
267                 }
268                 if (info->value_size) {
269                         for (i = 0; i < n; i++) {
270                                 printf("value (CPU %02d):%c",
271                                        i, info->value_size > 16 ? '\n' : ' ');
272                                 fprint_hex(stdout, value + i * step,
273                                            info->value_size, " ");
274                                 printf("\n");
275                         }
276                 }
277         }
278 }
279
280 static char **parse_bytes(char **argv, const char *name, unsigned char *val,
281                           unsigned int n)
282 {
283         unsigned int i = 0, base = 0;
284         char *endptr;
285
286         if (is_prefix(*argv, "hex")) {
287                 base = 16;
288                 argv++;
289         }
290
291         while (i < n && argv[i]) {
292                 val[i] = strtoul(argv[i], &endptr, base);
293                 if (*endptr) {
294                         p_err("error parsing byte: %s", argv[i]);
295                         return NULL;
296                 }
297                 i++;
298         }
299
300         if (i != n) {
301                 p_err("%s expected %d bytes got %d", name, n, i);
302                 return NULL;
303         }
304
305         return argv + i;
306 }
307
308 /* on per cpu maps we must copy the provided value on all value instances */
309 static void fill_per_cpu_value(struct bpf_map_info *info, void *value)
310 {
311         unsigned int i, n, step;
312
313         if (!map_is_per_cpu(info->type))
314                 return;
315
316         n = get_possible_cpus();
317         step = round_up(info->value_size, 8);
318         for (i = 1; i < n; i++)
319                 memcpy(value + i * step, value, info->value_size);
320 }
321
322 static int parse_elem(char **argv, struct bpf_map_info *info,
323                       void *key, void *value, __u32 key_size, __u32 value_size,
324                       __u32 *flags, __u32 **value_fd)
325 {
326         if (!*argv) {
327                 if (!key && !value)
328                         return 0;
329                 p_err("did not find %s", key ? "key" : "value");
330                 return -1;
331         }
332
333         if (is_prefix(*argv, "key")) {
334                 if (!key) {
335                         if (key_size)
336                                 p_err("duplicate key");
337                         else
338                                 p_err("unnecessary key");
339                         return -1;
340                 }
341
342                 argv = parse_bytes(argv + 1, "key", key, key_size);
343                 if (!argv)
344                         return -1;
345
346                 return parse_elem(argv, info, NULL, value, key_size, value_size,
347                                   flags, value_fd);
348         } else if (is_prefix(*argv, "value")) {
349                 int fd;
350
351                 if (!value) {
352                         if (value_size)
353                                 p_err("duplicate value");
354                         else
355                                 p_err("unnecessary value");
356                         return -1;
357                 }
358
359                 argv++;
360
361                 if (map_is_map_of_maps(info->type)) {
362                         int argc = 2;
363
364                         if (value_size != 4) {
365                                 p_err("value smaller than 4B for map in map?");
366                                 return -1;
367                         }
368                         if (!argv[0] || !argv[1]) {
369                                 p_err("not enough value arguments for map in map");
370                                 return -1;
371                         }
372
373                         fd = map_parse_fd(&argc, &argv);
374                         if (fd < 0)
375                                 return -1;
376
377                         *value_fd = value;
378                         **value_fd = fd;
379                 } else if (map_is_map_of_progs(info->type)) {
380                         int argc = 2;
381
382                         if (value_size != 4) {
383                                 p_err("value smaller than 4B for map of progs?");
384                                 return -1;
385                         }
386                         if (!argv[0] || !argv[1]) {
387                                 p_err("not enough value arguments for map of progs");
388                                 return -1;
389                         }
390                         if (is_prefix(*argv, "id"))
391                                 p_info("Warning: updating program array via MAP_ID, make sure this map is kept open\n"
392                                        "         by some process or pinned otherwise update will be lost");
393
394                         fd = prog_parse_fd(&argc, &argv);
395                         if (fd < 0)
396                                 return -1;
397
398                         *value_fd = value;
399                         **value_fd = fd;
400                 } else {
401                         argv = parse_bytes(argv, "value", value, value_size);
402                         if (!argv)
403                                 return -1;
404
405                         fill_per_cpu_value(info, value);
406                 }
407
408                 return parse_elem(argv, info, key, NULL, key_size, value_size,
409                                   flags, NULL);
410         } else if (is_prefix(*argv, "any") || is_prefix(*argv, "noexist") ||
411                    is_prefix(*argv, "exist")) {
412                 if (!flags) {
413                         p_err("flags specified multiple times: %s", *argv);
414                         return -1;
415                 }
416
417                 if (is_prefix(*argv, "any"))
418                         *flags = BPF_ANY;
419                 else if (is_prefix(*argv, "noexist"))
420                         *flags = BPF_NOEXIST;
421                 else if (is_prefix(*argv, "exist"))
422                         *flags = BPF_EXIST;
423
424                 return parse_elem(argv + 1, info, key, value, key_size,
425                                   value_size, NULL, value_fd);
426         }
427
428         p_err("expected key or value, got: %s", *argv);
429         return -1;
430 }
431
432 static void show_map_header_json(struct bpf_map_info *info, json_writer_t *wtr)
433 {
434         jsonw_uint_field(wtr, "id", info->id);
435         if (info->type < ARRAY_SIZE(map_type_name))
436                 jsonw_string_field(wtr, "type", map_type_name[info->type]);
437         else
438                 jsonw_uint_field(wtr, "type", info->type);
439
440         if (*info->name)
441                 jsonw_string_field(wtr, "name", info->name);
442
443         jsonw_name(wtr, "flags");
444         jsonw_printf(wtr, "%d", info->map_flags);
445 }
446
447 static int show_map_close_json(int fd, struct bpf_map_info *info)
448 {
449         char *memlock, *frozen_str;
450         int frozen = 0;
451
452         memlock = get_fdinfo(fd, "memlock");
453         frozen_str = get_fdinfo(fd, "frozen");
454
455         jsonw_start_object(json_wtr);
456
457         show_map_header_json(info, json_wtr);
458
459         print_dev_json(info->ifindex, info->netns_dev, info->netns_ino);
460
461         jsonw_uint_field(json_wtr, "bytes_key", info->key_size);
462         jsonw_uint_field(json_wtr, "bytes_value", info->value_size);
463         jsonw_uint_field(json_wtr, "max_entries", info->max_entries);
464
465         if (memlock)
466                 jsonw_int_field(json_wtr, "bytes_memlock", atoi(memlock));
467         free(memlock);
468
469         if (info->type == BPF_MAP_TYPE_PROG_ARRAY) {
470                 char *owner_prog_type = get_fdinfo(fd, "owner_prog_type");
471                 char *owner_jited = get_fdinfo(fd, "owner_jited");
472
473                 if (owner_prog_type) {
474                         unsigned int prog_type = atoi(owner_prog_type);
475
476                         if (prog_type < prog_type_name_size)
477                                 jsonw_string_field(json_wtr, "owner_prog_type",
478                                                    prog_type_name[prog_type]);
479                         else
480                                 jsonw_uint_field(json_wtr, "owner_prog_type",
481                                                  prog_type);
482                 }
483                 if (owner_jited)
484                         jsonw_bool_field(json_wtr, "owner_jited",
485                                          !!atoi(owner_jited));
486
487                 free(owner_prog_type);
488                 free(owner_jited);
489         }
490         close(fd);
491
492         if (frozen_str) {
493                 frozen = atoi(frozen_str);
494                 free(frozen_str);
495         }
496         jsonw_int_field(json_wtr, "frozen", frozen);
497
498         if (info->btf_id)
499                 jsonw_int_field(json_wtr, "btf_id", info->btf_id);
500
501         if (!hash_empty(map_table.table)) {
502                 struct pinned_obj *obj;
503
504                 jsonw_name(json_wtr, "pinned");
505                 jsonw_start_array(json_wtr);
506                 hash_for_each_possible(map_table.table, obj, hash, info->id) {
507                         if (obj->id == info->id)
508                                 jsonw_string(json_wtr, obj->path);
509                 }
510                 jsonw_end_array(json_wtr);
511         }
512
513         emit_obj_refs_json(&refs_table, info->id, json_wtr);
514
515         jsonw_end_object(json_wtr);
516
517         return 0;
518 }
519
520 static void show_map_header_plain(struct bpf_map_info *info)
521 {
522         printf("%u: ", info->id);
523         if (info->type < ARRAY_SIZE(map_type_name))
524                 printf("%s  ", map_type_name[info->type]);
525         else
526                 printf("type %u  ", info->type);
527
528         if (*info->name)
529                 printf("name %s  ", info->name);
530
531         printf("flags 0x%x", info->map_flags);
532         print_dev_plain(info->ifindex, info->netns_dev, info->netns_ino);
533         printf("\n");
534 }
535
536 static int show_map_close_plain(int fd, struct bpf_map_info *info)
537 {
538         char *memlock, *frozen_str;
539         int frozen = 0;
540
541         memlock = get_fdinfo(fd, "memlock");
542         frozen_str = get_fdinfo(fd, "frozen");
543
544         show_map_header_plain(info);
545         printf("\tkey %uB  value %uB  max_entries %u",
546                info->key_size, info->value_size, info->max_entries);
547
548         if (memlock)
549                 printf("  memlock %sB", memlock);
550         free(memlock);
551
552         if (info->type == BPF_MAP_TYPE_PROG_ARRAY) {
553                 char *owner_prog_type = get_fdinfo(fd, "owner_prog_type");
554                 char *owner_jited = get_fdinfo(fd, "owner_jited");
555
556                 if (owner_prog_type || owner_jited)
557                         printf("\n\t");
558                 if (owner_prog_type) {
559                         unsigned int prog_type = atoi(owner_prog_type);
560
561                         if (prog_type < prog_type_name_size)
562                                 printf("owner_prog_type %s  ",
563                                        prog_type_name[prog_type]);
564                         else
565                                 printf("owner_prog_type %d  ", prog_type);
566                 }
567                 if (owner_jited)
568                         printf("owner%s jited",
569                                atoi(owner_jited) ? "" : " not");
570
571                 free(owner_prog_type);
572                 free(owner_jited);
573         }
574         close(fd);
575
576         if (!hash_empty(map_table.table)) {
577                 struct pinned_obj *obj;
578
579                 hash_for_each_possible(map_table.table, obj, hash, info->id) {
580                         if (obj->id == info->id)
581                                 printf("\n\tpinned %s", obj->path);
582                 }
583         }
584         printf("\n");
585
586         if (frozen_str) {
587                 frozen = atoi(frozen_str);
588                 free(frozen_str);
589         }
590
591         if (!info->btf_id && !frozen)
592                 return 0;
593
594         printf("\t");
595
596         if (info->btf_id)
597                 printf("btf_id %d", info->btf_id);
598
599         if (frozen)
600                 printf("%sfrozen", info->btf_id ? "  " : "");
601
602         emit_obj_refs_plain(&refs_table, info->id, "\n\tpids ");
603
604         printf("\n");
605         return 0;
606 }
607
608 static int do_show_subset(int argc, char **argv)
609 {
610         struct bpf_map_info info = {};
611         __u32 len = sizeof(info);
612         int *fds = NULL;
613         int nb_fds, i;
614         int err = -1;
615
616         fds = malloc(sizeof(int));
617         if (!fds) {
618                 p_err("mem alloc failed");
619                 return -1;
620         }
621         nb_fds = map_parse_fds(&argc, &argv, &fds);
622         if (nb_fds < 1)
623                 goto exit_free;
624
625         if (json_output && nb_fds > 1)
626                 jsonw_start_array(json_wtr);    /* root array */
627         for (i = 0; i < nb_fds; i++) {
628                 err = bpf_obj_get_info_by_fd(fds[i], &info, &len);
629                 if (err) {
630                         p_err("can't get map info: %s",
631                               strerror(errno));
632                         for (; i < nb_fds; i++)
633                                 close(fds[i]);
634                         break;
635                 }
636
637                 if (json_output)
638                         show_map_close_json(fds[i], &info);
639                 else
640                         show_map_close_plain(fds[i], &info);
641
642                 close(fds[i]);
643         }
644         if (json_output && nb_fds > 1)
645                 jsonw_end_array(json_wtr);      /* root array */
646
647 exit_free:
648         free(fds);
649         return err;
650 }
651
652 static int do_show(int argc, char **argv)
653 {
654         struct bpf_map_info info = {};
655         __u32 len = sizeof(info);
656         __u32 id = 0;
657         int err;
658         int fd;
659
660         if (show_pinned)
661                 build_pinned_obj_table(&map_table, BPF_OBJ_MAP);
662         build_obj_refs_table(&refs_table, BPF_OBJ_MAP);
663
664         if (argc == 2)
665                 return do_show_subset(argc, argv);
666
667         if (argc)
668                 return BAD_ARG();
669
670         if (json_output)
671                 jsonw_start_array(json_wtr);
672         while (true) {
673                 err = bpf_map_get_next_id(id, &id);
674                 if (err) {
675                         if (errno == ENOENT)
676                                 break;
677                         p_err("can't get next map: %s%s", strerror(errno),
678                               errno == EINVAL ? " -- kernel too old?" : "");
679                         break;
680                 }
681
682                 fd = bpf_map_get_fd_by_id(id);
683                 if (fd < 0) {
684                         if (errno == ENOENT)
685                                 continue;
686                         p_err("can't get map by id (%u): %s",
687                               id, strerror(errno));
688                         break;
689                 }
690
691                 err = bpf_obj_get_info_by_fd(fd, &info, &len);
692                 if (err) {
693                         p_err("can't get map info: %s", strerror(errno));
694                         close(fd);
695                         break;
696                 }
697
698                 if (json_output)
699                         show_map_close_json(fd, &info);
700                 else
701                         show_map_close_plain(fd, &info);
702         }
703         if (json_output)
704                 jsonw_end_array(json_wtr);
705
706         delete_obj_refs_table(&refs_table);
707
708         return errno == ENOENT ? 0 : -1;
709 }
710
711 static int dump_map_elem(int fd, void *key, void *value,
712                          struct bpf_map_info *map_info, struct btf *btf,
713                          json_writer_t *btf_wtr)
714 {
715         int num_elems = 0;
716         int lookup_errno;
717
718         if (!bpf_map_lookup_elem(fd, key, value)) {
719                 if (json_output) {
720                         print_entry_json(map_info, key, value, btf);
721                 } else {
722                         if (btf) {
723                                 struct btf_dumper d = {
724                                         .btf = btf,
725                                         .jw = btf_wtr,
726                                         .is_plain_text = true,
727                                 };
728
729                                 do_dump_btf(&d, map_info, key, value);
730                         } else {
731                                 print_entry_plain(map_info, key, value);
732                         }
733                         num_elems++;
734                 }
735                 return num_elems;
736         }
737
738         /* lookup error handling */
739         lookup_errno = errno;
740
741         if (map_is_map_of_maps(map_info->type) ||
742             map_is_map_of_progs(map_info->type))
743                 return 0;
744
745         if (json_output) {
746                 jsonw_start_object(json_wtr);
747                 jsonw_name(json_wtr, "key");
748                 print_hex_data_json(key, map_info->key_size);
749                 jsonw_name(json_wtr, "value");
750                 jsonw_start_object(json_wtr);
751                 jsonw_string_field(json_wtr, "error", strerror(lookup_errno));
752                 jsonw_end_object(json_wtr);
753                 jsonw_end_object(json_wtr);
754         } else {
755                 const char *msg = NULL;
756
757                 if (lookup_errno == ENOENT)
758                         msg = "<no entry>";
759                 else if (lookup_errno == ENOSPC &&
760                          map_info->type == BPF_MAP_TYPE_REUSEPORT_SOCKARRAY)
761                         msg = "<cannot read>";
762
763                 print_entry_error(map_info, key,
764                                   msg ? : strerror(lookup_errno));
765         }
766
767         return 0;
768 }
769
770 static int maps_have_btf(int *fds, int nb_fds)
771 {
772         struct bpf_map_info info = {};
773         __u32 len = sizeof(info);
774         int err, i;
775
776         for (i = 0; i < nb_fds; i++) {
777                 err = bpf_obj_get_info_by_fd(fds[i], &info, &len);
778                 if (err) {
779                         p_err("can't get map info: %s", strerror(errno));
780                         return -1;
781                 }
782
783                 if (!info.btf_id)
784                         return 0;
785         }
786
787         return 1;
788 }
789
790 static struct btf *btf_vmlinux;
791
792 static struct btf *get_map_kv_btf(const struct bpf_map_info *info)
793 {
794         struct btf *btf = NULL;
795
796         if (info->btf_vmlinux_value_type_id) {
797                 if (!btf_vmlinux) {
798                         btf_vmlinux = libbpf_find_kernel_btf();
799                         if (IS_ERR(btf_vmlinux))
800                                 p_err("failed to get kernel btf");
801                 }
802                 return btf_vmlinux;
803         } else if (info->btf_value_type_id) {
804                 int err;
805
806                 err = btf__get_from_id(info->btf_id, &btf);
807                 if (err || !btf) {
808                         p_err("failed to get btf");
809                         btf = err ? ERR_PTR(err) : ERR_PTR(-ESRCH);
810                 }
811         }
812
813         return btf;
814 }
815
816 static void free_map_kv_btf(struct btf *btf)
817 {
818         if (!IS_ERR(btf) && btf != btf_vmlinux)
819                 btf__free(btf);
820 }
821
822 static void free_btf_vmlinux(void)
823 {
824         if (!IS_ERR(btf_vmlinux))
825                 btf__free(btf_vmlinux);
826 }
827
828 static int
829 map_dump(int fd, struct bpf_map_info *info, json_writer_t *wtr,
830          bool show_header)
831 {
832         void *key, *value, *prev_key;
833         unsigned int num_elems = 0;
834         struct btf *btf = NULL;
835         int err;
836
837         key = malloc(info->key_size);
838         value = alloc_value(info);
839         if (!key || !value) {
840                 p_err("mem alloc failed");
841                 err = -1;
842                 goto exit_free;
843         }
844
845         prev_key = NULL;
846
847         if (wtr) {
848                 btf = get_map_kv_btf(info);
849                 if (IS_ERR(btf)) {
850                         err = PTR_ERR(btf);
851                         goto exit_free;
852                 }
853
854                 if (show_header) {
855                         jsonw_start_object(wtr);        /* map object */
856                         show_map_header_json(info, wtr);
857                         jsonw_name(wtr, "elements");
858                 }
859                 jsonw_start_array(wtr);         /* elements */
860         } else if (show_header) {
861                 show_map_header_plain(info);
862         }
863
864         if (info->type == BPF_MAP_TYPE_REUSEPORT_SOCKARRAY &&
865             info->value_size != 8)
866                 p_info("Warning: cannot read values from %s map with value_size != 8",
867                        map_type_name[info->type]);
868         while (true) {
869                 err = bpf_map_get_next_key(fd, prev_key, key);
870                 if (err) {
871                         if (errno == ENOENT)
872                                 err = 0;
873                         break;
874                 }
875                 num_elems += dump_map_elem(fd, key, value, info, btf, wtr);
876                 prev_key = key;
877         }
878
879         if (wtr) {
880                 jsonw_end_array(wtr);   /* elements */
881                 if (show_header)
882                         jsonw_end_object(wtr);  /* map object */
883         } else {
884                 printf("Found %u element%s\n", num_elems,
885                        num_elems != 1 ? "s" : "");
886         }
887
888 exit_free:
889         free(key);
890         free(value);
891         close(fd);
892         free_map_kv_btf(btf);
893
894         return err;
895 }
896
897 static int do_dump(int argc, char **argv)
898 {
899         json_writer_t *wtr = NULL, *btf_wtr = NULL;
900         struct bpf_map_info info = {};
901         int nb_fds, i = 0;
902         __u32 len = sizeof(info);
903         int *fds = NULL;
904         int err = -1;
905
906         if (argc != 2)
907                 usage();
908
909         fds = malloc(sizeof(int));
910         if (!fds) {
911                 p_err("mem alloc failed");
912                 return -1;
913         }
914         nb_fds = map_parse_fds(&argc, &argv, &fds);
915         if (nb_fds < 1)
916                 goto exit_free;
917
918         if (json_output) {
919                 wtr = json_wtr;
920         } else {
921                 int do_plain_btf;
922
923                 do_plain_btf = maps_have_btf(fds, nb_fds);
924                 if (do_plain_btf < 0)
925                         goto exit_close;
926
927                 if (do_plain_btf) {
928                         btf_wtr = get_btf_writer();
929                         wtr = btf_wtr;
930                         if (!btf_wtr)
931                                 p_info("failed to create json writer for btf. falling back to plain output");
932                 }
933         }
934
935         if (wtr && nb_fds > 1)
936                 jsonw_start_array(wtr); /* root array */
937         for (i = 0; i < nb_fds; i++) {
938                 if (bpf_obj_get_info_by_fd(fds[i], &info, &len)) {
939                         p_err("can't get map info: %s", strerror(errno));
940                         break;
941                 }
942                 err = map_dump(fds[i], &info, wtr, nb_fds > 1);
943                 if (!wtr && i != nb_fds - 1)
944                         printf("\n");
945
946                 if (err)
947                         break;
948                 close(fds[i]);
949         }
950         if (wtr && nb_fds > 1)
951                 jsonw_end_array(wtr);   /* root array */
952
953         if (btf_wtr)
954                 jsonw_destroy(&btf_wtr);
955 exit_close:
956         for (; i < nb_fds; i++)
957                 close(fds[i]);
958 exit_free:
959         free(fds);
960         free_btf_vmlinux();
961         return err;
962 }
963
964 static int alloc_key_value(struct bpf_map_info *info, void **key, void **value)
965 {
966         *key = NULL;
967         *value = NULL;
968
969         if (info->key_size) {
970                 *key = malloc(info->key_size);
971                 if (!*key) {
972                         p_err("key mem alloc failed");
973                         return -1;
974                 }
975         }
976
977         if (info->value_size) {
978                 *value = alloc_value(info);
979                 if (!*value) {
980                         p_err("value mem alloc failed");
981                         free(*key);
982                         *key = NULL;
983                         return -1;
984                 }
985         }
986
987         return 0;
988 }
989
990 static int do_update(int argc, char **argv)
991 {
992         struct bpf_map_info info = {};
993         __u32 len = sizeof(info);
994         __u32 *value_fd = NULL;
995         __u32 flags = BPF_ANY;
996         void *key, *value;
997         int fd, err;
998
999         if (argc < 2)
1000                 usage();
1001
1002         fd = map_parse_fd_and_info(&argc, &argv, &info, &len);
1003         if (fd < 0)
1004                 return -1;
1005
1006         err = alloc_key_value(&info, &key, &value);
1007         if (err)
1008                 goto exit_free;
1009
1010         err = parse_elem(argv, &info, key, value, info.key_size,
1011                          info.value_size, &flags, &value_fd);
1012         if (err)
1013                 goto exit_free;
1014
1015         err = bpf_map_update_elem(fd, key, value, flags);
1016         if (err) {
1017                 p_err("update failed: %s", strerror(errno));
1018                 goto exit_free;
1019         }
1020
1021 exit_free:
1022         if (value_fd)
1023                 close(*value_fd);
1024         free(key);
1025         free(value);
1026         close(fd);
1027
1028         if (!err && json_output)
1029                 jsonw_null(json_wtr);
1030         return err;
1031 }
1032
1033 static void print_key_value(struct bpf_map_info *info, void *key,
1034                             void *value)
1035 {
1036         json_writer_t *btf_wtr;
1037         struct btf *btf = NULL;
1038         int err;
1039
1040         err = btf__get_from_id(info->btf_id, &btf);
1041         if (err) {
1042                 p_err("failed to get btf");
1043                 return;
1044         }
1045
1046         if (json_output) {
1047                 print_entry_json(info, key, value, btf);
1048         } else if (btf) {
1049                 /* if here json_wtr wouldn't have been initialised,
1050                  * so let's create separate writer for btf
1051                  */
1052                 btf_wtr = get_btf_writer();
1053                 if (!btf_wtr) {
1054                         p_info("failed to create json writer for btf. falling back to plain output");
1055                         btf__free(btf);
1056                         btf = NULL;
1057                         print_entry_plain(info, key, value);
1058                 } else {
1059                         struct btf_dumper d = {
1060                                 .btf = btf,
1061                                 .jw = btf_wtr,
1062                                 .is_plain_text = true,
1063                         };
1064
1065                         do_dump_btf(&d, info, key, value);
1066                         jsonw_destroy(&btf_wtr);
1067                 }
1068         } else {
1069                 print_entry_plain(info, key, value);
1070         }
1071         btf__free(btf);
1072 }
1073
1074 static int do_lookup(int argc, char **argv)
1075 {
1076         struct bpf_map_info info = {};
1077         __u32 len = sizeof(info);
1078         void *key, *value;
1079         int err;
1080         int fd;
1081
1082         if (argc < 2)
1083                 usage();
1084
1085         fd = map_parse_fd_and_info(&argc, &argv, &info, &len);
1086         if (fd < 0)
1087                 return -1;
1088
1089         err = alloc_key_value(&info, &key, &value);
1090         if (err)
1091                 goto exit_free;
1092
1093         err = parse_elem(argv, &info, key, NULL, info.key_size, 0, NULL, NULL);
1094         if (err)
1095                 goto exit_free;
1096
1097         err = bpf_map_lookup_elem(fd, key, value);
1098         if (err) {
1099                 if (errno == ENOENT) {
1100                         if (json_output) {
1101                                 jsonw_null(json_wtr);
1102                         } else {
1103                                 printf("key:\n");
1104                                 fprint_hex(stdout, key, info.key_size, " ");
1105                                 printf("\n\nNot found\n");
1106                         }
1107                 } else {
1108                         p_err("lookup failed: %s", strerror(errno));
1109                 }
1110
1111                 goto exit_free;
1112         }
1113
1114         /* here means bpf_map_lookup_elem() succeeded */
1115         print_key_value(&info, key, value);
1116
1117 exit_free:
1118         free(key);
1119         free(value);
1120         close(fd);
1121
1122         return err;
1123 }
1124
1125 static int do_getnext(int argc, char **argv)
1126 {
1127         struct bpf_map_info info = {};
1128         __u32 len = sizeof(info);
1129         void *key, *nextkey;
1130         int err;
1131         int fd;
1132
1133         if (argc < 2)
1134                 usage();
1135
1136         fd = map_parse_fd_and_info(&argc, &argv, &info, &len);
1137         if (fd < 0)
1138                 return -1;
1139
1140         key = malloc(info.key_size);
1141         nextkey = malloc(info.key_size);
1142         if (!key || !nextkey) {
1143                 p_err("mem alloc failed");
1144                 err = -1;
1145                 goto exit_free;
1146         }
1147
1148         if (argc) {
1149                 err = parse_elem(argv, &info, key, NULL, info.key_size, 0,
1150                                  NULL, NULL);
1151                 if (err)
1152                         goto exit_free;
1153         } else {
1154                 free(key);
1155                 key = NULL;
1156         }
1157
1158         err = bpf_map_get_next_key(fd, key, nextkey);
1159         if (err) {
1160                 p_err("can't get next key: %s", strerror(errno));
1161                 goto exit_free;
1162         }
1163
1164         if (json_output) {
1165                 jsonw_start_object(json_wtr);
1166                 if (key) {
1167                         jsonw_name(json_wtr, "key");
1168                         print_hex_data_json(key, info.key_size);
1169                 } else {
1170                         jsonw_null_field(json_wtr, "key");
1171                 }
1172                 jsonw_name(json_wtr, "next_key");
1173                 print_hex_data_json(nextkey, info.key_size);
1174                 jsonw_end_object(json_wtr);
1175         } else {
1176                 if (key) {
1177                         printf("key:\n");
1178                         fprint_hex(stdout, key, info.key_size, " ");
1179                         printf("\n");
1180                 } else {
1181                         printf("key: None\n");
1182                 }
1183                 printf("next key:\n");
1184                 fprint_hex(stdout, nextkey, info.key_size, " ");
1185                 printf("\n");
1186         }
1187
1188 exit_free:
1189         free(nextkey);
1190         free(key);
1191         close(fd);
1192
1193         return err;
1194 }
1195
1196 static int do_delete(int argc, char **argv)
1197 {
1198         struct bpf_map_info info = {};
1199         __u32 len = sizeof(info);
1200         void *key;
1201         int err;
1202         int fd;
1203
1204         if (argc < 2)
1205                 usage();
1206
1207         fd = map_parse_fd_and_info(&argc, &argv, &info, &len);
1208         if (fd < 0)
1209                 return -1;
1210
1211         key = malloc(info.key_size);
1212         if (!key) {
1213                 p_err("mem alloc failed");
1214                 err = -1;
1215                 goto exit_free;
1216         }
1217
1218         err = parse_elem(argv, &info, key, NULL, info.key_size, 0, NULL, NULL);
1219         if (err)
1220                 goto exit_free;
1221
1222         err = bpf_map_delete_elem(fd, key);
1223         if (err)
1224                 p_err("delete failed: %s", strerror(errno));
1225
1226 exit_free:
1227         free(key);
1228         close(fd);
1229
1230         if (!err && json_output)
1231                 jsonw_null(json_wtr);
1232         return err;
1233 }
1234
1235 static int do_pin(int argc, char **argv)
1236 {
1237         int err;
1238
1239         err = do_pin_any(argc, argv, map_parse_fd);
1240         if (!err && json_output)
1241                 jsonw_null(json_wtr);
1242         return err;
1243 }
1244
1245 static int do_create(int argc, char **argv)
1246 {
1247         struct bpf_create_map_attr attr = { NULL, };
1248         const char *pinfile;
1249         int err, fd;
1250
1251         if (!REQ_ARGS(7))
1252                 return -1;
1253         pinfile = GET_ARG();
1254
1255         while (argc) {
1256                 if (!REQ_ARGS(2))
1257                         return -1;
1258
1259                 if (is_prefix(*argv, "type")) {
1260                         NEXT_ARG();
1261
1262                         if (attr.map_type) {
1263                                 p_err("map type already specified");
1264                                 return -1;
1265                         }
1266
1267                         attr.map_type = map_type_from_str(*argv);
1268                         if ((int)attr.map_type < 0) {
1269                                 p_err("unrecognized map type: %s", *argv);
1270                                 return -1;
1271                         }
1272                         NEXT_ARG();
1273                 } else if (is_prefix(*argv, "name")) {
1274                         NEXT_ARG();
1275                         attr.name = GET_ARG();
1276                 } else if (is_prefix(*argv, "key")) {
1277                         if (parse_u32_arg(&argc, &argv, &attr.key_size,
1278                                           "key size"))
1279                                 return -1;
1280                 } else if (is_prefix(*argv, "value")) {
1281                         if (parse_u32_arg(&argc, &argv, &attr.value_size,
1282                                           "value size"))
1283                                 return -1;
1284                 } else if (is_prefix(*argv, "entries")) {
1285                         if (parse_u32_arg(&argc, &argv, &attr.max_entries,
1286                                           "max entries"))
1287                                 return -1;
1288                 } else if (is_prefix(*argv, "flags")) {
1289                         if (parse_u32_arg(&argc, &argv, &attr.map_flags,
1290                                           "flags"))
1291                                 return -1;
1292                 } else if (is_prefix(*argv, "dev")) {
1293                         NEXT_ARG();
1294
1295                         if (attr.map_ifindex) {
1296                                 p_err("offload device already specified");
1297                                 return -1;
1298                         }
1299
1300                         attr.map_ifindex = if_nametoindex(*argv);
1301                         if (!attr.map_ifindex) {
1302                                 p_err("unrecognized netdevice '%s': %s",
1303                                       *argv, strerror(errno));
1304                                 return -1;
1305                         }
1306                         NEXT_ARG();
1307                 } else {
1308                         p_err("unknown arg %s", *argv);
1309                         return -1;
1310                 }
1311         }
1312
1313         if (!attr.name) {
1314                 p_err("map name not specified");
1315                 return -1;
1316         }
1317
1318         set_max_rlimit();
1319
1320         fd = bpf_create_map_xattr(&attr);
1321         if (fd < 0) {
1322                 p_err("map create failed: %s", strerror(errno));
1323                 return -1;
1324         }
1325
1326         err = do_pin_fd(fd, pinfile);
1327         close(fd);
1328         if (err)
1329                 return err;
1330
1331         if (json_output)
1332                 jsonw_null(json_wtr);
1333         return 0;
1334 }
1335
1336 static int do_pop_dequeue(int argc, char **argv)
1337 {
1338         struct bpf_map_info info = {};
1339         __u32 len = sizeof(info);
1340         void *key, *value;
1341         int err;
1342         int fd;
1343
1344         if (argc < 2)
1345                 usage();
1346
1347         fd = map_parse_fd_and_info(&argc, &argv, &info, &len);
1348         if (fd < 0)
1349                 return -1;
1350
1351         err = alloc_key_value(&info, &key, &value);
1352         if (err)
1353                 goto exit_free;
1354
1355         err = bpf_map_lookup_and_delete_elem(fd, key, value);
1356         if (err) {
1357                 if (errno == ENOENT) {
1358                         if (json_output)
1359                                 jsonw_null(json_wtr);
1360                         else
1361                                 printf("Error: empty map\n");
1362                 } else {
1363                         p_err("pop failed: %s", strerror(errno));
1364                 }
1365
1366                 goto exit_free;
1367         }
1368
1369         print_key_value(&info, key, value);
1370
1371 exit_free:
1372         free(key);
1373         free(value);
1374         close(fd);
1375
1376         return err;
1377 }
1378
1379 static int do_freeze(int argc, char **argv)
1380 {
1381         int err, fd;
1382
1383         if (!REQ_ARGS(2))
1384                 return -1;
1385
1386         fd = map_parse_fd(&argc, &argv);
1387         if (fd < 0)
1388                 return -1;
1389
1390         if (argc) {
1391                 close(fd);
1392                 return BAD_ARG();
1393         }
1394
1395         err = bpf_map_freeze(fd);
1396         close(fd);
1397         if (err) {
1398                 p_err("failed to freeze map: %s", strerror(errno));
1399                 return err;
1400         }
1401
1402         if (json_output)
1403                 jsonw_null(json_wtr);
1404
1405         return 0;
1406 }
1407
1408 static int do_help(int argc, char **argv)
1409 {
1410         if (json_output) {
1411                 jsonw_null(json_wtr);
1412                 return 0;
1413         }
1414
1415         fprintf(stderr,
1416                 "Usage: %1$s %2$s { show | list }   [MAP]\n"
1417                 "       %1$s %2$s create     FILE type TYPE key KEY_SIZE value VALUE_SIZE \\\n"
1418                 "                                  entries MAX_ENTRIES name NAME [flags FLAGS] \\\n"
1419                 "                                  [dev NAME]\n"
1420                 "       %1$s %2$s dump       MAP\n"
1421                 "       %1$s %2$s update     MAP [key DATA] [value VALUE] [UPDATE_FLAGS]\n"
1422                 "       %1$s %2$s lookup     MAP [key DATA]\n"
1423                 "       %1$s %2$s getnext    MAP [key DATA]\n"
1424                 "       %1$s %2$s delete     MAP  key DATA\n"
1425                 "       %1$s %2$s pin        MAP  FILE\n"
1426                 "       %1$s %2$s event_pipe MAP [cpu N index M]\n"
1427                 "       %1$s %2$s peek       MAP\n"
1428                 "       %1$s %2$s push       MAP value VALUE\n"
1429                 "       %1$s %2$s pop        MAP\n"
1430                 "       %1$s %2$s enqueue    MAP value VALUE\n"
1431                 "       %1$s %2$s dequeue    MAP\n"
1432                 "       %1$s %2$s freeze     MAP\n"
1433                 "       %1$s %2$s help\n"
1434                 "\n"
1435                 "       " HELP_SPEC_MAP "\n"
1436                 "       DATA := { [hex] BYTES }\n"
1437                 "       " HELP_SPEC_PROGRAM "\n"
1438                 "       VALUE := { DATA | MAP | PROG }\n"
1439                 "       UPDATE_FLAGS := { any | exist | noexist }\n"
1440                 "       TYPE := { hash | array | prog_array | perf_event_array | percpu_hash |\n"
1441                 "                 percpu_array | stack_trace | cgroup_array | lru_hash |\n"
1442                 "                 lru_percpu_hash | lpm_trie | array_of_maps | hash_of_maps |\n"
1443                 "                 devmap | devmap_hash | sockmap | cpumap | xskmap | sockhash |\n"
1444                 "                 cgroup_storage | reuseport_sockarray | percpu_cgroup_storage |\n"
1445                 "                 queue | stack | sk_storage | struct_ops | ringbuf }\n"
1446                 "       " HELP_SPEC_OPTIONS "\n"
1447                 "",
1448                 bin_name, argv[-2]);
1449
1450         return 0;
1451 }
1452
1453 static const struct cmd cmds[] = {
1454         { "show",       do_show },
1455         { "list",       do_show },
1456         { "help",       do_help },
1457         { "dump",       do_dump },
1458         { "update",     do_update },
1459         { "lookup",     do_lookup },
1460         { "getnext",    do_getnext },
1461         { "delete",     do_delete },
1462         { "pin",        do_pin },
1463         { "event_pipe", do_event_pipe },
1464         { "create",     do_create },
1465         { "peek",       do_lookup },
1466         { "push",       do_update },
1467         { "enqueue",    do_update },
1468         { "pop",        do_pop_dequeue },
1469         { "dequeue",    do_pop_dequeue },
1470         { "freeze",     do_freeze },
1471         { 0 }
1472 };
1473
1474 int do_map(int argc, char **argv)
1475 {
1476         return cmd_select(cmds, argc, argv, do_help);
1477 }