1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* Copyright (c) 2020 Facebook */ 3 #include <linux/bpf.h> 4 #include <bpf/bpf_helpers.h> 5 6 struct inner_map { 7 __uint(type, BPF_MAP_TYPE_ARRAY); 8 __uint(max_entries, 1); 9 __type(key, int); 10 __type(value, int); 11 } inner_map1 SEC(".maps"), 12 inner_map2 SEC(".maps"); 13 14 struct outer_arr { 15 __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS); 16 __uint(max_entries, 3); 17 __uint(key_size, sizeof(int)); 18 __uint(value_size, sizeof(int)); 19 /* it's possible to use anonymous struct as inner map definition here */ 20 __array(values, struct { 21 __uint(type, BPF_MAP_TYPE_ARRAY); 22 /* changing max_entries to 2 will fail during load 23 * due to incompatibility with inner_map definition */ 24 __uint(max_entries, 1); 25 __type(key, int); 26 __type(value, int); 27 }); 28 } outer_arr SEC(".maps") = { 29 /* (void *) cast is necessary because we didn't use `struct inner_map` 30 * in __inner(values, ...) 31 * Actually, a conscious effort is required to screw up initialization 32 * of inner map slots, which is a great thing! 33 */ 34 .values = { (void *)&inner_map1, 0, (void *)&inner_map2 }, 35 }; 36 37 struct outer_hash { 38 __uint(type, BPF_MAP_TYPE_HASH_OF_MAPS); 39 __uint(max_entries, 5); 40 __uint(key_size, sizeof(int)); 41 /* Here everything works flawlessly due to reuse of struct inner_map 42 * and compiler will complain at the attempt to use non-inner_map 43 * references below. This is great experience. 44 */ 45 __array(values, struct inner_map); 46 } outer_hash SEC(".maps") = { 47 .values = { 48 [0] = &inner_map2, 49 [4] = &inner_map1, 50 }, 51 }; 52 53 int input = 0; 54 55 SEC("raw_tp/sys_enter") 56 int handle__sys_enter(void *ctx) 57 { 58 struct inner_map *inner_map; 59 int key = 0, val; 60 61 inner_map = bpf_map_lookup_elem(&outer_arr, &key); 62 if (!inner_map) 63 return 1; 64 val = input; 65 bpf_map_update_elem(inner_map, &key, &val, 0); 66 67 inner_map = bpf_map_lookup_elem(&outer_hash, &key); 68 if (!inner_map) 69 return 1; 70 val = input + 1; 71 bpf_map_update_elem(inner_map, &key, &val, 0); 72 73 return 0; 74 } 75 76 char _license[] SEC("license") = "GPL"; 77