return fd;
 }
 
-static int bpf_prog_attach_check_attach_type(const struct bpf_prog *prog,
-                                            enum bpf_attach_type attach_type)
-{
-       switch (prog->type) {
-       case BPF_PROG_TYPE_CGROUP_SOCK:
-       case BPF_PROG_TYPE_CGROUP_SOCK_ADDR:
-       case BPF_PROG_TYPE_CGROUP_SOCKOPT:
-       case BPF_PROG_TYPE_SK_LOOKUP:
-               return attach_type == prog->expected_attach_type ? 0 : -EINVAL;
-       case BPF_PROG_TYPE_CGROUP_SKB:
-               if (!capable(CAP_NET_ADMIN))
-                       /* cg-skb progs can be loaded by unpriv user.
-                        * check permissions at attach time.
-                        */
-                       return -EPERM;
-               return prog->enforce_expected_attach_type &&
-                       prog->expected_attach_type != attach_type ?
-                       -EINVAL : 0;
-       case BPF_PROG_TYPE_KPROBE:
-               if (prog->expected_attach_type == BPF_TRACE_KPROBE_MULTI &&
-                   attach_type != BPF_TRACE_KPROBE_MULTI)
-                       return -EINVAL;
-               return 0;
-       default:
-               return 0;
-       }
-}
-
 static enum bpf_prog_type
 attach_type_to_prog_type(enum bpf_attach_type attach_type)
 {
        }
 }
 
+static int bpf_prog_attach_check_attach_type(const struct bpf_prog *prog,
+                                            enum bpf_attach_type attach_type)
+{
+       enum bpf_prog_type ptype;
+
+       switch (prog->type) {
+       case BPF_PROG_TYPE_CGROUP_SOCK:
+       case BPF_PROG_TYPE_CGROUP_SOCK_ADDR:
+       case BPF_PROG_TYPE_CGROUP_SOCKOPT:
+       case BPF_PROG_TYPE_SK_LOOKUP:
+               return attach_type == prog->expected_attach_type ? 0 : -EINVAL;
+       case BPF_PROG_TYPE_CGROUP_SKB:
+               if (!capable(CAP_NET_ADMIN))
+                       /* cg-skb progs can be loaded by unpriv user.
+                        * check permissions at attach time.
+                        */
+                       return -EPERM;
+               return prog->enforce_expected_attach_type &&
+                       prog->expected_attach_type != attach_type ?
+                       -EINVAL : 0;
+       case BPF_PROG_TYPE_EXT:
+               return 0;
+       case BPF_PROG_TYPE_NETFILTER:
+               if (attach_type != BPF_NETFILTER)
+                       return -EINVAL;
+               return 0;
+       case BPF_PROG_TYPE_PERF_EVENT:
+       case BPF_PROG_TYPE_TRACEPOINT:
+               if (attach_type != BPF_PERF_EVENT)
+                       return -EINVAL;
+               return 0;
+       case BPF_PROG_TYPE_KPROBE:
+               if (prog->expected_attach_type == BPF_TRACE_KPROBE_MULTI &&
+                   attach_type != BPF_TRACE_KPROBE_MULTI)
+                       return -EINVAL;
+               if (attach_type != BPF_PERF_EVENT &&
+                   attach_type != BPF_TRACE_KPROBE_MULTI)
+                       return -EINVAL;
+               return 0;
+       case BPF_PROG_TYPE_SCHED_CLS:
+               if (attach_type != BPF_TCX_INGRESS &&
+                   attach_type != BPF_TCX_EGRESS)
+                       return -EINVAL;
+               return 0;
+       default:
+               ptype = attach_type_to_prog_type(attach_type);
+               if (ptype == BPF_PROG_TYPE_UNSPEC || ptype != prog->type)
+                       return -EINVAL;
+               return 0;
+       }
+}
+
 #define BPF_PROG_ATTACH_LAST_FIELD expected_revision
 
 #define BPF_F_ATTACH_MASK_BASE \
 #define BPF_LINK_CREATE_LAST_FIELD link_create.kprobe_multi.cookies
 static int link_create(union bpf_attr *attr, bpfptr_t uattr)
 {
-       enum bpf_prog_type ptype;
        struct bpf_prog *prog;
        int ret;
 
        if (ret)
                goto out;
 
-       switch (prog->type) {
-       case BPF_PROG_TYPE_EXT:
-               break;
-       case BPF_PROG_TYPE_NETFILTER:
-               if (attr->link_create.attach_type != BPF_NETFILTER) {
-                       ret = -EINVAL;
-                       goto out;
-               }
-               break;
-       case BPF_PROG_TYPE_PERF_EVENT:
-       case BPF_PROG_TYPE_TRACEPOINT:
-               if (attr->link_create.attach_type != BPF_PERF_EVENT) {
-                       ret = -EINVAL;
-                       goto out;
-               }
-               break;
-       case BPF_PROG_TYPE_KPROBE:
-               if (attr->link_create.attach_type != BPF_PERF_EVENT &&
-                   attr->link_create.attach_type != BPF_TRACE_KPROBE_MULTI) {
-                       ret = -EINVAL;
-                       goto out;
-               }
-               break;
-       case BPF_PROG_TYPE_SCHED_CLS:
-               if (attr->link_create.attach_type != BPF_TCX_INGRESS &&
-                   attr->link_create.attach_type != BPF_TCX_EGRESS) {
-                       ret = -EINVAL;
-                       goto out;
-               }
-               break;
-       default:
-               ptype = attach_type_to_prog_type(attr->link_create.attach_type);
-               if (ptype == BPF_PROG_TYPE_UNSPEC || ptype != prog->type) {
-                       ret = -EINVAL;
-                       goto out;
-               }
-               break;
-       }
-
        switch (prog->type) {
        case BPF_PROG_TYPE_CGROUP_SKB:
        case BPF_PROG_TYPE_CGROUP_SOCK: