Hi,
New in Patch v2:
- Fixes an issue in eth_dev_start/stop where a single interface was
always opened/closed even though pcap files had been selected for rx/tx
streams.
- The link_status was not being properly updated in case of using a
single interface for rx/tx streams.
Nico.
On 2014-10-04 23:24, Nicol?s Pernas Maradei wrote:
> From: Nicol?s Pernas Maradei
>
> librte_pmd_pcap driver was opening the pcap/interfaces only at init
> time and
> closing them only when the port was being stopped. This behaviour would
> cause
> problems (leading to segfault) if the user closed the port 2 times. The
> first
> time the pcap/interfaces would be normally closed but libpcap would
> throw an
> error causing a segfault if the closed pcaps/interfaces were closed
> again.
> This behaviour is solved by re-openning pcaps/interfaces when the port
> is
> started (only if these weren't open already for example at init time).
>
> Signed-off-by: Nicol?s Pernas Maradei
> ---
> lib/librte_pmd_pcap/rte_eth_pcap.c | 271
> +
> 1 file changed, 212 insertions(+), 59 deletions(-)
>
> diff --git a/lib/librte_pmd_pcap/rte_eth_pcap.c
> b/lib/librte_pmd_pcap/rte_eth_pcap.c
> index 19492e8..f12d1e7 100644
> --- a/lib/librte_pmd_pcap/rte_eth_pcap.c
> +++ b/lib/librte_pmd_pcap/rte_eth_pcap.c
> @@ -67,6 +67,8 @@ struct pcap_rx_queue {
> struct rte_mempool *mb_pool;
> volatile unsigned long rx_pkts;
> volatile unsigned long err_pkts;
> + const char *name;
> + const char *type;
> };
>
> struct pcap_tx_queue {
> @@ -74,27 +76,32 @@ struct pcap_tx_queue {
> pcap_t *pcap;
> volatile unsigned long tx_pkts;
> volatile unsigned long err_pkts;
> + const char *name;
> + const char *type;
> };
>
> struct rx_pcaps {
> unsigned num_of_rx;
> pcap_t *pcaps[RTE_PMD_RING_MAX_RX_RINGS];
> + const char *names[RTE_PMD_RING_MAX_RX_RINGS];
> + const char *types[RTE_PMD_RING_MAX_RX_RINGS];
> };
>
> struct tx_pcaps {
> unsigned num_of_tx;
> pcap_dumper_t *dumpers[RTE_PMD_RING_MAX_TX_RINGS];
> pcap_t *pcaps[RTE_PMD_RING_MAX_RX_RINGS];
> + const char *names[RTE_PMD_RING_MAX_RX_RINGS];
> + const char *types[RTE_PMD_RING_MAX_RX_RINGS];
> };
>
> struct pmd_internals {
> + struct pcap_rx_queue rx_queue[RTE_PMD_RING_MAX_RX_RINGS];
> + struct pcap_tx_queue tx_queue[RTE_PMD_RING_MAX_TX_RINGS];
> unsigned nb_rx_queues;
> unsigned nb_tx_queues;
> -
> int if_index;
> -
> - struct pcap_rx_queue rx_queue[RTE_PMD_RING_MAX_RX_RINGS];
> - struct pcap_tx_queue tx_queue[RTE_PMD_RING_MAX_TX_RINGS];
> + int single_iface;
> };
>
> const char *valid_arguments[] = {
> @@ -106,6 +113,10 @@ const char *valid_arguments[] = {
> NULL
> };
>
> +static int open_single_tx_pcap(const char *pcap_filename,
> pcap_dumper_t **dumper);
> +static int open_single_rx_pcap(const char *pcap_filename, pcap_t
> **pcap);
> +static int open_single_iface(const char *iface, pcap_t **pcap);
> +
> static struct ether_addr eth_addr = { .addr_bytes = { 0, 0, 0, 0x1,
> 0x2, 0x3 } };
> static const char *drivername = "Pcap PMD";
> static struct rte_eth_link pmd_link = {
> @@ -258,6 +269,59 @@ eth_pcap_tx(void *queue,
> static int
> eth_dev_start(struct rte_eth_dev *dev)
> {
> + unsigned i;
> + struct pmd_internals *internals = dev->data->dev_private;
> + struct pcap_tx_queue *tx;
> + struct pcap_rx_queue *rx;
> +
> + /* Special iface case. Single pcap is open and shared between tx/rx.
> */
> + if (internals->single_iface) {
> + tx = &internals->tx_queue[0];
> + rx = &internals->rx_queue[0];
> +
> + if (!tx->pcap && strcmp(tx->type, ETH_PCAP_IFACE_ARG) == 0) {
> + if (open_single_iface(tx->name, &tx->pcap) < 0)
> + return -1;
> + rx->pcap = tx->pcap;
> + }
> + goto status_up;
> + }
> +
> + /* If not open already, open tx pcaps/dumpers */
> + for (i = 0; i < internals->nb_tx_queues; i++) {
> + tx = &internals->tx_queue[i];
> +
> + if (!tx->dumper && strcmp(tx->type, ETH_PCAP_TX_PCAP_ARG) == 0)
> {
> + if (open_single_tx_pcap(tx->name, &tx->dumper) < 0)
> + return -1;
> + }
> +
> + else if (!tx->pcap && strcmp(tx->type, ETH_PCAP_TX_IFACE_ARG)
> == 0)
> {
> + if (open_single_iface(tx->name, &tx->pcap) < 0)
> + return -1;
> + }
> + }
> +
> + /* If not open already, open rx pcaps */
> + for (i = 0; i < internals->nb_rx_queues; i++) {
> + rx = &internals->rx_queue[i];
> +
> + if (rx->pcap != NULL)
> + continue;
> +
> + if (strcmp(rx->type, ETH_PCAP_RX_PCAP_ARG) == 0) {
> + if (open_single_rx_pcap(rx->nam