diff options
Diffstat (limited to 'net/net.c')
| -rw-r--r-- | net/net.c | 47 |
1 files changed, 18 insertions, 29 deletions
diff --git a/net/net.c b/net/net.c index a2f0c828bb..6938da05e0 100644 --- a/net/net.c +++ b/net/net.c @@ -56,6 +56,7 @@ #include "net/filter.h" #include "qapi/string-output-visitor.h" #include "qapi/qobject-input-visitor.h" +#include "standard-headers/linux/virtio_net.h" /* Net bridge is currently not supported for W32. */ #if !defined(_WIN32) @@ -529,24 +530,6 @@ bool qemu_has_vnet_hdr_len(NetClientState *nc, int len) return nc->info->has_vnet_hdr_len(nc, len); } -bool qemu_get_using_vnet_hdr(NetClientState *nc) -{ - if (!nc || !nc->info->get_using_vnet_hdr) { - return false; - } - - return nc->info->get_using_vnet_hdr(nc); -} - -void qemu_using_vnet_hdr(NetClientState *nc, bool enable) -{ - if (!nc || !nc->info->using_vnet_hdr) { - return; - } - - nc->info->using_vnet_hdr(nc, enable); -} - void qemu_set_offload(NetClientState *nc, int csum, int tso4, int tso6, int ecn, int ufo, int uso4, int uso6) { @@ -559,11 +542,7 @@ void qemu_set_offload(NetClientState *nc, int csum, int tso4, int tso6, int qemu_get_vnet_hdr_len(NetClientState *nc) { - if (!nc || !nc->info->get_vnet_hdr_len) { - return 0; - } - - return nc->info->get_vnet_hdr_len(nc); + return nc->vnet_hdr_len; } void qemu_set_vnet_hdr_len(NetClientState *nc, int len) @@ -572,6 +551,10 @@ void qemu_set_vnet_hdr_len(NetClientState *nc, int len) return; } + assert(len == sizeof(struct virtio_net_hdr_mrg_rxbuf) || + len == sizeof(struct virtio_net_hdr) || + len == sizeof(struct virtio_net_hdr_v1_hash)); + nc->vnet_hdr_len = len; nc->info->set_vnet_hdr_len(nc, len); } @@ -804,11 +787,7 @@ static ssize_t nc_sendv_compat(NetClientState *nc, const struct iovec *iov, offset = iov_to_buf(iov, iovcnt, 0, buf, offset); } - if (flags & QEMU_NET_PACKET_FLAG_RAW && nc->info->receive_raw) { - ret = nc->info->receive_raw(nc, buffer, offset); - } else { - ret = nc->info->receive(nc, buffer, offset); - } + ret = nc->info->receive(nc, buffer, offset); g_free(buf); return ret; @@ -823,6 +802,8 @@ static ssize_t qemu_deliver_packet_iov(NetClientState *sender, MemReentrancyGuard *owned_reentrancy_guard; NetClientState *nc = opaque; int ret; + struct virtio_net_hdr_v1_hash vnet_hdr = { }; + g_autofree struct iovec *iov_copy = NULL; if (nc->link_down) { @@ -841,7 +822,15 @@ static ssize_t qemu_deliver_packet_iov(NetClientState *sender, owned_reentrancy_guard->engaged_in_io = true; } - if (nc->info->receive_iov && !(flags & QEMU_NET_PACKET_FLAG_RAW)) { + if ((flags & QEMU_NET_PACKET_FLAG_RAW) && nc->vnet_hdr_len) { + iov_copy = g_new(struct iovec, iovcnt + 1); + iov_copy[0].iov_base = &vnet_hdr; + iov_copy[0].iov_len = nc->vnet_hdr_len; + memcpy(&iov_copy[1], iov, iovcnt * sizeof(*iov)); + iov = iov_copy; + } + + if (nc->info->receive_iov) { ret = nc->info->receive_iov(nc, iov, iovcnt); } else { ret = nc_sendv_compat(nc, iov, iovcnt, flags); |