qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [RFC Patch v2 06/10] virtio-net rsc: IPv4 checksum


From: Wei Xu
Subject: Re: [Qemu-devel] [RFC Patch v2 06/10] virtio-net rsc: IPv4 checksum
Date: Mon, 01 Feb 2016 16:40:13 +0800
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0



On 02/01/2016 02:31 PM, Jason Wang wrote:

On 02/01/2016 02:13 AM, address@hidden wrote:
From: Wei Xu <address@hidden>

If a field in the IPv4 header is modified, then the checksum
have to be recalculated before sending it out.
This in fact breaks bisection. I think you need either squash this into
previous patch or introduce virtio_net_rsc_ipv4_checksum() as a helper
before the patch of ipv4 coalescing.
OK.
Signed-off-by: Wei Xu <address@hidden>
---
  hw/net/virtio-net.c | 19 +++++++++++++++++++
  1 file changed, 19 insertions(+)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 93df0d5..88fc4f8 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -1630,6 +1630,18 @@ static int virtio_net_load_device(VirtIODevice *vdev, 
QEMUFile *f,
      return 0;
  }
+static void virtio_net_rsc_ipv4_checksum(NetRscSeg *seg)
+{
+    uint32_t sum;
+    struct ip_header *ip;
+
+    ip = (struct ip_header *)(seg->buf + IP_OFFSET);
+
+    ip->ip_sum = 0;
+    sum = net_checksum_add_cont(sizeof(struct ip_header), (uint8_t *)ip, 0);
+    ip->ip_sum = cpu_to_be16(net_checksum_finish(sum));
+}
+
  static void virtio_net_rsc_purge(void *opq)
  {
      int ret = 0;
@@ -1643,6 +1655,10 @@ static void virtio_net_rsc_purge(void *opq)
              continue;
          }
+ if ((chain->proto == ETH_P_IP) && seg->is_coalesced) {
+            virtio_net_rsc_ipv4_checksum(seg);
+        }
+
          ret = virtio_net_do_receive(seg->nc, seg->buf, seg->size);
          QTAILQ_REMOVE(&chain->buffers, seg, next);
          g_free(seg->buf);
@@ -1853,6 +1869,9 @@ static size_t virtio_net_rsc_callback(NetRscChain *chain, 
NetClientState *nc,
      QTAILQ_FOREACH_SAFE(seg, &chain->buffers, next, nseg) {
          ret = coalesce(chain, seg, buf, size);
          if (RSC_FINAL == ret) {
+            if ((chain->proto == ETH_P_IP) && seg->is_coalesced) {
+                virtio_net_rsc_ipv4_checksum(seg);
+            }
              ret = virtio_net_do_receive(seg->nc, seg->buf, seg->size);
              QTAILQ_REMOVE(&chain->buffers, seg, next);
              g_free(seg->buf);





reply via email to

[Prev in Thread] Current Thread [Next in Thread]