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