qemu/net/tap.c
<<
>>
Prefs
   1/*
   2 * QEMU System Emulator
   3 *
   4 * Copyright (c) 2003-2008 Fabrice Bellard
   5 * Copyright (c) 2009 Red Hat, Inc.
   6 *
   7 * Permission is hereby granted, free of charge, to any person obtaining a copy
   8 * of this software and associated documentation files (the "Software"), to deal
   9 * in the Software without restriction, including without limitation the rights
  10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11 * copies of the Software, and to permit persons to whom the Software is
  12 * furnished to do so, subject to the following conditions:
  13 *
  14 * The above copyright notice and this permission notice shall be included in
  15 * all copies or substantial portions of the Software.
  16 *
  17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23 * THE SOFTWARE.
  24 */
  25
  26#include "qemu/osdep.h"
  27#include "tap_int.h"
  28
  29
  30#include <sys/ioctl.h>
  31#include <sys/wait.h>
  32#include <sys/socket.h>
  33#include <net/if.h>
  34
  35#include "net/eth.h"
  36#include "net/net.h"
  37#include "clients.h"
  38#include "monitor/monitor.h"
  39#include "sysemu/sysemu.h"
  40#include "qapi/error.h"
  41#include "qemu-common.h"
  42#include "qemu/cutils.h"
  43#include "qemu/error-report.h"
  44#include "qemu/main-loop.h"
  45#include "qemu/sockets.h"
  46
  47#include "net/tap.h"
  48
  49#include "net/vhost_net.h"
  50
  51typedef struct TAPState {
  52    NetClientState nc;
  53    int fd;
  54    char down_script[1024];
  55    char down_script_arg[128];
  56    uint8_t buf[NET_BUFSIZE];
  57    bool read_poll;
  58    bool write_poll;
  59    bool using_vnet_hdr;
  60    bool has_ufo;
  61    bool enabled;
  62    VHostNetState *vhost_net;
  63    unsigned host_vnet_hdr_len;
  64    Notifier exit;
  65} TAPState;
  66
  67static void launch_script(const char *setup_script, const char *ifname,
  68                          int fd, Error **errp);
  69
  70static void tap_send(void *opaque);
  71static void tap_writable(void *opaque);
  72
  73static void tap_update_fd_handler(TAPState *s)
  74{
  75    qemu_set_fd_handler(s->fd,
  76                        s->read_poll && s->enabled ? tap_send : NULL,
  77                        s->write_poll && s->enabled ? tap_writable : NULL,
  78                        s);
  79}
  80
  81static void tap_read_poll(TAPState *s, bool enable)
  82{
  83    s->read_poll = enable;
  84    tap_update_fd_handler(s);
  85}
  86
  87static void tap_write_poll(TAPState *s, bool enable)
  88{
  89    s->write_poll = enable;
  90    tap_update_fd_handler(s);
  91}
  92
  93static void tap_writable(void *opaque)
  94{
  95    TAPState *s = opaque;
  96
  97    tap_write_poll(s, false);
  98
  99    qemu_flush_queued_packets(&s->nc);
 100}
 101
 102static ssize_t tap_write_packet(TAPState *s, const struct iovec *iov, int iovcnt)
 103{
 104    ssize_t len;
 105
 106    do {
 107        len = writev(s->fd, iov, iovcnt);
 108    } while (len == -1 && errno == EINTR);
 109
 110    if (len == -1 && errno == EAGAIN) {
 111        tap_write_poll(s, true);
 112        return 0;
 113    }
 114
 115    return len;
 116}
 117
 118static ssize_t tap_receive_iov(NetClientState *nc, const struct iovec *iov,
 119                               int iovcnt)
 120{
 121    TAPState *s = DO_UPCAST(TAPState, nc, nc);
 122    const struct iovec *iovp = iov;
 123    struct iovec iov_copy[iovcnt + 1];
 124    struct virtio_net_hdr_mrg_rxbuf hdr = { };
 125
 126    if (s->host_vnet_hdr_len && !s->using_vnet_hdr) {
 127        iov_copy[0].iov_base = &hdr;
 128        iov_copy[0].iov_len =  s->host_vnet_hdr_len;
 129        memcpy(&iov_copy[1], iov, iovcnt * sizeof(*iov));
 130        iovp = iov_copy;
 131        iovcnt++;
 132    }
 133
 134    return tap_write_packet(s, iovp, iovcnt);
 135}
 136
 137static ssize_t tap_receive_raw(NetClientState *nc, const uint8_t *buf, size_t size)
 138{
 139    TAPState *s = DO_UPCAST(TAPState, nc, nc);
 140    struct iovec iov[2];
 141    int iovcnt = 0;
 142    struct virtio_net_hdr_mrg_rxbuf hdr = { };
 143
 144    if (s->host_vnet_hdr_len) {
 145        iov[iovcnt].iov_base = &hdr;
 146        iov[iovcnt].iov_len  = s->host_vnet_hdr_len;
 147        iovcnt++;
 148    }
 149
 150    iov[iovcnt].iov_base = (char *)buf;
 151    iov[iovcnt].iov_len  = size;
 152    iovcnt++;
 153
 154    return tap_write_packet(s, iov, iovcnt);
 155}
 156
 157static ssize_t tap_receive(NetClientState *nc, const uint8_t *buf, size_t size)
 158{
 159    TAPState *s = DO_UPCAST(TAPState, nc, nc);
 160    struct iovec iov[1];
 161
 162    if (s->host_vnet_hdr_len && !s->using_vnet_hdr) {
 163        return tap_receive_raw(nc, buf, size);
 164    }
 165
 166    iov[0].iov_base = (char *)buf;
 167    iov[0].iov_len  = size;
 168
 169    return tap_write_packet(s, iov, 1);
 170}
 171
 172#ifndef __sun__
 173ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen)
 174{
 175    return read(tapfd, buf, maxlen);
 176}
 177#endif
 178
 179static void tap_send_completed(NetClientState *nc, ssize_t len)
 180{
 181    TAPState *s = DO_UPCAST(TAPState, nc, nc);
 182    tap_read_poll(s, true);
 183}
 184
 185static void tap_send(void *opaque)
 186{
 187    TAPState *s = opaque;
 188    int size;
 189    int packets = 0;
 190
 191    while (true) {
 192        uint8_t *buf = s->buf;
 193        uint8_t min_pkt[ETH_ZLEN];
 194        size_t min_pktsz = sizeof(min_pkt);
 195
 196        size = tap_read_packet(s->fd, s->buf, sizeof(s->buf));
 197        if (size <= 0) {
 198            break;
 199        }
 200
 201        if (s->host_vnet_hdr_len && !s->using_vnet_hdr) {
 202            buf  += s->host_vnet_hdr_len;
 203            size -= s->host_vnet_hdr_len;
 204        }
 205
 206        if (net_peer_needs_padding(&s->nc)) {
 207            if (eth_pad_short_frame(min_pkt, &min_pktsz, buf, size)) {
 208                buf = min_pkt;
 209                size = min_pktsz;
 210            }
 211        }
 212
 213        size = qemu_send_packet_async(&s->nc, buf, size, tap_send_completed);
 214        if (size == 0) {
 215            tap_read_poll(s, false);
 216            break;
 217        } else if (size < 0) {
 218            break;
 219        }
 220
 221        /*
 222         * When the host keeps receiving more packets while tap_send() is
 223         * running we can hog the QEMU global mutex.  Limit the number of
 224         * packets that are processed per tap_send() callback to prevent
 225         * stalling the guest.
 226         */
 227        packets++;
 228        if (packets >= 50) {
 229            break;
 230        }
 231    }
 232}
 233
 234static bool tap_has_ufo(NetClientState *nc)
 235{
 236    TAPState *s = DO_UPCAST(TAPState, nc, nc);
 237
 238    assert(nc->info->type == NET_CLIENT_DRIVER_TAP);
 239
 240    return s->has_ufo;
 241}
 242
 243static bool tap_has_vnet_hdr(NetClientState *nc)
 244{
 245    TAPState *s = DO_UPCAST(TAPState, nc, nc);
 246
 247    assert(nc->info->type == NET_CLIENT_DRIVER_TAP);
 248
 249    return !!s->host_vnet_hdr_len;
 250}
 251
 252static bool tap_has_vnet_hdr_len(NetClientState *nc, int len)
 253{
 254    TAPState *s = DO_UPCAST(TAPState, nc, nc);
 255
 256    assert(nc->info->type == NET_CLIENT_DRIVER_TAP);
 257
 258    return !!tap_probe_vnet_hdr_len(s->fd, len);
 259}
 260
 261static void tap_set_vnet_hdr_len(NetClientState *nc, int len)
 262{
 263    TAPState *s = DO_UPCAST(TAPState, nc, nc);
 264
 265    assert(nc->info->type == NET_CLIENT_DRIVER_TAP);
 266    assert(len == sizeof(struct virtio_net_hdr_mrg_rxbuf) ||
 267           len == sizeof(struct virtio_net_hdr) ||
 268           len == sizeof(struct virtio_net_hdr_v1_hash));
 269
 270    tap_fd_set_vnet_hdr_len(s->fd, len);
 271    s->host_vnet_hdr_len = len;
 272}
 273
 274static void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr)
 275{
 276    TAPState *s = DO_UPCAST(TAPState, nc, nc);
 277
 278    assert(nc->info->type == NET_CLIENT_DRIVER_TAP);
 279    assert(!!s->host_vnet_hdr_len == using_vnet_hdr);
 280
 281    s->using_vnet_hdr = using_vnet_hdr;
 282}
 283
 284static int tap_set_vnet_le(NetClientState *nc, bool is_le)
 285{
 286    TAPState *s = DO_UPCAST(TAPState, nc, nc);
 287
 288    return tap_fd_set_vnet_le(s->fd, is_le);
 289}
 290
 291static int tap_set_vnet_be(NetClientState *nc, bool is_be)
 292{
 293    TAPState *s = DO_UPCAST(TAPState, nc, nc);
 294
 295    return tap_fd_set_vnet_be(s->fd, is_be);
 296}
 297
 298static void tap_set_offload(NetClientState *nc, int csum, int tso4,
 299                     int tso6, int ecn, int ufo)
 300{
 301    TAPState *s = DO_UPCAST(TAPState, nc, nc);
 302    if (s->fd < 0) {
 303        return;
 304    }
 305
 306    tap_fd_set_offload(s->fd, csum, tso4, tso6, ecn, ufo);
 307}
 308
 309static void tap_exit_notify(Notifier *notifier, void *data)
 310{
 311    TAPState *s = container_of(notifier, TAPState, exit);
 312    Error *err = NULL;
 313
 314    if (s->down_script[0]) {
 315        launch_script(s->down_script, s->down_script_arg, s->fd, &err);
 316        if (err) {
 317            error_report_err(err);
 318        }
 319    }
 320}
 321
 322static void tap_cleanup(NetClientState *nc)
 323{
 324    TAPState *s = DO_UPCAST(TAPState, nc, nc);
 325
 326    if (s->vhost_net) {
 327        vhost_net_cleanup(s->vhost_net);
 328        g_free(s->vhost_net);
 329        s->vhost_net = NULL;
 330    }
 331
 332    qemu_purge_queued_packets(nc);
 333
 334    tap_exit_notify(&s->exit, NULL);
 335    qemu_remove_exit_notifier(&s->exit);
 336
 337    tap_read_poll(s, false);
 338    tap_write_poll(s, false);
 339    close(s->fd);
 340    s->fd = -1;
 341}
 342
 343static void tap_poll(NetClientState *nc, bool enable)
 344{
 345    TAPState *s = DO_UPCAST(TAPState, nc, nc);
 346    tap_read_poll(s, enable);
 347    tap_write_poll(s, enable);
 348}
 349
 350int tap_get_fd(NetClientState *nc)
 351{
 352    TAPState *s = DO_UPCAST(TAPState, nc, nc);
 353    assert(nc->info->type == NET_CLIENT_DRIVER_TAP);
 354    return s->fd;
 355}
 356
 357/* fd support */
 358
 359static NetClientInfo net_tap_info = {
 360    .type = NET_CLIENT_DRIVER_TAP,
 361    .size = sizeof(TAPState),
 362    .receive = tap_receive,
 363    .receive_raw = tap_receive_raw,
 364    .receive_iov = tap_receive_iov,
 365    .poll = tap_poll,
 366    .cleanup = tap_cleanup,
 367    .has_ufo = tap_has_ufo,
 368    .has_vnet_hdr = tap_has_vnet_hdr,
 369    .has_vnet_hdr_len = tap_has_vnet_hdr_len,
 370    .using_vnet_hdr = tap_using_vnet_hdr,
 371    .set_offload = tap_set_offload,
 372    .set_vnet_hdr_len = tap_set_vnet_hdr_len,
 373    .set_vnet_le = tap_set_vnet_le,
 374    .set_vnet_be = tap_set_vnet_be,
 375};
 376
 377static TAPState *net_tap_fd_init(NetClientState *peer,
 378                                 const char *model,
 379                                 const char *name,
 380                                 int fd,
 381                                 int vnet_hdr)
 382{
 383    NetClientState *nc;
 384    TAPState *s;
 385
 386    nc = qemu_new_net_client(&net_tap_info, peer, model, name);
 387
 388    s = DO_UPCAST(TAPState, nc, nc);
 389
 390    s->fd = fd;
 391    s->host_vnet_hdr_len = vnet_hdr ? sizeof(struct virtio_net_hdr) : 0;
 392    s->using_vnet_hdr = false;
 393    s->has_ufo = tap_probe_has_ufo(s->fd);
 394    s->enabled = true;
 395    tap_set_offload(&s->nc, 0, 0, 0, 0, 0);
 396    /*
 397     * Make sure host header length is set correctly in tap:
 398     * it might have been modified by another instance of qemu.
 399     */
 400    if (tap_probe_vnet_hdr_len(s->fd, s->host_vnet_hdr_len)) {
 401        tap_fd_set_vnet_hdr_len(s->fd, s->host_vnet_hdr_len);
 402    }
 403    tap_read_poll(s, true);
 404    s->vhost_net = NULL;
 405
 406    s->exit.notify = tap_exit_notify;
 407    qemu_add_exit_notifier(&s->exit);
 408
 409    return s;
 410}
 411
 412static void launch_script(const char *setup_script, const char *ifname,
 413                          int fd, Error **errp)
 414{
 415    int pid, status;
 416    char *args[3];
 417    char **parg;
 418
 419    /* try to launch network script */
 420    pid = fork();
 421    if (pid < 0) {
 422        error_setg_errno(errp, errno, "could not launch network script %s",
 423                         setup_script);
 424        return;
 425    }
 426    if (pid == 0) {
 427        int open_max = sysconf(_SC_OPEN_MAX), i;
 428
 429        for (i = 3; i < open_max; i++) {
 430            if (i != fd) {
 431                close(i);
 432            }
 433        }
 434        parg = args;
 435        *parg++ = (char *)setup_script;
 436        *parg++ = (char *)ifname;
 437        *parg = NULL;
 438        execv(setup_script, args);
 439        _exit(1);
 440    } else {
 441        while (waitpid(pid, &status, 0) != pid) {
 442            /* loop */
 443        }
 444
 445        if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
 446            return;
 447        }
 448        error_setg(errp, "network script %s failed with status %d",
 449                   setup_script, status);
 450    }
 451}
 452
 453static int recv_fd(int c)
 454{
 455    int fd;
 456    uint8_t msgbuf[CMSG_SPACE(sizeof(fd))];
 457    struct msghdr msg = {
 458        .msg_control = msgbuf,
 459        .msg_controllen = sizeof(msgbuf),
 460    };
 461    struct cmsghdr *cmsg;
 462    struct iovec iov;
 463    uint8_t req[1];
 464    ssize_t len;
 465
 466    cmsg = CMSG_FIRSTHDR(&msg);
 467    cmsg->cmsg_level = SOL_SOCKET;
 468    cmsg->cmsg_type = SCM_RIGHTS;
 469    cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
 470    msg.msg_controllen = cmsg->cmsg_len;
 471
 472    iov.iov_base = req;
 473    iov.iov_len = sizeof(req);
 474
 475    msg.msg_iov = &iov;
 476    msg.msg_iovlen = 1;
 477
 478    len = recvmsg(c, &msg, 0);
 479    if (len > 0) {
 480        memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd));
 481        return fd;
 482    }
 483
 484    return len;
 485}
 486
 487static int net_bridge_run_helper(const char *helper, const char *bridge,
 488                                 Error **errp)
 489{
 490    sigset_t oldmask, mask;
 491    g_autofree char *default_helper = NULL;
 492    int pid, status;
 493    char *args[5];
 494    char **parg;
 495    int sv[2];
 496
 497    sigemptyset(&mask);
 498    sigaddset(&mask, SIGCHLD);
 499    sigprocmask(SIG_BLOCK, &mask, &oldmask);
 500
 501    if (!helper) {
 502        helper = default_helper = get_relocated_path(DEFAULT_BRIDGE_HELPER);
 503    }
 504
 505    if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) == -1) {
 506        error_setg_errno(errp, errno, "socketpair() failed");
 507        return -1;
 508    }
 509
 510    /* try to launch bridge helper */
 511    pid = fork();
 512    if (pid < 0) {
 513        error_setg_errno(errp, errno, "Can't fork bridge helper");
 514        return -1;
 515    }
 516    if (pid == 0) {
 517        int open_max = sysconf(_SC_OPEN_MAX), i;
 518        char *fd_buf = NULL;
 519        char *br_buf = NULL;
 520        char *helper_cmd = NULL;
 521
 522        for (i = 3; i < open_max; i++) {
 523            if (i != sv[1]) {
 524                close(i);
 525            }
 526        }
 527
 528        fd_buf = g_strdup_printf("%s%d", "--fd=", sv[1]);
 529
 530        if (strrchr(helper, ' ') || strrchr(helper, '\t')) {
 531            /* assume helper is a command */
 532
 533            if (strstr(helper, "--br=") == NULL) {
 534                br_buf = g_strdup_printf("%s%s", "--br=", bridge);
 535            }
 536
 537            helper_cmd = g_strdup_printf("%s %s %s %s", helper,
 538                            "--use-vnet", fd_buf, br_buf ? br_buf : "");
 539
 540            parg = args;
 541            *parg++ = (char *)"sh";
 542            *parg++ = (char *)"-c";
 543            *parg++ = helper_cmd;
 544            *parg++ = NULL;
 545
 546            execv("/bin/sh", args);
 547            g_free(helper_cmd);
 548        } else {
 549            /* assume helper is just the executable path name */
 550
 551            br_buf = g_strdup_printf("%s%s", "--br=", bridge);
 552
 553            parg = args;
 554            *parg++ = (char *)helper;
 555            *parg++ = (char *)"--use-vnet";
 556            *parg++ = fd_buf;
 557            *parg++ = br_buf;
 558            *parg++ = NULL;
 559
 560            execv(helper, args);
 561        }
 562        g_free(fd_buf);
 563        g_free(br_buf);
 564        _exit(1);
 565
 566    } else {
 567        int fd;
 568        int saved_errno;
 569
 570        close(sv[1]);
 571
 572        do {
 573            fd = recv_fd(sv[0]);
 574        } while (fd == -1 && errno == EINTR);
 575        saved_errno = errno;
 576
 577        close(sv[0]);
 578
 579        while (waitpid(pid, &status, 0) != pid) {
 580            /* loop */
 581        }
 582        sigprocmask(SIG_SETMASK, &oldmask, NULL);
 583        if (fd < 0) {
 584            error_setg_errno(errp, saved_errno,
 585                             "failed to recv file descriptor");
 586            return -1;
 587        }
 588        if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
 589            error_setg(errp, "bridge helper failed");
 590            return -1;
 591        }
 592        return fd;
 593    }
 594}
 595
 596int net_init_bridge(const Netdev *netdev, const char *name,
 597                    NetClientState *peer, Error **errp)
 598{
 599    const NetdevBridgeOptions *bridge;
 600    const char *helper, *br;
 601    TAPState *s;
 602    int fd, vnet_hdr;
 603
 604    assert(netdev->type == NET_CLIENT_DRIVER_BRIDGE);
 605    bridge = &netdev->u.bridge;
 606    helper = bridge->has_helper ? bridge->helper : NULL;
 607    br     = bridge->has_br     ? bridge->br     : DEFAULT_BRIDGE_INTERFACE;
 608
 609    fd = net_bridge_run_helper(helper, br, errp);
 610    if (fd == -1) {
 611        return -1;
 612    }
 613
 614    qemu_set_nonblock(fd);
 615    vnet_hdr = tap_probe_vnet_hdr(fd, errp);
 616    if (vnet_hdr < 0) {
 617        close(fd);
 618        return -1;
 619    }
 620    s = net_tap_fd_init(peer, "bridge", name, fd, vnet_hdr);
 621
 622    snprintf(s->nc.info_str, sizeof(s->nc.info_str), "helper=%s,br=%s", helper,
 623             br);
 624
 625    return 0;
 626}
 627
 628static int net_tap_init(const NetdevTapOptions *tap, int *vnet_hdr,
 629                        const char *setup_script, char *ifname,
 630                        size_t ifname_sz, int mq_required, Error **errp)
 631{
 632    Error *err = NULL;
 633    int fd, vnet_hdr_required;
 634
 635    if (tap->has_vnet_hdr) {
 636        *vnet_hdr = tap->vnet_hdr;
 637        vnet_hdr_required = *vnet_hdr;
 638    } else {
 639        *vnet_hdr = 1;
 640        vnet_hdr_required = 0;
 641    }
 642
 643    TFR(fd = tap_open(ifname, ifname_sz, vnet_hdr, vnet_hdr_required,
 644                      mq_required, errp));
 645    if (fd < 0) {
 646        return -1;
 647    }
 648
 649    if (setup_script &&
 650        setup_script[0] != '\0' &&
 651        strcmp(setup_script, "no") != 0) {
 652        launch_script(setup_script, ifname, fd, &err);
 653        if (err) {
 654            error_propagate(errp, err);
 655            close(fd);
 656            return -1;
 657        }
 658    }
 659
 660    return fd;
 661}
 662
 663#define MAX_TAP_QUEUES 1024
 664
 665static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer,
 666                             const char *model, const char *name,
 667                             const char *ifname, const char *script,
 668                             const char *downscript, const char *vhostfdname,
 669                             int vnet_hdr, int fd, Error **errp)
 670{
 671    Error *err = NULL;
 672    TAPState *s = net_tap_fd_init(peer, model, name, fd, vnet_hdr);
 673    int vhostfd;
 674
 675    tap_set_sndbuf(s->fd, tap, &err);
 676    if (err) {
 677        error_propagate(errp, err);
 678        return;
 679    }
 680
 681    if (tap->has_fd || tap->has_fds) {
 682        snprintf(s->nc.info_str, sizeof(s->nc.info_str), "fd=%d", fd);
 683    } else if (tap->has_helper) {
 684        snprintf(s->nc.info_str, sizeof(s->nc.info_str), "helper=%s",
 685                 tap->helper);
 686    } else {
 687        snprintf(s->nc.info_str, sizeof(s->nc.info_str),
 688                 "ifname=%s,script=%s,downscript=%s", ifname, script,
 689                 downscript);
 690
 691        if (strcmp(downscript, "no") != 0) {
 692            snprintf(s->down_script, sizeof(s->down_script), "%s", downscript);
 693            snprintf(s->down_script_arg, sizeof(s->down_script_arg),
 694                     "%s", ifname);
 695        }
 696    }
 697
 698    if (tap->has_vhost ? tap->vhost :
 699        vhostfdname || (tap->has_vhostforce && tap->vhostforce)) {
 700        VhostNetOptions options;
 701
 702        options.backend_type = VHOST_BACKEND_TYPE_KERNEL;
 703        options.net_backend = &s->nc;
 704        if (tap->has_poll_us) {
 705            options.busyloop_timeout = tap->poll_us;
 706        } else {
 707            options.busyloop_timeout = 0;
 708        }
 709
 710        if (vhostfdname) {
 711            int ret;
 712
 713            vhostfd = monitor_fd_param(monitor_cur(), vhostfdname, &err);
 714            if (vhostfd == -1) {
 715                if (tap->has_vhostforce && tap->vhostforce) {
 716                    error_propagate(errp, err);
 717                } else {
 718                    warn_report_err(err);
 719                }
 720                return;
 721            }
 722            ret = qemu_try_set_nonblock(vhostfd);
 723            if (ret < 0) {
 724                error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d",
 725                                 name, fd);
 726                return;
 727            }
 728        } else {
 729            vhostfd = open("/dev/vhost-net", O_RDWR);
 730            if (vhostfd < 0) {
 731                if (tap->has_vhostforce && tap->vhostforce) {
 732                    error_setg_errno(errp, errno,
 733                                     "tap: open vhost char device failed");
 734                } else {
 735                    warn_report("tap: open vhost char device failed: %s",
 736                                strerror(errno));
 737                }
 738                return;
 739            }
 740            qemu_set_nonblock(vhostfd);
 741        }
 742        options.opaque = (void *)(uintptr_t)vhostfd;
 743
 744        s->vhost_net = vhost_net_init(&options);
 745        if (!s->vhost_net) {
 746            if (tap->has_vhostforce && tap->vhostforce) {
 747                error_setg(errp, VHOST_NET_INIT_FAILED);
 748            } else {
 749                warn_report(VHOST_NET_INIT_FAILED);
 750            }
 751            return;
 752        }
 753    } else if (vhostfdname) {
 754        error_setg(errp, "vhostfd(s)= is not valid without vhost");
 755    }
 756}
 757
 758static int get_fds(char *str, char *fds[], int max)
 759{
 760    char *ptr = str, *this;
 761    size_t len = strlen(str);
 762    int i = 0;
 763
 764    while (i < max && ptr < str + len) {
 765        this = strchr(ptr, ':');
 766
 767        if (this == NULL) {
 768            fds[i] = g_strdup(ptr);
 769        } else {
 770            fds[i] = g_strndup(ptr, this - ptr);
 771        }
 772
 773        i++;
 774        if (this == NULL) {
 775            break;
 776        } else {
 777            ptr = this + 1;
 778        }
 779    }
 780
 781    return i;
 782}
 783
 784int net_init_tap(const Netdev *netdev, const char *name,
 785                 NetClientState *peer, Error **errp)
 786{
 787    const NetdevTapOptions *tap;
 788    int fd, vnet_hdr = 0, i = 0, queues;
 789    /* for the no-fd, no-helper case */
 790    const char *script;
 791    const char *downscript;
 792    Error *err = NULL;
 793    const char *vhostfdname;
 794    char ifname[128];
 795    int ret = 0;
 796
 797    assert(netdev->type == NET_CLIENT_DRIVER_TAP);
 798    tap = &netdev->u.tap;
 799    queues = tap->has_queues ? tap->queues : 1;
 800    vhostfdname = tap->has_vhostfd ? tap->vhostfd : NULL;
 801    script = tap->has_script ? tap->script : NULL;
 802    downscript = tap->has_downscript ? tap->downscript : NULL;
 803
 804    /* QEMU hubs do not support multiqueue tap, in this case peer is set.
 805     * For -netdev, peer is always NULL. */
 806    if (peer && (tap->has_queues || tap->has_fds || tap->has_vhostfds)) {
 807        error_setg(errp, "Multiqueue tap cannot be used with hubs");
 808        return -1;
 809    }
 810
 811    if (tap->has_fd) {
 812        if (tap->has_ifname || tap->has_script || tap->has_downscript ||
 813            tap->has_vnet_hdr || tap->has_helper || tap->has_queues ||
 814            tap->has_fds || tap->has_vhostfds) {
 815            error_setg(errp, "ifname=, script=, downscript=, vnet_hdr=, "
 816                       "helper=, queues=, fds=, and vhostfds= "
 817                       "are invalid with fd=");
 818            return -1;
 819        }
 820
 821        fd = monitor_fd_param(monitor_cur(), tap->fd, errp);
 822        if (fd == -1) {
 823            return -1;
 824        }
 825
 826        ret = qemu_try_set_nonblock(fd);
 827        if (ret < 0) {
 828            error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d",
 829                             name, fd);
 830            close(fd);
 831            return -1;
 832        }
 833
 834        vnet_hdr = tap_probe_vnet_hdr(fd, errp);
 835        if (vnet_hdr < 0) {
 836            close(fd);
 837            return -1;
 838        }
 839
 840        net_init_tap_one(tap, peer, "tap", name, NULL,
 841                         script, downscript,
 842                         vhostfdname, vnet_hdr, fd, &err);
 843        if (err) {
 844            error_propagate(errp, err);
 845            close(fd);
 846            return -1;
 847        }
 848    } else if (tap->has_fds) {
 849        char **fds;
 850        char **vhost_fds;
 851        int nfds = 0, nvhosts = 0;
 852
 853        if (tap->has_ifname || tap->has_script || tap->has_downscript ||
 854            tap->has_vnet_hdr || tap->has_helper || tap->has_queues ||
 855            tap->has_vhostfd) {
 856            error_setg(errp, "ifname=, script=, downscript=, vnet_hdr=, "
 857                       "helper=, queues=, and vhostfd= "
 858                       "are invalid with fds=");
 859            return -1;
 860        }
 861
 862        fds = g_new0(char *, MAX_TAP_QUEUES);
 863        vhost_fds = g_new0(char *, MAX_TAP_QUEUES);
 864
 865        nfds = get_fds(tap->fds, fds, MAX_TAP_QUEUES);
 866        if (tap->has_vhostfds) {
 867            nvhosts = get_fds(tap->vhostfds, vhost_fds, MAX_TAP_QUEUES);
 868            if (nfds != nvhosts) {
 869                error_setg(errp, "The number of fds passed does not match "
 870                           "the number of vhostfds passed");
 871                ret = -1;
 872                goto free_fail;
 873            }
 874        }
 875
 876        for (i = 0; i < nfds; i++) {
 877            fd = monitor_fd_param(monitor_cur(), fds[i], errp);
 878            if (fd == -1) {
 879                ret = -1;
 880                goto free_fail;
 881            }
 882
 883            ret = qemu_try_set_nonblock(fd);
 884            if (ret < 0) {
 885                error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d",
 886                                 name, fd);
 887                goto free_fail;
 888            }
 889
 890            if (i == 0) {
 891                vnet_hdr = tap_probe_vnet_hdr(fd, errp);
 892                if (vnet_hdr < 0) {
 893                    goto free_fail;
 894                }
 895            } else if (vnet_hdr != tap_probe_vnet_hdr(fd, NULL)) {
 896                error_setg(errp,
 897                           "vnet_hdr not consistent across given tap fds");
 898                ret = -1;
 899                goto free_fail;
 900            }
 901
 902            net_init_tap_one(tap, peer, "tap", name, ifname,
 903                             script, downscript,
 904                             tap->has_vhostfds ? vhost_fds[i] : NULL,
 905                             vnet_hdr, fd, &err);
 906            if (err) {
 907                error_propagate(errp, err);
 908                ret = -1;
 909                goto free_fail;
 910            }
 911        }
 912
 913free_fail:
 914        for (i = 0; i < nvhosts; i++) {
 915            g_free(vhost_fds[i]);
 916        }
 917        for (i = 0; i < nfds; i++) {
 918            g_free(fds[i]);
 919        }
 920        g_free(fds);
 921        g_free(vhost_fds);
 922        return ret;
 923    } else if (tap->has_helper) {
 924        if (tap->has_ifname || tap->has_script || tap->has_downscript ||
 925            tap->has_vnet_hdr || tap->has_queues || tap->has_vhostfds) {
 926            error_setg(errp, "ifname=, script=, downscript=, vnet_hdr=, "
 927                       "queues=, and vhostfds= are invalid with helper=");
 928            return -1;
 929        }
 930
 931        fd = net_bridge_run_helper(tap->helper,
 932                                   tap->has_br ?
 933                                   tap->br : DEFAULT_BRIDGE_INTERFACE,
 934                                   errp);
 935        if (fd == -1) {
 936            return -1;
 937        }
 938
 939        qemu_set_nonblock(fd);
 940        vnet_hdr = tap_probe_vnet_hdr(fd, errp);
 941        if (vnet_hdr < 0) {
 942            close(fd);
 943            return -1;
 944        }
 945
 946        net_init_tap_one(tap, peer, "bridge", name, ifname,
 947                         script, downscript, vhostfdname,
 948                         vnet_hdr, fd, &err);
 949        if (err) {
 950            error_propagate(errp, err);
 951            close(fd);
 952            return -1;
 953        }
 954    } else {
 955        g_autofree char *default_script = NULL;
 956        g_autofree char *default_downscript = NULL;
 957        if (tap->has_vhostfds) {
 958            error_setg(errp, "vhostfds= is invalid if fds= wasn't specified");
 959            return -1;
 960        }
 961
 962        if (!script) {
 963            script = default_script = get_relocated_path(DEFAULT_NETWORK_SCRIPT);
 964        }
 965        if (!downscript) {
 966            downscript = default_downscript =
 967                                 get_relocated_path(DEFAULT_NETWORK_DOWN_SCRIPT);
 968        }
 969
 970        if (tap->has_ifname) {
 971            pstrcpy(ifname, sizeof ifname, tap->ifname);
 972        } else {
 973            ifname[0] = '\0';
 974        }
 975
 976        for (i = 0; i < queues; i++) {
 977            fd = net_tap_init(tap, &vnet_hdr, i >= 1 ? "no" : script,
 978                              ifname, sizeof ifname, queues > 1, errp);
 979            if (fd == -1) {
 980                return -1;
 981            }
 982
 983            if (queues > 1 && i == 0 && !tap->has_ifname) {
 984                if (tap_fd_get_ifname(fd, ifname)) {
 985                    error_setg(errp, "Fail to get ifname");
 986                    close(fd);
 987                    return -1;
 988                }
 989            }
 990
 991            net_init_tap_one(tap, peer, "tap", name, ifname,
 992                             i >= 1 ? "no" : script,
 993                             i >= 1 ? "no" : downscript,
 994                             vhostfdname, vnet_hdr, fd, &err);
 995            if (err) {
 996                error_propagate(errp, err);
 997                close(fd);
 998                return -1;
 999            }
1000        }
1001    }
1002
1003    return 0;
1004}
1005
1006VHostNetState *tap_get_vhost_net(NetClientState *nc)
1007{
1008    TAPState *s = DO_UPCAST(TAPState, nc, nc);
1009    assert(nc->info->type == NET_CLIENT_DRIVER_TAP);
1010    return s->vhost_net;
1011}
1012
1013int tap_enable(NetClientState *nc)
1014{
1015    TAPState *s = DO_UPCAST(TAPState, nc, nc);
1016    int ret;
1017
1018    if (s->enabled) {
1019        return 0;
1020    } else {
1021        ret = tap_fd_enable(s->fd);
1022        if (ret == 0) {
1023            s->enabled = true;
1024            tap_update_fd_handler(s);
1025        }
1026        return ret;
1027    }
1028}
1029
1030int tap_disable(NetClientState *nc)
1031{
1032    TAPState *s = DO_UPCAST(TAPState, nc, nc);
1033    int ret;
1034
1035    if (s->enabled == 0) {
1036        return 0;
1037    } else {
1038        ret = tap_fd_disable(s->fd);
1039        if (ret == 0) {
1040            qemu_purge_queued_packets(nc);
1041            s->enabled = false;
1042            tap_update_fd_handler(s);
1043        }
1044        return ret;
1045    }
1046}
1047