-
- ti = vec_elt_at_index (tm->tapcli_interfaces, ready_interface_indices[i]);
-
- /* Make sure we have some RX buffers. */
- {
- uword n_left = vec_len (tm->rx_buffers);
- uword n_alloc;
-
- if (n_left < VLIB_FRAME_SIZE / 2)
- {
- if (! tm->rx_buffers)
- vec_alloc (tm->rx_buffers, VLIB_FRAME_SIZE);
-
- n_alloc = vlib_buffer_alloc_from_free_list
- (vm, tm->rx_buffers + n_left, VLIB_FRAME_SIZE - n_left,
- free_list_index);
- _vec_len (tm->rx_buffers) = n_left + n_alloc;
- }
- }
-
- /* Allocate RX buffers from end of rx_buffers.
- Turn them into iovecs to pass to readv. */
- {
- uword i_rx = vec_len (tm->rx_buffers) - 1;
- vlib_buffer_t * b;
- word j, n_bytes_left, n_bytes_in_packet;
-#if DPDK == 1
- u8 out_of_dpdk_buffers = 0;
-#endif
-
- /* We need enough buffers left for an MTU sized packet. */
- if (PREDICT_FALSE(vec_len (tm->rx_buffers) < tm->mtu_buffers))
- {
- clib_bitmap_set (tm->pending_read_bitmap,
- ready_interface_indices[i], 1);
- clib_warning ("buffer allocation failure");
- continue;
- }
-
- vec_validate (tm->iovecs, tm->mtu_buffers - 1);
- for (j = 0; j < tm->mtu_buffers; j++)
- {
- b = vlib_get_buffer (vm, tm->rx_buffers[i_rx - j]);
- tm->iovecs[j].iov_base = b->data;
- tm->iovecs[j].iov_len = buffer_size;
- }
-
-#if DPDK == 1
- if (PREDICT_FALSE(out_of_dpdk_buffers == 1))
- continue;
-#endif
-
- n_bytes_left = readv (ti->unix_fd, tm->iovecs, tm->mtu_buffers);
- n_bytes_in_packet = n_bytes_left;
- if (n_bytes_left <= 0)
- {
- if (errno != EAGAIN)
- clib_unix_warning ("readv %d", n_bytes_left);
- return 0;
- }
-
- bi = tm->rx_buffers[i_rx];
- while (1)
- {
- b = vlib_get_buffer (vm, tm->rx_buffers[i_rx]);
-
- b->flags = 0;
- b->current_data = 0;
- b->current_length = n_bytes_left < buffer_size
- ? n_bytes_left : buffer_size;
-
- n_bytes_left -= buffer_size;
-
- if (n_bytes_left <= 0)
- {
-#if DPDK == 1
- struct rte_mbuf *mb = (struct rte_mbuf *)(b - 1);
- rte_pktmbuf_data_len (mb) = n_bytes_in_packet;
- rte_pktmbuf_pkt_len (mb) = n_bytes_in_packet;
-#endif
- break;
- }
-
- i_rx--;
- b->flags |= VLIB_BUFFER_NEXT_PRESENT;
- b->next_buffer = tm->rx_buffers[i_rx];
-#if DPDK == 1
- ASSERT(0); /* $$$$ fixme */
- /* ((struct rte_pktmbuf *)(b->mb))->next =
- vlib_get_buffer (vm, tm->rx_buffers[i_rx])->mb; */
-#endif
- }
-
- /* Interface counters for tapcli interface. */
- vlib_increment_combined_counter
- (vnet_main.interface_main.combined_sw_if_counters
- + VNET_INTERFACE_COUNTER_RX,
- os_get_cpu_number(),
- ti->sw_if_index,
- 1, n_bytes_in_packet);
-
- _vec_len (tm->rx_buffers) = i_rx;
- }
-
- b = vlib_get_buffer (vm, bi);
-
- /*
- * Turn this on if you run into
- * "bad monkey" contexts, and you want to know exactly
- * which nodes they've visited... See .../vlib/vlib/buffer.h
- */
- VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b);
-
- {
- u32 next_index;
- uword n_trace = vlib_get_trace_count (vm, node);