}
 
 static int xsk_configure_socket(struct xsk_socket_info *xsk, struct xsk_umem_info *umem,
-                               struct ifobject *ifobject, u32 qid)
+                               struct ifobject *ifobject, bool shared)
 {
-       struct xsk_socket_config cfg;
+       struct xsk_socket_config cfg = {};
        struct xsk_ring_cons *rxr;
        struct xsk_ring_prod *txr;
 
        xsk->umem = umem;
        cfg.rx_size = xsk->rxqsize;
        cfg.tx_size = XSK_RING_PROD__DEFAULT_NUM_DESCS;
-       cfg.libbpf_flags = 0;
+       cfg.libbpf_flags = XSK_LIBBPF_FLAGS__INHIBIT_PROG_LOAD;
        cfg.xdp_flags = ifobject->xdp_flags;
        cfg.bind_flags = ifobject->bind_flags;
+       if (shared)
+               cfg.bind_flags |= XDP_SHARED_UMEM;
 
        txr = ifobject->tx_on ? &xsk->tx : NULL;
        rxr = ifobject->rx_on ? &xsk->rx : NULL;
-       return xsk_socket__create(&xsk->xsk, ifobject->ifname, qid, umem->umem, rxr, txr, &cfg);
+       return xsk_socket__create(&xsk->xsk, ifobject->ifname, 0, umem->umem, rxr, txr, &cfg);
 }
 
 static struct option long_options[] = {
        for (i = 0; i < MAX_INTERFACES; i++) {
                struct ifobject *ifobj = i ? ifobj_rx : ifobj_tx;
 
-               ifobj->umem = &ifobj->umem_arr[0];
                ifobj->xsk = &ifobj->xsk_arr[0];
                ifobj->use_poll = false;
                ifobj->pacing_on = true;
                        ifobj->tx_on = false;
                }
 
+               memset(ifobj->umem, 0, sizeof(*ifobj->umem));
+               ifobj->umem->num_frames = DEFAULT_UMEM_BUFFERS;
+               ifobj->umem->frame_size = XSK_UMEM__DEFAULT_FRAME_SIZE;
+
                for (j = 0; j < MAX_SOCKETS; j++) {
-                       memset(&ifobj->umem_arr[j], 0, sizeof(ifobj->umem_arr[j]));
                        memset(&ifobj->xsk_arr[j], 0, sizeof(ifobj->xsk_arr[j]));
-                       ifobj->umem_arr[j].num_frames = DEFAULT_UMEM_BUFFERS;
-                       ifobj->umem_arr[j].frame_size = XSK_UMEM__DEFAULT_FRAME_SIZE;
                        ifobj->xsk_arr[j].rxqsize = XSK_RING_CONS__DEFAULT_NUM_DESCS;
                }
        }
 
 static void thread_common_ops(struct test_spec *test, struct ifobject *ifobject)
 {
+       u64 umem_sz = ifobject->umem->num_frames * ifobject->umem->frame_size;
        int mmap_flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE;
+       int ret, ifindex;
+       void *bufs;
        u32 i;
 
        ifobject->ns_fd = switch_namespace(ifobject->nsname);
        if (ifobject->umem->unaligned_mode)
                mmap_flags |= MAP_HUGETLB;
 
-       for (i = 0; i < test->nb_sockets; i++) {
-               u64 umem_sz = ifobject->umem->num_frames * ifobject->umem->frame_size;
-               u32 ctr = 0;
-               void *bufs;
-               int ret;
+       bufs = mmap(NULL, umem_sz, PROT_READ | PROT_WRITE, mmap_flags, -1, 0);
+       if (bufs == MAP_FAILED)
+               exit_with_error(errno);
 
-               bufs = mmap(NULL, umem_sz, PROT_READ | PROT_WRITE, mmap_flags, -1, 0);
-               if (bufs == MAP_FAILED)
-                       exit_with_error(errno);
+       ret = xsk_configure_umem(ifobject->umem, bufs, umem_sz);
+       if (ret)
+               exit_with_error(-ret);
 
-               ret = xsk_configure_umem(&ifobject->umem_arr[i], bufs, umem_sz);
-               if (ret)
-                       exit_with_error(-ret);
+       for (i = 0; i < test->nb_sockets; i++) {
+               u32 ctr = 0;
 
                while (ctr++ < SOCK_RECONF_CTR) {
-                       ret = xsk_configure_socket(&ifobject->xsk_arr[i], &ifobject->umem_arr[i],
-                                                  ifobject, i);
+                       ret = xsk_configure_socket(&ifobject->xsk_arr[i], ifobject->umem,
+                                                  ifobject, !!i);
                        if (!ret)
                                break;
 
                }
        }
 
-       ifobject->umem = &ifobject->umem_arr[0];
        ifobject->xsk = &ifobject->xsk_arr[0];
+
+       if (!ifobject->rx_on)
+               return;
+
+       ifindex = if_nametoindex(ifobject->ifname);
+       if (!ifindex)
+               exit_with_error(errno);
+
+       ret = xsk_setup_xdp_prog(ifindex, &ifobject->xsk_map_fd);
+       if (ret)
+               exit_with_error(-ret);
+
+       ret = xsk_socket__update_xskmap(ifobject->xsk->xsk, ifobject->xsk_map_fd);
+       if (ret)
+               exit_with_error(-ret);
 }
 
 static void testapp_cleanup_xsk_res(struct ifobject *ifobj)
 
 static void swap_xsk_resources(struct ifobject *ifobj_tx, struct ifobject *ifobj_rx)
 {
+       int ret;
+
        xsk_socket__delete(ifobj_tx->xsk->xsk);
-       xsk_umem__delete(ifobj_tx->umem->umem);
        xsk_socket__delete(ifobj_rx->xsk->xsk);
-       xsk_umem__delete(ifobj_rx->umem->umem);
-       ifobj_tx->umem = &ifobj_tx->umem_arr[1];
        ifobj_tx->xsk = &ifobj_tx->xsk_arr[1];
-       ifobj_rx->umem = &ifobj_rx->umem_arr[1];
        ifobj_rx->xsk = &ifobj_rx->xsk_arr[1];
+
+       ret = xsk_socket__update_xskmap(ifobj_rx->xsk->xsk, ifobj_rx->xsk_map_fd);
+       if (ret)
+               exit_with_error(-ret);
 }
 
 static void testapp_bpf_res(struct test_spec *test)
        if (!ifobj->xsk_arr)
                goto out_xsk_arr;
 
-       ifobj->umem_arr = calloc(MAX_SOCKETS, sizeof(*ifobj->umem_arr));
-       if (!ifobj->umem_arr)
-               goto out_umem_arr;
+       ifobj->umem = calloc(1, sizeof(*ifobj->umem));
+       if (!ifobj->umem)
+               goto out_umem;
 
        return ifobj;
 
-out_umem_arr:
+out_umem:
        free(ifobj->xsk_arr);
 out_xsk_arr:
        free(ifobj);
 
 static void ifobject_delete(struct ifobject *ifobj)
 {
-       free(ifobj->umem_arr);
+       free(ifobj->umem);
        free(ifobj->xsk_arr);
        free(ifobj);
 }