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