1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _BPF_CGROUP_H 3 #define _BPF_CGROUP_H 4 5 #include <linux/jump_label.h> 6 #include <uapi/linux/bpf.h> 7 8 struct sock; 9 struct sockaddr; 10 struct cgroup; 11 struct sk_buff; 12 struct bpf_sock_ops_kern; 13 14 #ifdef CONFIG_CGROUP_BPF 15 16 extern struct static_key_false cgroup_bpf_enabled_key; 17 #define cgroup_bpf_enabled static_branch_unlikely(&cgroup_bpf_enabled_key) 18 19 struct bpf_prog_list { 20 struct list_head node; 21 struct bpf_prog *prog; 22 }; 23 24 struct bpf_prog_array; 25 26 struct cgroup_bpf { 27 /* array of effective progs in this cgroup */ 28 struct bpf_prog_array __rcu *effective[MAX_BPF_ATTACH_TYPE]; 29 30 /* attached progs to this cgroup and attach flags 31 * when flags == 0 or BPF_F_ALLOW_OVERRIDE the progs list will 32 * have either zero or one element 33 * when BPF_F_ALLOW_MULTI the list can have up to BPF_CGROUP_MAX_PROGS 34 */ 35 struct list_head progs[MAX_BPF_ATTACH_TYPE]; 36 u32 flags[MAX_BPF_ATTACH_TYPE]; 37 38 /* temp storage for effective prog array used by prog_attach/detach */ 39 struct bpf_prog_array __rcu *inactive; 40 }; 41 42 void cgroup_bpf_put(struct cgroup *cgrp); 43 int cgroup_bpf_inherit(struct cgroup *cgrp); 44 45 int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog, 46 enum bpf_attach_type type, u32 flags); 47 int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog, 48 enum bpf_attach_type type, u32 flags); 49 int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr, 50 union bpf_attr __user *uattr); 51 52 /* Wrapper for __cgroup_bpf_*() protected by cgroup_mutex */ 53 int cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog, 54 enum bpf_attach_type type, u32 flags); 55 int cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog, 56 enum bpf_attach_type type, u32 flags); 57 int cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr, 58 union bpf_attr __user *uattr); 59 60 int __cgroup_bpf_run_filter_skb(struct sock *sk, 61 struct sk_buff *skb, 62 enum bpf_attach_type type); 63 64 int __cgroup_bpf_run_filter_sk(struct sock *sk, 65 enum bpf_attach_type type); 66 67 int __cgroup_bpf_run_filter_sock_addr(struct sock *sk, 68 struct sockaddr *uaddr, 69 enum bpf_attach_type type, 70 void *t_ctx); 71 72 int __cgroup_bpf_run_filter_sock_ops(struct sock *sk, 73 struct bpf_sock_ops_kern *sock_ops, 74 enum bpf_attach_type type); 75 76 int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor, 77 short access, enum bpf_attach_type type); 78 79 /* Wrappers for __cgroup_bpf_run_filter_skb() guarded by cgroup_bpf_enabled. */ 80 #define BPF_CGROUP_RUN_PROG_INET_INGRESS(sk, skb) \ 81 ({ \ 82 int __ret = 0; \ 83 if (cgroup_bpf_enabled) \ 84 __ret = __cgroup_bpf_run_filter_skb(sk, skb, \ 85 BPF_CGROUP_INET_INGRESS); \ 86 \ 87 __ret; \ 88 }) 89 90 #define BPF_CGROUP_RUN_PROG_INET_EGRESS(sk, skb) \ 91 ({ \ 92 int __ret = 0; \ 93 if (cgroup_bpf_enabled && sk && sk == skb->sk) { \ 94 typeof(sk) __sk = sk_to_full_sk(sk); \ 95 if (sk_fullsock(__sk)) \ 96 __ret = __cgroup_bpf_run_filter_skb(__sk, skb, \ 97 BPF_CGROUP_INET_EGRESS); \ 98 } \ 99 __ret; \ 100 }) 101 102 #define BPF_CGROUP_RUN_SK_PROG(sk, type) \ 103 ({ \ 104 int __ret = 0; \ 105 if (cgroup_bpf_enabled) { \ 106 __ret = __cgroup_bpf_run_filter_sk(sk, type); \ 107 } \ 108 __ret; \ 109 }) 110 111 #define BPF_CGROUP_RUN_PROG_INET_SOCK(sk) \ 112 BPF_CGROUP_RUN_SK_PROG(sk, BPF_CGROUP_INET_SOCK_CREATE) 113 114 #define BPF_CGROUP_RUN_PROG_INET4_POST_BIND(sk) \ 115 BPF_CGROUP_RUN_SK_PROG(sk, BPF_CGROUP_INET4_POST_BIND) 116 117 #define BPF_CGROUP_RUN_PROG_INET6_POST_BIND(sk) \ 118 BPF_CGROUP_RUN_SK_PROG(sk, BPF_CGROUP_INET6_POST_BIND) 119 120 #define BPF_CGROUP_RUN_SA_PROG(sk, uaddr, type) \ 121 ({ \ 122 int __ret = 0; \ 123 if (cgroup_bpf_enabled) \ 124 __ret = __cgroup_bpf_run_filter_sock_addr(sk, uaddr, type, \ 125 NULL); \ 126 __ret; \ 127 }) 128 129 #define BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, type, t_ctx) \ 130 ({ \ 131 int __ret = 0; \ 132 if (cgroup_bpf_enabled) { \ 133 lock_sock(sk); \ 134 __ret = __cgroup_bpf_run_filter_sock_addr(sk, uaddr, type, \ 135 t_ctx); \ 136 release_sock(sk); \ 137 } \ 138 __ret; \ 139 }) 140 141 #define BPF_CGROUP_RUN_PROG_INET4_BIND(sk, uaddr) \ 142 BPF_CGROUP_RUN_SA_PROG(sk, uaddr, BPF_CGROUP_INET4_BIND) 143 144 #define BPF_CGROUP_RUN_PROG_INET6_BIND(sk, uaddr) \ 145 BPF_CGROUP_RUN_SA_PROG(sk, uaddr, BPF_CGROUP_INET6_BIND) 146 147 #define BPF_CGROUP_PRE_CONNECT_ENABLED(sk) (cgroup_bpf_enabled && \ 148 sk->sk_prot->pre_connect) 149 150 #define BPF_CGROUP_RUN_PROG_INET4_CONNECT(sk, uaddr) \ 151 BPF_CGROUP_RUN_SA_PROG(sk, uaddr, BPF_CGROUP_INET4_CONNECT) 152 153 #define BPF_CGROUP_RUN_PROG_INET6_CONNECT(sk, uaddr) \ 154 BPF_CGROUP_RUN_SA_PROG(sk, uaddr, BPF_CGROUP_INET6_CONNECT) 155 156 #define BPF_CGROUP_RUN_PROG_INET4_CONNECT_LOCK(sk, uaddr) \ 157 BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, BPF_CGROUP_INET4_CONNECT, NULL) 158 159 #define BPF_CGROUP_RUN_PROG_INET6_CONNECT_LOCK(sk, uaddr) \ 160 BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, BPF_CGROUP_INET6_CONNECT, NULL) 161 162 #define BPF_CGROUP_RUN_PROG_UDP4_SENDMSG_LOCK(sk, uaddr, t_ctx) \ 163 BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, BPF_CGROUP_UDP4_SENDMSG, t_ctx) 164 165 #define BPF_CGROUP_RUN_PROG_UDP6_SENDMSG_LOCK(sk, uaddr, t_ctx) \ 166 BPF_CGROUP_RUN_SA_PROG_LOCK(sk, uaddr, BPF_CGROUP_UDP6_SENDMSG, t_ctx) 167 168 #define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) \ 169 ({ \ 170 int __ret = 0; \ 171 if (cgroup_bpf_enabled && (sock_ops)->sk) { \ 172 typeof(sk) __sk = sk_to_full_sk((sock_ops)->sk); \ 173 if (__sk && sk_fullsock(__sk)) \ 174 __ret = __cgroup_bpf_run_filter_sock_ops(__sk, \ 175 sock_ops, \ 176 BPF_CGROUP_SOCK_OPS); \ 177 } \ 178 __ret; \ 179 }) 180 181 #define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(type, major, minor, access) \ 182 ({ \ 183 int __ret = 0; \ 184 if (cgroup_bpf_enabled) \ 185 __ret = __cgroup_bpf_check_dev_permission(type, major, minor, \ 186 access, \ 187 BPF_CGROUP_DEVICE); \ 188 \ 189 __ret; \ 190 }) 191 #else 192 193 struct cgroup_bpf {}; 194 static inline void cgroup_bpf_put(struct cgroup *cgrp) {} 195 static inline int cgroup_bpf_inherit(struct cgroup *cgrp) { return 0; } 196 197 #define cgroup_bpf_enabled (0) 198 #define BPF_CGROUP_PRE_CONNECT_ENABLED(sk) (0) 199 #define BPF_CGROUP_RUN_PROG_INET_INGRESS(sk,skb) ({ 0; }) 200 #define BPF_CGROUP_RUN_PROG_INET_EGRESS(sk,skb) ({ 0; }) 201 #define BPF_CGROUP_RUN_PROG_INET_SOCK(sk) ({ 0; }) 202 #define BPF_CGROUP_RUN_PROG_INET4_BIND(sk, uaddr) ({ 0; }) 203 #define BPF_CGROUP_RUN_PROG_INET6_BIND(sk, uaddr) ({ 0; }) 204 #define BPF_CGROUP_RUN_PROG_INET4_POST_BIND(sk) ({ 0; }) 205 #define BPF_CGROUP_RUN_PROG_INET6_POST_BIND(sk) ({ 0; }) 206 #define BPF_CGROUP_RUN_PROG_INET4_CONNECT(sk, uaddr) ({ 0; }) 207 #define BPF_CGROUP_RUN_PROG_INET4_CONNECT_LOCK(sk, uaddr) ({ 0; }) 208 #define BPF_CGROUP_RUN_PROG_INET6_CONNECT(sk, uaddr) ({ 0; }) 209 #define BPF_CGROUP_RUN_PROG_INET6_CONNECT_LOCK(sk, uaddr) ({ 0; }) 210 #define BPF_CGROUP_RUN_PROG_UDP4_SENDMSG_LOCK(sk, uaddr, t_ctx) ({ 0; }) 211 #define BPF_CGROUP_RUN_PROG_UDP6_SENDMSG_LOCK(sk, uaddr, t_ctx) ({ 0; }) 212 #define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) ({ 0; }) 213 #define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(type,major,minor,access) ({ 0; }) 214 215 #endif /* CONFIG_CGROUP_BPF */ 216 217 #endif /* _BPF_CGROUP_H */ 218