30 #define MAX(a,b) ((a) < (b) ? (b) : (a)) 34 #define MIN(a,b) ((a) < (b) ? (a) : (b)) 50 #define VMWARE_LENGTH_BUG_WORKAROUND 0 61 return RTE_ETH_IS_IPV4_HDR (mb->packet_type) != 0;
67 return RTE_ETH_IS_IPV6_HDR (mb->packet_type) != 0;
74 return (h->
type == clib_host_to_net_u16 (ETHERNET_TYPE_MPLS_UNICAST));
87 #ifdef RTE_LIBRTE_MBUF_EXT_RX_OLFLAGS
88 PKT_EXT_RX_PKT_ERROR | PKT_EXT_RX_BAD_FCS |
90 PKT_RX_IP_CKSUM_BAD | PKT_RX_L4_CKSUM_BAD)))
95 #ifdef RTE_LIBRTE_MBUF_EXT_RX_OLFLAGS 96 (mb_flags & PKT_EXT_RX_PKT_ERROR) ? DPDK_ERROR_RX_PACKET_ERROR :
97 (mb_flags & PKT_EXT_RX_BAD_FCS) ? DPDK_ERROR_RX_BAD_FCS :
99 (mb_flags & PKT_RX_IP_CKSUM_BAD) ? DPDK_ERROR_IP_CHECKSUM_ERROR :
100 (mb_flags & PKT_RX_L4_CKSUM_BAD) ? DPDK_ERROR_L4_CHECKSUM_ERROR :
105 *error0 = DPDK_ERROR_NONE;
180 #ifdef RTE_LIBRTE_MBUF_EXT_RX_OLFLAGS 185 mb->ol_flags &= PKT_EXT_RX_CLR_TX_FLAGS_MASK;
238 if (eh->
type == clib_host_to_net_u16 (ETHERNET_TYPE_IP4))
242 u8 pkt_prec = (ipv4->
tos >> 5);
245 DPDK_ERROR_IPV4_EFD_DROP_PKTS : DPDK_ERROR_NONE);
247 else if (eh->
type == clib_net_to_host_u16 (ETHERNET_TYPE_IP6))
255 DPDK_ERROR_IPV6_EFD_DROP_PKTS : DPDK_ERROR_NONE);
257 else if (eh->
type == clib_net_to_host_u16 (ETHERNET_TYPE_MPLS_UNICAST))
264 DPDK_ERROR_MPLS_EFD_DROP_PKTS : DPDK_ERROR_NONE);
266 else if ((eh->
type == clib_net_to_host_u16 (ETHERNET_TYPE_VLAN)) ||
267 (eh->
type == clib_net_to_host_u16 (ETHERNET_TYPE_DOT1AD)))
274 DPDK_ERROR_VLAN_EFD_DROP_PKTS : DPDK_ERROR_NONE);
277 return DPDK_ERROR_NONE;
294 n_this_chunk = rte_eth_rx_burst (xd->
device_index, queue_id,
297 n_buffers += n_this_chunk;
298 n_left -= n_this_chunk;
301 if (n_this_chunk < 32)
313 offset = queue_id * VIRTIO_QNUM;
315 struct vhost_virtqueue *vq =
316 xd->vu_vhost_dev.virtqueue[offset + VIRTIO_TXQ];
321 struct rte_mbuf **pkts = xd->
rx_vectors[queue_id];
324 n_this_chunk = rte_vhost_dequeue_burst (&xd->vu_vhost_dev,
328 pkts + n_buffers, n_left);
329 n_buffers += n_this_chunk;
330 n_left -= n_this_chunk;
331 if (n_this_chunk == 0)
337 for (i = 0; i < n_buffers; i++)
339 struct rte_mbuf *buff = pkts[
i];
340 bytes += rte_pktmbuf_data_len (buff);
345 dpdk_vu_vring *vring =
NULL;
347 if (dpdk_vhost_user_want_interrupt (xd, offset + VIRTIO_TXQ))
349 vring = &(xd->vu_intf->vrings[offset + VIRTIO_TXQ]);
350 vring->n_since_last_int += n_buffers;
352 if ((vring->n_since_last_int && (vring->int_deadline < now))
354 dpdk_vhost_user_send_interrupt (vm, xd, offset + VIRTIO_TXQ);
357 vring = &(xd->vu_intf->vrings[offset + VIRTIO_RXQ]);
358 vring->packets += n_buffers;
359 vring->bytes += bytes;
361 if (dpdk_vhost_user_want_interrupt (xd, offset + VIRTIO_RXQ))
363 if (vring->n_since_last_int && (vring->int_deadline < now))
364 dpdk_vhost_user_send_interrupt (vm, xd, offset + VIRTIO_RXQ);
369 #ifdef RTE_LIBRTE_KNI 374 rte_kni_handle_request (xd->
kni);
393 u32 cpu_index,
u16 queue_id,
int use_efd)
397 u32 n_left_to_next, *to_next;
400 uword n_rx_bytes = 0;
401 u32 n_trace, trace_cnt __attribute__ ((unused));
403 u8 efd_discard_burst = 0;
404 u32 buffer_flags_template;
438 for (mb_index = 0; mb_index < n_buffers; mb_index++)
439 rte_pktmbuf_free (xd->
rx_vectors[queue_id][mb_index]);
455 for (mb_index = 0; mb_index < n_buffers; mb_index++)
456 rte_pktmbuf_free (xd->
rx_vectors[queue_id][mb_index]);
460 DPDK_ERROR_VLAN_EFD_DROP_PKTS,
477 efd_discard_burst = 1;
484 while (n_buffers > 0)
494 while (n_buffers > 0 && n_left_to_next > 0)
497 struct rte_mbuf *mb = xd->
rx_vectors[queue_id][mb_index];
498 struct rte_mbuf *mb_seg = mb->next;
502 struct rte_mbuf *pfmb = xd->
rx_vectors[queue_id][mb_index + 2];
519 rte_pktmbuf_free (mb);
531 struct rte_mbuf *pfmb = mb->next;
548 #ifdef RTE_LIBRTE_MBUF_EXT_RX_OLFLAGS 555 mb->ol_flags &= PKT_EXT_RX_CLR_TX_FLAGS_MASK;
570 b0->
current_data += mb->data_off - RTE_PKTMBUF_HEADROOM;
573 b0->
flags = buffer_flags_template;
580 n_rx_bytes += mb->pkt_len;
583 while ((mb->nb_segs > 1) && (nb_seg < mb->nb_segs))
598 (mb_seg->buf_addr + mb_seg->data_off) - (
void *) b_seg->
data;
607 mb_seg = mb_seg->next;
619 to_next, n_left_to_next,
654 struct timespec ts, tsrem;
659 while (nanosleep (&ts, &tsrem) < 0)
713 uword n_rx_packets = 0;
740 uword n_rx_packets = 0;
766 uword n_rx_packets = 0;
790 .name =
"dpdk-input",
793 .state = VLIB_NODE_STATE_DISABLED,
839 r->next_nodes[next] = name;
840 r_handoff->next_nodes[next] = name;
844 clib_warning (
"%s: illegal next %d\n", __FUNCTION__, next);
859 for (ix = 0; ix < 8; ix++)
864 (*bitmap) |= (1 << ix);
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
void dpdk_rx_trace(dpdk_main_t *dm, vlib_node_runtime_t *node, dpdk_device_t *xd, u16 queue_id, u32 *buffers, uword n_buffers)
sll srl srl sll sra u16x4 i
uword dpdk_input_rss(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *f)
#define rte_mbuf_from_vlib_buffer(x)
static int vlib_buffer_is_mpls(vlib_buffer_t *b)
static u32 vlib_get_trace_count(vlib_main_t *vm, vlib_node_runtime_t *rt)
void dpdk_efd_update_counters(dpdk_device_t *xd, u32 n_buffers, u16 enabled)
static vlib_main_t * vlib_get_main(void)
static u32 dpdk_rx_burst(dpdk_main_t *dm, dpdk_device_t *xd, u16 queue_id)
#define VLIB_EFD_DISCARD_ENABLED
#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b)
u32 vhost_coalesce_frames
void dpdk_set_next_node(dpdk_rx_next_t next, char *name)
#define foreach_dpdk_error
static f64 vlib_time_now(vlib_main_t *vm)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
static u64 clib_cpu_time_now(void)
struct _vlib_node_registration vlib_node_registration_t
#define BUFFER_HANDOFF_NEXT_VALID
vlib_buffer_main_t * buffer_main
u32 per_interface_next_index
static int dpdk_mbuf_is_ip6(struct rte_mbuf *mb)
static void poll_rate_limit(dpdk_main_t *dm)
static char * dpdk_error_strings[]
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
static u32 dpdk_device_input(dpdk_main_t *dm, dpdk_device_t *xd, vlib_node_runtime_t *node, u32 cpu_index, u16 queue_id, int use_efd)
static void vlib_trace_buffer(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, vlib_buffer_t *b, int follow_chain)
static void vlib_buffer_init_for_free_list(vlib_buffer_t *_dst, vlib_buffer_free_list_t *fl)
vnet_main_t * vnet_get_main(void)
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
static int dpdk_mbuf_is_ip4(struct rte_mbuf *mb)
void efd_config(u32 enabled, u32 ip_prec, u32 ip_op, u32 mpls_exp, u32 mpls_op, u32 vlan_cos, u32 vlan_op)
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
u8 pre_data[VLIB_BUFFER_PRE_DATA_SIZE]
Space for inserting data before buffer start.
#define clib_warning(format, args...)
vlib_node_registration_t dpdk_input_node
(constructor) VLIB_REGISTER_NODE (dpdk_input_node)
#define VMWARE_LENGTH_BUG_WORKAROUND
static u32 vlib_get_buffer_index(vlib_main_t *vm, void *p)
Translate buffer pointer into buffer index.
#define VLIB_BUFFER_NEXT_PRESENT
vlib_node_registration_t handoff_dispatch_node
(constructor) VLIB_REGISTER_NODE (handoff_dispatch_node)
u16 consec_full_frames_hi_thresh
format_function_t format_dpdk_rx_dma_trace
u16 current_length
Nbytes between current data and the end of this buffer.
dpdk_device_and_queue_t ** devices_by_cpu
static_always_inline void increment_efd_drop_counter(vlib_main_t *vm, u32 counter_index, u32 count)
u32 consec_full_frames_cnt
#define DPDK_EFD_DISCARD_ENABLED
uword os_get_cpu_number(void)
unsigned short int uint16_t
#define DPDK_EFD_MONITOR_ENABLED
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
vlib_error_t error
Error code for buffers to be enqueued to error handler.
u8 * format_ethernet_header_with_length(u8 *s, va_list *args)
struct rte_mempool ** pktmbuf_pools
#define CLIB_PREFETCH(addr, size, type)
static vlib_thread_main_t * vlib_get_thread_main()
struct rte_mbuf *** rx_vectors
#define clib_memcpy(a, b, c)
#define VLIB_NODE_FUNCTION_MULTIARCH_CLONE(fn)
#define EFD_OPERATION_GREATER_OR_EQUAL
#define VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX
static void vlib_increment_combined_counter(vlib_combined_counter_main_t *cm, u32 cpu_index, u32 index, u32 packet_increment, u32 byte_increment)
Increment a combined counter.
static void dpdk_rx_next_and_error_from_mb_flags_x1(dpdk_device_t *xd, struct rte_mbuf *mb, vlib_buffer_t *b0, u8 *next0, u8 *error0)
u32 next_buffer
Next buffer for this linked-list of buffers.
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
u32 total_length_not_including_first_buffer
Only valid for first buffer in chain.
template key/value backing page structure
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
dpdk_device_type_t dev_type
dpdk_efd_agent_t efd_agent
#define DPDK_EFD_DROPALL_ENABLED
u32 buffer_flags_template
#define VLIB_REGISTER_NODE(x,...)
#define vlib_buffer_from_rte_mbuf(x)
#define vec_foreach(var, vec)
Vector iterator.
#define EFD_OPERATION_LESS_THAN
static vlib_buffer_free_list_t * vlib_buffer_get_free_list(vlib_main_t *vm, u32 free_list_index)
static void vlib_set_trace_count(vlib_main_t *vm, vlib_node_runtime_t *rt, u32 count)
u32 is_efd_discardable(vlib_thread_main_t *tm, vlib_buffer_t *b0, struct rte_mbuf *mb)
#define CLIB_CACHE_LINE_BYTES
CLIB_MULTIARCH_SELECT_FN(dpdk_input)
u32 flags
buffer flags: VLIB_BUFFER_IS_TRACED: trace this buffer.
static uword dpdk_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *f)
Main DPDK input node.
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
uword dpdk_input_efd(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *f)
CLIB vectors are ubiquitous dynamically resized arrays with by user defined "headers".
dpdk_config_main_t * conf
void set_efd_bitmap(u8 *bitmap, u32 value, u32 op)