static const struct bpf_func_proto *
 bpf_lsm_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
 {
+       const struct bpf_func_proto *func_proto;
+
+       if (prog->expected_attach_type == BPF_LSM_CGROUP) {
+               func_proto = cgroup_common_func_proto(func_id, prog);
+               if (func_proto)
+                       return func_proto;
+       }
+
        switch (func_id) {
        case BPF_FUNC_inode_storage_get:
                return &bpf_inode_storage_get_proto;
                return prog->aux->sleepable ? &bpf_ima_file_hash_proto : NULL;
        case BPF_FUNC_get_attach_cookie:
                return bpf_prog_has_trampoline(prog) ? &bpf_get_attach_cookie_proto : NULL;
-       case BPF_FUNC_get_local_storage:
-               return prog->expected_attach_type == BPF_LSM_CGROUP ?
-                       &bpf_get_local_storage_proto : NULL;
-       case BPF_FUNC_set_retval:
-               return prog->expected_attach_type == BPF_LSM_CGROUP ?
-                       &bpf_set_retval_proto : NULL;
-       case BPF_FUNC_get_retval:
-               return prog->expected_attach_type == BPF_LSM_CGROUP ?
-                       &bpf_get_retval_proto : NULL;
 #ifdef CONFIG_NET
        case BPF_FUNC_setsockopt:
                if (prog->expected_attach_type != BPF_LSM_CGROUP)
 
        case BPF_FUNC_get_local_storage:
                return &bpf_get_local_storage_proto;
        case BPF_FUNC_get_retval:
-               return &bpf_get_retval_proto;
+               switch (prog->expected_attach_type) {
+               case BPF_CGROUP_INET_INGRESS:
+               case BPF_CGROUP_INET_EGRESS:
+               case BPF_CGROUP_SOCK_OPS:
+               case BPF_CGROUP_UDP4_RECVMSG:
+               case BPF_CGROUP_UDP6_RECVMSG:
+               case BPF_CGROUP_INET4_GETPEERNAME:
+               case BPF_CGROUP_INET6_GETPEERNAME:
+               case BPF_CGROUP_INET4_GETSOCKNAME:
+               case BPF_CGROUP_INET6_GETSOCKNAME:
+                       return NULL;
+               default:
+                       return &bpf_get_retval_proto;
+               }
        case BPF_FUNC_set_retval:
-               return &bpf_set_retval_proto;
+               switch (prog->expected_attach_type) {
+               case BPF_CGROUP_INET_INGRESS:
+               case BPF_CGROUP_INET_EGRESS:
+               case BPF_CGROUP_SOCK_OPS:
+               case BPF_CGROUP_UDP4_RECVMSG:
+               case BPF_CGROUP_UDP6_RECVMSG:
+               case BPF_CGROUP_INET4_GETPEERNAME:
+               case BPF_CGROUP_INET6_GETPEERNAME:
+               case BPF_CGROUP_INET4_GETSOCKNAME:
+               case BPF_CGROUP_INET6_GETSOCKNAME:
+                       return NULL;
+               default:
+                       return &bpf_set_retval_proto;
+               }
        default:
                return NULL;
        }
        switch (func_id) {
        case BPF_FUNC_get_current_uid_gid:
                return &bpf_get_current_uid_gid_proto;
+       case BPF_FUNC_get_current_pid_tgid:
+               return &bpf_get_current_pid_tgid_proto;
+       case BPF_FUNC_get_current_comm:
+               return &bpf_get_current_comm_proto;
        case BPF_FUNC_get_current_cgroup_id:
                return &bpf_get_current_cgroup_id_proto;
+       case BPF_FUNC_get_current_ancestor_cgroup_id:
+               return &bpf_get_current_ancestor_cgroup_id_proto;
+#ifdef CONFIG_CGROUP_NET_CLASSID
+       case BPF_FUNC_get_cgroup_classid:
+               return &bpf_get_cgroup_classid_curr_proto;
+#endif
        default:
                return NULL;
        }
 
        return __task_get_classid(current);
 }
 
-static const struct bpf_func_proto bpf_get_cgroup_classid_curr_proto = {
+const struct bpf_func_proto bpf_get_cgroup_classid_curr_proto = {
        .func           = bpf_get_cgroup_classid_curr,
        .gpl_only       = false,
        .ret_type       = RET_INTEGER,
 static const struct bpf_func_proto *
 sock_filter_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
 {
+       const struct bpf_func_proto *func_proto;
+
+       func_proto = cgroup_common_func_proto(func_id, prog);
+       if (func_proto)
+               return func_proto;
+
+       func_proto = cgroup_current_func_proto(func_id, prog);
+       if (func_proto)
+               return func_proto;
+
        switch (func_id) {
-       /* inet and inet6 sockets are created in a process
-        * context so there is always a valid uid/gid
-        */
-       case BPF_FUNC_get_current_uid_gid:
-               return &bpf_get_current_uid_gid_proto;
-       case BPF_FUNC_get_local_storage:
-               return &bpf_get_local_storage_proto;
        case BPF_FUNC_get_socket_cookie:
                return &bpf_get_socket_cookie_sock_proto;
        case BPF_FUNC_get_netns_cookie:
                return &bpf_get_netns_cookie_sock_proto;
        case BPF_FUNC_perf_event_output:
                return &bpf_event_output_data_proto;
-       case BPF_FUNC_get_current_pid_tgid:
-               return &bpf_get_current_pid_tgid_proto;
-       case BPF_FUNC_get_current_comm:
-               return &bpf_get_current_comm_proto;
-#ifdef CONFIG_CGROUPS
-       case BPF_FUNC_get_current_cgroup_id:
-               return &bpf_get_current_cgroup_id_proto;
-       case BPF_FUNC_get_current_ancestor_cgroup_id:
-               return &bpf_get_current_ancestor_cgroup_id_proto;
-#endif
-#ifdef CONFIG_CGROUP_NET_CLASSID
-       case BPF_FUNC_get_cgroup_classid:
-               return &bpf_get_cgroup_classid_curr_proto;
-#endif
        case BPF_FUNC_sk_storage_get:
                return &bpf_sk_storage_get_cg_sock_proto;
        case BPF_FUNC_ktime_get_coarse_ns:
 static const struct bpf_func_proto *
 sock_addr_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
 {
+       const struct bpf_func_proto *func_proto;
+
+       func_proto = cgroup_common_func_proto(func_id, prog);
+       if (func_proto)
+               return func_proto;
+
+       func_proto = cgroup_current_func_proto(func_id, prog);
+       if (func_proto)
+               return func_proto;
+
        switch (func_id) {
-       /* inet and inet6 sockets are created in a process
-        * context so there is always a valid uid/gid
-        */
-       case BPF_FUNC_get_current_uid_gid:
-               return &bpf_get_current_uid_gid_proto;
        case BPF_FUNC_bind:
                switch (prog->expected_attach_type) {
                case BPF_CGROUP_INET4_CONNECT:
                return &bpf_get_socket_cookie_sock_addr_proto;
        case BPF_FUNC_get_netns_cookie:
                return &bpf_get_netns_cookie_sock_addr_proto;
-       case BPF_FUNC_get_local_storage:
-               return &bpf_get_local_storage_proto;
        case BPF_FUNC_perf_event_output:
                return &bpf_event_output_data_proto;
-       case BPF_FUNC_get_current_pid_tgid:
-               return &bpf_get_current_pid_tgid_proto;
-       case BPF_FUNC_get_current_comm:
-               return &bpf_get_current_comm_proto;
-#ifdef CONFIG_CGROUPS
-       case BPF_FUNC_get_current_cgroup_id:
-               return &bpf_get_current_cgroup_id_proto;
-       case BPF_FUNC_get_current_ancestor_cgroup_id:
-               return &bpf_get_current_ancestor_cgroup_id_proto;
-#endif
-#ifdef CONFIG_CGROUP_NET_CLASSID
-       case BPF_FUNC_get_cgroup_classid:
-               return &bpf_get_cgroup_classid_curr_proto;
-#endif
 #ifdef CONFIG_INET
        case BPF_FUNC_sk_lookup_tcp:
                return &bpf_sock_addr_sk_lookup_tcp_proto;
 static const struct bpf_func_proto *
 cg_skb_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
 {
+       const struct bpf_func_proto *func_proto;
+
+       func_proto = cgroup_common_func_proto(func_id, prog);
+       if (func_proto)
+               return func_proto;
+
        switch (func_id) {
-       case BPF_FUNC_get_local_storage:
-               return &bpf_get_local_storage_proto;
        case BPF_FUNC_sk_fullsock:
                return &bpf_sk_fullsock_proto;
        case BPF_FUNC_sk_storage_get:
 static const struct bpf_func_proto *
 sock_ops_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
 {
+       const struct bpf_func_proto *func_proto;
+
+       func_proto = cgroup_common_func_proto(func_id, prog);
+       if (func_proto)
+               return func_proto;
+
        switch (func_id) {
        case BPF_FUNC_setsockopt:
                return &bpf_sock_ops_setsockopt_proto;
                return &bpf_sock_hash_update_proto;
        case BPF_FUNC_get_socket_cookie:
                return &bpf_get_socket_cookie_sock_ops_proto;
-       case BPF_FUNC_get_local_storage:
-               return &bpf_get_local_storage_proto;
        case BPF_FUNC_perf_event_output:
                return &bpf_event_output_data_proto;
        case BPF_FUNC_sk_storage_get: