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