Message ID | 20140613112420.22108.4861.stgit@bahia.local |
---|---|
State | New |
Headers | show |
On 13.06.14 13:24, Greg Kurz wrote: > From: Rusty Russell <rusty@rustcorp.com.au> > > Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> > Reviewed-by: Anthony Liguori <aliguori@us.ibm.com> > [ pass VirtIODevice * to memory accessors, > TCP checksums fix by Cédric Le Goater, > Greg Kurz <gkurz@linux.vnet.ibm.com> ] > Cc: Cédric Le Goater <clg@fr.ibm.com> > Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com> > --- > hw/net/virtio-net.c | 34 +++++++++++++++++++++++++++------- > 1 file changed, 27 insertions(+), 7 deletions(-) > > diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c > index 58e7b73..fb17919 100644 > --- a/hw/net/virtio-net.c > +++ b/hw/net/virtio-net.c > @@ -23,6 +23,7 @@ > #include "hw/virtio/virtio-bus.h" > #include "qapi/qmp/qjson.h" > #include "monitor/monitor.h" > +#include "hw/virtio/virtio-access.h" > > #define VIRTIO_NET_VM_VERSION 11 > > @@ -72,8 +73,8 @@ static void virtio_net_get_config(VirtIODevice *vdev, uint8_t *config) > VirtIONet *n = VIRTIO_NET(vdev); > struct virtio_net_config netcfg; > > - stw_p(&netcfg.status, n->status); > - stw_p(&netcfg.max_virtqueue_pairs, n->max_queues); > + virtio_stw_p(vdev, &netcfg.status, n->status); > + virtio_stw_p(vdev, &netcfg.max_virtqueue_pairs, n->max_queues); > memcpy(netcfg.mac, n->mac, ETH_ALEN); > memcpy(config, &netcfg, n->config_size); > } > @@ -611,6 +612,7 @@ static int virtio_net_handle_offloads(VirtIONet *n, uint8_t cmd, > static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd, > struct iovec *iov, unsigned int iov_cnt) > { > + VirtIODevice *vdev = VIRTIO_DEVICE(n); > struct virtio_net_ctrl_mac mac_data; > size_t s; > NetClientState *nc = qemu_get_queue(n->nic); > @@ -639,7 +641,7 @@ static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd, > > s = iov_to_buf(iov, iov_cnt, 0, &mac_data.entries, > sizeof(mac_data.entries)); > - mac_data.entries = ldl_p(&mac_data.entries); > + mac_data.entries = virtio_ldl_p(vdev, &mac_data.entries); > if (s != sizeof(mac_data.entries)) { > goto error; > } > @@ -666,7 +668,7 @@ static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd, > > s = iov_to_buf(iov, iov_cnt, 0, &mac_data.entries, > sizeof(mac_data.entries)); > - mac_data.entries = ldl_p(&mac_data.entries); > + mac_data.entries = virtio_ldl_p(vdev, &mac_data.entries); > if (s != sizeof(mac_data.entries)) { > goto error; > } > @@ -706,12 +708,13 @@ error: > static int virtio_net_handle_vlan_table(VirtIONet *n, uint8_t cmd, > struct iovec *iov, unsigned int iov_cnt) > { > + VirtIODevice *vdev = VIRTIO_DEVICE(n); > uint16_t vid; > size_t s; > NetClientState *nc = qemu_get_queue(n->nic); > > s = iov_to_buf(iov, iov_cnt, 0, &vid, sizeof(vid)); > - vid = lduw_p(&vid); > + vid = virtio_lduw_p(vdev, &vid); > if (s != sizeof(vid)) { > return VIRTIO_NET_ERR; > } > @@ -748,7 +751,7 @@ static int virtio_net_handle_mq(VirtIONet *n, uint8_t cmd, > return VIRTIO_NET_ERR; > } > > - queues = lduw_p(&mq.virtqueue_pairs); > + queues = virtio_lduw_p(vdev, &mq.virtqueue_pairs); > > if (queues < VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN || > queues > VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX || > @@ -863,6 +866,14 @@ static int virtio_net_has_buffers(VirtIONetQueue *q, int bufsize) > return 1; > } > > +static void virtio_net_hdr_swap(VirtIODevice *vdev, struct virtio_net_hdr *hdr) > +{ > + virtio_tswap16s(vdev, &hdr->hdr_len); > + virtio_tswap16s(vdev, &hdr->gso_size); > + virtio_tswap16s(vdev, &hdr->csum_start); > + virtio_tswap16s(vdev, &hdr->csum_offset); > +} > + > /* dhclient uses AF_PACKET but doesn't pass auxdata to the kernel so > * it never finds out that the packets don't have valid checksums. This > * causes dhclient to get upset. Fedora's carried a patch for ages to > @@ -898,6 +909,7 @@ static void receive_header(VirtIONet *n, const struct iovec *iov, int iov_cnt, > void *wbuf = (void *)buf; > work_around_broken_dhclient(wbuf, wbuf + n->host_hdr_len, > size - n->host_hdr_len); > + virtio_net_hdr_swap(VIRTIO_DEVICE(n), wbuf); > iov_from_buf(iov, iov_cnt, 0, buf, sizeof(struct virtio_net_hdr)); > } else { > struct virtio_net_hdr hdr = { > @@ -1047,7 +1059,7 @@ static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t > } > > if (mhdr_cnt) { > - stw_p(&mhdr.num_buffers, i); > + virtio_stw_p(vdev, &mhdr.num_buffers, i); > iov_from_buf(mhdr_sg, mhdr_cnt, > 0, > &mhdr.num_buffers, sizeof mhdr.num_buffers); > @@ -1106,6 +1118,14 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q) > exit(1); > } > > + if (n->has_vnet_hdr) { > + if (out_sg[0].iov_len < n->guest_hdr_len) { > + error_report("virtio-net header incorrect"); > + exit(1); > + } > + virtio_net_hdr_swap(vdev, (void *) out_sg[0].iov_base); Where does this come from? If you're doing twap() wouldn't that have been broken before too? Alex
On 06/13/2014 01:52 PM, Alexander Graf wrote: > > On 13.06.14 13:24, Greg Kurz wrote: >> From: Rusty Russell <rusty@rustcorp.com.au> >> >> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> >> Reviewed-by: Anthony Liguori <aliguori@us.ibm.com> >> [ pass VirtIODevice * to memory accessors, >> TCP checksums fix by Cédric Le Goater, >> Greg Kurz <gkurz@linux.vnet.ibm.com> ] >> Cc: Cédric Le Goater <clg@fr.ibm.com> >> Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com> >> --- >> hw/net/virtio-net.c | 34 +++++++++++++++++++++++++++------- >> 1 file changed, 27 insertions(+), 7 deletions(-) >> >> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c >> index 58e7b73..fb17919 100644 >> --- a/hw/net/virtio-net.c >> +++ b/hw/net/virtio-net.c >> @@ -23,6 +23,7 @@ >> #include "hw/virtio/virtio-bus.h" >> #include "qapi/qmp/qjson.h" >> #include "monitor/monitor.h" >> +#include "hw/virtio/virtio-access.h" >> #define VIRTIO_NET_VM_VERSION 11 >> @@ -72,8 +73,8 @@ static void virtio_net_get_config(VirtIODevice *vdev, uint8_t *config) >> VirtIONet *n = VIRTIO_NET(vdev); >> struct virtio_net_config netcfg; >> - stw_p(&netcfg.status, n->status); >> - stw_p(&netcfg.max_virtqueue_pairs, n->max_queues); >> + virtio_stw_p(vdev, &netcfg.status, n->status); >> + virtio_stw_p(vdev, &netcfg.max_virtqueue_pairs, n->max_queues); >> memcpy(netcfg.mac, n->mac, ETH_ALEN); >> memcpy(config, &netcfg, n->config_size); >> } >> @@ -611,6 +612,7 @@ static int virtio_net_handle_offloads(VirtIONet *n, uint8_t cmd, >> static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd, >> struct iovec *iov, unsigned int iov_cnt) >> { >> + VirtIODevice *vdev = VIRTIO_DEVICE(n); >> struct virtio_net_ctrl_mac mac_data; >> size_t s; >> NetClientState *nc = qemu_get_queue(n->nic); >> @@ -639,7 +641,7 @@ static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd, >> s = iov_to_buf(iov, iov_cnt, 0, &mac_data.entries, >> sizeof(mac_data.entries)); >> - mac_data.entries = ldl_p(&mac_data.entries); >> + mac_data.entries = virtio_ldl_p(vdev, &mac_data.entries); >> if (s != sizeof(mac_data.entries)) { >> goto error; >> } >> @@ -666,7 +668,7 @@ static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd, >> s = iov_to_buf(iov, iov_cnt, 0, &mac_data.entries, >> sizeof(mac_data.entries)); >> - mac_data.entries = ldl_p(&mac_data.entries); >> + mac_data.entries = virtio_ldl_p(vdev, &mac_data.entries); >> if (s != sizeof(mac_data.entries)) { >> goto error; >> } >> @@ -706,12 +708,13 @@ error: >> static int virtio_net_handle_vlan_table(VirtIONet *n, uint8_t cmd, >> struct iovec *iov, unsigned int iov_cnt) >> { >> + VirtIODevice *vdev = VIRTIO_DEVICE(n); >> uint16_t vid; >> size_t s; >> NetClientState *nc = qemu_get_queue(n->nic); >> s = iov_to_buf(iov, iov_cnt, 0, &vid, sizeof(vid)); >> - vid = lduw_p(&vid); >> + vid = virtio_lduw_p(vdev, &vid); >> if (s != sizeof(vid)) { >> return VIRTIO_NET_ERR; >> } >> @@ -748,7 +751,7 @@ static int virtio_net_handle_mq(VirtIONet *n, uint8_t cmd, >> return VIRTIO_NET_ERR; >> } >> - queues = lduw_p(&mq.virtqueue_pairs); >> + queues = virtio_lduw_p(vdev, &mq.virtqueue_pairs); >> if (queues < VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN || >> queues > VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX || >> @@ -863,6 +866,14 @@ static int virtio_net_has_buffers(VirtIONetQueue *q, int bufsize) >> return 1; >> } >> +static void virtio_net_hdr_swap(VirtIODevice *vdev, struct virtio_net_hdr *hdr) >> +{ >> + virtio_tswap16s(vdev, &hdr->hdr_len); >> + virtio_tswap16s(vdev, &hdr->gso_size); >> + virtio_tswap16s(vdev, &hdr->csum_start); >> + virtio_tswap16s(vdev, &hdr->csum_offset); >> +} >> + >> /* dhclient uses AF_PACKET but doesn't pass auxdata to the kernel so >> * it never finds out that the packets don't have valid checksums. This >> * causes dhclient to get upset. Fedora's carried a patch for ages to >> @@ -898,6 +909,7 @@ static void receive_header(VirtIONet *n, const struct iovec *iov, int iov_cnt, >> void *wbuf = (void *)buf; >> work_around_broken_dhclient(wbuf, wbuf + n->host_hdr_len, >> size - n->host_hdr_len); >> + virtio_net_hdr_swap(VIRTIO_DEVICE(n), wbuf); >> iov_from_buf(iov, iov_cnt, 0, buf, sizeof(struct virtio_net_hdr)); >> } else { >> struct virtio_net_hdr hdr = { >> @@ -1047,7 +1059,7 @@ static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t >> } >> if (mhdr_cnt) { >> - stw_p(&mhdr.num_buffers, i); >> + virtio_stw_p(vdev, &mhdr.num_buffers, i); >> iov_from_buf(mhdr_sg, mhdr_cnt, >> 0, >> &mhdr.num_buffers, sizeof mhdr.num_buffers); >> @@ -1106,6 +1118,14 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q) >> exit(1); >> } >> + if (n->has_vnet_hdr) { >> + if (out_sg[0].iov_len < n->guest_hdr_len) { >> + error_report("virtio-net header incorrect"); >> + exit(1); >> + } >> + virtio_net_hdr_swap(vdev, (void *) out_sg[0].iov_base); > > Where does this come from? If you're doing twap() wouldn't that have been broken before too? That's a (possible) fix for virtio-net when vhost=off. It should probably be in another patch. C.
On Fri, 13 Jun 2014 14:24:47 +0200 Cedric Le Goater <clg@fr.ibm.com> wrote: > On 06/13/2014 01:52 PM, Alexander Graf wrote: > > > > On 13.06.14 13:24, Greg Kurz wrote: > >> From: Rusty Russell <rusty@rustcorp.com.au> > >> > >> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> > >> Reviewed-by: Anthony Liguori <aliguori@us.ibm.com> > >> [ pass VirtIODevice * to memory accessors, > >> TCP checksums fix by Cédric Le Goater, > >> Greg Kurz <gkurz@linux.vnet.ibm.com> ] > >> Cc: Cédric Le Goater <clg@fr.ibm.com> > >> Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com> > >> --- > >> hw/net/virtio-net.c | 34 +++++++++++++++++++++++++++------- > >> 1 file changed, 27 insertions(+), 7 deletions(-) > >> > >> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c > >> index 58e7b73..fb17919 100644 > >> --- a/hw/net/virtio-net.c > >> +++ b/hw/net/virtio-net.c > >> @@ -23,6 +23,7 @@ > >> #include "hw/virtio/virtio-bus.h" > >> #include "qapi/qmp/qjson.h" > >> #include "monitor/monitor.h" > >> +#include "hw/virtio/virtio-access.h" > >> #define VIRTIO_NET_VM_VERSION 11 > >> @@ -72,8 +73,8 @@ static void virtio_net_get_config(VirtIODevice *vdev, uint8_t *config) > >> VirtIONet *n = VIRTIO_NET(vdev); > >> struct virtio_net_config netcfg; > >> - stw_p(&netcfg.status, n->status); > >> - stw_p(&netcfg.max_virtqueue_pairs, n->max_queues); > >> + virtio_stw_p(vdev, &netcfg.status, n->status); > >> + virtio_stw_p(vdev, &netcfg.max_virtqueue_pairs, n->max_queues); > >> memcpy(netcfg.mac, n->mac, ETH_ALEN); > >> memcpy(config, &netcfg, n->config_size); > >> } > >> @@ -611,6 +612,7 @@ static int virtio_net_handle_offloads(VirtIONet *n, uint8_t cmd, > >> static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd, > >> struct iovec *iov, unsigned int iov_cnt) > >> { > >> + VirtIODevice *vdev = VIRTIO_DEVICE(n); > >> struct virtio_net_ctrl_mac mac_data; > >> size_t s; > >> NetClientState *nc = qemu_get_queue(n->nic); > >> @@ -639,7 +641,7 @@ static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd, > >> s = iov_to_buf(iov, iov_cnt, 0, &mac_data.entries, > >> sizeof(mac_data.entries)); > >> - mac_data.entries = ldl_p(&mac_data.entries); > >> + mac_data.entries = virtio_ldl_p(vdev, &mac_data.entries); > >> if (s != sizeof(mac_data.entries)) { > >> goto error; > >> } > >> @@ -666,7 +668,7 @@ static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd, > >> s = iov_to_buf(iov, iov_cnt, 0, &mac_data.entries, > >> sizeof(mac_data.entries)); > >> - mac_data.entries = ldl_p(&mac_data.entries); > >> + mac_data.entries = virtio_ldl_p(vdev, &mac_data.entries); > >> if (s != sizeof(mac_data.entries)) { > >> goto error; > >> } > >> @@ -706,12 +708,13 @@ error: > >> static int virtio_net_handle_vlan_table(VirtIONet *n, uint8_t cmd, > >> struct iovec *iov, unsigned int iov_cnt) > >> { > >> + VirtIODevice *vdev = VIRTIO_DEVICE(n); > >> uint16_t vid; > >> size_t s; > >> NetClientState *nc = qemu_get_queue(n->nic); > >> s = iov_to_buf(iov, iov_cnt, 0, &vid, sizeof(vid)); > >> - vid = lduw_p(&vid); > >> + vid = virtio_lduw_p(vdev, &vid); > >> if (s != sizeof(vid)) { > >> return VIRTIO_NET_ERR; > >> } > >> @@ -748,7 +751,7 @@ static int virtio_net_handle_mq(VirtIONet *n, uint8_t cmd, > >> return VIRTIO_NET_ERR; > >> } > >> - queues = lduw_p(&mq.virtqueue_pairs); > >> + queues = virtio_lduw_p(vdev, &mq.virtqueue_pairs); > >> if (queues < VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN || > >> queues > VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX || > >> @@ -863,6 +866,14 @@ static int virtio_net_has_buffers(VirtIONetQueue *q, int bufsize) > >> return 1; > >> } > >> +static void virtio_net_hdr_swap(VirtIODevice *vdev, struct virtio_net_hdr *hdr) > >> +{ > >> + virtio_tswap16s(vdev, &hdr->hdr_len); > >> + virtio_tswap16s(vdev, &hdr->gso_size); > >> + virtio_tswap16s(vdev, &hdr->csum_start); > >> + virtio_tswap16s(vdev, &hdr->csum_offset); > >> +} > >> + > >> /* dhclient uses AF_PACKET but doesn't pass auxdata to the kernel so > >> * it never finds out that the packets don't have valid checksums. This > >> * causes dhclient to get upset. Fedora's carried a patch for ages to > >> @@ -898,6 +909,7 @@ static void receive_header(VirtIONet *n, const struct iovec *iov, int iov_cnt, > >> void *wbuf = (void *)buf; > >> work_around_broken_dhclient(wbuf, wbuf + n->host_hdr_len, > >> size - n->host_hdr_len); > >> + virtio_net_hdr_swap(VIRTIO_DEVICE(n), wbuf); > >> iov_from_buf(iov, iov_cnt, 0, buf, sizeof(struct virtio_net_hdr)); > >> } else { > >> struct virtio_net_hdr hdr = { > >> @@ -1047,7 +1059,7 @@ static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t > >> } > >> if (mhdr_cnt) { > >> - stw_p(&mhdr.num_buffers, i); > >> + virtio_stw_p(vdev, &mhdr.num_buffers, i); > >> iov_from_buf(mhdr_sg, mhdr_cnt, > >> 0, > >> &mhdr.num_buffers, sizeof mhdr.num_buffers); > >> @@ -1106,6 +1118,14 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q) > >> exit(1); > >> } > >> + if (n->has_vnet_hdr) { > >> + if (out_sg[0].iov_len < n->guest_hdr_len) { > >> + error_report("virtio-net header incorrect"); > >> + exit(1); > >> + } > >> + virtio_net_hdr_swap(vdev, (void *) out_sg[0].iov_base); > > > > Where does this come from? If you're doing twap() wouldn't that have been broken before too? > > That's a (possible) fix for virtio-net when vhost=off. It should probably > be in another patch. > > C. > Yeah you are right, this is a fix for a different issue. I'll simply drop these bits for now, and send a standalone patch later.
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 58e7b73..fb17919 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -23,6 +23,7 @@ #include "hw/virtio/virtio-bus.h" #include "qapi/qmp/qjson.h" #include "monitor/monitor.h" +#include "hw/virtio/virtio-access.h" #define VIRTIO_NET_VM_VERSION 11 @@ -72,8 +73,8 @@ static void virtio_net_get_config(VirtIODevice *vdev, uint8_t *config) VirtIONet *n = VIRTIO_NET(vdev); struct virtio_net_config netcfg; - stw_p(&netcfg.status, n->status); - stw_p(&netcfg.max_virtqueue_pairs, n->max_queues); + virtio_stw_p(vdev, &netcfg.status, n->status); + virtio_stw_p(vdev, &netcfg.max_virtqueue_pairs, n->max_queues); memcpy(netcfg.mac, n->mac, ETH_ALEN); memcpy(config, &netcfg, n->config_size); } @@ -611,6 +612,7 @@ static int virtio_net_handle_offloads(VirtIONet *n, uint8_t cmd, static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd, struct iovec *iov, unsigned int iov_cnt) { + VirtIODevice *vdev = VIRTIO_DEVICE(n); struct virtio_net_ctrl_mac mac_data; size_t s; NetClientState *nc = qemu_get_queue(n->nic); @@ -639,7 +641,7 @@ static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd, s = iov_to_buf(iov, iov_cnt, 0, &mac_data.entries, sizeof(mac_data.entries)); - mac_data.entries = ldl_p(&mac_data.entries); + mac_data.entries = virtio_ldl_p(vdev, &mac_data.entries); if (s != sizeof(mac_data.entries)) { goto error; } @@ -666,7 +668,7 @@ static int virtio_net_handle_mac(VirtIONet *n, uint8_t cmd, s = iov_to_buf(iov, iov_cnt, 0, &mac_data.entries, sizeof(mac_data.entries)); - mac_data.entries = ldl_p(&mac_data.entries); + mac_data.entries = virtio_ldl_p(vdev, &mac_data.entries); if (s != sizeof(mac_data.entries)) { goto error; } @@ -706,12 +708,13 @@ error: static int virtio_net_handle_vlan_table(VirtIONet *n, uint8_t cmd, struct iovec *iov, unsigned int iov_cnt) { + VirtIODevice *vdev = VIRTIO_DEVICE(n); uint16_t vid; size_t s; NetClientState *nc = qemu_get_queue(n->nic); s = iov_to_buf(iov, iov_cnt, 0, &vid, sizeof(vid)); - vid = lduw_p(&vid); + vid = virtio_lduw_p(vdev, &vid); if (s != sizeof(vid)) { return VIRTIO_NET_ERR; } @@ -748,7 +751,7 @@ static int virtio_net_handle_mq(VirtIONet *n, uint8_t cmd, return VIRTIO_NET_ERR; } - queues = lduw_p(&mq.virtqueue_pairs); + queues = virtio_lduw_p(vdev, &mq.virtqueue_pairs); if (queues < VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN || queues > VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX || @@ -863,6 +866,14 @@ static int virtio_net_has_buffers(VirtIONetQueue *q, int bufsize) return 1; } +static void virtio_net_hdr_swap(VirtIODevice *vdev, struct virtio_net_hdr *hdr) +{ + virtio_tswap16s(vdev, &hdr->hdr_len); + virtio_tswap16s(vdev, &hdr->gso_size); + virtio_tswap16s(vdev, &hdr->csum_start); + virtio_tswap16s(vdev, &hdr->csum_offset); +} + /* dhclient uses AF_PACKET but doesn't pass auxdata to the kernel so * it never finds out that the packets don't have valid checksums. This * causes dhclient to get upset. Fedora's carried a patch for ages to @@ -898,6 +909,7 @@ static void receive_header(VirtIONet *n, const struct iovec *iov, int iov_cnt, void *wbuf = (void *)buf; work_around_broken_dhclient(wbuf, wbuf + n->host_hdr_len, size - n->host_hdr_len); + virtio_net_hdr_swap(VIRTIO_DEVICE(n), wbuf); iov_from_buf(iov, iov_cnt, 0, buf, sizeof(struct virtio_net_hdr)); } else { struct virtio_net_hdr hdr = { @@ -1047,7 +1059,7 @@ static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t } if (mhdr_cnt) { - stw_p(&mhdr.num_buffers, i); + virtio_stw_p(vdev, &mhdr.num_buffers, i); iov_from_buf(mhdr_sg, mhdr_cnt, 0, &mhdr.num_buffers, sizeof mhdr.num_buffers); @@ -1106,6 +1118,14 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q) exit(1); } + if (n->has_vnet_hdr) { + if (out_sg[0].iov_len < n->guest_hdr_len) { + error_report("virtio-net header incorrect"); + exit(1); + } + virtio_net_hdr_swap(vdev, (void *) out_sg[0].iov_base); + } + /* * If host wants to see the guest header as is, we can * pass it on unchanged. Otherwise, copy just the parts