xref: /linux-6.15/include/linux/bpf-cgroup.h (revision ebc614f6)
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;
930070984SDaniel Mack struct cgroup;
1030070984SDaniel Mack struct sk_buff;
1140304b2aSLawrence Brakmo struct bpf_sock_ops_kern;
1230070984SDaniel Mack 
1330070984SDaniel Mack #ifdef CONFIG_CGROUP_BPF
1430070984SDaniel Mack 
1530070984SDaniel Mack extern struct static_key_false cgroup_bpf_enabled_key;
1630070984SDaniel Mack #define cgroup_bpf_enabled static_branch_unlikely(&cgroup_bpf_enabled_key)
1730070984SDaniel Mack 
18324bda9eSAlexei Starovoitov struct bpf_prog_list {
19324bda9eSAlexei Starovoitov 	struct list_head node;
20324bda9eSAlexei Starovoitov 	struct bpf_prog *prog;
21324bda9eSAlexei Starovoitov };
22324bda9eSAlexei Starovoitov 
23324bda9eSAlexei Starovoitov struct bpf_prog_array;
24324bda9eSAlexei Starovoitov 
2530070984SDaniel Mack struct cgroup_bpf {
26324bda9eSAlexei Starovoitov 	/* array of effective progs in this cgroup */
27324bda9eSAlexei Starovoitov 	struct bpf_prog_array __rcu *effective[MAX_BPF_ATTACH_TYPE];
28324bda9eSAlexei Starovoitov 
29324bda9eSAlexei Starovoitov 	/* attached progs to this cgroup and attach flags
30324bda9eSAlexei Starovoitov 	 * when flags == 0 or BPF_F_ALLOW_OVERRIDE the progs list will
31324bda9eSAlexei Starovoitov 	 * have either zero or one element
32324bda9eSAlexei Starovoitov 	 * when BPF_F_ALLOW_MULTI the list can have up to BPF_CGROUP_MAX_PROGS
3330070984SDaniel Mack 	 */
34324bda9eSAlexei Starovoitov 	struct list_head progs[MAX_BPF_ATTACH_TYPE];
35324bda9eSAlexei Starovoitov 	u32 flags[MAX_BPF_ATTACH_TYPE];
36324bda9eSAlexei Starovoitov 
37324bda9eSAlexei Starovoitov 	/* temp storage for effective prog array used by prog_attach/detach */
38324bda9eSAlexei Starovoitov 	struct bpf_prog_array __rcu *inactive;
3930070984SDaniel Mack };
4030070984SDaniel Mack 
4130070984SDaniel Mack void cgroup_bpf_put(struct cgroup *cgrp);
42324bda9eSAlexei Starovoitov int cgroup_bpf_inherit(struct cgroup *cgrp);
4330070984SDaniel Mack 
44324bda9eSAlexei Starovoitov int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog,
45324bda9eSAlexei Starovoitov 			enum bpf_attach_type type, u32 flags);
46324bda9eSAlexei Starovoitov int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
47324bda9eSAlexei Starovoitov 			enum bpf_attach_type type, u32 flags);
48468e2f64SAlexei Starovoitov int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
49468e2f64SAlexei Starovoitov 		       union bpf_attr __user *uattr);
5030070984SDaniel Mack 
51324bda9eSAlexei Starovoitov /* Wrapper for __cgroup_bpf_*() protected by cgroup_mutex */
52324bda9eSAlexei Starovoitov int cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog,
53324bda9eSAlexei Starovoitov 		      enum bpf_attach_type type, u32 flags);
54324bda9eSAlexei Starovoitov int cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
55324bda9eSAlexei Starovoitov 		      enum bpf_attach_type type, u32 flags);
56468e2f64SAlexei Starovoitov int cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
57468e2f64SAlexei Starovoitov 		     union bpf_attr __user *uattr);
5830070984SDaniel Mack 
59b2cd1257SDavid Ahern int __cgroup_bpf_run_filter_skb(struct sock *sk,
6030070984SDaniel Mack 				struct sk_buff *skb,
6130070984SDaniel Mack 				enum bpf_attach_type type);
6230070984SDaniel Mack 
6361023658SDavid Ahern int __cgroup_bpf_run_filter_sk(struct sock *sk,
6461023658SDavid Ahern 			       enum bpf_attach_type type);
6561023658SDavid Ahern 
6640304b2aSLawrence Brakmo int __cgroup_bpf_run_filter_sock_ops(struct sock *sk,
6740304b2aSLawrence Brakmo 				     struct bpf_sock_ops_kern *sock_ops,
6840304b2aSLawrence Brakmo 				     enum bpf_attach_type type);
6940304b2aSLawrence Brakmo 
70*ebc614f6SRoman Gushchin int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor,
71*ebc614f6SRoman Gushchin 				      short access, enum bpf_attach_type type);
72*ebc614f6SRoman Gushchin 
73b2cd1257SDavid Ahern /* Wrappers for __cgroup_bpf_run_filter_skb() guarded by cgroup_bpf_enabled. */
7430070984SDaniel Mack #define BPF_CGROUP_RUN_PROG_INET_INGRESS(sk, skb)			      \
7530070984SDaniel Mack ({									      \
7630070984SDaniel Mack 	int __ret = 0;							      \
7730070984SDaniel Mack 	if (cgroup_bpf_enabled)						      \
78b2cd1257SDavid Ahern 		__ret = __cgroup_bpf_run_filter_skb(sk, skb,		      \
7930070984SDaniel Mack 						    BPF_CGROUP_INET_INGRESS); \
8030070984SDaniel Mack 									      \
8130070984SDaniel Mack 	__ret;								      \
8230070984SDaniel Mack })
8330070984SDaniel Mack 
8430070984SDaniel Mack #define BPF_CGROUP_RUN_PROG_INET_EGRESS(sk, skb)			       \
8530070984SDaniel Mack ({									       \
8630070984SDaniel Mack 	int __ret = 0;							       \
8730070984SDaniel Mack 	if (cgroup_bpf_enabled && sk && sk == skb->sk) {		       \
8830070984SDaniel Mack 		typeof(sk) __sk = sk_to_full_sk(sk);			       \
8930070984SDaniel Mack 		if (sk_fullsock(__sk))					       \
90b2cd1257SDavid Ahern 			__ret = __cgroup_bpf_run_filter_skb(__sk, skb,	       \
9130070984SDaniel Mack 						      BPF_CGROUP_INET_EGRESS); \
9230070984SDaniel Mack 	}								       \
9330070984SDaniel Mack 	__ret;								       \
9430070984SDaniel Mack })
9530070984SDaniel Mack 
9661023658SDavid Ahern #define BPF_CGROUP_RUN_PROG_INET_SOCK(sk)				       \
9761023658SDavid Ahern ({									       \
9861023658SDavid Ahern 	int __ret = 0;							       \
9961023658SDavid Ahern 	if (cgroup_bpf_enabled && sk) {					       \
10061023658SDavid Ahern 		__ret = __cgroup_bpf_run_filter_sk(sk,			       \
10161023658SDavid Ahern 						 BPF_CGROUP_INET_SOCK_CREATE); \
10261023658SDavid Ahern 	}								       \
10361023658SDavid Ahern 	__ret;								       \
10461023658SDavid Ahern })
10561023658SDavid Ahern 
10640304b2aSLawrence Brakmo #define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops)				       \
10740304b2aSLawrence Brakmo ({									       \
10840304b2aSLawrence Brakmo 	int __ret = 0;							       \
10940304b2aSLawrence Brakmo 	if (cgroup_bpf_enabled && (sock_ops)->sk) {	       \
11040304b2aSLawrence Brakmo 		typeof(sk) __sk = sk_to_full_sk((sock_ops)->sk);	       \
111df39a9f1SWANG Cong 		if (__sk && sk_fullsock(__sk))				       \
11240304b2aSLawrence Brakmo 			__ret = __cgroup_bpf_run_filter_sock_ops(__sk,	       \
11340304b2aSLawrence Brakmo 								 sock_ops,     \
11440304b2aSLawrence Brakmo 							 BPF_CGROUP_SOCK_OPS); \
11540304b2aSLawrence Brakmo 	}								       \
11640304b2aSLawrence Brakmo 	__ret;								       \
11740304b2aSLawrence Brakmo })
118*ebc614f6SRoman Gushchin 
119*ebc614f6SRoman Gushchin #define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(type, major, minor, access)	      \
120*ebc614f6SRoman Gushchin ({									      \
121*ebc614f6SRoman Gushchin 	int __ret = 0;							      \
122*ebc614f6SRoman Gushchin 	if (cgroup_bpf_enabled)						      \
123*ebc614f6SRoman Gushchin 		__ret = __cgroup_bpf_check_dev_permission(type, major, minor, \
124*ebc614f6SRoman Gushchin 							  access,	      \
125*ebc614f6SRoman Gushchin 							  BPF_CGROUP_DEVICE); \
126*ebc614f6SRoman Gushchin 									      \
127*ebc614f6SRoman Gushchin 	__ret;								      \
128*ebc614f6SRoman Gushchin })
12930070984SDaniel Mack #else
13030070984SDaniel Mack 
13130070984SDaniel Mack struct cgroup_bpf {};
13230070984SDaniel Mack static inline void cgroup_bpf_put(struct cgroup *cgrp) {}
133324bda9eSAlexei Starovoitov static inline int cgroup_bpf_inherit(struct cgroup *cgrp) { return 0; }
13430070984SDaniel Mack 
13530070984SDaniel Mack #define BPF_CGROUP_RUN_PROG_INET_INGRESS(sk,skb) ({ 0; })
13630070984SDaniel Mack #define BPF_CGROUP_RUN_PROG_INET_EGRESS(sk,skb) ({ 0; })
13761023658SDavid Ahern #define BPF_CGROUP_RUN_PROG_INET_SOCK(sk) ({ 0; })
13840304b2aSLawrence Brakmo #define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) ({ 0; })
139*ebc614f6SRoman Gushchin #define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(type,major,minor,access) ({ 0; })
14030070984SDaniel Mack 
14130070984SDaniel Mack #endif /* CONFIG_CGROUP_BPF */
14230070984SDaniel Mack 
14330070984SDaniel Mack #endif /* _BPF_CGROUP_H */
144