Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /* Copyright (c) 2020 Facebook */
0003 #include <linux/bpf.h>
0004 #include <bpf/bpf_helpers.h>
0005 
0006 struct inner_map {
0007     __uint(type, BPF_MAP_TYPE_ARRAY);
0008     __uint(max_entries, 1);
0009     __type(key, int);
0010     __type(value, int);
0011 } inner_map1 SEC(".maps"),
0012   inner_map2 SEC(".maps");
0013 
0014 struct inner_map_sz2 {
0015     __uint(type, BPF_MAP_TYPE_ARRAY);
0016     __uint(max_entries, 2);
0017     __type(key, int);
0018     __type(value, int);
0019 } inner_map_sz2 SEC(".maps");
0020 
0021 struct outer_arr {
0022     __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
0023     __uint(max_entries, 3);
0024     __type(key, int);
0025     __type(value, int);
0026     /* it's possible to use anonymous struct as inner map definition here */
0027     __array(values, struct {
0028         __uint(type, BPF_MAP_TYPE_ARRAY);
0029         /* changing max_entries to 2 will fail during load
0030          * due to incompatibility with inner_map definition */
0031         __uint(max_entries, 1);
0032         __type(key, int);
0033         __type(value, int);
0034     });
0035 } outer_arr SEC(".maps") = {
0036     /* (void *) cast is necessary because we didn't use `struct inner_map`
0037      * in __inner(values, ...)
0038      * Actually, a conscious effort is required to screw up initialization
0039      * of inner map slots, which is a great thing!
0040      */
0041     .values = { (void *)&inner_map1, 0, (void *)&inner_map2 },
0042 };
0043 
0044 struct inner_map_sz3 {
0045     __uint(type, BPF_MAP_TYPE_ARRAY);
0046     __uint(map_flags, BPF_F_INNER_MAP);
0047     __uint(max_entries, 3);
0048     __type(key, int);
0049     __type(value, int);
0050 } inner_map3 SEC(".maps"),
0051   inner_map4 SEC(".maps");
0052 
0053 struct inner_map_sz4 {
0054     __uint(type, BPF_MAP_TYPE_ARRAY);
0055     __uint(map_flags, BPF_F_INNER_MAP);
0056     __uint(max_entries, 5);
0057     __type(key, int);
0058     __type(value, int);
0059 } inner_map5 SEC(".maps");
0060 
0061 struct outer_arr_dyn {
0062     __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
0063     __uint(max_entries, 3);
0064     __type(key, int);
0065     __type(value, int);
0066     __array(values, struct {
0067         __uint(type, BPF_MAP_TYPE_ARRAY);
0068         __uint(map_flags, BPF_F_INNER_MAP);
0069         __uint(max_entries, 1);
0070         __type(key, int);
0071         __type(value, int);
0072     });
0073 } outer_arr_dyn SEC(".maps") = {
0074     .values = {
0075         [0] = (void *)&inner_map3,
0076         [1] = (void *)&inner_map4,
0077         [2] = (void *)&inner_map5,
0078     },
0079 };
0080 
0081 struct outer_hash {
0082     __uint(type, BPF_MAP_TYPE_HASH_OF_MAPS);
0083     __uint(max_entries, 5);
0084     __type(key, int);
0085     /* Here everything works flawlessly due to reuse of struct inner_map
0086      * and compiler will complain at the attempt to use non-inner_map
0087      * references below. This is great experience.
0088      */
0089     __array(values, struct inner_map);
0090 } outer_hash SEC(".maps") = {
0091     .values = {
0092         [0] = &inner_map2,
0093         [4] = &inner_map1,
0094     },
0095 };
0096 
0097 struct sockarr_sz1 {
0098     __uint(type, BPF_MAP_TYPE_REUSEPORT_SOCKARRAY);
0099     __uint(max_entries, 1);
0100     __type(key, int);
0101     __type(value, int);
0102 } sockarr_sz1 SEC(".maps");
0103 
0104 struct sockarr_sz2 {
0105     __uint(type, BPF_MAP_TYPE_REUSEPORT_SOCKARRAY);
0106     __uint(max_entries, 2);
0107     __type(key, int);
0108     __type(value, int);
0109 } sockarr_sz2 SEC(".maps");
0110 
0111 struct outer_sockarr_sz1 {
0112     __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
0113     __uint(max_entries, 1);
0114     __type(key, int);
0115     __type(value, int);
0116     __array(values, struct sockarr_sz1);
0117 } outer_sockarr SEC(".maps") = {
0118     .values = { (void *)&sockarr_sz1 },
0119 };
0120 
0121 int input = 0;
0122 
0123 SEC("raw_tp/sys_enter")
0124 int handle__sys_enter(void *ctx)
0125 {
0126     struct inner_map *inner_map;
0127     int key = 0, val;
0128 
0129     inner_map = bpf_map_lookup_elem(&outer_arr, &key);
0130     if (!inner_map)
0131         return 1;
0132     val = input;
0133     bpf_map_update_elem(inner_map, &key, &val, 0);
0134 
0135     inner_map = bpf_map_lookup_elem(&outer_hash, &key);
0136     if (!inner_map)
0137         return 1;
0138     val = input + 1;
0139     bpf_map_update_elem(inner_map, &key, &val, 0);
0140 
0141     inner_map = bpf_map_lookup_elem(&outer_arr_dyn, &key);
0142     if (!inner_map)
0143         return 1;
0144     val = input + 2;
0145     bpf_map_update_elem(inner_map, &key, &val, 0);
0146 
0147     return 0;
0148 }
0149 
0150 char _license[] SEC("license") = "GPL";