124 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (c) 2020 Facebook */3#include "bpf_iter.h"4#include <bpf/bpf_helpers.h>5 6char _license[] SEC("license") = "GPL";7 8struct key_t {9 int a;10 int b;11 int c;12};13 14struct {15 __uint(type, BPF_MAP_TYPE_HASH);16 __uint(max_entries, 3);17 __type(key, struct key_t);18 __type(value, __u64);19} hashmap1 SEC(".maps");20 21struct {22 __uint(type, BPF_MAP_TYPE_HASH);23 __uint(max_entries, 3);24 __type(key, __u64);25 __type(value, __u64);26} hashmap2 SEC(".maps");27 28struct {29 __uint(type, BPF_MAP_TYPE_HASH);30 __uint(max_entries, 3);31 __type(key, struct key_t);32 __type(value, __u32);33} hashmap3 SEC(".maps");34 35/* will set before prog run */36bool in_test_mode = 0;37 38/* will collect results during prog run */39__u32 key_sum_a = 0, key_sum_b = 0, key_sum_c = 0;40__u64 val_sum = 0;41 42SEC("iter/bpf_map_elem")43int dump_bpf_hash_map(struct bpf_iter__bpf_map_elem *ctx)44{45 struct seq_file *seq = ctx->meta->seq;46 __u32 seq_num = ctx->meta->seq_num;47 struct bpf_map *map = ctx->map;48 struct key_t *key = ctx->key;49 struct key_t tmp_key;50 __u64 *val = ctx->value;51 __u64 tmp_val = 0;52 int ret;53 54 if (in_test_mode) {55 /* test mode is used by selftests to56 * test functionality of bpf_hash_map iter.57 *58 * the above hashmap1 will have correct size59 * and will be accepted, hashmap2 and hashmap360 * should be rejected due to smaller key/value61 * size.62 */63 if (key == (void *)0 || val == (void *)0)64 return 0;65 66 /* update the value and then delete the <key, value> pair.67 * it should not impact the existing 'val' which is still68 * accessible under rcu.69 */70 __builtin_memcpy(&tmp_key, key, sizeof(struct key_t));71 ret = bpf_map_update_elem(&hashmap1, &tmp_key, &tmp_val, 0);72 if (ret)73 return 0;74 ret = bpf_map_delete_elem(&hashmap1, &tmp_key);75 if (ret)76 return 0;77 78 key_sum_a += key->a;79 key_sum_b += key->b;80 key_sum_c += key->c;81 val_sum += *val;82 return 0;83 }84 85 /* non-test mode, the map is prepared with the86 * below bpftool command sequence:87 * bpftool map create /sys/fs/bpf/m1 type hash \88 * key 12 value 8 entries 3 name map189 * bpftool map update id 77 key 0 0 0 1 0 0 0 0 0 0 0 1 \90 * value 0 0 0 1 0 0 0 191 * bpftool map update id 77 key 0 0 0 1 0 0 0 0 0 0 0 2 \92 * value 0 0 0 1 0 0 0 293 * The bpftool iter command line:94 * bpftool iter pin ./bpf_iter_bpf_hash_map.o /sys/fs/bpf/p1 \95 * map id 7796 * The below output will be:97 * map dump starts98 * 77: (1000000 0 2000000) (200000001000000)99 * 77: (1000000 0 1000000) (100000001000000)100 * map dump ends101 */102 if (seq_num == 0)103 BPF_SEQ_PRINTF(seq, "map dump starts\n");104 105 if (key == (void *)0 || val == (void *)0) {106 BPF_SEQ_PRINTF(seq, "map dump ends\n");107 return 0;108 }109 110 BPF_SEQ_PRINTF(seq, "%d: (%x %d %x) (%llx)\n", map->id,111 key->a, key->b, key->c, *val);112 113 return 0;114}115 116SEC("iter.s/bpf_map_elem")117int sleepable_dummy_dump(struct bpf_iter__bpf_map_elem *ctx)118{119 if (ctx->meta->seq_num == 0)120 BPF_SEQ_PRINTF(ctx->meta->seq, "map dump starts\n");121 122 return 0;123}124