162306a36Sopenharmony_ci// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci#include "util/bpf_map.h" 462306a36Sopenharmony_ci#include <bpf/bpf.h> 562306a36Sopenharmony_ci#include <bpf/libbpf.h> 662306a36Sopenharmony_ci#include <linux/err.h> 762306a36Sopenharmony_ci#include <linux/kernel.h> 862306a36Sopenharmony_ci#include <stdbool.h> 962306a36Sopenharmony_ci#include <stdlib.h> 1062306a36Sopenharmony_ci#include <unistd.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_cistatic bool bpf_map__is_per_cpu(enum bpf_map_type type) 1362306a36Sopenharmony_ci{ 1462306a36Sopenharmony_ci return type == BPF_MAP_TYPE_PERCPU_HASH || 1562306a36Sopenharmony_ci type == BPF_MAP_TYPE_PERCPU_ARRAY || 1662306a36Sopenharmony_ci type == BPF_MAP_TYPE_LRU_PERCPU_HASH || 1762306a36Sopenharmony_ci type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE; 1862306a36Sopenharmony_ci} 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_cistatic void *bpf_map__alloc_value(const struct bpf_map *map) 2162306a36Sopenharmony_ci{ 2262306a36Sopenharmony_ci if (bpf_map__is_per_cpu(bpf_map__type(map))) 2362306a36Sopenharmony_ci return malloc(round_up(bpf_map__value_size(map), 8) * 2462306a36Sopenharmony_ci sysconf(_SC_NPROCESSORS_CONF)); 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci return malloc(bpf_map__value_size(map)); 2762306a36Sopenharmony_ci} 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ciint bpf_map__fprintf(struct bpf_map *map, FILE *fp) 3062306a36Sopenharmony_ci{ 3162306a36Sopenharmony_ci void *prev_key = NULL, *key, *value; 3262306a36Sopenharmony_ci int fd = bpf_map__fd(map), err; 3362306a36Sopenharmony_ci int printed = 0; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci if (fd < 0) 3662306a36Sopenharmony_ci return fd; 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci if (!map) 3962306a36Sopenharmony_ci return PTR_ERR(map); 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci err = -ENOMEM; 4262306a36Sopenharmony_ci key = malloc(bpf_map__key_size(map)); 4362306a36Sopenharmony_ci if (key == NULL) 4462306a36Sopenharmony_ci goto out; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci value = bpf_map__alloc_value(map); 4762306a36Sopenharmony_ci if (value == NULL) 4862306a36Sopenharmony_ci goto out_free_key; 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci while ((err = bpf_map_get_next_key(fd, prev_key, key) == 0)) { 5162306a36Sopenharmony_ci int intkey = *(int *)key; 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci if (!bpf_map_lookup_elem(fd, key, value)) { 5462306a36Sopenharmony_ci bool boolval = *(bool *)value; 5562306a36Sopenharmony_ci if (boolval) 5662306a36Sopenharmony_ci printed += fprintf(fp, "[%d] = %d,\n", intkey, boolval); 5762306a36Sopenharmony_ci } else { 5862306a36Sopenharmony_ci printed += fprintf(fp, "[%d] = ERROR,\n", intkey); 5962306a36Sopenharmony_ci } 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci prev_key = key; 6262306a36Sopenharmony_ci } 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci if (err == ENOENT) 6562306a36Sopenharmony_ci err = printed; 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci free(value); 6862306a36Sopenharmony_ciout_free_key: 6962306a36Sopenharmony_ci free(key); 7062306a36Sopenharmony_ciout: 7162306a36Sopenharmony_ci return err; 7262306a36Sopenharmony_ci} 73