1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2016 Intel Corporation. 3 * Copyright(c) 2014 6WIND S.A. 4 * All rights reserved. 5 */ 6 7 #include <stdlib.h> 8 #include <time.h> 9 10 #include <pcap.h> 11 12 #include <rte_cycles.h> 13 #include <ethdev_driver.h> 14 #include <ethdev_vdev.h> 15 #include <rte_kvargs.h> 16 #include <rte_malloc.h> 17 #include <rte_mbuf.h> 18 #include <rte_mbuf_dyn.h> 19 #include <bus_vdev_driver.h> 20 #include <rte_os_shim.h> 21 22 #include "pcap_osdep.h" 23 24 #define RTE_ETH_PCAP_SNAPSHOT_LEN 65535 25 #define RTE_ETH_PCAP_SNAPLEN RTE_ETHER_MAX_JUMBO_FRAME_LEN 26 #define RTE_ETH_PCAP_PROMISC 1 27 #define RTE_ETH_PCAP_TIMEOUT -1 28 29 #define ETH_PCAP_RX_PCAP_ARG "rx_pcap" 30 #define ETH_PCAP_TX_PCAP_ARG "tx_pcap" 31 #define ETH_PCAP_RX_IFACE_ARG "rx_iface" 32 #define ETH_PCAP_RX_IFACE_IN_ARG "rx_iface_in" 33 #define ETH_PCAP_TX_IFACE_ARG "tx_iface" 34 #define ETH_PCAP_IFACE_ARG "iface" 35 #define ETH_PCAP_PHY_MAC_ARG "phy_mac" 36 #define ETH_PCAP_INFINITE_RX_ARG "infinite_rx" 37 38 #define ETH_PCAP_ARG_MAXLEN 64 39 40 #define RTE_PMD_PCAP_MAX_QUEUES 16 41 42 static char errbuf[PCAP_ERRBUF_SIZE]; 43 static struct timespec start_time; 44 static uint64_t start_cycles; 45 static uint64_t hz; 46 static uint8_t iface_idx; 47 48 static uint64_t timestamp_rx_dynflag; 49 static int timestamp_dynfield_offset = -1; 50 51 struct queue_stat { 52 volatile unsigned long pkts; 53 volatile unsigned long bytes; 54 volatile unsigned long err_pkts; 55 volatile unsigned long rx_nombuf; 56 }; 57 58 struct queue_missed_stat { 59 /* last value retrieved from pcap */ 60 unsigned int pcap; 61 /* stores values lost by pcap stop or rollover */ 62 unsigned long mnemonic; 63 /* value on last reset */ 64 unsigned long reset; 65 }; 66 67 struct pcap_rx_queue { 68 uint16_t port_id; 69 uint16_t queue_id; 70 struct rte_mempool *mb_pool; 71 struct queue_stat rx_stat; 72 struct queue_missed_stat missed_stat; 73 char name[PATH_MAX]; 74 char type[ETH_PCAP_ARG_MAXLEN]; 75 76 /* Contains pre-generated packets to be looped through */ 77 struct rte_ring *pkts; 78 }; 79 80 struct pcap_tx_queue { 81 uint16_t port_id; 82 uint16_t queue_id; 83 struct queue_stat tx_stat; 84 char name[PATH_MAX]; 85 char type[ETH_PCAP_ARG_MAXLEN]; 86 }; 87 88 struct pmd_internals { 89 struct pcap_rx_queue rx_queue[RTE_PMD_PCAP_MAX_QUEUES]; 90 struct pcap_tx_queue tx_queue[RTE_PMD_PCAP_MAX_QUEUES]; 91 char devargs[ETH_PCAP_ARG_MAXLEN]; 92 struct rte_ether_addr eth_addr; 93 int if_index; 94 int single_iface; 95 int phy_mac; 96 unsigned int infinite_rx; 97 }; 98 99 struct pmd_process_private { 100 pcap_t *rx_pcap[RTE_PMD_PCAP_MAX_QUEUES]; 101 pcap_t *tx_pcap[RTE_PMD_PCAP_MAX_QUEUES]; 102 pcap_dumper_t *tx_dumper[RTE_PMD_PCAP_MAX_QUEUES]; 103 }; 104 105 struct pmd_devargs { 106 unsigned int num_of_queue; 107 struct devargs_queue { 108 pcap_dumper_t *dumper; 109 pcap_t *pcap; 110 const char *name; 111 const char *type; 112 } queue[RTE_PMD_PCAP_MAX_QUEUES]; 113 int phy_mac; 114 }; 115 116 struct pmd_devargs_all { 117 struct pmd_devargs rx_queues; 118 struct pmd_devargs tx_queues; 119 int single_iface; 120 unsigned int is_tx_pcap; 121 unsigned int is_tx_iface; 122 unsigned int is_rx_pcap; 123 unsigned int is_rx_iface; 124 unsigned int infinite_rx; 125 }; 126 127 static const char *valid_arguments[] = { 128 ETH_PCAP_RX_PCAP_ARG, 129 ETH_PCAP_TX_PCAP_ARG, 130 ETH_PCAP_RX_IFACE_ARG, 131 ETH_PCAP_RX_IFACE_IN_ARG, 132 ETH_PCAP_TX_IFACE_ARG, 133 ETH_PCAP_IFACE_ARG, 134 ETH_PCAP_PHY_MAC_ARG, 135 ETH_PCAP_INFINITE_RX_ARG, 136 NULL 137 }; 138 139 static struct rte_eth_link pmd_link = { 140 .link_speed = RTE_ETH_SPEED_NUM_10G, 141 .link_duplex = RTE_ETH_LINK_FULL_DUPLEX, 142 .link_status = RTE_ETH_LINK_DOWN, 143 .link_autoneg = RTE_ETH_LINK_FIXED, 144 }; 145 146 RTE_LOG_REGISTER_DEFAULT(eth_pcap_logtype, NOTICE); 147 148 static struct queue_missed_stat* 149 queue_missed_stat_update(struct rte_eth_dev *dev, unsigned int qid) 150 { 151 struct pmd_internals *internals = dev->data->dev_private; 152 struct queue_missed_stat *missed_stat = 153 &internals->rx_queue[qid].missed_stat; 154 const struct pmd_process_private *pp = dev->process_private; 155 pcap_t *pcap = pp->rx_pcap[qid]; 156 struct pcap_stat stat; 157 158 if (!pcap || (pcap_stats(pcap, &stat) != 0)) 159 return missed_stat; 160 161 /* rollover check - best effort fixup assuming single rollover */ 162 if (stat.ps_drop < missed_stat->pcap) 163 missed_stat->mnemonic += UINT_MAX; 164 missed_stat->pcap = stat.ps_drop; 165 166 return missed_stat; 167 } 168 169 static void 170 queue_missed_stat_on_stop_update(struct rte_eth_dev *dev, unsigned int qid) 171 { 172 struct queue_missed_stat *missed_stat = 173 queue_missed_stat_update(dev, qid); 174 175 missed_stat->mnemonic += missed_stat->pcap; 176 missed_stat->pcap = 0; 177 } 178 179 static void 180 queue_missed_stat_reset(struct rte_eth_dev *dev, unsigned int qid) 181 { 182 struct queue_missed_stat *missed_stat = 183 queue_missed_stat_update(dev, qid); 184 185 missed_stat->reset = missed_stat->pcap; 186 missed_stat->mnemonic = 0; 187 } 188 189 static unsigned long 190 queue_missed_stat_get(struct rte_eth_dev *dev, unsigned int qid) 191 { 192 const struct queue_missed_stat *missed_stat = 193 queue_missed_stat_update(dev, qid); 194 195 return missed_stat->pcap + missed_stat->mnemonic - missed_stat->reset; 196 } 197 198 static int 199 eth_pcap_rx_jumbo(struct rte_mempool *mb_pool, struct rte_mbuf *mbuf, 200 const u_char *data, uint16_t data_len) 201 { 202 /* Copy the first segment. */ 203 uint16_t len = rte_pktmbuf_tailroom(mbuf); 204 struct rte_mbuf *m = mbuf; 205 206 rte_memcpy(rte_pktmbuf_append(mbuf, len), data, len); 207 data_len -= len; 208 data += len; 209 210 while (data_len > 0) { 211 /* Allocate next mbuf and point to that. */ 212 m->next = rte_pktmbuf_alloc(mb_pool); 213 214 if (unlikely(!m->next)) 215 return -1; 216 217 m = m->next; 218 219 /* Headroom is not needed in chained mbufs. */ 220 rte_pktmbuf_prepend(m, rte_pktmbuf_headroom(m)); 221 m->pkt_len = 0; 222 m->data_len = 0; 223 224 /* Copy next segment. */ 225 len = RTE_MIN(rte_pktmbuf_tailroom(m), data_len); 226 rte_memcpy(rte_pktmbuf_append(m, len), data, len); 227 228 mbuf->nb_segs++; 229 data_len -= len; 230 data += len; 231 } 232 233 return mbuf->nb_segs; 234 } 235 236 static uint16_t 237 eth_pcap_rx_infinite(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) 238 { 239 int i; 240 struct pcap_rx_queue *pcap_q = queue; 241 uint32_t rx_bytes = 0; 242 243 if (unlikely(nb_pkts == 0)) 244 return 0; 245 246 if (rte_pktmbuf_alloc_bulk(pcap_q->mb_pool, bufs, nb_pkts) != 0) 247 return 0; 248 249 for (i = 0; i < nb_pkts; i++) { 250 struct rte_mbuf *pcap_buf; 251 int err = rte_ring_dequeue(pcap_q->pkts, (void **)&pcap_buf); 252 if (err) 253 return i; 254 255 rte_memcpy(rte_pktmbuf_mtod(bufs[i], void *), 256 rte_pktmbuf_mtod(pcap_buf, void *), 257 pcap_buf->data_len); 258 bufs[i]->data_len = pcap_buf->data_len; 259 bufs[i]->pkt_len = pcap_buf->pkt_len; 260 bufs[i]->port = pcap_q->port_id; 261 rx_bytes += pcap_buf->data_len; 262 263 /* Enqueue packet back on ring to allow infinite rx. */ 264 rte_ring_enqueue(pcap_q->pkts, pcap_buf); 265 } 266 267 pcap_q->rx_stat.pkts += i; 268 pcap_q->rx_stat.bytes += rx_bytes; 269 270 return i; 271 } 272 273 static uint16_t 274 eth_pcap_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) 275 { 276 unsigned int i; 277 struct pcap_pkthdr header; 278 struct pmd_process_private *pp; 279 const u_char *packet; 280 struct rte_mbuf *mbuf; 281 struct pcap_rx_queue *pcap_q = queue; 282 uint16_t num_rx = 0; 283 uint32_t rx_bytes = 0; 284 pcap_t *pcap; 285 286 pp = rte_eth_devices[pcap_q->port_id].process_private; 287 pcap = pp->rx_pcap[pcap_q->queue_id]; 288 289 if (unlikely(pcap == NULL || nb_pkts == 0)) 290 return 0; 291 292 /* Reads the given number of packets from the pcap file one by one 293 * and copies the packet data into a newly allocated mbuf to return. 294 */ 295 for (i = 0; i < nb_pkts; i++) { 296 /* Get the next PCAP packet */ 297 packet = pcap_next(pcap, &header); 298 if (unlikely(packet == NULL)) 299 break; 300 301 mbuf = rte_pktmbuf_alloc(pcap_q->mb_pool); 302 if (unlikely(mbuf == NULL)) { 303 pcap_q->rx_stat.rx_nombuf++; 304 break; 305 } 306 307 if (header.caplen <= rte_pktmbuf_tailroom(mbuf)) { 308 /* pcap packet will fit in the mbuf, can copy it */ 309 rte_memcpy(rte_pktmbuf_mtod(mbuf, void *), packet, 310 header.caplen); 311 mbuf->data_len = (uint16_t)header.caplen; 312 } else { 313 /* Try read jumbo frame into multi mbufs. */ 314 if (unlikely(eth_pcap_rx_jumbo(pcap_q->mb_pool, 315 mbuf, 316 packet, 317 header.caplen) == -1)) { 318 pcap_q->rx_stat.err_pkts++; 319 rte_pktmbuf_free(mbuf); 320 break; 321 } 322 } 323 324 mbuf->pkt_len = (uint16_t)header.caplen; 325 *RTE_MBUF_DYNFIELD(mbuf, timestamp_dynfield_offset, 326 rte_mbuf_timestamp_t *) = 327 (uint64_t)header.ts.tv_sec * 1000000 + 328 header.ts.tv_usec; 329 mbuf->ol_flags |= timestamp_rx_dynflag; 330 mbuf->port = pcap_q->port_id; 331 bufs[num_rx] = mbuf; 332 num_rx++; 333 rx_bytes += header.caplen; 334 } 335 pcap_q->rx_stat.pkts += num_rx; 336 pcap_q->rx_stat.bytes += rx_bytes; 337 338 return num_rx; 339 } 340 341 static uint16_t 342 eth_null_rx(void *queue __rte_unused, 343 struct rte_mbuf **bufs __rte_unused, 344 uint16_t nb_pkts __rte_unused) 345 { 346 return 0; 347 } 348 349 #define NSEC_PER_SEC 1000000000L 350 351 /* 352 * This function stores nanoseconds in `tv_usec` field of `struct timeval`, 353 * because `ts` goes directly to nanosecond-precision dump. 354 */ 355 static inline void 356 calculate_timestamp(struct timeval *ts) { 357 uint64_t cycles; 358 struct timespec cur_time; 359 360 cycles = rte_get_timer_cycles() - start_cycles; 361 cur_time.tv_sec = cycles / hz; 362 cur_time.tv_nsec = (cycles % hz) * NSEC_PER_SEC / hz; 363 364 ts->tv_sec = start_time.tv_sec + cur_time.tv_sec; 365 ts->tv_usec = start_time.tv_nsec + cur_time.tv_nsec; 366 if (ts->tv_usec >= NSEC_PER_SEC) { 367 ts->tv_usec -= NSEC_PER_SEC; 368 ts->tv_sec += 1; 369 } 370 } 371 372 /* 373 * Callback to handle writing packets to a pcap file. 374 */ 375 static uint16_t 376 eth_pcap_tx_dumper(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) 377 { 378 unsigned int i; 379 struct rte_mbuf *mbuf; 380 struct pmd_process_private *pp; 381 struct pcap_tx_queue *dumper_q = queue; 382 uint16_t num_tx = 0; 383 uint32_t tx_bytes = 0; 384 struct pcap_pkthdr header; 385 pcap_dumper_t *dumper; 386 unsigned char temp_data[RTE_ETH_PCAP_SNAPLEN]; 387 size_t len, caplen; 388 389 pp = rte_eth_devices[dumper_q->port_id].process_private; 390 dumper = pp->tx_dumper[dumper_q->queue_id]; 391 392 if (dumper == NULL || nb_pkts == 0) 393 return 0; 394 395 /* writes the nb_pkts packets to the previously opened pcap file 396 * dumper */ 397 for (i = 0; i < nb_pkts; i++) { 398 mbuf = bufs[i]; 399 len = caplen = rte_pktmbuf_pkt_len(mbuf); 400 if (unlikely(!rte_pktmbuf_is_contiguous(mbuf) && 401 len > sizeof(temp_data))) { 402 caplen = sizeof(temp_data); 403 } 404 405 calculate_timestamp(&header.ts); 406 header.len = len; 407 header.caplen = caplen; 408 /* rte_pktmbuf_read() returns a pointer to the data directly 409 * in the mbuf (when the mbuf is contiguous) or, otherwise, 410 * a pointer to temp_data after copying into it. 411 */ 412 pcap_dump((u_char *)dumper, &header, 413 rte_pktmbuf_read(mbuf, 0, caplen, temp_data)); 414 415 num_tx++; 416 tx_bytes += caplen; 417 rte_pktmbuf_free(mbuf); 418 } 419 420 /* 421 * Since there's no place to hook a callback when the forwarding 422 * process stops and to make sure the pcap file is actually written, 423 * we flush the pcap dumper within each burst. 424 */ 425 pcap_dump_flush(dumper); 426 dumper_q->tx_stat.pkts += num_tx; 427 dumper_q->tx_stat.bytes += tx_bytes; 428 dumper_q->tx_stat.err_pkts += nb_pkts - num_tx; 429 430 return nb_pkts; 431 } 432 433 /* 434 * Callback to handle dropping packets in the infinite rx case. 435 */ 436 static uint16_t 437 eth_tx_drop(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) 438 { 439 unsigned int i; 440 uint32_t tx_bytes = 0; 441 struct pcap_tx_queue *tx_queue = queue; 442 443 if (unlikely(nb_pkts == 0)) 444 return 0; 445 446 for (i = 0; i < nb_pkts; i++) { 447 tx_bytes += bufs[i]->pkt_len; 448 rte_pktmbuf_free(bufs[i]); 449 } 450 451 tx_queue->tx_stat.pkts += nb_pkts; 452 tx_queue->tx_stat.bytes += tx_bytes; 453 454 return i; 455 } 456 457 /* 458 * Callback to handle sending packets through a real NIC. 459 */ 460 static uint16_t 461 eth_pcap_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts) 462 { 463 unsigned int i; 464 int ret; 465 struct rte_mbuf *mbuf; 466 struct pmd_process_private *pp; 467 struct pcap_tx_queue *tx_queue = queue; 468 uint16_t num_tx = 0; 469 uint32_t tx_bytes = 0; 470 pcap_t *pcap; 471 unsigned char temp_data[RTE_ETH_PCAP_SNAPLEN]; 472 size_t len; 473 474 pp = rte_eth_devices[tx_queue->port_id].process_private; 475 pcap = pp->tx_pcap[tx_queue->queue_id]; 476 477 if (unlikely(nb_pkts == 0 || pcap == NULL)) 478 return 0; 479 480 for (i = 0; i < nb_pkts; i++) { 481 mbuf = bufs[i]; 482 len = rte_pktmbuf_pkt_len(mbuf); 483 if (unlikely(!rte_pktmbuf_is_contiguous(mbuf) && 484 len > sizeof(temp_data))) { 485 PMD_LOG(ERR, 486 "Dropping multi segment PCAP packet. Size (%zd) > max size (%zd).", 487 len, sizeof(temp_data)); 488 rte_pktmbuf_free(mbuf); 489 continue; 490 } 491 492 /* rte_pktmbuf_read() returns a pointer to the data directly 493 * in the mbuf (when the mbuf is contiguous) or, otherwise, 494 * a pointer to temp_data after copying into it. 495 */ 496 ret = pcap_sendpacket(pcap, 497 rte_pktmbuf_read(mbuf, 0, len, temp_data), len); 498 if (unlikely(ret != 0)) 499 break; 500 num_tx++; 501 tx_bytes += len; 502 rte_pktmbuf_free(mbuf); 503 } 504 505 tx_queue->tx_stat.pkts += num_tx; 506 tx_queue->tx_stat.bytes += tx_bytes; 507 tx_queue->tx_stat.err_pkts += i - num_tx; 508 509 return i; 510 } 511 512 /* 513 * pcap_open_live wrapper function 514 */ 515 static inline int 516 open_iface_live(const char *iface, pcap_t **pcap) { 517 *pcap = pcap_open_live(iface, RTE_ETH_PCAP_SNAPLEN, 518 RTE_ETH_PCAP_PROMISC, RTE_ETH_PCAP_TIMEOUT, errbuf); 519 520 if (*pcap == NULL) { 521 PMD_LOG(ERR, "Couldn't open %s: %s", iface, errbuf); 522 return -1; 523 } 524 525 return 0; 526 } 527 528 static int 529 open_single_iface(const char *iface, pcap_t **pcap) 530 { 531 if (open_iface_live(iface, pcap) < 0) { 532 PMD_LOG(ERR, "Couldn't open interface %s", iface); 533 return -1; 534 } 535 536 return 0; 537 } 538 539 static int 540 open_single_tx_pcap(const char *pcap_filename, pcap_dumper_t **dumper) 541 { 542 pcap_t *tx_pcap; 543 544 /* 545 * We need to create a dummy empty pcap_t to use it 546 * with pcap_dump_open(). We create big enough an Ethernet 547 * pcap holder. 548 */ 549 tx_pcap = pcap_open_dead_with_tstamp_precision(DLT_EN10MB, 550 RTE_ETH_PCAP_SNAPSHOT_LEN, PCAP_TSTAMP_PRECISION_NANO); 551 if (tx_pcap == NULL) { 552 PMD_LOG(ERR, "Couldn't create dead pcap"); 553 return -1; 554 } 555 556 /* The dumper is created using the previous pcap_t reference */ 557 *dumper = pcap_dump_open(tx_pcap, pcap_filename); 558 if (*dumper == NULL) { 559 pcap_close(tx_pcap); 560 PMD_LOG(ERR, "Couldn't open %s for writing.", 561 pcap_filename); 562 return -1; 563 } 564 565 pcap_close(tx_pcap); 566 return 0; 567 } 568 569 static int 570 open_single_rx_pcap(const char *pcap_filename, pcap_t **pcap) 571 { 572 *pcap = pcap_open_offline(pcap_filename, errbuf); 573 if (*pcap == NULL) { 574 PMD_LOG(ERR, "Couldn't open %s: %s", pcap_filename, 575 errbuf); 576 return -1; 577 } 578 579 return 0; 580 } 581 582 static uint64_t 583 count_packets_in_pcap(pcap_t **pcap, struct pcap_rx_queue *pcap_q) 584 { 585 const u_char *packet; 586 struct pcap_pkthdr header; 587 uint64_t pcap_pkt_count = 0; 588 589 while ((packet = pcap_next(*pcap, &header))) 590 pcap_pkt_count++; 591 592 /* The pcap is reopened so it can be used as normal later. */ 593 pcap_close(*pcap); 594 *pcap = NULL; 595 open_single_rx_pcap(pcap_q->name, pcap); 596 597 return pcap_pkt_count; 598 } 599 600 static int 601 eth_dev_start(struct rte_eth_dev *dev) 602 { 603 unsigned int i; 604 struct pmd_internals *internals = dev->data->dev_private; 605 struct pmd_process_private *pp = dev->process_private; 606 struct pcap_tx_queue *tx; 607 struct pcap_rx_queue *rx; 608 609 /* Special iface case. Single pcap is open and shared between tx/rx. */ 610 if (internals->single_iface) { 611 tx = &internals->tx_queue[0]; 612 rx = &internals->rx_queue[0]; 613 614 if (!pp->tx_pcap[0] && 615 strcmp(tx->type, ETH_PCAP_IFACE_ARG) == 0) { 616 if (open_single_iface(tx->name, &pp->tx_pcap[0]) < 0) 617 return -1; 618 pp->rx_pcap[0] = pp->tx_pcap[0]; 619 } 620 621 goto status_up; 622 } 623 624 /* If not open already, open tx pcaps/dumpers */ 625 for (i = 0; i < dev->data->nb_tx_queues; i++) { 626 tx = &internals->tx_queue[i]; 627 628 if (!pp->tx_dumper[i] && 629 strcmp(tx->type, ETH_PCAP_TX_PCAP_ARG) == 0) { 630 if (open_single_tx_pcap(tx->name, 631 &pp->tx_dumper[i]) < 0) 632 return -1; 633 } else if (!pp->tx_pcap[i] && 634 strcmp(tx->type, ETH_PCAP_TX_IFACE_ARG) == 0) { 635 if (open_single_iface(tx->name, &pp->tx_pcap[i]) < 0) 636 return -1; 637 } 638 } 639 640 /* If not open already, open rx pcaps */ 641 for (i = 0; i < dev->data->nb_rx_queues; i++) { 642 rx = &internals->rx_queue[i]; 643 644 if (pp->rx_pcap[i] != NULL) 645 continue; 646 647 if (strcmp(rx->type, ETH_PCAP_RX_PCAP_ARG) == 0) { 648 if (open_single_rx_pcap(rx->name, &pp->rx_pcap[i]) < 0) 649 return -1; 650 } else if (strcmp(rx->type, ETH_PCAP_RX_IFACE_ARG) == 0) { 651 if (open_single_iface(rx->name, &pp->rx_pcap[i]) < 0) 652 return -1; 653 } 654 } 655 656 status_up: 657 for (i = 0; i < dev->data->nb_rx_queues; i++) 658 dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED; 659 660 for (i = 0; i < dev->data->nb_tx_queues; i++) 661 dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED; 662 663 dev->data->dev_link.link_status = RTE_ETH_LINK_UP; 664 665 return 0; 666 } 667 668 /* 669 * This function gets called when the current port gets stopped. 670 * Is the only place for us to close all the tx streams dumpers. 671 * If not called the dumpers will be flushed within each tx burst. 672 */ 673 static int 674 eth_dev_stop(struct rte_eth_dev *dev) 675 { 676 unsigned int i; 677 struct pmd_internals *internals = dev->data->dev_private; 678 struct pmd_process_private *pp = dev->process_private; 679 680 /* Special iface case. Single pcap is open and shared between tx/rx. */ 681 if (internals->single_iface) { 682 queue_missed_stat_on_stop_update(dev, 0); 683 if (pp->tx_pcap[0] != NULL) { 684 pcap_close(pp->tx_pcap[0]); 685 pp->tx_pcap[0] = NULL; 686 pp->rx_pcap[0] = NULL; 687 } 688 goto status_down; 689 } 690 691 for (i = 0; i < dev->data->nb_tx_queues; i++) { 692 if (pp->tx_dumper[i] != NULL) { 693 pcap_dump_close(pp->tx_dumper[i]); 694 pp->tx_dumper[i] = NULL; 695 } 696 697 if (pp->tx_pcap[i] != NULL) { 698 pcap_close(pp->tx_pcap[i]); 699 pp->tx_pcap[i] = NULL; 700 } 701 } 702 703 for (i = 0; i < dev->data->nb_rx_queues; i++) { 704 if (pp->rx_pcap[i] != NULL) { 705 queue_missed_stat_on_stop_update(dev, i); 706 pcap_close(pp->rx_pcap[i]); 707 pp->rx_pcap[i] = NULL; 708 } 709 } 710 711 status_down: 712 for (i = 0; i < dev->data->nb_rx_queues; i++) 713 dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED; 714 715 for (i = 0; i < dev->data->nb_tx_queues; i++) 716 dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED; 717 718 dev->data->dev_link.link_status = RTE_ETH_LINK_DOWN; 719 720 return 0; 721 } 722 723 static int 724 eth_dev_configure(struct rte_eth_dev *dev __rte_unused) 725 { 726 return 0; 727 } 728 729 static int 730 eth_dev_info(struct rte_eth_dev *dev, 731 struct rte_eth_dev_info *dev_info) 732 { 733 struct pmd_internals *internals = dev->data->dev_private; 734 735 dev_info->if_index = internals->if_index; 736 dev_info->max_mac_addrs = 1; 737 dev_info->max_rx_pktlen = (uint32_t) -1; 738 dev_info->max_rx_queues = dev->data->nb_rx_queues; 739 dev_info->max_tx_queues = dev->data->nb_tx_queues; 740 dev_info->min_rx_bufsize = 0; 741 742 return 0; 743 } 744 745 static int 746 eth_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) 747 { 748 unsigned int i; 749 unsigned long rx_packets_total = 0, rx_bytes_total = 0; 750 unsigned long rx_missed_total = 0; 751 unsigned long rx_nombuf_total = 0, rx_err_total = 0; 752 unsigned long tx_packets_total = 0, tx_bytes_total = 0; 753 unsigned long tx_packets_err_total = 0; 754 const struct pmd_internals *internal = dev->data->dev_private; 755 756 for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS && 757 i < dev->data->nb_rx_queues; i++) { 758 stats->q_ipackets[i] = internal->rx_queue[i].rx_stat.pkts; 759 stats->q_ibytes[i] = internal->rx_queue[i].rx_stat.bytes; 760 rx_nombuf_total += internal->rx_queue[i].rx_stat.rx_nombuf; 761 rx_err_total += internal->rx_queue[i].rx_stat.err_pkts; 762 rx_packets_total += stats->q_ipackets[i]; 763 rx_bytes_total += stats->q_ibytes[i]; 764 rx_missed_total += queue_missed_stat_get(dev, i); 765 } 766 767 for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS && 768 i < dev->data->nb_tx_queues; i++) { 769 stats->q_opackets[i] = internal->tx_queue[i].tx_stat.pkts; 770 stats->q_obytes[i] = internal->tx_queue[i].tx_stat.bytes; 771 tx_packets_total += stats->q_opackets[i]; 772 tx_bytes_total += stats->q_obytes[i]; 773 tx_packets_err_total += internal->tx_queue[i].tx_stat.err_pkts; 774 } 775 776 stats->ipackets = rx_packets_total; 777 stats->ibytes = rx_bytes_total; 778 stats->imissed = rx_missed_total; 779 stats->ierrors = rx_err_total; 780 stats->rx_nombuf = rx_nombuf_total; 781 stats->opackets = tx_packets_total; 782 stats->obytes = tx_bytes_total; 783 stats->oerrors = tx_packets_err_total; 784 785 return 0; 786 } 787 788 static int 789 eth_stats_reset(struct rte_eth_dev *dev) 790 { 791 unsigned int i; 792 struct pmd_internals *internal = dev->data->dev_private; 793 794 for (i = 0; i < dev->data->nb_rx_queues; i++) { 795 internal->rx_queue[i].rx_stat.pkts = 0; 796 internal->rx_queue[i].rx_stat.bytes = 0; 797 internal->rx_queue[i].rx_stat.err_pkts = 0; 798 internal->rx_queue[i].rx_stat.rx_nombuf = 0; 799 queue_missed_stat_reset(dev, i); 800 } 801 802 for (i = 0; i < dev->data->nb_tx_queues; i++) { 803 internal->tx_queue[i].tx_stat.pkts = 0; 804 internal->tx_queue[i].tx_stat.bytes = 0; 805 internal->tx_queue[i].tx_stat.err_pkts = 0; 806 } 807 808 return 0; 809 } 810 811 static inline void 812 infinite_rx_ring_free(struct rte_ring *pkts) 813 { 814 struct rte_mbuf *bufs; 815 816 while (!rte_ring_dequeue(pkts, (void **)&bufs)) 817 rte_pktmbuf_free(bufs); 818 819 rte_ring_free(pkts); 820 } 821 822 static int 823 eth_dev_close(struct rte_eth_dev *dev) 824 { 825 unsigned int i; 826 struct pmd_internals *internals = dev->data->dev_private; 827 828 PMD_LOG(INFO, "Closing pcap ethdev on NUMA socket %d", 829 rte_socket_id()); 830 831 eth_dev_stop(dev); 832 833 rte_free(dev->process_private); 834 835 if (rte_eal_process_type() != RTE_PROC_PRIMARY) 836 return 0; 837 838 /* Device wide flag, but cleanup must be performed per queue. */ 839 if (internals->infinite_rx) { 840 for (i = 0; i < dev->data->nb_rx_queues; i++) { 841 struct pcap_rx_queue *pcap_q = &internals->rx_queue[i]; 842 843 /* 844 * 'pcap_q->pkts' can be NULL if 'eth_dev_close()' 845 * called before 'eth_rx_queue_setup()' has been called 846 */ 847 if (pcap_q->pkts == NULL) 848 continue; 849 850 infinite_rx_ring_free(pcap_q->pkts); 851 } 852 } 853 854 if (internals->phy_mac == 0) 855 /* not dynamically allocated, must not be freed */ 856 dev->data->mac_addrs = NULL; 857 858 return 0; 859 } 860 861 static int 862 eth_link_update(struct rte_eth_dev *dev __rte_unused, 863 int wait_to_complete __rte_unused) 864 { 865 return 0; 866 } 867 868 static int 869 eth_rx_queue_setup(struct rte_eth_dev *dev, 870 uint16_t rx_queue_id, 871 uint16_t nb_rx_desc __rte_unused, 872 unsigned int socket_id __rte_unused, 873 const struct rte_eth_rxconf *rx_conf __rte_unused, 874 struct rte_mempool *mb_pool) 875 { 876 struct pmd_internals *internals = dev->data->dev_private; 877 struct pcap_rx_queue *pcap_q = &internals->rx_queue[rx_queue_id]; 878 879 pcap_q->mb_pool = mb_pool; 880 pcap_q->port_id = dev->data->port_id; 881 pcap_q->queue_id = rx_queue_id; 882 dev->data->rx_queues[rx_queue_id] = pcap_q; 883 884 if (internals->infinite_rx) { 885 struct pmd_process_private *pp; 886 char ring_name[RTE_RING_NAMESIZE]; 887 static uint32_t ring_number; 888 uint64_t pcap_pkt_count = 0; 889 struct rte_mbuf *bufs[1]; 890 pcap_t **pcap; 891 892 pp = rte_eth_devices[pcap_q->port_id].process_private; 893 pcap = &pp->rx_pcap[pcap_q->queue_id]; 894 895 if (unlikely(*pcap == NULL)) 896 return -ENOENT; 897 898 pcap_pkt_count = count_packets_in_pcap(pcap, pcap_q); 899 900 snprintf(ring_name, sizeof(ring_name), "PCAP_RING%" PRIu32, 901 ring_number); 902 903 pcap_q->pkts = rte_ring_create(ring_name, 904 rte_align64pow2(pcap_pkt_count + 1), 0, 905 RING_F_SP_ENQ | RING_F_SC_DEQ); 906 ring_number++; 907 if (!pcap_q->pkts) 908 return -ENOENT; 909 910 /* Fill ring with packets from PCAP file one by one. */ 911 while (eth_pcap_rx(pcap_q, bufs, 1)) { 912 /* Check for multiseg mbufs. */ 913 if (bufs[0]->nb_segs != 1) { 914 infinite_rx_ring_free(pcap_q->pkts); 915 PMD_LOG(ERR, 916 "Multiseg mbufs are not supported in infinite_rx mode."); 917 return -EINVAL; 918 } 919 920 rte_ring_enqueue_bulk(pcap_q->pkts, 921 (void * const *)bufs, 1, NULL); 922 } 923 924 if (rte_ring_count(pcap_q->pkts) < pcap_pkt_count) { 925 infinite_rx_ring_free(pcap_q->pkts); 926 PMD_LOG(ERR, 927 "Not enough mbufs to accommodate packets in pcap file. " 928 "At least %" PRIu64 " mbufs per queue is required.", 929 pcap_pkt_count); 930 return -EINVAL; 931 } 932 933 /* 934 * Reset the stats for this queue since eth_pcap_rx calls above 935 * didn't result in the application receiving packets. 936 */ 937 pcap_q->rx_stat.pkts = 0; 938 pcap_q->rx_stat.bytes = 0; 939 } 940 941 return 0; 942 } 943 944 static int 945 eth_tx_queue_setup(struct rte_eth_dev *dev, 946 uint16_t tx_queue_id, 947 uint16_t nb_tx_desc __rte_unused, 948 unsigned int socket_id __rte_unused, 949 const struct rte_eth_txconf *tx_conf __rte_unused) 950 { 951 struct pmd_internals *internals = dev->data->dev_private; 952 struct pcap_tx_queue *pcap_q = &internals->tx_queue[tx_queue_id]; 953 954 pcap_q->port_id = dev->data->port_id; 955 pcap_q->queue_id = tx_queue_id; 956 dev->data->tx_queues[tx_queue_id] = pcap_q; 957 958 return 0; 959 } 960 961 static int 962 eth_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id) 963 { 964 dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED; 965 966 return 0; 967 } 968 969 static int 970 eth_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id) 971 { 972 dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED; 973 974 return 0; 975 } 976 977 static int 978 eth_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id) 979 { 980 dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED; 981 982 return 0; 983 } 984 985 static int 986 eth_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id) 987 { 988 dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED; 989 990 return 0; 991 } 992 993 static const struct eth_dev_ops ops = { 994 .dev_start = eth_dev_start, 995 .dev_stop = eth_dev_stop, 996 .dev_close = eth_dev_close, 997 .dev_configure = eth_dev_configure, 998 .dev_infos_get = eth_dev_info, 999 .rx_queue_setup = eth_rx_queue_setup, 1000 .tx_queue_setup = eth_tx_queue_setup, 1001 .rx_queue_start = eth_rx_queue_start, 1002 .tx_queue_start = eth_tx_queue_start, 1003 .rx_queue_stop = eth_rx_queue_stop, 1004 .tx_queue_stop = eth_tx_queue_stop, 1005 .link_update = eth_link_update, 1006 .stats_get = eth_stats_get, 1007 .stats_reset = eth_stats_reset, 1008 }; 1009 1010 static int 1011 add_queue(struct pmd_devargs *pmd, const char *name, const char *type, 1012 pcap_t *pcap, pcap_dumper_t *dumper) 1013 { 1014 if (pmd->num_of_queue >= RTE_PMD_PCAP_MAX_QUEUES) 1015 return -1; 1016 if (pcap) 1017 pmd->queue[pmd->num_of_queue].pcap = pcap; 1018 if (dumper) 1019 pmd->queue[pmd->num_of_queue].dumper = dumper; 1020 pmd->queue[pmd->num_of_queue].name = name; 1021 pmd->queue[pmd->num_of_queue].type = type; 1022 pmd->num_of_queue++; 1023 return 0; 1024 } 1025 1026 /* 1027 * Function handler that opens the pcap file for reading a stores a 1028 * reference of it for use it later on. 1029 */ 1030 static int 1031 open_rx_pcap(const char *key, const char *value, void *extra_args) 1032 { 1033 const char *pcap_filename = value; 1034 struct pmd_devargs *rx = extra_args; 1035 pcap_t *pcap = NULL; 1036 1037 if (open_single_rx_pcap(pcap_filename, &pcap) < 0) 1038 return -1; 1039 1040 if (add_queue(rx, pcap_filename, key, pcap, NULL) < 0) { 1041 pcap_close(pcap); 1042 return -1; 1043 } 1044 1045 return 0; 1046 } 1047 1048 /* 1049 * Opens a pcap file for writing and stores a reference to it 1050 * for use it later on. 1051 */ 1052 static int 1053 open_tx_pcap(const char *key, const char *value, void *extra_args) 1054 { 1055 const char *pcap_filename = value; 1056 struct pmd_devargs *dumpers = extra_args; 1057 pcap_dumper_t *dumper; 1058 1059 if (open_single_tx_pcap(pcap_filename, &dumper) < 0) 1060 return -1; 1061 1062 if (add_queue(dumpers, pcap_filename, key, NULL, dumper) < 0) { 1063 pcap_dump_close(dumper); 1064 return -1; 1065 } 1066 1067 return 0; 1068 } 1069 1070 /* 1071 * Opens an interface for reading and writing 1072 */ 1073 static inline int 1074 open_rx_tx_iface(const char *key, const char *value, void *extra_args) 1075 { 1076 const char *iface = value; 1077 struct pmd_devargs *tx = extra_args; 1078 pcap_t *pcap = NULL; 1079 1080 if (open_single_iface(iface, &pcap) < 0) 1081 return -1; 1082 1083 tx->queue[0].pcap = pcap; 1084 tx->queue[0].name = iface; 1085 tx->queue[0].type = key; 1086 1087 return 0; 1088 } 1089 1090 static inline int 1091 set_iface_direction(const char *iface, pcap_t *pcap, 1092 pcap_direction_t direction) 1093 { 1094 const char *direction_str = (direction == PCAP_D_IN) ? "IN" : "OUT"; 1095 if (pcap_setdirection(pcap, direction) < 0) { 1096 PMD_LOG(ERR, "Setting %s pcap direction %s failed - %s\n", 1097 iface, direction_str, pcap_geterr(pcap)); 1098 return -1; 1099 } 1100 PMD_LOG(INFO, "Setting %s pcap direction %s\n", 1101 iface, direction_str); 1102 return 0; 1103 } 1104 1105 static inline int 1106 open_iface(const char *key, const char *value, void *extra_args) 1107 { 1108 const char *iface = value; 1109 struct pmd_devargs *pmd = extra_args; 1110 pcap_t *pcap = NULL; 1111 1112 if (open_single_iface(iface, &pcap) < 0) 1113 return -1; 1114 if (add_queue(pmd, iface, key, pcap, NULL) < 0) { 1115 pcap_close(pcap); 1116 return -1; 1117 } 1118 1119 return 0; 1120 } 1121 1122 /* 1123 * Opens a NIC for reading packets from it 1124 */ 1125 static inline int 1126 open_rx_iface(const char *key, const char *value, void *extra_args) 1127 { 1128 int ret = open_iface(key, value, extra_args); 1129 if (ret < 0) 1130 return ret; 1131 if (strcmp(key, ETH_PCAP_RX_IFACE_IN_ARG) == 0) { 1132 struct pmd_devargs *pmd = extra_args; 1133 unsigned int qid = pmd->num_of_queue - 1; 1134 1135 set_iface_direction(pmd->queue[qid].name, 1136 pmd->queue[qid].pcap, 1137 PCAP_D_IN); 1138 } 1139 1140 return 0; 1141 } 1142 1143 static inline int 1144 rx_iface_args_process(const char *key, const char *value, void *extra_args) 1145 { 1146 if (strcmp(key, ETH_PCAP_RX_IFACE_ARG) == 0 || 1147 strcmp(key, ETH_PCAP_RX_IFACE_IN_ARG) == 0) 1148 return open_rx_iface(key, value, extra_args); 1149 1150 return 0; 1151 } 1152 1153 /* 1154 * Opens a NIC for writing packets to it 1155 */ 1156 static int 1157 open_tx_iface(const char *key, const char *value, void *extra_args) 1158 { 1159 return open_iface(key, value, extra_args); 1160 } 1161 1162 static int 1163 select_phy_mac(const char *key __rte_unused, const char *value, 1164 void *extra_args) 1165 { 1166 if (extra_args) { 1167 const int phy_mac = atoi(value); 1168 int *enable_phy_mac = extra_args; 1169 1170 if (phy_mac) 1171 *enable_phy_mac = 1; 1172 } 1173 return 0; 1174 } 1175 1176 static int 1177 get_infinite_rx_arg(const char *key __rte_unused, 1178 const char *value, void *extra_args) 1179 { 1180 if (extra_args) { 1181 const int infinite_rx = atoi(value); 1182 int *enable_infinite_rx = extra_args; 1183 1184 if (infinite_rx > 0) 1185 *enable_infinite_rx = 1; 1186 } 1187 return 0; 1188 } 1189 1190 static int 1191 pmd_init_internals(struct rte_vdev_device *vdev, 1192 const unsigned int nb_rx_queues, 1193 const unsigned int nb_tx_queues, 1194 struct pmd_internals **internals, 1195 struct rte_eth_dev **eth_dev) 1196 { 1197 struct rte_eth_dev_data *data; 1198 struct pmd_process_private *pp; 1199 unsigned int numa_node = vdev->device.numa_node; 1200 1201 PMD_LOG(INFO, "Creating pcap-backed ethdev on numa socket %d", 1202 numa_node); 1203 1204 pp = (struct pmd_process_private *) 1205 rte_zmalloc(NULL, sizeof(struct pmd_process_private), 1206 RTE_CACHE_LINE_SIZE); 1207 1208 if (pp == NULL) { 1209 PMD_LOG(ERR, 1210 "Failed to allocate memory for process private"); 1211 return -1; 1212 } 1213 1214 /* reserve an ethdev entry */ 1215 *eth_dev = rte_eth_vdev_allocate(vdev, sizeof(**internals)); 1216 if (!(*eth_dev)) { 1217 rte_free(pp); 1218 return -1; 1219 } 1220 (*eth_dev)->process_private = pp; 1221 /* now put it all together 1222 * - store queue data in internals, 1223 * - store numa_node info in eth_dev 1224 * - point eth_dev_data to internals 1225 * - and point eth_dev structure to new eth_dev_data structure 1226 */ 1227 *internals = (*eth_dev)->data->dev_private; 1228 /* 1229 * Interface MAC = 02:70:63:61:70:<iface_idx> 1230 * derived from: 'locally administered':'p':'c':'a':'p':'iface_idx' 1231 * where the middle 4 characters are converted to hex. 1232 */ 1233 (*internals)->eth_addr = (struct rte_ether_addr) { 1234 .addr_bytes = { 0x02, 0x70, 0x63, 0x61, 0x70, iface_idx++ } 1235 }; 1236 (*internals)->phy_mac = 0; 1237 data = (*eth_dev)->data; 1238 data->nb_rx_queues = (uint16_t)nb_rx_queues; 1239 data->nb_tx_queues = (uint16_t)nb_tx_queues; 1240 data->dev_link = pmd_link; 1241 data->mac_addrs = &(*internals)->eth_addr; 1242 data->promiscuous = 1; 1243 data->all_multicast = 1; 1244 data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS; 1245 1246 /* 1247 * NOTE: we'll replace the data element, of originally allocated 1248 * eth_dev so the rings are local per-process 1249 */ 1250 (*eth_dev)->dev_ops = &ops; 1251 1252 strlcpy((*internals)->devargs, rte_vdev_device_args(vdev), 1253 ETH_PCAP_ARG_MAXLEN); 1254 1255 return 0; 1256 } 1257 1258 static int 1259 eth_pcap_update_mac(const char *if_name, struct rte_eth_dev *eth_dev, 1260 const unsigned int numa_node) 1261 { 1262 void *mac_addrs; 1263 struct rte_ether_addr mac; 1264 1265 if (osdep_iface_mac_get(if_name, &mac) < 0) 1266 return -1; 1267 1268 mac_addrs = rte_zmalloc_socket(NULL, RTE_ETHER_ADDR_LEN, 0, numa_node); 1269 if (mac_addrs == NULL) 1270 return -1; 1271 1272 PMD_LOG(INFO, "Setting phy MAC for %s", if_name); 1273 rte_memcpy(mac_addrs, mac.addr_bytes, RTE_ETHER_ADDR_LEN); 1274 eth_dev->data->mac_addrs = mac_addrs; 1275 return 0; 1276 } 1277 1278 static int 1279 eth_from_pcaps_common(struct rte_vdev_device *vdev, 1280 struct pmd_devargs_all *devargs_all, 1281 struct pmd_internals **internals, struct rte_eth_dev **eth_dev) 1282 { 1283 struct pmd_process_private *pp; 1284 struct pmd_devargs *rx_queues = &devargs_all->rx_queues; 1285 struct pmd_devargs *tx_queues = &devargs_all->tx_queues; 1286 const unsigned int nb_rx_queues = rx_queues->num_of_queue; 1287 const unsigned int nb_tx_queues = tx_queues->num_of_queue; 1288 unsigned int i; 1289 1290 if (pmd_init_internals(vdev, nb_rx_queues, nb_tx_queues, internals, 1291 eth_dev) < 0) 1292 return -1; 1293 1294 pp = (*eth_dev)->process_private; 1295 for (i = 0; i < nb_rx_queues; i++) { 1296 struct pcap_rx_queue *rx = &(*internals)->rx_queue[i]; 1297 struct devargs_queue *queue = &rx_queues->queue[i]; 1298 1299 pp->rx_pcap[i] = queue->pcap; 1300 strlcpy(rx->name, queue->name, sizeof(rx->name)); 1301 strlcpy(rx->type, queue->type, sizeof(rx->type)); 1302 } 1303 1304 for (i = 0; i < nb_tx_queues; i++) { 1305 struct pcap_tx_queue *tx = &(*internals)->tx_queue[i]; 1306 struct devargs_queue *queue = &tx_queues->queue[i]; 1307 1308 pp->tx_dumper[i] = queue->dumper; 1309 pp->tx_pcap[i] = queue->pcap; 1310 strlcpy(tx->name, queue->name, sizeof(tx->name)); 1311 strlcpy(tx->type, queue->type, sizeof(tx->type)); 1312 } 1313 1314 return 0; 1315 } 1316 1317 static int 1318 eth_from_pcaps(struct rte_vdev_device *vdev, 1319 struct pmd_devargs_all *devargs_all) 1320 { 1321 struct pmd_internals *internals = NULL; 1322 struct rte_eth_dev *eth_dev = NULL; 1323 struct pmd_devargs *rx_queues = &devargs_all->rx_queues; 1324 int single_iface = devargs_all->single_iface; 1325 unsigned int infinite_rx = devargs_all->infinite_rx; 1326 int ret; 1327 1328 ret = eth_from_pcaps_common(vdev, devargs_all, &internals, ð_dev); 1329 1330 if (ret < 0) 1331 return ret; 1332 1333 /* store weather we are using a single interface for rx/tx or not */ 1334 internals->single_iface = single_iface; 1335 1336 if (single_iface) { 1337 internals->if_index = 1338 osdep_iface_index_get(rx_queues->queue[0].name); 1339 1340 /* phy_mac arg is applied only only if "iface" devarg is provided */ 1341 if (rx_queues->phy_mac) { 1342 if (eth_pcap_update_mac(rx_queues->queue[0].name, 1343 eth_dev, vdev->device.numa_node) == 0) 1344 internals->phy_mac = 1; 1345 } 1346 } 1347 1348 internals->infinite_rx = infinite_rx; 1349 /* Assign rx ops. */ 1350 if (infinite_rx) 1351 eth_dev->rx_pkt_burst = eth_pcap_rx_infinite; 1352 else if (devargs_all->is_rx_pcap || devargs_all->is_rx_iface || 1353 single_iface) 1354 eth_dev->rx_pkt_burst = eth_pcap_rx; 1355 else 1356 eth_dev->rx_pkt_burst = eth_null_rx; 1357 1358 /* Assign tx ops. */ 1359 if (devargs_all->is_tx_pcap) 1360 eth_dev->tx_pkt_burst = eth_pcap_tx_dumper; 1361 else if (devargs_all->is_tx_iface || single_iface) 1362 eth_dev->tx_pkt_burst = eth_pcap_tx; 1363 else 1364 eth_dev->tx_pkt_burst = eth_tx_drop; 1365 1366 rte_eth_dev_probing_finish(eth_dev); 1367 return 0; 1368 } 1369 1370 static void 1371 eth_release_pcaps(struct pmd_devargs *pcaps, 1372 struct pmd_devargs *dumpers, 1373 int single_iface) 1374 { 1375 unsigned int i; 1376 1377 if (single_iface) { 1378 if (pcaps->queue[0].pcap) 1379 pcap_close(pcaps->queue[0].pcap); 1380 return; 1381 } 1382 1383 for (i = 0; i < dumpers->num_of_queue; i++) { 1384 if (dumpers->queue[i].dumper) 1385 pcap_dump_close(dumpers->queue[i].dumper); 1386 1387 if (dumpers->queue[i].pcap) 1388 pcap_close(dumpers->queue[i].pcap); 1389 } 1390 1391 for (i = 0; i < pcaps->num_of_queue; i++) { 1392 if (pcaps->queue[i].pcap) 1393 pcap_close(pcaps->queue[i].pcap); 1394 } 1395 } 1396 1397 static int 1398 pmd_pcap_probe(struct rte_vdev_device *dev) 1399 { 1400 const char *name; 1401 struct rte_kvargs *kvlist; 1402 struct pmd_devargs pcaps = {0}; 1403 struct pmd_devargs dumpers = {0}; 1404 struct rte_eth_dev *eth_dev = NULL; 1405 struct pmd_internals *internal; 1406 int ret = 0; 1407 1408 struct pmd_devargs_all devargs_all = { 1409 .single_iface = 0, 1410 .is_tx_pcap = 0, 1411 .is_tx_iface = 0, 1412 .infinite_rx = 0, 1413 }; 1414 1415 name = rte_vdev_device_name(dev); 1416 PMD_LOG(INFO, "Initializing pmd_pcap for %s", name); 1417 1418 timespec_get(&start_time, TIME_UTC); 1419 start_cycles = rte_get_timer_cycles(); 1420 hz = rte_get_timer_hz(); 1421 1422 ret = rte_mbuf_dyn_rx_timestamp_register(×tamp_dynfield_offset, 1423 ×tamp_rx_dynflag); 1424 if (ret != 0) { 1425 PMD_LOG(ERR, "Failed to register Rx timestamp field/flag"); 1426 return -1; 1427 } 1428 1429 if (rte_eal_process_type() == RTE_PROC_SECONDARY) { 1430 eth_dev = rte_eth_dev_attach_secondary(name); 1431 if (!eth_dev) { 1432 PMD_LOG(ERR, "Failed to probe %s", name); 1433 return -1; 1434 } 1435 1436 internal = eth_dev->data->dev_private; 1437 1438 kvlist = rte_kvargs_parse(internal->devargs, valid_arguments); 1439 if (kvlist == NULL) 1440 return -1; 1441 } else { 1442 kvlist = rte_kvargs_parse(rte_vdev_device_args(dev), 1443 valid_arguments); 1444 if (kvlist == NULL) 1445 return -1; 1446 } 1447 1448 /* 1449 * If iface argument is passed we open the NICs and use them for 1450 * reading / writing 1451 */ 1452 if (rte_kvargs_count(kvlist, ETH_PCAP_IFACE_ARG) == 1) { 1453 1454 ret = rte_kvargs_process(kvlist, ETH_PCAP_IFACE_ARG, 1455 &open_rx_tx_iface, &pcaps); 1456 if (ret < 0) 1457 goto free_kvlist; 1458 1459 dumpers.queue[0] = pcaps.queue[0]; 1460 1461 ret = rte_kvargs_process(kvlist, ETH_PCAP_PHY_MAC_ARG, 1462 &select_phy_mac, &pcaps.phy_mac); 1463 if (ret < 0) 1464 goto free_kvlist; 1465 1466 dumpers.phy_mac = pcaps.phy_mac; 1467 1468 devargs_all.single_iface = 1; 1469 pcaps.num_of_queue = 1; 1470 dumpers.num_of_queue = 1; 1471 1472 goto create_eth; 1473 } 1474 1475 /* 1476 * We check whether we want to open a RX stream from a real NIC, a 1477 * pcap file or open a dummy RX stream 1478 */ 1479 devargs_all.is_rx_pcap = 1480 rte_kvargs_count(kvlist, ETH_PCAP_RX_PCAP_ARG) ? 1 : 0; 1481 devargs_all.is_rx_iface = 1482 (rte_kvargs_count(kvlist, ETH_PCAP_RX_IFACE_ARG) + 1483 rte_kvargs_count(kvlist, ETH_PCAP_RX_IFACE_IN_ARG)) ? 1 : 0; 1484 pcaps.num_of_queue = 0; 1485 1486 devargs_all.is_tx_pcap = 1487 rte_kvargs_count(kvlist, ETH_PCAP_TX_PCAP_ARG) ? 1 : 0; 1488 devargs_all.is_tx_iface = 1489 rte_kvargs_count(kvlist, ETH_PCAP_TX_IFACE_ARG) ? 1 : 0; 1490 dumpers.num_of_queue = 0; 1491 1492 if (devargs_all.is_rx_pcap) { 1493 /* 1494 * We check whether we want to infinitely rx the pcap file. 1495 */ 1496 unsigned int infinite_rx_arg_cnt = rte_kvargs_count(kvlist, 1497 ETH_PCAP_INFINITE_RX_ARG); 1498 1499 if (infinite_rx_arg_cnt == 1) { 1500 ret = rte_kvargs_process(kvlist, 1501 ETH_PCAP_INFINITE_RX_ARG, 1502 &get_infinite_rx_arg, 1503 &devargs_all.infinite_rx); 1504 if (ret < 0) 1505 goto free_kvlist; 1506 PMD_LOG(INFO, "infinite_rx has been %s for %s", 1507 devargs_all.infinite_rx ? "enabled" : "disabled", 1508 name); 1509 1510 } else if (infinite_rx_arg_cnt > 1) { 1511 PMD_LOG(WARNING, "infinite_rx has not been enabled since the " 1512 "argument has been provided more than once " 1513 "for %s", name); 1514 } 1515 1516 ret = rte_kvargs_process(kvlist, ETH_PCAP_RX_PCAP_ARG, 1517 &open_rx_pcap, &pcaps); 1518 } else if (devargs_all.is_rx_iface) { 1519 ret = rte_kvargs_process(kvlist, NULL, 1520 &rx_iface_args_process, &pcaps); 1521 } else if (devargs_all.is_tx_iface || devargs_all.is_tx_pcap) { 1522 unsigned int i; 1523 1524 /* Count number of tx queue args passed before dummy rx queue 1525 * creation so a dummy rx queue can be created for each tx queue 1526 */ 1527 unsigned int num_tx_queues = 1528 (rte_kvargs_count(kvlist, ETH_PCAP_TX_PCAP_ARG) + 1529 rte_kvargs_count(kvlist, ETH_PCAP_TX_IFACE_ARG)); 1530 1531 PMD_LOG(INFO, "Creating null rx queue since no rx queues were provided."); 1532 1533 /* Creating a dummy rx queue for each tx queue passed */ 1534 for (i = 0; i < num_tx_queues; i++) 1535 ret = add_queue(&pcaps, "dummy_rx", "rx_null", NULL, 1536 NULL); 1537 } else { 1538 PMD_LOG(ERR, "Error - No rx or tx queues provided"); 1539 ret = -ENOENT; 1540 } 1541 if (ret < 0) 1542 goto free_kvlist; 1543 1544 /* 1545 * We check whether we want to open a TX stream to a real NIC, 1546 * a pcap file, or drop packets on tx 1547 */ 1548 if (devargs_all.is_tx_pcap) { 1549 ret = rte_kvargs_process(kvlist, ETH_PCAP_TX_PCAP_ARG, 1550 &open_tx_pcap, &dumpers); 1551 } else if (devargs_all.is_tx_iface) { 1552 ret = rte_kvargs_process(kvlist, ETH_PCAP_TX_IFACE_ARG, 1553 &open_tx_iface, &dumpers); 1554 } else { 1555 unsigned int i; 1556 1557 PMD_LOG(INFO, "Dropping packets on tx since no tx queues were provided."); 1558 1559 /* Add 1 dummy queue per rxq which counts and drops packets. */ 1560 for (i = 0; i < pcaps.num_of_queue; i++) 1561 ret = add_queue(&dumpers, "dummy_tx", "tx_drop", NULL, 1562 NULL); 1563 } 1564 1565 if (ret < 0) 1566 goto free_kvlist; 1567 1568 create_eth: 1569 if (rte_eal_process_type() == RTE_PROC_SECONDARY) { 1570 struct pmd_process_private *pp; 1571 unsigned int i; 1572 1573 internal = eth_dev->data->dev_private; 1574 pp = (struct pmd_process_private *) 1575 rte_zmalloc(NULL, 1576 sizeof(struct pmd_process_private), 1577 RTE_CACHE_LINE_SIZE); 1578 1579 if (pp == NULL) { 1580 PMD_LOG(ERR, 1581 "Failed to allocate memory for process private"); 1582 ret = -1; 1583 goto free_kvlist; 1584 } 1585 1586 eth_dev->dev_ops = &ops; 1587 eth_dev->device = &dev->device; 1588 1589 /* setup process private */ 1590 for (i = 0; i < pcaps.num_of_queue; i++) 1591 pp->rx_pcap[i] = pcaps.queue[i].pcap; 1592 1593 for (i = 0; i < dumpers.num_of_queue; i++) { 1594 pp->tx_dumper[i] = dumpers.queue[i].dumper; 1595 pp->tx_pcap[i] = dumpers.queue[i].pcap; 1596 } 1597 1598 eth_dev->process_private = pp; 1599 eth_dev->rx_pkt_burst = eth_pcap_rx; 1600 if (devargs_all.is_tx_pcap) 1601 eth_dev->tx_pkt_burst = eth_pcap_tx_dumper; 1602 else 1603 eth_dev->tx_pkt_burst = eth_pcap_tx; 1604 1605 rte_eth_dev_probing_finish(eth_dev); 1606 goto free_kvlist; 1607 } 1608 1609 devargs_all.rx_queues = pcaps; 1610 devargs_all.tx_queues = dumpers; 1611 1612 ret = eth_from_pcaps(dev, &devargs_all); 1613 1614 free_kvlist: 1615 rte_kvargs_free(kvlist); 1616 1617 if (ret < 0) 1618 eth_release_pcaps(&pcaps, &dumpers, devargs_all.single_iface); 1619 1620 return ret; 1621 } 1622 1623 static int 1624 pmd_pcap_remove(struct rte_vdev_device *dev) 1625 { 1626 struct rte_eth_dev *eth_dev = NULL; 1627 1628 if (!dev) 1629 return -1; 1630 1631 eth_dev = rte_eth_dev_allocated(rte_vdev_device_name(dev)); 1632 if (eth_dev == NULL) 1633 return 0; /* port already released */ 1634 1635 eth_dev_close(eth_dev); 1636 rte_eth_dev_release_port(eth_dev); 1637 1638 return 0; 1639 } 1640 1641 static struct rte_vdev_driver pmd_pcap_drv = { 1642 .probe = pmd_pcap_probe, 1643 .remove = pmd_pcap_remove, 1644 }; 1645 1646 RTE_PMD_REGISTER_VDEV(net_pcap, pmd_pcap_drv); 1647 RTE_PMD_REGISTER_ALIAS(net_pcap, eth_pcap); 1648 RTE_PMD_REGISTER_PARAM_STRING(net_pcap, 1649 ETH_PCAP_RX_PCAP_ARG "=<string> " 1650 ETH_PCAP_TX_PCAP_ARG "=<string> " 1651 ETH_PCAP_RX_IFACE_ARG "=<ifc> " 1652 ETH_PCAP_RX_IFACE_IN_ARG "=<ifc> " 1653 ETH_PCAP_TX_IFACE_ARG "=<ifc> " 1654 ETH_PCAP_IFACE_ARG "=<ifc> " 1655 ETH_PCAP_PHY_MAC_ARG "=<int>" 1656 ETH_PCAP_INFINITE_RX_ARG "=<0|1>"); 1657