[PATCH 2/5] drivers/net/pcap: add public api to create pcap device
From: Reshma Pattan <hidden>
Date: 2016-01-29 13:10:58
Subsystem:
networking drivers, the rest · Maintainers:
Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
Added new public api to create pcap device from pcaps. Added new header file for API declaration. Added new public api to version map Signed-off-by: Reshma Pattan <redacted> --- drivers/net/pcap/Makefile | 4 +- drivers/net/pcap/rte_eth_pcap.c | 156 +++++++++++++++++++++++++--- drivers/net/pcap/rte_eth_pcap.h | 87 ++++++++++++++++ drivers/net/pcap/rte_pmd_pcap_version.map | 8 ++ 4 files changed, 236 insertions(+), 19 deletions(-) create mode 100644 drivers/net/pcap/rte_eth_pcap.h
diff --git a/drivers/net/pcap/Makefile b/drivers/net/pcap/Makefile
index b41d8a2..8e424bf 100644
--- a/drivers/net/pcap/Makefile
+++ b/drivers/net/pcap/Makefile@@ -1,6 +1,6 @@ # BSD LICENSE # -# Copyright(c) 2010-2014 Intel Corporation. All rights reserved. +# Copyright(c) 2010-2016 Intel Corporation. All rights reserved. # Copyright(c) 2014 6WIND S.A. # All rights reserved. #
@@ -53,7 +53,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += rte_eth_pcap.c # # Export include files # -SYMLINK-y-include += +SYMLINK-y-include += rte_eth_pcap.h # this lib depends upon: DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += lib/librte_mbuf
diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c
index f9230eb..1da7913 100644
--- a/drivers/net/pcap/rte_eth_pcap.c
+++ b/drivers/net/pcap/rte_eth_pcap.c@@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. * Copyright(c) 2014 6WIND S.A. * All rights reserved. *
@@ -44,7 +44,7 @@ #include <net/if.h> -#include <pcap.h> +#include "rte_eth_pcap.h" #define RTE_ETH_PCAP_SNAPSHOT_LEN 65535 #define RTE_ETH_PCAP_SNAPLEN ETHER_MAX_JUMBO_FRAME_LEN
@@ -85,21 +85,6 @@ struct pcap_tx_queue { char type[ETH_PCAP_ARG_MAXLEN]; }; -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];
@@ -875,6 +860,143 @@ error: return -1; } +int +rte_eth_from_pcapsndumpers(const char *name, + struct rx_pcaps *rx_queues, + const unsigned nb_rx_queues, + struct tx_pcaps *tx_queues, + const unsigned nb_tx_queues, + const unsigned numa_node) +{ + struct rte_eth_dev_data *data = NULL; + struct pmd_internals *internals = NULL; + struct rte_eth_dev *eth_dev = NULL; + unsigned i; + pcap_dumper_t *dumper; + pcap_t *pcap = NULL; + + hz = rte_get_timer_hz(); + /* do some parameter checking */ + if (!rx_queues && nb_rx_queues > 0) + return -1; + if (!tx_queues && nb_tx_queues > 0) + return -1; + + /* initialize rx and tx pcaps */ + for (i = 0; i < nb_rx_queues; i++) { + if (open_single_rx_pcap(rx_queues->names[i], &pcap) < 0) + return -1; + rx_queues->pcaps[i] = pcap; + } + for (i = 0; i < nb_tx_queues; i++) { + if (open_single_tx_pcap(tx_queues->names[i], &dumper) < 0) + return -1; + tx_queues->dumpers[i] = dumper; + } + + RTE_LOG(INFO, PMD, "Creating pcap-backed ethdev on numa socket %u\n", numa_node); + + /* now do all data allocation - for eth_dev structure, dummy pci driver + * and internal (private) data + */ + data = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node); + if (!data) + goto error; + + if (nb_rx_queues) { + data->rx_queues = rte_zmalloc_socket(name, sizeof(void *) * nb_rx_queues, + 0, numa_node); + if (!data->rx_queues) + goto error; + } + + if (nb_tx_queues) { + data->tx_queues = rte_zmalloc_socket(name, sizeof(void *) * nb_tx_queues, + 0, numa_node); + if (data->tx_queues == NULL) + goto error; + } + + internals = rte_zmalloc_socket(name, sizeof(*internals), 0, numa_node); + if (!internals) + goto error; + + /* reserve an ethdev entry */ + eth_dev = rte_eth_dev_allocate(name, RTE_ETH_DEV_VIRTUAL); + if (!eth_dev) + goto error; + + /* check length of device name */ + if ((strlen(eth_dev->data->name) + 1) > sizeof(data->name)) + goto error; + + /* now put it all together + * - store queue data in internals, + * - store numa_node info in eth_dev_data + * - point eth_dev_data to internals + * - and point eth_dev structure to new eth_dev_data structure + */ + internals->nb_rx_queues = nb_rx_queues; + internals->nb_tx_queues = nb_tx_queues; + internals->if_index = if_nametoindex(name); + + data->dev_private = internals; + data->port_id = eth_dev->data->port_id; + strncpy(data->name, eth_dev->data->name, strlen(eth_dev->data->name)); + data->nb_rx_queues = (uint16_t)nb_rx_queues; + data->nb_tx_queues = (uint16_t)nb_tx_queues; + data->dev_link = pmd_link; + data->mac_addrs = ð_addr; + + strncpy(data->name, + eth_dev->data->name, strlen(eth_dev->data->name)); + eth_dev->data = data; + eth_dev->driver = NULL; + eth_dev->dev_ops = &ops; + eth_dev->data->dev_flags = RTE_ETH_DEV_DETACHABLE; + eth_dev->data->kdrv = RTE_KDRV_NONE; + eth_dev->data->drv_name = drivername; + eth_dev->data->numa_node = numa_node; + + for (i = 0; i < nb_rx_queues; i++) { + internals->rx_queue[i].pcap = rx_queues->pcaps[i]; + snprintf(internals->rx_queue[i].name, + sizeof(internals->rx_queue[i].name), "%s", + rx_queues->names[i]); + snprintf(internals->rx_queue[i].type, + sizeof(internals->rx_queue[i].type), "%s", + rx_queues->types[i]); + } + for (i = 0; i < nb_tx_queues; i++) { + internals->tx_queue[i].dumper = tx_queues->dumpers[i]; + snprintf(internals->tx_queue[i].name, + sizeof(internals->tx_queue[i].name), "%s", + tx_queues->names[i]); + snprintf(internals->tx_queue[i].type, + sizeof(internals->tx_queue[i].type), "%s", + tx_queues->types[i]); + } + + /* using multiple pcaps/interfaces */ + internals->single_iface = 0; + + /* finally assign rx and tx ops */ + eth_dev->rx_pkt_burst = eth_pcap_rx; + eth_dev->tx_pkt_burst = eth_pcap_tx_dumper; + + return data->port_id; + +error: + if (data) { + rte_free(data->rx_queues); + rte_free(data->tx_queues); + } + rte_free(data); + rte_free(internals); + + return -1; +} + static int rte_eth_from_pcaps_n_dumpers(const char *name, struct rx_pcaps *rx_queues,
diff --git a/drivers/net/pcap/rte_eth_pcap.h b/drivers/net/pcap/rte_eth_pcap.h
new file mode 100644
index 0000000..5bcfb5d
--- /dev/null
+++ b/drivers/net/pcap/rte_eth_pcap.h@@ -0,0 +1,87 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2016 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _RTE_ETH_PCAP_H_ +#define _RTE_ETH_PCAP_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <pcap.h> + +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]; +}; + +/** + * Create a new ethdev port from pcaps + * + * @param name + * name to be given to the new ethdev port + * @param rx_queues + * pointer to array of pcaps to be used as RX queues + * @param nb_rx_queues + * number of elements in the rx_queues array + * @param tx_queues + * pointer to array of pcaps to be used as TX queues + * @param nb_tx_queues + * number of elements in the tx_queues array + * @param numa_node + * the numa node on which the memory for this port is to be allocated + * @return + * the port number of the newly created the ethdev or -1 on error. + */ +int rte_eth_from_pcapsndumpers(const char *name, + struct rx_pcaps *rx_queues, + const unsigned nb_rx_queues, + struct tx_pcaps *tx_queues, + const unsigned nb_tx_queues, + const unsigned numa_node); + +#ifdef __cplusplus +} +#endif + +#endif
diff --git a/drivers/net/pcap/rte_pmd_pcap_version.map b/drivers/net/pcap/rte_pmd_pcap_version.map
index ef35398..104dc4d 100644
--- a/drivers/net/pcap/rte_pmd_pcap_version.map
+++ b/drivers/net/pcap/rte_pmd_pcap_version.map@@ -2,3 +2,11 @@ DPDK_2.0 { local: *; }; + +DPDK_2.3 { + global: + + rte_eth_from_pcapsndumpers; + +} DPDK_2.0; +
--
1.7.4.1