bpftool: Use libbpf_bpf_map_type_str

This change switches bpftool over to using the recently introduced
libbpf_bpf_map_type_str function instead of maintaining its own string
representation for the bpf_map_type enum.

Signed-off-by: Daniel Müller <deso@posteo.net>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Quentin Monnet <quentin@isovalent.com>
Link: https://lore.kernel.org/bpf/20220523230428.3077108-7-deso@posteo.net
This commit is contained in:
Daniel Müller 2022-05-23 23:04:22 +00:00 committed by Andrii Nakryiko
parent c3a2574011
commit 2e98964bd6
4 changed files with 71 additions and 79 deletions

View File

@ -615,8 +615,8 @@ static bool probe_map_type_ifindex(enum bpf_map_type map_type, __u32 ifindex)
}
static void
probe_map_type(enum bpf_map_type map_type, const char *define_prefix,
__u32 ifindex)
probe_map_type(enum bpf_map_type map_type, char const *map_type_str,
const char *define_prefix, __u32 ifindex)
{
char feat_name[128], plain_desc[128], define_name[128];
const char *plain_comment = "eBPF map_type ";
@ -641,20 +641,16 @@ probe_map_type(enum bpf_map_type map_type, const char *define_prefix,
* check required for unprivileged users
*/
if (!map_type_name[map_type]) {
p_info("map type name not found (type %d)", map_type);
return;
}
maxlen = sizeof(plain_desc) - strlen(plain_comment) - 1;
if (strlen(map_type_name[map_type]) > maxlen) {
if (strlen(map_type_str) > maxlen) {
p_info("map type name too long");
return;
}
sprintf(feat_name, "have_%s_map_type", map_type_name[map_type]);
sprintf(define_name, "%s_map_type", map_type_name[map_type]);
sprintf(feat_name, "have_%s_map_type", map_type_str);
sprintf(define_name, "%s_map_type", map_type_str);
uppercase(define_name, sizeof(define_name));
sprintf(plain_desc, "%s%s", plain_comment, map_type_name[map_type]);
sprintf(plain_desc, "%s%s", plain_comment, map_type_str);
print_bool_feature(feat_name, plain_desc, define_name, res,
define_prefix);
}
@ -963,15 +959,23 @@ section_program_types(bool *supported_types, const char *define_prefix,
static void section_map_types(const char *define_prefix, __u32 ifindex)
{
unsigned int i;
unsigned int map_type = BPF_MAP_TYPE_UNSPEC;
const char *map_type_str;
print_start_section("map_types",
"Scanning eBPF map types...",
"/*** eBPF map types ***/",
define_prefix);
for (i = BPF_MAP_TYPE_UNSPEC + 1; i < map_type_name_size; i++)
probe_map_type(i, define_prefix, ifindex);
while (true) {
map_type++;
map_type_str = libbpf_bpf_map_type_str(map_type);
/* libbpf will return NULL for variants unknown to it. */
if (!map_type_str)
break;
probe_map_type(map_type, map_type_str, define_prefix, ifindex);
}
print_end_section();
}

View File

@ -65,9 +65,6 @@ static inline void *u64_to_ptr(__u64 ptr)
extern const char * const attach_type_name[__MAX_BPF_ATTACH_TYPE];
extern const char * const map_type_name[];
extern const size_t map_type_name_size;
/* keep in sync with the definition in skeleton/pid_iter.bpf.c */
enum bpf_obj_type {
BPF_OBJ_UNKNOWN,

View File

@ -22,42 +22,6 @@
#include "json_writer.h"
#include "main.h"
const char * const map_type_name[] = {
[BPF_MAP_TYPE_UNSPEC] = "unspec",
[BPF_MAP_TYPE_HASH] = "hash",
[BPF_MAP_TYPE_ARRAY] = "array",
[BPF_MAP_TYPE_PROG_ARRAY] = "prog_array",
[BPF_MAP_TYPE_PERF_EVENT_ARRAY] = "perf_event_array",
[BPF_MAP_TYPE_PERCPU_HASH] = "percpu_hash",
[BPF_MAP_TYPE_PERCPU_ARRAY] = "percpu_array",
[BPF_MAP_TYPE_STACK_TRACE] = "stack_trace",
[BPF_MAP_TYPE_CGROUP_ARRAY] = "cgroup_array",
[BPF_MAP_TYPE_LRU_HASH] = "lru_hash",
[BPF_MAP_TYPE_LRU_PERCPU_HASH] = "lru_percpu_hash",
[BPF_MAP_TYPE_LPM_TRIE] = "lpm_trie",
[BPF_MAP_TYPE_ARRAY_OF_MAPS] = "array_of_maps",
[BPF_MAP_TYPE_HASH_OF_MAPS] = "hash_of_maps",
[BPF_MAP_TYPE_DEVMAP] = "devmap",
[BPF_MAP_TYPE_DEVMAP_HASH] = "devmap_hash",
[BPF_MAP_TYPE_SOCKMAP] = "sockmap",
[BPF_MAP_TYPE_CPUMAP] = "cpumap",
[BPF_MAP_TYPE_XSKMAP] = "xskmap",
[BPF_MAP_TYPE_SOCKHASH] = "sockhash",
[BPF_MAP_TYPE_CGROUP_STORAGE] = "cgroup_storage",
[BPF_MAP_TYPE_REUSEPORT_SOCKARRAY] = "reuseport_sockarray",
[BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE] = "percpu_cgroup_storage",
[BPF_MAP_TYPE_QUEUE] = "queue",
[BPF_MAP_TYPE_STACK] = "stack",
[BPF_MAP_TYPE_SK_STORAGE] = "sk_storage",
[BPF_MAP_TYPE_STRUCT_OPS] = "struct_ops",
[BPF_MAP_TYPE_RINGBUF] = "ringbuf",
[BPF_MAP_TYPE_INODE_STORAGE] = "inode_storage",
[BPF_MAP_TYPE_TASK_STORAGE] = "task_storage",
[BPF_MAP_TYPE_BLOOM_FILTER] = "bloom_filter",
};
const size_t map_type_name_size = ARRAY_SIZE(map_type_name);
static struct hashmap *map_table;
static bool map_is_per_cpu(__u32 type)
@ -81,12 +45,18 @@ static bool map_is_map_of_progs(__u32 type)
static int map_type_from_str(const char *type)
{
const char *map_type_str;
unsigned int i;
for (i = 0; i < ARRAY_SIZE(map_type_name); i++)
for (i = 0; ; i++) {
map_type_str = libbpf_bpf_map_type_str(i);
if (!map_type_str)
break;
/* Don't allow prefixing in case of possible future shadowing */
if (map_type_name[i] && !strcmp(map_type_name[i], type))
if (!strcmp(map_type_str, type))
return i;
}
return -1;
}
@ -472,9 +442,12 @@ static int parse_elem(char **argv, struct bpf_map_info *info,
static void show_map_header_json(struct bpf_map_info *info, json_writer_t *wtr)
{
const char *map_type_str;
jsonw_uint_field(wtr, "id", info->id);
if (info->type < ARRAY_SIZE(map_type_name))
jsonw_string_field(wtr, "type", map_type_name[info->type]);
map_type_str = libbpf_bpf_map_type_str(info->type);
if (map_type_str)
jsonw_string_field(wtr, "type", map_type_str);
else
jsonw_uint_field(wtr, "type", info->type);
@ -561,9 +534,13 @@ static int show_map_close_json(int fd, struct bpf_map_info *info)
static void show_map_header_plain(struct bpf_map_info *info)
{
const char *map_type_str;
printf("%u: ", info->id);
if (info->type < ARRAY_SIZE(map_type_name))
printf("%s ", map_type_name[info->type]);
map_type_str = libbpf_bpf_map_type_str(info->type);
if (map_type_str)
printf("%s ", map_type_str);
else
printf("type %u ", info->type);
@ -879,9 +856,13 @@ map_dump(int fd, struct bpf_map_info *info, json_writer_t *wtr,
}
if (info->type == BPF_MAP_TYPE_REUSEPORT_SOCKARRAY &&
info->value_size != 8)
info->value_size != 8) {
const char *map_type_str;
map_type_str = libbpf_bpf_map_type_str(info->type);
p_info("Warning: cannot read values from %s map with value_size != 8",
map_type_name[info->type]);
map_type_str);
}
while (true) {
err = bpf_map_get_next_key(fd, prev_key, key);
if (err) {

View File

@ -186,6 +186,27 @@ class FileExtractor(object):
parser.search_block(start_marker)
return parser.parse(pattern, end_marker)
def make_enum_map(self, names, enum_prefix):
"""
Search for and parse an enum containing BPF_* members, just as get_enum
does. However, instead of just returning a set of the variant names,
also generate a textual representation from them by (assuming and)
removing a provided prefix and lowercasing the remainder. Then return a
dict mapping from name to textual representation.
@enum_values: a set of enum values; e.g., as retrieved by get_enum
@enum_prefix: the prefix to remove from each of the variants to infer
textual representation
"""
mapping = {}
for name in names:
if not name.startswith(enum_prefix):
raise Exception(f"enum variant {name} does not start with {enum_prefix}")
text = name[len(enum_prefix):].lower()
mapping[name] = text
return mapping
def __get_description_list(self, start_marker, pattern, end_marker):
parser = InlineListParser(self.reader)
parser.search_block(start_marker)
@ -345,9 +366,6 @@ class MapFileExtractor(SourceFileExtractor):
"""
filename = os.path.join(BPFTOOL_DIR, 'map.c')
def get_map_types(self):
return self.get_types_from_array('map_type_name')
def get_map_help(self):
return self.get_help_list('TYPE')
@ -403,8 +421,9 @@ class BpfHeaderExtractor(FileExtractor):
def get_prog_types(self):
return self.get_enum('bpf_prog_type')
def get_map_types(self):
return self.get_enum('bpf_map_type')
def get_map_type_map(self):
names = self.get_enum('bpf_map_type')
return self.make_enum_map(names, 'BPF_MAP_TYPE_')
def get_attach_types(self):
return self.get_enum('bpf_attach_type')
@ -492,21 +511,12 @@ def main():
""")
args = argParser.parse_args()
# Map types (enum)
bpf_info = BpfHeaderExtractor()
ref = bpf_info.get_map_types()
map_info = MapFileExtractor()
source_map_items = map_info.get_map_types()
map_types_enum = set(source_map_items.keys())
verify(ref, map_types_enum,
f'Comparing BPF header (enum bpf_map_type) and {MapFileExtractor.filename} (map_type_name):')
# Map types (names)
source_map_types = set(source_map_items.values())
map_info = MapFileExtractor()
source_map_types = set(bpf_info.get_map_type_map().values())
source_map_types.discard('unspec')
help_map_types = map_info.get_map_help()
@ -522,13 +532,13 @@ def main():
bashcomp_map_types = bashcomp_info.get_map_types()
verify(source_map_types, help_map_types,
f'Comparing {MapFileExtractor.filename} (map_type_name) and {MapFileExtractor.filename} (do_help() TYPE):')
f'Comparing {BpfHeaderExtractor.filename} (bpf_map_type) and {MapFileExtractor.filename} (do_help() TYPE):')
verify(source_map_types, man_map_types,
f'Comparing {MapFileExtractor.filename} (map_type_name) and {ManMapExtractor.filename} (TYPE):')
f'Comparing {BpfHeaderExtractor.filename} (bpf_map_type) and {ManMapExtractor.filename} (TYPE):')
verify(help_map_options, man_map_options,
f'Comparing {MapFileExtractor.filename} (do_help() OPTIONS) and {ManMapExtractor.filename} (OPTIONS):')
verify(source_map_types, bashcomp_map_types,
f'Comparing {MapFileExtractor.filename} (map_type_name) and {BashcompExtractor.filename} (BPFTOOL_MAP_CREATE_TYPES):')
f'Comparing {BpfHeaderExtractor.filename} (bpf_map_type) and {BashcompExtractor.filename} (BPFTOOL_MAP_CREATE_TYPES):')
# Attach types (enum)