xref: /linux-6.15/include/linux/bpf-cgroup.h (revision aac3fc32)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
230070984SDaniel Mack #ifndef _BPF_CGROUP_H
330070984SDaniel Mack #define _BPF_CGROUP_H
430070984SDaniel Mack 
530070984SDaniel Mack #include <linux/jump_label.h>
630070984SDaniel Mack #include <uapi/linux/bpf.h>
730070984SDaniel Mack 
830070984SDaniel Mack struct sock;
94fbac77dSAndrey Ignatov struct sockaddr;
1030070984SDaniel Mack struct cgroup;
1130070984SDaniel Mack struct sk_buff;
1240304b2aSLawrence Brakmo struct bpf_sock_ops_kern;
1330070984SDaniel Mack 
1430070984SDaniel Mack #ifdef CONFIG_CGROUP_BPF
1530070984SDaniel Mack 
1630070984SDaniel Mack extern struct static_key_false cgroup_bpf_enabled_key;
1730070984SDaniel Mack #define cgroup_bpf_enabled static_branch_unlikely(&cgroup_bpf_enabled_key)
1830070984SDaniel Mack 
19324bda9eSAlexei Starovoitov struct bpf_prog_list {
20324bda9eSAlexei Starovoitov 	struct list_head node;
21324bda9eSAlexei Starovoitov 	struct bpf_prog *prog;
22324bda9eSAlexei Starovoitov };
23324bda9eSAlexei Starovoitov 
24324bda9eSAlexei Starovoitov struct bpf_prog_array;
25324bda9eSAlexei Starovoitov 
2630070984SDaniel Mack struct cgroup_bpf {
27324bda9eSAlexei Starovoitov 	/* array of effective progs in this cgroup */
28324bda9eSAlexei Starovoitov 	struct bpf_prog_array __rcu *effective[MAX_BPF_ATTACH_TYPE];
29324bda9eSAlexei Starovoitov 
30324bda9eSAlexei Starovoitov 	/* attached progs to this cgroup and attach flags
31324bda9eSAlexei Starovoitov 	 * when flags == 0 or BPF_F_ALLOW_OVERRIDE the progs list will
32324bda9eSAlexei Starovoitov 	 * have either zero or one element
33324bda9eSAlexei Starovoitov 	 * when BPF_F_ALLOW_MULTI the list can have up to BPF_CGROUP_MAX_PROGS
3430070984SDaniel Mack 	 */
35324bda9eSAlexei Starovoitov 	struct list_head progs[MAX_BPF_ATTACH_TYPE];
36324bda9eSAlexei Starovoitov 	u32 flags[MAX_BPF_ATTACH_TYPE];
37324bda9eSAlexei Starovoitov 
38324bda9eSAlexei Starovoitov 	/* temp storage for effective prog array used by prog_attach/detach */
39324bda9eSAlexei Starovoitov 	struct bpf_prog_array __rcu *inactive;
4030070984SDaniel Mack };
4130070984SDaniel Mack 
4230070984SDaniel Mack void cgroup_bpf_put(struct cgroup *cgrp);
43324bda9eSAlexei Starovoitov int cgroup_bpf_inherit(struct cgroup *cgrp);
4430070984SDaniel Mack 
45324bda9eSAlexei Starovoitov int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog,
46324bda9eSAlexei Starovoitov 			enum bpf_attach_type type, u32 flags);
47324bda9eSAlexei Starovoitov int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
48324bda9eSAlexei Starovoitov 			enum bpf_attach_type type, u32 flags);
49468e2f64SAlexei Starovoitov int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
50468e2f64SAlexei Starovoitov 		       union bpf_attr __user *uattr);
5130070984SDaniel Mack 
52324bda9eSAlexei Starovoitov /* Wrapper for __cgroup_bpf_*() protected by cgroup_mutex */
53324bda9eSAlexei Starovoitov int cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog,
54324bda9eSAlexei Starovoitov 		      enum bpf_attach_type type, u32 flags);
55324bda9eSAlexei Starovoitov int cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
56324bda9eSAlexei Starovoitov 		      enum bpf_attach_type type, u32 flags);
57468e2f64SAlexei Starovoitov int cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
58468e2f64SAlexei Starovoitov 		     union bpf_attr __user *uattr);
5930070984SDaniel Mack 
60b2cd1257SDavid Ahern int __cgroup_bpf_run_filter_skb(struct sock *sk,
6130070984SDaniel Mack 				struct sk_buff *skb,
6230070984SDaniel Mack 				enum bpf_attach_type type);
6330070984SDaniel Mack 
6461023658SDavid Ahern int __cgroup_bpf_run_filter_sk(struct sock *sk,
6561023658SDavid Ahern 			       enum bpf_attach_type type);
6661023658SDavid Ahern 
674fbac77dSAndrey Ignatov int __cgroup_bpf_run_filter_sock_addr(struct sock *sk,
684fbac77dSAndrey Ignatov 				      struct sockaddr *uaddr,
694fbac77dSAndrey Ignatov 				      enum bpf_attach_type type);
704fbac77dSAndrey Ignatov 
7140304b2aSLawrence Brakmo int __cgroup_bpf_run_filter_sock_ops(struct sock *sk,
7240304b2aSLawrence Brakmo 				     struct bpf_sock_ops_kern *sock_ops,
7340304b2aSLawrence Brakmo 				     enum bpf_attach_type type);
7440304b2aSLawrence Brakmo 
75ebc614f6SRoman Gushchin int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor,
76ebc614f6SRoman Gushchin 				      short access, enum bpf_attach_type type);
77ebc614f6SRoman Gushchin 
78b2cd1257SDavid Ahern /* Wrappers for __cgroup_bpf_run_filter_skb() guarded by cgroup_bpf_enabled. */
7930070984SDaniel Mack #define BPF_CGROUP_RUN_PROG_INET_INGRESS(sk, skb)			      \
8030070984SDaniel Mack ({									      \
8130070984SDaniel Mack 	int __ret = 0;							      \
8230070984SDaniel Mack 	if (cgroup_bpf_enabled)						      \
83b2cd1257SDavid Ahern 		__ret = __cgroup_bpf_run_filter_skb(sk, skb,		      \
8430070984SDaniel Mack 						    BPF_CGROUP_INET_INGRESS); \
8530070984SDaniel Mack 									      \
8630070984SDaniel Mack 	__ret;								      \
8730070984SDaniel Mack })
8830070984SDaniel Mack 
8930070984SDaniel Mack #define BPF_CGROUP_RUN_PROG_INET_EGRESS(sk, skb)			       \
9030070984SDaniel Mack ({									       \
9130070984SDaniel Mack 	int __ret = 0;							       \
9230070984SDaniel Mack 	if (cgroup_bpf_enabled && sk && sk == skb->sk) {		       \
9330070984SDaniel Mack 		typeof(sk) __sk = sk_to_full_sk(sk);			       \
9430070984SDaniel Mack 		if (sk_fullsock(__sk))					       \
95b2cd1257SDavid Ahern 			__ret = __cgroup_bpf_run_filter_skb(__sk, skb,	       \
9630070984SDaniel Mack 						      BPF_CGROUP_INET_EGRESS); \
9730070984SDaniel Mack 	}								       \
9830070984SDaniel Mack 	__ret;								       \
9930070984SDaniel Mack })
10030070984SDaniel Mack 
101*aac3fc32SAndrey Ignatov #define BPF_CGROUP_RUN_SK_PROG(sk, type)				       \
10261023658SDavid Ahern ({									       \
10361023658SDavid Ahern 	int __ret = 0;							       \
104ee07862fSYafang Shao 	if (cgroup_bpf_enabled) {					       \
105*aac3fc32SAndrey Ignatov 		__ret = __cgroup_bpf_run_filter_sk(sk, type);		       \
10661023658SDavid Ahern 	}								       \
10761023658SDavid Ahern 	__ret;								       \
10861023658SDavid Ahern })
10961023658SDavid Ahern 
110*aac3fc32SAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET_SOCK(sk)				       \
111*aac3fc32SAndrey Ignatov 	BPF_CGROUP_RUN_SK_PROG(sk, BPF_CGROUP_INET_SOCK_CREATE)
112*aac3fc32SAndrey Ignatov 
113*aac3fc32SAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET4_POST_BIND(sk)				       \
114*aac3fc32SAndrey Ignatov 	BPF_CGROUP_RUN_SK_PROG(sk, BPF_CGROUP_INET4_POST_BIND)
115*aac3fc32SAndrey Ignatov 
116*aac3fc32SAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET6_POST_BIND(sk)				       \
117*aac3fc32SAndrey Ignatov 	BPF_CGROUP_RUN_SK_PROG(sk, BPF_CGROUP_INET6_POST_BIND)
118*aac3fc32SAndrey Ignatov 
1194fbac77dSAndrey Ignatov #define BPF_CGROUP_RUN_SA_PROG(sk, uaddr, type)				       \
1204fbac77dSAndrey Ignatov ({									       \
1214fbac77dSAndrey Ignatov 	int __ret = 0;							       \
1224fbac77dSAndrey Ignatov 	if (cgroup_bpf_enabled)						       \
1234fbac77dSAndrey Ignatov 		__ret = __cgroup_bpf_run_filter_sock_addr(sk, uaddr, type);    \
1244fbac77dSAndrey Ignatov 	__ret;								       \
1254fbac77dSAndrey Ignatov })
1264fbac77dSAndrey Ignatov 
127d74bad4eSAndrey Ignatov #define BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, type)			       \
128d74bad4eSAndrey Ignatov ({									       \
129d74bad4eSAndrey Ignatov 	int __ret = 0;							       \
130d74bad4eSAndrey Ignatov 	if (cgroup_bpf_enabled)	{					       \
131d74bad4eSAndrey Ignatov 		lock_sock(sk);						       \
132d74bad4eSAndrey Ignatov 		__ret = __cgroup_bpf_run_filter_sock_addr(sk, uaddr, type);    \
133d74bad4eSAndrey Ignatov 		release_sock(sk);					       \
134d74bad4eSAndrey Ignatov 	}								       \
135d74bad4eSAndrey Ignatov 	__ret;								       \
136d74bad4eSAndrey Ignatov })
137d74bad4eSAndrey Ignatov 
1384fbac77dSAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET4_BIND(sk, uaddr)			       \
1394fbac77dSAndrey Ignatov 	BPF_CGROUP_RUN_SA_PROG(sk, uaddr, BPF_CGROUP_INET4_BIND)
1404fbac77dSAndrey Ignatov 
1414fbac77dSAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET6_BIND(sk, uaddr)			       \
1424fbac77dSAndrey Ignatov 	BPF_CGROUP_RUN_SA_PROG(sk, uaddr, BPF_CGROUP_INET6_BIND)
1434fbac77dSAndrey Ignatov 
144d74bad4eSAndrey Ignatov #define BPF_CGROUP_PRE_CONNECT_ENABLED(sk) (cgroup_bpf_enabled && \
145d74bad4eSAndrey Ignatov 					    sk->sk_prot->pre_connect)
146d74bad4eSAndrey Ignatov 
147d74bad4eSAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET4_CONNECT(sk, uaddr)			       \
148d74bad4eSAndrey Ignatov 	BPF_CGROUP_RUN_SA_PROG(sk, uaddr, BPF_CGROUP_INET4_CONNECT)
149d74bad4eSAndrey Ignatov 
150d74bad4eSAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET6_CONNECT(sk, uaddr)			       \
151d74bad4eSAndrey Ignatov 	BPF_CGROUP_RUN_SA_PROG(sk, uaddr, BPF_CGROUP_INET6_CONNECT)
152d74bad4eSAndrey Ignatov 
153d74bad4eSAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET4_CONNECT_LOCK(sk, uaddr)		       \
154d74bad4eSAndrey Ignatov 	BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, BPF_CGROUP_INET4_CONNECT)
155d74bad4eSAndrey Ignatov 
156d74bad4eSAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET6_CONNECT_LOCK(sk, uaddr)		       \
157d74bad4eSAndrey Ignatov 	BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, BPF_CGROUP_INET6_CONNECT)
158d74bad4eSAndrey Ignatov 
15940304b2aSLawrence Brakmo #define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops)				       \
16040304b2aSLawrence Brakmo ({									       \
16140304b2aSLawrence Brakmo 	int __ret = 0;							       \
16240304b2aSLawrence Brakmo 	if (cgroup_bpf_enabled && (sock_ops)->sk) {	       \
16340304b2aSLawrence Brakmo 		typeof(sk) __sk = sk_to_full_sk((sock_ops)->sk);	       \
164df39a9f1SWANG Cong 		if (__sk && sk_fullsock(__sk))				       \
16540304b2aSLawrence Brakmo 			__ret = __cgroup_bpf_run_filter_sock_ops(__sk,	       \
16640304b2aSLawrence Brakmo 								 sock_ops,     \
16740304b2aSLawrence Brakmo 							 BPF_CGROUP_SOCK_OPS); \
16840304b2aSLawrence Brakmo 	}								       \
16940304b2aSLawrence Brakmo 	__ret;								       \
17040304b2aSLawrence Brakmo })
171ebc614f6SRoman Gushchin 
172ebc614f6SRoman Gushchin #define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(type, major, minor, access)	      \
173ebc614f6SRoman Gushchin ({									      \
174ebc614f6SRoman Gushchin 	int __ret = 0;							      \
175ebc614f6SRoman Gushchin 	if (cgroup_bpf_enabled)						      \
176ebc614f6SRoman Gushchin 		__ret = __cgroup_bpf_check_dev_permission(type, major, minor, \
177ebc614f6SRoman Gushchin 							  access,	      \
178ebc614f6SRoman Gushchin 							  BPF_CGROUP_DEVICE); \
179ebc614f6SRoman Gushchin 									      \
180ebc614f6SRoman Gushchin 	__ret;								      \
181ebc614f6SRoman Gushchin })
18230070984SDaniel Mack #else
18330070984SDaniel Mack 
18430070984SDaniel Mack struct cgroup_bpf {};
18530070984SDaniel Mack static inline void cgroup_bpf_put(struct cgroup *cgrp) {}
186324bda9eSAlexei Starovoitov static inline int cgroup_bpf_inherit(struct cgroup *cgrp) { return 0; }
18730070984SDaniel Mack 
188d74bad4eSAndrey Ignatov #define BPF_CGROUP_PRE_CONNECT_ENABLED(sk) (0)
18930070984SDaniel Mack #define BPF_CGROUP_RUN_PROG_INET_INGRESS(sk,skb) ({ 0; })
19030070984SDaniel Mack #define BPF_CGROUP_RUN_PROG_INET_EGRESS(sk,skb) ({ 0; })
19161023658SDavid Ahern #define BPF_CGROUP_RUN_PROG_INET_SOCK(sk) ({ 0; })
1924fbac77dSAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET4_BIND(sk, uaddr) ({ 0; })
1934fbac77dSAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET6_BIND(sk, uaddr) ({ 0; })
194*aac3fc32SAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET4_POST_BIND(sk) ({ 0; })
195*aac3fc32SAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET6_POST_BIND(sk) ({ 0; })
196d74bad4eSAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET4_CONNECT(sk, uaddr) ({ 0; })
197d74bad4eSAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET4_CONNECT_LOCK(sk, uaddr) ({ 0; })
198d74bad4eSAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET6_CONNECT(sk, uaddr) ({ 0; })
199d74bad4eSAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET6_CONNECT_LOCK(sk, uaddr) ({ 0; })
20040304b2aSLawrence Brakmo #define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) ({ 0; })
201ebc614f6SRoman Gushchin #define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(type,major,minor,access) ({ 0; })
20230070984SDaniel Mack 
20330070984SDaniel Mack #endif /* CONFIG_CGROUP_BPF */
20430070984SDaniel Mack 
20530070984SDaniel Mack #endif /* _BPF_CGROUP_H */
206