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