This patch defines BPF_CGROUP_RUN_PROG_SOCKINIT() helper, and implements __cgroup_bpf_run_sockinit() helper to run a sockinit program. Signed-off-by: Geliang Tang <geliang.tang@xxxxxxxx> --- include/linux/bpf-cgroup-defs.h | 1 + include/linux/bpf-cgroup.h | 14 ++++++++++++++ kernel/bpf/cgroup.c | 24 ++++++++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/include/linux/bpf-cgroup-defs.h b/include/linux/bpf-cgroup-defs.h index 7b121bd780eb..aa9ee82f5d20 100644 --- a/include/linux/bpf-cgroup-defs.h +++ b/include/linux/bpf-cgroup-defs.h @@ -37,6 +37,7 @@ enum cgroup_bpf_attach_type { CGROUP_UDP6_RECVMSG, CGROUP_GETSOCKOPT, CGROUP_SETSOCKOPT, + CGROUP_SOCKINIT, CGROUP_INET4_GETPEERNAME, CGROUP_INET6_GETPEERNAME, CGROUP_INET4_GETSOCKNAME, diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h index 57e9e109257e..a2f58f0d2260 100644 --- a/include/linux/bpf-cgroup.h +++ b/include/linux/bpf-cgroup.h @@ -57,6 +57,7 @@ to_cgroup_bpf_attach_type(enum bpf_attach_type attach_type) CGROUP_ATYPE(CGROUP_UDP6_RECVMSG); CGROUP_ATYPE(CGROUP_GETSOCKOPT); CGROUP_ATYPE(CGROUP_SETSOCKOPT); + CGROUP_ATYPE(CGROUP_SOCKINIT); CGROUP_ATYPE(CGROUP_INET4_GETPEERNAME); CGROUP_ATYPE(CGROUP_INET6_GETPEERNAME); CGROUP_ATYPE(CGROUP_INET4_GETSOCKNAME); @@ -148,6 +149,9 @@ int __cgroup_bpf_run_filter_getsockopt_kern(struct sock *sk, int level, int optname, void *optval, int *optlen, int retval); +int __cgroup_bpf_run_sockinit(int *family, int *type, int *protocol, + enum cgroup_bpf_attach_type atype); + static inline enum bpf_cgroup_storage_type cgroup_storage_type( struct bpf_map *map) { @@ -407,6 +411,15 @@ static inline bool cgroup_bpf_sock_enabled(struct sock *sk, __ret; \ }) +#define BPF_CGROUP_RUN_PROG_SOCKINIT(family, type, protocol) \ +({ \ + int __ret = 0; \ + if (cgroup_bpf_enabled(CGROUP_SOCKINIT)) \ + __ret = __cgroup_bpf_run_sockinit(family, type, protocol, \ + CGROUP_SOCKINIT); \ + __ret; \ +}) + int cgroup_bpf_prog_attach(const union bpf_attr *attr, enum bpf_prog_type ptype, struct bpf_prog *prog); int cgroup_bpf_prog_detach(const union bpf_attr *attr, @@ -505,6 +518,7 @@ static inline int bpf_percpu_cgroup_storage_update(struct bpf_map *map, optlen, retval) ({ retval; }) #define BPF_CGROUP_RUN_PROG_SETSOCKOPT(sock, level, optname, optval, optlen, \ kernel_optval) ({ 0; }) +#define BPF_CGROUP_RUN_PROG_SOCKINIT(family, type, protocol) ({ 0; }) #define for_each_cgroup_storage_type(stype) for (; false; ) diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c index 93b9f404a007..fe294e4d618c 100644 --- a/kernel/bpf/cgroup.c +++ b/kernel/bpf/cgroup.c @@ -1996,6 +1996,30 @@ int __cgroup_bpf_run_filter_getsockopt_kern(struct sock *sk, int level, return ret; } + +int __cgroup_bpf_run_sockinit(int *family, int *type, int *protocol, + enum cgroup_bpf_attach_type atype) +{ + struct bpf_sockinit_ctx ctx = { + .family = *family, + .type = *type, + .protocol = *protocol, + }; + struct cgroup *cgrp; + int ret; + + rcu_read_lock(); + cgrp = task_dfl_cgroup(current); + ret = bpf_prog_run_array_cg(&cgrp->bpf, atype, &ctx, bpf_prog_run, 0, + NULL); + rcu_read_unlock(); + + *family = ctx.family; + *type = ctx.type; + *protocol = ctx.protocol; + + return ret; +} #endif static ssize_t sysctl_cpy_dir(const struct ctl_dir *dir, char **bufp, -- 2.35.3