return -errno;
}
}
- ret = rte_flow_dev_dump(port_id, file, &error);
+ ret = rte_flow_dev_dump(port_id, NULL, file, &error);
if (ret) {
port_flow_complain(&error);
printf("Failed to dump flow: %s\n", strerror(-ret));
.. code-block:: console
- testpmd> flow dump <port> <output_file>
+ To dump all flows:
+ testpmd> flow dump <port> all <output_file>
+ and dump one flow:
+ testpmd> flow dump <port> rule <rule_id> <output_file>
- call rte_flow_dev_dump api:
.. code-block:: console
- rte_flow_dev_dump(port, file, NULL);
+ rte_flow_dev_dump(port, flow, file, NULL);
#. Dump human-readable flows from raw file:
.. code-block:: console
- mlx_steering_dump.py -f <output_file>
+ mlx_steering_dump.py -f <output_file> -flowptr <flow_ptr>
* pci: The value ``PCI_ANY_ID`` is marked as deprecated
and can be replaced with ``RTE_PCI_ANY_ID``.
+* ethdev: Added a ``rte_flow`` pointer parameter to the function
+ ``rte_flow_dev_dump()`` allowing dump for single flow.
+
* cryptodev: The experimental raw data path API for dequeue
``rte_cryptodev_raw_dequeue_burst`` got a new parameter
``max_nb_to_dequeue`` to provide flexible control on dequeue.
}
/* Dump flow. */
dev = &rte_eth_devices[port_id];
- ret = mlx5_flow_dev_dump(dev, file, NULL);
+ ret = mlx5_flow_dev_dump(dev, NULL, file, NULL);
/* Set-up the ancillary data and reply. */
msg.msg_controllen = 0;
msg.msg_control = NULL;
void mlx5_counter_free(struct rte_eth_dev *dev, uint32_t cnt);
int mlx5_counter_query(struct rte_eth_dev *dev, uint32_t cnt,
bool clear, uint64_t *pkts, uint64_t *bytes);
-int mlx5_flow_dev_dump(struct rte_eth_dev *dev, FILE *file,
- struct rte_flow_error *error);
+int mlx5_flow_dev_dump(struct rte_eth_dev *dev, struct rte_flow *flow,
+ FILE *file, struct rte_flow_error *error);
void mlx5_flow_rxq_dynf_metadata_set(struct rte_eth_dev *dev);
int mlx5_flow_get_aged_flows(struct rte_eth_dev *dev, void **contexts,
uint32_t nb_contexts, struct rte_flow_error *error);
* 0 on success, a nagative value otherwise.
*/
int
-mlx5_flow_dev_dump(struct rte_eth_dev *dev,
+mlx5_flow_dev_dump(struct rte_eth_dev *dev, struct rte_flow *flow_idx,
FILE *file,
struct rte_flow_error *error __rte_unused)
{
return -errno;
return -ENOTSUP;
}
- return mlx5_devx_cmd_flow_dump(sh->fdb_domain, sh->rx_domain,
- sh->tx_domain, file);
+
+ if (!flow_idx)
+ return mlx5_devx_cmd_flow_dump(sh->fdb_domain,
+ sh->rx_domain, sh->tx_domain, file);
+ return -ENOTSUP;
}
/**
static int
otx2_flow_dev_dump(struct rte_eth_dev *dev,
- FILE *file,
+ struct rte_flow *flow, FILE *file,
struct rte_flow_error *error)
{
struct otx2_eth_dev *hw = dev->data->dev_private;
"Invalid file");
return -EINVAL;
}
+ if (flow != NULL) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_HANDLE,
+ NULL,
+ "Invalid argument");
+ return -EINVAL;
+ }
max_prio = hw->npc_flow.flow_max_priority;
}
int
-rte_flow_dev_dump(uint16_t port_id, FILE *file, struct rte_flow_error *error)
+rte_flow_dev_dump(uint16_t port_id, struct rte_flow *flow,
+ FILE *file, struct rte_flow_error *error)
{
struct rte_eth_dev *dev = &rte_eth_devices[port_id];
const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
return -rte_errno;
if (likely(!!ops->dev_dump)) {
fts_enter(dev);
- ret = ops->dev_dump(dev, file, error);
+ ret = ops->dev_dump(dev, flow, file, error);
fts_exit(dev);
return flow_err(port_id, ret, error);
}
*
* @param[in] port_id
* The port identifier of the Ethernet device.
+ * @param[in] flow
+ * The pointer of flow rule to dump. Dump all rules if NULL.
* @param[in] file
* A pointer to a file for output.
* @param[out] error
*/
__rte_experimental
int
-rte_flow_dev_dump(uint16_t port_id, FILE *file, struct rte_flow_error *error);
+rte_flow_dev_dump(uint16_t port_id, struct rte_flow *flow,
+ FILE *file, struct rte_flow_error *error);
/**
* Check if mbuf dynamic field for metadata is registered.
/** See rte_flow_dev_dump(). */
int (*dev_dump)
(struct rte_eth_dev *dev,
+ struct rte_flow *flow,
FILE *file,
struct rte_flow_error *error);
/** See rte_flow_get_aged_flows() */