attr.expected_attach_type = load_attr->expected_attach_type;
        if (attr.prog_type == BPF_PROG_TYPE_STRUCT_OPS) {
                attr.attach_btf_id = load_attr->attach_btf_id;
-       } else if (attr.prog_type == BPF_PROG_TYPE_TRACING) {
+       } else if (attr.prog_type == BPF_PROG_TYPE_TRACING ||
+                  attr.prog_type == BPF_PROG_TYPE_EXT) {
                attr.attach_btf_id = load_attr->attach_btf_id;
                attr.attach_prog_fd = load_attr->attach_prog_fd;
        } else {
 
        load_attr.license = license;
        if (prog->type == BPF_PROG_TYPE_STRUCT_OPS) {
                load_attr.attach_btf_id = prog->attach_btf_id;
-       } else if (prog->type == BPF_PROG_TYPE_TRACING) {
+       } else if (prog->type == BPF_PROG_TYPE_TRACING ||
+                  prog->type == BPF_PROG_TYPE_EXT) {
                load_attr.attach_prog_fd = prog->attach_prog_fd;
                load_attr.attach_btf_id = prog->attach_btf_id;
        } else {
 {
        int err = 0, fd, i, btf_id;
 
-       if (prog->type == BPF_PROG_TYPE_TRACING) {
+       if (prog->type == BPF_PROG_TYPE_TRACING ||
+           prog->type == BPF_PROG_TYPE_EXT) {
                btf_id = libbpf_find_attach_btf_id(prog);
                if (btf_id <= 0)
                        return btf_id;
 
                bpf_program__set_type(prog, prog_type);
                bpf_program__set_expected_attach_type(prog, attach_type);
-               if (prog_type == BPF_PROG_TYPE_TRACING)
+               if (prog_type == BPF_PROG_TYPE_TRACING ||
+                   prog_type == BPF_PROG_TYPE_EXT)
                        prog->attach_prog_fd = OPTS_GET(opts, attach_prog_fd, 0);
        }
 
 BPF_PROG_TYPE_FNS(perf_event, BPF_PROG_TYPE_PERF_EVENT);
 BPF_PROG_TYPE_FNS(tracing, BPF_PROG_TYPE_TRACING);
 BPF_PROG_TYPE_FNS(struct_ops, BPF_PROG_TYPE_STRUCT_OPS);
+BPF_PROG_TYPE_FNS(extension, BPF_PROG_TYPE_EXT);
 
 enum bpf_attach_type
 bpf_program__get_expected_attach_type(struct bpf_program *prog)
                .expected_attach_type = BPF_TRACE_FEXIT,
                .is_attach_btf = true,
                .attach_fn = attach_trace),
+       SEC_DEF("freplace/", EXT,
+               .is_attach_btf = true,
+               .attach_fn = attach_trace),
        BPF_PROG_SEC("xdp",                     BPF_PROG_TYPE_XDP),
        BPF_PROG_SEC("perf_event",              BPF_PROG_TYPE_PERF_EVENT),
        BPF_PROG_SEC("lwt_in",                  BPF_PROG_TYPE_LWT_IN),
 
 LIBBPF_API int bpf_program__set_perf_event(struct bpf_program *prog);
 LIBBPF_API int bpf_program__set_tracing(struct bpf_program *prog);
 LIBBPF_API int bpf_program__set_struct_ops(struct bpf_program *prog);
+LIBBPF_API int bpf_program__set_extension(struct bpf_program *prog);
 
 LIBBPF_API enum bpf_prog_type bpf_program__get_type(struct bpf_program *prog);
 LIBBPF_API void bpf_program__set_type(struct bpf_program *prog,
 LIBBPF_API bool bpf_program__is_perf_event(const struct bpf_program *prog);
 LIBBPF_API bool bpf_program__is_tracing(const struct bpf_program *prog);
 LIBBPF_API bool bpf_program__is_struct_ops(const struct bpf_program *prog);
+LIBBPF_API bool bpf_program__is_extension(const struct bpf_program *prog);
 
 /*
  * No need for __attribute__((packed)), all members of 'bpf_map_def'