net/pcap: fix checkpatch warnings
[dpdk.git] / drivers / net / pcap / rte_eth_pcap.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
5  *   Copyright(c) 2014 6WIND S.A.
6  *   All rights reserved.
7  *
8  *   Redistribution and use in source and binary forms, with or without
9  *   modification, are permitted provided that the following conditions
10  *   are met:
11  *
12  *     * Redistributions of source code must retain the above copyright
13  *       notice, this list of conditions and the following disclaimer.
14  *     * Redistributions in binary form must reproduce the above copyright
15  *       notice, this list of conditions and the following disclaimer in
16  *       the documentation and/or other materials provided with the
17  *       distribution.
18  *     * Neither the name of Intel Corporation nor the names of its
19  *       contributors may be used to endorse or promote products derived
20  *       from this software without specific prior written permission.
21  *
22  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34
35 #include <time.h>
36
37 #include <net/if.h>
38
39 #include <pcap.h>
40
41 #include <rte_cycles.h>
42 #include <rte_ethdev.h>
43 #include <rte_kvargs.h>
44 #include <rte_malloc.h>
45 #include <rte_mbuf.h>
46 #include <rte_vdev.h>
47
48 #define RTE_ETH_PCAP_SNAPSHOT_LEN 65535
49 #define RTE_ETH_PCAP_SNAPLEN ETHER_MAX_JUMBO_FRAME_LEN
50 #define RTE_ETH_PCAP_PROMISC 1
51 #define RTE_ETH_PCAP_TIMEOUT -1
52
53 #define ETH_PCAP_RX_PCAP_ARG  "rx_pcap"
54 #define ETH_PCAP_TX_PCAP_ARG  "tx_pcap"
55 #define ETH_PCAP_RX_IFACE_ARG "rx_iface"
56 #define ETH_PCAP_TX_IFACE_ARG "tx_iface"
57 #define ETH_PCAP_IFACE_ARG    "iface"
58
59 #define ETH_PCAP_ARG_MAXLEN     64
60
61 #define RTE_PMD_PCAP_MAX_QUEUES 16
62
63 static char errbuf[PCAP_ERRBUF_SIZE];
64 static unsigned char tx_pcap_data[RTE_ETH_PCAP_SNAPLEN];
65 static struct timeval start_time;
66 static uint64_t start_cycles;
67 static uint64_t hz;
68
69 struct queue_stat {
70         volatile unsigned long pkts;
71         volatile unsigned long bytes;
72         volatile unsigned long err_pkts;
73 };
74
75 struct pcap_rx_queue {
76         pcap_t *pcap;
77         uint8_t in_port;
78         struct rte_mempool *mb_pool;
79         struct queue_stat rx_stat;
80         char name[PATH_MAX];
81         char type[ETH_PCAP_ARG_MAXLEN];
82 };
83
84 struct pcap_tx_queue {
85         pcap_dumper_t *dumper;
86         pcap_t *pcap;
87         struct queue_stat tx_stat;
88         char name[PATH_MAX];
89         char type[ETH_PCAP_ARG_MAXLEN];
90 };
91
92 struct pmd_internals {
93         struct pcap_rx_queue rx_queue[RTE_PMD_PCAP_MAX_QUEUES];
94         struct pcap_tx_queue tx_queue[RTE_PMD_PCAP_MAX_QUEUES];
95         int if_index;
96         int single_iface;
97 };
98
99 struct pmd_devargs {
100         unsigned int num_of_queue;
101         struct devargs_queue {
102                 pcap_dumper_t *dumper;
103                 pcap_t *pcap;
104                 const char *name;
105                 const char *type;
106         } queue[RTE_PMD_PCAP_MAX_QUEUES];
107 };
108
109 static const char *valid_arguments[] = {
110         ETH_PCAP_RX_PCAP_ARG,
111         ETH_PCAP_TX_PCAP_ARG,
112         ETH_PCAP_RX_IFACE_ARG,
113         ETH_PCAP_TX_IFACE_ARG,
114         ETH_PCAP_IFACE_ARG,
115         NULL
116 };
117
118 static struct ether_addr eth_addr = {
119         .addr_bytes = { 0, 0, 0, 0x1, 0x2, 0x3 }
120 };
121
122 static const char *drivername = "Pcap PMD";
123 static struct rte_eth_link pmd_link = {
124                 .link_speed = ETH_SPEED_NUM_10G,
125                 .link_duplex = ETH_LINK_FULL_DUPLEX,
126                 .link_status = ETH_LINK_DOWN,
127                 .link_autoneg = ETH_LINK_SPEED_FIXED,
128 };
129
130 static int
131 eth_pcap_rx_jumbo(struct rte_mempool *mb_pool, struct rte_mbuf *mbuf,
132                 const u_char *data, uint16_t data_len)
133 {
134         /* Copy the first segment. */
135         uint16_t len = rte_pktmbuf_tailroom(mbuf);
136         struct rte_mbuf *m = mbuf;
137
138         rte_memcpy(rte_pktmbuf_append(mbuf, len), data, len);
139         data_len -= len;
140         data += len;
141
142         while (data_len > 0) {
143                 /* Allocate next mbuf and point to that. */
144                 m->next = rte_pktmbuf_alloc(mb_pool);
145
146                 if (unlikely(!m->next))
147                         return -1;
148
149                 m = m->next;
150
151                 /* Headroom is not needed in chained mbufs. */
152                 rte_pktmbuf_prepend(m, rte_pktmbuf_headroom(m));
153                 m->pkt_len = 0;
154                 m->data_len = 0;
155
156                 /* Copy next segment. */
157                 len = RTE_MIN(rte_pktmbuf_tailroom(m), data_len);
158                 rte_memcpy(rte_pktmbuf_append(m, len), data, len);
159
160                 mbuf->nb_segs++;
161                 data_len -= len;
162                 data += len;
163         }
164
165         return mbuf->nb_segs;
166 }
167
168 /* Copy data from mbuf chain to a buffer suitable for writing to a PCAP file. */
169 static void
170 eth_pcap_gather_data(unsigned char *data, struct rte_mbuf *mbuf)
171 {
172         uint16_t data_len = 0;
173
174         while (mbuf) {
175                 rte_memcpy(data + data_len, rte_pktmbuf_mtod(mbuf, void *),
176                         mbuf->data_len);
177
178                 data_len += mbuf->data_len;
179                 mbuf = mbuf->next;
180         }
181 }
182
183 static uint16_t
184 eth_pcap_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
185 {
186         unsigned int i;
187         struct pcap_pkthdr header;
188         const u_char *packet;
189         struct rte_mbuf *mbuf;
190         struct pcap_rx_queue *pcap_q = queue;
191         uint16_t num_rx = 0;
192         uint16_t buf_size;
193         uint32_t rx_bytes = 0;
194
195         if (unlikely(pcap_q->pcap == NULL || nb_pkts == 0))
196                 return 0;
197
198         /* Reads the given number of packets from the pcap file one by one
199          * and copies the packet data into a newly allocated mbuf to return.
200          */
201         for (i = 0; i < nb_pkts; i++) {
202                 /* Get the next PCAP packet */
203                 packet = pcap_next(pcap_q->pcap, &header);
204                 if (unlikely(packet == NULL))
205                         break;
206
207                 mbuf = rte_pktmbuf_alloc(pcap_q->mb_pool);
208                 if (unlikely(mbuf == NULL))
209                         break;
210
211                 /* Now get the space available for data in the mbuf */
212                 buf_size = rte_pktmbuf_data_room_size(pcap_q->mb_pool) -
213                                 RTE_PKTMBUF_HEADROOM;
214
215                 if (header.caplen <= buf_size) {
216                         /* pcap packet will fit in the mbuf, can copy it */
217                         rte_memcpy(rte_pktmbuf_mtod(mbuf, void *), packet,
218                                         header.caplen);
219                         mbuf->data_len = (uint16_t)header.caplen;
220                 } else {
221                         /* Try read jumbo frame into multi mbufs. */
222                         if (unlikely(eth_pcap_rx_jumbo(pcap_q->mb_pool,
223                                                        mbuf,
224                                                        packet,
225                                                        header.caplen) == -1))
226                                 break;
227                 }
228
229                 mbuf->pkt_len = (uint16_t)header.caplen;
230                 mbuf->port = pcap_q->in_port;
231                 bufs[num_rx] = mbuf;
232                 num_rx++;
233                 rx_bytes += header.caplen;
234         }
235         pcap_q->rx_stat.pkts += num_rx;
236         pcap_q->rx_stat.bytes += rx_bytes;
237
238         return num_rx;
239 }
240
241 static inline void
242 calculate_timestamp(struct timeval *ts) {
243         uint64_t cycles;
244         struct timeval cur_time;
245
246         cycles = rte_get_timer_cycles() - start_cycles;
247         cur_time.tv_sec = cycles / hz;
248         cur_time.tv_usec = (cycles % hz) * 10e6 / hz;
249         timeradd(&start_time, &cur_time, ts);
250 }
251
252 /*
253  * Callback to handle writing packets to a pcap file.
254  */
255 static uint16_t
256 eth_pcap_tx_dumper(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
257 {
258         unsigned int i;
259         struct rte_mbuf *mbuf;
260         struct pcap_tx_queue *dumper_q = queue;
261         uint16_t num_tx = 0;
262         uint32_t tx_bytes = 0;
263         struct pcap_pkthdr header;
264
265         if (dumper_q->dumper == NULL || nb_pkts == 0)
266                 return 0;
267
268         /* writes the nb_pkts packets to the previously opened pcap file
269          * dumper */
270         for (i = 0; i < nb_pkts; i++) {
271                 mbuf = bufs[i];
272                 calculate_timestamp(&header.ts);
273                 header.len = mbuf->pkt_len;
274                 header.caplen = header.len;
275
276                 if (likely(mbuf->nb_segs == 1)) {
277                         pcap_dump((u_char *)dumper_q->dumper, &header,
278                                   rte_pktmbuf_mtod(mbuf, void*));
279                 } else {
280                         if (mbuf->pkt_len <= ETHER_MAX_JUMBO_FRAME_LEN) {
281                                 eth_pcap_gather_data(tx_pcap_data, mbuf);
282                                 pcap_dump((u_char *)dumper_q->dumper, &header,
283                                           tx_pcap_data);
284                         } else {
285                                 RTE_LOG(ERR, PMD,
286                                         "Dropping PCAP packet. Size (%d) > max jumbo size (%d).\n",
287                                         mbuf->pkt_len,
288                                         ETHER_MAX_JUMBO_FRAME_LEN);
289
290                                 rte_pktmbuf_free(mbuf);
291                                 break;
292                         }
293                 }
294
295                 rte_pktmbuf_free(mbuf);
296                 num_tx++;
297                 tx_bytes += mbuf->pkt_len;
298         }
299
300         /*
301          * Since there's no place to hook a callback when the forwarding
302          * process stops and to make sure the pcap file is actually written,
303          * we flush the pcap dumper within each burst.
304          */
305         pcap_dump_flush(dumper_q->dumper);
306         dumper_q->tx_stat.pkts += num_tx;
307         dumper_q->tx_stat.bytes += tx_bytes;
308         dumper_q->tx_stat.err_pkts += nb_pkts - num_tx;
309
310         return num_tx;
311 }
312
313 /*
314  * Callback to handle sending packets through a real NIC.
315  */
316 static uint16_t
317 eth_pcap_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
318 {
319         unsigned int i;
320         int ret;
321         struct rte_mbuf *mbuf;
322         struct pcap_tx_queue *tx_queue = queue;
323         uint16_t num_tx = 0;
324         uint32_t tx_bytes = 0;
325
326         if (unlikely(nb_pkts == 0 || tx_queue->pcap == NULL))
327                 return 0;
328
329         for (i = 0; i < nb_pkts; i++) {
330                 mbuf = bufs[i];
331
332                 if (likely(mbuf->nb_segs == 1)) {
333                         ret = pcap_sendpacket(tx_queue->pcap,
334                                         rte_pktmbuf_mtod(mbuf, u_char *),
335                                         mbuf->pkt_len);
336                 } else {
337                         if (mbuf->pkt_len <= ETHER_MAX_JUMBO_FRAME_LEN) {
338                                 eth_pcap_gather_data(tx_pcap_data, mbuf);
339                                 ret = pcap_sendpacket(tx_queue->pcap,
340                                                 tx_pcap_data, mbuf->pkt_len);
341                         } else {
342                                 RTE_LOG(ERR, PMD,
343                                         "Dropping PCAP packet. Size (%d) > max jumbo size (%d).\n",
344                                         mbuf->pkt_len,
345                                         ETHER_MAX_JUMBO_FRAME_LEN);
346
347                                 rte_pktmbuf_free(mbuf);
348                                 break;
349                         }
350                 }
351
352                 if (unlikely(ret != 0))
353                         break;
354                 num_tx++;
355                 tx_bytes += mbuf->pkt_len;
356                 rte_pktmbuf_free(mbuf);
357         }
358
359         tx_queue->tx_stat.pkts += num_tx;
360         tx_queue->tx_stat.bytes += tx_bytes;
361         tx_queue->tx_stat.err_pkts += nb_pkts - num_tx;
362
363         return num_tx;
364 }
365
366 /*
367  * pcap_open_live wrapper function
368  */
369 static inline int
370 open_iface_live(const char *iface, pcap_t **pcap) {
371         *pcap = pcap_open_live(iface, RTE_ETH_PCAP_SNAPLEN,
372                         RTE_ETH_PCAP_PROMISC, RTE_ETH_PCAP_TIMEOUT, errbuf);
373
374         if (*pcap == NULL) {
375                 RTE_LOG(ERR, PMD, "Couldn't open %s: %s\n", iface, errbuf);
376                 return -1;
377         }
378
379         return 0;
380 }
381
382 static int
383 open_single_iface(const char *iface, pcap_t **pcap)
384 {
385         if (open_iface_live(iface, pcap) < 0) {
386                 RTE_LOG(ERR, PMD, "Couldn't open interface %s\n", iface);
387                 return -1;
388         }
389
390         return 0;
391 }
392
393 static int
394 open_single_tx_pcap(const char *pcap_filename, pcap_dumper_t **dumper)
395 {
396         pcap_t *tx_pcap;
397
398         /*
399          * We need to create a dummy empty pcap_t to use it
400          * with pcap_dump_open(). We create big enough an Ethernet
401          * pcap holder.
402          */
403         tx_pcap = pcap_open_dead(DLT_EN10MB, RTE_ETH_PCAP_SNAPSHOT_LEN);
404         if (tx_pcap == NULL) {
405                 RTE_LOG(ERR, PMD, "Couldn't create dead pcap\n");
406                 return -1;
407         }
408
409         /* The dumper is created using the previous pcap_t reference */
410         *dumper = pcap_dump_open(tx_pcap, pcap_filename);
411         if (*dumper == NULL) {
412                 RTE_LOG(ERR, PMD, "Couldn't open %s for writing.\n",
413                         pcap_filename);
414                 return -1;
415         }
416
417         return 0;
418 }
419
420 static int
421 open_single_rx_pcap(const char *pcap_filename, pcap_t **pcap)
422 {
423         *pcap = pcap_open_offline(pcap_filename, errbuf);
424         if (*pcap == NULL) {
425                 RTE_LOG(ERR, PMD, "Couldn't open %s: %s\n", pcap_filename,
426                         errbuf);
427                 return -1;
428         }
429
430         return 0;
431 }
432
433 static int
434 eth_dev_start(struct rte_eth_dev *dev)
435 {
436         unsigned int i;
437         struct pmd_internals *internals = dev->data->dev_private;
438         struct pcap_tx_queue *tx;
439         struct pcap_rx_queue *rx;
440
441         /* Special iface case. Single pcap is open and shared between tx/rx. */
442         if (internals->single_iface) {
443                 tx = &internals->tx_queue[0];
444                 rx = &internals->rx_queue[0];
445
446                 if (!tx->pcap && strcmp(tx->type, ETH_PCAP_IFACE_ARG) == 0) {
447                         if (open_single_iface(tx->name, &tx->pcap) < 0)
448                                 return -1;
449                         rx->pcap = tx->pcap;
450                 }
451                 goto status_up;
452         }
453
454         /* If not open already, open tx pcaps/dumpers */
455         for (i = 0; i < dev->data->nb_tx_queues; i++) {
456                 tx = &internals->tx_queue[i];
457
458                 if (!tx->dumper &&
459                                 strcmp(tx->type, ETH_PCAP_TX_PCAP_ARG) == 0) {
460                         if (open_single_tx_pcap(tx->name, &tx->dumper) < 0)
461                                 return -1;
462                 } else if (!tx->pcap &&
463                                 strcmp(tx->type, ETH_PCAP_TX_IFACE_ARG) == 0) {
464                         if (open_single_iface(tx->name, &tx->pcap) < 0)
465                                 return -1;
466                 }
467         }
468
469         /* If not open already, open rx pcaps */
470         for (i = 0; i < dev->data->nb_rx_queues; i++) {
471                 rx = &internals->rx_queue[i];
472
473                 if (rx->pcap != NULL)
474                         continue;
475
476                 if (strcmp(rx->type, ETH_PCAP_RX_PCAP_ARG) == 0) {
477                         if (open_single_rx_pcap(rx->name, &rx->pcap) < 0)
478                                 return -1;
479                 } else if (strcmp(rx->type, ETH_PCAP_RX_IFACE_ARG) == 0) {
480                         if (open_single_iface(rx->name, &rx->pcap) < 0)
481                                 return -1;
482                 }
483         }
484
485 status_up:
486         dev->data->dev_link.link_status = ETH_LINK_UP;
487
488         return 0;
489 }
490
491 /*
492  * This function gets called when the current port gets stopped.
493  * Is the only place for us to close all the tx streams dumpers.
494  * If not called the dumpers will be flushed within each tx burst.
495  */
496 static void
497 eth_dev_stop(struct rte_eth_dev *dev)
498 {
499         unsigned int i;
500         struct pmd_internals *internals = dev->data->dev_private;
501         struct pcap_tx_queue *tx;
502         struct pcap_rx_queue *rx;
503
504         /* Special iface case. Single pcap is open and shared between tx/rx. */
505         if (internals->single_iface) {
506                 tx = &internals->tx_queue[0];
507                 rx = &internals->rx_queue[0];
508                 pcap_close(tx->pcap);
509                 tx->pcap = NULL;
510                 rx->pcap = NULL;
511                 goto status_down;
512         }
513
514         for (i = 0; i < dev->data->nb_tx_queues; i++) {
515                 tx = &internals->tx_queue[i];
516
517                 if (tx->dumper != NULL) {
518                         pcap_dump_close(tx->dumper);
519                         tx->dumper = NULL;
520                 }
521
522                 if (tx->pcap != NULL) {
523                         pcap_close(tx->pcap);
524                         tx->pcap = NULL;
525                 }
526         }
527
528         for (i = 0; i < dev->data->nb_rx_queues; i++) {
529                 rx = &internals->rx_queue[i];
530
531                 if (rx->pcap != NULL) {
532                         pcap_close(rx->pcap);
533                         rx->pcap = NULL;
534                 }
535         }
536
537 status_down:
538         dev->data->dev_link.link_status = ETH_LINK_DOWN;
539 }
540
541 static int
542 eth_dev_configure(struct rte_eth_dev *dev __rte_unused)
543 {
544         return 0;
545 }
546
547 static void
548 eth_dev_info(struct rte_eth_dev *dev,
549                 struct rte_eth_dev_info *dev_info)
550 {
551         struct pmd_internals *internals = dev->data->dev_private;
552
553         dev_info->driver_name = drivername;
554         dev_info->if_index = internals->if_index;
555         dev_info->max_mac_addrs = 1;
556         dev_info->max_rx_pktlen = (uint32_t) -1;
557         dev_info->max_rx_queues = dev->data->nb_rx_queues;
558         dev_info->max_tx_queues = dev->data->nb_tx_queues;
559         dev_info->min_rx_bufsize = 0;
560         dev_info->pci_dev = NULL;
561 }
562
563 static void
564 eth_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
565 {
566         unsigned int i;
567         unsigned long rx_packets_total = 0, rx_bytes_total = 0;
568         unsigned long tx_packets_total = 0, tx_bytes_total = 0;
569         unsigned long tx_packets_err_total = 0;
570         const struct pmd_internals *internal = dev->data->dev_private;
571
572         for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS &&
573                         i < dev->data->nb_rx_queues; i++) {
574                 stats->q_ipackets[i] = internal->rx_queue[i].rx_stat.pkts;
575                 stats->q_ibytes[i] = internal->rx_queue[i].rx_stat.bytes;
576                 rx_packets_total += stats->q_ipackets[i];
577                 rx_bytes_total += stats->q_ibytes[i];
578         }
579
580         for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS &&
581                         i < dev->data->nb_tx_queues; i++) {
582                 stats->q_opackets[i] = internal->tx_queue[i].tx_stat.pkts;
583                 stats->q_obytes[i] = internal->tx_queue[i].tx_stat.bytes;
584                 stats->q_errors[i] = internal->tx_queue[i].tx_stat.err_pkts;
585                 tx_packets_total += stats->q_opackets[i];
586                 tx_bytes_total += stats->q_obytes[i];
587                 tx_packets_err_total += stats->q_errors[i];
588         }
589
590         stats->ipackets = rx_packets_total;
591         stats->ibytes = rx_bytes_total;
592         stats->opackets = tx_packets_total;
593         stats->obytes = tx_bytes_total;
594         stats->oerrors = tx_packets_err_total;
595 }
596
597 static void
598 eth_stats_reset(struct rte_eth_dev *dev)
599 {
600         unsigned int i;
601         struct pmd_internals *internal = dev->data->dev_private;
602
603         for (i = 0; i < dev->data->nb_rx_queues; i++) {
604                 internal->rx_queue[i].rx_stat.pkts = 0;
605                 internal->rx_queue[i].rx_stat.bytes = 0;
606         }
607
608         for (i = 0; i < dev->data->nb_tx_queues; i++) {
609                 internal->tx_queue[i].tx_stat.pkts = 0;
610                 internal->tx_queue[i].tx_stat.bytes = 0;
611                 internal->tx_queue[i].tx_stat.err_pkts = 0;
612         }
613 }
614
615 static void
616 eth_dev_close(struct rte_eth_dev *dev __rte_unused)
617 {
618 }
619
620 static void
621 eth_queue_release(void *q __rte_unused)
622 {
623 }
624
625 static int
626 eth_link_update(struct rte_eth_dev *dev __rte_unused,
627                 int wait_to_complete __rte_unused)
628 {
629         return 0;
630 }
631
632 static int
633 eth_rx_queue_setup(struct rte_eth_dev *dev,
634                 uint16_t rx_queue_id,
635                 uint16_t nb_rx_desc __rte_unused,
636                 unsigned int socket_id __rte_unused,
637                 const struct rte_eth_rxconf *rx_conf __rte_unused,
638                 struct rte_mempool *mb_pool)
639 {
640         struct pmd_internals *internals = dev->data->dev_private;
641         struct pcap_rx_queue *pcap_q = &internals->rx_queue[rx_queue_id];
642
643         pcap_q->mb_pool = mb_pool;
644         dev->data->rx_queues[rx_queue_id] = pcap_q;
645         pcap_q->in_port = dev->data->port_id;
646
647         return 0;
648 }
649
650 static int
651 eth_tx_queue_setup(struct rte_eth_dev *dev,
652                 uint16_t tx_queue_id,
653                 uint16_t nb_tx_desc __rte_unused,
654                 unsigned int socket_id __rte_unused,
655                 const struct rte_eth_txconf *tx_conf __rte_unused)
656 {
657         struct pmd_internals *internals = dev->data->dev_private;
658
659         dev->data->tx_queues[tx_queue_id] = &internals->tx_queue[tx_queue_id];
660
661         return 0;
662 }
663
664 static const struct eth_dev_ops ops = {
665         .dev_start = eth_dev_start,
666         .dev_stop = eth_dev_stop,
667         .dev_close = eth_dev_close,
668         .dev_configure = eth_dev_configure,
669         .dev_infos_get = eth_dev_info,
670         .rx_queue_setup = eth_rx_queue_setup,
671         .tx_queue_setup = eth_tx_queue_setup,
672         .rx_queue_release = eth_queue_release,
673         .tx_queue_release = eth_queue_release,
674         .link_update = eth_link_update,
675         .stats_get = eth_stats_get,
676         .stats_reset = eth_stats_reset,
677 };
678
679 /*
680  * Function handler that opens the pcap file for reading a stores a
681  * reference of it for use it later on.
682  */
683 static int
684 open_rx_pcap(const char *key, const char *value, void *extra_args)
685 {
686         unsigned int i;
687         const char *pcap_filename = value;
688         struct pmd_devargs *rx = extra_args;
689         pcap_t *pcap = NULL;
690
691         for (i = 0; i < rx->num_of_queue; i++) {
692                 if (open_single_rx_pcap(pcap_filename, &pcap) < 0)
693                         return -1;
694
695                 rx->queue[i].pcap = pcap;
696                 rx->queue[i].name = pcap_filename;
697                 rx->queue[i].type = key;
698         }
699
700         return 0;
701 }
702
703 /*
704  * Opens a pcap file for writing and stores a reference to it
705  * for use it later on.
706  */
707 static int
708 open_tx_pcap(const char *key, const char *value, void *extra_args)
709 {
710         unsigned int i;
711         const char *pcap_filename = value;
712         struct pmd_devargs *dumpers = extra_args;
713         pcap_dumper_t *dumper;
714
715         for (i = 0; i < dumpers->num_of_queue; i++) {
716                 if (open_single_tx_pcap(pcap_filename, &dumper) < 0)
717                         return -1;
718
719                 dumpers->queue[i].dumper = dumper;
720                 dumpers->queue[i].name = pcap_filename;
721                 dumpers->queue[i].type = key;
722         }
723
724         return 0;
725 }
726
727 /*
728  * Opens an interface for reading and writing
729  */
730 static inline int
731 open_rx_tx_iface(const char *key, const char *value, void *extra_args)
732 {
733         const char *iface = value;
734         struct pmd_devargs *tx = extra_args;
735         pcap_t *pcap = NULL;
736
737         if (open_single_iface(iface, &pcap) < 0)
738                 return -1;
739
740         tx->queue[0].pcap = pcap;
741         tx->queue[0].name = iface;
742         tx->queue[0].type = key;
743
744         return 0;
745 }
746
747 /*
748  * Opens a NIC for reading packets from it
749  */
750 static inline int
751 open_rx_iface(const char *key, const char *value, void *extra_args)
752 {
753         unsigned int i;
754         const char *iface = value;
755         struct pmd_devargs *rx = extra_args;
756         pcap_t *pcap = NULL;
757
758         for (i = 0; i < rx->num_of_queue; i++) {
759                 if (open_single_iface(iface, &pcap) < 0)
760                         return -1;
761                 rx->queue[i].pcap = pcap;
762                 rx->queue[i].name = iface;
763                 rx->queue[i].type = key;
764         }
765
766         return 0;
767 }
768
769 /*
770  * Opens a NIC for writing packets to it
771  */
772 static int
773 open_tx_iface(const char *key, const char *value, void *extra_args)
774 {
775         unsigned int i;
776         const char *iface = value;
777         struct pmd_devargs *tx = extra_args;
778         pcap_t *pcap;
779
780         for (i = 0; i < tx->num_of_queue; i++) {
781                 if (open_single_iface(iface, &pcap) < 0)
782                         return -1;
783                 tx->queue[i].pcap = pcap;
784                 tx->queue[i].name = iface;
785                 tx->queue[i].type = key;
786         }
787
788         return 0;
789 }
790
791 static int
792 pmd_init_internals(const char *name, const unsigned int nb_rx_queues,
793                 const unsigned int nb_tx_queues,
794                 struct pmd_internals **internals,
795                 struct rte_eth_dev **eth_dev)
796 {
797         struct rte_eth_dev_data *data = NULL;
798         unsigned int numa_node = rte_socket_id();
799
800         RTE_LOG(INFO, PMD, "Creating pcap-backed ethdev on numa socket %u\n",
801                 numa_node);
802
803         /* now do all data allocation - for eth_dev structure
804          * and internal (private) data
805          */
806         data = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node);
807         if (data == NULL)
808                 goto error;
809
810         *internals = rte_zmalloc_socket(name, sizeof(**internals), 0,
811                         numa_node);
812         if (*internals == NULL)
813                 goto error;
814
815         /* reserve an ethdev entry */
816         *eth_dev = rte_eth_dev_allocate(name);
817         if (*eth_dev == NULL)
818                 goto error;
819
820         /* now put it all together
821          * - store queue data in internals,
822          * - store numa_node info in eth_dev
823          * - point eth_dev_data to internals
824          * - and point eth_dev structure to new eth_dev_data structure
825          */
826         data->dev_private = *internals;
827         data->port_id = (*eth_dev)->data->port_id;
828         snprintf(data->name, sizeof(data->name), "%s", (*eth_dev)->data->name);
829         data->nb_rx_queues = (uint16_t)nb_rx_queues;
830         data->nb_tx_queues = (uint16_t)nb_tx_queues;
831         data->dev_link = pmd_link;
832         data->mac_addrs = &eth_addr;
833
834         /*
835          * NOTE: we'll replace the data element, of originally allocated
836          * eth_dev so the rings are local per-process
837          */
838         (*eth_dev)->data = data;
839         (*eth_dev)->dev_ops = &ops;
840         (*eth_dev)->driver = NULL;
841         data->dev_flags = RTE_ETH_DEV_DETACHABLE;
842         data->kdrv = RTE_KDRV_NONE;
843         data->drv_name = drivername;
844         data->numa_node = numa_node;
845
846         return 0;
847
848 error:
849         rte_free(data);
850         rte_free(*internals);
851
852         return -1;
853 }
854
855 static int
856 eth_from_pcaps_common(const char *name, struct pmd_devargs *rx_queues,
857                 const unsigned int nb_rx_queues, struct pmd_devargs *tx_queues,
858                 const unsigned int nb_tx_queues, struct rte_kvargs *kvlist,
859                 struct pmd_internals **internals, struct rte_eth_dev **eth_dev)
860 {
861         struct rte_kvargs_pair *pair = NULL;
862         unsigned int k_idx;
863         unsigned int i;
864
865         /* do some parameter checking */
866         if (rx_queues == NULL && nb_rx_queues > 0)
867                 return -1;
868         if (tx_queues == NULL && nb_tx_queues > 0)
869                 return -1;
870
871         if (pmd_init_internals(name, nb_rx_queues, nb_tx_queues, internals,
872                         eth_dev) < 0)
873                 return -1;
874
875         for (i = 0; i < nb_rx_queues; i++) {
876                 struct pcap_rx_queue *rx = &(*internals)->rx_queue[i];
877                 struct devargs_queue *queue = &rx_queues->queue[i];
878
879                 rx->pcap = queue->pcap;
880                 snprintf(rx->name, sizeof(rx->name), "%s", queue->name);
881                 snprintf(rx->type, sizeof(rx->type), "%s", queue->type);
882         }
883
884         for (i = 0; i < nb_tx_queues; i++) {
885                 struct pcap_tx_queue *tx = &(*internals)->tx_queue[i];
886                 struct devargs_queue *queue = &tx_queues->queue[i];
887
888                 tx->dumper = queue->dumper;
889                 tx->pcap = queue->pcap;
890                 snprintf(tx->name, sizeof(tx->name), "%s", queue->name);
891                 snprintf(tx->type, sizeof(tx->type), "%s", queue->type);
892         }
893
894         for (k_idx = 0; k_idx < kvlist->count; k_idx++) {
895                 pair = &kvlist->pairs[k_idx];
896                 if (strstr(pair->key, ETH_PCAP_IFACE_ARG) != NULL)
897                         break;
898         }
899
900         if (pair == NULL)
901                 (*internals)->if_index = 0;
902         else
903                 (*internals)->if_index = if_nametoindex(pair->value);
904
905         return 0;
906 }
907
908 static int
909 eth_from_pcaps(const char *name, struct pmd_devargs *rx_queues,
910                 const unsigned int nb_rx_queues, struct pmd_devargs *tx_queues,
911                 const unsigned int nb_tx_queues, struct rte_kvargs *kvlist,
912                 int single_iface, unsigned int using_dumpers)
913 {
914         struct pmd_internals *internals = NULL;
915         struct rte_eth_dev *eth_dev = NULL;
916         int ret;
917
918         ret = eth_from_pcaps_common(name, rx_queues, nb_rx_queues,
919                 tx_queues, nb_tx_queues, kvlist, &internals, &eth_dev);
920
921         if (ret < 0)
922                 return ret;
923
924         /* store weather we are using a single interface for rx/tx or not */
925         internals->single_iface = single_iface;
926
927         eth_dev->rx_pkt_burst = eth_pcap_rx;
928
929         if (using_dumpers)
930                 eth_dev->tx_pkt_burst = eth_pcap_tx_dumper;
931         else
932                 eth_dev->tx_pkt_burst = eth_pcap_tx;
933
934         return 0;
935 }
936
937 static int
938 pmd_pcap_devinit(const char *name, const char *params)
939 {
940         unsigned int is_rx_pcap = 0, is_tx_pcap = 0;
941         struct rte_kvargs *kvlist;
942         struct pmd_devargs pcaps = {0};
943         struct pmd_devargs dumpers = {0};
944         int single_iface = 0;
945         int ret;
946
947         RTE_LOG(INFO, PMD, "Initializing pmd_pcap for %s\n", name);
948
949         gettimeofday(&start_time, NULL);
950         start_cycles = rte_get_timer_cycles();
951         hz = rte_get_timer_hz();
952
953         kvlist = rte_kvargs_parse(params, valid_arguments);
954         if (kvlist == NULL)
955                 return -1;
956
957         /*
958          * If iface argument is passed we open the NICs and use them for
959          * reading / writing
960          */
961         if (rte_kvargs_count(kvlist, ETH_PCAP_IFACE_ARG) == 1) {
962
963                 ret = rte_kvargs_process(kvlist, ETH_PCAP_IFACE_ARG,
964                                 &open_rx_tx_iface, &pcaps);
965
966                 if (ret < 0)
967                         goto free_kvlist;
968
969                 dumpers.queue[0] = pcaps.queue[0];
970
971                 single_iface = 1;
972                 pcaps.num_of_queue = 1;
973                 dumpers.num_of_queue = 1;
974
975                 goto create_eth;
976         }
977
978         /*
979          * We check whether we want to open a RX stream from a real NIC or a
980          * pcap file
981          */
982         pcaps.num_of_queue = rte_kvargs_count(kvlist, ETH_PCAP_RX_PCAP_ARG);
983         if (pcaps.num_of_queue)
984                 is_rx_pcap = 1;
985         else
986                 pcaps.num_of_queue = rte_kvargs_count(kvlist,
987                                 ETH_PCAP_RX_IFACE_ARG);
988
989         if (pcaps.num_of_queue > RTE_PMD_PCAP_MAX_QUEUES)
990                 pcaps.num_of_queue = RTE_PMD_PCAP_MAX_QUEUES;
991
992         if (is_rx_pcap)
993                 ret = rte_kvargs_process(kvlist, ETH_PCAP_RX_PCAP_ARG,
994                                 &open_rx_pcap, &pcaps);
995         else
996                 ret = rte_kvargs_process(kvlist, ETH_PCAP_RX_IFACE_ARG,
997                                 &open_rx_iface, &pcaps);
998
999         if (ret < 0)
1000                 goto free_kvlist;
1001
1002         /*
1003          * We check whether we want to open a TX stream to a real NIC or a
1004          * pcap file
1005          */
1006         dumpers.num_of_queue = rte_kvargs_count(kvlist, ETH_PCAP_TX_PCAP_ARG);
1007         if (dumpers.num_of_queue)
1008                 is_tx_pcap = 1;
1009         else
1010                 dumpers.num_of_queue = rte_kvargs_count(kvlist,
1011                                 ETH_PCAP_TX_IFACE_ARG);
1012
1013         if (dumpers.num_of_queue > RTE_PMD_PCAP_MAX_QUEUES)
1014                 dumpers.num_of_queue = RTE_PMD_PCAP_MAX_QUEUES;
1015
1016         if (is_tx_pcap)
1017                 ret = rte_kvargs_process(kvlist, ETH_PCAP_TX_PCAP_ARG,
1018                                 &open_tx_pcap, &dumpers);
1019         else
1020                 ret = rte_kvargs_process(kvlist, ETH_PCAP_TX_IFACE_ARG,
1021                                 &open_tx_iface, &dumpers);
1022
1023         if (ret < 0)
1024                 goto free_kvlist;
1025
1026 create_eth:
1027         ret = eth_from_pcaps(name, &pcaps, pcaps.num_of_queue, &dumpers,
1028                 dumpers.num_of_queue, kvlist, single_iface, is_tx_pcap);
1029
1030 free_kvlist:
1031         rte_kvargs_free(kvlist);
1032
1033         return ret;
1034 }
1035
1036 static int
1037 pmd_pcap_devuninit(const char *name)
1038 {
1039         struct rte_eth_dev *eth_dev = NULL;
1040
1041         RTE_LOG(INFO, PMD, "Closing pcap ethdev on numa socket %u\n",
1042                         rte_socket_id());
1043
1044         if (name == NULL)
1045                 return -1;
1046
1047         /* reserve an ethdev entry */
1048         eth_dev = rte_eth_dev_allocated(name);
1049         if (eth_dev == NULL)
1050                 return -1;
1051
1052         rte_free(eth_dev->data->dev_private);
1053         rte_free(eth_dev->data);
1054
1055         rte_eth_dev_release_port(eth_dev);
1056
1057         return 0;
1058 }
1059
1060 static struct rte_vdev_driver pmd_pcap_drv = {
1061         .init = pmd_pcap_devinit,
1062         .uninit = pmd_pcap_devuninit,
1063 };
1064
1065 DRIVER_REGISTER_VDEV(net_pcap, pmd_pcap_drv);
1066 DRIVER_REGISTER_PARAM_STRING(net_pcap,
1067         ETH_PCAP_RX_PCAP_ARG "=<string> "
1068         ETH_PCAP_TX_PCAP_ARG "=<string> "
1069         ETH_PCAP_RX_IFACE_ARG "=<ifc> "
1070         ETH_PCAP_TX_IFACE_ARG "=<ifc> "
1071         ETH_PCAP_IFACE_ARG "=<ifc>");