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