interface: Fix the tso segmentation 20/20220/4
authorMohsin Kazmi <sykazmi@cisco.com>
Tue, 18 Jun 2019 21:45:54 +0000 (23:45 +0200)
committerDamjan Marion <dmarion@me.com>
Wed, 19 Jun 2019 13:33:17 +0000 (13:33 +0000)
ASSERT (b[0]->current_length > 0) fails in single loop of
function vnet_interface_output_node_inline_gso.

Under 'do_segmentation' condition, there are two places in code
which execute "continue" in while-loop without incrementing the
pointer to next buffer which is wrong behavior. In fact, at one
place, current buffer is also freed. In which case, during next
iteration buffer ptr still points to free buffer which current
length is 0 and triggers the above assert.

Type: fix

Change-Id: Ic9d540748c1d00a54e18acc2b0f23730728d7460
Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
src/vnet/interface_output.c

index 2e4f360..28f44c3 100644 (file)
@@ -713,6 +713,7 @@ vnet_interface_output_node_inline_gso (vlib_main_t * vm,
                    {
                      drop_one_buffer_and_count (vm, vnm, node, from - 1,
                                                 VNET_INTERFACE_OUTPUT_ERROR_NO_BUFFERS_FOR_GSO);
+                     b += 1;
                      continue;
                    }
 
@@ -737,17 +738,14 @@ vnet_interface_output_node_inline_gso (vlib_main_t * vm,
                          vlib_get_new_next_frame (vm, node, next_index,
                                                   to_tx, n_left_to_tx);
                        }
-                     else
+                     while (n_tx_bufs > 0)
                        {
-                         while (n_tx_bufs > 0)
-                           {
-                             to_tx[0] = from_tx_seg[0];
-                             to_tx += 1;
-                             from_tx_seg += 1;
-                             n_left_to_tx -= 1;
-                             n_tx_bufs -= 1;
-                             n_packets += 1;
-                           }
+                         to_tx[0] = from_tx_seg[0];
+                         to_tx += 1;
+                         from_tx_seg += 1;
+                         n_left_to_tx -= 1;
+                         n_tx_bufs -= 1;
+                         n_packets += 1;
                        }
                    }
                  n_bytes += n_tx_bytes;
@@ -763,6 +761,7 @@ vnet_interface_output_node_inline_gso (vlib_main_t * vm,
                  _vec_len (ptd->split_buffers) = 0;
                  /* Free the now segmented buffer */
                  vlib_buffer_free_one (vm, bi0);
+                 b += 1;
                  continue;
                }
            }