ip: fix ip6/udp checksum for pkts using buffer chaining 61/21061/1
authorJohn Lo <loj@cisco.com>
Sat, 3 Aug 2019 18:36:39 +0000 (14:36 -0400)
committerJohn Lo <loj@cisco.com>
Mon, 5 Aug 2019 13:08:20 +0000 (13:08 +0000)
Fix ip6_tcp_udp_icmp_compute_checksum to work properly for packets
with multiple buffers.
Fix ip4_tcp_udp_compute_checksum to exit upon detecting error.

Type: fix

Signed-off-by: John Lo <loj@cisco.com>
Change-Id: I673547f4479d72cd60757383343fc562cff10265
(cherry picked from commit 3bc6bc21fb79a9da4ec674f5e6a3303e7e2be625)

src/vnet/ip/ip4_forward.c
src/vnet/ip/ip6_forward.c

index e18a40b..4d7aa06 100644 (file)
@@ -1172,6 +1172,9 @@ ip4_tcp_udp_compute_checksum (vlib_main_t * vm, vlib_buffer_t * p0,
        break;
 
       ASSERT (p0->flags & VLIB_BUFFER_NEXT_PRESENT);
+      if (!(p0->flags & VLIB_BUFFER_NEXT_PRESENT))
+       return 0xfefe;
+
       p0 = vlib_get_buffer (vm, p0->next_buffer);
       data_this_buffer = vlib_buffer_get_current (p0);
       n_this_buffer = clib_min (p0->current_length, n_bytes_left);
index 6df3d4b..3410a5d 100644 (file)
@@ -993,10 +993,18 @@ ip6_tcp_udp_icmp_compute_checksum (vlib_main_t * vm, vlib_buffer_t * p0,
     }
 
   n_bytes_left = n_this_buffer = payload_length_host_byte_order;
-  if (p0 && n_this_buffer + headers_size > p0->current_length)
-    n_this_buffer =
-      p0->current_length >
-      headers_size ? p0->current_length - headers_size : 0;
+
+  if (p0)
+    {
+      u32 n_ip_bytes_this_buffer =
+       p0->current_length - (((u8 *) ip0 - p0->data) - p0->current_data);
+      if (n_this_buffer + headers_size > n_ip_bytes_this_buffer)
+       {
+         n_this_buffer = p0->current_length > headers_size ?
+           n_ip_bytes_this_buffer - headers_size : 0;
+       }
+    }
+
   while (1)
     {
       sum0 = ip_incremental_checksum (sum0, data_this_buffer, n_this_buffer);