+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
+ *
+ * Allocate and set up a transmit hairpin queue for an Ethernet device.
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @param tx_queue_id
+ * The index of the transmit queue to set up.
+ * The value must be in the range [0, nb_tx_queue - 1] previously supplied
+ * to rte_eth_dev_configure().
+ * @param nb_tx_desc
+ * The number of transmit descriptors to allocate for the transmit ring.
+ * 0 to set default PMD value.
+ * @param conf
+ * The hairpin configuration.
+ *
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if *port_id* is invalid.
+ * - (-ENOTSUP) if hardware doesn't support.
+ * - (-EINVAL) if bad parameter.
+ * - (-ENOMEM) if unable to allocate the resources.
+ */
+__rte_experimental
+int rte_eth_tx_hairpin_queue_setup
+ (uint16_t port_id, uint16_t tx_queue_id, uint16_t nb_tx_desc,
+ const struct rte_eth_hairpin_conf *conf);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
+ *
+ * Get all the hairpin peer Rx / Tx ports of the current port.
+ * The caller should ensure that the array is large enough to save the ports
+ * list.
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @param peer_ports
+ * Pointer to the array to store the peer ports list.
+ * @param len
+ * Length of the array to store the port identifiers.
+ * @param direction
+ * Current port to peer port direction
+ * positive - current used as Tx to get all peer Rx ports.
+ * zero - current used as Rx to get all peer Tx ports.
+ *
+ * @return
+ * - (0 or positive) actual peer ports number.
+ * - (-EINVAL) if bad parameter.
+ * - (-ENODEV) if *port_id* invalid
+ * - (-ENOTSUP) if hardware doesn't support.
+ * - Others detailed errors from PMD drivers.
+ */
+__rte_experimental
+int rte_eth_hairpin_get_peer_ports(uint16_t port_id, uint16_t *peer_ports,
+ size_t len, uint32_t direction);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
+ *
+ * Bind all hairpin Tx queues of one port to the Rx queues of the peer port.
+ * It is only allowed to call this function after all hairpin queues are
+ * configured properly and the devices are in started state.
+ *
+ * @param tx_port
+ * The identifier of the Tx port.
+ * @param rx_port
+ * The identifier of peer Rx port.
+ * RTE_MAX_ETHPORTS is allowed for the traversal of all devices.
+ * Rx port ID could have the same value as Tx port ID.
+ *
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if Tx port ID is invalid.
+ * - (-EBUSY) if device is not in started state.
+ * - (-ENOTSUP) if hardware doesn't support.
+ * - Others detailed errors from PMD drivers.
+ */
+__rte_experimental
+int rte_eth_hairpin_bind(uint16_t tx_port, uint16_t rx_port);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
+ *
+ * Unbind all hairpin Tx queues of one port from the Rx queues of the peer port.
+ * This should be called before closing the Tx or Rx devices, if the bind
+ * function is called before.
+ * After unbinding the hairpin ports pair, it is allowed to bind them again.
+ * Changing queues configuration should be after stopping the device(s).
+ *
+ * @param tx_port
+ * The identifier of the Tx port.
+ * @param rx_port
+ * The identifier of peer Rx port.
+ * RTE_MAX_ETHPORTS is allowed for traversal of all devices.
+ * Rx port ID could have the same value as Tx port ID.
+ *
+ * @return
+ * - (0) if successful.
+ * - (-ENODEV) if Tx port ID is invalid.
+ * - (-EBUSY) if device is in stopped state.
+ * - (-ENOTSUP) if hardware doesn't support.
+ * - Others detailed errors from PMD drivers.
+ */
+__rte_experimental
+int rte_eth_hairpin_unbind(uint16_t tx_port, uint16_t rx_port);
+