+ optind = 1; /* reset getopt lib */
+ return 0;
+}
+
+/*
+ * Tx buffer error callback
+ */
+static void
+flush_tx_error_callback(struct rte_mbuf **unsent, uint16_t count,
+ void *userdata __rte_unused) {
+
+ /* free the mbufs which failed from transmit */
+ app_stats.tx.ro_tx_failed_pkts += count;
+ RTE_LOG_DP(DEBUG, REORDERAPP, "%s:Packet loss with tx_burst\n", __func__);
+ pktmbuf_free_bulk(unsent, count);
+
+}
+
+static inline int
+free_tx_buffers(struct rte_eth_dev_tx_buffer *tx_buffer[]) {
+ const uint8_t nb_ports = rte_eth_dev_count();
+ unsigned port_id;
+
+ /* initialize buffers for all ports */
+ for (port_id = 0; port_id < nb_ports; port_id++) {
+ /* skip ports that are not enabled */
+ if ((portmask & (1 << port_id)) == 0)
+ continue;
+
+ rte_free(tx_buffer[port_id]);
+ }
+ return 0;
+}
+
+static inline int
+configure_tx_buffers(struct rte_eth_dev_tx_buffer *tx_buffer[])
+{
+ const uint8_t nb_ports = rte_eth_dev_count();
+ unsigned port_id;
+ int ret;
+
+ /* initialize buffers for all ports */
+ for (port_id = 0; port_id < nb_ports; port_id++) {
+ /* skip ports that are not enabled */
+ if ((portmask & (1 << port_id)) == 0)
+ continue;
+
+ /* Initialize TX buffers */
+ tx_buffer[port_id] = rte_zmalloc_socket("tx_buffer",
+ RTE_ETH_TX_BUFFER_SIZE(MAX_PKTS_BURST), 0,
+ rte_eth_dev_socket_id(port_id));
+ if (tx_buffer[port_id] == NULL)
+ rte_exit(EXIT_FAILURE, "Cannot allocate buffer for tx on port %u\n",
+ port_id);
+
+ rte_eth_tx_buffer_init(tx_buffer[port_id], MAX_PKTS_BURST);
+
+ ret = rte_eth_tx_buffer_set_err_callback(tx_buffer[port_id],
+ flush_tx_error_callback, NULL);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE,
+ "Cannot set error callback for tx buffer on port %u\n",
+ port_id);
+ }