xref: /linux/include/linux/bpf-cgroup.h (revision 44f57d78)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _BPF_CGROUP_H
3 #define _BPF_CGROUP_H
4 
5 #include <linux/bpf.h>
6 #include <linux/errno.h>
7 #include <linux/jump_label.h>
8 #include <linux/percpu.h>
9 #include <linux/rbtree.h>
10 #include <uapi/linux/bpf.h>
11 
12 struct sock;
13 struct sockaddr;
14 struct cgroup;
15 struct sk_buff;
16 struct bpf_map;
17 struct bpf_prog;
18 struct bpf_sock_ops_kern;
19 struct bpf_cgroup_storage;
20 struct ctl_table;
21 struct ctl_table_header;
22 
23 #ifdef CONFIG_CGROUP_BPF
24 
25 extern struct static_key_false cgroup_bpf_enabled_key;
26 #define cgroup_bpf_enabled static_branch_unlikely(&cgroup_bpf_enabled_key)
27 
28 DECLARE_PER_CPU(struct bpf_cgroup_storage*,
29 		bpf_cgroup_storage[MAX_BPF_CGROUP_STORAGE_TYPE]);
30 
31 #define for_each_cgroup_storage_type(stype) \
32 	for (stype = 0; stype < MAX_BPF_CGROUP_STORAGE_TYPE; stype++)
33 
34 struct bpf_cgroup_storage_map;
35 
36 struct bpf_storage_buffer {
37 	struct rcu_head rcu;
38 	char data[0];
39 };
40 
41 struct bpf_cgroup_storage {
42 	union {
43 		struct bpf_storage_buffer *buf;
44 		void __percpu *percpu_buf;
45 	};
46 	struct bpf_cgroup_storage_map *map;
47 	struct bpf_cgroup_storage_key key;
48 	struct list_head list;
49 	struct rb_node node;
50 	struct rcu_head rcu;
51 };
52 
53 struct bpf_prog_list {
54 	struct list_head node;
55 	struct bpf_prog *prog;
56 	struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE];
57 };
58 
59 struct bpf_prog_array;
60 
61 struct cgroup_bpf {
62 	/* array of effective progs in this cgroup */
63 	struct bpf_prog_array __rcu *effective[MAX_BPF_ATTACH_TYPE];
64 
65 	/* attached progs to this cgroup and attach flags
66 	 * when flags == 0 or BPF_F_ALLOW_OVERRIDE the progs list will
67 	 * have either zero or one element
68 	 * when BPF_F_ALLOW_MULTI the list can have up to BPF_CGROUP_MAX_PROGS
69 	 */
70 	struct list_head progs[MAX_BPF_ATTACH_TYPE];
71 	u32 flags[MAX_BPF_ATTACH_TYPE];
72 
73 	/* temp storage for effective prog array used by prog_attach/detach */
74 	struct bpf_prog_array __rcu *inactive;
75 };
76 
77 void cgroup_bpf_put(struct cgroup *cgrp);
78 int cgroup_bpf_inherit(struct cgroup *cgrp);
79 
80 int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog,
81 			enum bpf_attach_type type, u32 flags);
82 int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
83 			enum bpf_attach_type type);
84 int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
85 		       union bpf_attr __user *uattr);
86 
87 /* Wrapper for __cgroup_bpf_*() protected by cgroup_mutex */
88 int cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog,
89 		      enum bpf_attach_type type, u32 flags);
90 int cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
91 		      enum bpf_attach_type type, u32 flags);
92 int cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
93 		     union bpf_attr __user *uattr);
94 
95 int __cgroup_bpf_run_filter_skb(struct sock *sk,
96 				struct sk_buff *skb,
97 				enum bpf_attach_type type);
98 
99 int __cgroup_bpf_run_filter_sk(struct sock *sk,
100 			       enum bpf_attach_type type);
101 
102 int __cgroup_bpf_run_filter_sock_addr(struct sock *sk,
103 				      struct sockaddr *uaddr,
104 				      enum bpf_attach_type type,
105 				      void *t_ctx);
106 
107 int __cgroup_bpf_run_filter_sock_ops(struct sock *sk,
108 				     struct bpf_sock_ops_kern *sock_ops,
109 				     enum bpf_attach_type type);
110 
111 int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor,
112 				      short access, enum bpf_attach_type type);
113 
114 int __cgroup_bpf_run_filter_sysctl(struct ctl_table_header *head,
115 				   struct ctl_table *table, int write,
116 				   void __user *buf, size_t *pcount,
117 				   loff_t *ppos, void **new_buf,
118 				   enum bpf_attach_type type);
119 
120 static inline enum bpf_cgroup_storage_type cgroup_storage_type(
121 	struct bpf_map *map)
122 {
123 	if (map->map_type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE)
124 		return BPF_CGROUP_STORAGE_PERCPU;
125 
126 	return BPF_CGROUP_STORAGE_SHARED;
127 }
128 
129 static inline void bpf_cgroup_storage_set(struct bpf_cgroup_storage
130 					  *storage[MAX_BPF_CGROUP_STORAGE_TYPE])
131 {
132 	enum bpf_cgroup_storage_type stype;
133 
134 	for_each_cgroup_storage_type(stype)
135 		this_cpu_write(bpf_cgroup_storage[stype], storage[stype]);
136 }
137 
138 struct bpf_cgroup_storage *bpf_cgroup_storage_alloc(struct bpf_prog *prog,
139 					enum bpf_cgroup_storage_type stype);
140 void bpf_cgroup_storage_free(struct bpf_cgroup_storage *storage);
141 void bpf_cgroup_storage_link(struct bpf_cgroup_storage *storage,
142 			     struct cgroup *cgroup,
143 			     enum bpf_attach_type type);
144 void bpf_cgroup_storage_unlink(struct bpf_cgroup_storage *storage);
145 int bpf_cgroup_storage_assign(struct bpf_prog *prog, struct bpf_map *map);
146 void bpf_cgroup_storage_release(struct bpf_prog *prog, struct bpf_map *map);
147 
148 int bpf_percpu_cgroup_storage_copy(struct bpf_map *map, void *key, void *value);
149 int bpf_percpu_cgroup_storage_update(struct bpf_map *map, void *key,
150 				     void *value, u64 flags);
151 
152 /* Wrappers for __cgroup_bpf_run_filter_skb() guarded by cgroup_bpf_enabled. */
153 #define BPF_CGROUP_RUN_PROG_INET_INGRESS(sk, skb)			      \
154 ({									      \
155 	int __ret = 0;							      \
156 	if (cgroup_bpf_enabled)						      \
157 		__ret = __cgroup_bpf_run_filter_skb(sk, skb,		      \
158 						    BPF_CGROUP_INET_INGRESS); \
159 									      \
160 	__ret;								      \
161 })
162 
163 #define BPF_CGROUP_RUN_PROG_INET_EGRESS(sk, skb)			       \
164 ({									       \
165 	int __ret = 0;							       \
166 	if (cgroup_bpf_enabled && sk && sk == skb->sk) {		       \
167 		typeof(sk) __sk = sk_to_full_sk(sk);			       \
168 		if (sk_fullsock(__sk))					       \
169 			__ret = __cgroup_bpf_run_filter_skb(__sk, skb,	       \
170 						      BPF_CGROUP_INET_EGRESS); \
171 	}								       \
172 	__ret;								       \
173 })
174 
175 #define BPF_CGROUP_RUN_SK_PROG(sk, type)				       \
176 ({									       \
177 	int __ret = 0;							       \
178 	if (cgroup_bpf_enabled) {					       \
179 		__ret = __cgroup_bpf_run_filter_sk(sk, type);		       \
180 	}								       \
181 	__ret;								       \
182 })
183 
184 #define BPF_CGROUP_RUN_PROG_INET_SOCK(sk)				       \
185 	BPF_CGROUP_RUN_SK_PROG(sk, BPF_CGROUP_INET_SOCK_CREATE)
186 
187 #define BPF_CGROUP_RUN_PROG_INET4_POST_BIND(sk)				       \
188 	BPF_CGROUP_RUN_SK_PROG(sk, BPF_CGROUP_INET4_POST_BIND)
189 
190 #define BPF_CGROUP_RUN_PROG_INET6_POST_BIND(sk)				       \
191 	BPF_CGROUP_RUN_SK_PROG(sk, BPF_CGROUP_INET6_POST_BIND)
192 
193 #define BPF_CGROUP_RUN_SA_PROG(sk, uaddr, type)				       \
194 ({									       \
195 	int __ret = 0;							       \
196 	if (cgroup_bpf_enabled)						       \
197 		__ret = __cgroup_bpf_run_filter_sock_addr(sk, uaddr, type,     \
198 							  NULL);	       \
199 	__ret;								       \
200 })
201 
202 #define BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, type, t_ctx)		       \
203 ({									       \
204 	int __ret = 0;							       \
205 	if (cgroup_bpf_enabled)	{					       \
206 		lock_sock(sk);						       \
207 		__ret = __cgroup_bpf_run_filter_sock_addr(sk, uaddr, type,     \
208 							  t_ctx);	       \
209 		release_sock(sk);					       \
210 	}								       \
211 	__ret;								       \
212 })
213 
214 #define BPF_CGROUP_RUN_PROG_INET4_BIND(sk, uaddr)			       \
215 	BPF_CGROUP_RUN_SA_PROG(sk, uaddr, BPF_CGROUP_INET4_BIND)
216 
217 #define BPF_CGROUP_RUN_PROG_INET6_BIND(sk, uaddr)			       \
218 	BPF_CGROUP_RUN_SA_PROG(sk, uaddr, BPF_CGROUP_INET6_BIND)
219 
220 #define BPF_CGROUP_PRE_CONNECT_ENABLED(sk) (cgroup_bpf_enabled && \
221 					    sk->sk_prot->pre_connect)
222 
223 #define BPF_CGROUP_RUN_PROG_INET4_CONNECT(sk, uaddr)			       \
224 	BPF_CGROUP_RUN_SA_PROG(sk, uaddr, BPF_CGROUP_INET4_CONNECT)
225 
226 #define BPF_CGROUP_RUN_PROG_INET6_CONNECT(sk, uaddr)			       \
227 	BPF_CGROUP_RUN_SA_PROG(sk, uaddr, BPF_CGROUP_INET6_CONNECT)
228 
229 #define BPF_CGROUP_RUN_PROG_INET4_CONNECT_LOCK(sk, uaddr)		       \
230 	BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, BPF_CGROUP_INET4_CONNECT, NULL)
231 
232 #define BPF_CGROUP_RUN_PROG_INET6_CONNECT_LOCK(sk, uaddr)		       \
233 	BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, BPF_CGROUP_INET6_CONNECT, NULL)
234 
235 #define BPF_CGROUP_RUN_PROG_UDP4_SENDMSG_LOCK(sk, uaddr, t_ctx)		       \
236 	BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, BPF_CGROUP_UDP4_SENDMSG, t_ctx)
237 
238 #define BPF_CGROUP_RUN_PROG_UDP6_SENDMSG_LOCK(sk, uaddr, t_ctx)		       \
239 	BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, BPF_CGROUP_UDP6_SENDMSG, t_ctx)
240 
241 #define BPF_CGROUP_RUN_PROG_UDP4_RECVMSG_LOCK(sk, uaddr)			\
242 	BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, BPF_CGROUP_UDP4_RECVMSG, NULL)
243 
244 #define BPF_CGROUP_RUN_PROG_UDP6_RECVMSG_LOCK(sk, uaddr)			\
245 	BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, BPF_CGROUP_UDP6_RECVMSG, NULL)
246 
247 #define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops)				       \
248 ({									       \
249 	int __ret = 0;							       \
250 	if (cgroup_bpf_enabled && (sock_ops)->sk) {	       \
251 		typeof(sk) __sk = sk_to_full_sk((sock_ops)->sk);	       \
252 		if (__sk && sk_fullsock(__sk))				       \
253 			__ret = __cgroup_bpf_run_filter_sock_ops(__sk,	       \
254 								 sock_ops,     \
255 							 BPF_CGROUP_SOCK_OPS); \
256 	}								       \
257 	__ret;								       \
258 })
259 
260 #define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(type, major, minor, access)	      \
261 ({									      \
262 	int __ret = 0;							      \
263 	if (cgroup_bpf_enabled)						      \
264 		__ret = __cgroup_bpf_check_dev_permission(type, major, minor, \
265 							  access,	      \
266 							  BPF_CGROUP_DEVICE); \
267 									      \
268 	__ret;								      \
269 })
270 
271 
272 #define BPF_CGROUP_RUN_PROG_SYSCTL(head, table, write, buf, count, pos, nbuf)  \
273 ({									       \
274 	int __ret = 0;							       \
275 	if (cgroup_bpf_enabled)						       \
276 		__ret = __cgroup_bpf_run_filter_sysctl(head, table, write,     \
277 						       buf, count, pos, nbuf,  \
278 						       BPF_CGROUP_SYSCTL);     \
279 	__ret;								       \
280 })
281 
282 int cgroup_bpf_prog_attach(const union bpf_attr *attr,
283 			   enum bpf_prog_type ptype, struct bpf_prog *prog);
284 int cgroup_bpf_prog_detach(const union bpf_attr *attr,
285 			   enum bpf_prog_type ptype);
286 int cgroup_bpf_prog_query(const union bpf_attr *attr,
287 			  union bpf_attr __user *uattr);
288 #else
289 
290 struct bpf_prog;
291 struct cgroup_bpf {};
292 static inline void cgroup_bpf_put(struct cgroup *cgrp) {}
293 static inline int cgroup_bpf_inherit(struct cgroup *cgrp) { return 0; }
294 
295 static inline int cgroup_bpf_prog_attach(const union bpf_attr *attr,
296 					 enum bpf_prog_type ptype,
297 					 struct bpf_prog *prog)
298 {
299 	return -EINVAL;
300 }
301 
302 static inline int cgroup_bpf_prog_detach(const union bpf_attr *attr,
303 					 enum bpf_prog_type ptype)
304 {
305 	return -EINVAL;
306 }
307 
308 static inline int cgroup_bpf_prog_query(const union bpf_attr *attr,
309 					union bpf_attr __user *uattr)
310 {
311 	return -EINVAL;
312 }
313 
314 static inline void bpf_cgroup_storage_set(
315 	struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE]) {}
316 static inline int bpf_cgroup_storage_assign(struct bpf_prog *prog,
317 					    struct bpf_map *map) { return 0; }
318 static inline void bpf_cgroup_storage_release(struct bpf_prog *prog,
319 					      struct bpf_map *map) {}
320 static inline struct bpf_cgroup_storage *bpf_cgroup_storage_alloc(
321 	struct bpf_prog *prog, enum bpf_cgroup_storage_type stype) { return NULL; }
322 static inline void bpf_cgroup_storage_free(
323 	struct bpf_cgroup_storage *storage) {}
324 static inline int bpf_percpu_cgroup_storage_copy(struct bpf_map *map, void *key,
325 						 void *value) {
326 	return 0;
327 }
328 static inline int bpf_percpu_cgroup_storage_update(struct bpf_map *map,
329 					void *key, void *value, u64 flags) {
330 	return 0;
331 }
332 
333 #define cgroup_bpf_enabled (0)
334 #define BPF_CGROUP_PRE_CONNECT_ENABLED(sk) (0)
335 #define BPF_CGROUP_RUN_PROG_INET_INGRESS(sk,skb) ({ 0; })
336 #define BPF_CGROUP_RUN_PROG_INET_EGRESS(sk,skb) ({ 0; })
337 #define BPF_CGROUP_RUN_PROG_INET_SOCK(sk) ({ 0; })
338 #define BPF_CGROUP_RUN_PROG_INET4_BIND(sk, uaddr) ({ 0; })
339 #define BPF_CGROUP_RUN_PROG_INET6_BIND(sk, uaddr) ({ 0; })
340 #define BPF_CGROUP_RUN_PROG_INET4_POST_BIND(sk) ({ 0; })
341 #define BPF_CGROUP_RUN_PROG_INET6_POST_BIND(sk) ({ 0; })
342 #define BPF_CGROUP_RUN_PROG_INET4_CONNECT(sk, uaddr) ({ 0; })
343 #define BPF_CGROUP_RUN_PROG_INET4_CONNECT_LOCK(sk, uaddr) ({ 0; })
344 #define BPF_CGROUP_RUN_PROG_INET6_CONNECT(sk, uaddr) ({ 0; })
345 #define BPF_CGROUP_RUN_PROG_INET6_CONNECT_LOCK(sk, uaddr) ({ 0; })
346 #define BPF_CGROUP_RUN_PROG_UDP4_SENDMSG_LOCK(sk, uaddr, t_ctx) ({ 0; })
347 #define BPF_CGROUP_RUN_PROG_UDP6_SENDMSG_LOCK(sk, uaddr, t_ctx) ({ 0; })
348 #define BPF_CGROUP_RUN_PROG_UDP4_RECVMSG_LOCK(sk, uaddr) ({ 0; })
349 #define BPF_CGROUP_RUN_PROG_UDP6_RECVMSG_LOCK(sk, uaddr) ({ 0; })
350 #define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) ({ 0; })
351 #define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(type,major,minor,access) ({ 0; })
352 #define BPF_CGROUP_RUN_PROG_SYSCTL(head,table,write,buf,count,pos,nbuf) ({ 0; })
353 
354 #define for_each_cgroup_storage_type(stype) for (; false; )
355 
356 #endif /* CONFIG_CGROUP_BPF */
357 
358 #endif /* _BPF_CGROUP_H */
359