当前位置: 首页 > 工具软件 > VPP > 使用案例 >

VPP

秦城
2023-12-01

VPP

always_inline uword
ip4_input_inline (vlib_main_t * vm,
vlib_node_runtime_t * node,
vlib_frame_t * frame, int verify_checksum)
{
vnet_main_t *vnm = vnet_get_main ();
u32 n_left_from, *from;
u32 thread_index = vm->thread_index;
vlib_node_runtime_t *error_node =
vlib_node_get_runtime (vm, ip4_input_node.index);
vlib_simple_counter_main_t *cm;
vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b;
ip4_header_t *ip[4];
u16 nexts[VLIB_FRAME_SIZE], *next;
u32 sw_if_index[4];
u32 last_sw_if_index = ~0;
u32 cnt = 0;
int arc_enabled = 0;

from = vlib_frame_vector_args (frame);
n_left_from = frame->n_vectors;

if (node->flags & VLIB_NODE_FLAG_TRACE)
vlib_trace_frame_buffers_only (vm, node, from, frame->n_vectors,
/* stride */ 1,
sizeof (ip4_input_trace_t));

cm = vec_elt_at_index (vnm->interface_main.sw_if_counters,
VNET_INTERFACE_COUNTER_IP4);

vlib_get_buffers (vm, from, bufs, n_left_from);
b = bufs;
next = nexts;
while (n_left_from >= 4)
{
u32 x = 0;

  /* Prefetch next iteration. */
  if (n_left_from >= 12)
{
  vlib_prefetch_buffer_header (b[8], LOAD);
  vlib_prefetch_buffer_header (b[9], LOAD);
  vlib_prefetch_buffer_header (b[10], LOAD);
  vlib_prefetch_buffer_header (b[11], LOAD);

  vlib_prefetch_buffer_data (b[4], LOAD);
  vlib_prefetch_buffer_data (b[5], LOAD);
  vlib_prefetch_buffer_data (b[6], LOAD);
  vlib_prefetch_buffer_data (b[7], LOAD);
}

  vnet_buffer (b[0])->ip.adj_index[VLIB_RX] = ~0;
  vnet_buffer (b[1])->ip.adj_index[VLIB_RX] = ~0;
  vnet_buffer (b[2])->ip.adj_index[VLIB_RX] = ~0;
  vnet_buffer (b[3])->ip.adj_index[VLIB_RX] = ~0;

  sw_if_index[0] = vnet_buffer (b[0])->sw_if_index[VLIB_RX];
  sw_if_index[1] = vnet_buffer (b[1])->sw_if_index[VLIB_RX];
  sw_if_index[2] = vnet_buffer (b[2])->sw_if_index[VLIB_RX];
  sw_if_index[3] = vnet_buffer (b[3])->sw_if_index[VLIB_RX];

  x |= sw_if_index[0] ^ last_sw_if_index;
  x |= sw_if_index[1] ^ last_sw_if_index;
  x |= sw_if_index[2] ^ last_sw_if_index;
  x |= sw_if_index[3] ^ last_sw_if_index;

  if (PREDICT_TRUE (x == 0))
{
  /* we deal with 4 more packets sharing the same sw_if_index
     with the previous one, so we can optimize */
  cnt += 4;
  if (arc_enabled)
    {
      next[0] = ip4_input_set_next (sw_if_index[0], b[0], 1);
      next[1] = ip4_input_set_next (sw_if_index[1], b[1], 1);
      next[2] = ip4_input_set_next (sw_if_index[2], b[2], 1);
      next[3] = ip4_input_set_next (sw_if_index[3], b[3], 1);
    }
  else
    {
      next[0] = ip4_input_set_next (sw_if_index[0], b[0], 0);
      next[1] = ip4_input_set_next (sw_if_index[1], b[1], 0);
      next[2] = ip4_input_set_next (sw_if_index[2], b[2], 0);
      next[3] = ip4_input_set_next (sw_if_index[3], b[3], 0);
    }
}
  else
{
  ip4_input_check_sw_if_index (vm, cm, sw_if_index[0],
			       &last_sw_if_index, &cnt, &arc_enabled);
  ip4_input_check_sw_if_index (vm, cm, sw_if_index[1],
			       &last_sw_if_index, &cnt, &arc_enabled);
  ip4_input_check_sw_if_index (vm, cm, sw_if_index[2],
			       &last_sw_if_index, &cnt, &arc_enabled);
  ip4_input_check_sw_if_index (vm, cm, sw_if_index[3],
			       &last_sw_if_index, &cnt, &arc_enabled);

  next[0] = ip4_input_set_next (sw_if_index[0], b[0], 1);
  next[1] = ip4_input_set_next (sw_if_index[1], b[1], 1);
  next[2] = ip4_input_set_next (sw_if_index[2], b[2], 1);
  next[3] = ip4_input_set_next (sw_if_index[3], b[3], 1);
}

  ip[0] = vlib_buffer_get_current (b[0]);
  ip[1] = vlib_buffer_get_current (b[1]);
  ip[2] = vlib_buffer_get_current (b[2]);
  ip[3] = vlib_buffer_get_current (b[3]);

  ip4_input_check_x4 (vm, error_node, b, ip, next, verify_checksum);

  /* next */
  b += 4;
  next += 4;
  n_left_from -= 4;
}

while (n_left_from)
{
u32 next0;
vnet_buffer (b[0])->ip.adj_index[VLIB_RX] = ~0;
sw_if_index[0] = vnet_buffer (b[0])->sw_if_index[VLIB_RX];
ip4_input_check_sw_if_index (vm, cm, sw_if_index[0], &last_sw_if_index,
&cnt, &arc_enabled);
next0 = ip4_input_set_next (sw_if_index[0], b[0], arc_enabled);
ip[0] = vlib_buffer_get_current (b[0]);
ip4_input_check_x1 (vm, error_node, b[0], ip[0], &next0,
verify_checksum);
next[0] = next0;

  /* next */
  b += 1;
  next += 1;
  n_left_from -= 1;
}

vlib_increment_simple_counter (cm, thread_index, last_sw_if_index, cnt);
vlib_buffer_enqueue_to_next (vm, node, from, nexts, frame->n_vectors);
return frame->n_vectors;
}

相关阅读

相关文章

相关问答