200
202
memset(n->vlans, 0, MAX_VLAN >> 3);
203
static int peer_has_vnet_hdr(VirtIONet *n)
205
static void peer_test_vnet_hdr(VirtIONet *n)
205
207
if (!n->nic->nc.peer)
208
210
if (n->nic->nc.peer->info->type != NET_CLIENT_OPTIONS_KIND_TAP)
211
213
n->has_vnet_hdr = tap_has_vnet_hdr(n->nic->nc.peer);
216
static int peer_has_vnet_hdr(VirtIONet *n)
213
218
return n->has_vnet_hdr;
223
228
return n->has_ufo;
231
static void virtio_net_set_mrg_rx_bufs(VirtIONet *n, int mergeable_rx_bufs)
233
n->mergeable_rx_bufs = mergeable_rx_bufs;
235
n->guest_hdr_len = n->mergeable_rx_bufs ?
236
sizeof(struct virtio_net_hdr_mrg_rxbuf) : sizeof(struct virtio_net_hdr);
238
if (peer_has_vnet_hdr(n) &&
239
tap_has_vnet_hdr_len(n->nic->nc.peer, n->guest_hdr_len)) {
240
tap_set_vnet_hdr_len(n->nic->nc.peer, n->guest_hdr_len);
241
n->host_hdr_len = n->guest_hdr_len;
226
245
static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features)
228
247
VirtIONet *n = to_virtio_net(vdev);
230
249
features |= (1 << VIRTIO_NET_F_MAC);
232
if (peer_has_vnet_hdr(n)) {
233
tap_using_vnet_hdr(n->nic->nc.peer, 1);
251
if (!peer_has_vnet_hdr(n)) {
235
252
features &= ~(0x1 << VIRTIO_NET_F_CSUM);
236
253
features &= ~(0x1 << VIRTIO_NET_F_HOST_TSO4);
237
254
features &= ~(0x1 << VIRTIO_NET_F_HOST_TSO6);
505
518
static void work_around_broken_dhclient(struct virtio_net_hdr *hdr,
506
const uint8_t *buf, size_t size)
519
uint8_t *buf, size_t size)
508
521
if ((hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && /* missing csum */
509
522
(size > 27 && size < 1500) && /* normal sized MTU */
510
523
(buf[12] == 0x08 && buf[13] == 0x00) && /* ethertype == IPv4 */
511
524
(buf[23] == 17) && /* ip.protocol == UDP */
512
525
(buf[34] == 0 && buf[35] == 67)) { /* udp.srcport == bootps */
526
net_checksum_calculate(buf, size);
527
hdr->flags &= ~VIRTIO_NET_HDR_F_NEEDS_CSUM;
531
static void receive_header(VirtIONet *n, const struct iovec *iov, int iov_cnt,
532
const void *buf, size_t size)
534
if (n->has_vnet_hdr) {
513
535
/* FIXME this cast is evil */
514
net_checksum_calculate((uint8_t *)buf, size);
515
hdr->flags &= ~VIRTIO_NET_HDR_F_NEEDS_CSUM;
519
static int receive_header(VirtIONet *n, struct iovec *iov, int iovcnt,
520
const void *buf, size_t size, size_t hdr_len)
522
struct virtio_net_hdr *hdr = (struct virtio_net_hdr *)iov[0].iov_base;
526
hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
528
if (n->has_vnet_hdr) {
529
memcpy(hdr, buf, sizeof(*hdr));
530
offset = sizeof(*hdr);
531
work_around_broken_dhclient(hdr, buf + offset, size - offset);
534
/* We only ever receive a struct virtio_net_hdr from the tapfd,
535
* but we may be passing along a larger header to the guest.
537
iov[0].iov_base += hdr_len;
538
iov[0].iov_len -= hdr_len;
536
void *wbuf = (void *)buf;
537
work_around_broken_dhclient(wbuf, wbuf + n->host_hdr_len,
538
size - n->host_hdr_len);
539
iov_from_buf(iov, iov_cnt, 0, buf, sizeof(struct virtio_net_hdr));
541
struct virtio_net_hdr hdr = {
543
.gso_type = VIRTIO_NET_HDR_GSO_NONE
545
iov_from_buf(iov, iov_cnt, 0, &hdr, sizeof hdr);
543
549
static int receive_filter(VirtIONet *n, const uint8_t *buf, int size)
596
600
static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t size)
598
602
VirtIONet *n = DO_UPCAST(NICState, nc, nc)->opaque;
599
struct virtio_net_hdr_mrg_rxbuf *mhdr = NULL;
600
size_t guest_hdr_len, offset, i, host_hdr_len;
603
struct iovec mhdr_sg[VIRTQUEUE_MAX_SIZE];
604
struct virtio_net_hdr_mrg_rxbuf mhdr;
605
unsigned mhdr_cnt = 0;
606
size_t offset, i, guest_offset;
602
608
if (!virtio_net_can_receive(&n->nic->nc))
605
611
/* hdr_len refers to the header we supply to the guest */
606
guest_hdr_len = n->mergeable_rx_bufs ?
607
sizeof(struct virtio_net_hdr_mrg_rxbuf) : sizeof(struct virtio_net_hdr);
610
host_hdr_len = n->has_vnet_hdr ? sizeof(struct virtio_net_hdr) : 0;
611
if (!virtio_net_has_buffers(n, size + guest_hdr_len - host_hdr_len))
612
if (!virtio_net_has_buffers(n, size + n->guest_hdr_len - n->host_hdr_len))
614
615
if (!receive_filter(n, buf, size))
630
631
"i %zd mergeable %d offset %zd, size %zd, "
631
632
"guest hdr len %zd, host hdr len %zd guest features 0x%x",
632
633
i, n->mergeable_rx_bufs, offset, size,
633
guest_hdr_len, host_hdr_len, n->vdev.guest_features);
634
n->guest_hdr_len, n->host_hdr_len, n->vdev.guest_features);
642
if (!n->mergeable_rx_bufs && elem.in_sg[0].iov_len != guest_hdr_len) {
643
error_report("virtio-net header not in first element");
647
memcpy(&sg, &elem.in_sg[0], sizeof(sg[0]) * elem.in_num);
650
if (n->mergeable_rx_bufs)
651
mhdr = (struct virtio_net_hdr_mrg_rxbuf *)sg[0].iov_base;
645
if (n->mergeable_rx_bufs) {
646
mhdr_cnt = iov_copy(mhdr_sg, ARRAY_SIZE(mhdr_sg),
648
offsetof(typeof(mhdr), num_buffers),
649
sizeof(mhdr.num_buffers));
653
offset += receive_header(n, sg, elem.in_num,
654
buf + offset, size - offset, guest_hdr_len);
655
total += guest_hdr_len;
652
receive_header(n, sg, elem.in_num, buf, size);
653
offset = n->host_hdr_len;
654
total += n->guest_hdr_len;
655
guest_offset = n->guest_hdr_len;
658
660
/* copy in packet. ugh */
659
len = iov_from_buf(sg, elem.in_num, 0,
661
len = iov_from_buf(sg, elem.in_num, guest_offset,
660
662
buf + offset, size - offset);
669
671
"i %zd mergeable %d offset %zd, size %zd, "
670
672
"guest hdr len %zd, host hdr len %zd",
671
673
i, n->mergeable_rx_bufs,
672
offset, size, guest_hdr_len, host_hdr_len);
674
offset, size, n->guest_hdr_len, n->host_hdr_len);
678
680
virtqueue_fill(n->rx_vq, &elem, total, i++);
682
stw_p(&mhdr->num_buffers, i);
684
stw_p(&mhdr.num_buffers, i);
685
iov_from_buf(mhdr_sg, mhdr_cnt,
687
&mhdr.num_buffers, sizeof mhdr.num_buffers);
685
690
virtqueue_flush(n->rx_vq, i);
695
700
VirtIONet *n = DO_UPCAST(NICState, nc, nc)->opaque;
697
virtqueue_push(n->tx_vq, &n->async_tx.elem, n->async_tx.len);
702
virtqueue_push(n->tx_vq, &n->async_tx.elem, 0);
698
703
virtio_notify(&n->vdev, n->tx_vq);
700
705
n->async_tx.elem.out_num = n->async_tx.len = 0;
722
727
while (virtqueue_pop(vq, &elem)) {
723
ssize_t ret, len = 0;
724
729
unsigned int out_num = elem.out_num;
725
730
struct iovec *out_sg = &elem.out_sg[0];
728
/* hdr_len refers to the header received from the guest */
729
hdr_len = n->mergeable_rx_bufs ?
730
sizeof(struct virtio_net_hdr_mrg_rxbuf) :
731
sizeof(struct virtio_net_hdr);
733
if (out_num < 1 || out_sg->iov_len != hdr_len) {
731
struct iovec sg[VIRTQUEUE_MAX_SIZE];
734
734
error_report("virtio-net header not in first element");
738
/* ignore the header if GSO is not supported */
739
if (!n->has_vnet_hdr) {
743
} else if (n->mergeable_rx_bufs) {
744
/* tapfd expects a struct virtio_net_hdr */
745
hdr_len -= sizeof(struct virtio_net_hdr);
746
out_sg->iov_len -= hdr_len;
739
* If host wants to see the guest header as is, we can
740
* pass it on unchanged. Otherwise, copy just the parts
741
* that host is interested in.
743
assert(n->host_hdr_len <= n->guest_hdr_len);
744
if (n->host_hdr_len != n->guest_hdr_len) {
745
unsigned sg_num = iov_copy(sg, ARRAY_SIZE(sg),
748
sg_num += iov_copy(sg + sg_num, ARRAY_SIZE(sg) - sg_num,
750
n->guest_hdr_len, -1);
755
len = n->guest_hdr_len;
750
757
ret = qemu_sendv_packet_async(&n->nic->nc, out_sg, out_num,
751
758
virtio_net_tx_complete);
761
virtqueue_push(vq, &elem, len);
768
virtqueue_push(vq, &elem, 0);
762
769
virtio_notify(&n->vdev, vq);
764
771
if (++num_packets >= n->tx_burst) {
904
911
qemu_get_buffer(f, n->mac, ETH_ALEN);
905
912
n->tx_waiting = qemu_get_be32(f);
906
n->mergeable_rx_bufs = qemu_get_be32(f);
914
virtio_net_set_mrg_rx_bufs(n, qemu_get_be32(f));
908
916
if (version_id >= 3)
909
917
n->status = qemu_get_be16(f);
925
933
qemu_get_buffer(f, n->mac_table.macs,
926
934
n->mac_table.in_use * ETH_ALEN);
927
935
} else if (n->mac_table.in_use) {
928
qemu_fseek(f, n->mac_table.in_use * ETH_ALEN, SEEK_CUR);
936
uint8_t *buf = g_malloc0(n->mac_table.in_use);
937
qemu_get_buffer(f, buf, n->mac_table.in_use * ETH_ALEN);
929
939
n->mac_table.multi_overflow = n->mac_table.uni_overflow = 1;
930
940
n->mac_table.in_use = 0;
1035
1049
n->status = VIRTIO_NET_S_LINK_UP;
1037
1051
n->nic = qemu_new_nic(&net_virtio_info, conf, object_get_typename(OBJECT(dev)), dev->id, n);
1052
peer_test_vnet_hdr(n);
1053
if (peer_has_vnet_hdr(n)) {
1054
tap_using_vnet_hdr(n->nic->nc.peer, 1);
1055
n->host_hdr_len = sizeof(struct virtio_net_hdr);
1057
n->host_hdr_len = 0;
1039
1060
qemu_format_nic_info_str(&n->nic->nc, conf->macaddr.a);
1041
1062
n->tx_waiting = 0;
1042
1063
n->tx_burst = net->txburst;
1043
n->mergeable_rx_bufs = 0;
1064
virtio_net_set_mrg_rx_bufs(n, 0);
1044
1065
n->promisc = 1; /* for compatibility */
1046
1067
n->mac_table.macs = g_malloc0(MAC_TABLE_ENTRIES * ETH_ALEN);