Hi Bruce, We also found buffer overflow problems with the pcap driver. 1) Frame may be longer than mbuf. 2) Caplen may be less than original packet.
I've been meaning to submit a change, but I'm not familiar with the process. Here is a diff of the relevant code in rte_eth_pcap.c: ==== if (unlikely(mbuf == NULL)) break; - rte_memcpy(mbuf->pkt.data, packet, header.len); - mbuf->pkt.data_len = (uint16_t)header.len; - mbuf->pkt.pkt_len = mbuf->pkt.data_len; + + /* + * Fix buffer overflow problems. + * 1. Frame may be longer than mbuf. + * 2. Capture length (caplen) may be less than original packet length. + */ + uint16_t len = (uint16_t)header.caplen; + uint16_t tailroom = rte_pktmbuf_tailroom(mbuf); + if (len > tailroom) + len = tailroom; + + /**** + RTE_LOG(INFO, PMD, "eth_pcap_rx: i=%u caplen=%u framelen=%u tail=%u len=%u\n", + i, header.caplen, header.len, tailroom, len); + ****/ + + rte_memcpy(mbuf->pkt.data, packet, len); + mbuf->pkt.data_len = len; + mbuf->pkt.pkt_len = len; + bufs[i] = mbuf; num_rx++; } ==== Regards, Robert On Tue, Nov 26, 2013 at 8:46 AM, Richardson, Bruce < bruce.richardson at intel.com> wrote: > Hi Mats, > > yes, you are right, there is an issue in the pcap driver that it is not > allocating mbufs correctly. We are working on a fix. > > Regards, > /Bruce > > > -----Original Message----- > > From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Mats Liljegren > > Sent: Tuesday, November 26, 2013 1:07 PM > > To: dev at dpdk.org > > Subject: [dpdk-dev] Question: Can't make pcap and refcnt to match > > > > I have had stability problems when using pcap in my little application. > My > > application is a simple benchmark applications that is trying to see how > > much data I can send and receive. > > > > It has one lcore per NIC, where each lcore handles transmit and receive. > On > > the hardware, I make a loopback between two NICs, so the NICs are in > > practice paired. I currently use 4 NICs and therefore 4 lcores. Port 0 > sends to > > port 1 and vice versa. Port 2 send to port 3 and vice versa. One pair is > using > > DPDK hardware driver against a dual > > i350 NIC. The other pair is using pcap against two of the four on-board > NICs. > > > > When enabling everything saying "DEBUG" in its name in the .config file, > I > > get the following error: > > > > PMD: rte_eth_dev_config_restore: port 1: MAC address array not > > supported > > PMD: rte_eth_promiscuous_disable: Function not supported > > PMD: rte_eth_allmulticast_disable: Function not supported > > Speed: 10000 Mbps, full duplex > > Port 1 up and running. > > PMD: e1000_put_hw_semaphore_generic(): > > e1000_put_hw_semaphore_generic PANIC in rte_mbuf_sanity_check(): > > bad ref cnt > > PANIC in rte_mbuf_sanity_check(): > > bad ref cnt > > PMD: e1000_release_phy_82575(): e1000_release_phy_82575 > > PMD: e1000_release_swfw_sync_82575(): > > e1000_release_swfw_sync_82575 > > PMD: e1000_get_hw_semaphore_generic(): > > e1000_get_hw_semaphore_generic > > PMD: eth_igb_rx_queue_setup(): sw_ring=0x7fff776eefc0 > > hw_ring=0x7fff76830480 dma_addr=0x464630480 > > > > PMD: e1000_put_hw_semaphore_generic(): > > e1000_put_hw_semaphore_generic > > PMD: To improve 1G driver performance, consider setting the TX WTHRESH > > value to 4, 8, or 16. > > PMD: eth_igb_tx_queue_setup(): sw_ring=0x7fff776ece40 > > hw_ring=0x7fff76840500 dma_addr=0x464640500 > > > > PMD: eth_igb_start(): >> > > PMD: e1000_read_phy_reg_82580(): e1000_read_phy_reg_82580 > > PMD: e1000_acquire_phy_82575(): e1000_acquire_phy_82575 > > PMD: e1000_acquire_swfw_sync_82575(): > > e1000_acquire_swfw_sync_82575 > > PMD: e1000_get_hw_semaphore_generic(): > > e1000_get_hw_semaphore_generic > > PMD: e1000_get_cfg_done_82575(): e1000_get_cfg_done_82575 > > PMD: e1000_put_hw_semaphore_generic(): > > e1000_put_hw_semaphore_generic > > PMD: e1000_read_phy_reg_mdic(): e1000_read_phy_reg_mdic > > 9: [/lib/x86_64-linux-gnu/libc.so.6(clone+0x6d) [0x7ffff72a89cd]] > > 8: [/lib/x86_64-linux-gnu/libpthread.so.0(+0x7f6e) [0x7ffff757df6e]] > > 7: [/home/mlil/dpdk-demo/build/enea-demo(eal_thread_loop+0x1b9) > > [0x492669]] > > 6: [/home/mlil/dpdk-demo/build/enea-demo() [0x4150bc]] > > 5: [/home/mlil/dpdk-demo/build/enea-demo() [0x414d0b]] > > 4: [/home/mlil/dpdk-demo/build/enea-demo() [0x4116ef]] > > 3: [/home/mlil/dpdk-demo/build/enea- > > demo(rte_mbuf_sanity_check+0xa7) [0x484707]] > > 2: [/home/mlil/dpdk-demo/build/enea-demo(__rte_panic+0xc1) > > [0x40f788]] > > 1: [/home/mlil/dpdk-demo/build/enea-demo(rte_dump_stack+0x18) > > [0x493f68]] > > PMD: e1000_release_phy_82575(): e1000_release_phy_82575 > > PMD: e1000_release_swfw_sync_82575(): > > e1000_release_swfw_sync_82575 > > PMD: e1000_get_hw_semaphore_generic(): > > e1000_get_hw_semaphore_generic > > > > I checked the source code for pcap, and in the file rte_eth_pcap.c, > function > > eth_pcap_rx(), I make the following observation: > > > > It pre-allocates a number of mbufs (64 to be exact). It then fills these > mbufs > > with data and returns them. The pre-allocation seems to only be done > once, > > and then they are re-used. > > > > This confuses me. How does this work when more than 64 packets are > > requested? I see no safety checks for this. > > > > Aren't application supposed to call rte_pktmbuf_free() on the returned > > mbufs? If so, the pre-allocated mbufs will have been free'd as far as I > can > > see and can therefore not be re-used. > > > > What am I missing here? > > > > Regards > > Mats >