As far as api the attach should probably be to a cgroup+lsm_hook pair. link_create.target_fd will be cgroup_fd. At prog load time attach_btf_id should probably be one of existing bpf_lsm_* hooks. Feels wrong to duplicate the whole set into lsm_cgroup_sock set. It's fine to have prog->expected_attach_type == BPF_LSM_CGROUP_SOCK to disambiguate. Will we probably only have two: BPF_LSM_CGROUP_SOCK and BPF_LSM_CGROUP_TASK ? > +int __cgroup_bpf_run_lsm_sock(u64 *regs, const struct bpf_prog *prog) > +{ > + struct socket *sock = (void *)regs[BPF_REG_0]; > + struct cgroup *cgrp; > + struct sock *sk; > + > + sk = sock->sk; > + if (!sk) > + return 0; > + > + cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data); > + > + return BPF_PROG_RUN_ARRAY_CG(cgrp->bpf.effective[prog->aux->cgroup_atype], > + regs, bpf_prog_run, 0); > +} Would it be fast enough? We went through a bunch of optimization for normal cgroup and ended with: if (cgroup_bpf_enabled(CGROUP_INET_INGRESS) && cgroup_bpf_sock_enabled(sk, CGROUP_INET_INGRESS)) Here the trampoline code plus call into __cgroup_bpf_run_lsm_sock will be there for all cgroups. Since cgroup specific check will be inside BPF_PROG_RUN_ARRAY_CG. I suspect it's ok, since the link_create will be for few specific lsm hooks which are typically not in the fast path. Unlike traditional cgroup hook like ingress that is hot. For BPF_LSM_CGROUP_TASK it will take cgroup from current instead of sock, right? Args access should magically work. 'regs' above should be fine for all lsm hooks. The typical prog: +SEC("lsm_cgroup_sock/socket_post_create") +int BPF_PROG(socket_post_create, struct socket *sock, int family, + int type, int protocol, int kern) looks good too. Feel natural. I guess they can be sleepable too?