44 #define NS_PER_SEC 1E9
45 #define STATS_MAX_BUFF_SIZE 1024
72 .dev1_stats.rx_dropped = 0,
73 .dev1_stats.total_tx_pkts = 0,
74 .dev2_stats.rx_pkts = 0,
75 .dev2_stats.rx_dropped = 0,
76 .dev2_stats.total_tx_pkts = 0};
88 static uint64_t prev_total_rx_pkts_dev1 = 0;
89 static uint64_t prev_total_rx_pkts_dev2 = 0;
90 static uint64_t prev_total_tx_pkts_dev1 = 0;
91 static uint64_t prev_total_tx_pkts_dev2 = 0;
92 static uint64_t prev_time_ns = 0;
95 char *buff_cursor = buff;
96 int curr_buff_offset = 0;
98 if (clock_gettime(CLOCK_REALTIME, &t) != 0) {
99 DOCA_LOG_ERR(
"Failed to show statistics: Failed to get time specification with clock_gettime()");
103 if (prev_time_ns == 0)
106 uint64_t curr_time_ns = (uint64_t)t.tv_nsec + (uint64_t)t.tv_sec *
NS_PER_SEC;
107 uint64_t diff_ns = curr_time_ns - prev_time_ns;
110 uint64_t dev1_diff_total_pkts_rx = dev1_total_rx_pkts - prev_total_rx_pkts_dev1;
114 uint64_t dev2_diff_total_pkts_rx = dev2_total_rx_pkts - prev_total_rx_pkts_dev2;
117 uint64_t dev1_rx_pps = ((double)(dev1_diff_total_pkts_rx) / diff_ns) *
NS_PER_SEC;
118 uint64_t dev1_tx_pps = ((double)(dev1_diff_pkts_tx) / diff_ns) *
NS_PER_SEC;
120 uint64_t dev2_rx_pps = ((double)(dev2_diff_total_pkts_rx) / diff_ns) *
NS_PER_SEC;
121 uint64_t dev2_tx_pps = ((double)(dev2_diff_pkts_tx) / diff_ns) *
NS_PER_SEC;
123 curr_buff_offset += snprintf(
126 "\n**************************** Forward statistics for device 1 *****************************\n");
127 curr_buff_offset += snprintf(buff_cursor + curr_buff_offset,
128 buff_size - curr_buff_offset,
129 "RX-packets: %-17" PRIu64
" RX-SW-dropped: %-17" PRIu64
" RX-total: %-17" PRIu64
134 curr_buff_offset += snprintf(buff_cursor + curr_buff_offset,
135 buff_size - curr_buff_offset,
136 "TX-packets: %-" PRIu64
"\n",
138 curr_buff_offset += snprintf(buff_cursor + curr_buff_offset,
139 buff_size - curr_buff_offset,
140 "\nThroughput (since last call)\n");
141 curr_buff_offset += snprintf(buff_cursor + curr_buff_offset,
142 buff_size - curr_buff_offset,
143 "RX-pps: %-" PRIu64
"\n",
145 curr_buff_offset += snprintf(buff_cursor + curr_buff_offset,
146 buff_size - curr_buff_offset,
147 "TX-pps: %-" PRIu64
"\n",
149 curr_buff_offset += snprintf(
150 buff_cursor + curr_buff_offset,
151 buff_size - curr_buff_offset,
152 "******************************************************************************************\n");
154 curr_buff_offset += snprintf(
155 buff_cursor + curr_buff_offset,
156 buff_size - curr_buff_offset,
157 "\n**************************** Forward statistics for device 2 *****************************\n");
158 curr_buff_offset += snprintf(buff_cursor + curr_buff_offset,
159 buff_size - curr_buff_offset,
160 "RX-packets: %-17" PRIu64
" RX-SW-dropped: %-17" PRIu64
" RX-total: %-17" PRIu64
165 curr_buff_offset += snprintf(buff_cursor + curr_buff_offset,
166 buff_size - curr_buff_offset,
167 "TX-packets: %-" PRIu64
"\n",
169 curr_buff_offset += snprintf(buff_cursor + curr_buff_offset,
170 buff_size - curr_buff_offset,
171 "\nThroughput (since last call)\n");
172 curr_buff_offset += snprintf(buff_cursor + curr_buff_offset,
173 buff_size - curr_buff_offset,
174 "RX-pps: %-" PRIu64
"\n",
176 curr_buff_offset += snprintf(buff_cursor + curr_buff_offset,
177 buff_size - curr_buff_offset,
178 "TX-pps: %-" PRIu64
"\n",
180 snprintf(buff_cursor + curr_buff_offset,
181 buff_size - curr_buff_offset,
182 "******************************************************************************************");
186 prev_total_rx_pkts_dev1 = dev1_total_rx_pkts;
189 prev_total_rx_pkts_dev2 = dev2_total_rx_pkts;
192 prev_time_ns = curr_time_ns;
234 DOCA_LOG_ERR(
"Failed to allocate memory for mmap's buffer");
292 static void rx_success_cb1(
struct doca_eth_rxq_event_batch_managed_recv *event_batch_managed_recv,
293 uint16_t events_number,
296 struct doca_buf **pkt_array)
300 (void)event_batch_managed_recv;
303 struct doca_eth_txq *eth_txq = (
struct doca_eth_txq *)(event_batch_user_data.
ptr);
305 struct doca_buf **batch_pkt_array;
307 struct doca_task_batch *task_batch_send;
309 send_task_data.
ptr = pkt_array;
315 &task_user_data_array,
323 memcpy(batch_pkt_array, pkt_array,
sizeof(
struct doca_buf *) * events_number);
342 static void rx_success_cb2(
struct doca_eth_rxq_event_batch_managed_recv *event_batch_managed_recv,
343 uint16_t events_number,
346 struct doca_buf **pkt_array)
350 (void)event_batch_managed_recv;
353 struct doca_eth_txq *eth_txq = (
struct doca_eth_txq *)(event_batch_user_data.
ptr);
355 struct doca_buf **batch_pkt_array;
357 struct doca_task_batch *task_batch_send;
359 send_task_data.
ptr = pkt_array;
365 &task_user_data_array,
373 memcpy(batch_pkt_array, pkt_array,
sizeof(
struct doca_buf *) * events_number);
392 static void rx_error_cb(
struct doca_eth_rxq_event_batch_managed_recv *event_batch_managed_recv,
393 uint16_t events_number,
396 struct doca_buf **pkt_array)
401 (void)event_batch_managed_recv;
403 struct doca_eth_txq *eth_txq = (
struct doca_eth_txq *)(event_batch_user_data.
ptr);
431 struct doca_buf **pkt_array,
437 (void)task_user_data_array;
441 struct doca_buf **pkt_array_handle = (
struct doca_buf **)task_batch_user_data.
ptr;
466 struct doca_buf **pkt_array,
472 (void)task_user_data_array;
476 struct doca_buf **pkt_array_handle = (
struct doca_buf **)task_batch_user_data.
ptr;
501 struct doca_buf **pkt_array,
507 (void)task_user_data_array;
519 struct doca_buf **pkt_array_handle = (
struct doca_buf **)task_batch_user_data.
ptr;
545 uint32_t max_burst_size, max_pkt_size;
553 if (max_burst_size < cfg->max_burst_size) {
554 DOCA_LOG_ERR(
"Failed to create ETH RXQ context: max burst size to set is to big");
564 if (max_pkt_size < cfg->max_pkt_size) {
565 DOCA_LOG_ERR(
"Failed to create ETH RXQ context: max packet size to set is to big");
590 user_data.
ptr = data;
604 DOCA_LOG_ERR(
"Failed to retrieve DOCA ETH RXQ context as DOCA context: %s",
645 uint32_t max_burst_size;
653 if (max_burst_size < cfg->max_burst_size) {
654 DOCA_LOG_ERR(
"Failed to create ETH TXQ context: max burst size to set is to big");
672 cfg->num_task_batches,
682 DOCA_LOG_ERR(
"Failed to retrieve DOCA ETH TXQ context as DOCA context: %s",
712 if (clock_gettime(CLOCK_REALTIME, &t) != 0) {
713 DOCA_LOG_ERR(
"Failed to get time specification with clock_gettime()");
742 strlen(
cfg->mlxdev_name1),
746 DOCA_LOG_ERR(
"Failed to open the first device based on IB device name: %s",
cfg->mlxdev_name1);
751 strlen(
cfg->mlxdev_name2),
755 DOCA_LOG_ERR(
"Failed to open the second device based on IB device name: %s",
cfg->mlxdev_name2);
765 uint32_t recommended_size;
768 cfg->pkt_max_process_time,
781 if (
cfg->one_sided_fwd == 0 ||
cfg->one_sided_fwd == 1) {
791 DOCA_LOG_ERR(
"Failed to initialize DOCA flow port for device 1: %s",
798 DOCA_LOG_ERR(
"Failed to initialize ETH TXQ context for device 2: %s",
811 DOCA_LOG_ERR(
"Failed to initialize ETH RXQ context for device 1: %s",
822 DOCA_LOG_ERR(
"Failed to allocate ETH RXQ flow resources for device 1: %s",
829 if (
cfg->one_sided_fwd == 0 ||
cfg->one_sided_fwd == 2) {
839 DOCA_LOG_ERR(
"Failed to initialize DOCA flow port for device 2: %s",
846 DOCA_LOG_ERR(
"Failed to initialize ETH TXQ context for device 1: %s",
859 DOCA_LOG_ERR(
"Failed to initialize ETH RXQ context for device 2: %s",
870 DOCA_LOG_ERR(
"Failed to allocate ETH RXQ flow resources for device 2: %s",
882 DOCA_LOG_INFO(
"Ethernet L2 Forwarding Application execution finished successfully");
895 uint8_t num_ctx_in_progress = 0;
922 ++num_ctx_in_progress;
933 ++num_ctx_in_progress;
944 ++num_ctx_in_progress;
955 ++num_ctx_in_progress;
964 while (num_ctx_in_progress > 0) {
970 DOCA_LOG_ERR(
"Failed get status of ETH RXQ DOCA CTX for device 1: %s",
977 --num_ctx_in_progress;
984 DOCA_LOG_ERR(
"Failed get status of ETH RXQ DOCA CTX for device 2: %s",
991 --num_ctx_in_progress;
998 DOCA_LOG_ERR(
"Failed get status of ETH TXQ DOCA CTX for device 1: %s",
1005 --num_ctx_in_progress;
1012 DOCA_LOG_ERR(
"Failed get status of ETH TXQ DOCA CTX for device 2: %s",
1019 --num_ctx_in_progress;
1104 DOCA_LOG_INFO(
"Ethernet L2 Forwarding Application resources cleanup finished successfully");
doca_error_t open_doca_device_with_ibdev_name(const uint8_t *value, size_t val_size, tasks_check func, struct doca_dev **retval)
static bool force_app_stop
doca_error_t eth_l2_fwd_cleanup(struct eth_l2_fwd_resources *state)
static void eth_l2_fwd_show_stats(void)
static doca_error_t check_device_caps(struct doca_devinfo *devinfo)
static struct eth_l2_fwd_stats stats
static doca_error_t forward_pkts(struct doca_pe *pe)
DOCA_LOG_REGISTER(ETH_L2_FWD :Core)
static void rx_success_cb1(struct doca_eth_rxq_event_batch_managed_recv *event_batch_managed_recv, uint16_t events_number, union doca_data event_batch_user_data, doca_error_t status, struct doca_buf **pkt_array)
#define STATS_MAX_BUFF_SIZE
doca_error_t eth_l2_fwd_execute(struct eth_l2_fwd_cfg *cfg, struct eth_l2_fwd_resources *state)
static doca_error_t init_eth_txq_ctx(struct eth_l2_fwd_cfg *cfg, struct eth_l2_fwd_dev_resources *dev_resrc, struct doca_pe *pe, doca_eth_txq_task_batch_send_completion_cb_t tx_success_cb)
static void rx_error_cb(struct doca_eth_rxq_event_batch_managed_recv *event_batch_managed_recv, uint16_t events_number, union doca_data event_batch_user_data, doca_error_t status, struct doca_buf **pkt_array)
static void rx_success_cb2(struct doca_eth_rxq_event_batch_managed_recv *event_batch_managed_recv, uint16_t events_number, union doca_data event_batch_user_data, doca_error_t status, struct doca_buf **pkt_array)
static void tx_success_cb2(struct doca_task_batch *task_batch, uint16_t tasks_num, union doca_data ctx_user_data, union doca_data task_batch_user_data, union doca_data *task_user_data_array, struct doca_buf **pkt_array, doca_error_t *status_array)
static uint32_t total_forwardings
static doca_error_t create_mmap(struct doca_dev *dev1, struct doca_dev *dev2, struct mmap_resources *mmap_res)
static void tx_success_cb1(struct doca_task_batch *task_batch, uint16_t tasks_num, union doca_data ctx_user_data, union doca_data task_batch_user_data, union doca_data *task_user_data_array, struct doca_buf **pkt_array, doca_error_t *status_array)
void eth_l2_fwd_force_stop(void)
static void tx_error_cb(struct doca_task_batch *task_batch, uint16_t tasks_num, union doca_data ctx_user_data, union doca_data task_batch_user_data, union doca_data *task_user_data_array, struct doca_buf **pkt_array, doca_error_t *status_array)
static doca_error_t init_eth_rxq_ctx(struct eth_l2_fwd_cfg *cfg, struct eth_l2_fwd_dev_resources *dev_resrc, struct doca_pe *pe, doca_eth_rxq_event_batch_managed_recv_handler_cb_t rx_success_cb, void *data)
#define ETH_L2_FWD_LOG_MAX_LRO_DEFAULT
doca_error_t allocate_eth_rxq_flow_resources(struct eth_rxq_flow_config *cfg, struct eth_rxq_flow_resources *resources)
doca_error_t rxq_common_init_doca_flow(struct doca_dev *dev, struct eth_rxq_flow_resources *resources)
static struct doca_pe * pe
DOCA_STABLE doca_error_t doca_ctx_start(struct doca_ctx *ctx)
Finalizes all configurations, and starts the DOCA CTX.
DOCA_STABLE doca_error_t doca_ctx_get_state(const struct doca_ctx *ctx, enum doca_ctx_states *state)
Get context state.
DOCA_STABLE doca_error_t doca_ctx_stop(struct doca_ctx *ctx)
Stops the context allowing reconfiguration.
doca_ctx_states
This enum defines the states of a context.
@ DOCA_CTX_STATE_STOPPING
DOCA_STABLE struct doca_devinfo * doca_dev_as_devinfo(const struct doca_dev *dev)
Get local device info from device. This should be useful when wanting to query information about devi...
DOCA_STABLE doca_error_t doca_dev_close(struct doca_dev *dev)
Destroy allocated local device instance.
enum doca_error doca_error_t
DOCA API return codes.
DOCA_STABLE const char * doca_error_get_name(doca_error_t error)
Returns the string representation of an error code name.
DOCA_STABLE const char * doca_error_get_descr(doca_error_t error)
Returns the description string of an error code.
DOCA_EXPERIMENTAL void doca_eth_rxq_event_batch_managed_recv_pkt_array_free(struct doca_buf **pkt_array)
This method frees the packet array acquired using managed receive event batch and returns it to the o...
void(* doca_eth_rxq_event_batch_managed_recv_handler_cb_t)(struct doca_eth_rxq_event_batch_managed_recv *event_batch_managed_recv, uint16_t events_number, union doca_data event_batch_user_data, doca_error_t status, struct doca_buf **pkt_array)
Function to be executed on managed receive event batch occurrence.
DOCA_EXPERIMENTAL doca_error_t doca_eth_rxq_event_batch_managed_recv_register(struct doca_eth_rxq *eth_rxq, enum doca_event_batch_events_number events_number_max, enum doca_event_batch_events_number events_number_min, union doca_data user_data, doca_eth_rxq_event_batch_managed_recv_handler_cb_t success_event_batch_handler, doca_eth_rxq_event_batch_managed_recv_handler_cb_t error_event_batch_handler)
This method registers a doca_eth_rxq_event_managed_recv event batch. Allows user to get multiple even...
DOCA_EXPERIMENTAL doca_error_t doca_eth_txq_task_batch_send_set_conf(struct doca_eth_txq *eth_txq, enum doca_task_batch_max_tasks_number max_tasks_number, uint16_t num_task_batches, doca_eth_txq_task_batch_send_completion_cb_t success_completion_cb, doca_eth_txq_task_batch_send_completion_cb_t error_completion_cb)
This method sets the task_batch of send tasks configuration.
DOCA_EXPERIMENTAL doca_error_t doca_eth_txq_task_batch_send_allocate(struct doca_eth_txq *eth_txq, uint16_t tasks_num, union doca_data task_batch_user_data, struct doca_buf ***pkt_array, union doca_data **task_user_data_array, struct doca_task_batch **task_batch)
This method allocates a doca_taskbtach of doca_eth_txq_task_send tasks.
void(* doca_eth_txq_task_batch_send_completion_cb_t)(struct doca_task_batch *task_batch, uint16_t tasks_num, union doca_data ctx_user_data, union doca_data task_batch_user_data, union doca_data *task_user_data_array, struct doca_buf **pkt_array, doca_error_t *status_array)
Function to execute on task_batch completion.
DOCA_EXPERIMENTAL struct doca_ctx * doca_eth_txq_as_doca_ctx(struct doca_eth_txq *eth_txq)
Convert doca_eth_txq instance into a generalized context for use with doca core objects.
DOCA_EXPERIMENTAL doca_error_t doca_eth_txq_cap_get_max_burst_size(const struct doca_devinfo *devinfo, uint32_t max_send_buf_list_len, uint16_t max_lso_header_size, uint32_t *max_burst_size)
Get the maximum burst size supported by the device.
DOCA_EXPERIMENTAL doca_error_t doca_eth_txq_create(struct doca_dev *dev, uint32_t max_burst_size, struct doca_eth_txq **eth_txq)
Create a DOCA ETH TXQ instance.
DOCA_EXPERIMENTAL doca_error_t doca_eth_txq_destroy(struct doca_eth_txq *eth_txq)
Destroy a DOCA ETH TXQ instance.
DOCA_EXPERIMENTAL doca_error_t doca_eth_txq_set_type(struct doca_eth_txq *eth_txq, enum doca_eth_txq_type type)
Set TX queue type property for doca_eth_txq. can only be called before calling doca_ctx_start().
DOCA_EXPERIMENTAL doca_error_t doca_eth_txq_cap_is_type_supported(const struct doca_devinfo *devinfo, enum doca_eth_txq_type type, enum doca_eth_txq_data_path_type data_path_type)
Check if TX queue type is supported.
@ DOCA_ETH_TXQ_DATA_PATH_TYPE_CPU
@ DOCA_ETH_TXQ_TYPE_REGULAR
DOCA_EXPERIMENTAL doca_error_t doca_eth_rxq_get_flow_queue_id(struct doca_eth_rxq *eth_rxq, uint16_t *flow_queue_id)
Get the DPDK queue ID of the doca_eth receive queue. can only be called after calling doca_ctx_start(...
DOCA_EXPERIMENTAL doca_error_t doca_eth_rxq_set_type(struct doca_eth_rxq *eth_rxq, enum doca_eth_rxq_type type)
Set RX queue type property for doca_eth_rxq. can only be called before calling doca_ctx_start().
DOCA_EXPERIMENTAL doca_error_t doca_eth_rxq_destroy(struct doca_eth_rxq *eth_rxq)
Destroy a DOCA ETH RXQ instance.
DOCA_EXPERIMENTAL doca_error_t doca_eth_rxq_cap_is_type_supported(const struct doca_devinfo *devinfo, enum doca_eth_rxq_type type, enum doca_eth_rxq_data_path_type data_path_type)
Check if RX queue type is supported.
DOCA_EXPERIMENTAL struct doca_ctx * doca_eth_rxq_as_doca_ctx(struct doca_eth_rxq *eth_rxq)
Convert doca_eth_rxq instance into a generalized context for use with doca core objects.
DOCA_EXPERIMENTAL doca_error_t doca_eth_rxq_cap_get_max_packet_size(const struct doca_devinfo *devinfo, uint32_t *max_packet_size)
Get the maximum packet size supported by the device.
DOCA_EXPERIMENTAL doca_error_t doca_eth_rxq_create(struct doca_dev *dev, uint32_t max_burst_size, uint32_t max_packet_size, struct doca_eth_rxq **eth_rxq)
Create a DOCA ETH RXQ instance.
DOCA_EXPERIMENTAL doca_error_t doca_eth_rxq_set_pkt_buf(struct doca_eth_rxq *eth_rxq, struct doca_mmap *mmap, uint32_t mmap_offset, uint32_t mmap_len)
Set Eth packet buffer for a doca_eth_rxq. can only be called before calling doca_ctx_start().
DOCA_EXPERIMENTAL doca_error_t doca_eth_rxq_cap_get_max_burst_size(const struct doca_devinfo *devinfo, uint32_t *max_burst_size)
Get the maximum burst size supported by the device.
DOCA_EXPERIMENTAL doca_error_t doca_eth_rxq_estimate_packet_buf_size(enum doca_eth_rxq_type type, uint32_t rate, uint16_t pkt_max_time, uint32_t max_packet_size, uint32_t max_burst_size, uint8_t log_max_lro_pkt_sz, uint16_t head_size, uint16_t tail_size, uint32_t *buf_size)
Get the recommended size for the mmap buffer of a doca_eth_rxq.
@ DOCA_ETH_RXQ_TYPE_MANAGED_MEMPOOL
@ DOCA_ETH_RXQ_DATA_PATH_TYPE_CPU
DOCA_STABLE void doca_flow_pipe_destroy(struct doca_flow_pipe *pipe)
Destroy one pipe.
DOCA_STABLE doca_error_t doca_flow_port_stop(struct doca_flow_port *port)
Stop a doca port.
DOCA_STABLE void doca_flow_destroy(void)
Destroy the doca flow.
#define DOCA_LOG_ERR(format,...)
Generates an ERROR application log message.
#define DOCA_LOG_INFO(format,...)
Generates an INFO application log message.
DOCA_STABLE doca_error_t doca_mmap_set_memrange(struct doca_mmap *mmap, void *addr, size_t len)
Set the memory range of DOCA memory map.
DOCA_STABLE doca_error_t doca_mmap_set_max_num_devices(struct doca_mmap *mmap, uint32_t max_num_devices)
Set a new max number of devices to add to a DOCA Memory Map.
DOCA_STABLE doca_error_t doca_mmap_destroy(struct doca_mmap *mmap)
Destroy DOCA Memory Map structure.
DOCA_STABLE doca_error_t doca_mmap_create(struct doca_mmap **mmap)
Allocates zero size memory map object with default/unset attributes.
DOCA_STABLE doca_error_t doca_mmap_set_permissions(struct doca_mmap *mmap, uint32_t access_mask)
Set access flags of the registered memory.
DOCA_STABLE doca_error_t doca_mmap_start(struct doca_mmap *mmap)
Start DOCA Memory Map.
DOCA_STABLE doca_error_t doca_mmap_add_dev(struct doca_mmap *mmap, struct doca_dev *dev)
Register DOCA memory map on a given device.
DOCA_STABLE doca_error_t doca_pe_destroy(struct doca_pe *pe)
Destroy doca progress engine.
DOCA_STABLE doca_error_t doca_pe_connect_ctx(struct doca_pe *pe, struct doca_ctx *ctx)
This method connects a context to a progress engine.
DOCA_EXPERIMENTAL struct doca_ctx * doca_task_batch_get_ctx(const struct doca_task_batch *task_batch)
Get context from a doca task_batch.
DOCA_EXPERIMENTAL void doca_task_batch_free(struct doca_task_batch *task_batch)
Free a task_batch back to where it was allocated from.
DOCA_STABLE uint8_t doca_pe_progress(struct doca_pe *pe)
Run the progress engine.
DOCA_EXPERIMENTAL doca_error_t doca_task_batch_submit(struct doca_task_batch *task_batch)
Submit a task_batch to a progress engine.
DOCA_STABLE doca_error_t doca_pe_create(struct doca_pe **pe)
Creates DOCA progress engine.
@ DOCA_TASK_BATCH_MAX_TASKS_NUMBER_128
@ DOCA_EVENT_BATCH_EVENTS_NUMBER_128
@ DOCA_ACCESS_FLAG_LOCAL_READ_WRITE
const struct ip_frag_config * cfg
void rx_success_cb(struct doca_rmax_in_stream_event_rx_data *event_rx_data, union doca_data event_user_data)
uint16_t rxq_flow_queue_id
struct doca_eth_txq * eth_txq
struct doca_ctx * eth_rxq_ctx
struct doca_ctx * eth_txq_ctx
struct doca_eth_rxq * eth_rxq
struct mmap_resources mmap_resrc
struct eth_rxq_flow_resources flow_resrc
struct eth_l2_fwd_dev_resources dev_resrc1
struct eth_l2_fwd_dev_resources dev_resrc2
struct eth_l2_fwd_dev_stats dev1_stats
struct eth_l2_fwd_dev_stats dev2_stats
uint16_t * rxq_flow_queue_ids
struct doca_flow_pipe * root_pipe
struct doca_flow_port * df_port
Convenience type for representing opaque data.