If we invoke the subject API with 2 buffers, each with 2 chains, the content of
buffers[0] should be head of 1st buffer, and content of buffer[1] should be
head of 2nd buffer.
What the code did was to put
buffers[0] = head of 1st buffer
buffers[1] = next chain of 1st buffer
buffers[2] = head of 2nd buffer
buffers[3] = next chain of 2nd buffer
This is wrong and can cause crash.
The fix is to only increment bi when the entire packet is found which may consist
of multiple fragments.
Change-Id: If02cd5186a039d7a6c08a0959112840bdb242317
Signed-off-by: Steven <sluong@cisco.com>
(rxq->rx_comp[comp_ring->next].flags & VMXNET3_RXCF_GEN))
{
vlib_buffer_t *b0;
(rxq->rx_comp[comp_ring->next].flags & VMXNET3_RXCF_GEN))
{
vlib_buffer_t *b0;
comp_idx = comp_ring->next;
rx_comp = &rxq->rx_comp[comp_idx];
comp_idx = comp_ring->next;
rx_comp = &rxq->rx_comp[comp_idx];
desc_idx = rx_comp->index & VMXNET3_RXC_INDEX;
ring->consume = desc_idx;
desc_idx = rx_comp->index & VMXNET3_RXC_INDEX;
ring->consume = desc_idx;
- bi[0] = ring->bufs[desc_idx];
+ bi0 = ring->bufs[desc_idx];
ring->bufs[desc_idx] = ~0;
ring->bufs[desc_idx] = ~0;
- b0 = vlib_get_buffer (vm, bi[0]);
+ b0 = vlib_get_buffer (vm, bi0);
vnet_buffer (b0)->sw_if_index[VLIB_RX] = vd->sw_if_index;
vnet_buffer (b0)->sw_if_index[VLIB_TX] = (u32) ~ 0;
vnet_buffer (b0)->feature_arc_index = 0;
vnet_buffer (b0)->sw_if_index[VLIB_RX] = vd->sw_if_index;
vnet_buffer (b0)->sw_if_index[VLIB_TX] = (u32) ~ 0;
vnet_buffer (b0)->feature_arc_index = 0;
{
/* start segment */
hb = b0;
{
/* start segment */
hb = b0;
if (!(rx_comp->index & VMXNET3_RXCI_EOP))
{
hb->flags = VLIB_BUFFER_TOTAL_LENGTH_VALID;
if (!(rx_comp->index & VMXNET3_RXCI_EOP))
{
hb->flags = VLIB_BUFFER_TOTAL_LENGTH_VALID;
/* end of segment */
if (prev_b0)
{
/* end of segment */
if (prev_b0)
{
- prev_b0->next_buffer = bi[0];
+ prev_b0->next_buffer = bi0;
prev_b0->flags |= VLIB_BUFFER_NEXT_PRESENT;
hb->total_length_not_including_first_buffer +=
b0->current_length;
prev_b0->flags |= VLIB_BUFFER_NEXT_PRESENT;
hb->total_length_not_including_first_buffer +=
b0->current_length;
{
/* EOP without SOP, error */
hb = 0;
{
/* EOP without SOP, error */
hb = 0;
vlib_error_count (vm, node->node_index,
VMXNET3_INPUT_ERROR_RX_PACKET, 1);
vlib_error_count (vm, node->node_index,
VMXNET3_INPUT_ERROR_RX_PACKET, 1);
- vlib_buffer_free_one (vm, bi[0]);
+ vlib_buffer_free_one (vm, bi0);
{
/* mid chain */
b0->flags |= VLIB_BUFFER_NEXT_PRESENT;
{
/* mid chain */
b0->flags |= VLIB_BUFFER_NEXT_PRESENT;
- prev_b0->next_buffer = bi[0];
+ prev_b0->next_buffer = bi0;
prev_b0 = b0;
hb->total_length_not_including_first_buffer += b0->current_length;
}
prev_b0 = b0;
hb->total_length_not_including_first_buffer += b0->current_length;
}
n_rx_bytes += b0->current_length;
if (!prev_b0)
n_rx_bytes += b0->current_length;
if (!prev_b0)