diff --git a/config/common_base b/config/common_base
index c73f71a..3be2f18 100644
--- a/config/common_base
+++ b/config/common_base
@@ -458,6 +458,7 @@ CONFIG_RTE_LIBRTE_REORDER=y
 #
 CONFIG_RTE_LIBRTE_PORT=y
 CONFIG_RTE_PORT_STATS_COLLECT=n
+CONFIG_RTE_PORT_PCAP=n
 
 #
 # Compile librte_table
diff --git a/lib/librte_port/Makefile b/lib/librte_port/Makefile
index 410053e..0b31c04 100644
--- a/lib/librte_port/Makefile
+++ b/lib/librte_port/Makefile
@@ -1,6 +1,6 @@
 #   BSD LICENSE
 #
-#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+#   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
 #   All rights reserved.
 #
 #   Redistribution and use in source and binary forms, with or without
@@ -36,6 +36,14 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_port.a
 
+ifeq ($(CONFIG_RTE_NEXT_ABI),y)
+
+ifeq ($(CONFIG_RTE_PORT_PCAP),y)
+LDLIBS += -lpcap
+endif
+
+endif
+
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 
diff --git a/lib/librte_port/rte_port_source_sink.c b/lib/librte_port/rte_port_source_sink.c
index a06477e..3d4e8d9 100644
--- a/lib/librte_port/rte_port_source_sink.c
+++ b/lib/librte_port/rte_port_source_sink.c
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -37,6 +37,16 @@
 #include <rte_mempool.h>
 #include <rte_malloc.h>
 
+#ifdef RTE_NEXT_ABI
+
+#include <rte_memcpy.h>
+
+#ifdef RTE_PORT_PCAP
+#include <pcap.h>
+#endif
+
+#endif
+
 #include "rte_port_source_sink.h"
 
 /*
@@ -60,8 +70,174 @@ struct rte_port_source {
 	struct rte_port_in_stats stats;
 
 	struct rte_mempool *mempool;
+
+#ifdef RTE_NEXT_ABI
+	/* PCAP buffers and indexes */
+	uint8_t **pkts;
+	uint8_t *pkt_buff;
+	uint32_t *pkt_len;
+	uint32_t n_pkts;
+	uint32_t pkt_index;
+#endif
 };
 
+#ifdef RTE_NEXT_ABI
+
+#ifdef RTE_PORT_PCAP
+
+/**
+ * Load PCAP file, allocate and copy packets in the file to memory
+ *
+ * @param p
+ *   Parameters for source port
+ * @param port
+ *   Handle to source port
+ * @param socket_id
+ *   Socket id where the memory is created
+ * @return
+ *   0 on SUCCESS
+ *   error code otherwise
+ */
+static int
+pcap_source_load(struct rte_port_source_params *p,
+		struct rte_port_source *port,
+		int socket_id)
+{
+	uint32_t status = 0;
+	uint32_t n_pkts = 0;
+	uint32_t i;
+	uint32_t *pkt_len_aligns = NULL;
+	size_t total_buff_len = 0;
+	pcap_t *pcap_handle;
+	char pcap_errbuf[PCAP_ERRBUF_SIZE];
+	uint32_t max_len;
+	struct pcap_pkthdr pcap_hdr;
+	const uint8_t *pkt;
+	uint8_t *buff = NULL;
+	uint32_t pktmbuf_maxlen = (uint32_t)
+			(rte_pktmbuf_data_room_size(port->mempool) -
+			RTE_PKTMBUF_HEADROOM);
+
+	if (p->file_name == NULL)
+		return 0;
+
+	if (p->n_bytes_per_pkt == 0)
+		max_len = pktmbuf_maxlen;
+	else
+		max_len = RTE_MIN(p->n_bytes_per_pkt, pktmbuf_maxlen);
+
+	/* first time open, get packet number */
+	pcap_handle = pcap_open_offline(p->file_name, pcap_errbuf);
+	if (pcap_handle == NULL) {
+		status = -ENOENT;
+		goto error_exit;
+	}
+
+	while ((pkt = pcap_next(pcap_handle, &pcap_hdr)) != NULL)
+		n_pkts++;
+
+	pcap_close(pcap_handle);
+
+	port->pkt_len = rte_zmalloc_socket("PCAP",
+		(sizeof(*port->pkt_len) * n_pkts), 0, socket_id);
+	if (port->pkt_len == NULL) {
+		status = -ENOMEM;
+		goto error_exit;
+	}
+
+	pkt_len_aligns = rte_malloc("PCAP",
+		(sizeof(*pkt_len_aligns) * n_pkts), 0);
+	if (pkt_len_aligns == NULL) {
+		status = -ENOMEM;
+		goto error_exit;
+	}
+
+	port->pkts = rte_zmalloc_socket("PCAP",
+		(sizeof(*port->pkts) * n_pkts), 0, socket_id);
+	if (port->pkts == NULL) {
+		status = -ENOMEM;
+		goto error_exit;
+	}
+
+	/* open 2nd time, get pkt_len */
+	pcap_handle = pcap_open_offline(p->file_name, pcap_errbuf);
+	if (pcap_handle == NULL) {
+		status = -ENOENT;
+		goto error_exit;
+	}
+
+	for (i = 0; i < n_pkts; i++) {
+		pkt = pcap_next(pcap_handle, &pcap_hdr);
+		port->pkt_len[i] = RTE_MIN(max_len, pcap_hdr.len);
+		pkt_len_aligns[i] = RTE_CACHE_LINE_ROUNDUP(
+			port->pkt_len[i]);
+		total_buff_len += pkt_len_aligns[i];
+	}
+
+	pcap_close(pcap_handle);
+
+	/* allocate a big trunk of data for pcap file load */
+	buff = rte_zmalloc_socket("PCAP",
+		total_buff_len, 0, socket_id);
+	if (buff == NULL) {
+		status = -ENOMEM;
+		goto error_exit;
+	}
+
+	port->pkt_buff = buff;
+
+	/* open file one last time to copy the pkt content */
+	pcap_handle = pcap_open_offline(p->file_name, pcap_errbuf);
+	if (pcap_handle == NULL) {
+		status = -ENOENT;
+		goto error_exit;
+	}
+
+	for (i = 0; i < n_pkts; i++) {
+		pkt = pcap_next(pcap_handle, &pcap_hdr);
+		rte_memcpy(buff, pkt, port->pkt_len[i]);
+		port->pkts[i] = buff;
+		buff += pkt_len_aligns[i];
+	}
+
+	pcap_close(pcap_handle);
+
+	port->n_pkts = n_pkts;
+
+	rte_free(pkt_len_aligns);
+
+	return 0;
+
+error_exit:
+	if (pkt_len_aligns)
+		rte_free(pkt_len_aligns);
+	if (port->pkt_len)
+		rte_free(port->pkt_len);
+	if (port->pkts)
+		rte_free(port->pkts);
+	if (port->pkt_buff)
+		rte_free(port->pkt_buff);
+
+	return status;
+}
+
+#else
+static int
+pcap_source_load(__rte_unused struct rte_port_source_params *p,
+		struct rte_port_source *port,
+		__rte_unused int socket_id)
+{
+	port->pkt_buff = NULL;
+	port->pkt_len = NULL;
+	port->pkts = NULL;
+	port->pkt_index = 0;
+
+	return -ENOTSUP;
+}
+#endif /* RTE_PORT_PCAP */
+
+#endif
+
 static void *
 rte_port_source_create(void *params, int socket_id)
 {
@@ -86,17 +262,66 @@ rte_port_source_create(void *params, int socket_id)
 	/* Initialization */
 	port->mempool = (struct rte_mempool *) p->mempool;
 
+#ifdef RTE_NEXT_ABI
+
+	/* pcap file load and initialization */
+	int status = pcap_source_load(p, port, socket_id);
+
+	if (status == 0) {
+		if (port->pkt_buff != NULL) {
+			RTE_LOG(INFO, PORT, "Successfully load pcap file "
+				"'%s' with %u pkts\n",
+				p->file_name, port->n_pkts);
+		}
+	} else if (status != -ENOTSUP) {
+		/* ENOTSUP is not treated as error */
+		switch (status) {
+		case -ENOENT:
+			RTE_LOG(ERR, PORT, "%s: Failed to open pcap file "
+				"'%s' for reading\n",
+				__func__, p->file_name);
+			break;
+		case -ENOMEM:
+			RTE_LOG(ERR, PORT, "%s: Not enough memory\n",
+				__func__);
+			break;
+		default:
+			RTE_LOG(ERR, PORT, "%s: Failed to enable PCAP "
+				"support for unknown reason\n",
+				__func__);
+			break;
+		}
+
+		rte_free(port);
+		port = NULL;
+	}
+
+#endif
+
 	return port;
 }
 
 static int
 rte_port_source_free(void *port)
 {
+	struct rte_port_source *p =
+			(struct rte_port_source *)port;
+
 	/* Check input parameters */
-	if (port == NULL)
+	if (p == NULL)
 		return 0;
 
-	rte_free(port);
+#ifdef RTE_NEXT_ABI
+
+	if (p->pkt_len)
+		rte_free(p->pkt_len);
+	if (p->pkts)
+		rte_free(p->pkts);
+	if (p->pkt_buff)
+		rte_free(p->pkt_buff);
+#endif
+
+	rte_free(p);
 
 	return 0;
 }
@@ -115,6 +340,26 @@ rte_port_source_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
 		rte_pktmbuf_reset(pkts[i]);
 	}
 
+#ifdef RTE_NEXT_ABI
+
+	if (p->pkt_buff != NULL) {
+		for (i = 0; i < n_pkts; i++) {
+			uint8_t *pkt_data = rte_pktmbuf_mtod(pkts[i],
+				uint8_t *);
+
+			rte_memcpy(pkt_data, p->pkts[p->pkt_index],
+					p->pkt_len[p->pkt_index]);
+			pkts[i]->data_len = p->pkt_len[p->pkt_index];
+			pkts[i]->pkt_len = pkts[i]->data_len;
+
+			p->pkt_index++;
+			if (p->pkt_index >= p->n_pkts)
+				p->pkt_index = 0;
+		}
+	}
+
+#endif
+
 	RTE_PORT_SOURCE_STATS_PKTS_IN_ADD(p, n_pkts);
 
 	return n_pkts;
diff --git a/lib/librte_port/rte_port_source_sink.h b/lib/librte_port/rte_port_source_sink.h
index 0f9be79..522d10d 100644
--- a/lib/librte_port/rte_port_source_sink.h
+++ b/lib/librte_port/rte_port_source_sink.h
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -53,6 +53,17 @@ extern "C" {
 struct rte_port_source_params {
 	/** Pre-initialized buffer pool */
 	struct rte_mempool *mempool;
+#ifdef RTE_NEXT_ABI
+
+	/** The full path of the pcap file to read packets from */
+	char *file_name;
+	/** The number of bytes to be read from each packet in the
+	 *  pcap file. If this value is 0, the whole packet is read;
+	 *  if it is bigger than packet size, the generated packets
+	 *  will contain the whole packet */
+	uint32_t n_bytes_per_pkt;
+
+#endif
 };
 
 /** source port operations */
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index daac09f..f621e11 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -95,6 +95,11 @@ endif
 # The static libraries do not know their dependencies.
 # So linking with static library requires explicit dependencies.
 ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
+
+ifeq ($(CONFIG_RTE_NEXT_ABI),y)
+_LDLIBS-$(CONFIG_RTE_PORT_PCAP)             += -lpcap
+endif
+
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_PCAP)       += -lpcap
 _LDLIBS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD)      += -lz
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX4_PMD)       += -libverbs
