From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id B315B5A57 for ; Wed, 8 Jul 2015 17:53:35 +0200 (CEST) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga103.fm.intel.com with ESMTP; 08 Jul 2015 08:53:26 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.15,432,1432623600"; d="scan'208";a="758436839" Received: from irvmail001.ir.intel.com ([163.33.26.43]) by fmsmga002.fm.intel.com with ESMTP; 08 Jul 2015 08:53:24 -0700 Received: from sivswdev02.ir.intel.com (sivswdev02.ir.intel.com [10.237.217.46]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id t68FrNas020147; Wed, 8 Jul 2015 16:53:23 +0100 Received: from sivswdev02.ir.intel.com (localhost [127.0.0.1]) by sivswdev02.ir.intel.com with ESMTP id t68FrNYP031471; Wed, 8 Jul 2015 16:53:23 +0100 Received: (from jmcnam2x@localhost) by sivswdev02.ir.intel.com with id t68FrNZa031467; Wed, 8 Jul 2015 16:53:23 +0100 From: John McNamara To: dev@dpdk.org Date: Wed, 8 Jul 2015 16:53:20 +0100 Message-Id: <1436370800-31437-1-git-send-email-john.mcnamara@intel.com> X-Mailer: git-send-email 1.7.4.1 Cc: Tero Aho Subject: [dpdk-dev] [PATCH] pcap: add support for jumbo frames X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 08 Jul 2015 15:53:36 -0000 From: Tero Aho Extend eth_pcap rx and tx to support jumbo frames. On the receive side read large packets into multiple mbufs and on the transmit side convert them back to a single pcap buffer. Signed-off-by: Tero Aho Signed-off-by: John McNamara --- drivers/net/pcap/rte_eth_pcap.c | 129 +++++++++++++++++++++++++++++++++++----- 1 file changed, 113 insertions(+), 16 deletions(-) diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c index a6ed5bd..682628f 100644 --- a/drivers/net/pcap/rte_eth_pcap.c +++ b/drivers/net/pcap/rte_eth_pcap.c @@ -47,7 +47,7 @@ #include #define RTE_ETH_PCAP_SNAPSHOT_LEN 65535 -#define RTE_ETH_PCAP_SNAPLEN 4096 +#define RTE_ETH_PCAP_SNAPLEN ETHER_MAX_JUMBO_FRAME_LEN #define RTE_ETH_PCAP_PROMISC 1 #define RTE_ETH_PCAP_TIMEOUT -1 #define ETH_PCAP_RX_PCAP_ARG "rx_pcap" @@ -59,6 +59,7 @@ #define ETH_PCAP_ARG_MAXLEN 64 static char errbuf[PCAP_ERRBUF_SIZE]; +static unsigned char tx_pcap_data[RTE_ETH_PCAP_SNAPLEN]; static struct timeval start_time; static uint64_t start_cycles; static uint64_t hz; @@ -127,6 +128,61 @@ static struct rte_eth_link pmd_link = { .link_status = 0 }; +static int +eth_pcap_rx_jumbo(struct rte_mempool *mb_pool, + struct rte_mbuf *mbuf, + const u_char *data, + uint16_t data_len) +{ + struct rte_mbuf *m = mbuf; + + /* Copy the first segment. */ + uint16_t len = rte_pktmbuf_tailroom(mbuf); + + rte_memcpy(rte_pktmbuf_append(mbuf, len), data, len); + data_len -= len; + data += len; + + while (data_len > 0) { + /* Allocate next mbuf and point to that. */ + m->next = rte_pktmbuf_alloc(mb_pool); + + if (unlikely(!m->next)) + return -1; + + m = m->next; + + /* Headroom is not needed in chained mbufs. */ + rte_pktmbuf_prepend(m, rte_pktmbuf_headroom(m)); + m->pkt_len = 0; + m->data_len = 0; + + /* Copy next segment. */ + len = RTE_MIN(rte_pktmbuf_tailroom(m), data_len); + rte_memcpy(rte_pktmbuf_append(m, len), data, len); + + mbuf->nb_segs++; + data_len -= len; + data += len; + } + + return mbuf->nb_segs; +} + +/* Copy data from mbuf chain to a buffer suitable for writing to a PCAP file. */ +static void +eth_pcap_gather_data(unsigned char *data, struct rte_mbuf *mbuf) +{ + uint16_t data_len = 0; + + while (mbuf) { + rte_memcpy(data + data_len, rte_pktmbuf_mtod(mbuf, void *), + mbuf->data_len); + + data_len += mbuf->data_len; + mbuf = mbuf->next; + } +} static uint16_t eth_pcap_rx(void *queue, @@ -166,17 +222,19 @@ eth_pcap_rx(void *queue, rte_memcpy(rte_pktmbuf_mtod(mbuf, void *), packet, header.len); mbuf->data_len = (uint16_t)header.len; - mbuf->pkt_len = mbuf->data_len; - mbuf->port = pcap_q->in_port; - bufs[num_rx] = mbuf; - num_rx++; } else { - /* pcap packet will not fit in the mbuf, so drop packet */ - RTE_LOG(ERR, PMD, - "PCAP packet %d bytes will not fit in mbuf (%d bytes)\n", - header.len, buf_size); - rte_pktmbuf_free(mbuf); + /* Try read jumbo frame into multi mbufs. */ + if (unlikely(eth_pcap_rx_jumbo(pcap_q->mb_pool, + mbuf, + packet, + header.len) == -1)) + break; } + + mbuf->pkt_len = (uint16_t)header.len; + mbuf->port = pcap_q->in_port; + bufs[num_rx] = mbuf; + num_rx++; } pcap_q->rx_pkts += num_rx; return num_rx; @@ -214,10 +272,29 @@ eth_pcap_tx_dumper(void *queue, for (i = 0; i < nb_pkts; i++) { mbuf = bufs[i]; calculate_timestamp(&header.ts); - header.len = mbuf->data_len; + header.len = mbuf->pkt_len; header.caplen = header.len; - pcap_dump((u_char *)dumper_q->dumper, &header, - rte_pktmbuf_mtod(mbuf, void*)); + + if (likely(mbuf->nb_segs == 1)) { + pcap_dump((u_char *)dumper_q->dumper, &header, + rte_pktmbuf_mtod(mbuf, void*)); + } else { + if (mbuf->pkt_len <= ETHER_MAX_JUMBO_FRAME_LEN) { + eth_pcap_gather_data(tx_pcap_data, mbuf); + pcap_dump((u_char *)dumper_q->dumper, &header, + tx_pcap_data); + } else { + RTE_LOG(ERR, PMD, + "Dropping PCAP packet. " + "Size (%d) > max jumbo size (%d).\n", + mbuf->pkt_len, + ETHER_MAX_JUMBO_FRAME_LEN); + + rte_pktmbuf_free(mbuf); + break; + } + } + rte_pktmbuf_free(mbuf); num_tx++; } @@ -252,9 +329,29 @@ eth_pcap_tx(void *queue, for (i = 0; i < nb_pkts; i++) { mbuf = bufs[i]; - ret = pcap_sendpacket(tx_queue->pcap, - rte_pktmbuf_mtod(mbuf, u_char *), - mbuf->data_len); + + if (likely(mbuf->nb_segs == 1)) { + ret = pcap_sendpacket(tx_queue->pcap, + rte_pktmbuf_mtod(mbuf, u_char *), + mbuf->pkt_len); + } else { + if (mbuf->pkt_len <= ETHER_MAX_JUMBO_FRAME_LEN) { + eth_pcap_gather_data(tx_pcap_data, mbuf); + ret = pcap_sendpacket(tx_queue->pcap, + tx_pcap_data, + mbuf->pkt_len); + } else { + RTE_LOG(ERR, PMD, + "Dropping PCAP packet. " + "Size (%d) > max jumbo size (%d).\n", + mbuf->pkt_len, + ETHER_MAX_JUMBO_FRAME_LEN); + + rte_pktmbuf_free(mbuf); + break; + } + } + if (unlikely(ret != 0)) break; num_tx++; -- 1.8.1.4