qemu/net.c
<<
>>
Prefs
   1/*
   2 * QEMU System Emulator
   3 *
   4 * Copyright (c) 2003-2008 Fabrice Bellard
   5 *
   6 * Permission is hereby granted, free of charge, to any person obtaining a copy
   7 * of this software and associated documentation files (the "Software"), to deal
   8 * in the Software without restriction, including without limitation the rights
   9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 * copies of the Software, and to permit persons to whom the Software is
  11 * furnished to do so, subject to the following conditions:
  12 *
  13 * The above copyright notice and this permission notice shall be included in
  14 * all copies or substantial portions of the Software.
  15 *
  16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 * THE SOFTWARE.
  23 */
  24#include "config-host.h"
  25
  26#include "net.h"
  27#include "net/clients.h"
  28#include "net/hub.h"
  29#include "net/slirp.h"
  30#include "net/util.h"
  31
  32#include "monitor.h"
  33#include "qemu-common.h"
  34#include "qemu_socket.h"
  35#include "qmp-commands.h"
  36#include "hw/qdev.h"
  37#include "iov.h"
  38#include "qapi-visit.h"
  39#include "qapi/opts-visitor.h"
  40#include "qapi/qapi-dealloc-visitor.h"
  41
  42/* Net bridge is currently not supported for W32. */
  43#if !defined(_WIN32)
  44# define CONFIG_NET_BRIDGE
  45#endif
  46
  47static QTAILQ_HEAD(, NetClientState) net_clients;
  48
  49int default_net = 1;
  50
  51/***********************************************************/
  52/* network device redirectors */
  53
  54#if defined(DEBUG_NET)
  55static void hex_dump(FILE *f, const uint8_t *buf, int size)
  56{
  57    int len, i, j, c;
  58
  59    for(i=0;i<size;i+=16) {
  60        len = size - i;
  61        if (len > 16)
  62            len = 16;
  63        fprintf(f, "%08x ", i);
  64        for(j=0;j<16;j++) {
  65            if (j < len)
  66                fprintf(f, " %02x", buf[i+j]);
  67            else
  68                fprintf(f, "   ");
  69        }
  70        fprintf(f, " ");
  71        for(j=0;j<len;j++) {
  72            c = buf[i+j];
  73            if (c < ' ' || c > '~')
  74                c = '.';
  75            fprintf(f, "%c", c);
  76        }
  77        fprintf(f, "\n");
  78    }
  79}
  80#endif
  81
  82static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
  83{
  84    const char *p, *p1;
  85    int len;
  86    p = *pp;
  87    p1 = strchr(p, sep);
  88    if (!p1)
  89        return -1;
  90    len = p1 - p;
  91    p1++;
  92    if (buf_size > 0) {
  93        if (len > buf_size - 1)
  94            len = buf_size - 1;
  95        memcpy(buf, p, len);
  96        buf[len] = '\0';
  97    }
  98    *pp = p1;
  99    return 0;
 100}
 101
 102int parse_host_port(struct sockaddr_in *saddr, const char *str)
 103{
 104    char buf[512];
 105    struct hostent *he;
 106    const char *p, *r;
 107    int port;
 108
 109    p = str;
 110    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
 111        return -1;
 112    saddr->sin_family = AF_INET;
 113    if (buf[0] == '\0') {
 114        saddr->sin_addr.s_addr = 0;
 115    } else {
 116        if (qemu_isdigit(buf[0])) {
 117            if (!inet_aton(buf, &saddr->sin_addr))
 118                return -1;
 119        } else {
 120            if ((he = gethostbyname(buf)) == NULL)
 121                return - 1;
 122            saddr->sin_addr = *(struct in_addr *)he->h_addr;
 123        }
 124    }
 125    port = strtol(p, (char **)&r, 0);
 126    if (r == p)
 127        return -1;
 128    saddr->sin_port = htons(port);
 129    return 0;
 130}
 131
 132void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6])
 133{
 134    snprintf(nc->info_str, sizeof(nc->info_str),
 135             "model=%s,macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
 136             nc->model,
 137             macaddr[0], macaddr[1], macaddr[2],
 138             macaddr[3], macaddr[4], macaddr[5]);
 139}
 140
 141void qemu_macaddr_default_if_unset(MACAddr *macaddr)
 142{
 143    static int index = 0;
 144    static const MACAddr zero = { .a = { 0,0,0,0,0,0 } };
 145
 146    if (memcmp(macaddr, &zero, sizeof(zero)) != 0)
 147        return;
 148    macaddr->a[0] = 0x52;
 149    macaddr->a[1] = 0x54;
 150    macaddr->a[2] = 0x00;
 151    macaddr->a[3] = 0x12;
 152    macaddr->a[4] = 0x34;
 153    macaddr->a[5] = 0x56 + index++;
 154}
 155
 156/**
 157 * Generate a name for net client
 158 *
 159 * Only net clients created with the legacy -net option need this.  Naming is
 160 * mandatory for net clients created with -netdev.
 161 */
 162static char *assign_name(NetClientState *nc1, const char *model)
 163{
 164    NetClientState *nc;
 165    char buf[256];
 166    int id = 0;
 167
 168    QTAILQ_FOREACH(nc, &net_clients, next) {
 169        if (nc == nc1) {
 170            continue;
 171        }
 172        /* For compatibility only bump id for net clients on a vlan */
 173        if (strcmp(nc->model, model) == 0 &&
 174            net_hub_id_for_client(nc, NULL) == 0) {
 175            id++;
 176        }
 177    }
 178
 179    snprintf(buf, sizeof(buf), "%s.%d", model, id);
 180
 181    return g_strdup(buf);
 182}
 183
 184NetClientState *qemu_new_net_client(NetClientInfo *info,
 185                                    NetClientState *peer,
 186                                    const char *model,
 187                                    const char *name)
 188{
 189    NetClientState *nc;
 190
 191    assert(info->size >= sizeof(NetClientState));
 192
 193    nc = g_malloc0(info->size);
 194
 195    nc->info = info;
 196    nc->model = g_strdup(model);
 197    if (name) {
 198        nc->name = g_strdup(name);
 199    } else {
 200        nc->name = assign_name(nc, model);
 201    }
 202
 203    if (peer) {
 204        assert(!peer->peer);
 205        nc->peer = peer;
 206        peer->peer = nc;
 207    }
 208    QTAILQ_INSERT_TAIL(&net_clients, nc, next);
 209
 210    nc->send_queue = qemu_new_net_queue(nc);
 211
 212    return nc;
 213}
 214
 215NICState *qemu_new_nic(NetClientInfo *info,
 216                       NICConf *conf,
 217                       const char *model,
 218                       const char *name,
 219                       void *opaque)
 220{
 221    NetClientState *nc;
 222    NICState *nic;
 223
 224    assert(info->type == NET_CLIENT_OPTIONS_KIND_NIC);
 225    assert(info->size >= sizeof(NICState));
 226
 227    nc = qemu_new_net_client(info, conf->peer, model, name);
 228
 229    nic = DO_UPCAST(NICState, nc, nc);
 230    nic->conf = conf;
 231    nic->opaque = opaque;
 232
 233    return nic;
 234}
 235
 236static void qemu_cleanup_net_client(NetClientState *nc)
 237{
 238    QTAILQ_REMOVE(&net_clients, nc, next);
 239
 240    if (nc->info->cleanup) {
 241        nc->info->cleanup(nc);
 242    }
 243}
 244
 245static void qemu_free_net_client(NetClientState *nc)
 246{
 247    if (nc->send_queue) {
 248        qemu_del_net_queue(nc->send_queue);
 249    }
 250    if (nc->peer) {
 251        nc->peer->peer = NULL;
 252    }
 253    g_free(nc->name);
 254    g_free(nc->model);
 255    g_free(nc);
 256}
 257
 258void qemu_del_net_client(NetClientState *nc)
 259{
 260    /* If there is a peer NIC, delete and cleanup client, but do not free. */
 261    if (nc->peer && nc->peer->info->type == NET_CLIENT_OPTIONS_KIND_NIC) {
 262        NICState *nic = DO_UPCAST(NICState, nc, nc->peer);
 263        if (nic->peer_deleted) {
 264            return;
 265        }
 266        nic->peer_deleted = true;
 267        /* Let NIC know peer is gone. */
 268        nc->peer->link_down = true;
 269        if (nc->peer->info->link_status_changed) {
 270            nc->peer->info->link_status_changed(nc->peer);
 271        }
 272        qemu_cleanup_net_client(nc);
 273        return;
 274    }
 275
 276    /* If this is a peer NIC and peer has already been deleted, free it now. */
 277    if (nc->peer && nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC) {
 278        NICState *nic = DO_UPCAST(NICState, nc, nc);
 279        if (nic->peer_deleted) {
 280            qemu_free_net_client(nc->peer);
 281        }
 282    }
 283
 284    qemu_cleanup_net_client(nc);
 285    qemu_free_net_client(nc);
 286}
 287
 288void qemu_foreach_nic(qemu_nic_foreach func, void *opaque)
 289{
 290    NetClientState *nc;
 291
 292    QTAILQ_FOREACH(nc, &net_clients, next) {
 293        if (nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC) {
 294            func(DO_UPCAST(NICState, nc, nc), opaque);
 295        }
 296    }
 297}
 298
 299int qemu_can_send_packet(NetClientState *sender)
 300{
 301    if (!sender->peer) {
 302        return 1;
 303    }
 304
 305    if (sender->peer->receive_disabled) {
 306        return 0;
 307    } else if (sender->peer->info->can_receive &&
 308               !sender->peer->info->can_receive(sender->peer)) {
 309        return 0;
 310    }
 311    return 1;
 312}
 313
 314ssize_t qemu_deliver_packet(NetClientState *sender,
 315                            unsigned flags,
 316                            const uint8_t *data,
 317                            size_t size,
 318                            void *opaque)
 319{
 320    NetClientState *nc = opaque;
 321    ssize_t ret;
 322
 323    if (nc->link_down) {
 324        return size;
 325    }
 326
 327    if (nc->receive_disabled) {
 328        return 0;
 329    }
 330
 331    if (flags & QEMU_NET_PACKET_FLAG_RAW && nc->info->receive_raw) {
 332        ret = nc->info->receive_raw(nc, data, size);
 333    } else {
 334        ret = nc->info->receive(nc, data, size);
 335    }
 336
 337    if (ret == 0) {
 338        nc->receive_disabled = 1;
 339    };
 340
 341    return ret;
 342}
 343
 344void qemu_purge_queued_packets(NetClientState *nc)
 345{
 346    if (!nc->peer) {
 347        return;
 348    }
 349
 350    qemu_net_queue_purge(nc->peer->send_queue, nc);
 351}
 352
 353void qemu_flush_queued_packets(NetClientState *nc)
 354{
 355    nc->receive_disabled = 0;
 356
 357    if (qemu_net_queue_flush(nc->send_queue)) {
 358        /* We emptied the queue successfully, signal to the IO thread to repoll
 359         * the file descriptor (for tap, for example).
 360         */
 361        qemu_notify_event();
 362    }
 363}
 364
 365static ssize_t qemu_send_packet_async_with_flags(NetClientState *sender,
 366                                                 unsigned flags,
 367                                                 const uint8_t *buf, int size,
 368                                                 NetPacketSent *sent_cb)
 369{
 370    NetQueue *queue;
 371
 372#ifdef DEBUG_NET
 373    printf("qemu_send_packet_async:\n");
 374    hex_dump(stdout, buf, size);
 375#endif
 376
 377    if (sender->link_down || !sender->peer) {
 378        return size;
 379    }
 380
 381    queue = sender->peer->send_queue;
 382
 383    return qemu_net_queue_send(queue, sender, flags, buf, size, sent_cb);
 384}
 385
 386ssize_t qemu_send_packet_async(NetClientState *sender,
 387                               const uint8_t *buf, int size,
 388                               NetPacketSent *sent_cb)
 389{
 390    return qemu_send_packet_async_with_flags(sender, QEMU_NET_PACKET_FLAG_NONE,
 391                                             buf, size, sent_cb);
 392}
 393
 394void qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size)
 395{
 396    qemu_send_packet_async(nc, buf, size, NULL);
 397}
 398
 399ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size)
 400{
 401    return qemu_send_packet_async_with_flags(nc, QEMU_NET_PACKET_FLAG_RAW,
 402                                             buf, size, NULL);
 403}
 404
 405static ssize_t nc_sendv_compat(NetClientState *nc, const struct iovec *iov,
 406                               int iovcnt)
 407{
 408    uint8_t buffer[4096];
 409    size_t offset;
 410
 411    offset = iov_to_buf(iov, iovcnt, 0, buffer, sizeof(buffer));
 412
 413    return nc->info->receive(nc, buffer, offset);
 414}
 415
 416ssize_t qemu_deliver_packet_iov(NetClientState *sender,
 417                                unsigned flags,
 418                                const struct iovec *iov,
 419                                int iovcnt,
 420                                void *opaque)
 421{
 422    NetClientState *nc = opaque;
 423    int ret;
 424
 425    if (nc->link_down) {
 426        return iov_size(iov, iovcnt);
 427    }
 428
 429    if (nc->receive_disabled) {
 430        return 0;
 431    }
 432
 433    if (nc->info->receive_iov) {
 434        ret = nc->info->receive_iov(nc, iov, iovcnt);
 435    } else {
 436        ret = nc_sendv_compat(nc, iov, iovcnt);
 437    }
 438
 439    if (ret == 0) {
 440        nc->receive_disabled = 1;
 441    }
 442
 443    return ret;
 444}
 445
 446ssize_t qemu_sendv_packet_async(NetClientState *sender,
 447                                const struct iovec *iov, int iovcnt,
 448                                NetPacketSent *sent_cb)
 449{
 450    NetQueue *queue;
 451
 452    if (sender->link_down || !sender->peer) {
 453        return iov_size(iov, iovcnt);
 454    }
 455
 456    queue = sender->peer->send_queue;
 457
 458    return qemu_net_queue_send_iov(queue, sender,
 459                                   QEMU_NET_PACKET_FLAG_NONE,
 460                                   iov, iovcnt, sent_cb);
 461}
 462
 463ssize_t
 464qemu_sendv_packet(NetClientState *nc, const struct iovec *iov, int iovcnt)
 465{
 466    return qemu_sendv_packet_async(nc, iov, iovcnt, NULL);
 467}
 468
 469NetClientState *qemu_find_netdev(const char *id)
 470{
 471    NetClientState *nc;
 472
 473    QTAILQ_FOREACH(nc, &net_clients, next) {
 474        if (nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC)
 475            continue;
 476        if (!strcmp(nc->name, id)) {
 477            return nc;
 478        }
 479    }
 480
 481    return NULL;
 482}
 483
 484static int nic_get_free_idx(void)
 485{
 486    int index;
 487
 488    for (index = 0; index < MAX_NICS; index++)
 489        if (!nd_table[index].used)
 490            return index;
 491    return -1;
 492}
 493
 494int qemu_show_nic_models(const char *arg, const char *const *models)
 495{
 496    int i;
 497
 498    if (!arg || !is_help_option(arg)) {
 499        return 0;
 500    }
 501
 502    fprintf(stderr, "qemu: Supported NIC models: ");
 503    for (i = 0 ; models[i]; i++)
 504        fprintf(stderr, "%s%c", models[i], models[i+1] ? ',' : '\n');
 505    return 1;
 506}
 507
 508void qemu_check_nic_model(NICInfo *nd, const char *model)
 509{
 510    const char *models[2];
 511
 512    models[0] = model;
 513    models[1] = NULL;
 514
 515    if (qemu_show_nic_models(nd->model, models))
 516        exit(0);
 517    if (qemu_find_nic_model(nd, models, model) < 0)
 518        exit(1);
 519}
 520
 521int qemu_find_nic_model(NICInfo *nd, const char * const *models,
 522                        const char *default_model)
 523{
 524    int i;
 525
 526    if (!nd->model)
 527        nd->model = g_strdup(default_model);
 528
 529    for (i = 0 ; models[i]; i++) {
 530        if (strcmp(nd->model, models[i]) == 0)
 531            return i;
 532    }
 533
 534    error_report("Unsupported NIC model: %s", nd->model);
 535    return -1;
 536}
 537
 538static int net_init_nic(const NetClientOptions *opts, const char *name,
 539                        NetClientState *peer)
 540{
 541    int idx;
 542    NICInfo *nd;
 543    const NetLegacyNicOptions *nic;
 544
 545    assert(opts->kind == NET_CLIENT_OPTIONS_KIND_NIC);
 546    nic = opts->nic;
 547
 548    idx = nic_get_free_idx();
 549    if (idx == -1 || nb_nics >= MAX_NICS) {
 550        error_report("Too Many NICs");
 551        return -1;
 552    }
 553
 554    nd = &nd_table[idx];
 555
 556    memset(nd, 0, sizeof(*nd));
 557
 558    if (nic->has_netdev) {
 559        nd->netdev = qemu_find_netdev(nic->netdev);
 560        if (!nd->netdev) {
 561            error_report("netdev '%s' not found", nic->netdev);
 562            return -1;
 563        }
 564    } else {
 565        assert(peer);
 566        nd->netdev = peer;
 567    }
 568    if (name) {
 569        nd->name = g_strdup(name);
 570    }
 571    if (nic->has_model) {
 572        nd->model = g_strdup(nic->model);
 573    }
 574    if (nic->has_addr) {
 575        nd->devaddr = g_strdup(nic->addr);
 576    }
 577
 578    if (nic->has_macaddr &&
 579        net_parse_macaddr(nd->macaddr.a, nic->macaddr) < 0) {
 580        error_report("invalid syntax for ethernet address");
 581        return -1;
 582    }
 583    qemu_macaddr_default_if_unset(&nd->macaddr);
 584
 585    if (nic->has_vectors) {
 586        if (nic->vectors > 0x7ffffff) {
 587            error_report("invalid # of vectors: %"PRIu32, nic->vectors);
 588            return -1;
 589        }
 590        nd->nvectors = nic->vectors;
 591    } else {
 592        nd->nvectors = DEV_NVECTORS_UNSPECIFIED;
 593    }
 594
 595    nd->used = 1;
 596    nb_nics++;
 597
 598    return idx;
 599}
 600
 601
 602static int (* const net_client_init_fun[NET_CLIENT_OPTIONS_KIND_MAX])(
 603    const NetClientOptions *opts,
 604    const char *name,
 605    NetClientState *peer) = {
 606        [NET_CLIENT_OPTIONS_KIND_NIC]       = net_init_nic,
 607#ifdef CONFIG_SLIRP
 608        [NET_CLIENT_OPTIONS_KIND_USER]      = net_init_slirp,
 609#endif
 610        [NET_CLIENT_OPTIONS_KIND_TAP]       = net_init_tap,
 611        [NET_CLIENT_OPTIONS_KIND_SOCKET]    = net_init_socket,
 612#ifdef CONFIG_VDE
 613        [NET_CLIENT_OPTIONS_KIND_VDE]       = net_init_vde,
 614#endif
 615        [NET_CLIENT_OPTIONS_KIND_DUMP]      = net_init_dump,
 616#ifdef CONFIG_NET_BRIDGE
 617        [NET_CLIENT_OPTIONS_KIND_BRIDGE]    = net_init_bridge,
 618#endif
 619        [NET_CLIENT_OPTIONS_KIND_HUBPORT]   = net_init_hubport,
 620};
 621
 622
 623static int net_client_init1(const void *object, int is_netdev, Error **errp)
 624{
 625    union {
 626        const Netdev    *netdev;
 627        const NetLegacy *net;
 628    } u;
 629    const NetClientOptions *opts;
 630    const char *name;
 631
 632    if (is_netdev) {
 633        u.netdev = object;
 634        opts = u.netdev->opts;
 635        name = u.netdev->id;
 636
 637        switch (opts->kind) {
 638#ifdef CONFIG_SLIRP
 639        case NET_CLIENT_OPTIONS_KIND_USER:
 640#endif
 641        case NET_CLIENT_OPTIONS_KIND_TAP:
 642        case NET_CLIENT_OPTIONS_KIND_SOCKET:
 643#ifdef CONFIG_VDE
 644        case NET_CLIENT_OPTIONS_KIND_VDE:
 645#endif
 646#ifdef CONFIG_NET_BRIDGE
 647        case NET_CLIENT_OPTIONS_KIND_BRIDGE:
 648#endif
 649        case NET_CLIENT_OPTIONS_KIND_HUBPORT:
 650            break;
 651
 652        default:
 653            error_set(errp, QERR_INVALID_PARAMETER_VALUE, "type",
 654                      "a netdev backend type");
 655            return -1;
 656        }
 657    } else {
 658        u.net = object;
 659        opts = u.net->opts;
 660        /* missing optional values have been initialized to "all bits zero" */
 661        name = u.net->has_id ? u.net->id : u.net->name;
 662    }
 663
 664    if (net_client_init_fun[opts->kind]) {
 665        NetClientState *peer = NULL;
 666
 667        /* Do not add to a vlan if it's a -netdev or a nic with a netdev=
 668         * parameter. */
 669        if (!is_netdev &&
 670            (opts->kind != NET_CLIENT_OPTIONS_KIND_NIC ||
 671             !opts->nic->has_netdev)) {
 672            peer = net_hub_add_port(u.net->has_vlan ? u.net->vlan : 0, NULL);
 673        }
 674
 675        if (net_client_init_fun[opts->kind](opts, name, peer) < 0) {
 676            /* TODO push error reporting into init() methods */
 677            error_set(errp, QERR_DEVICE_INIT_FAILED,
 678                      NetClientOptionsKind_lookup[opts->kind]);
 679            return -1;
 680        }
 681    }
 682    return 0;
 683}
 684
 685
 686static void net_visit(Visitor *v, int is_netdev, void **object, Error **errp)
 687{
 688    if (is_netdev) {
 689        visit_type_Netdev(v, (Netdev **)object, NULL, errp);
 690    } else {
 691        visit_type_NetLegacy(v, (NetLegacy **)object, NULL, errp);
 692    }
 693}
 694
 695
 696int net_client_init(QemuOpts *opts, int is_netdev, Error **errp)
 697{
 698    void *object = NULL;
 699    Error *err = NULL;
 700    int ret = -1;
 701
 702    {
 703        OptsVisitor *ov = opts_visitor_new(opts);
 704
 705        net_visit(opts_get_visitor(ov), is_netdev, &object, &err);
 706        opts_visitor_cleanup(ov);
 707    }
 708
 709    if (!err) {
 710        ret = net_client_init1(object, is_netdev, &err);
 711    }
 712
 713    if (object) {
 714        QapiDeallocVisitor *dv = qapi_dealloc_visitor_new();
 715
 716        net_visit(qapi_dealloc_get_visitor(dv), is_netdev, &object, NULL);
 717        qapi_dealloc_visitor_cleanup(dv);
 718    }
 719
 720    error_propagate(errp, err);
 721    return ret;
 722}
 723
 724
 725static int net_host_check_device(const char *device)
 726{
 727    int i;
 728    const char *valid_param_list[] = { "tap", "socket", "dump"
 729#ifdef CONFIG_NET_BRIDGE
 730                                       , "bridge"
 731#endif
 732#ifdef CONFIG_SLIRP
 733                                       ,"user"
 734#endif
 735#ifdef CONFIG_VDE
 736                                       ,"vde"
 737#endif
 738    };
 739    for (i = 0; i < sizeof(valid_param_list) / sizeof(char *); i++) {
 740        if (!strncmp(valid_param_list[i], device,
 741                     strlen(valid_param_list[i])))
 742            return 1;
 743    }
 744
 745    return 0;
 746}
 747
 748void net_host_device_add(Monitor *mon, const QDict *qdict)
 749{
 750    const char *device = qdict_get_str(qdict, "device");
 751    const char *opts_str = qdict_get_try_str(qdict, "opts");
 752    Error *local_err = NULL;
 753    QemuOpts *opts;
 754
 755    if (!net_host_check_device(device)) {
 756        monitor_printf(mon, "invalid host network device %s\n", device);
 757        return;
 758    }
 759
 760    opts = qemu_opts_parse(qemu_find_opts("net"), opts_str ? opts_str : "", 0);
 761    if (!opts) {
 762        return;
 763    }
 764
 765    qemu_opt_set(opts, "type", device);
 766
 767    net_client_init(opts, 0, &local_err);
 768    if (error_is_set(&local_err)) {
 769        qerror_report_err(local_err);
 770        error_free(local_err);
 771        monitor_printf(mon, "adding host network device %s failed\n", device);
 772    }
 773}
 774
 775void net_host_device_remove(Monitor *mon, const QDict *qdict)
 776{
 777    NetClientState *nc;
 778    int vlan_id = qdict_get_int(qdict, "vlan_id");
 779    const char *device = qdict_get_str(qdict, "device");
 780
 781    nc = net_hub_find_client_by_name(vlan_id, device);
 782    if (!nc) {
 783        return;
 784    }
 785    if (!net_host_check_device(nc->model)) {
 786        monitor_printf(mon, "invalid host network device %s\n", device);
 787        return;
 788    }
 789    qemu_del_net_client(nc);
 790}
 791
 792void netdev_add(QemuOpts *opts, Error **errp)
 793{
 794    net_client_init(opts, 1, errp);
 795}
 796
 797int qmp_netdev_add(Monitor *mon, const QDict *qdict, QObject **ret)
 798{
 799    Error *local_err = NULL;
 800    QemuOptsList *opts_list;
 801    QemuOpts *opts;
 802
 803    opts_list = qemu_find_opts_err("netdev", &local_err);
 804    if (error_is_set(&local_err)) {
 805        goto exit_err;
 806    }
 807
 808    opts = qemu_opts_from_qdict(opts_list, qdict, &local_err);
 809    if (error_is_set(&local_err)) {
 810        goto exit_err;
 811    }
 812
 813    netdev_add(opts, &local_err);
 814    if (error_is_set(&local_err)) {
 815        qemu_opts_del(opts);
 816        goto exit_err;
 817    }
 818
 819    return 0;
 820
 821exit_err:
 822    qerror_report_err(local_err);
 823    error_free(local_err);
 824    return -1;
 825}
 826
 827void qmp_netdev_del(const char *id, Error **errp)
 828{
 829    NetClientState *nc;
 830    QemuOpts *opts;
 831
 832    nc = qemu_find_netdev(id);
 833    if (!nc) {
 834        error_set(errp, QERR_DEVICE_NOT_FOUND, id);
 835        return;
 836    }
 837
 838    opts = qemu_opts_find(qemu_find_opts_err("netdev", NULL), id);
 839    if (!opts) {
 840        error_setg(errp, "Device '%s' is not a netdev", id);
 841        return;
 842    }
 843
 844    qemu_del_net_client(nc);
 845    qemu_opts_del(opts);
 846}
 847
 848void print_net_client(Monitor *mon, NetClientState *nc)
 849{
 850    monitor_printf(mon, "%s: type=%s,%s\n", nc->name,
 851                   NetClientOptionsKind_lookup[nc->info->type], nc->info_str);
 852}
 853
 854void do_info_network(Monitor *mon)
 855{
 856    NetClientState *nc, *peer;
 857    NetClientOptionsKind type;
 858
 859    net_hub_info(mon);
 860
 861    QTAILQ_FOREACH(nc, &net_clients, next) {
 862        peer = nc->peer;
 863        type = nc->info->type;
 864
 865        /* Skip if already printed in hub info */
 866        if (net_hub_id_for_client(nc, NULL) == 0) {
 867            continue;
 868        }
 869
 870        if (!peer || type == NET_CLIENT_OPTIONS_KIND_NIC) {
 871            print_net_client(mon, nc);
 872        } /* else it's a netdev connected to a NIC, printed with the NIC */
 873        if (peer && type == NET_CLIENT_OPTIONS_KIND_NIC) {
 874            monitor_printf(mon, " \\ ");
 875            print_net_client(mon, peer);
 876        }
 877    }
 878}
 879
 880void qmp_set_link(const char *name, bool up, Error **errp)
 881{
 882    NetClientState *nc = NULL;
 883
 884    QTAILQ_FOREACH(nc, &net_clients, next) {
 885        if (!strcmp(nc->name, name)) {
 886            goto done;
 887        }
 888    }
 889done:
 890    if (!nc) {
 891        error_set(errp, QERR_DEVICE_NOT_FOUND, name);
 892        return;
 893    }
 894
 895    nc->link_down = !up;
 896
 897    if (nc->info->link_status_changed) {
 898        nc->info->link_status_changed(nc);
 899    }
 900
 901    /* Notify peer. Don't update peer link status: this makes it possible to
 902     * disconnect from host network without notifying the guest.
 903     * FIXME: is disconnected link status change operation useful?
 904     *
 905     * Current behaviour is compatible with qemu vlans where there could be
 906     * multiple clients that can still communicate with each other in
 907     * disconnected mode. For now maintain this compatibility. */
 908    if (nc->peer && nc->peer->info->link_status_changed) {
 909        nc->peer->info->link_status_changed(nc->peer);
 910    }
 911}
 912
 913void net_cleanup(void)
 914{
 915    NetClientState *nc, *next_vc;
 916
 917    QTAILQ_FOREACH_SAFE(nc, &net_clients, next, next_vc) {
 918        qemu_del_net_client(nc);
 919    }
 920}
 921
 922void net_check_clients(void)
 923{
 924    NetClientState *nc;
 925    int i;
 926
 927    /* Don't warn about the default network setup that you get if
 928     * no command line -net or -netdev options are specified. There
 929     * are two cases that we would otherwise complain about:
 930     * (1) board doesn't support a NIC but the implicit "-net nic"
 931     * requested one
 932     * (2) CONFIG_SLIRP not set, in which case the implicit "-net nic"
 933     * sets up a nic that isn't connected to anything.
 934     */
 935    if (default_net) {
 936        return;
 937    }
 938
 939    net_hub_check_clients();
 940
 941    QTAILQ_FOREACH(nc, &net_clients, next) {
 942        if (!nc->peer) {
 943            fprintf(stderr, "Warning: %s %s has no peer\n",
 944                    nc->info->type == NET_CLIENT_OPTIONS_KIND_NIC ?
 945                    "nic" : "netdev", nc->name);
 946        }
 947    }
 948
 949    /* Check that all NICs requested via -net nic actually got created.
 950     * NICs created via -device don't need to be checked here because
 951     * they are always instantiated.
 952     */
 953    for (i = 0; i < MAX_NICS; i++) {
 954        NICInfo *nd = &nd_table[i];
 955        if (nd->used && !nd->instantiated) {
 956            fprintf(stderr, "Warning: requested NIC (%s, model %s) "
 957                    "was not created (not supported by this machine?)\n",
 958                    nd->name ? nd->name : "anonymous",
 959                    nd->model ? nd->model : "unspecified");
 960        }
 961    }
 962}
 963
 964static int net_init_client(QemuOpts *opts, void *dummy)
 965{
 966    Error *local_err = NULL;
 967
 968    net_client_init(opts, 0, &local_err);
 969    if (error_is_set(&local_err)) {
 970        qerror_report_err(local_err);
 971        error_free(local_err);
 972        return -1;
 973    }
 974
 975    return 0;
 976}
 977
 978static int net_init_netdev(QemuOpts *opts, void *dummy)
 979{
 980    Error *local_err = NULL;
 981    int ret;
 982
 983    ret = net_client_init(opts, 1, &local_err);
 984    if (error_is_set(&local_err)) {
 985        qerror_report_err(local_err);
 986        error_free(local_err);
 987        return -1;
 988    }
 989
 990    return ret;
 991}
 992
 993int net_init_clients(void)
 994{
 995    QemuOptsList *net = qemu_find_opts("net");
 996
 997    if (default_net) {
 998        /* if no clients, we use a default config */
 999        qemu_opts_set(net, NULL, "type", "nic");
1000#ifdef CONFIG_SLIRP
1001        qemu_opts_set(net, NULL, "type", "user");
1002#endif
1003    }
1004
1005    QTAILQ_INIT(&net_clients);
1006
1007    if (qemu_opts_foreach(qemu_find_opts("netdev"), net_init_netdev, NULL, 1) == -1)
1008        return -1;
1009
1010    if (qemu_opts_foreach(net, net_init_client, NULL, 1) == -1) {
1011        return -1;
1012    }
1013
1014    return 0;
1015}
1016
1017int net_client_parse(QemuOptsList *opts_list, const char *optarg)
1018{
1019#if defined(CONFIG_SLIRP)
1020    int ret;
1021    if (net_slirp_parse_legacy(opts_list, optarg, &ret)) {
1022        return ret;
1023    }
1024#endif
1025
1026    if (!qemu_opts_parse(opts_list, optarg, 1)) {
1027        return -1;
1028    }
1029
1030    default_net = 0;
1031    return 0;
1032}
1033
1034/* From FreeBSD */
1035/* XXX: optimize */
1036unsigned compute_mcast_idx(const uint8_t *ep)
1037{
1038    uint32_t crc;
1039    int carry, i, j;
1040    uint8_t b;
1041
1042    crc = 0xffffffff;
1043    for (i = 0; i < 6; i++) {
1044        b = *ep++;
1045        for (j = 0; j < 8; j++) {
1046            carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01);
1047            crc <<= 1;
1048            b >>= 1;
1049            if (carry) {
1050                crc = ((crc ^ POLYNOMIAL) | carry);
1051            }
1052        }
1053    }
1054    return crc >> 26;
1055}
1056