/*-
* BSD LICENSE
*
- * Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2014 6WIND S.A.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#include <rte_memcpy.h>
#include <rte_string_fns.h>
#include <rte_cycles.h>
+#include <rte_kvargs.h>
+#include <rte_dev.h>
-#include "rte_eth_pcap.h"
-#include "rte_eth_pcap_arg_parser.h"
+#include <net/if.h>
+
+#include <pcap.h>
#define RTE_ETH_PCAP_SNAPSHOT_LEN 65535
#define RTE_ETH_PCAP_SNAPLEN 4096
#define RTE_ETH_PCAP_PROMISC 1
#define RTE_ETH_PCAP_TIMEOUT -1
-#define RTE_ETH_PCAP_MBUFS 64
#define ETH_PCAP_RX_PCAP_ARG "rx_pcap"
#define ETH_PCAP_TX_PCAP_ARG "tx_pcap"
#define ETH_PCAP_RX_IFACE_ARG "rx_iface"
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];
};
break;
/* Now get the space available for data in the mbuf */
- mbp_priv = (struct rte_pktmbuf_pool_private *)
- ((char *)pcap_q->mb_pool + sizeof(struct rte_mempool));
+ mbp_priv = rte_mempool_get_priv(pcap_q->mb_pool);
buf_size = (uint16_t) (mbp_priv->mbuf_data_room_size -
RTE_PKTMBUF_HEADROOM);
mbuf = bufs[i];
ret = pcap_sendpacket(tx_queue->pcap, (u_char*) mbuf->pkt.data,
mbuf->pkt.data_len);
- if(likely(!ret))
- num_tx++;
+ if (unlikely(ret != 0))
+ break;
+ num_tx++;
rte_pktmbuf_free(mbuf);
}
{
struct pmd_internals *internals = dev->data->dev_private;
dev_info->driver_name = drivername;
+ dev_info->if_index = internals->if_index;
dev_info->max_mac_addrs = 1;
dev_info->max_rx_pktlen = (uint32_t) -1;
dev_info->max_rx_queues = (uint16_t)internals->nb_rx_queues;
* reference of it for use it later on.
*/
static int
-open_rx_pcap(char *value, void *extra_args)
+open_rx_pcap(const char *key __rte_unused, const char *value, void *extra_args)
{
unsigned i;
- char *pcap_filename = value;
+ const char *pcap_filename = value;
struct rx_pcaps *pcaps = extra_args;
pcap_t *rx_pcap;
* for use it later on.
*/
static int
-open_tx_pcap(char *value, void *extra_args)
+open_tx_pcap(const char *key __rte_unused, const char *value, void *extra_args)
{
unsigned i;
- char *pcap_filename = value;
+ const char *pcap_filename = value;
struct tx_pcaps *dumpers = extra_args;
pcap_t *tx_pcap;
pcap_dumper_t *dumper;
* Opens an interface for reading and writing
*/
static inline int
-open_rx_tx_iface(char *value, void *extra_args)
+open_rx_tx_iface(const char *key __rte_unused, const char *value, void *extra_args)
{
const char *iface = value;
pcap_t **pcap = extra_args;
* Opens a NIC for reading packets from it
*/
static inline int
-open_rx_iface(char *value, void *extra_args)
+open_rx_iface(const char *key __rte_unused, const char *value, void *extra_args)
{
unsigned i;
const char *iface = value;
* Opens a NIC for writing packets to it
*/
static inline int
-open_tx_iface(char *value, void *extra_args)
+open_tx_iface(const char *key __rte_unused, const char *value, void *extra_args)
{
unsigned i;
const char *iface = value;
const unsigned nb_tx_queues,
const unsigned numa_node,
struct pmd_internals **internals,
- struct rte_eth_dev **eth_dev)
+ struct rte_eth_dev **eth_dev,
+ struct rte_kvargs *kvlist)
{
struct rte_eth_dev_data *data = NULL;
struct rte_pci_device *pci_dev = NULL;
+ unsigned k_idx;
+ struct rte_kvargs_pair *pair = NULL;
+
+ for (k_idx = 0; k_idx < kvlist->count; k_idx++) {
+ pair = &kvlist->pairs[k_idx];
+ if (strstr(pair->key, ETH_PCAP_IFACE_ARG) != NULL)
+ break;
+ }
RTE_LOG(INFO, PMD,
"Creating pcap-backed ethdev on numa socket %u\n", numa_node);
(*internals)->nb_rx_queues = nb_rx_queues;
(*internals)->nb_tx_queues = nb_tx_queues;
+ if (pair == NULL)
+ (*internals)->if_index = 0;
+ else
+ (*internals)->if_index = if_nametoindex(pair->value);
+
pci_dev->numa_node = numa_node;
data->dev_private = *internals;
return -1;
}
-int
+static int
rte_eth_from_pcaps_n_dumpers(pcap_t * const rx_queues[],
const unsigned nb_rx_queues,
pcap_dumper_t * const tx_queues[],
const unsigned nb_tx_queues,
- const unsigned numa_node)
+ const unsigned numa_node,
+ struct rte_kvargs *kvlist)
{
struct pmd_internals *internals = NULL;
struct rte_eth_dev *eth_dev = NULL;
return -1;
if (rte_pmd_init_internals(nb_rx_queues, nb_tx_queues, numa_node,
- &internals, ð_dev) < 0)
+ &internals, ð_dev, kvlist) < 0)
return -1;
for (i = 0; i < nb_rx_queues; i++) {
return 0;
}
-int
+static int
rte_eth_from_pcaps(pcap_t * const rx_queues[],
const unsigned nb_rx_queues,
pcap_t * const tx_queues[],
const unsigned nb_tx_queues,
- const unsigned numa_node)
+ const unsigned numa_node,
+ struct rte_kvargs *kvlist)
{
struct pmd_internals *internals = NULL;
struct rte_eth_dev *eth_dev = NULL;
return -1;
if (rte_pmd_init_internals(nb_rx_queues, nb_tx_queues, numa_node,
- &internals, ð_dev) < 0)
+ &internals, ð_dev, kvlist) < 0)
return -1;
for (i = 0; i < nb_rx_queues; i++) {
}
-int
-rte_pmd_pcap_init(const char *name, const char *params)
+static int
+rte_pmd_pcap_devinit(const char *name, const char *params)
{
unsigned numa_node, using_dumpers = 0;
int ret;
- struct args_dict dict;
+ struct rte_kvargs *kvlist;
struct rx_pcaps pcaps;
struct tx_pcaps dumpers;
- rte_eth_pcap_init_args_dict(&dict);
+ RTE_LOG(INFO, PMD, "Initializing pmd_pcap for %s\n", name);
numa_node = rte_socket_id();
start_cycles = rte_get_timer_cycles();
hz = rte_get_timer_hz();
- if (rte_eth_pcap_parse_args(&dict, name, params, valid_arguments) < 0)
+ kvlist = rte_kvargs_parse(params, valid_arguments);
+ if (kvlist == NULL)
return -1;
/*
* If iface argument is passed we open the NICs and use them for
* reading / writing
*/
- if (rte_eth_pcap_num_of_args(&dict, ETH_PCAP_IFACE_ARG) == 1) {
+ if (rte_kvargs_count(kvlist, ETH_PCAP_IFACE_ARG) == 1) {
- ret = rte_eth_pcap_post_process_arguments(&dict, ETH_PCAP_IFACE_ARG,
+ ret = rte_kvargs_process(kvlist, ETH_PCAP_IFACE_ARG,
&open_rx_tx_iface, &pcaps.pcaps[0]);
if (ret < 0)
return -1;
- return rte_eth_from_pcaps(pcaps.pcaps, 1, pcaps.pcaps, 1, numa_node);
+ return rte_eth_from_pcaps(pcaps.pcaps, 1, pcaps.pcaps, 1,
+ numa_node, kvlist);
}
/*
* We check whether we want to open a RX stream from a real NIC or a
* pcap file
*/
- if ((pcaps.num_of_rx = rte_eth_pcap_num_of_args(&dict, ETH_PCAP_RX_PCAP_ARG))) {
- ret = rte_eth_pcap_post_process_arguments(&dict, ETH_PCAP_RX_PCAP_ARG,
+ if ((pcaps.num_of_rx = rte_kvargs_count(kvlist, ETH_PCAP_RX_PCAP_ARG))) {
+ ret = rte_kvargs_process(kvlist, ETH_PCAP_RX_PCAP_ARG,
&open_rx_pcap, &pcaps);
} else {
- pcaps.num_of_rx = rte_eth_pcap_num_of_args(&dict,
+ pcaps.num_of_rx = rte_kvargs_count(kvlist,
ETH_PCAP_RX_IFACE_ARG);
- ret = rte_eth_pcap_post_process_arguments(&dict, ETH_PCAP_RX_IFACE_ARG,
+ ret = rte_kvargs_process(kvlist, ETH_PCAP_RX_IFACE_ARG,
&open_rx_iface, &pcaps);
}
* We check whether we want to open a TX stream to a real NIC or a
* pcap file
*/
- if ((dumpers.num_of_tx = rte_eth_pcap_num_of_args(&dict,
+ if ((dumpers.num_of_tx = rte_kvargs_count(kvlist,
ETH_PCAP_TX_PCAP_ARG))) {
- ret = rte_eth_pcap_post_process_arguments(&dict, ETH_PCAP_TX_PCAP_ARG,
+ ret = rte_kvargs_process(kvlist, ETH_PCAP_TX_PCAP_ARG,
&open_tx_pcap, &dumpers);
using_dumpers = 1;
} else {
- dumpers.num_of_tx = rte_eth_pcap_num_of_args(&dict,
+ dumpers.num_of_tx = rte_kvargs_count(kvlist,
ETH_PCAP_TX_IFACE_ARG);
- ret = rte_eth_pcap_post_process_arguments(&dict, ETH_PCAP_TX_IFACE_ARG,
+ ret = rte_kvargs_process(kvlist, ETH_PCAP_TX_IFACE_ARG,
&open_tx_iface, &dumpers);
}
if (using_dumpers)
return rte_eth_from_pcaps_n_dumpers(pcaps.pcaps, pcaps.num_of_rx,
- dumpers.dumpers, dumpers.num_of_tx, numa_node);
+ dumpers.dumpers, dumpers.num_of_tx, numa_node, kvlist);
return rte_eth_from_pcaps(pcaps.pcaps, pcaps.num_of_rx, dumpers.pcaps,
- dumpers.num_of_tx, numa_node);
+ dumpers.num_of_tx, numa_node, kvlist);
}
+static struct rte_driver pmd_pcap_drv = {
+ .name = "eth_pcap",
+ .type = PMD_VDEV,
+ .init = rte_pmd_pcap_devinit,
+};
+
+PMD_REGISTER_DRIVER(pmd_pcap_drv);