~ubuntu-branches/ubuntu/trusty/qemu/trusty

« back to all changes in this revision

Viewing changes to hw/net/virtio-net.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2013-10-22 22:47:07 UTC
  • mfrom: (1.8.3) (10.1.42 sid)
  • Revision ID: package-import@ubuntu.com-20131022224707-1lya34fw3k3f24tv
Tags: 1.6.0+dfsg-2ubuntu1
* Merge 1.6.0~rc0+dfsg-2exp from debian experimental.  Remaining changes:
  - debian/control
    * update maintainer
    * remove libiscsi, usb-redir, vde, vnc-jpeg, and libssh2-1-dev
      from build-deps
    * enable rbd
    * add qemu-system and qemu-common B/R to qemu-keymaps
    * add D:udev, R:qemu, R:qemu-common and B:qemu-common to
      qemu-system-common
    * qemu-system-arm, qemu-system-ppc, qemu-system-sparc:
      - add qemu-kvm to Provides
      - add qemu-common, qemu-kvm, kvm to B/R
      - remove openbios-sparc from qemu-system-sparc D
      - drop openbios-ppc and openhackware Depends to Suggests (for now)
    * qemu-system-x86:
      - add qemu-common to Breaks/Replaces.
      - add cpu-checker to Recommends.
    * qemu-user: add B/R:qemu-kvm
    * qemu-kvm:
      - add armhf armel powerpc sparc to Architecture
      - C/R/P: qemu-kvm-spice
    * add qemu-common package
    * drop qemu-slof which is not packaged in ubuntu
  - add qemu-system-common.links for tap ifup/down scripts and OVMF link.
  - qemu-system-x86.links:
    * remove pxe rom links which are in kvm-ipxe
    * add symlink for kvm.1 manpage
  - debian/rules
    * add kvm-spice symlink to qemu-kvm
    * call dh_installmodules for qemu-system-x86
    * update dh_installinit to install upstart script
    * run dh_installman (Closes: #709241) (cherrypicked from 1.5.0+dfsg-2)
  - Add qemu-utils.links for kvm-* symlinks.
  - Add qemu-system-x86.qemu-kvm.upstart and .default
  - Add qemu-system-x86.modprobe to set nesting=1
  - Add qemu-system-common.preinst to add kvm group
  - qemu-system-common.postinst: remove bad group acl if there, then have
    udev relabel /dev/kvm.
  - New linaro patches from qemu-linaro rebasing branch
  - Dropped patches:
    * xen-simplify-xen_enabled.patch
    * sparc-linux-user-fix-missing-symbols-in-.rel-.rela.plt-sections.patch
    * main_loop-do-not-set-nonblocking-if-xen_enabled.patch
    * xen_machine_pv-do-not-create-a-dummy-CPU-in-machine-.patch
    * virtio-rng-fix-crash
  - Kept patches:
    * expose_vms_qemu64cpu.patch - updated
    * linaro arm patches from qemu-linaro rebasing branch
  - New patches:
    * fix-pci-add: change CONFIG variable in ifdef to make sure that
      pci_add is defined.
* Add linaro patches
* Add experimental mach-virt patches for arm virtualization.
* qemu-system-common.install: add debian/tmp/usr/lib to install the
  qemu-bridge-helper

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
#include "hw/virtio/virtio-net.h"
22
22
#include "net/vhost_net.h"
23
23
#include "hw/virtio/virtio-bus.h"
 
24
#include "qapi/qmp/qjson.h"
 
25
#include "monitor/monitor.h"
24
26
 
25
27
#define VIRTIO_NET_VM_VERSION    11
26
28
 
192
194
    virtio_net_set_status(vdev, vdev->status);
193
195
}
194
196
 
 
197
static void rxfilter_notify(NetClientState *nc)
 
198
{
 
199
    QObject *event_data;
 
200
    VirtIONet *n = qemu_get_nic_opaque(nc);
 
201
 
 
202
    if (nc->rxfilter_notify_enabled) {
 
203
        if (n->netclient_name) {
 
204
            event_data = qobject_from_jsonf("{ 'name': %s, 'path': %s }",
 
205
                                    n->netclient_name,
 
206
                                    object_get_canonical_path(OBJECT(n->qdev)));
 
207
        } else {
 
208
            event_data = qobject_from_jsonf("{ 'path': %s }",
 
209
                                    object_get_canonical_path(OBJECT(n->qdev)));
 
210
        }
 
211
        monitor_protocol_event(QEVENT_NIC_RX_FILTER_CHANGED, event_data);
 
212
        qobject_decref(event_data);
 
213
 
 
214
        /* disable event notification to avoid events flooding */
 
215
        nc->rxfilter_notify_enabled = 0;
 
216
    }
 
217
}
 
218
 
 
219
static char *mac_strdup_printf(const uint8_t *mac)
 
220
{
 
221
    return g_strdup_printf("%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", mac[0],
 
222
                            mac[1], mac[2], mac[3], mac[4], mac[5]);
 
223
}
 
224
 
 
225
static RxFilterInfo *virtio_net_query_rxfilter(NetClientState *nc)
 
226
{
 
227
    VirtIONet *n = qemu_get_nic_opaque(nc);
 
228
    RxFilterInfo *info;
 
229
    strList *str_list, *entry;
 
230
    intList *int_list, *int_entry;
 
231
    int i, j;
 
232
 
 
233
    info = g_malloc0(sizeof(*info));
 
234
    info->name = g_strdup(nc->name);
 
235
    info->promiscuous = n->promisc;
 
236
 
 
237
    if (n->nouni) {
 
238
        info->unicast = RX_STATE_NONE;
 
239
    } else if (n->alluni) {
 
240
        info->unicast = RX_STATE_ALL;
 
241
    } else {
 
242
        info->unicast = RX_STATE_NORMAL;
 
243
    }
 
244
 
 
245
    if (n->nomulti) {
 
246
        info->multicast = RX_STATE_NONE;
 
247
    } else if (n->allmulti) {
 
248
        info->multicast = RX_STATE_ALL;
 
249
    } else {
 
250
        info->multicast = RX_STATE_NORMAL;
 
251
    }
 
252
 
 
253
    info->broadcast_allowed = n->nobcast;
 
254
    info->multicast_overflow = n->mac_table.multi_overflow;
 
255
    info->unicast_overflow = n->mac_table.uni_overflow;
 
256
 
 
257
    info->main_mac = mac_strdup_printf(n->mac);
 
258
 
 
259
    str_list = NULL;
 
260
    for (i = 0; i < n->mac_table.first_multi; i++) {
 
261
        entry = g_malloc0(sizeof(*entry));
 
262
        entry->value = mac_strdup_printf(n->mac_table.macs + i * ETH_ALEN);
 
263
        entry->next = str_list;
 
264
        str_list = entry;
 
265
    }
 
266
    info->unicast_table = str_list;
 
267
 
 
268
    str_list = NULL;
 
269
    for (i = n->mac_table.first_multi; i < n->mac_table.in_use; i++) {
 
270
        entry = g_malloc0(sizeof(*entry));
 
271
        entry->value = mac_strdup_printf(n->mac_table.macs + i * ETH_ALEN);
 
272
        entry->next = str_list;
 
273
        str_list = entry;
 
274
    }
 
275
    info->multicast_table = str_list;
 
276
 
 
277
    int_list = NULL;
 
278
    for (i = 0; i < MAX_VLAN >> 5; i++) {
 
279
        for (j = 0; n->vlans[i] && j < 0x1f; j++) {
 
280
            if (n->vlans[i] & (1U << j)) {
 
281
                int_entry = g_malloc0(sizeof(*int_entry));
 
282
                int_entry->value = (i << 5) + j;
 
283
                int_entry->next = int_list;
 
284
                int_list = int_entry;
 
285
            }
 
286
        }
 
287
    }
 
288
    info->vlan_table = int_list;
 
289
 
 
290
    /* enable event notification after query */
 
291
    nc->rxfilter_notify_enabled = 1;
 
292
 
 
293
    return info;
 
294
}
 
295
 
195
296
static void virtio_net_reset(VirtIODevice *vdev)
196
297
{
197
298
    VirtIONet *n = VIRTIO_NET(vdev);
359
460
    return features;
360
461
}
361
462
 
 
463
static void virtio_net_apply_guest_offloads(VirtIONet *n)
 
464
{
 
465
    tap_set_offload(qemu_get_subqueue(n->nic, 0)->peer,
 
466
            !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_CSUM)),
 
467
            !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO4)),
 
468
            !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_TSO6)),
 
469
            !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_ECN)),
 
470
            !!(n->curr_guest_offloads & (1ULL << VIRTIO_NET_F_GUEST_UFO)));
 
471
}
 
472
 
 
473
static uint64_t virtio_net_guest_offloads_by_features(uint32_t features)
 
474
{
 
475
    static const uint64_t guest_offloads_mask =
 
476
        (1ULL << VIRTIO_NET_F_GUEST_CSUM) |
 
477
        (1ULL << VIRTIO_NET_F_GUEST_TSO4) |
 
478
        (1ULL << VIRTIO_NET_F_GUEST_TSO6) |
 
479
        (1ULL << VIRTIO_NET_F_GUEST_ECN)  |
 
480
        (1ULL << VIRTIO_NET_F_GUEST_UFO);
 
481
 
 
482
    return guest_offloads_mask & features;
 
483
}
 
484
 
 
485
static inline uint64_t virtio_net_supported_guest_offloads(VirtIONet *n)
 
486
{
 
487
    VirtIODevice *vdev = VIRTIO_DEVICE(n);
 
488
    return virtio_net_guest_offloads_by_features(vdev->guest_features);
 
489
}
 
490
 
362
491
static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
363
492
{
364
493
    VirtIONet *n = VIRTIO_NET(vdev);
369
498
    virtio_net_set_mrg_rx_bufs(n, !!(features & (1 << VIRTIO_NET_F_MRG_RXBUF)));
370
499
 
371
500
    if (n->has_vnet_hdr) {
372
 
        tap_set_offload(qemu_get_subqueue(n->nic, 0)->peer,
373
 
                        (features >> VIRTIO_NET_F_GUEST_CSUM) & 1,
374
 
                        (features >> VIRTIO_NET_F_GUEST_TSO4) & 1,
375
 
                        (features >> VIRTIO_NET_F_GUEST_TSO6) & 1,
376
 
                        (features >> VIRTIO_NET_F_GUEST_ECN)  & 1,
377
 
                        (features >> VIRTIO_NET_F_GUEST_UFO)  & 1);
 
501
        n->curr_guest_offloads =
 
502
            virtio_net_guest_offloads_by_features(features);
 
503
        virtio_net_apply_guest_offloads(n);
378
504
    }
379
505
 
380
506
    for (i = 0;  i < n->max_queues; i++) {
395
521
{
396
522
    uint8_t on;
397
523
    size_t s;
 
524
    NetClientState *nc = qemu_get_queue(n->nic);
398
525
 
399
526
    s = iov_to_buf(iov, iov_cnt, 0, &on, sizeof(on));
400
527
    if (s != sizeof(on)) {
417
544
        return VIRTIO_NET_ERR;
418
545
    }
419
546
 
 
547
    rxfilter_notify(nc);
 
548
 
420
549
    return VIRTIO_NET_OK;
421
550
}
422
551
 
 
552
static int virtio_net_handle_offloads(VirtIONet *n, uint8_t cmd,
 
553
                                     struct iovec *iov, unsigned int iov_cnt)
 
554
{
 
555
    VirtIODevice *vdev = VIRTIO_DEVICE(n);
 
556
    uint64_t offloads;
 
557
    size_t s;
 
558
 
 
559
    if (!((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features)) {
 
560
        return VIRTIO_NET_ERR;
 
561
    }
 
562
 
 
563
    s = iov_to_buf(iov, iov_cnt, 0, &offloads, sizeof(offloads));
 
564
    if (s != sizeof(offloads)) {
 
565
        return VIRTIO_NET_ERR;
 
566
    }
 
567
 
 
568
    if (cmd == VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET) {
 
569
        uint64_t supported_offloads;
 
570
 
 
571
        if (!n->has_vnet_hdr) {
 
572
            return VIRTIO_NET_ERR;
 
573
        }
 
574
 
 
575
        supported_offloads = virtio_net_supported_guest_offloads(n);
 
576
        if (offloads & ~supported_offloads) {
 
577
            return VIRTIO_NET_ERR;
 
578
        }
 
579
 
 
580
        n->curr_guest_offloads = offloads;
 
581
        virtio_net_apply_guest_offloads(n);
 
582
 
 
583
        return VIRTIO_NET_OK;
 
584
    } else {
 
585
        return VIRTIO_NET_ERR;
 
586
    }
 
587
}
 
588
 
423
589
static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd,
424
590
                                 struct iovec *iov, unsigned int iov_cnt)
425
591
{
426
592
    struct virtio_net_ctrl_mac mac_data;
427
593
    size_t s;
 
594
    NetClientState *nc = qemu_get_queue(n->nic);
428
595
 
429
596
    if (cmd == VIRTIO_NET_CTRL_MAC_ADDR_SET) {
430
597
        if (iov_size(iov, iov_cnt) != sizeof(n->mac)) {
433
600
        s = iov_to_buf(iov, iov_cnt, 0, &n->mac, sizeof(n->mac));
434
601
        assert(s == sizeof(n->mac));
435
602
        qemu_format_nic_info_str(qemu_get_queue(n->nic), n->mac);
 
603
        rxfilter_notify(nc);
 
604
 
436
605
        return VIRTIO_NET_OK;
437
606
    }
438
607
 
450
619
                   sizeof(mac_data.entries));
451
620
    mac_data.entries = ldl_p(&mac_data.entries);
452
621
    if (s != sizeof(mac_data.entries)) {
453
 
        return VIRTIO_NET_ERR;
 
622
        goto error;
454
623
    }
455
624
    iov_discard_front(&iov, &iov_cnt, s);
456
625
 
457
626
    if (mac_data.entries * ETH_ALEN > iov_size(iov, iov_cnt)) {
458
 
        return VIRTIO_NET_ERR;
 
627
        goto error;
459
628
    }
460
629
 
461
630
    if (mac_data.entries <= MAC_TABLE_ENTRIES) {
462
631
        s = iov_to_buf(iov, iov_cnt, 0, n->mac_table.macs,
463
632
                       mac_data.entries * ETH_ALEN);
464
633
        if (s != mac_data.entries * ETH_ALEN) {
465
 
            return VIRTIO_NET_ERR;
 
634
            goto error;
466
635
        }
467
636
        n->mac_table.in_use += mac_data.entries;
468
637
    } else {
477
646
                   sizeof(mac_data.entries));
478
647
    mac_data.entries = ldl_p(&mac_data.entries);
479
648
    if (s != sizeof(mac_data.entries)) {
480
 
        return VIRTIO_NET_ERR;
 
649
        goto error;
481
650
    }
482
651
 
483
652
    iov_discard_front(&iov, &iov_cnt, s);
484
653
 
485
654
    if (mac_data.entries * ETH_ALEN != iov_size(iov, iov_cnt)) {
486
 
        return VIRTIO_NET_ERR;
 
655
        goto error;
487
656
    }
488
657
 
489
658
    if (n->mac_table.in_use + mac_data.entries <= MAC_TABLE_ENTRIES) {
490
659
        s = iov_to_buf(iov, iov_cnt, 0, n->mac_table.macs,
491
660
                       mac_data.entries * ETH_ALEN);
492
661
        if (s != mac_data.entries * ETH_ALEN) {
493
 
            return VIRTIO_NET_ERR;
 
662
            goto error;
494
663
        }
495
664
        n->mac_table.in_use += mac_data.entries;
496
665
    } else {
497
666
        n->mac_table.multi_overflow = 1;
498
667
    }
499
668
 
 
669
    rxfilter_notify(nc);
 
670
 
500
671
    return VIRTIO_NET_OK;
 
672
 
 
673
error:
 
674
    rxfilter_notify(nc);
 
675
    return VIRTIO_NET_ERR;
501
676
}
502
677
 
503
678
static int virtio_net_handle_vlan_table(VirtIONet *n, uint8_t cmd,
505
680
{
506
681
    uint16_t vid;
507
682
    size_t s;
 
683
    NetClientState *nc = qemu_get_queue(n->nic);
508
684
 
509
685
    s = iov_to_buf(iov, iov_cnt, 0, &vid, sizeof(vid));
510
686
    vid = lduw_p(&vid);
522
698
    else
523
699
        return VIRTIO_NET_ERR;
524
700
 
 
701
    rxfilter_notify(nc);
 
702
 
525
703
    return VIRTIO_NET_OK;
526
704
}
527
705
 
590
768
            status = virtio_net_handle_vlan_table(n, ctrl.cmd, iov, iov_cnt);
591
769
        } else if (ctrl.class == VIRTIO_NET_CTRL_MQ) {
592
770
            status = virtio_net_handle_mq(n, ctrl.cmd, iov, iov_cnt);
 
771
        } else if (ctrl.class == VIRTIO_NET_CTRL_GUEST_OFFLOADS) {
 
772
            status = virtio_net_handle_offloads(n, ctrl.cmd, iov, iov_cnt);
593
773
        }
594
774
 
595
775
        s = iov_from_buf(elem.in_sg, elem.in_num, 0, &status, sizeof(status));
1110
1290
            qemu_put_be32(f, n->vqs[i].tx_waiting);
1111
1291
        }
1112
1292
    }
 
1293
 
 
1294
    if ((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features) {
 
1295
        qemu_put_be64(f, n->curr_guest_offloads);
 
1296
    }
1113
1297
}
1114
1298
 
1115
1299
static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
1167
1351
            error_report("virtio-net: saved image requires vnet_hdr=on");
1168
1352
            return -1;
1169
1353
        }
1170
 
 
1171
 
        if (n->has_vnet_hdr) {
1172
 
            tap_set_offload(qemu_get_queue(n->nic)->peer,
1173
 
                    (vdev->guest_features >> VIRTIO_NET_F_GUEST_CSUM) & 1,
1174
 
                    (vdev->guest_features >> VIRTIO_NET_F_GUEST_TSO4) & 1,
1175
 
                    (vdev->guest_features >> VIRTIO_NET_F_GUEST_TSO6) & 1,
1176
 
                    (vdev->guest_features >> VIRTIO_NET_F_GUEST_ECN)  & 1,
1177
 
                    (vdev->guest_features >> VIRTIO_NET_F_GUEST_UFO)  & 1);
1178
 
        }
1179
1354
    }
1180
1355
 
1181
1356
    if (version_id >= 9) {
1209
1384
        }
1210
1385
    }
1211
1386
 
 
1387
    if ((1 << VIRTIO_NET_F_CTRL_GUEST_OFFLOADS) & vdev->guest_features) {
 
1388
        n->curr_guest_offloads = qemu_get_be64(f);
 
1389
    } else {
 
1390
        n->curr_guest_offloads = virtio_net_supported_guest_offloads(n);
 
1391
    }
 
1392
 
 
1393
    if (peer_has_vnet_hdr(n)) {
 
1394
        virtio_net_apply_guest_offloads(n);
 
1395
    }
 
1396
 
1212
1397
    virtio_net_set_queues(n);
1213
1398
 
1214
1399
    /* Find the first multicast entry in the saved MAC filter */
1243
1428
    .receive = virtio_net_receive,
1244
1429
        .cleanup = virtio_net_cleanup,
1245
1430
    .link_status_changed = virtio_net_set_link_status,
 
1431
    .query_rx_filter = virtio_net_query_rxfilter,
1246
1432
};
1247
1433
 
1248
1434
static bool virtio_net_guest_notifier_pending(VirtIODevice *vdev, int idx)
1304
1490
 
1305
1491
    DeviceState *qdev = DEVICE(vdev);
1306
1492
    VirtIONet *n = VIRTIO_NET(vdev);
 
1493
    NetClientState *nc;
1307
1494
 
1308
1495
    virtio_init(VIRTIO_DEVICE(n), "virtio-net", VIRTIO_ID_NET,
1309
1496
                                  n->config_size);
1370
1557
 
1371
1558
    n->vlans = g_malloc0(MAX_VLAN >> 3);
1372
1559
 
 
1560
    nc = qemu_get_queue(n->nic);
 
1561
    nc->rxfilter_notify_enabled = 1;
 
1562
 
1373
1563
    n->qdev = qdev;
1374
1564
    register_savevm(qdev, "virtio-net", -1, VIRTIO_NET_VM_VERSION,
1375
1565
                    virtio_net_save, virtio_net_load, n);
1448
1638
    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
1449
1639
    dc->exit = virtio_net_device_exit;
1450
1640
    dc->props = virtio_net_properties;
 
1641
    set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
1451
1642
    vdc->init = virtio_net_device_init;
1452
1643
    vdc->get_config = virtio_net_get_config;
1453
1644
    vdc->set_config = virtio_net_set_config;