linux/tools/testing/selftests/bpf/progs/test_btf_map_in_map.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/* Copyright (c) 2020 Facebook */
   3#include <linux/bpf.h>
   4#include <bpf/bpf_helpers.h>
   5
   6struct 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
  14struct 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
  37struct 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
  53int input = 0;
  54
  55SEC("raw_tp/sys_enter")
  56int 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
  76char _license[] SEC("license") = "GPL";
  77