1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 230070984SDaniel Mack #ifndef _BPF_CGROUP_H 330070984SDaniel Mack #define _BPF_CGROUP_H 430070984SDaniel Mack 5*f292b87dSRoman Gushchin #include <linux/errno.h> 630070984SDaniel Mack #include <linux/jump_label.h> 730070984SDaniel Mack #include <uapi/linux/bpf.h> 830070984SDaniel Mack 930070984SDaniel Mack struct sock; 104fbac77dSAndrey Ignatov struct sockaddr; 1130070984SDaniel Mack struct cgroup; 1230070984SDaniel Mack struct sk_buff; 1340304b2aSLawrence Brakmo struct bpf_sock_ops_kern; 1430070984SDaniel Mack 1530070984SDaniel Mack #ifdef CONFIG_CGROUP_BPF 1630070984SDaniel Mack 1730070984SDaniel Mack extern struct static_key_false cgroup_bpf_enabled_key; 1830070984SDaniel Mack #define cgroup_bpf_enabled static_branch_unlikely(&cgroup_bpf_enabled_key) 1930070984SDaniel Mack 20324bda9eSAlexei Starovoitov struct bpf_prog_list { 21324bda9eSAlexei Starovoitov struct list_head node; 22324bda9eSAlexei Starovoitov struct bpf_prog *prog; 23324bda9eSAlexei Starovoitov }; 24324bda9eSAlexei Starovoitov 25324bda9eSAlexei Starovoitov struct bpf_prog_array; 26324bda9eSAlexei Starovoitov 2730070984SDaniel Mack struct cgroup_bpf { 28324bda9eSAlexei Starovoitov /* array of effective progs in this cgroup */ 29324bda9eSAlexei Starovoitov struct bpf_prog_array __rcu *effective[MAX_BPF_ATTACH_TYPE]; 30324bda9eSAlexei Starovoitov 31324bda9eSAlexei Starovoitov /* attached progs to this cgroup and attach flags 32324bda9eSAlexei Starovoitov * when flags == 0 or BPF_F_ALLOW_OVERRIDE the progs list will 33324bda9eSAlexei Starovoitov * have either zero or one element 34324bda9eSAlexei Starovoitov * when BPF_F_ALLOW_MULTI the list can have up to BPF_CGROUP_MAX_PROGS 3530070984SDaniel Mack */ 36324bda9eSAlexei Starovoitov struct list_head progs[MAX_BPF_ATTACH_TYPE]; 37324bda9eSAlexei Starovoitov u32 flags[MAX_BPF_ATTACH_TYPE]; 38324bda9eSAlexei Starovoitov 39324bda9eSAlexei Starovoitov /* temp storage for effective prog array used by prog_attach/detach */ 40324bda9eSAlexei Starovoitov struct bpf_prog_array __rcu *inactive; 4130070984SDaniel Mack }; 4230070984SDaniel Mack 4330070984SDaniel Mack void cgroup_bpf_put(struct cgroup *cgrp); 44324bda9eSAlexei Starovoitov int cgroup_bpf_inherit(struct cgroup *cgrp); 4530070984SDaniel Mack 46324bda9eSAlexei Starovoitov int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog, 47324bda9eSAlexei Starovoitov enum bpf_attach_type type, u32 flags); 48324bda9eSAlexei Starovoitov int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog, 49324bda9eSAlexei Starovoitov enum bpf_attach_type type, u32 flags); 50468e2f64SAlexei Starovoitov int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr, 51468e2f64SAlexei Starovoitov union bpf_attr __user *uattr); 5230070984SDaniel Mack 53324bda9eSAlexei Starovoitov /* Wrapper for __cgroup_bpf_*() protected by cgroup_mutex */ 54324bda9eSAlexei Starovoitov int cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog, 55324bda9eSAlexei Starovoitov enum bpf_attach_type type, u32 flags); 56324bda9eSAlexei Starovoitov int cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog, 57324bda9eSAlexei Starovoitov enum bpf_attach_type type, u32 flags); 58468e2f64SAlexei Starovoitov int cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr, 59468e2f64SAlexei Starovoitov union bpf_attr __user *uattr); 6030070984SDaniel Mack 61b2cd1257SDavid Ahern int __cgroup_bpf_run_filter_skb(struct sock *sk, 6230070984SDaniel Mack struct sk_buff *skb, 6330070984SDaniel Mack enum bpf_attach_type type); 6430070984SDaniel Mack 6561023658SDavid Ahern int __cgroup_bpf_run_filter_sk(struct sock *sk, 6661023658SDavid Ahern enum bpf_attach_type type); 6761023658SDavid Ahern 684fbac77dSAndrey Ignatov int __cgroup_bpf_run_filter_sock_addr(struct sock *sk, 694fbac77dSAndrey Ignatov struct sockaddr *uaddr, 701cedee13SAndrey Ignatov enum bpf_attach_type type, 711cedee13SAndrey Ignatov void *t_ctx); 724fbac77dSAndrey Ignatov 7340304b2aSLawrence Brakmo int __cgroup_bpf_run_filter_sock_ops(struct sock *sk, 7440304b2aSLawrence Brakmo struct bpf_sock_ops_kern *sock_ops, 7540304b2aSLawrence Brakmo enum bpf_attach_type type); 7640304b2aSLawrence Brakmo 77ebc614f6SRoman Gushchin int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor, 78ebc614f6SRoman Gushchin short access, enum bpf_attach_type type); 79ebc614f6SRoman Gushchin 80b2cd1257SDavid Ahern /* Wrappers for __cgroup_bpf_run_filter_skb() guarded by cgroup_bpf_enabled. */ 8130070984SDaniel Mack #define BPF_CGROUP_RUN_PROG_INET_INGRESS(sk, skb) \ 8230070984SDaniel Mack ({ \ 8330070984SDaniel Mack int __ret = 0; \ 8430070984SDaniel Mack if (cgroup_bpf_enabled) \ 85b2cd1257SDavid Ahern __ret = __cgroup_bpf_run_filter_skb(sk, skb, \ 8630070984SDaniel Mack BPF_CGROUP_INET_INGRESS); \ 8730070984SDaniel Mack \ 8830070984SDaniel Mack __ret; \ 8930070984SDaniel Mack }) 9030070984SDaniel Mack 9130070984SDaniel Mack #define BPF_CGROUP_RUN_PROG_INET_EGRESS(sk, skb) \ 9230070984SDaniel Mack ({ \ 9330070984SDaniel Mack int __ret = 0; \ 9430070984SDaniel Mack if (cgroup_bpf_enabled && sk && sk == skb->sk) { \ 9530070984SDaniel Mack typeof(sk) __sk = sk_to_full_sk(sk); \ 9630070984SDaniel Mack if (sk_fullsock(__sk)) \ 97b2cd1257SDavid Ahern __ret = __cgroup_bpf_run_filter_skb(__sk, skb, \ 9830070984SDaniel Mack BPF_CGROUP_INET_EGRESS); \ 9930070984SDaniel Mack } \ 10030070984SDaniel Mack __ret; \ 10130070984SDaniel Mack }) 10230070984SDaniel Mack 103aac3fc32SAndrey Ignatov #define BPF_CGROUP_RUN_SK_PROG(sk, type) \ 10461023658SDavid Ahern ({ \ 10561023658SDavid Ahern int __ret = 0; \ 106ee07862fSYafang Shao if (cgroup_bpf_enabled) { \ 107aac3fc32SAndrey Ignatov __ret = __cgroup_bpf_run_filter_sk(sk, type); \ 10861023658SDavid Ahern } \ 10961023658SDavid Ahern __ret; \ 11061023658SDavid Ahern }) 11161023658SDavid Ahern 112aac3fc32SAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET_SOCK(sk) \ 113aac3fc32SAndrey Ignatov BPF_CGROUP_RUN_SK_PROG(sk, BPF_CGROUP_INET_SOCK_CREATE) 114aac3fc32SAndrey Ignatov 115aac3fc32SAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET4_POST_BIND(sk) \ 116aac3fc32SAndrey Ignatov BPF_CGROUP_RUN_SK_PROG(sk, BPF_CGROUP_INET4_POST_BIND) 117aac3fc32SAndrey Ignatov 118aac3fc32SAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET6_POST_BIND(sk) \ 119aac3fc32SAndrey Ignatov BPF_CGROUP_RUN_SK_PROG(sk, BPF_CGROUP_INET6_POST_BIND) 120aac3fc32SAndrey Ignatov 1214fbac77dSAndrey Ignatov #define BPF_CGROUP_RUN_SA_PROG(sk, uaddr, type) \ 1224fbac77dSAndrey Ignatov ({ \ 1234fbac77dSAndrey Ignatov int __ret = 0; \ 1244fbac77dSAndrey Ignatov if (cgroup_bpf_enabled) \ 1251cedee13SAndrey Ignatov __ret = __cgroup_bpf_run_filter_sock_addr(sk, uaddr, type, \ 1261cedee13SAndrey Ignatov NULL); \ 1274fbac77dSAndrey Ignatov __ret; \ 1284fbac77dSAndrey Ignatov }) 1294fbac77dSAndrey Ignatov 1301cedee13SAndrey Ignatov #define BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, type, t_ctx) \ 131d74bad4eSAndrey Ignatov ({ \ 132d74bad4eSAndrey Ignatov int __ret = 0; \ 133d74bad4eSAndrey Ignatov if (cgroup_bpf_enabled) { \ 134d74bad4eSAndrey Ignatov lock_sock(sk); \ 1351cedee13SAndrey Ignatov __ret = __cgroup_bpf_run_filter_sock_addr(sk, uaddr, type, \ 1361cedee13SAndrey Ignatov t_ctx); \ 137d74bad4eSAndrey Ignatov release_sock(sk); \ 138d74bad4eSAndrey Ignatov } \ 139d74bad4eSAndrey Ignatov __ret; \ 140d74bad4eSAndrey Ignatov }) 141d74bad4eSAndrey Ignatov 1424fbac77dSAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET4_BIND(sk, uaddr) \ 1434fbac77dSAndrey Ignatov BPF_CGROUP_RUN_SA_PROG(sk, uaddr, BPF_CGROUP_INET4_BIND) 1444fbac77dSAndrey Ignatov 1454fbac77dSAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET6_BIND(sk, uaddr) \ 1464fbac77dSAndrey Ignatov BPF_CGROUP_RUN_SA_PROG(sk, uaddr, BPF_CGROUP_INET6_BIND) 1474fbac77dSAndrey Ignatov 148d74bad4eSAndrey Ignatov #define BPF_CGROUP_PRE_CONNECT_ENABLED(sk) (cgroup_bpf_enabled && \ 149d74bad4eSAndrey Ignatov sk->sk_prot->pre_connect) 150d74bad4eSAndrey Ignatov 151d74bad4eSAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET4_CONNECT(sk, uaddr) \ 152d74bad4eSAndrey Ignatov BPF_CGROUP_RUN_SA_PROG(sk, uaddr, BPF_CGROUP_INET4_CONNECT) 153d74bad4eSAndrey Ignatov 154d74bad4eSAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET6_CONNECT(sk, uaddr) \ 155d74bad4eSAndrey Ignatov BPF_CGROUP_RUN_SA_PROG(sk, uaddr, BPF_CGROUP_INET6_CONNECT) 156d74bad4eSAndrey Ignatov 157d74bad4eSAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET4_CONNECT_LOCK(sk, uaddr) \ 1581cedee13SAndrey Ignatov BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, BPF_CGROUP_INET4_CONNECT, NULL) 159d74bad4eSAndrey Ignatov 160d74bad4eSAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET6_CONNECT_LOCK(sk, uaddr) \ 1611cedee13SAndrey Ignatov BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, BPF_CGROUP_INET6_CONNECT, NULL) 1621cedee13SAndrey Ignatov 1631cedee13SAndrey Ignatov #define BPF_CGROUP_RUN_PROG_UDP4_SENDMSG_LOCK(sk, uaddr, t_ctx) \ 1641cedee13SAndrey Ignatov BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, BPF_CGROUP_UDP4_SENDMSG, t_ctx) 1651cedee13SAndrey Ignatov 1661cedee13SAndrey Ignatov #define BPF_CGROUP_RUN_PROG_UDP6_SENDMSG_LOCK(sk, uaddr, t_ctx) \ 1671cedee13SAndrey Ignatov BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, BPF_CGROUP_UDP6_SENDMSG, t_ctx) 168d74bad4eSAndrey Ignatov 16940304b2aSLawrence Brakmo #define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) \ 17040304b2aSLawrence Brakmo ({ \ 17140304b2aSLawrence Brakmo int __ret = 0; \ 17240304b2aSLawrence Brakmo if (cgroup_bpf_enabled && (sock_ops)->sk) { \ 17340304b2aSLawrence Brakmo typeof(sk) __sk = sk_to_full_sk((sock_ops)->sk); \ 174df39a9f1SWANG Cong if (__sk && sk_fullsock(__sk)) \ 17540304b2aSLawrence Brakmo __ret = __cgroup_bpf_run_filter_sock_ops(__sk, \ 17640304b2aSLawrence Brakmo sock_ops, \ 17740304b2aSLawrence Brakmo BPF_CGROUP_SOCK_OPS); \ 17840304b2aSLawrence Brakmo } \ 17940304b2aSLawrence Brakmo __ret; \ 18040304b2aSLawrence Brakmo }) 181ebc614f6SRoman Gushchin 182ebc614f6SRoman Gushchin #define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(type, major, minor, access) \ 183ebc614f6SRoman Gushchin ({ \ 184ebc614f6SRoman Gushchin int __ret = 0; \ 185ebc614f6SRoman Gushchin if (cgroup_bpf_enabled) \ 186ebc614f6SRoman Gushchin __ret = __cgroup_bpf_check_dev_permission(type, major, minor, \ 187ebc614f6SRoman Gushchin access, \ 188ebc614f6SRoman Gushchin BPF_CGROUP_DEVICE); \ 189ebc614f6SRoman Gushchin \ 190ebc614f6SRoman Gushchin __ret; \ 191ebc614f6SRoman Gushchin }) 192fdb5c453SSean Young int cgroup_bpf_prog_attach(const union bpf_attr *attr, 193fdb5c453SSean Young enum bpf_prog_type ptype, struct bpf_prog *prog); 194fdb5c453SSean Young int cgroup_bpf_prog_detach(const union bpf_attr *attr, 195fdb5c453SSean Young enum bpf_prog_type ptype); 196fdb5c453SSean Young int cgroup_bpf_prog_query(const union bpf_attr *attr, 197fdb5c453SSean Young union bpf_attr __user *uattr); 19830070984SDaniel Mack #else 19930070984SDaniel Mack 200fdb5c453SSean Young struct bpf_prog; 20130070984SDaniel Mack struct cgroup_bpf {}; 20230070984SDaniel Mack static inline void cgroup_bpf_put(struct cgroup *cgrp) {} 203324bda9eSAlexei Starovoitov static inline int cgroup_bpf_inherit(struct cgroup *cgrp) { return 0; } 20430070984SDaniel Mack 205fdb5c453SSean Young static inline int cgroup_bpf_prog_attach(const union bpf_attr *attr, 206fdb5c453SSean Young enum bpf_prog_type ptype, 207fdb5c453SSean Young struct bpf_prog *prog) 208fdb5c453SSean Young { 209fdb5c453SSean Young return -EINVAL; 210fdb5c453SSean Young } 211fdb5c453SSean Young 212fdb5c453SSean Young static inline int cgroup_bpf_prog_detach(const union bpf_attr *attr, 213fdb5c453SSean Young enum bpf_prog_type ptype) 214fdb5c453SSean Young { 215fdb5c453SSean Young return -EINVAL; 216fdb5c453SSean Young } 217fdb5c453SSean Young 218fdb5c453SSean Young static inline int cgroup_bpf_prog_query(const union bpf_attr *attr, 219fdb5c453SSean Young union bpf_attr __user *uattr) 220fdb5c453SSean Young { 221fdb5c453SSean Young return -EINVAL; 222fdb5c453SSean Young } 223fdb5c453SSean Young 22413193b0fSAndrey Ignatov #define cgroup_bpf_enabled (0) 225d74bad4eSAndrey Ignatov #define BPF_CGROUP_PRE_CONNECT_ENABLED(sk) (0) 22630070984SDaniel Mack #define BPF_CGROUP_RUN_PROG_INET_INGRESS(sk,skb) ({ 0; }) 22730070984SDaniel Mack #define BPF_CGROUP_RUN_PROG_INET_EGRESS(sk,skb) ({ 0; }) 22861023658SDavid Ahern #define BPF_CGROUP_RUN_PROG_INET_SOCK(sk) ({ 0; }) 2294fbac77dSAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET4_BIND(sk, uaddr) ({ 0; }) 2304fbac77dSAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET6_BIND(sk, uaddr) ({ 0; }) 231aac3fc32SAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET4_POST_BIND(sk) ({ 0; }) 232aac3fc32SAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET6_POST_BIND(sk) ({ 0; }) 233d74bad4eSAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET4_CONNECT(sk, uaddr) ({ 0; }) 234d74bad4eSAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET4_CONNECT_LOCK(sk, uaddr) ({ 0; }) 235d74bad4eSAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET6_CONNECT(sk, uaddr) ({ 0; }) 236d74bad4eSAndrey Ignatov #define BPF_CGROUP_RUN_PROG_INET6_CONNECT_LOCK(sk, uaddr) ({ 0; }) 2371cedee13SAndrey Ignatov #define BPF_CGROUP_RUN_PROG_UDP4_SENDMSG_LOCK(sk, uaddr, t_ctx) ({ 0; }) 2381cedee13SAndrey Ignatov #define BPF_CGROUP_RUN_PROG_UDP6_SENDMSG_LOCK(sk, uaddr, t_ctx) ({ 0; }) 23940304b2aSLawrence Brakmo #define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) ({ 0; }) 240ebc614f6SRoman Gushchin #define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(type,major,minor,access) ({ 0; }) 24130070984SDaniel Mack 24230070984SDaniel Mack #endif /* CONFIG_CGROUP_BPF */ 24330070984SDaniel Mack 24430070984SDaniel Mack #endif /* _BPF_CGROUP_H */ 245