net/pcap: create null Rx function
Checks
Commit Message
Previously in the PCAP PMD it was only possibe to specify an rxq which
uses an iface or a pcap file. This patch creates a 'dummy Rx' function
which is used when no rx_pcap or rx_iface is passed but a tx queue is
passed. This function can be polled and receives no packets.
Signed-off-by: A.McLoughlin <aideen.mcloughlin@intel.com>
---
drivers/net/pcap/rte_eth_pcap.c | 64 ++++++++++++++++++++++++---------
1 file changed, 48 insertions(+), 16 deletions(-)
Comments
On 7/16/2019 10:34 AM, A.McLoughlin wrote:
> Previously in the PCAP PMD it was only possibe to specify an rxq which
> uses an iface or a pcap file. This patch creates a 'dummy Rx' function
> which is used when no rx_pcap or rx_iface is passed but a tx queue is
> passed. This function can be polled and receives no packets.
+1 to the feature, thanks.
So user doesn't have to provide both "rx" and "tx" queue anymore, user can only
provide "tx" queue if the intention is just capture Tx packets.
>
> Signed-off-by: A.McLoughlin <aideen.mcloughlin@intel.com>
> ---
> drivers/net/pcap/rte_eth_pcap.c | 64 ++++++++++++++++++++++++---------
Can you please update documentation too, 'pcap_ring.rst' to document new
behavior and release notes to announce the feature briefly?
<...>
> + /* Creating a dummy rx queue for each tx queue passed */
> + for (i = 0; i < num_tx_queues; i++)
> + ret =
> + add_queue(&pcaps, "dummy_rx", "rx_null", NULL, NULL);
Please fix the syntax.
> + } else {
> + PMD_LOG(ERR, "Error - No rx or tx queues provided");
> + exit(0);
We are not allowed to exit/abort in drivers, that is application's discretion,
can you please return error in this case, please remember the cleanup before return.
@@ -112,6 +112,8 @@ struct pmd_devargs_all {
int single_iface;
unsigned int is_tx_pcap;
unsigned int is_tx_iface;
+ unsigned int is_rx_pcap;
+ unsigned int is_rx_iface;
unsigned int infinite_rx;
};
@@ -295,6 +297,14 @@ eth_pcap_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
return num_rx;
}
+static uint16_t
+eth_null_rx(void *queue __rte_unused,
+ struct rte_mbuf **bufs __rte_unused,
+ uint16_t nb_pkts __rte_unused)
+{
+ return 0;
+}
+
static inline void
calculate_timestamp(struct timeval *ts) {
uint64_t cycles;
@@ -1316,8 +1326,10 @@ eth_from_pcaps(struct rte_vdev_device *vdev,
/* Assign rx ops. */
if (infinite_rx)
eth_dev->rx_pkt_burst = eth_pcap_rx_infinite;
- else
+ else if (devargs_all->is_rx_pcap || devargs_all->is_rx_iface)
eth_dev->rx_pkt_burst = eth_pcap_rx;
+ else
+ eth_dev->rx_pkt_burst = eth_null_rx;
/* Assign tx ops. */
if (devargs_all->is_tx_pcap)
@@ -1335,13 +1347,12 @@ static int
pmd_pcap_probe(struct rte_vdev_device *dev)
{
const char *name;
- unsigned int is_rx_pcap = 0;
struct rte_kvargs *kvlist;
struct pmd_devargs pcaps = {0};
struct pmd_devargs dumpers = {0};
struct rte_eth_dev *eth_dev = NULL;
struct pmd_internals *internal;
- int ret;
+ int ret = 0;
struct pmd_devargs_all devargs_all = {
.single_iface = 0,
@@ -1404,13 +1415,22 @@ pmd_pcap_probe(struct rte_vdev_device *dev)
}
/*
- * We check whether we want to open a RX stream from a real NIC or a
- * pcap file
+ * We check whether we want to open a RX stream from a real NIC, a
+ * pcap file or open a dummy RX stream
*/
- is_rx_pcap = rte_kvargs_count(kvlist, ETH_PCAP_RX_PCAP_ARG) ? 1 : 0;
+ devargs_all.is_rx_pcap =
+ rte_kvargs_count(kvlist, ETH_PCAP_RX_PCAP_ARG) ? 1 : 0;
+ devargs_all.is_rx_iface =
+ rte_kvargs_count(kvlist, ETH_PCAP_RX_IFACE_ARG) ? 1 : 0;
pcaps.num_of_queue = 0;
- if (is_rx_pcap) {
+ devargs_all.is_tx_pcap =
+ rte_kvargs_count(kvlist, ETH_PCAP_TX_PCAP_ARG) ? 1 : 0;
+ devargs_all.is_tx_iface =
+ rte_kvargs_count(kvlist, ETH_PCAP_TX_IFACE_ARG) ? 1 : 0;
+ dumpers.num_of_queue = 0;
+
+ if (devargs_all.is_rx_pcap) {
/*
* We check whether we want to infinitely rx the pcap file.
*/
@@ -1436,11 +1456,29 @@ pmd_pcap_probe(struct rte_vdev_device *dev)
ret = rte_kvargs_process(kvlist, ETH_PCAP_RX_PCAP_ARG,
&open_rx_pcap, &pcaps);
- } else {
+ } else if (devargs_all.is_rx_iface) {
ret = rte_kvargs_process(kvlist, NULL,
&rx_iface_args_process, &pcaps);
- }
+ } else if (devargs_all.is_tx_iface || devargs_all.is_tx_pcap) {
+ unsigned int i;
+ /* Count number of tx queue args passed before dummy rx queue
+ * creation so a dummy rx queue can be created for each tx queue
+ */
+ unsigned int num_tx_queues =
+ (rte_kvargs_count(kvlist, ETH_PCAP_TX_PCAP_ARG) +
+ rte_kvargs_count(kvlist, ETH_PCAP_TX_IFACE_ARG));
+
+ PMD_LOG(INFO, "Creating null rx queue since no rx queues were provided.");
+
+ /* Creating a dummy rx queue for each tx queue passed */
+ for (i = 0; i < num_tx_queues; i++)
+ ret =
+ add_queue(&pcaps, "dummy_rx", "rx_null", NULL, NULL);
+ } else {
+ PMD_LOG(ERR, "Error - No rx or tx queues provided");
+ exit(0);
+ }
if (ret < 0)
goto free_kvlist;
@@ -1448,12 +1486,6 @@ pmd_pcap_probe(struct rte_vdev_device *dev)
* We check whether we want to open a TX stream to a real NIC,
* a pcap file, or drop packets on tx
*/
- devargs_all.is_tx_pcap =
- rte_kvargs_count(kvlist, ETH_PCAP_TX_PCAP_ARG) ? 1 : 0;
- devargs_all.is_tx_iface =
- rte_kvargs_count(kvlist, ETH_PCAP_TX_IFACE_ARG) ? 1 : 0;
- dumpers.num_of_queue = 0;
-
if (devargs_all.is_tx_pcap) {
ret = rte_kvargs_process(kvlist, ETH_PCAP_TX_PCAP_ARG,
&open_tx_pcap, &dumpers);
@@ -1467,7 +1499,7 @@ pmd_pcap_probe(struct rte_vdev_device *dev)
/* Add 1 dummy queue per rxq which counts and drops packets. */
for (i = 0; i < pcaps.num_of_queue; i++)
- ret = add_queue(&dumpers, "dummy", "tx_drop", NULL,
+ ret = add_queue(&dumpers, "dummy_tx", "tx_drop", NULL,
NULL);
}