aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVijayabhaskar Katamreddy <vkatamre@cisco.com>2019-05-23 13:02:28 -0700
committerOle Trøan <otroan@employees.org>2019-05-24 09:02:40 +0000
commit90556d69f9600926e7d99f59d55f06354bd02dcd (patch)
tree3f2bce2812cfa6906166e5dab78486685e0dd28f
parent5f2cfb21fdf6eb4a32346809c8cee2550d775b19 (diff)
ip4/6-reassembly fixes
When multichained fragments comes into reassembly, followed by buffer Linearization or dropping the buffer for other reasons inbetween disturbs the multichained mbuf linking. When packet is transmitted, followed by freeing of the buffers, woudl result in double free and packet corruptions Change-Id: Ib5711d54e61fdd6a67deb30dad0b2a14afb9c2da Signed-off-by: Vijayabhaskar Katamreddy <vkatamre@cisco.com>
-rw-r--r--src/vnet/ip/ip4_reassembly.c12
-rw-r--r--src/vnet/ip/ip6_reassembly.c1
2 files changed, 11 insertions, 2 deletions
diff --git a/src/vnet/ip/ip4_reassembly.c b/src/vnet/ip/ip4_reassembly.c
index f27351038fe..763229c5baa 100644
--- a/src/vnet/ip/ip4_reassembly.c
+++ b/src/vnet/ip/ip4_reassembly.c
@@ -489,6 +489,7 @@ ip4_reass_finalize (vlib_main_t * vm, vlib_node_runtime_t * node,
}
tmp->flags &= ~VLIB_BUFFER_NEXT_PRESENT;
tmp_bi = tmp->next_buffer;
+ tmp->next_buffer = 0;
tmp = vlib_get_buffer (vm, tmp_bi);
vlib_buffer_free_one (vm, to_be_freed_bi);
continue;
@@ -540,12 +541,15 @@ ip4_reass_finalize (vlib_main_t * vm, vlib_node_runtime_t * node,
}
if (tmp->flags & VLIB_BUFFER_NEXT_PRESENT)
{
+ tmp->flags &= ~VLIB_BUFFER_NEXT_PRESENT;
tmp_bi = tmp->next_buffer;
- tmp = vlib_get_buffer (vm, tmp->next_buffer);
+ tmp->next_buffer = 0;
+ tmp = vlib_get_buffer (vm, tmp_bi);
vlib_buffer_free_one (vm, to_be_freed_bi);
}
else
{
+ tmp->next_buffer = 0;
vlib_buffer_free_one (vm, to_be_freed_bi);
break;
}
@@ -562,6 +566,7 @@ ip4_reass_finalize (vlib_main_t * vm, vlib_node_runtime_t * node,
return IP4_REASS_RC_INTERNAL_ERROR;
}
last_b->flags &= ~VLIB_BUFFER_NEXT_PRESENT;
+
if (total_length < first_b->current_length)
{
return IP4_REASS_RC_INTERNAL_ERROR;
@@ -577,7 +582,8 @@ ip4_reass_finalize (vlib_main_t * vm, vlib_node_runtime_t * node,
{
return IP4_REASS_RC_NO_BUF;
}
-
+ // reset to reconstruct the mbuf linking
+ first_b->flags &= ~VLIB_BUFFER_EXT_HDR_VALID;
if (PREDICT_FALSE (first_b->flags & VLIB_BUFFER_IS_TRACED))
{
ip4_reass_add_trace (vm, node, rm, reass, reass->first_bi, FINALIZE, 0);
@@ -700,11 +706,13 @@ ip4_reass_remove_range_from_chain (vlib_main_t * vm,
{
discard_b->flags &= ~VLIB_BUFFER_NEXT_PRESENT;
discard_bi = discard_b->next_buffer;
+ discard_b->next_buffer = 0;
discard_b = vlib_get_buffer (vm, discard_bi);
vlib_buffer_free_one (vm, to_be_freed_bi);
}
else
{
+ discard_b->next_buffer = 0;
vlib_buffer_free_one (vm, to_be_freed_bi);
break;
}
diff --git a/src/vnet/ip/ip6_reassembly.c b/src/vnet/ip/ip6_reassembly.c
index 45cd2b2eaeb..cb1cd9afeb4 100644
--- a/src/vnet/ip/ip6_reassembly.c
+++ b/src/vnet/ip/ip6_reassembly.c
@@ -633,6 +633,7 @@ ip6_reass_finalize (vlib_main_t * vm, vlib_node_runtime_t * node,
rv = IP6_REASS_RC_NO_BUF;
goto free_buffers_and_return;
}
+ first_b->flags &= ~VLIB_BUFFER_EXT_HDR_VALID;
if (PREDICT_FALSE (first_b->flags & VLIB_BUFFER_IS_TRACED))
{
ip6_reass_add_trace (vm, node, rm, reass, reass->first_bi, FINALIZE, 0);