summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKingwel Xie <kingwel.xie@ericsson.com>2018-10-26 23:26:06 -0400
committerDamjan Marion <dmarion@me.com>2018-10-27 09:15:03 +0000
commita91866fc1fd673a5edab6e3cb61bd41b8ea3def7 (patch)
treee5dee75bc3a4f064e6e45c187de630873bea9b5f
parent49cd3bad66cba83f0364d94ed34de2457694f545 (diff)
pg: icmp4 & tcp4 ip length issue
length in ip4 header could be 0, when the length edit is fixed this happens if length is not specified or size is specified as, f.g., 100-100 As a result, tcp and icmp would get a negative value for checksum calculation Change-Id: I55fa1f5e95717ea4149cb3b8c9b73caf88ae7f98 Signed-off-by: Kingwel Xie <kingwel.xie@ericsson.com>
-rw-r--r--src/vnet/ip/icmp4.c8
-rw-r--r--src/vnet/tcp/tcp_pg.c6
2 files changed, 12 insertions, 2 deletions
diff --git a/src/vnet/ip/icmp4.c b/src/vnet/ip/icmp4.c
index 3626e96305b..a598ca9f174 100644
--- a/src/vnet/ip/icmp4.c
+++ b/src/vnet/ip/icmp4.c
@@ -653,7 +653,13 @@ icmp4_pg_edit_function (pg_main_t * pg,
ASSERT (p0->current_data == 0);
ip0 = (void *) (p0->data + ip_offset);
icmp0 = (void *) (p0->data + icmp_offset);
- len0 = clib_net_to_host_u16 (ip0->length) - ip4_header_bytes (ip0);
+
+ /* if IP length has been specified, then calculate the length based on buffer */
+ if (ip0->length == 0)
+ len0 = vlib_buffer_length_in_chain (vm, p0) - icmp_offset;
+ else
+ len0 = clib_net_to_host_u16 (ip0->length) - icmp_offset;
+
icmp0->checksum =
~ip_csum_fold (ip_incremental_checksum (0, icmp0, len0));
}
diff --git a/src/vnet/tcp/tcp_pg.c b/src/vnet/tcp/tcp_pg.c
index 3be4592c679..45eaed97b9b 100644
--- a/src/vnet/tcp/tcp_pg.c
+++ b/src/vnet/tcp/tcp_pg.c
@@ -77,7 +77,11 @@ tcp_pg_edit_function (pg_main_t * pg,
ASSERT (p0->current_data == 0);
ip0 = (void *) (p0->data + ip_offset);
tcp0 = (void *) (p0->data + tcp_offset);
- tcp_len0 = clib_net_to_host_u16 (ip0->length) - sizeof (ip0[0]);
+ /* if IP length has been specified, then calculate the length based on buffer */
+ if (ip0->length == 0)
+ tcp_len0 = vlib_buffer_length_in_chain (vm, p0) - tcp_offset;
+ else
+ tcp_len0 = clib_net_to_host_u16 (ip0->length) - tcp_offset;
/* Initialize checksum with header. */
if (BITS (sum0) == 32)