BPF_MAP_TYPE_ARRAY_OF_MAPS 和 BPF_MAP_TYPE_HASH_OF_MAPS¶
注意
BPF_MAP_TYPE_ARRAY_OF_MAPS和BPF_MAP_TYPE_HASH_OF_MAPS是在核心版本 4.12 中引入的
BPF_MAP_TYPE_ARRAY_OF_MAPS 和 BPF_MAP_TYPE_HASH_OF_MAPS 為 map-in-map 儲存提供了通用支援。支援一層巢狀,其中外部 map 包含單一型別內部 map 的例項,例如 array_of_maps->sock_map。
建立外部 map 時,使用內部 map 例項來初始化外部 map 持有的關於其內部 map 的元資料。這個內部 map 的生命週期與外部 map 分開,並且可以在外部 map 建立後刪除。
外部 map 支援從使用者空間使用系統呼叫 API 進行元素查詢、更新和刪除。BPF 程式只允許在外部 map 中進行元素查詢。
注意
不支援多層巢狀。
除了
BPF_MAP_TYPE_PROG_ARRAY,任何 BPF map 型別都可以用作內部 map。BPF 程式不能更新或刪除外部 map 條目。
對於 BPF_MAP_TYPE_ARRAY_OF_MAPS,鍵是陣列的無符號 32 位整型索引。陣列是固定大小的,具有 max_entries 個元素,這些元素在建立時被零初始化。
對於 BPF_MAP_TYPE_HASH_OF_MAPS,可以在定義 map 時選擇鍵型別。核心負責分配和釋放鍵/值對,直到您指定的 max_entries 限制。雜湊 map 預設使用預分配雜湊表元素。BPF_F_NO_PREALLOC 標誌可用於在記憶體開銷過大時停用預分配。
用法¶
核心 BPF 幫助函式¶
bpf_map_lookup_elem()¶
void *bpf_map_lookup_elem(struct bpf_map *map, const void *key)
可以使用 bpf_map_lookup_elem() 幫助函式檢索內部 map。如果未找到條目,此幫助函式返回指向內部 map 的指標,或 NULL。
示例¶
核心 BPF 示例¶
此片段展示瞭如何在 BPF 程式中建立和初始化 devmap 陣列。請注意,外部陣列只能透過系統呼叫 API 從使用者空間修改。
struct inner_map {
__uint(type, BPF_MAP_TYPE_DEVMAP);
__uint(max_entries, 10);
__type(key, __u32);
__type(value, __u32);
} inner_map1 SEC(".maps"), inner_map2 SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
__uint(max_entries, 2);
__type(key, __u32);
__array(values, struct inner_map);
} outer_map SEC(".maps") = {
.values = { &inner_map1,
&inner_map2 }
};
有關外部 map 宣告性初始化的更多示例,請參閱 tools/testing/selftests/bpf 中的 progs/test_btf_map_in_map.c。
使用者空間¶
此片段展示瞭如何建立基於陣列的外部 map
int create_outer_array(int inner_fd) {
LIBBPF_OPTS(bpf_map_create_opts, opts, .inner_map_fd = inner_fd);
int fd;
fd = bpf_map_create(BPF_MAP_TYPE_ARRAY_OF_MAPS,
"example_array", /* name */
sizeof(__u32), /* key size */
sizeof(__u32), /* value size */
256, /* max entries */
&opts); /* create opts */
return fd;
}
此片段展示瞭如何將內部 map 新增到外部 map
int add_devmap(int outer_fd, int index, const char *name) {
int fd;
fd = bpf_map_create(BPF_MAP_TYPE_DEVMAP, name,
sizeof(__u32), sizeof(__u32), 256, NULL);
if (fd < 0)
return fd;
return bpf_map_update_elem(outer_fd, &index, &fd, BPF_ANY);
}