Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
[linux-2.6-block.git] / tools / bpf / bpftool / map.c
1 /*
2  * Copyright (C) 2017-2018 Netronome Systems, Inc.
3  *
4  * This software is dual licensed under the GNU General License Version 2,
5  * June 1991 as shown in the file COPYING in the top-level directory of this
6  * source tree or the BSD 2-Clause License provided below.  You have the
7  * option to license this software under the complete terms of either license.
8  *
9  * The BSD 2-Clause License:
10  *
11  *     Redistribution and use in source and binary forms, with or
12  *     without modification, are permitted provided that the following
13  *     conditions are met:
14  *
15  *      1. Redistributions of source code must retain the above
16  *         copyright notice, this list of conditions and the following
17  *         disclaimer.
18  *
19  *      2. Redistributions in binary form must reproduce the above
20  *         copyright notice, this list of conditions and the following
21  *         disclaimer in the documentation and/or other materials
22  *         provided with the distribution.
23  *
24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31  * SOFTWARE.
32  */
33
34 #include <assert.h>
35 #include <errno.h>
36 #include <fcntl.h>
37 #include <linux/err.h>
38 #include <linux/kernel.h>
39 #include <stdbool.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <unistd.h>
44 #include <sys/types.h>
45 #include <sys/stat.h>
46
47 #include <bpf.h>
48
49 #include "btf.h"
50 #include "json_writer.h"
51 #include "main.h"
52
53 static const char * const map_type_name[] = {
54         [BPF_MAP_TYPE_UNSPEC]           = "unspec",
55         [BPF_MAP_TYPE_HASH]             = "hash",
56         [BPF_MAP_TYPE_ARRAY]            = "array",
57         [BPF_MAP_TYPE_PROG_ARRAY]       = "prog_array",
58         [BPF_MAP_TYPE_PERF_EVENT_ARRAY] = "perf_event_array",
59         [BPF_MAP_TYPE_PERCPU_HASH]      = "percpu_hash",
60         [BPF_MAP_TYPE_PERCPU_ARRAY]     = "percpu_array",
61         [BPF_MAP_TYPE_STACK_TRACE]      = "stack_trace",
62         [BPF_MAP_TYPE_CGROUP_ARRAY]     = "cgroup_array",
63         [BPF_MAP_TYPE_LRU_HASH]         = "lru_hash",
64         [BPF_MAP_TYPE_LRU_PERCPU_HASH]  = "lru_percpu_hash",
65         [BPF_MAP_TYPE_LPM_TRIE]         = "lpm_trie",
66         [BPF_MAP_TYPE_ARRAY_OF_MAPS]    = "array_of_maps",
67         [BPF_MAP_TYPE_HASH_OF_MAPS]     = "hash_of_maps",
68         [BPF_MAP_TYPE_DEVMAP]           = "devmap",
69         [BPF_MAP_TYPE_SOCKMAP]          = "sockmap",
70         [BPF_MAP_TYPE_CPUMAP]           = "cpumap",
71         [BPF_MAP_TYPE_SOCKHASH]         = "sockhash",
72         [BPF_MAP_TYPE_CGROUP_STORAGE]   = "cgroup_storage",
73 };
74
75 static bool map_is_per_cpu(__u32 type)
76 {
77         return type == BPF_MAP_TYPE_PERCPU_HASH ||
78                type == BPF_MAP_TYPE_PERCPU_ARRAY ||
79                type == BPF_MAP_TYPE_LRU_PERCPU_HASH;
80 }
81
82 static bool map_is_map_of_maps(__u32 type)
83 {
84         return type == BPF_MAP_TYPE_ARRAY_OF_MAPS ||
85                type == BPF_MAP_TYPE_HASH_OF_MAPS;
86 }
87
88 static bool map_is_map_of_progs(__u32 type)
89 {
90         return type == BPF_MAP_TYPE_PROG_ARRAY;
91 }
92
93 static void *alloc_value(struct bpf_map_info *info)
94 {
95         if (map_is_per_cpu(info->type))
96                 return malloc(round_up(info->value_size, 8) *
97                               get_possible_cpus());
98         else
99                 return malloc(info->value_size);
100 }
101
102 int map_parse_fd(int *argc, char ***argv)
103 {
104         int fd;
105
106         if (is_prefix(**argv, "id")) {
107                 unsigned int id;
108                 char *endptr;
109
110                 NEXT_ARGP();
111
112                 id = strtoul(**argv, &endptr, 0);
113                 if (*endptr) {
114                         p_err("can't parse %s as ID", **argv);
115                         return -1;
116                 }
117                 NEXT_ARGP();
118
119                 fd = bpf_map_get_fd_by_id(id);
120                 if (fd < 0)
121                         p_err("get map by id (%u): %s", id, strerror(errno));
122                 return fd;
123         } else if (is_prefix(**argv, "pinned")) {
124                 char *path;
125
126                 NEXT_ARGP();
127
128                 path = **argv;
129                 NEXT_ARGP();
130
131                 return open_obj_pinned_any(path, BPF_OBJ_MAP);
132         }
133
134         p_err("expected 'id' or 'pinned', got: '%s'?", **argv);
135         return -1;
136 }
137
138 int map_parse_fd_and_info(int *argc, char ***argv, void *info, __u32 *info_len)
139 {
140         int err;
141         int fd;
142
143         fd = map_parse_fd(argc, argv);
144         if (fd < 0)
145                 return -1;
146
147         err = bpf_obj_get_info_by_fd(fd, info, info_len);
148         if (err) {
149                 p_err("can't get map info: %s", strerror(errno));
150                 close(fd);
151                 return err;
152         }
153
154         return fd;
155 }
156
157 static int do_dump_btf(const struct btf_dumper *d,
158                        struct bpf_map_info *map_info, void *key,
159                        void *value)
160 {
161         int ret;
162
163         /* start of key-value pair */
164         jsonw_start_object(d->jw);
165
166         jsonw_name(d->jw, "key");
167
168         ret = btf_dumper_type(d, map_info->btf_key_type_id, key);
169         if (ret)
170                 goto err_end_obj;
171
172         jsonw_name(d->jw, "value");
173
174         ret = btf_dumper_type(d, map_info->btf_value_type_id, value);
175
176 err_end_obj:
177         /* end of key-value pair */
178         jsonw_end_object(d->jw);
179
180         return ret;
181 }
182
183 static int get_btf(struct bpf_map_info *map_info, struct btf **btf)
184 {
185         struct bpf_btf_info btf_info = { 0 };
186         __u32 len = sizeof(btf_info);
187         __u32 last_size;
188         int btf_fd;
189         void *ptr;
190         int err;
191
192         err = 0;
193         *btf = NULL;
194         btf_fd = bpf_btf_get_fd_by_id(map_info->btf_id);
195         if (btf_fd < 0)
196                 return 0;
197
198         /* we won't know btf_size until we call bpf_obj_get_info_by_fd(). so
199          * let's start with a sane default - 4KiB here - and resize it only if
200          * bpf_obj_get_info_by_fd() needs a bigger buffer.
201          */
202         btf_info.btf_size = 4096;
203         last_size = btf_info.btf_size;
204         ptr = malloc(last_size);
205         if (!ptr) {
206                 err = -ENOMEM;
207                 goto exit_free;
208         }
209
210         bzero(ptr, last_size);
211         btf_info.btf = ptr_to_u64(ptr);
212         err = bpf_obj_get_info_by_fd(btf_fd, &btf_info, &len);
213
214         if (!err && btf_info.btf_size > last_size) {
215                 void *temp_ptr;
216
217                 last_size = btf_info.btf_size;
218                 temp_ptr = realloc(ptr, last_size);
219                 if (!temp_ptr) {
220                         err = -ENOMEM;
221                         goto exit_free;
222                 }
223                 ptr = temp_ptr;
224                 bzero(ptr, last_size);
225                 btf_info.btf = ptr_to_u64(ptr);
226                 err = bpf_obj_get_info_by_fd(btf_fd, &btf_info, &len);
227         }
228
229         if (err || btf_info.btf_size > last_size) {
230                 err = errno;
231                 goto exit_free;
232         }
233
234         *btf = btf__new((__u8 *)btf_info.btf, btf_info.btf_size, NULL);
235         if (IS_ERR(*btf)) {
236                 err = PTR_ERR(*btf);
237                 *btf = NULL;
238         }
239
240 exit_free:
241         close(btf_fd);
242         free(ptr);
243
244         return err;
245 }
246
247 static json_writer_t *get_btf_writer(void)
248 {
249         json_writer_t *jw = jsonw_new(stdout);
250
251         if (!jw)
252                 return NULL;
253         jsonw_pretty(jw, true);
254
255         return jw;
256 }
257
258 static void print_entry_json(struct bpf_map_info *info, unsigned char *key,
259                              unsigned char *value, struct btf *btf)
260 {
261         jsonw_start_object(json_wtr);
262
263         if (!map_is_per_cpu(info->type)) {
264                 jsonw_name(json_wtr, "key");
265                 print_hex_data_json(key, info->key_size);
266                 jsonw_name(json_wtr, "value");
267                 print_hex_data_json(value, info->value_size);
268                 if (btf) {
269                         struct btf_dumper d = {
270                                 .btf = btf,
271                                 .jw = json_wtr,
272                                 .is_plain_text = false,
273                         };
274
275                         jsonw_name(json_wtr, "formatted");
276                         do_dump_btf(&d, info, key, value);
277                 }
278         } else {
279                 unsigned int i, n, step;
280
281                 n = get_possible_cpus();
282                 step = round_up(info->value_size, 8);
283
284                 jsonw_name(json_wtr, "key");
285                 print_hex_data_json(key, info->key_size);
286
287                 jsonw_name(json_wtr, "values");
288                 jsonw_start_array(json_wtr);
289                 for (i = 0; i < n; i++) {
290                         jsonw_start_object(json_wtr);
291
292                         jsonw_int_field(json_wtr, "cpu", i);
293
294                         jsonw_name(json_wtr, "value");
295                         print_hex_data_json(value + i * step,
296                                             info->value_size);
297
298                         jsonw_end_object(json_wtr);
299                 }
300                 jsonw_end_array(json_wtr);
301         }
302
303         jsonw_end_object(json_wtr);
304 }
305
306 static void print_entry_plain(struct bpf_map_info *info, unsigned char *key,
307                               unsigned char *value)
308 {
309         if (!map_is_per_cpu(info->type)) {
310                 bool single_line, break_names;
311
312                 break_names = info->key_size > 16 || info->value_size > 16;
313                 single_line = info->key_size + info->value_size <= 24 &&
314                         !break_names;
315
316                 printf("key:%c", break_names ? '\n' : ' ');
317                 fprint_hex(stdout, key, info->key_size, " ");
318
319                 printf(single_line ? "  " : "\n");
320
321                 printf("value:%c", break_names ? '\n' : ' ');
322                 fprint_hex(stdout, value, info->value_size, " ");
323
324                 printf("\n");
325         } else {
326                 unsigned int i, n, step;
327
328                 n = get_possible_cpus();
329                 step = round_up(info->value_size, 8);
330
331                 printf("key:\n");
332                 fprint_hex(stdout, key, info->key_size, " ");
333                 printf("\n");
334                 for (i = 0; i < n; i++) {
335                         printf("value (CPU %02d):%c",
336                                i, info->value_size > 16 ? '\n' : ' ');
337                         fprint_hex(stdout, value + i * step,
338                                    info->value_size, " ");
339                         printf("\n");
340                 }
341         }
342 }
343
344 static char **parse_bytes(char **argv, const char *name, unsigned char *val,
345                           unsigned int n)
346 {
347         unsigned int i = 0, base = 0;
348         char *endptr;
349
350         if (is_prefix(*argv, "hex")) {
351                 base = 16;
352                 argv++;
353         }
354
355         while (i < n && argv[i]) {
356                 val[i] = strtoul(argv[i], &endptr, base);
357                 if (*endptr) {
358                         p_err("error parsing byte: %s", argv[i]);
359                         return NULL;
360                 }
361                 i++;
362         }
363
364         if (i != n) {
365                 p_err("%s expected %d bytes got %d", name, n, i);
366                 return NULL;
367         }
368
369         return argv + i;
370 }
371
372 static int parse_elem(char **argv, struct bpf_map_info *info,
373                       void *key, void *value, __u32 key_size, __u32 value_size,
374                       __u32 *flags, __u32 **value_fd)
375 {
376         if (!*argv) {
377                 if (!key && !value)
378                         return 0;
379                 p_err("did not find %s", key ? "key" : "value");
380                 return -1;
381         }
382
383         if (is_prefix(*argv, "key")) {
384                 if (!key) {
385                         if (key_size)
386                                 p_err("duplicate key");
387                         else
388                                 p_err("unnecessary key");
389                         return -1;
390                 }
391
392                 argv = parse_bytes(argv + 1, "key", key, key_size);
393                 if (!argv)
394                         return -1;
395
396                 return parse_elem(argv, info, NULL, value, key_size, value_size,
397                                   flags, value_fd);
398         } else if (is_prefix(*argv, "value")) {
399                 int fd;
400
401                 if (!value) {
402                         if (value_size)
403                                 p_err("duplicate value");
404                         else
405                                 p_err("unnecessary value");
406                         return -1;
407                 }
408
409                 argv++;
410
411                 if (map_is_map_of_maps(info->type)) {
412                         int argc = 2;
413
414                         if (value_size != 4) {
415                                 p_err("value smaller than 4B for map in map?");
416                                 return -1;
417                         }
418                         if (!argv[0] || !argv[1]) {
419                                 p_err("not enough value arguments for map in map");
420                                 return -1;
421                         }
422
423                         fd = map_parse_fd(&argc, &argv);
424                         if (fd < 0)
425                                 return -1;
426
427                         *value_fd = value;
428                         **value_fd = fd;
429                 } else if (map_is_map_of_progs(info->type)) {
430                         int argc = 2;
431
432                         if (value_size != 4) {
433                                 p_err("value smaller than 4B for map of progs?");
434                                 return -1;
435                         }
436                         if (!argv[0] || !argv[1]) {
437                                 p_err("not enough value arguments for map of progs");
438                                 return -1;
439                         }
440
441                         fd = prog_parse_fd(&argc, &argv);
442                         if (fd < 0)
443                                 return -1;
444
445                         *value_fd = value;
446                         **value_fd = fd;
447                 } else {
448                         argv = parse_bytes(argv, "value", value, value_size);
449                         if (!argv)
450                                 return -1;
451                 }
452
453                 return parse_elem(argv, info, key, NULL, key_size, value_size,
454                                   flags, NULL);
455         } else if (is_prefix(*argv, "any") || is_prefix(*argv, "noexist") ||
456                    is_prefix(*argv, "exist")) {
457                 if (!flags) {
458                         p_err("flags specified multiple times: %s", *argv);
459                         return -1;
460                 }
461
462                 if (is_prefix(*argv, "any"))
463                         *flags = BPF_ANY;
464                 else if (is_prefix(*argv, "noexist"))
465                         *flags = BPF_NOEXIST;
466                 else if (is_prefix(*argv, "exist"))
467                         *flags = BPF_EXIST;
468
469                 return parse_elem(argv + 1, info, key, value, key_size,
470                                   value_size, NULL, value_fd);
471         }
472
473         p_err("expected key or value, got: %s", *argv);
474         return -1;
475 }
476
477 static int show_map_close_json(int fd, struct bpf_map_info *info)
478 {
479         char *memlock;
480
481         memlock = get_fdinfo(fd, "memlock");
482         close(fd);
483
484         jsonw_start_object(json_wtr);
485
486         jsonw_uint_field(json_wtr, "id", info->id);
487         if (info->type < ARRAY_SIZE(map_type_name))
488                 jsonw_string_field(json_wtr, "type",
489                                    map_type_name[info->type]);
490         else
491                 jsonw_uint_field(json_wtr, "type", info->type);
492
493         if (*info->name)
494                 jsonw_string_field(json_wtr, "name", info->name);
495
496         jsonw_name(json_wtr, "flags");
497         jsonw_printf(json_wtr, "%d", info->map_flags);
498
499         print_dev_json(info->ifindex, info->netns_dev, info->netns_ino);
500
501         jsonw_uint_field(json_wtr, "bytes_key", info->key_size);
502         jsonw_uint_field(json_wtr, "bytes_value", info->value_size);
503         jsonw_uint_field(json_wtr, "max_entries", info->max_entries);
504
505         if (memlock)
506                 jsonw_int_field(json_wtr, "bytes_memlock", atoi(memlock));
507         free(memlock);
508
509         if (!hash_empty(map_table.table)) {
510                 struct pinned_obj *obj;
511
512                 jsonw_name(json_wtr, "pinned");
513                 jsonw_start_array(json_wtr);
514                 hash_for_each_possible(map_table.table, obj, hash, info->id) {
515                         if (obj->id == info->id)
516                                 jsonw_string(json_wtr, obj->path);
517                 }
518                 jsonw_end_array(json_wtr);
519         }
520
521         jsonw_end_object(json_wtr);
522
523         return 0;
524 }
525
526 static int show_map_close_plain(int fd, struct bpf_map_info *info)
527 {
528         char *memlock;
529
530         memlock = get_fdinfo(fd, "memlock");
531         close(fd);
532
533         printf("%u: ", info->id);
534         if (info->type < ARRAY_SIZE(map_type_name))
535                 printf("%s  ", map_type_name[info->type]);
536         else
537                 printf("type %u  ", info->type);
538
539         if (*info->name)
540                 printf("name %s  ", info->name);
541
542         printf("flags 0x%x", info->map_flags);
543         print_dev_plain(info->ifindex, info->netns_dev, info->netns_ino);
544         printf("\n");
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         printf("\n");
553         if (!hash_empty(map_table.table)) {
554                 struct pinned_obj *obj;
555
556                 hash_for_each_possible(map_table.table, obj, hash, info->id) {
557                         if (obj->id == info->id)
558                                 printf("\tpinned %s\n", obj->path);
559                 }
560         }
561         return 0;
562 }
563
564 static int do_show(int argc, char **argv)
565 {
566         struct bpf_map_info info = {};
567         __u32 len = sizeof(info);
568         __u32 id = 0;
569         int err;
570         int fd;
571
572         if (show_pinned)
573                 build_pinned_obj_table(&map_table, BPF_OBJ_MAP);
574
575         if (argc == 2) {
576                 fd = map_parse_fd_and_info(&argc, &argv, &info, &len);
577                 if (fd < 0)
578                         return -1;
579
580                 if (json_output)
581                         return show_map_close_json(fd, &info);
582                 else
583                         return show_map_close_plain(fd, &info);
584         }
585
586         if (argc)
587                 return BAD_ARG();
588
589         if (json_output)
590                 jsonw_start_array(json_wtr);
591         while (true) {
592                 err = bpf_map_get_next_id(id, &id);
593                 if (err) {
594                         if (errno == ENOENT)
595                                 break;
596                         p_err("can't get next map: %s%s", strerror(errno),
597                               errno == EINVAL ? " -- kernel too old?" : "");
598                         break;
599                 }
600
601                 fd = bpf_map_get_fd_by_id(id);
602                 if (fd < 0) {
603                         if (errno == ENOENT)
604                                 continue;
605                         p_err("can't get map by id (%u): %s",
606                               id, strerror(errno));
607                         break;
608                 }
609
610                 err = bpf_obj_get_info_by_fd(fd, &info, &len);
611                 if (err) {
612                         p_err("can't get map info: %s", strerror(errno));
613                         close(fd);
614                         break;
615                 }
616
617                 if (json_output)
618                         show_map_close_json(fd, &info);
619                 else
620                         show_map_close_plain(fd, &info);
621         }
622         if (json_output)
623                 jsonw_end_array(json_wtr);
624
625         return errno == ENOENT ? 0 : -1;
626 }
627
628 static int do_dump(int argc, char **argv)
629 {
630         struct bpf_map_info info = {};
631         void *key, *value, *prev_key;
632         unsigned int num_elems = 0;
633         __u32 len = sizeof(info);
634         json_writer_t *btf_wtr;
635         struct btf *btf = NULL;
636         int err;
637         int fd;
638
639         if (argc != 2)
640                 usage();
641
642         fd = map_parse_fd_and_info(&argc, &argv, &info, &len);
643         if (fd < 0)
644                 return -1;
645
646         if (map_is_map_of_maps(info.type) || map_is_map_of_progs(info.type)) {
647                 p_err("Dumping maps of maps and program maps not supported");
648                 close(fd);
649                 return -1;
650         }
651
652         key = malloc(info.key_size);
653         value = alloc_value(&info);
654         if (!key || !value) {
655                 p_err("mem alloc failed");
656                 err = -1;
657                 goto exit_free;
658         }
659
660         prev_key = NULL;
661
662         err = get_btf(&info, &btf);
663         if (err) {
664                 p_err("failed to get btf");
665                 goto exit_free;
666         }
667
668         if (json_output)
669                 jsonw_start_array(json_wtr);
670         else
671                 if (btf) {
672                         btf_wtr = get_btf_writer();
673                         if (!btf_wtr) {
674                                 p_info("failed to create json writer for btf. falling back to plain output");
675                                 btf__free(btf);
676                                 btf = NULL;
677                         } else {
678                                 jsonw_start_array(btf_wtr);
679                         }
680                 }
681
682         while (true) {
683                 err = bpf_map_get_next_key(fd, prev_key, key);
684                 if (err) {
685                         if (errno == ENOENT)
686                                 err = 0;
687                         break;
688                 }
689
690                 if (!bpf_map_lookup_elem(fd, key, value)) {
691                         if (json_output)
692                                 print_entry_json(&info, key, value, btf);
693                         else
694                                 if (btf) {
695                                         struct btf_dumper d = {
696                                                 .btf = btf,
697                                                 .jw = btf_wtr,
698                                                 .is_plain_text = true,
699                                         };
700
701                                         do_dump_btf(&d, &info, key, value);
702                                 } else {
703                                         print_entry_plain(&info, key, value);
704                                 }
705                 } else {
706                         if (json_output) {
707                                 jsonw_name(json_wtr, "key");
708                                 print_hex_data_json(key, info.key_size);
709                                 jsonw_name(json_wtr, "value");
710                                 jsonw_start_object(json_wtr);
711                                 jsonw_string_field(json_wtr, "error",
712                                                    "can't lookup element");
713                                 jsonw_end_object(json_wtr);
714                         } else {
715                                 p_info("can't lookup element with key: ");
716                                 fprint_hex(stderr, key, info.key_size, " ");
717                                 fprintf(stderr, "\n");
718                         }
719                 }
720
721                 prev_key = key;
722                 num_elems++;
723         }
724
725         if (json_output)
726                 jsonw_end_array(json_wtr);
727         else if (btf) {
728                 jsonw_end_array(btf_wtr);
729                 jsonw_destroy(&btf_wtr);
730         } else {
731                 printf("Found %u element%s\n", num_elems,
732                        num_elems != 1 ? "s" : "");
733         }
734
735 exit_free:
736         free(key);
737         free(value);
738         close(fd);
739         btf__free(btf);
740
741         return err;
742 }
743
744 static int do_update(int argc, char **argv)
745 {
746         struct bpf_map_info info = {};
747         __u32 len = sizeof(info);
748         __u32 *value_fd = NULL;
749         __u32 flags = BPF_ANY;
750         void *key, *value;
751         int fd, err;
752
753         if (argc < 2)
754                 usage();
755
756         fd = map_parse_fd_and_info(&argc, &argv, &info, &len);
757         if (fd < 0)
758                 return -1;
759
760         key = malloc(info.key_size);
761         value = alloc_value(&info);
762         if (!key || !value) {
763                 p_err("mem alloc failed");
764                 err = -1;
765                 goto exit_free;
766         }
767
768         err = parse_elem(argv, &info, key, value, info.key_size,
769                          info.value_size, &flags, &value_fd);
770         if (err)
771                 goto exit_free;
772
773         err = bpf_map_update_elem(fd, key, value, flags);
774         if (err) {
775                 p_err("update failed: %s", strerror(errno));
776                 goto exit_free;
777         }
778
779 exit_free:
780         if (value_fd)
781                 close(*value_fd);
782         free(key);
783         free(value);
784         close(fd);
785
786         if (!err && json_output)
787                 jsonw_null(json_wtr);
788         return err;
789 }
790
791 static int do_lookup(int argc, char **argv)
792 {
793         struct bpf_map_info info = {};
794         __u32 len = sizeof(info);
795         json_writer_t *btf_wtr;
796         struct btf *btf = NULL;
797         void *key, *value;
798         int err;
799         int fd;
800
801         if (argc < 2)
802                 usage();
803
804         fd = map_parse_fd_and_info(&argc, &argv, &info, &len);
805         if (fd < 0)
806                 return -1;
807
808         key = malloc(info.key_size);
809         value = alloc_value(&info);
810         if (!key || !value) {
811                 p_err("mem alloc failed");
812                 err = -1;
813                 goto exit_free;
814         }
815
816         err = parse_elem(argv, &info, key, NULL, info.key_size, 0, NULL, NULL);
817         if (err)
818                 goto exit_free;
819
820         err = bpf_map_lookup_elem(fd, key, value);
821         if (err) {
822                 if (errno == ENOENT) {
823                         if (json_output) {
824                                 jsonw_null(json_wtr);
825                         } else {
826                                 printf("key:\n");
827                                 fprint_hex(stdout, key, info.key_size, " ");
828                                 printf("\n\nNot found\n");
829                         }
830                 } else {
831                         p_err("lookup failed: %s", strerror(errno));
832                 }
833
834                 goto exit_free;
835         }
836
837         /* here means bpf_map_lookup_elem() succeeded */
838         err = get_btf(&info, &btf);
839         if (err) {
840                 p_err("failed to get btf");
841                 goto exit_free;
842         }
843
844         if (json_output) {
845                 print_entry_json(&info, key, value, btf);
846         } else if (btf) {
847                 /* if here json_wtr wouldn't have been initialised,
848                  * so let's create separate writer for btf
849                  */
850                 btf_wtr = get_btf_writer();
851                 if (!btf_wtr) {
852                         p_info("failed to create json writer for btf. falling back to plain output");
853                         btf__free(btf);
854                         btf = NULL;
855                         print_entry_plain(&info, key, value);
856                 } else {
857                         struct btf_dumper d = {
858                                 .btf = btf,
859                                 .jw = btf_wtr,
860                                 .is_plain_text = true,
861                         };
862
863                         do_dump_btf(&d, &info, key, value);
864                         jsonw_destroy(&btf_wtr);
865                 }
866         } else {
867                 print_entry_plain(&info, key, value);
868         }
869
870 exit_free:
871         free(key);
872         free(value);
873         close(fd);
874         btf__free(btf);
875
876         return err;
877 }
878
879 static int do_getnext(int argc, char **argv)
880 {
881         struct bpf_map_info info = {};
882         __u32 len = sizeof(info);
883         void *key, *nextkey;
884         int err;
885         int fd;
886
887         if (argc < 2)
888                 usage();
889
890         fd = map_parse_fd_and_info(&argc, &argv, &info, &len);
891         if (fd < 0)
892                 return -1;
893
894         key = malloc(info.key_size);
895         nextkey = malloc(info.key_size);
896         if (!key || !nextkey) {
897                 p_err("mem alloc failed");
898                 err = -1;
899                 goto exit_free;
900         }
901
902         if (argc) {
903                 err = parse_elem(argv, &info, key, NULL, info.key_size, 0,
904                                  NULL, NULL);
905                 if (err)
906                         goto exit_free;
907         } else {
908                 free(key);
909                 key = NULL;
910         }
911
912         err = bpf_map_get_next_key(fd, key, nextkey);
913         if (err) {
914                 p_err("can't get next key: %s", strerror(errno));
915                 goto exit_free;
916         }
917
918         if (json_output) {
919                 jsonw_start_object(json_wtr);
920                 if (key) {
921                         jsonw_name(json_wtr, "key");
922                         print_hex_data_json(key, info.key_size);
923                 } else {
924                         jsonw_null_field(json_wtr, "key");
925                 }
926                 jsonw_name(json_wtr, "next_key");
927                 print_hex_data_json(nextkey, info.key_size);
928                 jsonw_end_object(json_wtr);
929         } else {
930                 if (key) {
931                         printf("key:\n");
932                         fprint_hex(stdout, key, info.key_size, " ");
933                         printf("\n");
934                 } else {
935                         printf("key: None\n");
936                 }
937                 printf("next key:\n");
938                 fprint_hex(stdout, nextkey, info.key_size, " ");
939                 printf("\n");
940         }
941
942 exit_free:
943         free(nextkey);
944         free(key);
945         close(fd);
946
947         return err;
948 }
949
950 static int do_delete(int argc, char **argv)
951 {
952         struct bpf_map_info info = {};
953         __u32 len = sizeof(info);
954         void *key;
955         int err;
956         int fd;
957
958         if (argc < 2)
959                 usage();
960
961         fd = map_parse_fd_and_info(&argc, &argv, &info, &len);
962         if (fd < 0)
963                 return -1;
964
965         key = malloc(info.key_size);
966         if (!key) {
967                 p_err("mem alloc failed");
968                 err = -1;
969                 goto exit_free;
970         }
971
972         err = parse_elem(argv, &info, key, NULL, info.key_size, 0, NULL, NULL);
973         if (err)
974                 goto exit_free;
975
976         err = bpf_map_delete_elem(fd, key);
977         if (err)
978                 p_err("delete failed: %s", strerror(errno));
979
980 exit_free:
981         free(key);
982         close(fd);
983
984         if (!err && json_output)
985                 jsonw_null(json_wtr);
986         return err;
987 }
988
989 static int do_pin(int argc, char **argv)
990 {
991         int err;
992
993         err = do_pin_any(argc, argv, bpf_map_get_fd_by_id);
994         if (!err && json_output)
995                 jsonw_null(json_wtr);
996         return err;
997 }
998
999 static int do_help(int argc, char **argv)
1000 {
1001         if (json_output) {
1002                 jsonw_null(json_wtr);
1003                 return 0;
1004         }
1005
1006         fprintf(stderr,
1007                 "Usage: %s %s { show | list }   [MAP]\n"
1008                 "       %s %s dump       MAP\n"
1009                 "       %s %s update     MAP  key DATA value VALUE [UPDATE_FLAGS]\n"
1010                 "       %s %s lookup     MAP  key DATA\n"
1011                 "       %s %s getnext    MAP [key DATA]\n"
1012                 "       %s %s delete     MAP  key DATA\n"
1013                 "       %s %s pin        MAP  FILE\n"
1014                 "       %s %s event_pipe MAP [cpu N index M]\n"
1015                 "       %s %s help\n"
1016                 "\n"
1017                 "       " HELP_SPEC_MAP "\n"
1018                 "       DATA := { [hex] BYTES }\n"
1019                 "       " HELP_SPEC_PROGRAM "\n"
1020                 "       VALUE := { DATA | MAP | PROG }\n"
1021                 "       UPDATE_FLAGS := { any | exist | noexist }\n"
1022                 "       " HELP_SPEC_OPTIONS "\n"
1023                 "",
1024                 bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2],
1025                 bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2],
1026                 bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2]);
1027
1028         return 0;
1029 }
1030
1031 static const struct cmd cmds[] = {
1032         { "show",       do_show },
1033         { "list",       do_show },
1034         { "help",       do_help },
1035         { "dump",       do_dump },
1036         { "update",     do_update },
1037         { "lookup",     do_lookup },
1038         { "getnext",    do_getnext },
1039         { "delete",     do_delete },
1040         { "pin",        do_pin },
1041         { "event_pipe", do_event_pipe },
1042         { 0 }
1043 };
1044
1045 int do_map(int argc, char **argv)
1046 {
1047         return cmd_select(cmds, argc, argv, do_help);
1048 }