static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,

                             const char *model, const char *name,

                             const char *ifname, const char *script,

                             const char *downscript, const char *vhostfdname,

                             int vnet_hdr, int fd, Error **errp)

{

    Error *err = NULL;

    TAPState *s = net_tap_fd_init(peer, model, name, fd, vnet_hdr);

    int vhostfd;



    tap_set_sndbuf(s->fd, tap, &err);

    if (err) {

        error_propagate(errp, err);

        return;

    }



    if (tap->has_fd || tap->has_fds) {

        snprintf(s->nc.info_str, sizeof(s->nc.info_str), "fd=%d", fd);

    } else if (tap->has_helper) {

        snprintf(s->nc.info_str, sizeof(s->nc.info_str), "helper=%s",

                 tap->helper);

    } else {

        snprintf(s->nc.info_str, sizeof(s->nc.info_str),

                 "ifname=%s,script=%s,downscript=%s", ifname, script,

                 downscript);



        if (strcmp(downscript, "no") != 0) {

            snprintf(s->down_script, sizeof(s->down_script), "%s", downscript);

            snprintf(s->down_script_arg, sizeof(s->down_script_arg),

                     "%s", ifname);

        }

    }



    if (tap->has_vhost ? tap->vhost :

        vhostfdname || (tap->has_vhostforce && tap->vhostforce)) {

        VhostNetOptions options;



        options.backend_type = VHOST_BACKEND_TYPE_KERNEL;

        options.net_backend = &s->nc;



        if (tap->has_vhostfd || tap->has_vhostfds) {

            vhostfd = monitor_fd_param(cur_mon, vhostfdname, &err);

            if (vhostfd == -1) {

                error_propagate(errp, err);

                return;

            }

        } else {

            vhostfd = open("/dev/vhost-net", O_RDWR);

            if (vhostfd < 0) {

                error_setg_errno(errp, errno,

                                 "tap: open vhost char device failed");

                return;

            }

        }

        options.opaque = (void *)(uintptr_t)vhostfd;



        s->vhost_net = vhost_net_init(&options);

        if (!s->vhost_net) {

            error_setg(errp,

                       "vhost-net requested but could not be initialized");

            return;

        }

    } else if (tap->has_vhostfd || tap->has_vhostfds) {

        error_setg(errp, "vhostfd= is not valid without vhost");

    }

}
