diff mbox

[RFC,06/10] IPv4 checksum.

Message ID 1453760690-21221-7-git-send-email-wexu@redhat.com
State New
Headers show

Commit Message

Wei Xu Jan. 25, 2016, 10:24 p.m. UTC
Signed-off-by: Wei Xu <wexu@redhat.com>
---
 hw/net/virtio-net.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
diff mbox

Patch

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 8da2815..1ca3dd5 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);