diff --git a/lib/librte_pmd_pcap/rte_eth_pcap.c b/lib/librte_pmd_pcap/rte_eth_pcap.c
index 289af28..3f23f0a 100644
--- a/lib/librte_pmd_pcap/rte_eth_pcap.c
+++ b/lib/librte_pmd_pcap/rte_eth_pcap.c
@@ -52,7 +52,7 @@
 #include <pcap.h>

 #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"
@@ -132,6 +132,43 @@ static struct rte_eth_link pmd_link = {
                .link_status = 0
 };

+/*
+ * Helper function to read mbuf chain.
+ */
+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 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 == NULL))
+                       return -1;
+               m = m->next;
+
+               /* no headroom needed in chained mbufs */
+               rte_pktmbuf_prepend(m, rte_pktmbuf_headroom(m));
+               m->data_len = m->pkt_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;
+}

 static uint16_t
 eth_pcap_rx(void *queue,
@@ -173,17 +210,18 @@ 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);
+                       /* pcap packet will not fit in a single mbuf */
+                       if (unlikely(eth_pcap_rx_jumbo(pcap_q->mb_pool, mbuf,
+                                       packet, header.len) == -1)) {
+                               rte_pktmbuf_free(mbuf);
+                               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;
@@ -241,6 +279,27 @@ eth_pcap_tx_dumper(void *queue,
 }

 /*
+ * Helper function to write mbuf chain.
+ */
+static uint16_t
+eth_pcap_tx_jumbo(pcap_t *pcap,
+                 struct rte_mbuf *mbuf)
+{
+       u_char data[ETHER_MAX_JUMBO_FRAME_LEN];
+       uint16_t data_len = 0;
+
+       while (mbuf != NULL) {
+               /* There is no writev style function in libpcap, */
+               /* we unfortunately have to copy data to a buffer. */
+               rte_memcpy(data + data_len, rte_pktmbuf_mtod(mbuf, void *),
+                          mbuf->data_len);
+               data_len += mbuf->data_len;
+               mbuf = mbuf->next;
+       }
+       return pcap_sendpacket(pcap, data, data_len);
+}
+
+/*
  * Callback to handle sending packets through a real NIC.
  */
 static uint16_t
@@ -259,9 +318,12 @@ 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->data_len);
+               else
+                       ret = eth_pcap_tx_jumbo(tx_queue->pcap, mbuf);
                if (unlikely(ret != 0))
                        break;
                num_tx++;
