Fix UDP length check for local IP/UDP lookup and error handling.

Change-Id: If6695e19e5a1e5471e56099e2cf31794c73f3303
Signed-off-by: John Lo <loj@cisco.com>
This commit is contained in:
John Lo
2016-03-03 00:25:54 -05:00
parent 2df2e3d7d5
commit 76f78ec39a

View File

@ -133,7 +133,7 @@ udp46_input_inline (vlib_main_t * vm,
advance1 = sizeof(ip6_header_t);
}
if (PREDICT_FALSE(b0->current_length < advance0 + sizeof (h0)))
if (PREDICT_FALSE(b0->current_length < advance0 + sizeof (*h0)))
{
error0 = UDP_ERROR_LENGTH_ERROR;
next0 = UDP_INPUT_NEXT_DROP;
@ -143,9 +143,15 @@ udp46_input_inline (vlib_main_t * vm,
vlib_buffer_advance (b0, advance0);
h0 = vlib_buffer_get_current (b0);
error0 = next0 = 0;
if (PREDICT_FALSE(clib_net_to_host_u16(h0->length) >
vlib_buffer_length_in_chain(vm, b0)))
{
error0 = UDP_ERROR_LENGTH_ERROR;
next0 = UDP_INPUT_NEXT_DROP;
}
}
if (PREDICT_FALSE(b1->current_length < advance1 + sizeof (h1)))
if (PREDICT_FALSE(b1->current_length < advance1 + sizeof (*h1)))
{
error1 = UDP_ERROR_LENGTH_ERROR;
next1 = UDP_INPUT_NEXT_DROP;
@ -155,9 +161,14 @@ udp46_input_inline (vlib_main_t * vm,
vlib_buffer_advance (b1, advance1);
h1 = vlib_buffer_get_current (b1);
error1 = next1 = 0;
if (PREDICT_FALSE(clib_net_to_host_u16(h1->length) >
vlib_buffer_length_in_chain(vm, b1)))
{
error1 = UDP_ERROR_LENGTH_ERROR;
next1 = UDP_INPUT_NEXT_DROP;
}
}
/* Index sparse array with network byte order. */
dst_port0 = (error0 == 0) ? h0->dst_port : 0;
dst_port1 = (error1 == 0) ? h1->dst_port : 0;
@ -166,10 +177,10 @@ udp46_input_inline (vlib_main_t * vm,
next0 = (error0 == 0) ? vec_elt(rt->next_by_dst_port, i0) : next0;
next1 = (error1 == 0) ? vec_elt(rt->next_by_dst_port, i1) : next1;
if (PREDICT_TRUE (error0 == 0))
b0->error = node->errors[next0 == SPARSE_VEC_INVALID_INDEX ? UDP_ERROR_NO_LISTENER : UDP_ERROR_NONE];
if (PREDICT_TRUE (error1 == 0))
b1->error = node->errors[next1 == SPARSE_VEC_INVALID_INDEX ? UDP_ERROR_NO_LISTENER : UDP_ERROR_NONE];
b0->error = node->errors[next0 == SPARSE_VEC_INVALID_INDEX ?
UDP_ERROR_NO_LISTENER : error0];
b1->error = node->errors[next1 == SPARSE_VEC_INVALID_INDEX ?
UDP_ERROR_NO_LISTENER : error1];
if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED))
{
@ -223,7 +234,7 @@ udp46_input_inline (vlib_main_t * vm,
else
advance0 = sizeof(ip6_header_t);
if (PREDICT_FALSE(b0->current_length < advance0 + sizeof (h0)))
if (PREDICT_FALSE(b0->current_length < advance0 + sizeof (*h0)))
{
b0->error = node->errors[UDP_ERROR_LENGTH_ERROR];
next0 = UDP_INPUT_NEXT_DROP;
@ -234,8 +245,8 @@ udp46_input_inline (vlib_main_t * vm,
h0 = vlib_buffer_get_current (b0);
if (PREDICT_TRUE
(clib_net_to_host_u16(h0->length) <= b0->current_length))
if (PREDICT_TRUE(clib_net_to_host_u16(h0->length) <=
vlib_buffer_length_in_chain(vm, b0)))
{
i0 = sparse_vec_index (rt->next_by_dst_port, h0->dst_port);
next0 = vec_elt(rt->next_by_dst_port, i0);