#define ETH_PCAP_RX_PCAP_ARG "rx_pcap"
#define ETH_PCAP_TX_PCAP_ARG "tx_pcap"
#define ETH_PCAP_RX_IFACE_ARG "rx_iface"
+#define ETH_PCAP_RX_IFACE_IN_ARG "rx_iface_in"
#define ETH_PCAP_TX_IFACE_ARG "tx_iface"
#define ETH_PCAP_IFACE_ARG "iface"
static struct timeval start_time;
static uint64_t start_cycles;
static uint64_t hz;
+static uint8_t iface_idx;
struct queue_stat {
volatile unsigned long pkts;
struct pmd_internals {
struct pcap_rx_queue rx_queue[RTE_PMD_PCAP_MAX_QUEUES];
struct pcap_tx_queue tx_queue[RTE_PMD_PCAP_MAX_QUEUES];
+ struct ether_addr eth_addr;
int if_index;
int single_iface;
};
ETH_PCAP_RX_PCAP_ARG,
ETH_PCAP_TX_PCAP_ARG,
ETH_PCAP_RX_IFACE_ARG,
+ ETH_PCAP_RX_IFACE_IN_ARG,
ETH_PCAP_TX_IFACE_ARG,
ETH_PCAP_IFACE_ARG,
NULL
};
-static struct ether_addr eth_addr = {
- .addr_bytes = { 0, 0, 0, 0x1, 0x2, 0x3 }
-};
-
static struct rte_eth_link pmd_link = {
.link_speed = ETH_SPEED_NUM_10G,
.link_duplex = ETH_LINK_FULL_DUPLEX,
return -1;
rx->pcap = tx->pcap;
}
+
goto status_up;
}
}
status_up:
+ for (i = 0; i < dev->data->nb_rx_queues; i++)
+ dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED;
+
+ for (i = 0; i < dev->data->nb_tx_queues; i++)
+ dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED;
+
dev->data->dev_link.link_status = ETH_LINK_UP;
return 0;
}
status_down:
+ for (i = 0; i < dev->data->nb_rx_queues; i++)
+ dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
+
+ for (i = 0; i < dev->data->nb_tx_queues; i++)
+ dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
+
dev->data->dev_link.link_status = ETH_LINK_DOWN;
}
return 0;
}
+static int
+eth_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)
+{
+ dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
+
+ return 0;
+}
+
+static int
+eth_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id)
+{
+ dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
+
+ return 0;
+}
+
+static int
+eth_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id)
+{
+ dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;
+
+ return 0;
+}
+
+static int
+eth_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)
+{
+ dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;
+
+ return 0;
+}
+
static const struct eth_dev_ops ops = {
.dev_start = eth_dev_start,
.dev_stop = eth_dev_stop,
.dev_infos_get = eth_dev_info,
.rx_queue_setup = eth_rx_queue_setup,
.tx_queue_setup = eth_tx_queue_setup,
+ .rx_queue_start = eth_rx_queue_start,
+ .tx_queue_start = eth_tx_queue_start,
+ .rx_queue_stop = eth_rx_queue_stop,
+ .tx_queue_stop = eth_tx_queue_stop,
.rx_queue_release = eth_queue_release,
.tx_queue_release = eth_queue_release,
.link_update = eth_link_update,
.stats_reset = eth_stats_reset,
};
+static int
+add_queue(struct pmd_devargs *pmd, const char *name, const char *type,
+ pcap_t *pcap, pcap_dumper_t *dumper)
+{
+ if (pmd->num_of_queue >= RTE_PMD_PCAP_MAX_QUEUES)
+ return -1;
+ if (pcap)
+ pmd->queue[pmd->num_of_queue].pcap = pcap;
+ if (dumper)
+ pmd->queue[pmd->num_of_queue].dumper = dumper;
+ pmd->queue[pmd->num_of_queue].name = name;
+ pmd->queue[pmd->num_of_queue].type = type;
+ pmd->num_of_queue++;
+ return 0;
+}
+
/*
* Function handler that opens the pcap file for reading a stores a
* reference of it for use it later on.
struct pmd_devargs *rx = extra_args;
pcap_t *pcap = NULL;
- if (rx->num_of_queue >= RTE_PMD_PCAP_MAX_QUEUES)
- return -1;
if (open_single_rx_pcap(pcap_filename, &pcap) < 0)
return -1;
- rx->queue[rx->num_of_queue].pcap = pcap;
- rx->queue[rx->num_of_queue].name = pcap_filename;
- rx->queue[rx->num_of_queue].type = key;
- rx->num_of_queue++;
+ if (add_queue(rx, pcap_filename, key, pcap, NULL) < 0) {
+ pcap_close(pcap);
+ return -1;
+ }
return 0;
}
struct pmd_devargs *dumpers = extra_args;
pcap_dumper_t *dumper;
- if (dumpers->num_of_queue >= RTE_PMD_PCAP_MAX_QUEUES)
- return -1;
if (open_single_tx_pcap(pcap_filename, &dumper) < 0)
return -1;
- dumpers->queue[dumpers->num_of_queue].dumper = dumper;
- dumpers->queue[dumpers->num_of_queue].name = pcap_filename;
- dumpers->queue[dumpers->num_of_queue].type = key;
- dumpers->num_of_queue++;
+ if (add_queue(dumpers, pcap_filename, key, NULL, dumper) < 0) {
+ pcap_dump_close(dumper);
+ return -1;
+ }
return 0;
}
return 0;
}
-/*
- * Opens a NIC for reading packets from it
- */
static inline int
-open_rx_iface(const char *key, const char *value, void *extra_args)
+set_iface_direction(const char *iface, pcap_t *pcap,
+ pcap_direction_t direction)
+{
+ const char *direction_str = (direction == PCAP_D_IN) ? "IN" : "OUT";
+ if (pcap_setdirection(pcap, direction) < 0) {
+ PMD_LOG(ERR, "Setting %s pcap direction %s failed - %s\n",
+ iface, direction_str, pcap_geterr(pcap));
+ return -1;
+ }
+ PMD_LOG(INFO, "Setting %s pcap direction %s\n",
+ iface, direction_str);
+ return 0;
+}
+
+static inline int
+open_iface(const char *key, const char *value, void *extra_args)
{
const char *iface = value;
- struct pmd_devargs *rx = extra_args;
+ struct pmd_devargs *pmd = extra_args;
pcap_t *pcap = NULL;
- if (rx->num_of_queue >= RTE_PMD_PCAP_MAX_QUEUES)
- return -1;
if (open_single_iface(iface, &pcap) < 0)
return -1;
- rx->queue[rx->num_of_queue].pcap = pcap;
- rx->queue[rx->num_of_queue].name = iface;
- rx->queue[rx->num_of_queue].type = key;
- rx->num_of_queue++;
+ if (add_queue(pmd, iface, key, pcap, NULL) < 0) {
+ pcap_close(pcap);
+ return -1;
+ }
return 0;
}
/*
- * Opens a NIC for writing packets to it
+ * Opens a NIC for reading packets from it
*/
-static int
-open_tx_iface(const char *key, const char *value, void *extra_args)
+static inline int
+open_rx_iface(const char *key, const char *value, void *extra_args)
{
- const char *iface = value;
- struct pmd_devargs *tx = extra_args;
- pcap_t *pcap;
+ int ret = open_iface(key, value, extra_args);
+ if (ret < 0)
+ return ret;
+ if (strcmp(key, ETH_PCAP_RX_IFACE_IN_ARG) == 0) {
+ struct pmd_devargs *pmd = extra_args;
+ unsigned int qid = pmd->num_of_queue - 1;
- if (tx->num_of_queue >= RTE_PMD_PCAP_MAX_QUEUES)
- return -1;
- if (open_single_iface(iface, &pcap) < 0)
- return -1;
- tx->queue[tx->num_of_queue].pcap = pcap;
- tx->queue[tx->num_of_queue].name = iface;
- tx->queue[tx->num_of_queue].type = key;
- tx->num_of_queue++;
+ set_iface_direction(pmd->queue[qid].name,
+ pmd->queue[qid].pcap,
+ PCAP_D_IN);
+ }
+
+ return 0;
+}
+
+static inline int
+rx_iface_args_process(const char *key, const char *value, void *extra_args)
+{
+ if (strcmp(key, ETH_PCAP_RX_IFACE_ARG) == 0 ||
+ strcmp(key, ETH_PCAP_RX_IFACE_IN_ARG) == 0)
+ return open_rx_iface(key, value, extra_args);
return 0;
}
+/*
+ * Opens a NIC for writing packets to it
+ */
+static int
+open_tx_iface(const char *key, const char *value, void *extra_args)
+{
+ return open_iface(key, value, extra_args);
+}
+
static struct rte_vdev_driver pmd_pcap_drv;
static int
* - and point eth_dev structure to new eth_dev_data structure
*/
*internals = (*eth_dev)->data->dev_private;
+ /*
+ * Interface MAC = 02:70:63:61:70:<iface_idx>
+ * derived from: 'locally administered':'p':'c':'a':'p':'iface_idx'
+ * where the middle 4 characters are converted to hex.
+ */
+ (*internals)->eth_addr = (struct ether_addr) {
+ .addr_bytes = { 0x02, 0x70, 0x63, 0x61, 0x70, iface_idx++ }
+ };
data = (*eth_dev)->data;
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;
+ data->mac_addrs = &(*internals)->eth_addr;
/*
* NOTE: we'll replace the data element, of originally allocated
}
/* TODO: request info from primary to set up Rx and Tx */
eth_dev->dev_ops = &ops;
+ eth_dev->device = &dev->device;
rte_eth_dev_probing_finish(eth_dev);
return 0;
}
is_rx_pcap = rte_kvargs_count(kvlist, ETH_PCAP_RX_PCAP_ARG) ? 1 : 0;
pcaps.num_of_queue = 0;
- if (is_rx_pcap)
+ if (is_rx_pcap) {
ret = rte_kvargs_process(kvlist, ETH_PCAP_RX_PCAP_ARG,
&open_rx_pcap, &pcaps);
- else
- ret = rte_kvargs_process(kvlist, ETH_PCAP_RX_IFACE_ARG,
- &open_rx_iface, &pcaps);
+ } else {
+ ret = rte_kvargs_process(kvlist, NULL,
+ &rx_iface_args_process, &pcaps);
+ }
if (ret < 0)
goto free_kvlist;
ETH_PCAP_RX_PCAP_ARG "=<string> "
ETH_PCAP_TX_PCAP_ARG "=<string> "
ETH_PCAP_RX_IFACE_ARG "=<ifc> "
+ ETH_PCAP_RX_IFACE_IN_ARG "=<ifc> "
ETH_PCAP_TX_IFACE_ARG "=<ifc> "
ETH_PCAP_IFACE_ARG "=<ifc>");
-RTE_INIT(eth_pcap_init_log);
-static void
-eth_pcap_init_log(void)
+RTE_INIT(eth_pcap_init_log)
{
eth_pcap_logtype = rte_log_register("pmd.net.pcap");
if (eth_pcap_logtype >= 0)