Linux Audio

Check our new training course

Linux BSP development engineering services

Need help to port Linux and bootloaders to your hardware?
Loading...
  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 inner_map_sz2 {
 15	__uint(type, BPF_MAP_TYPE_ARRAY);
 16	__uint(max_entries, 2);
 17	__type(key, int);
 18	__type(value, int);
 19} inner_map_sz2 SEC(".maps");
 20
 21struct outer_arr {
 22	__uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
 23	__uint(max_entries, 3);
 24	__type(key, int);
 25	__type(value, int);
 26	/* it's possible to use anonymous struct as inner map definition here */
 27	__array(values, struct {
 28		__uint(type, BPF_MAP_TYPE_ARRAY);
 29		/* changing max_entries to 2 will fail during load
 30		 * due to incompatibility with inner_map definition */
 31		__uint(max_entries, 1);
 32		__type(key, int);
 33		__type(value, int);
 34	});
 35} outer_arr SEC(".maps") = {
 36	/* (void *) cast is necessary because we didn't use `struct inner_map`
 37	 * in __inner(values, ...)
 38	 * Actually, a conscious effort is required to screw up initialization
 39	 * of inner map slots, which is a great thing!
 40	 */
 41	.values = { (void *)&inner_map1, 0, (void *)&inner_map2 },
 42};
 43
 44struct inner_map_sz3 {
 45	__uint(type, BPF_MAP_TYPE_ARRAY);
 46	__uint(map_flags, BPF_F_INNER_MAP);
 47	__uint(max_entries, 3);
 48	__type(key, int);
 49	__type(value, int);
 50} inner_map3 SEC(".maps"),
 51  inner_map4 SEC(".maps");
 52
 53struct inner_map_sz4 {
 54	__uint(type, BPF_MAP_TYPE_ARRAY);
 55	__uint(map_flags, BPF_F_INNER_MAP);
 56	__uint(max_entries, 5);
 57	__type(key, int);
 58	__type(value, int);
 59} inner_map5 SEC(".maps");
 60
 61struct outer_arr_dyn {
 62	__uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
 63	__uint(max_entries, 3);
 64	__type(key, int);
 65	__type(value, int);
 66	__array(values, struct {
 67		__uint(type, BPF_MAP_TYPE_ARRAY);
 68		__uint(map_flags, BPF_F_INNER_MAP);
 69		__uint(max_entries, 1);
 70		__type(key, int);
 71		__type(value, int);
 72	});
 73} outer_arr_dyn SEC(".maps") = {
 74	.values = {
 75		[0] = (void *)&inner_map3,
 76		[1] = (void *)&inner_map4,
 77		[2] = (void *)&inner_map5,
 78	},
 79};
 80
 81struct outer_hash {
 82	__uint(type, BPF_MAP_TYPE_HASH_OF_MAPS);
 83	__uint(max_entries, 5);
 84	__type(key, int);
 85	/* Here everything works flawlessly due to reuse of struct inner_map
 86	 * and compiler will complain at the attempt to use non-inner_map
 87	 * references below. This is great experience.
 88	 */
 89	__array(values, struct inner_map);
 90} outer_hash SEC(".maps") = {
 91	.values = {
 92		[0] = &inner_map2,
 93		[4] = &inner_map1,
 94	},
 95};
 96
 97struct sockarr_sz1 {
 98	__uint(type, BPF_MAP_TYPE_REUSEPORT_SOCKARRAY);
 99	__uint(max_entries, 1);
100	__type(key, int);
101	__type(value, int);
102} sockarr_sz1 SEC(".maps");
103
104struct sockarr_sz2 {
105	__uint(type, BPF_MAP_TYPE_REUSEPORT_SOCKARRAY);
106	__uint(max_entries, 2);
107	__type(key, int);
108	__type(value, int);
109} sockarr_sz2 SEC(".maps");
110
111struct outer_sockarr_sz1 {
112	__uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
113	__uint(max_entries, 1);
114	__type(key, int);
115	__type(value, int);
116	__array(values, struct sockarr_sz1);
117} outer_sockarr SEC(".maps") = {
118	.values = { (void *)&sockarr_sz1 },
119};
120
121int input = 0;
122
123SEC("raw_tp/sys_enter")
124int handle__sys_enter(void *ctx)
125{
126	struct inner_map *inner_map;
127	int key = 0, val;
128
129	inner_map = bpf_map_lookup_elem(&outer_arr, &key);
130	if (!inner_map)
131		return 1;
132	val = input;
133	bpf_map_update_elem(inner_map, &key, &val, 0);
134
135	inner_map = bpf_map_lookup_elem(&outer_hash, &key);
136	if (!inner_map)
137		return 1;
138	val = input + 1;
139	bpf_map_update_elem(inner_map, &key, &val, 0);
140
141	inner_map = bpf_map_lookup_elem(&outer_arr_dyn, &key);
142	if (!inner_map)
143		return 1;
144	val = input + 2;
145	bpf_map_update_elem(inner_map, &key, &val, 0);
146
147	return 0;
148}
149
150char _license[] SEC("license") = "GPL";