$(OUTPUT)/test_maps: $(TESTING_HELPERS)
 $(OUTPUT)/test_verifier: $(TESTING_HELPERS) $(CAP_HELPERS)
 $(OUTPUT)/xsk.o: $(BPFOBJ)
-$(OUTPUT)/xskxceiver: $(OUTPUT)/xsk.o
 
 BPFTOOL ?= $(DEFAULT_BPFTOOL)
 $(DEFAULT_BPFTOOL): $(wildcard $(BPFTOOLDIR)/*.[ch] $(BPFTOOLDIR)/Makefile)    \
 test_subskeleton.skel.h-deps := test_subskeleton_lib2.bpf.o test_subskeleton_lib.bpf.o test_subskeleton.bpf.o
 test_subskeleton_lib.skel.h-deps := test_subskeleton_lib2.bpf.o test_subskeleton_lib.bpf.o
 test_usdt.skel.h-deps := test_usdt.bpf.o test_usdt_multispec.bpf.o
+xsk_xdp_progs.skel.h-deps := xsk_xdp_progs.bpf.o
 
 LINKED_BPF_SRCS := $(patsubst %.bpf.o,%.c,$(foreach skel,$(LINKED_SKELS),$($(skel)-deps)))
 
        $(call msg,BINARY,,$@)
        $(Q)$(CC) $(CFLAGS) $(filter %.a %.o %.c,$^) $(LDLIBS) -o $@
 
+$(OUTPUT)/xskxceiver: xskxceiver.c $(OUTPUT)/xsk.o $(OUTPUT)/xsk_xdp_progs.skel.h $(BPFOBJ) | $(OUTPUT)
+       $(call msg,BINARY,,$@)
+       $(Q)$(CC) $(CFLAGS) $(filter %.a %.o %.c,$^) $(LDLIBS) -o $@
+
 # Make sure we are able to include and link libbpf against c++.
 $(OUTPUT)/test_cpp: test_cpp.cpp $(OUTPUT)/test_core_extern.skel.h $(BPFOBJ)
        $(call msg,CXX,,$@)
 
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2022 Intel */
+
+#include <linux/bpf.h>
+#include <bpf/bpf_helpers.h>
+
+struct {
+       __uint(type, BPF_MAP_TYPE_XSKMAP);
+       __uint(max_entries, 1);
+       __uint(key_size, sizeof(int));
+       __uint(value_size, sizeof(int));
+} xsk SEC(".maps");
+
+SEC("xdp") int xsk_def_prog(struct xdp_md *xdp)
+{
+       return bpf_redirect_map(&xsk, 0, XDP_DROP);
+}
+
+char _license[] SEC("license") = "GPL";
 
        return err;
 }
 
-static int __xsk_load_xdp_prog(int xsk_map_fd)
+int xsk_attach_xdp_program(struct bpf_program *prog, int ifindex, u32 xdp_flags)
 {
-       static const int log_buf_size = 16 * 1024;
-       char log_buf[log_buf_size];
        int prog_fd;
 
-       /* This is the post-5.3 kernel C-program:
-        * SEC("xdp_sock") int xdp_sock_prog(struct xdp_md *ctx)
-        * {
-        *     return bpf_redirect_map(&xsks_map, ctx->rx_queue_index, XDP_PASS);
-        * }
-        */
-       struct bpf_insn prog[] = {
-               /* r2 = *(u32 *)(r1 + 16) */
-               BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 16),
-               /* r1 = xskmap[] */
-               BPF_LD_MAP_FD(BPF_REG_1, xsk_map_fd),
-               /* r3 = XDP_PASS */
-               BPF_MOV64_IMM(BPF_REG_3, 2),
-               /* call bpf_redirect_map */
-               BPF_EMIT_CALL(BPF_FUNC_redirect_map),
-               BPF_EXIT_INSN(),
-       };
-       size_t insns_cnt = ARRAY_SIZE(prog);
-       LIBBPF_OPTS(bpf_prog_load_opts, opts,
-               .log_buf = log_buf,
-               .log_size = log_buf_size,
-       );
-
-       prog_fd = bpf_prog_load(BPF_PROG_TYPE_XDP, NULL, "LGPL-2.1 or BSD-2-Clause",
-                               prog, insns_cnt, &opts);
-       if (prog_fd < 0)
-               pr_warn("BPF log buffer:\n%s", log_buf);
-
-       return prog_fd;
+       prog_fd = bpf_program__fd(prog);
+       return bpf_xdp_attach(ifindex, prog_fd, xdp_flags, NULL);
 }
 
-int xsk_attach_xdp_program(int ifindex, int prog_fd, u32 xdp_flags)
+void xsk_detach_xdp_program(int ifindex, u32 xdp_flags)
 {
-       DECLARE_LIBBPF_OPTS(bpf_link_create_opts, opts);
-       __u32 prog_id = 0;
-       int link_fd;
-       int err;
-
-       err = bpf_xdp_query_id(ifindex, xdp_flags, &prog_id);
-       if (err) {
-               pr_warn("getting XDP prog id failed\n");
-               return err;
-       }
-
-       /* If there's a netlink-based XDP prog loaded on interface, bail out
-        * and ask user to do the removal by himself
-        */
-       if (prog_id) {
-               pr_warn("Netlink-based XDP prog detected, please unload it in order to launch AF_XDP prog\n");
-               return -EINVAL;
-       }
-
-       opts.flags = xdp_flags & ~(XDP_FLAGS_UPDATE_IF_NOEXIST | XDP_FLAGS_REPLACE);
+       bpf_xdp_detach(ifindex, xdp_flags, NULL);
+}
 
-       link_fd = bpf_link_create(prog_fd, ifindex, BPF_XDP, &opts);
-       if (link_fd < 0)
-               pr_warn("bpf_link_create failed: %s\n", strerror(errno));
+void xsk_clear_xskmap(struct bpf_map *map)
+{
+       u32 index = 0;
+       int map_fd;
 
-       return link_fd;
+       map_fd = bpf_map__fd(map);
+       bpf_map_delete_elem(map_fd, &index);
 }
 
-int xsk_load_xdp_program(int *xsk_map_fd, int *prog_fd)
+int xsk_update_xskmap(struct bpf_map *map, struct xsk_socket *xsk)
 {
-       *xsk_map_fd = bpf_map_create(BPF_MAP_TYPE_XSKMAP, "xsks_map", sizeof(int), sizeof(int),
-                                    XSKMAP_SIZE, NULL);
-       if (*xsk_map_fd < 0)
-               return *xsk_map_fd;
-
-       *prog_fd = __xsk_load_xdp_prog(*xsk_map_fd);
-       if (*prog_fd < 0) {
-               close(*xsk_map_fd);
-               return *prog_fd;
-       }
+       int map_fd, sock_fd;
+       u32 index = 0;
 
-       return 0;
+       map_fd = bpf_map__fd(map);
+       sock_fd = xsk_socket__fd(xsk);
+
+       return bpf_map_update_elem(map_fd, &index, &sock_fd, 0);
 }
 
 static struct xsk_ctx *xsk_get_ctx(struct xsk_umem *umem, int ifindex,
 
        __u32 flags;
 };
 
-int xsk_load_xdp_program(int *xsk_map_fd, int *prog_fd);
-int xsk_attach_xdp_program(int ifindex, int prog_fd, u32 xdp_flags);
+int xsk_attach_xdp_program(struct bpf_program *prog, int ifindex, u32 xdp_flags);
+void xsk_detach_xdp_program(int ifindex, u32 xdp_flags);
+int xsk_update_xskmap(struct bpf_map *map, struct xsk_socket *xsk);
+void xsk_clear_xskmap(struct bpf_map *map);
 
 struct xsk_socket_config {
        __u32 rx_size;
 
 {
        xsk_configure_socket(test, ifobject, test->ifobj_rx->umem, true);
        ifobject->xsk = &ifobject->xsk_arr[0];
-       ifobject->xsk_map_fd = test->ifobj_rx->xsk_map_fd;
+       ifobject->xskmap = test->ifobj_rx->xskmap;
        memcpy(ifobject->umem, test->ifobj_rx->umem, sizeof(struct xsk_umem_info));
 }
 
        u64 umem_sz = ifobject->umem->num_frames * ifobject->umem->frame_size;
        int mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE;
        LIBBPF_OPTS(bpf_xdp_query_opts, opts);
-       u32 queue_id = 0;
-       int ret, fd;
        void *bufs;
+       int ret;
 
        if (ifobject->umem->unaligned_mode)
                mmap_flags |= MAP_HUGETLB;
        if (!ifobject->rx_on)
                return;
 
-       fd = xsk_socket__fd(ifobject->xsk->xsk);
-       ret = bpf_map_update_elem(ifobject->xsk_map_fd, &queue_id, &fd, 0);
+       ret = xsk_update_xskmap(ifobject->xskmap, ifobject->xsk->xsk);
        if (ret)
                exit_with_error(errno);
 }
 {
        struct test_spec *test = (struct test_spec *)arg;
        struct ifobject *ifobject = test->ifobj_rx;
-       int id = 0, err, fd = xsk_socket__fd(ifobject->xsk->xsk);
        struct pollfd fds = { };
-       u32 queue_id = 0;
+       int err;
 
        if (test->current_step == 1) {
                thread_common_ops(test, ifobject);
        } else {
-               bpf_map_delete_elem(ifobject->xsk_map_fd, &id);
-               err = bpf_map_update_elem(ifobject->xsk_map_fd, &queue_id, &fd, 0);
+               xsk_clear_xskmap(ifobject->xskmap);
+               err = xsk_update_xskmap(ifobject->xskmap, ifobject->xsk->xsk);
                if (err) {
-                       printf("Error: Failed to update xskmap, error %s\n", strerror(err));
-                       exit_with_error(err);
+                       printf("Error: Failed to update xskmap, error %s\n", strerror(-err));
+                       exit_with_error(-err);
                }
        }
 
        pthread_join(t0, NULL);
 
        if (test->total_steps == test->current_step || test->fail) {
-               u32 queue_id = 0;
-
                xsk_socket__delete(ifobj->xsk->xsk);
-               bpf_map_delete_elem(ifobj->xsk_map_fd, &queue_id);
+               xsk_clear_xskmap(ifobj->xskmap);
                testapp_clean_xsk_umem(ifobj);
        }
 
 
 static void swap_xsk_resources(struct ifobject *ifobj_tx, struct ifobject *ifobj_rx)
 {
-       int ret, queue_id = 0, fd = xsk_socket__fd(ifobj_rx->xsk->xsk);
+       int ret;
 
        xsk_socket__delete(ifobj_tx->xsk->xsk);
        xsk_socket__delete(ifobj_rx->xsk->xsk);
        ifobj_tx->xsk = &ifobj_tx->xsk_arr[1];
        ifobj_rx->xsk = &ifobj_rx->xsk_arr[1];
 
-       ret = bpf_map_update_elem(ifobj_rx->xsk_map_fd, &queue_id, &fd, 0);
+       ret = xsk_update_xskmap(ifobj_rx->xskmap, ifobj_rx->xsk->xsk);
        if (ret)
                exit_with_error(errno);
 }
        pkt_stream_restore_default(test);
 }
 
+static int xsk_load_xdp_programs(struct ifobject *ifobj)
+{
+       ifobj->xdp_progs = xsk_xdp_progs__open_and_load();
+       if (libbpf_get_error(ifobj->xdp_progs))
+               return libbpf_get_error(ifobj->xdp_progs);
+
+       return 0;
+}
+
+static void xsk_unload_xdp_programs(struct ifobject *ifobj)
+{
+       xsk_xdp_progs__destroy(ifobj->xdp_progs);
+}
+
 static void init_iface(struct ifobject *ifobj, const char *dst_mac, const char *src_mac,
                       const char *dst_ip, const char *src_ip, const u16 dst_port,
                       const u16 src_port, thread_func_t func_ptr, bool load_xdp)
 {
-       int xsk_map_fd, prog_fd, err;
        struct in_addr ip;
+       int err;
 
        memcpy(ifobj->dst_mac, dst_mac, ETH_ALEN);
        memcpy(ifobj->src_mac, src_mac, ETH_ALEN);
        if (!load_xdp)
                return;
 
-       err = xsk_load_xdp_program(&xsk_map_fd, &prog_fd);
+       err = xsk_load_xdp_programs(ifobj);
        if (err) {
                printf("Error loading XDP program\n");
                exit_with_error(err);
        }
 
-       ifobj->xsk_map_fd = xsk_map_fd;
-       ifobj->prog_fd = prog_fd;
        ifobj->xdp_flags = mode_to_xdp_flags(TEST_MODE_SKB);
-       ifobj->link_fd = xsk_attach_xdp_program(ifobj->ifindex, prog_fd, ifobj->xdp_flags);
-       if (ifobj->link_fd < 0) {
+       err = xsk_attach_xdp_program(ifobj->xdp_progs->progs.xsk_def_prog, ifobj->ifindex,
+                                    ifobj->xdp_flags);
+       if (err) {
                printf("Error attaching XDP program\n");
-               exit_with_error(ifobj->link_fd);
+               exit_with_error(-err);
        }
+       ifobj->xskmap = ifobj->xdp_progs->maps.xsk;
 }
 
 static void run_pkt_test(struct test_spec *test, enum test_mode mode, enum test_type type)
 
 static void ifobject_delete(struct ifobject *ifobj)
 {
-       close(ifobj->prog_fd);
-       close(ifobj->xsk_map_fd);
-
        free(ifobj->umem);
        free(ifobj->xsk_arr);
        free(ifobj);
        LIBBPF_OPTS(bpf_xdp_query_opts, opts);
        int ret;
 
-       close(ifobj->link_fd);
-       ifobj->link_fd = xsk_attach_xdp_program(ifobj->ifindex, ifobj->prog_fd,
-                                               XDP_FLAGS_DRV_MODE);
-       if (ifobj->link_fd < 0) {
+       xsk_detach_xdp_program(ifobj->ifindex, ifobj->xdp_flags);
+       ifobj->xdp_flags = XDP_FLAGS_DRV_MODE;
+       ret = xsk_attach_xdp_program(ifobj->xdp_progs->progs.xsk_def_prog, ifobj->ifindex,
+                                    ifobj->xdp_flags);
+       if (ret) {
                ksft_print_msg("Error attaching XDP program\n");
-               exit_with_error(-ifobj->link_fd);
+               exit_with_error(-ret);
        }
+       ifobj->xskmap = ifobj->xdp_progs->maps.xsk;
 
        ret = bpf_xdp_query(ifobj->ifindex, XDP_FLAGS_DRV_MODE, &opts);
        if (ret)
 
        pkt_stream_delete(tx_pkt_stream_default);
        pkt_stream_delete(rx_pkt_stream_default);
+       xsk_unload_xdp_programs(ifobj_tx);
+       xsk_unload_xdp_programs(ifobj_rx);
        ifobject_delete(ifobj_tx);
        ifobject_delete(ifobj_rx);
 
 
 #ifndef XSKXCEIVER_H_
 #define XSKXCEIVER_H_
 
+#include "xsk_xdp_progs.skel.h"
+
 #ifndef SOL_XDP
 #define SOL_XDP 283
 #endif
        thread_func_t func_ptr;
        validation_func_t validation_func;
        struct pkt_stream *pkt_stream;
-       int xsk_map_fd;
-       int prog_fd;
-       int link_fd;
+       struct xsk_xdp_progs *xdp_progs;
+       struct bpf_map *xskmap;
        int ifindex;
        u32 dst_ip;
        u32 src_ip;