diff --git a/lib/librte_eal/common/eal_common_errno.c b/lib/librte_eal/common/eal_common_errno.c
index c63a943b3..b6fec8cd5 100644
--- a/lib/librte_eal/common/eal_common_errno.c
+++ b/lib/librte_eal/common/eal_common_errno.c
@@ -27,7 +27,12 @@ rte_strerror(int errnum)
 	static const char *sep = "";
 #endif
 #define RETVAL_SZ 256
+#ifdef _WIN64
+	typedef char c_retval[RETVAL_SZ];
+	RTE_DEFINE_PER_LCORE(static c_retval, retval);
+#else
 	static RTE_DEFINE_PER_LCORE(char[RETVAL_SZ], retval);
+#endif
 	char *ret = RTE_PER_LCORE(retval);
 
 	/* since some implementations of strerror_r throw an error
@@ -41,9 +46,13 @@ rte_strerror(int errnum)
 		case E_RTE_NO_CONFIG:
 			return "Missing rte_config structure";
 		default:
+#ifdef _WIN64
+		strerror_s(RTE_PER_LCORE(retval), RETVAL_SZ, errnum);
+#else
 			if (strerror_r(errnum, ret, RETVAL_SZ) != 0)
 				snprintf(ret, RETVAL_SZ, "Unknown error%s %d",
 						sep, errnum);
+#endif
 		}
 
 	return ret;
diff --git a/lib/librte_eal/common/eal_common_log.c b/lib/librte_eal/common/eal_common_log.c
index c714a4bd2..28407ce77 100644
--- a/lib/librte_eal/common/eal_common_log.c
+++ b/lib/librte_eal/common/eal_common_log.c
@@ -28,8 +28,10 @@ struct rte_eal_opt_loglevel {
 	/** Next list entry */
 	TAILQ_ENTRY(rte_eal_opt_loglevel) next;
 	/** Compiled regular expression obtained from the option */
+#ifndef _WIN64
 	regex_t re_match;
 	/** Glob match string option */
+#endif // !_WIN64
 	char *pattern;
 	/** Log level value obtained from the option */
 	uint32_t level;
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index e31eca5c0..17f2ae6a2 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -11,7 +11,9 @@
 #include <limits.h>
 #include <errno.h>
 #include <getopt.h>
+#ifndef _WIN64
 #include <dlfcn.h>
+#endif
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <dirent.h>
diff --git a/lib/librte_eal/common/eal_common_timer.c b/lib/librte_eal/common/eal_common_timer.c
index dcf26bfea..f6c965b64 100644
--- a/lib/librte_eal/common/eal_common_timer.c
+++ b/lib/librte_eal/common/eal_common_timer.c
@@ -33,6 +33,7 @@ rte_delay_us_block(unsigned int us)
 		rte_pause();
 }
 
+#ifndef _WIN64
 void __rte_experimental
 rte_delay_us_sleep(unsigned int us)
 {
@@ -54,6 +55,7 @@ rte_delay_us_sleep(unsigned int us)
 		ind = 1 - ind;
 	}
 }
+#endif
 
 uint64_t
 rte_get_tsc_hz(void)
diff --git a/lib/librte_eal/common/include/arch/x86/rte_byteorder.h b/lib/librte_eal/common/include/arch/x86/rte_byteorder.h
index a2dfecc1f..0f39af5c2 100644
--- a/lib/librte_eal/common/include/arch/x86/rte_byteorder.h
+++ b/lib/librte_eal/common/include/arch/x86/rte_byteorder.h
@@ -26,10 +26,16 @@ extern "C" {
 static inline uint16_t rte_arch_bswap16(uint16_t _x)
 {
 	uint16_t x = _x;
+#ifndef _WIN64
 	asm volatile ("xchgb %b[x1],%h[x2]"
 		      : [x1] "=Q" (x)
 		      : [x2] "0" (x)
 		      );
+#else
+	__asm {
+	    /* Add appropriate __asm here */
+	}
+#endif
 	return x;
 }
 
@@ -41,9 +47,17 @@ static inline uint16_t rte_arch_bswap16(uint16_t _x)
 static inline uint32_t rte_arch_bswap32(uint32_t _x)
 {
 	uint32_t x = _x;
+#ifndef _WIN64
 	asm volatile ("bswap %[x]"
 		      : [x] "+r" (x)
 		      );
+#else
+	__asm {
+	    mov     eax, x
+	    bswap   eax
+	    mov     x, eax
+	}
+#endif
 	return x;
 }
 
diff --git a/lib/librte_eal/common/include/arch/x86/rte_rtm.h b/lib/librte_eal/common/include/arch/x86/rte_rtm.h
index eb0f8e81e..8056b25de 100644
--- a/lib/librte_eal/common/include/arch/x86/rte_rtm.h
+++ b/lib/librte_eal/common/include/arch/x86/rte_rtm.h
@@ -29,29 +29,45 @@ static __attribute__((__always_inline__)) inline
 unsigned int rte_xbegin(void)
 {
 	unsigned int ret = RTE_XBEGIN_STARTED;
-
+#ifndef _WIN64
 	asm volatile(".byte 0xc7,0xf8 ; .long 0" : "+a" (ret) :: "memory");
+#else
+	/* Add appropriate asm here for Windows compilers */
+#endif
 	return ret;
 }
 
 static __attribute__((__always_inline__)) inline
 void rte_xend(void)
 {
-	 asm volatile(".byte 0x0f,0x01,0xd5" ::: "memory");
+#ifndef _WIN64
+	asm volatile(".byte 0x0f,0x01,0xd5" ::: "memory");
+#else
+	/* Add appropriate asm here for Windows compilers */
+#endif
 }
 
 /* not an inline function to workaround a clang bug with -O0 */
+#ifndef _WIN64
 #define rte_xabort(status) do { \
 	asm volatile(".byte 0xc6,0xf8,%P0" :: "i" (status) : "memory"); \
 } while (0)
+#else
+#define rte_xabort(status) do { \
+	/* Add appropriate asm here for Windows compilers */ \
+} while (0)
+#endif
 
 static __attribute__((__always_inline__)) inline
 int rte_xtest(void)
 {
 	unsigned char out;
-
+#ifndef _WIN64
 	asm volatile(".byte 0x0f,0x01,0xd6 ; setnz %0" :
 		"=r" (out) :: "memory");
+#else
+	/* Add appropriate asm here for Windows compilers */
+#endif
 	return out;
 }
 
diff --git a/lib/librte_eal/common/include/rte_common.h b/lib/librte_eal/common/include/rte_common.h
index 66cdf60b2..3e24463be 100644
--- a/lib/librte_eal/common/include/rte_common.h
+++ b/lib/librte_eal/common/include/rte_common.h
@@ -103,8 +103,15 @@ typedef uint16_t unaligned_uint16_t;
  *   Priority number must be above 100.
  *   Lowest number is the first to run.
  */
+#ifndef _WIN64
 #define RTE_INIT_PRIO(func, prio) \
 static void __attribute__((constructor(RTE_PRIO(prio)), used)) func(void)
+#else
+/* Re-define this without the __attribute__ and static declarator */
+#define RTE_INIT_PRIO(func, prio) \
+void func(void)
+#endif
+
 
 /**
  * Run function before main() with low priority.
@@ -262,7 +269,11 @@ static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void)
 static inline int
 rte_is_aligned(void *ptr, unsigned align)
 {
+#ifndef _WIN64
 	return RTE_PTR_ALIGN(ptr, align) == ptr;
+#else
+	return (((uintptr_t)ptr % align) == 0);
+#endif
 }
 
 /*********** Macros for compile type checks ********/
diff --git a/lib/librte_eal/common/include/rte_malloc_heap.h b/lib/librte_eal/common/include/rte_malloc_heap.h
index 4a7e0eb1d..3a23fcd59 100644
--- a/lib/librte_eal/common/include/rte_malloc_heap.h
+++ b/lib/librte_eal/common/include/rte_malloc_heap.h
@@ -20,6 +20,9 @@ struct malloc_elem;
 /**
  * Structure to hold malloc heap
  */
+#ifdef _WIN64
+RTE_CACHE_ALIGN
+#endif
 struct malloc_heap {
 	rte_spinlock_t lock;
 	LIST_HEAD(, malloc_elem) free_head[RTE_HEAP_NUM_FREELISTS];
diff --git a/lib/librte_eal/common/include/rte_random.h b/lib/librte_eal/common/include/rte_random.h
index b2ca1c209..680d0774c 100644
--- a/lib/librte_eal/common/include/rte_random.h
+++ b/lib/librte_eal/common/include/rte_random.h
@@ -18,6 +18,10 @@ extern "C" {
 #include <stdint.h>
 #include <stdlib.h>
 
+#ifdef _WIN64
+#include "rand48.h"
+#endif
+
 /**
  * Seed the pseudo-random generator.
  *
diff --git a/lib/librte_eal/common/include/rte_string_fns.h b/lib/librte_eal/common/include/rte_string_fns.h
index 9a2a1ff90..5615d1f3a 100644
--- a/lib/librte_eal/common/include/rte_string_fns.h
+++ b/lib/librte_eal/common/include/rte_string_fns.h
@@ -66,6 +66,7 @@ rte_strlcpy(char *dst, const char *src, size_t size)
 #endif
 
 #else /* non-BSD platforms */
+#ifndef _WIN64
 #ifdef RTE_USE_LIBBSD
 #include <bsd/string.h>
 
@@ -73,6 +74,7 @@ rte_strlcpy(char *dst, const char *src, size_t size)
 #define strlcpy(dst, src, size) rte_strlcpy(dst, src, size)
 
 #endif /* RTE_USE_LIBBSD */
+#endif /* WIN64 */
 #endif /* BSDAPP */
 
 /**
diff --git a/lib/librte_eal/common/malloc_elem.h b/lib/librte_eal/common/malloc_elem.h
index e2bda4c02..697b1b074 100644
--- a/lib/librte_eal/common/malloc_elem.h
+++ b/lib/librte_eal/common/malloc_elem.h
@@ -20,6 +20,9 @@ enum elem_state {
 	ELEM_PAD  /* element is a padding-only header */
 };
 
+#ifdef _WIN64
+RTE_CACHE_ALIGN
+#endif
 struct malloc_elem {
 	struct malloc_heap *heap;
 	struct malloc_elem *volatile prev;
diff --git a/lib/librte_eal/common/malloc_heap.c b/lib/librte_eal/common/malloc_heap.c
index c6a6d4f6b..5314ebd20 100644
--- a/lib/librte_eal/common/malloc_heap.c
+++ b/lib/librte_eal/common/malloc_heap.c
@@ -60,11 +60,13 @@ check_hugepage_sz(unsigned flags, uint64_t hugepage_sz)
 	case RTE_PGSIZE_1G:
 		check_flag = RTE_MEMZONE_1GB;
 		break;
+#ifndef _WIN64
 	case RTE_PGSIZE_4G:
 		check_flag = RTE_MEMZONE_4GB;
 		break;
 	case RTE_PGSIZE_16G:
 		check_flag = RTE_MEMZONE_16GB;
+#endif
 	}
 
 	return check_flag & flags;
diff --git a/lib/librte_eal/common/malloc_heap.h b/lib/librte_eal/common/malloc_heap.h
index e48996d52..df60ab62c 100644
--- a/lib/librte_eal/common/malloc_heap.h
+++ b/lib/librte_eal/common/malloc_heap.h
@@ -10,6 +10,10 @@
 #include <rte_malloc.h>
 #include <rte_malloc_heap.h>
 
+#ifdef _WIN64
+#include <rte_lcore.h>
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
diff --git a/lib/librte_eal/windows/eal/eal.c b/lib/librte_eal/windows/eal/eal.c
new file mode 100644
index 000000000..b060bbb92
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal.c
@@ -0,0 +1,697 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <direct.h>
+
+#include <rte_eal.h>
+#include <rte_eal_memconfig.h>
+#include <rte_log.h>
+#include <rte_random.h>
+#include <rte_cycles.h>
+#include <rte_errno.h>
+#include <rte_windows.h>
+
+#include "eal_private.h"
+#include "eal_thread.h"
+#include "eal_internal_cfg.h"
+#include "eal_filesystem.h"
+#include "eal_hugepages.h"
+#include "eal_options.h"
+#include "malloc_heap.h"
+#include "private.h"
+
+#define MEMSIZE_IF_NO_HUGE_PAGE (64ULL * 1024ULL * 1024ULL)
+
+/* Allow the application to print its usage message too if set */
+static rte_usage_hook_t	rte_application_usage_hook = NULL;
+
+/* define fd variable here, because file needs to be kept open for the
+ * duration of the program, as we hold a write lock on it in the primary proc */
+
+static int mem_cfg_fd = -1; // INVALID_HANDLE_VALUE;
+/*
+static struct flock wr_lock = {
+		.l_type = F_WRLCK,
+		.l_whence = SEEK_SET,
+		.l_start = offsetof(struct rte_mem_config, memseg),
+		.l_len = sizeof(early_mem_config.memseg),
+};
+*/
+/* early configuration structure, when memory config is not mmapped */
+static struct rte_mem_config early_mem_config;
+
+/* Address of global and public configuration */
+static struct rte_config rte_config = {
+		.mem_config = &early_mem_config,
+};
+
+/* internal configuration (per-core) */
+struct lcore_config lcore_config[RTE_MAX_LCORE];
+
+/* internal configuration */
+struct internal_config internal_config;
+
+/* external function protoypes */
+/* these functions are created by the RTE_REGISTER_BUS macro */
+extern void businitfn_pci(void);
+extern void businitfn_vdev(void);
+
+/* these functions are created by the MEMPOOL_REGISTER_OPS macro */
+extern void mp_hdlr_init_ops_mp_mc(void);
+extern void mp_hdlr_init_ops_sp_sc(void);
+extern void mp_hdlr_init_ops_mp_sc(void);
+extern void mp_hdlr_init_ops_sp_mc(void);
+
+/* these functions are created by the EAL_REGISTER_TAILQ macro */
+extern void init_rte_mempool_tailq(void);
+extern void init_rte_ring_tailq(void);
+extern void init_rte_hash_tailq(void);
+extern void init_rte_fbk_hash_tailq(void);
+extern void init_rte_distributor_tailq(void);
+extern void init_rte_dist_burst_tailq(void);
+extern void init_rte_uio_tailq(void);
+extern void init_rte_lpm_tailq(void);
+extern void init_rte_lpm6_tailq(void);
+
+/* these functions are created by the RTE_PMD_REGISTER_PCI macro */
+extern void pciinitfn_net_i40e(void);
+
+/* these are more constructor-like function, that we'll need to call at the start */
+extern void rte_timer_init(void);
+extern void rte_log_init(void);
+extern void i40e_init_log(void);
+
+/* Return a pointer to the configuration structure */
+struct rte_config *
+rte_eal_get_configuration(void)
+{
+	return &rte_config;
+}
+
+/* Return mbuf pool ops name */
+const char *
+rte_eal_mbuf_user_pool_ops(void)
+{
+	return internal_config.user_mbuf_pool_ops_name;
+}
+
+enum rte_iova_mode
+rte_eal_iova_mode(void)
+{
+	return rte_eal_get_configuration()->iova_mode;
+}
+
+/* platform-specific runtime dir */
+static char runtime_dir[PATH_MAX];
+
+/* create memory configuration in shared/mmap memory. Take out
+ * a write lock on the memsegs, so we can auto-detect primary/secondary.
+ * This means we never close the file while running (auto-close on exit).
+ * We also don't lock the whole file, so that in future we can use read-locks
+ * on other parts, e.g. memzones, to detect if there are running secondary
+ * processes. */
+static void
+rte_eal_config_create(void)
+{
+	void *rte_mem_cfg_addr;
+	BOOL retval;
+
+	const char *pathname = eal_runtime_config_path();
+
+	if (internal_config.no_shconf)
+		return;
+
+	if (mem_cfg_fd < 0) {
+	    mem_cfg_fd = _open(pathname, _O_CREAT | _O_RDWR | _O_TRUNC, _S_IREAD | _S_IWRITE);
+	    if (mem_cfg_fd < 0)
+		rte_panic("Cannot open '%s' for rte_mem_config...Error: %d\n", pathname, errno);
+	}
+
+	/* Lock file for exclusive access */
+	OVERLAPPED sOverlapped = {0};
+	sOverlapped.Offset = sizeof(*rte_config.mem_config);
+	sOverlapped.OffsetHigh = 0;
+
+	HANDLE hWinFileHandle = (HANDLE)_get_osfhandle(mem_cfg_fd);
+	retval = LockFileEx(hWinFileHandle,
+			    LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, 0,
+			    sizeof(*rte_config.mem_config), 0, &sOverlapped);
+	if (!retval) {
+	    _close(mem_cfg_fd);
+	    rte_exit(EXIT_FAILURE, "Cannot create lock on '%s'. Is another primary process running?\n", pathname);
+	}
+
+	rte_mem_cfg_addr = mmap(NULL, sizeof(*rte_config.mem_config),
+				PROT_READ | PROT_WRITE, MAP_SHARED, (int)mem_cfg_fd, 0);
+
+	if (rte_mem_cfg_addr == MAP_FAILED) {
+	    _close(mem_cfg_fd);
+	    rte_exit(EXIT_FAILURE, "Cannot mmap memory for rte_config\n");
+	}
+
+	memcpy(rte_mem_cfg_addr, &early_mem_config, sizeof(early_mem_config));
+	rte_config.mem_config = (struct rte_mem_config *) rte_mem_cfg_addr;
+}
+
+/* attach to an existing shared memory config */
+static void
+rte_eal_config_attach(void)
+{
+	void *rte_mem_cfg_addr;
+	const char *pathname = eal_runtime_config_path();
+
+	if (internal_config.no_shconf)
+		return;
+
+	if (mem_cfg_fd < 0) {
+	    mem_cfg_fd = _open(pathname, O_RDWR);
+	    if (mem_cfg_fd < 0)
+		rte_panic("Cannot open '%s' for rte_mem_config\n", pathname);
+	}
+
+	rte_mem_cfg_addr = mmap(NULL, sizeof(*rte_config.mem_config), PROT_READ | PROT_WRITE, MAP_SHARED, mem_cfg_fd, 0);
+	_close(mem_cfg_fd);
+
+	if (rte_mem_cfg_addr == MAP_FAILED)
+		rte_panic("Cannot mmap memory for rte_config\n");
+
+	rte_config.mem_config = (struct rte_mem_config *) rte_mem_cfg_addr;
+}
+
+/* Detect if we are a primary or a secondary process */
+enum rte_proc_type_t
+eal_proc_type_detect(void)
+{
+	enum rte_proc_type_t ptype = RTE_PROC_PRIMARY;
+	const char *pathname = eal_runtime_config_path();
+
+	/* if we can open the file but not get a write-lock we are a secondary
+	 * process. NOTE: if we get a file handle back, we keep that open
+	 * and don't close it to prevent a race condition between multiple opens */
+	if ((mem_cfg_fd = _open(pathname, O_RDWR)) >= 0) {
+	    OVERLAPPED sOverlapped = { 0 };
+	    sOverlapped.Offset = sizeof(*rte_config.mem_config);
+	    sOverlapped.OffsetHigh = 0;
+
+	    HANDLE hWinFileHandle = (HANDLE)_get_osfhandle(mem_cfg_fd);
+
+	    if (!LockFileEx(hWinFileHandle,
+			    LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, 0,
+			    sizeof(*rte_config.mem_config), 0, &sOverlapped))
+		ptype = RTE_PROC_SECONDARY;
+	}
+
+	RTE_LOG(INFO, EAL, "Auto-detected process type: %s\n",
+			    ptype == RTE_PROC_PRIMARY ? "PRIMARY" : "SECONDARY");
+
+	return ptype;
+}
+
+/* Sets up rte_config structure with the pointer to shared memory config.*/
+static void
+rte_config_init(void)
+{
+	rte_config.process_type = internal_config.process_type;
+
+	switch (rte_config.process_type){
+	case RTE_PROC_PRIMARY:
+		rte_eal_config_create();
+		break;
+	case RTE_PROC_SECONDARY:
+		rte_eal_config_attach();
+		rte_eal_mcfg_wait_complete(rte_config.mem_config);
+		break;
+	case RTE_PROC_AUTO:
+	case RTE_PROC_INVALID:
+		rte_panic("Invalid process type\n");
+	}
+}
+
+/* display usage */
+static void
+eal_usage(const char *prgname)
+{
+	printf("\nUsage: %s ", prgname);
+	eal_common_usage();
+	/* Allow the application to print its usage message too if hook is set */
+	if ( rte_application_usage_hook ) {
+		printf("===== Application Usage =====\n\n");
+		rte_application_usage_hook(prgname);
+	}
+}
+
+/* Set a per-application usage message */
+rte_usage_hook_t
+rte_set_application_usage_hook( rte_usage_hook_t usage_func )
+{
+	rte_usage_hook_t	old_func;
+
+	/* Will be NULL on the first call to denote the last usage routine. */
+	old_func			= rte_application_usage_hook;
+	rte_application_usage_hook	= usage_func;
+
+	return old_func;
+}
+
+static inline size_t
+eal_get_hugepage_mem_size(void)
+{
+	uint64_t size = 0;
+	size = (uint64_t)GetLargePageMinimum();
+
+	return (size < SIZE_MAX) ? (size_t)(size) : SIZE_MAX;
+}
+
+/* Parse the arguments for --log-level only */
+static void
+eal_log_level_parse(int argc, char **argv)
+{
+	int opt;
+	char **argvopt;
+	int option_index;
+
+	argvopt = argv;
+
+	eal_reset_internal_config(&internal_config);
+
+	while ((opt = getopt_long(argc, argvopt, eal_short_options,
+				  eal_long_options, &option_index)) != EOF) {
+
+		int ret;
+
+		/* getopt is not happy, stop right now */
+		if (opt == '?')
+			break;
+
+		ret = (opt == OPT_LOG_LEVEL_NUM) ?
+			eal_parse_common_option(opt, optarg, &internal_config) : 0;
+
+		/* common parser is not happy */
+		if (ret < 0)
+			break;
+	}
+
+	optind = 0; /* reset getopt lib */
+}
+
+/* Parse the argument given in the command line of the application */
+static int
+eal_parse_args(int argc, char **argv)
+{
+	int opt, ret;
+	char **argvopt;
+	int option_index;
+	char *prgname = argv[0];
+
+	argvopt = argv;
+
+	while ((opt = getopt_long(argc, argvopt, eal_short_options,
+				  eal_long_options, &option_index)) != EOF) {
+
+		int ret;
+
+		/* getopt is not happy, stop right now */
+		if (opt == '?') {
+			eal_usage(prgname);
+			return -1;
+		}
+
+		ret = eal_parse_common_option(opt, optarg, &internal_config);
+		/* common parser is not happy */
+		if (ret < 0) {
+			eal_usage(prgname);
+			return -1;
+		}
+		/* common parser handled this option */
+		if (ret == 0)
+			continue;
+
+		switch (opt) {
+		case 'h':
+			eal_usage(prgname);
+			exit(EXIT_SUCCESS);
+		default:
+			if (opt < OPT_LONG_MIN_NUM && isprint(opt)) {
+				RTE_LOG(ERR, EAL, "Option %c is not supported "
+					"on FreeBSD\n", opt);
+			} else if (opt >= OPT_LONG_MIN_NUM &&
+				   opt < OPT_LONG_MAX_NUM) {
+				RTE_LOG(ERR, EAL, "Option %s is not supported "
+					"on FreeBSD\n",
+					eal_long_options[option_index].name);
+			} else {
+				RTE_LOG(ERR, EAL, "Option %d is not supported "
+					"on FreeBSD\n", opt);
+			}
+			eal_usage(prgname);
+			return -1;
+		}
+	}
+
+	/* create runtime data directory */
+	if (internal_config.no_shconf == 0 &&
+		eal_create_runtime_dir() < 0) {
+		RTE_LOG(ERR, EAL, "Cannot create runtime directory\n");
+		return ret = -1;
+	}
+
+	if (eal_adjust_config(&internal_config) != 0)
+		return -1;
+
+	/* sanity checks */
+	if (eal_check_common_options(&internal_config) != 0) {
+		eal_usage(prgname);
+		return -1;
+	}
+
+	if (optind >= 0)
+		argv[optind-1] = prgname;
+	ret = optind-1;
+	optind = 0; /* reset getopt lib */
+	return ret;
+}
+
+static int
+check_socket(const struct rte_memseg_list *msl, void *arg)
+{
+	int *socket_id = arg;
+
+	return *socket_id == msl->socket_id;
+}
+
+static void
+eal_check_mem_on_local_socket(void)
+{
+	const struct rte_memseg *ms;
+	int i, socket_id;
+
+	socket_id = rte_lcore_to_socket_id(rte_config.master_lcore);
+
+	if (rte_memseg_list_walk(check_socket, &socket_id) == 0)
+		RTE_LOG(WARNING, EAL, "WARNING: Master core has no memory on local socket!\n");
+}
+
+static int
+sync_func(__attribute__((unused)) void *arg)
+{
+	return 0;
+}
+
+inline static void
+rte_eal_mcfg_complete(void)
+{
+	/* ALL shared mem_config related INIT DONE */
+	if (rte_config.process_type == RTE_PROC_PRIMARY)
+		rte_config.mem_config->magic = RTE_MAGIC;
+}
+
+/* return non-zero if hugepages are enabled. */
+int rte_eal_has_hugepages(void)
+{
+	return !internal_config.no_hugetlbfs;
+}
+
+/* Abstraction for port I/0 privilege */
+int
+rte_eal_iopl_init(void)
+{
+	// Not required on modern processors?
+	return -1;
+}
+
+static void rte_eal_init_alert(const char *msg)
+{
+	fprintf(stderr, "EAL: FATAL: %s\n", msg);
+	RTE_LOG(ERR, EAL, "%s\n", msg);
+}
+
+/* Register and initialize all buses */
+/* (This is a workaround for Windows in lieu of a constructor-like function) */
+static void
+eal_register_and_init_buses()
+{
+	businitfn_pci();
+	/* businitfn_vdev(); Not presently supported! */
+}
+
+/* Register and initialize all mempools */
+/* (This is a workaround for Windows in lieu of a constructor-like function) */
+static void
+eal_register_and_init_mempools()
+{
+	/* these functions are created by the MEMPOOL_REGISTER_OPS macro */
+	mp_hdlr_init_ops_mp_mc();
+	mp_hdlr_init_ops_sp_sc();
+	mp_hdlr_init_ops_mp_sc();
+	mp_hdlr_init_ops_sp_mc();
+}
+
+/* Register and initialize tailqs */
+/* (This is a workaround for Windows in lieu of a constructor-like function) */
+static void
+eal_register_and_init_tailq()
+{
+	/* these functions are created by the EAL_REGISTER_TAILQ macro */
+	init_rte_mempool_tailq();
+	init_rte_ring_tailq();
+	init_rte_hash_tailq();
+	init_rte_fbk_hash_tailq();
+	init_rte_distributor_tailq();
+	init_rte_dist_burst_tailq();
+	init_rte_uio_tailq();
+	init_rte_lpm_tailq();
+	init_rte_lpm6_tailq();
+}
+
+/* Register and initialize all supported PMDs */
+/* (This is a workaround for Windows in lieu of a constructor-like function) */
+static void
+eal_register_and_init_pmd()
+{
+	/* these functions are created by the RTE_PMD_REGISTER_PCI macro */
+	pciinitfn_net_i40e();  /* init the Intel 40GbE PMD */
+}
+
+/* Launch threads, called at application init(). */
+int
+rte_eal_init(int argc, char **argv)
+{
+	int i, fctret, ret;
+	pthread_t thread_id;
+	static rte_atomic32_t run_once = RTE_ATOMIC32_INIT(0);
+	char cpuset[RTE_CPU_AFFINITY_STR_LEN];
+
+	rte_timer_init(); /* Initialize timer function */
+
+	if (!rte_atomic32_test_and_set(&run_once))
+		return -1;
+
+	thread_id = pthread_self();
+
+	/* initialize all logs */
+	rte_eal_log_init(NULL, 0);
+	rte_log_init();
+
+	eal_log_level_parse(argc, argv);
+
+	/* set log level as early as possible */
+	rte_log_set_global_level(RTE_LOG_LEVEL);
+
+	/* create a map of all processors in the system */
+	eal_create_cpu_map();
+
+	if (rte_eal_cpu_init() < 0)
+		rte_panic("Cannot detect lcores\n");
+
+	fctret = eal_parse_args(argc, argv);
+	if (fctret < 0)
+		exit(1);
+
+	rte_config_init();
+
+	if (internal_config.no_hugetlbfs == 0 &&
+			internal_config.process_type != RTE_PROC_SECONDARY &&
+			eal_hugepage_info_init() < 0)
+		rte_panic("Cannot get hugepage information\n");
+
+	if (internal_config.memory == 0 && internal_config.force_sockets == 0) {
+		if (internal_config.no_hugetlbfs)
+			internal_config.memory = MEMSIZE_IF_NO_HUGE_PAGE;
+		else
+			internal_config.memory = eal_get_hugepage_mem_size();
+	}
+
+	if (internal_config.vmware_tsc_map == 1) {
+#ifdef RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT
+		rte_cycles_vmware_tsc_map = 1;
+		RTE_LOG (DEBUG, EAL, "Using VMWARE TSC MAP, "
+				"you must have monitor_control.pseudo_perfctr = TRUE\n");
+#else
+		RTE_LOG (WARNING, EAL, "Ignoring --vmware-tsc-map because "
+				"RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT is not set\n");
+#endif
+	}
+
+	rte_srand(rte_rdtsc());
+
+	/* in secondary processes, memory init may allocate additional fbarrays
+	* not present in primary processes, so to avoid any potential issues,
+	* initialize memzones first.
+	*/
+	if (rte_eal_memzone_init() < 0)
+		rte_panic("Cannot init memzone\n");
+
+	if (rte_eal_memory_init() < 0)
+		rte_panic("Cannot init memory\n");
+
+	if (rte_eal_malloc_heap_init() < 0)
+		rte_panic("Cannot init malloc heap\n");
+
+	if (rte_eal_tailqs_init() < 0)
+		rte_panic("Cannot init tail queues for objects\n");
+
+	if (rte_eal_alarm_init() < 0)
+		rte_panic("Cannot init interrupt-handling thread\n");
+
+	if (rte_eal_intr_init() < 0)
+		rte_panic("Cannot init interrupt-handling thread\n");
+
+	if (rte_eal_timer_init() < 0)
+		rte_panic("Cannot init HPET or TSC timers\n");
+
+	eal_check_mem_on_local_socket();
+
+	eal_thread_init_master(rte_config.master_lcore);
+
+	ret = eal_thread_dump_affinity(cpuset, RTE_CPU_AFFINITY_STR_LEN);
+
+	RTE_LOG(DEBUG, EAL, "Master lcore %u is ready (tid=%p;cpuset=[%s%s])\n",
+		rte_config.master_lcore, thread_id, cpuset,
+		ret == 0 ? "" : "...");
+
+	RTE_LCORE_FOREACH_SLAVE(i) {
+
+		/*
+		 * create communication pipes between master thread
+		 * and children
+		 */
+		if (pipe(lcore_config[i].pipe_master2slave) < 0)
+			rte_panic("Cannot create pipe\n");
+		if (pipe(lcore_config[i].pipe_slave2master) < 0)
+			rte_panic("Cannot create pipe\n");
+
+		lcore_config[i].state = WAIT;
+
+		/* create a thread for each lcore */
+		ret = pthread_create(&lcore_config[i].thread_id, NULL,
+				     eal_thread_loop, NULL);
+		if (ret != 0)
+			rte_panic("Cannot create thread\n");
+	}
+
+	/*
+	 * Launch a dummy function on all slave lcores, so that master lcore
+	 * knows they are all ready when this function returns.
+	 */
+	rte_eal_mp_remote_launch(sync_func, NULL, SKIP_MASTER);
+	rte_eal_mp_wait_lcore();
+
+#ifdef EAL_SERVICES_SUPPORT
+	/* Not supported on Windows, presently */
+	/* initialize services so vdevs register service during bus_probe. */
+	ret = rte_service_init();
+	if (ret) {
+		rte_eal_init_alert("rte_service_init() failed\n");
+		rte_errno = ENOEXEC;
+		return -1;
+	}
+#endif
+
+	/* Probe & Initialize PCI devices */
+	if (rte_bus_probe())
+		rte_panic("Cannot probe PCI\n");
+
+#ifdef EAL_SERVICES_SUPPORT
+	/* initialize default service/lcore mappings and start running. Ignore
+	* -ENOTSUP, as it indicates no service coremask passed to EAL.
+	*/
+	ret = rte_service_start_with_defaults();
+	if (ret < 0 && ret != -ENOTSUP) {
+		rte_errno = ENOEXEC;
+		return -1;
+	}
+#endif
+	rte_eal_mcfg_complete();
+
+	return fctret;
+}
+
+/* get core role */
+enum rte_lcore_role_t
+rte_eal_lcore_role(unsigned lcore_id)
+{
+	return rte_config.lcore_role[lcore_id];
+}
+
+enum rte_proc_type_t
+rte_eal_process_type(void)
+{
+	return rte_config.process_type;
+}
+
+int
+eal_create_runtime_dir(void)
+{
+	char  Directory[PATH_MAX];
+
+	GetTempPathA(sizeof(Directory), Directory);
+
+	char tmp[PATH_MAX];
+	int ret;
+
+
+	/* create DPDK subdirectory under runtime dir */
+	ret = snprintf(tmp, sizeof(tmp), "%s\\dpdk", Directory);
+	if (ret < 0 || ret == sizeof(tmp)) {
+		RTE_LOG(ERR, EAL, "Error creating DPDK runtime path name\n");
+		return -1;
+	}
+
+	/* create prefix-specific subdirectory under DPDK runtime dir */
+	ret = snprintf(runtime_dir, sizeof(runtime_dir), "%s\\%s",
+		tmp, internal_config.hugefile_prefix);
+	if (ret < 0 || ret == sizeof(runtime_dir)) {
+		RTE_LOG(ERR, EAL, "Error creating prefix-specific runtime path name\n");
+		return -1;
+	}
+
+	/* create the path if it doesn't exist. no "mkdir -p" here, so do it
+	* step by step.
+	*/
+	ret = mkdir(tmp);
+	if (ret < 0 && errno != EEXIST) {
+		RTE_LOG(ERR, EAL, "Error creating '%s': %s\n",
+			tmp, strerror(errno));
+		return -1;
+	}
+
+	ret = mkdir(runtime_dir);
+	if (ret < 0 && errno != EEXIST) {
+		RTE_LOG(ERR, EAL, "Error creating '%s': %s\n",
+			runtime_dir, strerror(errno));
+		return -1;
+	}
+
+	return 0;
+}
+
+const char *
+eal_get_runtime_dir(void)
+{
+	return runtime_dir;
+}
diff --git a/lib/librte_eal/windows/eal/eal_alarm.c b/lib/librte_eal/windows/eal/eal_alarm.c
new file mode 100644
index 000000000..d881cc5dd
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal_alarm.c
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#include <rte_alarm.h>
+#include <rte_common.h>
+#include "eal_private.h"
+
+int
+rte_eal_alarm_init(void)
+{
+	return 0;
+}
+
+
+int
+rte_eal_alarm_set(uint64_t us __rte_unused,
+		rte_eal_alarm_callback cb_fn __rte_unused,
+		void *cb_arg __rte_unused)
+{
+	return -ENOTSUP;
+}
+
+int
+rte_eal_alarm_cancel(rte_eal_alarm_callback cb_fn __rte_unused,
+		void *cb_arg __rte_unused)
+{
+	return -ENOTSUP;
+}
diff --git a/lib/librte_eal/windows/eal/eal_debug.c b/lib/librte_eal/windows/eal/eal_debug.c
new file mode 100644
index 000000000..c1cb810c5
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal_debug.c
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#include <rte_windows.h>
+#include <DbgHelp.h>
+
+#include <rte_log.h>
+#include <rte_debug.h>
+
+#define MAX_TRACE_STACK_FRAMES	1024
+
+/* dump the stack of the calling core */
+void rte_dump_stack(void)
+{
+	void *pCallingStack[MAX_TRACE_STACK_FRAMES];
+	WORD  numFrames;
+	DWORD dwError;
+	HANDLE hProcess = GetCurrentProcess();
+
+	SymInitialize(hProcess, NULL, TRUE);
+	numFrames = RtlCaptureStackBackTrace(0, MAX_TRACE_STACK_FRAMES, pCallingStack, NULL);
+
+	for (int i = 0; i < numFrames; i++) {
+	    DWORD64 dwAddress = (DWORD64)(pCallingStack[i]);
+	    DWORD   dwDisplacement;
+
+	    char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
+	    PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
+
+	    pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
+	    pSymbol->MaxNameLen = MAX_SYM_NAME;
+
+	    // Get the symbol information from the address
+	    if (SymFromAddr(hProcess, dwAddress, NULL, pSymbol)) {
+		// Get the line number from the same address
+		IMAGEHLP_LINE64 line;
+
+		SymSetOptions(SYMOPT_LOAD_LINES);
+		line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
+
+		if (SymGetLineFromAddr64(hProcess, dwAddress, &dwDisplacement, &line))
+		    printf("Currently at %s in %s: line: %lu: address: 0x%0X\n", pSymbol->Name, line.FileName, line.LineNumber, pSymbol->Address);
+		else
+		    goto error;
+	    }
+	    else
+		goto error;
+
+	    continue;
+error:
+	    dwError = GetLastError();
+	    printf("SymFromAddr()/SymGetLineFromAddr64() failed: Error: %d\n", dwError);
+	}
+
+	return;
+}
+
+/* not implemented in this environment */
+void rte_dump_registers(void)
+{
+	return;
+}
+
+/* call abort(), it will generate a coredump if enabled */
+void __rte_panic(const char *funcname, const char *format, ...)
+{
+	va_list ap;
+
+	rte_log(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, "PANIC in %s():\n", funcname);
+	va_start(ap, format);
+	rte_vlog(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, format, ap);
+	va_end(ap);
+	rte_dump_stack();
+	rte_dump_registers();
+	abort();
+}
+
+/*
+ * Like rte_panic this terminates the application. However, no traceback is
+ * provided and no core-dump is generated.
+ */
+void
+rte_exit(int exit_code, const char *format, ...)
+{
+	va_list ap;
+
+	if (exit_code != 0)
+		RTE_LOG(CRIT, EAL, "Error - exiting with code: %d\n  Cause: ", exit_code);
+
+	va_start(ap, format);
+	rte_vlog(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, format, ap);
+	va_end(ap);
+
+#ifndef RTE_EAL_ALWAYS_PANIC_ON_ERROR
+	exit(exit_code);
+#else
+	rte_dump_stack();
+	rte_dump_registers();
+	abort();
+#endif
+}
diff --git a/lib/librte_eal/windows/eal/eal_fbarray.c b/lib/librte_eal/windows/eal/eal_fbarray.c
new file mode 100644
index 000000000..8e3932b3f
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal_fbarray.c
@@ -0,0 +1,1273 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017-2018 Intel Corporation
+ */
+
+#include <inttypes.h>
+#include <limits.h>
+#include <assert.h>
+#include <sys/mman.h>
+#include <stdint.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include <rte_common.h>
+#include <rte_log.h>
+#include <rte_errno.h>
+#include <rte_spinlock.h>
+#include <rte_tailq.h>
+
+#include "eal_filesystem.h"
+#include "eal_private.h"
+
+#include "rte_fbarray.h"
+
+#define MASK_SHIFT 6ULL
+#define MASK_ALIGN (1ULL << MASK_SHIFT)
+#define MASK_LEN_TO_IDX(x) ((x) >> MASK_SHIFT)
+#define MASK_LEN_TO_MOD(x) ((x) - RTE_ALIGN_FLOOR(x, MASK_ALIGN))
+#define MASK_GET_IDX(idx, mod) ((idx << MASK_SHIFT) + mod)
+
+/*
+ * This is a mask that is always stored at the end of array, to provide fast
+ * way of finding free/used spots without looping through each element.
+ */
+
+struct used_mask {
+	unsigned int n_masks;
+	uint64_t data[];
+};
+
+static size_t
+calc_mask_size(unsigned int len)
+{
+	/* mask must be multiple of MASK_ALIGN, even though length of array
+	 * itself may not be aligned on that boundary.
+	 */
+	len = RTE_ALIGN_CEIL(len, MASK_ALIGN);
+	return sizeof(struct used_mask) +
+			sizeof(uint64_t) * MASK_LEN_TO_IDX(len);
+}
+
+static size_t
+calc_data_size(size_t page_sz, unsigned int elt_sz, unsigned int len)
+{
+	size_t data_sz = elt_sz * len;
+	size_t msk_sz = calc_mask_size(len);
+	return RTE_ALIGN_CEIL(data_sz + msk_sz, page_sz);
+}
+
+static struct used_mask *
+get_used_mask(void *data, unsigned int elt_sz, unsigned int len)
+{
+	return (struct used_mask *) RTE_PTR_ADD(data, elt_sz * len);
+}
+
+static void *
+resize_and_map(int fd, size_t len)
+{
+	// Map the file to the process virtual space and return the address
+	void *addr = mmap(NULL, len, PROT_READ | PROT_WRITE,
+			MAP_SHARED, fd, 0);
+	if (addr == MAP_FAILED) {
+		RTE_LOG(ERR, EAL, "mmap() failed: %s\n", strerror(errno));
+		/* pass errno up the chain */
+		rte_errno = errno;
+		return NULL;
+	}
+
+	return addr;
+}
+
+static int
+find_next_n(const struct rte_fbarray *arr, unsigned int start, unsigned int n,
+	    bool used)
+{
+	const struct used_mask *msk = get_used_mask(arr->data, arr->elt_sz,
+			arr->len);
+	unsigned int msk_idx, lookahead_idx, first, first_mod;
+	unsigned int last, last_mod;
+	uint64_t last_msk, ignore_msk;
+
+	/*
+	 * mask only has granularity of MASK_ALIGN, but start may not be aligned
+	 * on that boundary, so construct a special mask to exclude anything we
+	 * don't want to see to avoid confusing ctz.
+	 */
+	first = MASK_LEN_TO_IDX(start);
+	first_mod = MASK_LEN_TO_MOD(start);
+	ignore_msk = ~((1ULL << first_mod) - 1);
+
+	/* array length may not be aligned, so calculate ignore mask for last
+	 * mask index.
+	 */
+	last = MASK_LEN_TO_IDX(arr->len);
+	last_mod = MASK_LEN_TO_MOD(arr->len);
+	last_msk = ~(-1ULL << last_mod);
+
+	for (msk_idx = first; msk_idx < msk->n_masks; msk_idx++) {
+		uint64_t cur_msk, lookahead_msk;
+		unsigned int run_start, clz, left;
+		bool found = false;
+		/*
+		 * The process of getting n consecutive bits for arbitrary n is
+		 * a bit involved, but here it is in a nutshell:
+		 *
+		 *  1. let n be the number of consecutive bits we're looking for
+		 *  2. check if n can fit in one mask, and if so, do n-1
+		 *     rshift-ands to see if there is an appropriate run inside
+		 *     our current mask
+		 *    2a. if we found a run, bail out early
+		 *    2b. if we didn't find a run, proceed
+		 *  3. invert the mask and count leading zeroes (that is, count
+		 *     how many consecutive set bits we had starting from the
+		 *     end of current mask) as k
+		 *    3a. if k is 0, continue to next mask
+		 *    3b. if k is not 0, we have a potential run
+		 *  4. to satisfy our requirements, next mask must have n-k
+		 *     consecutive set bits right at the start, so we will do
+		 *     (n-k-1) rshift-ands and check if first bit is set.
+		 *
+		 * Step 4 will need to be repeated if (n-k) > MASK_ALIGN until
+		 * we either run out of masks, lose the run, or find what we
+		 * were looking for.
+		 */
+		cur_msk = msk->data[msk_idx];
+		left = n;
+
+		/* if we're looking for free spaces, invert the mask */
+		if (!used)
+			cur_msk = ~cur_msk;
+
+		/* combine current ignore mask with last index ignore mask */
+		if (msk_idx == last)
+			ignore_msk |= last_msk;
+
+		/* if we have an ignore mask, ignore once */
+		if (ignore_msk) {
+			cur_msk &= ignore_msk;
+			ignore_msk = 0;
+		}
+
+		/* if n can fit in within a single mask, do a search */
+		if (n <= MASK_ALIGN) {
+			uint64_t tmp_msk = cur_msk;
+			unsigned int s_idx;
+			for (s_idx = 0; s_idx < n - 1; s_idx++)
+				tmp_msk &= tmp_msk >> 1ULL;
+			/* we found what we were looking for */
+			if (tmp_msk != 0) {
+				run_start = __builtin_ctzll(tmp_msk);
+				return MASK_GET_IDX(msk_idx, run_start);
+			}
+		}
+
+		/*
+		 * we didn't find our run within the mask, or n > MASK_ALIGN,
+		 * so we're going for plan B.
+		 */
+
+		/* count leading zeroes on inverted mask */
+		if (~cur_msk == 0)
+			clz = sizeof(cur_msk) * 8;
+		else
+			clz = __builtin_clzll(~cur_msk);
+
+		/* if there aren't any runs at the end either, just continue */
+		if (clz == 0)
+			continue;
+
+		/* we have a partial run at the end, so try looking ahead */
+		run_start = MASK_ALIGN - clz;
+		left -= clz;
+
+		for (lookahead_idx = msk_idx + 1; lookahead_idx < msk->n_masks;
+				lookahead_idx++) {
+			unsigned int s_idx, need;
+			lookahead_msk = msk->data[lookahead_idx];
+
+			/* if we're looking for free space, invert the mask */
+			if (!used)
+				lookahead_msk = ~lookahead_msk;
+
+			/* figure out how many consecutive bits we need here */
+			need = RTE_MIN(left, MASK_ALIGN);
+
+			for (s_idx = 0; s_idx < need - 1; s_idx++)
+				lookahead_msk &= lookahead_msk >> 1ULL;
+
+			/* if first bit is not set, we've lost the run */
+			if ((lookahead_msk & 1) == 0) {
+				/*
+				 * we've scanned this far, so we know there are
+				 * no runs in the space we've lookahead-scanned
+				 * as well, so skip that on next iteration.
+				 */
+				ignore_msk = ~((1ULL << need) - 1);
+				msk_idx = lookahead_idx;
+				break;
+			}
+
+			left -= need;
+
+			/* check if we've found what we were looking for */
+			if (left == 0) {
+				found = true;
+				break;
+			}
+		}
+
+		/* we didn't find anything, so continue */
+		if (!found)
+			continue;
+
+		return MASK_GET_IDX(msk_idx, run_start);
+	}
+	/* we didn't find anything */
+	rte_errno = used ? ENOENT : ENOSPC;
+	return -1;
+}
+
+static int
+find_next(const struct rte_fbarray *arr, unsigned int start, bool used)
+{
+	const struct used_mask *msk = get_used_mask(arr->data, arr->elt_sz,
+			arr->len);
+	unsigned int idx, first, first_mod;
+	unsigned int last, last_mod;
+	uint64_t last_msk, ignore_msk;
+
+	/*
+	 * mask only has granularity of MASK_ALIGN, but start may not be aligned
+	 * on that boundary, so construct a special mask to exclude anything we
+	 * don't want to see to avoid confusing ctz.
+	 */
+	first = MASK_LEN_TO_IDX(start);
+	first_mod = MASK_LEN_TO_MOD(start);
+	ignore_msk = ~((1ULL << first_mod) - 1ULL);
+
+	/* array length may not be aligned, so calculate ignore mask for last
+	 * mask index.
+	 */
+	last = MASK_LEN_TO_IDX(arr->len);
+	last_mod = MASK_LEN_TO_MOD(arr->len);
+	last_msk = ~(-(1ULL) << last_mod);
+
+	for (idx = first; idx < msk->n_masks; idx++) {
+		uint64_t cur = msk->data[idx];
+		int found;
+
+		/* if we're looking for free entries, invert mask */
+		if (!used)
+			cur = ~cur;
+
+		if (idx == last)
+			cur &= last_msk;
+
+		/* ignore everything before start on first iteration */
+		if (idx == first)
+			cur &= ignore_msk;
+
+		/* check if we have any entries */
+		if (cur == 0)
+			continue;
+
+		/*
+		 * find first set bit - that will correspond to whatever it is
+		 * that we're looking for.
+		 */
+		found = __builtin_ctzll(cur);
+		return MASK_GET_IDX(idx, found);
+	}
+	/* we didn't find anything */
+	rte_errno = used ? ENOENT : ENOSPC;
+	return -1;
+}
+
+static int
+find_contig(const struct rte_fbarray *arr, unsigned int start, bool used)
+{
+	const struct used_mask *msk = get_used_mask(arr->data, arr->elt_sz,
+			arr->len);
+	unsigned int idx, first, first_mod;
+	unsigned int last, last_mod;
+	uint64_t last_msk;
+	unsigned int need_len, result = 0;
+
+	/* array length may not be aligned, so calculate ignore mask for last
+	 * mask index.
+	 */
+	last = MASK_LEN_TO_IDX(arr->len);
+	last_mod = MASK_LEN_TO_MOD(arr->len);
+	last_msk = ~(-(1ULL) << last_mod);
+
+	first = MASK_LEN_TO_IDX(start);
+	first_mod = MASK_LEN_TO_MOD(start);
+	for (idx = first; idx < msk->n_masks; idx++, result += need_len) {
+		uint64_t cur = msk->data[idx];
+		unsigned int run_len;
+
+		need_len = MASK_ALIGN;
+
+		/* if we're looking for free entries, invert mask */
+		if (!used)
+			cur = ~cur;
+
+		/* if this is last mask, ignore everything after last bit */
+		if (idx == last)
+			cur &= last_msk;
+
+		/* ignore everything before start on first iteration */
+		if (idx == first) {
+			cur >>= first_mod;
+			/* at the start, we don't need the full mask len */
+			need_len -= first_mod;
+		}
+
+		/* we will be looking for zeroes, so invert the mask */
+		cur = ~cur;
+
+		/* if mask is zero, we have a complete run */
+		if (cur == 0)
+			continue;
+
+		/*
+		 * see if current run ends before mask end.
+		 */
+		run_len = __builtin_ctzll(cur);
+
+		/* add however many zeroes we've had in the last run and quit */
+		if (run_len < need_len) {
+			result += run_len;
+			break;
+		}
+	}
+	return result;
+}
+
+static int
+find_prev_n(const struct rte_fbarray *arr, unsigned int start, unsigned int n,
+		bool used)
+{
+	const struct used_mask *msk = get_used_mask(arr->data, arr->elt_sz,
+			arr->len);
+	unsigned int msk_idx, lookbehind_idx, first, first_mod;
+	uint64_t ignore_msk;
+
+	/*
+	 * mask only has granularity of MASK_ALIGN, but start may not be aligned
+	 * on that boundary, so construct a special mask to exclude anything we
+	 * don't want to see to avoid confusing ctz.
+	 */
+	first = MASK_LEN_TO_IDX(start);
+	first_mod = MASK_LEN_TO_MOD(start);
+	/* we're going backwards, so mask must start from the top */
+	ignore_msk = first_mod == MASK_ALIGN - 1 ?
+				-1ULL : /* prevent overflow */
+				~(-1ULL << (first_mod + 1));
+
+	/* go backwards, include zero */
+	msk_idx = first;
+	do {
+		uint64_t cur_msk, lookbehind_msk;
+		unsigned int run_start, run_end, ctz, left;
+		bool found = false;
+		/*
+		 * The process of getting n consecutive bits from the top for
+		 * arbitrary n is a bit involved, but here it is in a nutshell:
+		 *
+		 *  1. let n be the number of consecutive bits we're looking for
+		 *  2. check if n can fit in one mask, and if so, do n-1
+		 *     lshift-ands to see if there is an appropriate run inside
+		 *     our current mask
+		 *    2a. if we found a run, bail out early
+		 *    2b. if we didn't find a run, proceed
+		 *  3. invert the mask and count trailing zeroes (that is, count
+		 *     how many consecutive set bits we had starting from the
+		 *     start of current mask) as k
+		 *    3a. if k is 0, continue to next mask
+		 *    3b. if k is not 0, we have a potential run
+		 *  4. to satisfy our requirements, next mask must have n-k
+		 *     consecutive set bits at the end, so we will do (n-k-1)
+		 *     lshift-ands and check if last bit is set.
+		 *
+		 * Step 4 will need to be repeated if (n-k) > MASK_ALIGN until
+		 * we either run out of masks, lose the run, or find what we
+		 * were looking for.
+		 */
+		cur_msk = msk->data[msk_idx];
+		left = n;
+
+		/* if we're looking for free spaces, invert the mask */
+		if (!used)
+			cur_msk = ~cur_msk;
+
+		/* if we have an ignore mask, ignore once */
+		if (ignore_msk) {
+			cur_msk &= ignore_msk;
+			ignore_msk = 0;
+		}
+
+		/* if n can fit in within a single mask, do a search */
+		if (n <= MASK_ALIGN) {
+			uint64_t tmp_msk = cur_msk;
+			unsigned int s_idx;
+			for (s_idx = 0; s_idx < n - 1; s_idx++)
+				tmp_msk &= tmp_msk << 1ULL;
+			/* we found what we were looking for */
+			if (tmp_msk != 0) {
+				/* clz will give us offset from end of mask, and
+				 * we only get the end of our run, not start,
+				 * so adjust result to point to where start
+				 * would have been.
+				 */
+				run_start = MASK_ALIGN -
+						__builtin_clzll(tmp_msk) - n;
+				return MASK_GET_IDX(msk_idx, run_start);
+			}
+		}
+
+		/*
+		 * we didn't find our run within the mask, or n > MASK_ALIGN,
+		 * so we're going for plan B.
+		 */
+
+		/* count trailing zeroes on inverted mask */
+		if (~cur_msk == 0)
+			ctz = sizeof(cur_msk) * 8;
+		else
+			ctz = __builtin_ctzll(~cur_msk);
+
+		/* if there aren't any runs at the start either, just
+		 * continue
+		 */
+		if (ctz == 0)
+			continue;
+
+		/* we have a partial run at the start, so try looking behind */
+		run_end = MASK_GET_IDX(msk_idx, ctz);
+		left -= ctz;
+
+		/* go backwards, include zero */
+		lookbehind_idx = msk_idx - 1;
+
+		/* we can't lookbehind as we've run out of masks, so stop */
+		if (msk_idx == 0)
+			break;
+
+		do {
+			const uint64_t last_bit = 1ULL << (MASK_ALIGN - 1);
+			unsigned int s_idx, need;
+
+			lookbehind_msk = msk->data[lookbehind_idx];
+
+			/* if we're looking for free space, invert the mask */
+			if (!used)
+				lookbehind_msk = ~lookbehind_msk;
+
+			/* figure out how many consecutive bits we need here */
+			need = RTE_MIN(left, MASK_ALIGN);
+
+			for (s_idx = 0; s_idx < need - 1; s_idx++)
+				lookbehind_msk &= lookbehind_msk << 1ULL;
+
+			/* if last bit is not set, we've lost the run */
+			if ((lookbehind_msk & last_bit) == 0) {
+				/*
+				 * we've scanned this far, so we know there are
+				 * no runs in the space we've lookbehind-scanned
+				 * as well, so skip that on next iteration.
+				 */
+				ignore_msk = -1ULL << need;
+				msk_idx = lookbehind_idx;
+				break;
+			}
+
+			left -= need;
+
+			/* check if we've found what we were looking for */
+			if (left == 0) {
+				found = true;
+				break;
+			}
+		} while ((lookbehind_idx--) != 0); /* decrement after check to
+						    * include zero
+						    */
+
+		/* we didn't find anything, so continue */
+		if (!found)
+			continue;
+
+		/* we've found what we were looking for, but we only know where
+		 * the run ended, so calculate start position.
+		 */
+		return run_end - n;
+	} while (msk_idx-- != 0); /* decrement after check to include zero */
+	/* we didn't find anything */
+	rte_errno = used ? ENOENT : ENOSPC;
+	return -1;
+}
+
+static int
+find_prev(const struct rte_fbarray *arr, unsigned int start, bool used)
+{
+	const struct used_mask *msk = get_used_mask(arr->data, arr->elt_sz,
+			arr->len);
+	unsigned int idx, first, first_mod;
+	uint64_t ignore_msk;
+
+	/*
+	 * mask only has granularity of MASK_ALIGN, but start may not be aligned
+	 * on that boundary, so construct a special mask to exclude anything we
+	 * don't want to see to avoid confusing clz.
+	 */
+	first = MASK_LEN_TO_IDX(start);
+	first_mod = MASK_LEN_TO_MOD(start);
+	/* we're going backwards, so mask must start from the top */
+	ignore_msk = first_mod == MASK_ALIGN - 1 ?
+				-1ULL : /* prevent overflow */
+				~(-1ULL << (first_mod + 1));
+
+	/* go backwards, include zero */
+	idx = first;
+	do {
+		uint64_t cur = msk->data[idx];
+		int found;
+
+		/* if we're looking for free entries, invert mask */
+		if (!used)
+			cur = ~cur;
+
+		/* ignore everything before start on first iteration */
+		if (idx == first)
+			cur &= ignore_msk;
+
+		/* check if we have any entries */
+		if (cur == 0)
+			continue;
+
+		/*
+		 * find last set bit - that will correspond to whatever it is
+		 * that we're looking for. we're counting trailing zeroes, thus
+		 * the value we get is counted from end of mask, so calculate
+		 * position from start of mask.
+		 */
+		found = MASK_ALIGN - __builtin_clzll(cur) - 1;
+
+		return MASK_GET_IDX(idx, found);
+	} while (idx-- != 0); /* decrement after check  to include zero*/
+
+	/* we didn't find anything */
+	rte_errno = used ? ENOENT : ENOSPC;
+	return -1;
+}
+
+static int
+find_rev_contig(const struct rte_fbarray *arr, unsigned int start, bool used)
+{
+	const struct used_mask *msk = get_used_mask(arr->data, arr->elt_sz,
+			arr->len);
+	unsigned int idx, first, first_mod;
+	unsigned int need_len, result = 0;
+
+	first = MASK_LEN_TO_IDX(start);
+	first_mod = MASK_LEN_TO_MOD(start);
+
+	/* go backwards, include zero */
+	idx = first;
+	do {
+		uint64_t cur = msk->data[idx];
+		unsigned int run_len;
+
+		need_len = MASK_ALIGN;
+
+		/* if we're looking for free entries, invert mask */
+		if (!used)
+			cur = ~cur;
+
+		/* ignore everything after start on first iteration */
+		if (idx == first) {
+			unsigned int end_len = MASK_ALIGN - first_mod - 1;
+			cur <<= end_len;
+			/* at the start, we don't need the full mask len */
+			need_len -= end_len;
+		}
+
+		/* we will be looking for zeroes, so invert the mask */
+		cur = ~cur;
+
+		/* if mask is zero, we have a complete run */
+		if (cur == 0)
+			goto endloop;
+
+		/*
+		 * see where run ends, starting from the end.
+		 */
+		run_len = __builtin_clzll(cur);
+
+		/* add however many zeroes we've had in the last run and quit */
+		if (run_len < need_len) {
+			result += run_len;
+			break;
+		}
+endloop:
+		result += need_len;
+	} while (idx-- != 0); /* decrement after check to include zero */
+	return result;
+}
+
+static int
+set_used(struct rte_fbarray *arr, unsigned int idx, bool used)
+{
+	struct used_mask *msk;
+	uint64_t msk_bit = 1ULL << MASK_LEN_TO_MOD(idx);
+	unsigned int msk_idx = MASK_LEN_TO_IDX(idx);
+	bool already_used;
+	int ret = -1;
+
+	if (arr == NULL || idx >= arr->len) {
+		rte_errno = EINVAL;
+		return -1;
+	}
+	msk = get_used_mask(arr->data, arr->elt_sz, arr->len);
+	ret = 0;
+
+	/* prevent array from changing under us */
+	rte_rwlock_write_lock(&arr->rwlock);
+
+	already_used = (msk->data[msk_idx] & msk_bit) != 0;
+
+	/* nothing to be done */
+	if (used == already_used)
+		goto out;
+
+	if (used) {
+		msk->data[msk_idx] |= msk_bit;
+		arr->count++;
+	} else {
+		msk->data[msk_idx] &= ~msk_bit;
+		arr->count--;
+	}
+out:
+	rte_rwlock_write_unlock(&arr->rwlock);
+
+	return ret;
+}
+
+static int
+fully_validate(const char *name, unsigned int elt_sz, unsigned int len)
+{
+	if (name == NULL || elt_sz == 0 || len == 0 || len > INT_MAX) {
+		rte_errno = EINVAL;
+		return -1;
+	}
+
+	if (strnlen(name, RTE_FBARRAY_NAME_LEN) == RTE_FBARRAY_NAME_LEN) {
+		rte_errno = ENAMETOOLONG;
+		return -1;
+	}
+	return 0;
+}
+
+int __rte_experimental
+rte_fbarray_init(struct rte_fbarray *arr, const char *name, unsigned int len,
+		unsigned int elt_sz)
+{
+	size_t page_sz, mmap_len;
+	char path[PATH_MAX];
+	struct used_mask *msk;
+	void *data = NULL;
+	int fd = -1;
+	BOOL retval;
+	HANDLE hWinFileHandle;
+
+	if (arr == NULL) {
+		rte_errno = EINVAL;
+		return -1;
+	}
+
+	if (fully_validate(name, elt_sz, len))
+		return -1;
+
+	page_sz = sysconf(_SC_PAGESIZE);
+	if (page_sz == (size_t)-1)
+		goto fail;
+
+	/* calculate our memory limits */
+	mmap_len = calc_data_size(page_sz, elt_sz, len);
+
+	if (internal_config.no_shconf) {
+		/* remap virtual area as writable */
+		void *new_data = mmap(data, mmap_len, PROT_READ | PROT_WRITE,
+				MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+		if (new_data == MAP_FAILED) {
+			RTE_LOG(DEBUG, EAL, "%s(): couldn't remap anonymous memory: %s\n",
+					__func__, strerror(errno));
+			goto fail;
+		}
+	} else {
+		eal_get_fbarray_path(path, sizeof(path), name);
+
+		/*
+		 * Each fbarray is unique to process namespace, i.e. the
+		 * filename depends on process prefix. Try to take out a lock
+		 * and see if we succeed. If we don't, someone else is using it
+		 * already.
+		 */
+		fd = _open(path, O_CREAT | O_RDWR | _O_TRUNC, _S_IREAD | _S_IWRITE);
+		if (fd < 0) {
+			RTE_LOG(DEBUG, EAL, "%s(): couldn't open %s: %s\n",
+					__func__, path, strerror(errno));
+			rte_errno = errno;
+			goto fail;
+		}
+
+		/* Lock file for exclusive access */
+		OVERLAPPED sOverlapped = { 0 };
+		sOverlapped.Offset = 0;
+		sOverlapped.OffsetHigh = 0;
+
+		hWinFileHandle = (HANDLE)_get_osfhandle(fd);
+		retval = LockFileEx(hWinFileHandle,
+			LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, 0,
+			mmap_len, 0, &sOverlapped);
+		if (!retval) {
+			RTE_LOG(DEBUG, EAL, "%s(): couldn't lock %s: %s\n",
+				__func__, path, strerror(errno));
+			rte_errno = EBUSY;
+			goto fail;
+		}
+
+
+		/* take out a non-exclusive lock, so that other processes could
+		* still attach to it, but no other process could reinitialize
+		* it.
+		*/
+		retval = UnlockFileEx(hWinFileHandle, 0, mmap_len, 0, &sOverlapped);
+		if (!retval) {
+			RTE_LOG(DEBUG, EAL, "%s(): couldn't unlock %s: %s\n",
+				__func__, path, strerror(errno));
+			rte_errno = EBUSY;
+			goto fail;
+		}else {
+			retval = LockFileEx(hWinFileHandle,
+				LOCKFILE_FAIL_IMMEDIATELY, 0,
+				mmap_len, 0, &sOverlapped);
+			if(!retval){
+				rte_errno = errno;
+				goto fail;
+			}
+		}
+		data = resize_and_map(fd, mmap_len);
+		if (data == NULL)
+			goto fail;
+
+		/* we've mmap'ed the file, we can now close the fd */
+		_close(fd);
+	}
+
+	/* initialize the data */
+	memset(data, 0, mmap_len);
+
+	/* populate data structure */
+	strlcpy(arr->name, name, sizeof(arr->name));
+	arr->data = data;
+	arr->len = len;
+	arr->elt_sz = elt_sz;
+	arr->count = 0;
+
+	msk = get_used_mask(data, elt_sz, len);
+	msk->n_masks = MASK_LEN_TO_IDX(RTE_ALIGN_CEIL(len, MASK_ALIGN));
+
+	rte_rwlock_init(&arr->rwlock);
+
+	return 0;
+fail:
+	if (data)
+		munmap(data, mmap_len);
+	if (fd >= 0)
+		_close(fd);
+	return -1;
+}
+
+int __rte_experimental
+rte_fbarray_attach(struct rte_fbarray *arr)
+{
+	size_t page_sz, mmap_len;
+	char path[PATH_MAX];
+	void *data = NULL;
+	int fd = -1;
+	BOOL retval;
+
+	if (arr == NULL) {
+		rte_errno = EINVAL;
+		return -1;
+	}
+
+	/*
+	 * we don't need to synchronize attach as two values we need (element
+	 * size and array length) are constant for the duration of life of
+	 * the array, so the parts we care about will not race.
+	 */
+
+	if (fully_validate(arr->name, arr->elt_sz, arr->len))
+		return -1;
+
+	page_sz = sysconf(_SC_PAGESIZE);
+	if (page_sz == (size_t)-1)
+		goto fail;
+
+	mmap_len = calc_data_size(page_sz, arr->elt_sz, arr->len);
+
+	data = eal_get_virtual_area(arr->data, &mmap_len, page_sz, 0, 0);
+	if (data == NULL)
+		goto fail;
+
+	eal_get_fbarray_path(path, sizeof(path), arr->name);
+
+	fd = open(path, O_RDWR);
+	if (fd < 0) {
+		rte_errno = errno;
+		goto fail;
+	}
+
+	/* lock the file, to let others know we're using it */
+	/* Lock file for exclusive access */
+	OVERLAPPED sOverlapped = { 0 };
+	sOverlapped.Offset = 0;
+	sOverlapped.OffsetHigh = 0;
+
+	HANDLE hWinFileHandle = (HANDLE)_get_osfhandle(fd);
+	retval = LockFileEx(hWinFileHandle, LOCKFILE_FAIL_IMMEDIATELY, 0, mmap_len, 0, &sOverlapped);
+	if (!retval) {
+		rte_errno = errno;
+		goto fail;
+	}
+	data = resize_and_map(fd, mmap_len);
+	if (data == NULL)
+		goto fail;
+
+	close(fd);
+
+	/* we're done */
+
+	return 0;
+fail:
+	if (data)
+		munmap(data, mmap_len);
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+int __rte_experimental
+rte_fbarray_detach(struct rte_fbarray *arr)
+{
+	if (arr == NULL) {
+		rte_errno = EINVAL;
+		return -1;
+	}
+
+	/*
+	 * we don't need to synchronize detach as two values we need (element
+	 * size and total capacity) are constant for the duration of life of
+	 * the array, so the parts we care about will not race. if the user is
+	 * detaching while doing something else in the same process, we can't
+	 * really do anything about it, things will blow up either way.
+	 */
+
+	size_t page_sz = sysconf(_SC_PAGESIZE);
+
+	if (page_sz == (size_t)-1)
+		return -1;
+
+	/* this may already be unmapped (e.g. repeated call from previously
+	 * failed destroy(), but this is on user, we can't (easily) know if this
+	 * is still mapped.
+	 */
+	munmap(arr->data, calc_data_size(page_sz, arr->elt_sz, arr->len));
+
+	return 0;
+}
+
+int __rte_experimental
+rte_fbarray_destroy(struct rte_fbarray *arr)
+{
+	int fd, ret;
+	char path[PATH_MAX];
+	BOOL retval;
+
+	ret = rte_fbarray_detach(arr);
+	if (ret)
+		return ret;
+
+	/* try deleting the file */
+	eal_get_fbarray_path(path, sizeof(path), arr->name);
+
+	fd = open(path, O_RDONLY);
+	if (fd < 0) {
+		RTE_LOG(ERR, EAL, "Could not open fbarray file: %s\n",
+			strerror(errno));
+		return -1;
+	}
+
+	OVERLAPPED sOverLapped = { 0 };
+	sOverLapped.Offset = 0;
+	sOverLapped.OffsetHigh = 0;
+
+	HANDLE hWinFileHandle = (HANDLE)_get_osfhandle(fd);
+
+	retval = LockFileEx(hWinFileHandle, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, 0, sizeof(*arr), 0, &sOverLapped);
+
+	if (!retval) {
+		RTE_LOG(DEBUG, EAL, "Cannot destroy fbarray - another process is using it\n");
+		rte_errno = EBUSY;
+		ret = -1;
+	} else {
+		ret = 0;
+		unlink(path);
+		memset(arr, 0, sizeof(*arr));
+	}
+	close(fd);
+
+	return ret;
+}
+
+void * __rte_experimental
+rte_fbarray_get(const struct rte_fbarray *arr, unsigned int idx)
+{
+	void *ret = NULL;
+	if (arr == NULL) {
+		rte_errno = EINVAL;
+		return NULL;
+	}
+
+	if (idx >= arr->len) {
+		rte_errno = EINVAL;
+		return NULL;
+	}
+
+	ret = RTE_PTR_ADD(arr->data, idx * arr->elt_sz);
+
+	return ret;
+}
+
+int __rte_experimental
+rte_fbarray_set_used(struct rte_fbarray *arr, unsigned int idx)
+{
+	return set_used(arr, idx, true);
+}
+
+int __rte_experimental
+rte_fbarray_set_free(struct rte_fbarray *arr, unsigned int idx)
+{
+	return set_used(arr, idx, false);
+}
+
+int __rte_experimental
+rte_fbarray_is_used(struct rte_fbarray *arr, unsigned int idx)
+{
+	struct used_mask *msk;
+	int msk_idx;
+	uint64_t msk_bit;
+	int ret = -1;
+
+	if (arr == NULL || idx >= arr->len) {
+		rte_errno = EINVAL;
+		return -1;
+	}
+
+	/* prevent array from changing under us */
+	rte_rwlock_read_lock(&arr->rwlock);
+
+	msk = get_used_mask(arr->data, arr->elt_sz, arr->len);
+	msk_idx = MASK_LEN_TO_IDX(idx);
+	msk_bit = 1ULL << MASK_LEN_TO_MOD(idx);
+
+	ret = (msk->data[msk_idx] & msk_bit) != 0;
+
+	rte_rwlock_read_unlock(&arr->rwlock);
+
+	return ret;
+}
+
+static int
+fbarray_find(struct rte_fbarray *arr, unsigned int start, bool next, bool used)
+{
+	int ret = -1;
+
+	if (arr == NULL || start >= arr->len) {
+		rte_errno = EINVAL;
+		return -1;
+	}
+
+	/* prevent array from changing under us */
+	rte_rwlock_read_lock(&arr->rwlock);
+
+	/* cheap checks to prevent doing useless work */
+	if (!used) {
+		if (arr->len == arr->count) {
+			rte_errno = ENOSPC;
+			goto out;
+		}
+		if (arr->count == 0) {
+			ret = start;
+			goto out;
+		}
+	} else {
+		if (arr->count == 0) {
+			rte_errno = ENOENT;
+			goto out;
+		}
+		if (arr->len == arr->count) {
+			ret = start;
+			goto out;
+		}
+	}
+	if (next)
+		ret = find_next(arr, start, used);
+	else
+		ret = find_prev(arr, start, used);
+out:
+	rte_rwlock_read_unlock(&arr->rwlock);
+	return ret;
+}
+
+int __rte_experimental
+rte_fbarray_find_next_free(struct rte_fbarray *arr, unsigned int start)
+{
+	return fbarray_find(arr, start, true, false);
+}
+
+int __rte_experimental
+rte_fbarray_find_next_used(struct rte_fbarray *arr, unsigned int start)
+{
+	return fbarray_find(arr, start, true, true);
+}
+
+int __rte_experimental
+rte_fbarray_find_prev_free(struct rte_fbarray *arr, unsigned int start)
+{
+	return fbarray_find(arr, start, false, false);
+}
+
+int __rte_experimental
+rte_fbarray_find_prev_used(struct rte_fbarray *arr, unsigned int start)
+{
+	return fbarray_find(arr, start, false, true);
+}
+
+static int
+fbarray_find_n(struct rte_fbarray *arr, unsigned int start, unsigned int n,
+		bool next, bool used)
+{
+	int ret = -1;
+
+	if (arr == NULL || start >= arr->len || n > arr->len || n == 0) {
+		rte_errno = EINVAL;
+		return -1;
+	}
+	if (next && (arr->len - start) < n) {
+		rte_errno = used ? ENOENT : ENOSPC;
+		return -1;
+	}
+	if (!next && start < (n - 1)) {
+		rte_errno = used ? ENOENT : ENOSPC;
+		return -1;
+	}
+
+	/* prevent array from changing under us */
+	rte_rwlock_read_lock(&arr->rwlock);
+
+	/* cheap checks to prevent doing useless work */
+	if (!used) {
+		if (arr->len == arr->count || arr->len - arr->count < n) {
+			rte_errno = ENOSPC;
+			goto out;
+		}
+		if (arr->count == 0) {
+			ret = next ? start : start - n + 1;
+			goto out;
+		}
+	} else {
+		if (arr->count < n) {
+			rte_errno = ENOENT;
+			goto out;
+		}
+		if (arr->count == arr->len) {
+			ret = next ? start : start - n + 1;
+			goto out;
+		}
+	}
+
+	if (next)
+		ret = find_next_n(arr, start, n, used);
+	else
+		ret = find_prev_n(arr, start, n, used);
+out:
+	rte_rwlock_read_unlock(&arr->rwlock);
+	return ret;
+}
+
+int __rte_experimental
+rte_fbarray_find_next_n_free(struct rte_fbarray *arr, unsigned int start,
+		unsigned int n)
+{
+	return fbarray_find_n(arr, start, n, true, false);
+}
+
+int __rte_experimental
+rte_fbarray_find_next_n_used(struct rte_fbarray *arr, unsigned int start,
+		unsigned int n)
+{
+	return fbarray_find_n(arr, start, n, true, true);
+}
+
+int __rte_experimental
+rte_fbarray_find_prev_n_free(struct rte_fbarray *arr, unsigned int start,
+		unsigned int n)
+{
+	return fbarray_find_n(arr, start, n, false, false);
+}
+
+int __rte_experimental
+rte_fbarray_find_prev_n_used(struct rte_fbarray *arr, unsigned int start,
+		unsigned int n)
+{
+	return fbarray_find_n(arr, start, n, false, true);
+}
+
+static int
+fbarray_find_contig(struct rte_fbarray *arr, unsigned int start, bool next,
+		bool used)
+{
+	int ret = -1;
+
+	if (arr == NULL || start >= arr->len) {
+		rte_errno = EINVAL;
+		return -1;
+	}
+
+	/* prevent array from changing under us */
+	rte_rwlock_read_lock(&arr->rwlock);
+
+	/* cheap checks to prevent doing useless work */
+	if (used) {
+		if (arr->count == 0) {
+			ret = 0;
+			goto out;
+		}
+		if (next && arr->count == arr->len) {
+			ret = arr->len - start;
+			goto out;
+		}
+		if (!next && arr->count == arr->len) {
+			ret = start + 1;
+			goto out;
+		}
+	} else {
+		if (arr->len == arr->count) {
+			ret = 0;
+			goto out;
+		}
+		if (next && arr->count == 0) {
+			ret = arr->len - start;
+			goto out;
+		}
+		if (!next && arr->count == 0) {
+			ret = start + 1;
+			goto out;
+		}
+	}
+
+	if (next)
+		ret = find_contig(arr, start, used);
+	else
+		ret = find_rev_contig(arr, start, used);
+out:
+	rte_rwlock_read_unlock(&arr->rwlock);
+	return ret;
+}
+
+int __rte_experimental
+rte_fbarray_find_contig_free(struct rte_fbarray *arr, unsigned int start)
+{
+	return fbarray_find_contig(arr, start, true, false);
+}
+
+int __rte_experimental
+rte_fbarray_find_contig_used(struct rte_fbarray *arr, unsigned int start)
+{
+	return fbarray_find_contig(arr, start, true, true);
+}
+
+int __rte_experimental
+rte_fbarray_find_rev_contig_free(struct rte_fbarray *arr, unsigned int start)
+{
+	return fbarray_find_contig(arr, start, false, false);
+}
+
+int __rte_experimental
+rte_fbarray_find_rev_contig_used(struct rte_fbarray *arr, unsigned int start)
+{
+	return fbarray_find_contig(arr, start, false, true);
+}
+
+int __rte_experimental
+rte_fbarray_find_idx(const struct rte_fbarray *arr, const void *elt)
+{
+	void *end;
+	int ret = -1;
+
+	/*
+	 * no need to synchronize as it doesn't matter if underlying data
+	 * changes - we're doing pointer arithmetic here.
+	 */
+
+	if (arr == NULL || elt == NULL) {
+		rte_errno = EINVAL;
+		return -1;
+	}
+	end = RTE_PTR_ADD(arr->data, arr->elt_sz * arr->len);
+	if (elt < arr->data || elt >= end) {
+		rte_errno = EINVAL;
+		return -1;
+	}
+
+	ret = RTE_PTR_DIFF(elt, arr->data) / arr->elt_sz;
+
+	return ret;
+}
+
+void __rte_experimental
+rte_fbarray_dump_metadata(struct rte_fbarray *arr, FILE *f)
+{
+	struct used_mask *msk;
+	unsigned int i;
+
+	if (arr == NULL || f == NULL) {
+		rte_errno = EINVAL;
+		return;
+	}
+
+	if (fully_validate(arr->name, arr->elt_sz, arr->len)) {
+		fprintf(f, "Invalid file-backed array\n");
+		goto out;
+	}
+
+	/* prevent array from changing under us */
+	rte_rwlock_read_lock(&arr->rwlock);
+
+	fprintf(f, "File-backed array: %s\n", arr->name);
+	fprintf(f, "size: %i occupied: %i elt_sz: %i\n",
+			arr->len, arr->count, arr->elt_sz);
+
+	msk = get_used_mask(arr->data, arr->elt_sz, arr->len);
+
+	for (i = 0; i < msk->n_masks; i++)
+		fprintf(f, "msk idx %i: 0x%016" PRIx64 "\n", i, msk->data[i]);
+out:
+	rte_rwlock_read_unlock(&arr->rwlock);
+}
diff --git a/lib/librte_eal/windows/eal/eal_filesystem.h b/lib/librte_eal/windows/eal/eal_filesystem.h
new file mode 100644
index 000000000..2bfb8b9a1
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal_filesystem.h
@@ -0,0 +1,97 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+/**
+ * @file
+ * Stores functions and path defines for files and directories
+ * on the filesystem for Windows, that are used by the Windows EAL.
+ */
+
+#ifndef EAL_FILESYSTEM_H
+#define EAL_FILESYSTEM_H
+
+#include <rte_windows.h>
+#include "eal_internal_cfg.h"
+
+
+ /* sets up platform-specific runtime data dir */
+int
+eal_create_runtime_dir(void);
+
+/* returns runtime dir */
+const char *
+eal_get_runtime_dir(void);
+
+ /* define the default filename prefix for the %s values below */
+#define HUGEFILE_PREFIX_DEFAULT "rte"
+
+/* Path of rte config file */
+#define RUNTIME_CONFIG_FMT "%s\\%s.config"
+
+static inline const char *
+eal_runtime_config_path(void)
+{
+	static char buffer[PATH_MAX];  /* static so auto-zeroed */
+	char  Directory[PATH_MAX];
+
+	GetTempPathA(sizeof(Directory), Directory);
+	snprintf(buffer, sizeof(buffer)-1, RUNTIME_CONFIG_FMT, Directory, internal_config.hugefile_prefix);
+
+	return buffer;
+}
+
+/* Path of file backed array*/
+#define FBARRAY_NAME_FMT "%s\\fbarray_%s"
+
+static inline const char *
+eal_get_fbarray_path(char *buffer, size_t buflen, const char *name) {
+	snprintf(buffer, buflen, FBARRAY_NAME_FMT, eal_get_runtime_dir(), name);
+	return buffer;
+}
+
+/** Path of primary/secondary communication unix socket file. */
+#define MP_SOCKET_FNAME "mp_socket"
+
+static inline const char *
+eal_mp_socket_path(void)
+{
+	static char buffer[PATH_MAX]; /* static so auto-zeroed */
+
+	snprintf(buffer, sizeof(buffer) - 1, "%s/%s", eal_get_runtime_dir(),
+		MP_SOCKET_FNAME);
+	return buffer;
+}
+
+/* Path of hugepage info file */
+#define HUGEPAGE_INFO_FMT "%s\\.%s_hugepage_info"
+
+static inline const char *
+eal_hugepage_info_path(void)
+{
+	static char buffer[PATH_MAX];  /* static so auto-zeroed */
+	TCHAR  Directory[PATH_MAX];
+
+	GetSystemDirectory(Directory, sizeof(Directory));
+	snprintf(buffer, sizeof(buffer)-1, HUGEPAGE_INFO_FMT, Directory, internal_config.hugefile_prefix);
+	return buffer;
+}
+
+/* String format for hugepage map files */
+#define HUGEFILE_FMT "%s/%smap_%d"
+#define TEMP_HUGEFILE_FMT "%s/%smap_temp_%d"
+
+static inline const char *
+eal_get_hugefile_path(char *buffer, size_t buflen, const char *hugedir, int f_id)
+{
+	snprintf(buffer, buflen, HUGEFILE_FMT, hugedir, internal_config.hugefile_prefix, f_id);
+	buffer[buflen - 1] = '\0';
+	return buffer;
+}
+
+
+/** Function to read a single numeric value from a file on the filesystem.
+ * Used to read information from files on /sys */
+int eal_parse_sysfs_value(const char *filename, unsigned long *val);
+
+#endif /* EAL_FILESYSTEM_H */
diff --git a/lib/librte_eal/windows/eal/eal_hugepage_info.c b/lib/librte_eal/windows/eal/eal_hugepage_info.c
new file mode 100644
index 000000000..d417da6da
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal_hugepage_info.c
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#include <rte_log.h>
+#include "eal_internal_cfg.h"
+#include "eal_hugepages.h"
+
+
+/*
+ * Need to complete hugepage support on Windows
+ */
+int
+eal_hugepage_info_init(void)
+{
+	internal_config.num_hugepage_sizes = 1;
+	internal_config.hugepage_info[0].hugepage_sz = (uint64_t)GetLargePageMinimum();
+
+	return 0;
+}
diff --git a/lib/librte_eal/windows/eal/eal_interrupts.c b/lib/librte_eal/windows/eal/eal_interrupts.c
new file mode 100644
index 000000000..6be47d14e
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal_interrupts.c
@@ -0,0 +1,90 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#include <rte_common.h>
+#include <rte_interrupts.h>
+#include "eal_private.h"
+
+int
+rte_intr_callback_register(const struct rte_intr_handle *intr_handle,
+				rte_intr_callback_fn cb,
+				void *cb_arg)
+{
+	return -ENOTSUP;
+}
+
+int
+rte_intr_callback_unregister(const struct rte_intr_handle *intr_handle,
+				rte_intr_callback_fn cb_fn,
+				void *cb_arg)
+{
+	return -ENOTSUP;
+}
+
+int
+rte_intr_enable(const struct rte_intr_handle *intr_handle)
+{
+	return -ENOTSUP;
+}
+
+int
+rte_intr_disable(const struct rte_intr_handle *intr_handle)
+{
+	return -ENOTSUP;
+}
+
+int
+rte_eal_intr_init(void)
+{
+	return 0;
+}
+
+int
+rte_intr_rx_ctl(struct rte_intr_handle *intr_handle,
+		int epfd, int op, unsigned int vec, void *data)
+{
+	RTE_SET_USED(intr_handle);
+	RTE_SET_USED(epfd);
+	RTE_SET_USED(op);
+	RTE_SET_USED(vec);
+	RTE_SET_USED(data);
+
+	return -ENOTSUP;
+}
+
+int
+rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd)
+{
+	RTE_SET_USED(intr_handle);
+	RTE_SET_USED(nb_efd);
+
+	return 0;
+}
+
+void
+rte_intr_efd_disable(struct rte_intr_handle *intr_handle)
+{
+	RTE_SET_USED(intr_handle);
+}
+
+int
+rte_intr_dp_is_en(struct rte_intr_handle *intr_handle)
+{
+	RTE_SET_USED(intr_handle);
+	return 0;
+}
+
+int
+rte_intr_allow_others(struct rte_intr_handle *intr_handle)
+{
+	RTE_SET_USED(intr_handle);
+	return 1;
+}
+
+int
+rte_intr_cap_multiple(struct rte_intr_handle *intr_handle)
+{
+	RTE_SET_USED(intr_handle);
+	return 0;
+}
diff --git a/lib/librte_eal/windows/eal/eal_lcore.c b/lib/librte_eal/windows/eal/eal_lcore.c
new file mode 100644
index 000000000..e8222e896
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal_lcore.c
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#include <rte_windows.h>
+
+/* global data structure that contains the CPU map */
+static struct _win_cpu_map {
+	unsigned numTotalProcessors;
+	unsigned numProcessorSockets;
+	unsigned numProcessorCores;
+	unsigned reserved;
+	struct _win_lcore_map {
+		uint8_t    socketid;
+		uint8_t    coreid;
+	} win_lcore_map[RTE_MAX_LCORE];
+} win_cpu_map = { 0 };
+
+
+void eal_create_cpu_map()
+{
+	win_cpu_map.numTotalProcessors = GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
+
+	LOGICAL_PROCESSOR_RELATIONSHIP lprocRel;
+	DWORD  lprocInfoSize = 0;
+	BOOL bHyperThreadingEnabled = FALSE;
+
+	/* First get the processor package information */
+	lprocRel = RelationProcessorPackage;
+	/* Determine the size of buffer we need (pass NULL) */
+	GetLogicalProcessorInformationEx(lprocRel, NULL, &lprocInfoSize);
+	win_cpu_map.numProcessorSockets = lprocInfoSize / 48;
+
+	lprocInfoSize = 0;
+	/* Next get the processor core information */
+	lprocRel = RelationProcessorCore;
+	GetLogicalProcessorInformationEx(lprocRel, NULL, &lprocInfoSize);
+	win_cpu_map.numProcessorCores = lprocInfoSize / 48;
+
+	if (win_cpu_map.numTotalProcessors > win_cpu_map.numProcessorCores)
+	    bHyperThreadingEnabled = TRUE;
+
+	/* Distribute the socket and core ids appropriately across the logical cores */
+	/* For now, split the cores equally across the sockets - might need to revisit this later */
+	unsigned lcore = 0;
+	for (unsigned socket=0; socket < win_cpu_map.numProcessorSockets; ++socket) {
+	    for (unsigned core = 0; core < (win_cpu_map.numProcessorCores / win_cpu_map.numProcessorSockets); ++core) {
+		win_cpu_map.win_lcore_map[lcore].socketid = socket;
+		win_cpu_map.win_lcore_map[lcore].coreid = core;
+
+		lcore++;
+
+		if (bHyperThreadingEnabled) {
+		    win_cpu_map.win_lcore_map[lcore].socketid = socket;
+		    win_cpu_map.win_lcore_map[lcore].coreid = core;
+		    lcore++;
+		}
+	    }
+	}
+
+	return;
+}
+
+/* Check if a cpu is present by the presence of the cpu information for it */
+int
+eal_cpu_detected(unsigned lcore_id)
+{
+	return (lcore_id < win_cpu_map.numTotalProcessors);
+}
+
+/* Get CPU socket id (NUMA node) for a logical core */
+unsigned
+eal_cpu_socket_id(unsigned lcore_id)
+{
+	return win_cpu_map.win_lcore_map[lcore_id].socketid;
+}
+
+/* Get the cpu core id value */
+unsigned
+eal_cpu_core_id(unsigned lcore_id)
+{
+	return win_cpu_map.win_lcore_map[lcore_id].coreid;
+}
diff --git a/lib/librte_eal/windows/eal/eal_log.c b/lib/librte_eal/windows/eal/eal_log.c
new file mode 100644
index 000000000..0f5ae54a9
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal_log.c
@@ -0,0 +1,415 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <rte_eal.h>
+#include <rte_log.h>
+#include <rte_per_lcore.h>
+
+#include "eal_private.h"
+
+/* global log structure */
+struct rte_logs rte_logs = {
+	.type = ~0,
+	.level = RTE_LOG_DEBUG,
+	.file = NULL,
+};
+
+struct rte_eal_opt_loglevel {
+	/** Next list entry */
+	TAILQ_ENTRY(rte_eal_opt_loglevel) next;
+	char *pattern;
+	/** Log level value obtained from the option */
+	uint32_t level;
+};
+
+TAILQ_HEAD(rte_eal_opt_loglevel_list, rte_eal_opt_loglevel);
+
+/** List of valid EAL log level options */
+static struct rte_eal_opt_loglevel_list opt_loglevel_list =
+TAILQ_HEAD_INITIALIZER(opt_loglevel_list);
+
+/* Stream to use for logging if rte_logs.file is NULL */
+static FILE *default_log_stream;
+
+/**
+* This global structure stores some informations about the message
+* that is currently being processed by one lcore
+*/
+struct log_cur_msg {
+	uint32_t loglevel; /**< log level - see rte_log.h */
+	uint32_t logtype;  /**< log type  - see rte_log.h */
+};
+
+struct rte_log_dynamic_type {
+	const char *name;
+	uint32_t loglevel;
+};
+
+/* per core log */
+static RTE_DEFINE_PER_LCORE(struct log_cur_msg, log_cur_msg);
+
+/* default logs */
+
+/* Change the stream that will be used by logging system */
+int
+rte_openlog_stream(FILE *f)
+{
+	rte_logs.file = f;
+	return 0;
+}
+
+/* Set global log level */
+void
+rte_log_set_global_level(uint32_t level)
+{
+	rte_logs.level = (uint32_t)level;
+}
+
+/* Get global log level */
+uint32_t
+rte_log_get_global_level(void)
+{
+	return rte_logs.level;
+}
+
+int
+rte_log_get_level(uint32_t type)
+{
+	if (type >= rte_logs.dynamic_types_len)
+		return -1;
+
+	return rte_logs.dynamic_types[type].loglevel;
+}
+
+int
+rte_log_set_level(uint32_t type, uint32_t level)
+{
+	if (type >= rte_logs.dynamic_types_len)
+		return -1;
+	if (level > RTE_LOG_DEBUG)
+		return -1;
+
+	rte_logs.dynamic_types[type].loglevel = level;
+
+	return 0;
+}
+
+/* set log level by regular expression */
+int
+rte_log_set_level_regexp(const char *regex, uint32_t level)
+{
+	/* Not implemented in Windows */
+	return 0;
+}
+
+/*
+* Save the type string and the loglevel for later dynamic
+* logtypes which may register later.
+*/
+static int rte_log_save_level(int priority,
+	const char *regex, const char *pattern)
+{
+	/* Not implemented in Windows */
+	return 0;
+}
+
+int rte_log_save_regexp(const char *regex, int tmp)
+{
+	return rte_log_save_level(tmp, regex, NULL);
+}
+
+/* set log level based on glob (file match) pattern */
+int
+rte_log_set_level_pattern(const char *pattern, uint32_t level)
+{
+	size_t i;
+
+	if (level > RTE_LOG_DEBUG)
+		return -1;
+
+	for (i = 0; i < rte_logs.dynamic_types_len; i++) {
+		if (rte_logs.dynamic_types[i].name == NULL)
+			continue;
+	}
+
+	return 0;
+}
+
+int rte_log_save_pattern(const char *pattern, int priority)
+{
+	return rte_log_save_level(priority, NULL, pattern);
+}
+
+/* get the current loglevel for the message being processed */
+int rte_log_cur_msg_loglevel(void)
+{
+	return RTE_PER_LCORE(log_cur_msg).loglevel;
+}
+
+/* get the current logtype for the message being processed */
+int rte_log_cur_msg_logtype(void)
+{
+	return RTE_PER_LCORE(log_cur_msg).logtype;
+}
+
+static int
+rte_log_lookup(const char *name)
+{
+	size_t i;
+
+	for (i = 0; i < rte_logs.dynamic_types_len; i++) {
+		if (rte_logs.dynamic_types[i].name == NULL)
+			continue;
+		if (strcmp(name, rte_logs.dynamic_types[i].name) == 0)
+			return i;
+	}
+
+	return -1;
+}
+
+/* register an extended log type, assuming table is large enough, and id
+* is not yet registered.
+*/
+static int
+__rte_log_register(const char *name, int id)
+{
+	char *dup_name = strdup(name);
+
+	if (dup_name == NULL)
+		return -ENOMEM;
+
+	rte_logs.dynamic_types[id].name = dup_name;
+	rte_logs.dynamic_types[id].loglevel = RTE_LOG_DEBUG/*RTE_LOG_INFO*/;
+
+	return id;
+}
+
+/* register an extended log type */
+int
+rte_log_register(const char *name)
+{
+	struct rte_log_dynamic_type *new_dynamic_types;
+	int id, ret;
+
+	id = rte_log_lookup(name);
+	if (id >= 0)
+		return id;
+
+	new_dynamic_types = realloc(rte_logs.dynamic_types,
+		sizeof(struct rte_log_dynamic_type) *
+		(rte_logs.dynamic_types_len + 1));
+	if (new_dynamic_types == NULL)
+		return -ENOMEM;
+	rte_logs.dynamic_types = new_dynamic_types;
+
+	ret = __rte_log_register(name, rte_logs.dynamic_types_len);
+	if (ret < 0)
+		return ret;
+
+	rte_logs.dynamic_types_len++;
+
+	return ret;
+}
+
+/* Register an extended log type and try to pick its level from EAL options */
+int __rte_experimental
+rte_log_register_type_and_pick_level(const char *name, uint32_t level_def)
+{
+	struct rte_eal_opt_loglevel *opt_ll;
+	uint32_t level = level_def;
+	int type;
+
+	type = rte_log_register(name);
+	if (type < 0)
+		return type;
+
+	TAILQ_FOREACH(opt_ll, &opt_loglevel_list, next) {
+		if (opt_ll->level > RTE_LOG_DEBUG)
+			continue;
+	}
+	rte_logs.dynamic_types[type].loglevel = level;
+
+	return type;
+}
+
+struct logtype {
+	uint32_t log_id;
+	const char *logtype;
+};
+
+static const struct logtype logtype_strings[] = {
+	{ RTE_LOGTYPE_EAL,        "lib.eal" },
+{ RTE_LOGTYPE_MALLOC,     "lib.malloc" },
+{ RTE_LOGTYPE_RING,       "lib.ring" },
+{ RTE_LOGTYPE_MEMPOOL,    "lib.mempool" },
+{ RTE_LOGTYPE_TIMER,      "lib.timer" },
+{ RTE_LOGTYPE_PMD,        "pmd" },
+{ RTE_LOGTYPE_HASH,       "lib.hash" },
+{ RTE_LOGTYPE_LPM,        "lib.lpm" },
+{ RTE_LOGTYPE_KNI,        "lib.kni" },
+{ RTE_LOGTYPE_ACL,        "lib.acl" },
+{ RTE_LOGTYPE_POWER,      "lib.power" },
+{ RTE_LOGTYPE_METER,      "lib.meter" },
+{ RTE_LOGTYPE_SCHED,      "lib.sched" },
+{ RTE_LOGTYPE_PORT,       "lib.port" },
+{ RTE_LOGTYPE_TABLE,      "lib.table" },
+{ RTE_LOGTYPE_PIPELINE,   "lib.pipeline" },
+{ RTE_LOGTYPE_MBUF,       "lib.mbuf" },
+{ RTE_LOGTYPE_CRYPTODEV,  "lib.cryptodev" },
+{ RTE_LOGTYPE_EFD,        "lib.efd" },
+{ RTE_LOGTYPE_EVENTDEV,   "lib.eventdev" },
+{ RTE_LOGTYPE_GSO,        "lib.gso" },
+{ RTE_LOGTYPE_USER1,      "user1" },
+{ RTE_LOGTYPE_USER2,      "user2" },
+{ RTE_LOGTYPE_USER3,      "user3" },
+{ RTE_LOGTYPE_USER4,      "user4" },
+{ RTE_LOGTYPE_USER5,      "user5" },
+{ RTE_LOGTYPE_USER6,      "user6" },
+{ RTE_LOGTYPE_USER7,      "user7" },
+{ RTE_LOGTYPE_USER8,      "user8" }
+};
+
+
+void
+rte_log_init(void)
+{
+	uint32_t i;
+
+	rte_log_set_global_level(RTE_LOG_DEBUG);
+
+	rte_logs.dynamic_types = calloc(RTE_LOGTYPE_FIRST_EXT_ID,
+		sizeof(struct rte_log_dynamic_type));
+	if (rte_logs.dynamic_types == NULL)
+		return;
+
+	/* register legacy log types */
+	for (i = 0; i < RTE_DIM(logtype_strings); i++)
+		__rte_log_register(logtype_strings[i].logtype,
+			logtype_strings[i].log_id);
+
+	rte_logs.dynamic_types_len = RTE_LOGTYPE_FIRST_EXT_ID;
+}
+
+static const char *
+loglevel_to_string(uint32_t level)
+{
+	switch (level) {
+	case 0: return "disabled";
+	case RTE_LOG_EMERG: return "emerg";
+	case RTE_LOG_ALERT: return "alert";
+	case RTE_LOG_CRIT: return "critical";
+	case RTE_LOG_ERR: return "error";
+	case RTE_LOG_WARNING: return "warning";
+	case RTE_LOG_NOTICE: return "notice";
+	case RTE_LOG_INFO: return "info";
+	case RTE_LOG_DEBUG: return "debug";
+	default: return "unknown";
+	}
+}
+
+/* dump global level and registered log types */
+void
+rte_log_dump(FILE *f)
+{
+	size_t i;
+
+	fprintf(f, "global log level is %s\n",
+		loglevel_to_string(rte_log_get_global_level()));
+
+	for (i = 0; i < rte_logs.dynamic_types_len; i++) {
+		if (rte_logs.dynamic_types[i].name == NULL)
+			continue;
+		fprintf(f, "id %zu: %s, level is %s\n",
+			i, rte_logs.dynamic_types[i].name,
+			loglevel_to_string(rte_logs.dynamic_types[i].loglevel));
+	}
+}
+
+/*
+* Generates a log message The message will be sent in the stream
+* defined by the previous call to rte_openlog_stream().
+*/
+int
+rte_vlog(uint32_t level, uint32_t logtype, const char *format, va_list ap)
+{
+	int ret;
+	FILE *f = rte_logs.file;
+	if (f == NULL) {
+		f = default_log_stream;
+		if (f == NULL) {
+			/*
+			* Grab the current value of stderr here, rather than
+			* just initializing default_log_stream to stderr. This
+			* ensures that we will always use the current value
+			* of stderr, even if the application closes and
+			* reopens it.
+			*/
+			f = stderr;
+		}
+	}
+
+	if (level > rte_logs.level)
+		return 0;
+	if (logtype >= rte_logs.dynamic_types_len)
+		return -1;
+	if (level > rte_logs.dynamic_types[logtype].loglevel)
+		return 0;
+
+	/* save loglevel and logtype in a global per-lcore variable */
+	RTE_PER_LCORE(log_cur_msg).loglevel = level;
+	RTE_PER_LCORE(log_cur_msg).logtype = logtype;
+
+	ret = vfprintf(f, format, ap);
+	fflush(f);
+	return ret;
+}
+
+/*
+* Generates a log message The message will be sent in the stream
+* defined by the previous call to rte_openlog_stream().
+* No need to check level here, done by rte_vlog().
+*/
+int
+rte_log(uint32_t level, uint32_t logtype, const char *format, ...)
+{
+	va_list ap;
+	int ret;
+
+	va_start(ap, format);
+	ret = rte_vlog(level, logtype, format, ap);
+	va_end(ap);
+	return ret;
+}
+
+/*
+* Called by environment-specific initialization functions.
+*/
+void
+eal_log_set_default(FILE *default_log)
+{
+	default_log_stream = default_log;
+
+#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG
+	RTE_LOG(NOTICE, EAL,
+		"Debug dataplane logs available - lower performance\n");
+#endif
+}
+
+/*
+* set the log to default function, called during eal init process,
+* once memzones are available.
+*/
+int
+rte_eal_log_init(const char *id, int facility)
+{
+	eal_log_set_default(stderr);
+	return 0;
+}
diff --git a/lib/librte_eal/windows/eal/eal_memalloc.c b/lib/librte_eal/windows/eal/eal_memalloc.c
new file mode 100644
index 000000000..66c0d1ca7
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal_memalloc.c
@@ -0,0 +1,995 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017-2018 Intel Corporation
+ */
+
+#define _FILE_OFFSET_BITS 64
+#include <errno.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/queue.h>
+#include <unistd.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <Intsafe.h>
+#include <process.h>
+
+#include <signal.h>
+#include <setjmp.h>
+
+#include <rte_common.h>
+#include <rte_log.h>
+#include <rte_eal_memconfig.h>
+#include <rte_eal.h>
+#include <rte_memory.h>
+#include <rte_spinlock.h>
+
+#include "eal_filesystem.h"
+#include "eal_internal_cfg.h"
+#include "eal_memalloc.h"
+#include "eal_private.h"
+
+const int anonymous_hugepages_supported =
+#ifdef MAP_HUGE_SHIFT
+		1;
+#define RTE_MAP_HUGE_SHIFT MAP_HUGE_SHIFT
+#else
+		0;
+#define RTE_MAP_HUGE_SHIFT 26
+#endif
+
+/*
+ * not all kernel version support fallocate on hugetlbfs, so fall back to
+ * ftruncate and disallow deallocation if fallocate is not supported.
+ */
+static int fallocate_supported = -1; /* unknown */
+
+/* for single-file segments, we need some kind of mechanism to keep track of
+ * which hugepages can be freed back to the system, and which cannot. we cannot
+ * use flock() because they don't allow locking parts of a file, and we cannot
+ * use fcntl() due to issues with their semantics, so we will have to rely on a
+ * bunch of lockfiles for each page.
+ *
+ * we cannot know how many pages a system will have in advance, but we do know
+ * that they come in lists, and we know lengths of these lists. so, simply store
+ * a malloc'd array of fd's indexed by list and segment index.
+ *
+ * they will be initialized at startup, and filled as we allocate/deallocate
+ * segments. also, use this to track memseg list proper fd.
+ */
+static struct {
+	int *fds; /**< dynamically allocated array of segment lock fd's */
+	int memseg_list_fd; /**< memseg list fd */
+	int len; /**< total length of the array */
+	int count; /**< entries used in an array */
+} fd_list[RTE_MAX_MEMSEG_LISTS];
+
+/** local copy of a memory map, used to synchronize memory hotplug in MP */
+static struct rte_memseg_list local_memsegs[RTE_MAX_MEMSEG_LISTS];
+
+static sigjmp_buf huge_jmpenv;
+
+/* Put setjmp into a wrap method to avoid compiling error. Any non-volatile,
+ * non-static local variable in the stack frame calling sigsetjmp might be
+ * clobbered by a call to longjmp.
+ */
+static int __rte_unused huge_wrap_sigsetjmp(void)
+{
+	return sigsetjmp(huge_jmpenv, 1);
+}
+
+static int
+get_seg_fd(char *path, int buflen, struct hugepage_info *hi,
+		unsigned int list_idx, unsigned int seg_idx)
+{
+	int fd;
+	BOOL ret;
+
+	if (internal_config.single_file_segments) {
+		/* create a hugepage file path */
+		eal_get_hugefile_path(path, buflen, hi->hugedir, list_idx);
+
+		fd = fd_list[list_idx].memseg_list_fd;
+
+		if (fd < 0) {
+			fd = _open(path, O_CREAT | O_RDWR, _S_IREAD | _S_IWRITE);
+			if (fd < 0) {
+				RTE_LOG(ERR, EAL, "%s(): open failed: %s\n",
+					__func__, strerror(errno));
+				return -1;
+			}
+
+			/* TODO dpdk-1808 take out a read lock and keep it indefinitely */
+
+			fd_list[list_idx].memseg_list_fd = fd;
+		}
+	} else {
+		/* create a hugepage file path */
+		eal_get_hugefile_path(path, buflen, hi->hugedir,
+				list_idx * RTE_MAX_MEMSEG_PER_LIST + seg_idx);
+		fd = _open(path, O_CREAT | O_RDWR, _S_IREAD | _S_IWRITE);
+		if (fd < 0) {
+			RTE_LOG(DEBUG, EAL, "%s(): open failed: %s\n", __func__,
+					strerror(errno));
+			return -1;
+		}
+		/* TODO dpdk-1808 take out a read lock */
+
+	}
+	return fd;
+}
+
+static int
+resize_hugefile(int fd, char *path, int list_idx, int seg_idx,
+		uint64_t fa_offset, uint64_t page_sz, bool grow)
+{
+	/* dpdk-1808 Not implemented in Windows*/
+	return 0;
+}
+
+static int
+alloc_seg(struct rte_memseg *ms, void *addr, int socket_id,
+		struct hugepage_info *hi, unsigned int list_idx,
+		unsigned int seg_idx)
+{
+#ifdef RTE_EAL_NUMA_AWARE_HUGEPAGES
+	int cur_socket_id = 0;
+#endif
+	uint64_t map_offset;
+	rte_iova_t iova;
+	void *va;
+	char path[PATH_MAX];
+	int ret = 0;
+	int fd;
+	size_t alloc_sz;
+	int flags;
+	void *new_addr;
+
+	alloc_sz = hi->hugepage_sz;
+	if (!internal_config.single_file_segments &&
+			internal_config.in_memory &&
+			anonymous_hugepages_supported) {
+		int log2, flags;
+
+		log2 = rte_log2_u32(alloc_sz);
+		/* as per mmap() manpage, all page sizes are log2 of page size
+		 * shifted by MAP_HUGE_SHIFT
+		 */
+		flags = (log2 << RTE_MAP_HUGE_SHIFT) | MAP_FIXED |
+				MAP_PRIVATE | MAP_ANONYMOUS;
+		fd = -1;
+		va = mmap(addr, alloc_sz, PROT_READ | PROT_WRITE, flags, -1, 0);
+
+		/* single-file segments codepath will never be active because
+		 * in-memory mode is incompatible with it and it's stopped at
+		 * EAL initialization stage, however the compiler doesn't know
+		 * that and complains about map_offset being used uninitialized
+		 * on failure codepaths while having in-memory mode enabled. so,
+		 * assign a value here.
+		 */
+		map_offset = 0;
+	} else {
+		/* takes out a read lock on segment or segment list */
+		fd = get_seg_fd(path, sizeof(path), hi, list_idx, seg_idx);
+		if (fd < 0) {
+			RTE_LOG(ERR, EAL, "Couldn't get fd on hugepage file\n");
+			return -1;
+		}
+
+		if (internal_config.single_file_segments) {
+			map_offset = seg_idx * alloc_sz;
+			ret = resize_hugefile(fd, path, list_idx, seg_idx,
+					map_offset, alloc_sz, true);
+			if (ret < 0)
+				goto resized;
+		} else {
+			map_offset = 0;
+			if (ftruncate(fd, alloc_sz) < 0) {
+				RTE_LOG(DEBUG, EAL, "%s(): ftruncate() failed: %s\n",
+					__func__, strerror(errno));
+				goto resized;
+			}
+			if (internal_config.hugepage_unlink) {
+				if (unlink(path)) {
+					RTE_LOG(DEBUG, EAL, "%s(): unlink() failed: %s\n",
+						__func__, strerror(errno));
+					goto resized;
+				}
+			}
+		}
+
+		/*
+		 * map the segment, and populate page tables, the kernel fills
+		 * this segment with zeros if it's a new page.
+		 */
+		va = mmap(addr, alloc_sz, PROT_READ | PROT_WRITE,
+				MAP_SHARED | MAP_FIXED, fd,
+				map_offset);
+	}
+
+	if (va == MAP_FAILED) {
+		RTE_LOG(DEBUG, EAL, "%s(): mmap() failed: %s\n", __func__,
+			strerror(errno));
+		/* mmap failed, but the previous region might have been
+		 * unmapped anyway. try to remap it
+		 */
+		goto unmapped;
+	}
+	if (va != addr) {
+		RTE_LOG(DEBUG, EAL, "%s(): wrong mmap() address\n", __func__);
+		munmap(va, alloc_sz);
+		goto resized;
+	}
+
+	/* In linux, hugetlb limitations, like cgroup, are
+	 * enforced at fault time instead of mmap(), even
+	 * with the option of MAP_POPULATE. Kernel will send
+	 * a SIGBUS signal. To avoid to be killed, save stack
+	 * environment here, if SIGBUS happens, we can jump
+	 * back here.
+	 */
+	if (huge_wrap_sigsetjmp()) {
+		RTE_LOG(DEBUG, EAL, "SIGBUS: Cannot mmap more hugepages of size %uMB\n",
+			(unsigned int)(alloc_sz >> 20));
+		goto mapped;
+	}
+
+	/* we need to trigger a write to the page to enforce page fault and
+	 * ensure that page is accessible to us, but we can't overwrite value
+	 * that is already there, so read the old value, and write itback.
+	 * kernel populates the page with zeroes initially.
+	 */
+	*(volatile int *)addr = *(volatile int *)addr;
+
+	iova = rte_mem_virt2iova(addr);
+	if (iova == RTE_BAD_PHYS_ADDR) {
+		RTE_LOG(DEBUG, EAL, "%s(): can't get IOVA addr\n",
+			__func__);
+		goto mapped;
+	}
+
+#ifdef RTE_EAL_NUMA_AWARE_HUGEPAGES
+	move_pages(getpid(), 1, &addr, NULL, &cur_socket_id, 0);
+
+	if (cur_socket_id != socket_id) {
+		RTE_LOG(DEBUG, EAL,
+				"%s(): allocation happened on wrong socket (wanted %d, got %d)\n",
+			__func__, socket_id, cur_socket_id);
+		goto mapped;
+	}
+#endif
+	/* for non-single file segments that aren't in-memory, we can close fd
+	 * here */
+	if (!internal_config.single_file_segments && !internal_config.in_memory)
+		close(fd);
+
+	ms->addr = addr;
+	ms->hugepage_sz = alloc_sz;
+	ms->len = alloc_sz;
+	ms->nchannel = rte_memory_get_nchannel();
+	ms->nrank = rte_memory_get_nrank();
+	ms->iova = iova;
+	ms->socket_id = socket_id;
+
+	return 0;
+
+mapped:
+	munmap(addr, alloc_sz);
+unmapped:
+	flags = MAP_FIXED;
+	new_addr = eal_get_virtual_area(addr, &alloc_sz, alloc_sz, 0, flags);
+	if (new_addr != addr) {
+		if (new_addr != NULL)
+			munmap(new_addr, alloc_sz);
+		/* we're leaving a hole in our virtual address space. if
+		 * somebody else maps this hole now, we could accidentally
+		 * override it in the future.
+		 */
+		RTE_LOG(CRIT, EAL, "Can't mmap holes in our virtual address space\n");
+	}
+resized:
+	/* in-memory mode will never be single-file-segments mode */
+	if (internal_config.single_file_segments) {
+		resize_hugefile(fd, path, list_idx, seg_idx, map_offset,
+				alloc_sz, false);
+		/* ignore failure, can't make it any worse */
+	} else {
+
+		/* TODO dpdk-1808 only remove file if we can take out a write lock */
+		if (internal_config.hugepage_unlink == 0 &&
+				internal_config.in_memory == 0 )
+			unlink(path);
+		close(fd);
+	}
+	return -1;
+}
+
+static int
+free_seg(struct rte_memseg *ms, struct hugepage_info *hi,
+		unsigned int list_idx, unsigned int seg_idx)
+{
+	char path[PATH_MAX];
+	int fd;
+	BOOL ret;
+
+	/* erase page data */
+	memset(ms->addr, 0, ms->len);
+
+
+
+	/* if we've already unlinked the page, nothing needs to be done */
+	if (internal_config.hugepage_unlink) {
+		memset(ms, 0, sizeof(*ms));
+		return 0;
+	}
+
+	/* Avoid unmmaping already mapped memory to boost performance*/
+
+	return 0;
+}
+
+struct alloc_walk_param {
+	struct hugepage_info *hi;
+	struct rte_memseg **ms;
+	size_t page_sz;
+	unsigned int segs_allocated;
+	unsigned int n_segs;
+	int socket;
+	bool exact;
+};
+static int
+alloc_seg_walk(const struct rte_memseg_list *msl, void *arg)
+{
+	struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+	struct alloc_walk_param *wa = arg;
+	struct rte_memseg_list *cur_msl;
+	size_t page_sz;
+	BOOL ret;
+	int cur_idx, start_idx, j, dir_fd = -1;
+	unsigned int msl_idx, need, i;
+
+	if (msl->page_sz != wa->page_sz)
+		return 0;
+	if (msl->socket_id != wa->socket)
+		return 0;
+
+	page_sz = (size_t)msl->page_sz;
+
+	msl_idx = msl - mcfg->memsegs;
+	cur_msl = &mcfg->memsegs[msl_idx];
+
+	need = wa->n_segs;
+
+	/* try finding space in memseg list */
+	cur_idx = rte_fbarray_find_next_n_free(&cur_msl->memseg_arr, 0, need);
+	if (cur_idx < 0)
+		return 0;
+	start_idx = cur_idx;
+
+	/*
+	 * TODO dpdk-1808
+	 * do not allow any page allocations during the time we're allocating,
+	 * because file creation and locking operations are not atomic,
+	 * and we might be the first or the last ones to use a particular page,
+	 * so we need to ensure atomicity of every operation.
+	 *
+	 * during init, we already hold a write lock, so don't try to take out
+	 * another one.
+	 */
+
+	for (i = 0; i < need; i++, cur_idx++) {
+		struct rte_memseg *cur;
+		void *map_addr;
+
+		cur = rte_fbarray_get(&cur_msl->memseg_arr, cur_idx);
+		map_addr = RTE_PTR_ADD(cur_msl->base_va,
+				cur_idx * page_sz);
+
+		if (alloc_seg(cur, map_addr, wa->socket, wa->hi,
+				msl_idx, cur_idx)) {
+			RTE_LOG(DEBUG, EAL, "attempted to allocate %i segments, but only %i were allocated\n",
+				need, i);
+
+			/* if exact number wasn't requested, stop */
+			if (!wa->exact)
+				goto out;
+
+			/* clean up */
+			for (j = start_idx; j < cur_idx; j++) {
+				struct rte_memseg *tmp;
+				struct rte_fbarray *arr =
+						&cur_msl->memseg_arr;
+
+				tmp = rte_fbarray_get(arr, j);
+				rte_fbarray_set_free(arr, j);
+
+				/* free_seg may attempt to create a file, which
+				 * may fail.
+				 */
+				if (free_seg(tmp, wa->hi, msl_idx, j))
+					RTE_LOG(DEBUG, EAL, "Cannot free page\n");
+			}
+			/* clear the list */
+			if (wa->ms)
+				memset(wa->ms, 0, sizeof(*wa->ms) * wa->n_segs);
+
+			if (dir_fd >= 0)
+				close(dir_fd);
+			return -1;
+		}
+		if (wa->ms)
+			wa->ms[i] = cur;
+
+		rte_fbarray_set_used(&cur_msl->memseg_arr, cur_idx);
+	}
+out:
+	wa->segs_allocated = i;
+	if (i > 0)
+		cur_msl->version++;
+	if (dir_fd >= 0)
+		close(dir_fd);
+	return 1;
+}
+
+struct free_walk_param {
+	struct hugepage_info *hi;
+	struct rte_memseg *ms;
+};
+static int
+free_seg_walk(const struct rte_memseg_list *msl, void *arg)
+{
+	struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+	struct rte_memseg_list *found_msl;
+	struct free_walk_param *wa = arg;
+	uintptr_t start_addr, end_addr;
+	int msl_idx, seg_idx, ret, dir_fd = -1;
+	BOOL retval;
+
+	start_addr = (uintptr_t) msl->base_va;
+	end_addr = start_addr + msl->memseg_arr.len * (size_t)msl->page_sz;
+
+	if ((uintptr_t)wa->ms->addr < start_addr ||
+			(uintptr_t)wa->ms->addr >= end_addr)
+		return 0;
+
+	msl_idx = msl - mcfg->memsegs;
+	seg_idx = RTE_PTR_DIFF(wa->ms->addr, start_addr) / msl->page_sz;
+
+	/* msl is const */
+	found_msl = &mcfg->memsegs[msl_idx];
+
+	/* Removing clean up and synchronization code*/
+	/* TODO dpdk-1808
+	* do not allow any page allocations during the time we're freeing,
+	* because file creation and locking operations are not atomic,
+	* and we might be the first or the last ones to use a particular page,
+	* so we need to ensure atomicity of every operation.
+	*
+	* during init, we already hold a write lock, so don't try to take out
+	* another one.
+	*/
+
+	found_msl->version++;
+
+	rte_fbarray_set_free(&found_msl->memseg_arr, seg_idx);
+
+	ret = free_seg(wa->ms, wa->hi, msl_idx, seg_idx);
+
+	if (ret < 0)
+		return -1;
+
+	return 1;
+}
+
+int
+eal_memalloc_alloc_seg_bulk(struct rte_memseg **ms, int n_segs, size_t page_sz,
+		int socket, bool exact)
+{
+	int i, ret = -1;
+#ifdef RTE_EAL_NUMA_AWARE_HUGEPAGES
+	bool have_numa = false;
+	int oldpolicy;
+	struct bitmask *oldmask;
+#endif
+	struct alloc_walk_param wa;
+	struct hugepage_info *hi = NULL;
+
+	memset(&wa, 0, sizeof(wa));
+
+	/* dynamic allocation not supported in legacy mode */
+	if (internal_config.legacy_mem)
+		return -1;
+
+	for (i = 0; i < (int) RTE_DIM(internal_config.hugepage_info); i++) {
+		if (page_sz ==
+				internal_config.hugepage_info[i].hugepage_sz) {
+			hi = &internal_config.hugepage_info[i];
+			break;
+		}
+	}
+	if (!hi) {
+		RTE_LOG(ERR, EAL, "%s(): can't find relevant hugepage_info entry\n",
+			__func__);
+		return -1;
+	}
+
+#ifdef RTE_EAL_NUMA_AWARE_HUGEPAGES
+	if (check_numa()) {
+		oldmask = numa_allocate_nodemask();
+		prepare_numa(&oldpolicy, oldmask, socket);
+		have_numa = true;
+	}
+#endif
+
+	wa.exact = exact;
+	wa.hi = hi;
+	wa.ms = ms;
+	wa.n_segs = n_segs;
+	wa.page_sz = page_sz;
+	wa.socket = socket;
+	wa.segs_allocated = 0;
+
+	/* memalloc is locked, so it's safe to use thread-unsafe version */
+	ret = rte_memseg_list_walk_thread_unsafe(alloc_seg_walk, &wa);
+	if (ret == 0) {
+		RTE_LOG(ERR, EAL, "%s(): couldn't find suitable memseg_list\n",
+			__func__);
+		ret = -1;
+	} else if (ret > 0) {
+		ret = (int)wa.segs_allocated;
+	}
+
+#ifdef RTE_EAL_NUMA_AWARE_HUGEPAGES
+	if (have_numa)
+		restore_numa(&oldpolicy, oldmask);
+#endif
+	return ret;
+}
+
+struct rte_memseg *
+eal_memalloc_alloc_seg(size_t page_sz, int socket)
+{
+	struct rte_memseg *ms;
+	if (eal_memalloc_alloc_seg_bulk(&ms, 1, page_sz, socket, true) < 0)
+		return NULL;
+	/* return pointer to newly allocated memseg */
+	return ms;
+}
+
+int
+eal_memalloc_free_seg_bulk(struct rte_memseg **ms, int n_segs)
+{
+	int seg, ret = 0;
+
+	/* dynamic free not supported in legacy mode */
+	if (internal_config.legacy_mem)
+		return -1;
+
+	for (seg = 0; seg < n_segs; seg++) {
+		struct rte_memseg *cur = ms[seg];
+		struct hugepage_info *hi = NULL;
+		struct free_walk_param wa;
+		int i, walk_res;
+
+		/* if this page is marked as unfreeable, fail */
+		if (cur->flags & RTE_MEMSEG_FLAG_DO_NOT_FREE) {
+			RTE_LOG(DEBUG, EAL, "Page is not allowed to be freed\n");
+			ret = -1;
+			continue;
+		}
+
+		memset(&wa, 0, sizeof(wa));
+
+
+
+		wa.ms = cur;
+		wa.hi = hi;
+
+		/* memalloc is locked, so it's safe to use thread-unsafe version
+		 */
+		walk_res = rte_memseg_list_walk_thread_unsafe(free_seg_walk,
+				&wa);
+		if (walk_res == 1)
+			continue;
+		if (walk_res == 0)
+			RTE_LOG(ERR, EAL, "Couldn't find memseg list\n");
+		ret = -1;
+	}
+	return ret;
+}
+
+int
+eal_memalloc_free_seg(struct rte_memseg *ms)
+{
+	/* dynamic free not supported in legacy mode */
+	if (internal_config.legacy_mem)
+		return -1;
+
+	return eal_memalloc_free_seg_bulk(&ms, 1);
+}
+
+static int
+sync_chunk(struct rte_memseg_list *primary_msl,
+		struct rte_memseg_list *local_msl, struct hugepage_info *hi,
+		unsigned int msl_idx, bool used, int start, int end)
+{
+	struct rte_fbarray *l_arr, *p_arr;
+	int i, ret, chunk_len, diff_len;
+
+	l_arr = &local_msl->memseg_arr;
+	p_arr = &primary_msl->memseg_arr;
+
+	/* we need to aggregate allocations/deallocations into bigger chunks,
+	 * as we don't want to spam the user with per-page callbacks.
+	 *
+	 * to avoid any potential issues, we also want to trigger
+	 * deallocation callbacks *before* we actually deallocate
+	 * memory, so that the user application could wrap up its use
+	 * before it goes away.
+	 */
+
+	chunk_len = end - start;
+
+	/* find how many contiguous pages we can map/unmap for this chunk */
+	diff_len = used ?
+			rte_fbarray_find_contig_free(l_arr, start) :
+			rte_fbarray_find_contig_used(l_arr, start);
+
+	/* has to be at least one page */
+	if (diff_len < 1)
+		return -1;
+
+	diff_len = RTE_MIN(chunk_len, diff_len);
+
+	/* if we are freeing memory, notify the application */
+	if (!used) {
+		struct rte_memseg *ms;
+		void *start_va;
+		size_t len, page_sz;
+
+		ms = rte_fbarray_get(l_arr, start);
+		start_va = ms->addr;
+		page_sz = (size_t)primary_msl->page_sz;
+		len = page_sz * diff_len;
+
+		eal_memalloc_mem_event_notify(RTE_MEM_EVENT_FREE,
+				start_va, len);
+	}
+
+	for (i = 0; i < diff_len; i++) {
+		struct rte_memseg *p_ms, *l_ms;
+		int seg_idx = start + i;
+
+		l_ms = rte_fbarray_get(l_arr, seg_idx);
+		p_ms = rte_fbarray_get(p_arr, seg_idx);
+
+		if (l_ms == NULL || p_ms == NULL)
+			return -1;
+
+		if (used) {
+			ret = alloc_seg(l_ms, p_ms->addr,
+					p_ms->socket_id, hi,
+					msl_idx, seg_idx);
+			if (ret < 0)
+				return -1;
+			rte_fbarray_set_used(l_arr, seg_idx);
+		} else {
+			ret = free_seg(l_ms, hi, msl_idx, seg_idx);
+			rte_fbarray_set_free(l_arr, seg_idx);
+			if (ret < 0)
+				return -1;
+		}
+	}
+
+	/* if we just allocated memory, notify the application */
+	if (used) {
+		struct rte_memseg *ms;
+		void *start_va;
+		size_t len, page_sz;
+
+		ms = rte_fbarray_get(l_arr, start);
+		start_va = ms->addr;
+		page_sz = (size_t)primary_msl->page_sz;
+		len = page_sz * diff_len;
+
+		eal_memalloc_mem_event_notify(RTE_MEM_EVENT_ALLOC,
+				start_va, len);
+	}
+
+	/* calculate how much we can advance until next chunk */
+	diff_len = used ?
+			rte_fbarray_find_contig_used(l_arr, start) :
+			rte_fbarray_find_contig_free(l_arr, start);
+	ret = RTE_MIN(chunk_len, diff_len);
+
+	return ret;
+}
+
+static int
+sync_status(struct rte_memseg_list *primary_msl,
+		struct rte_memseg_list *local_msl, struct hugepage_info *hi,
+		unsigned int msl_idx, bool used)
+{
+	struct rte_fbarray *l_arr, *p_arr;
+	int p_idx, l_chunk_len, p_chunk_len, ret;
+	int start, end;
+
+	/* this is a little bit tricky, but the basic idea is - walk both lists
+	 * and spot any places where there are discrepancies. walking both lists
+	 * and noting discrepancies in a single go is a hard problem, so we do
+	 * it in two passes - first we spot any places where allocated segments
+	 * mismatch (i.e. ensure that everything that's allocated in the primary
+	 * is also allocated in the secondary), and then we do it by looking at
+	 * free segments instead.
+	 *
+	 * we also need to aggregate changes into chunks, as we have to call
+	 * callbacks per allocation, not per page.
+	 */
+	l_arr = &local_msl->memseg_arr;
+	p_arr = &primary_msl->memseg_arr;
+
+	if (used)
+		p_idx = rte_fbarray_find_next_used(p_arr, 0);
+	else
+		p_idx = rte_fbarray_find_next_free(p_arr, 0);
+
+	while (p_idx >= 0) {
+		int next_chunk_search_idx;
+
+		if (used) {
+			p_chunk_len = rte_fbarray_find_contig_used(p_arr,
+					p_idx);
+			l_chunk_len = rte_fbarray_find_contig_used(l_arr,
+					p_idx);
+		} else {
+			p_chunk_len = rte_fbarray_find_contig_free(p_arr,
+					p_idx);
+			l_chunk_len = rte_fbarray_find_contig_free(l_arr,
+					p_idx);
+		}
+		/* best case scenario - no differences (or bigger, which will be
+		 * fixed during next iteration), look for next chunk
+		 */
+		if (l_chunk_len >= p_chunk_len) {
+			next_chunk_search_idx = p_idx + p_chunk_len;
+			goto next_chunk;
+		}
+
+		/* if both chunks start at the same point, skip parts we know
+		 * are identical, and sync the rest. each call to sync_chunk
+		 * will only sync contiguous segments, so we need to call this
+		 * until we are sure there are no more differences in this
+		 * chunk.
+		 */
+		start = p_idx + l_chunk_len;
+		end = p_idx + p_chunk_len;
+		do {
+			ret = sync_chunk(primary_msl, local_msl, hi, msl_idx,
+					used, start, end);
+			start += ret;
+		} while (start < end && ret >= 0);
+		/* if ret is negative, something went wrong */
+		if (ret < 0)
+			return -1;
+
+		next_chunk_search_idx = p_idx + p_chunk_len;
+next_chunk:
+		/* skip to end of this chunk */
+		if (used) {
+			p_idx = rte_fbarray_find_next_used(p_arr,
+					next_chunk_search_idx);
+		} else {
+			p_idx = rte_fbarray_find_next_free(p_arr,
+					next_chunk_search_idx);
+		}
+	}
+	return 0;
+}
+
+static int
+sync_existing(struct rte_memseg_list *primary_msl,
+		struct rte_memseg_list *local_msl, struct hugepage_info *hi,
+		unsigned int msl_idx)
+{
+	int ret, dir_fd;
+
+	/* TODO dpdk-1808
+	 * do not allow any page allocations during the time we're allocating,
+	 * because file creation and locking operations are not atomic,
+	 * and we might be the first or the last ones to use a particular page,
+	 * so we need to ensure atomicity of every operation.
+	 */
+
+
+	/* ensure all allocated space is the same in both lists */
+	ret = sync_status(primary_msl, local_msl, hi, msl_idx, true);
+	if (ret < 0)
+		goto fail;
+
+	/* ensure all unallocated space is the same in both lists */
+	ret = sync_status(primary_msl, local_msl, hi, msl_idx, false);
+	if (ret < 0)
+		goto fail;
+
+	/* update version number */
+	local_msl->version = primary_msl->version;
+
+	/* TODO dpdk-1808 Unlock and close the directory*/
+
+	return 0;
+fail:
+	/* TODO dpdk-1808 Unlock and close the directory*/
+	return -1;
+}
+
+static int
+sync_walk(const struct rte_memseg_list *msl, void *arg __rte_unused)
+{
+	struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+	struct rte_memseg_list *primary_msl, *local_msl;
+	struct hugepage_info *hi = NULL;
+	unsigned int i;
+	int msl_idx;
+
+	msl_idx = msl - mcfg->memsegs;
+	primary_msl = &mcfg->memsegs[msl_idx];
+	local_msl = &local_memsegs[msl_idx];
+
+	for (i = 0; i < RTE_DIM(internal_config.hugepage_info); i++) {
+		uint64_t cur_sz =
+			internal_config.hugepage_info[i].hugepage_sz;
+		uint64_t msl_sz = primary_msl->page_sz;
+		if (msl_sz == cur_sz) {
+			hi = &internal_config.hugepage_info[i];
+			break;
+		}
+	}
+	if (!hi) {
+		RTE_LOG(ERR, EAL, "Can't find relevant hugepage_info entry\n");
+		return -1;
+	}
+
+	/* if versions don't match, synchronize everything */
+	if (local_msl->version != primary_msl->version &&
+			sync_existing(primary_msl, local_msl, hi, msl_idx))
+		return -1;
+	return 0;
+}
+
+
+int
+eal_memalloc_sync_with_primary(void)
+{
+	/* nothing to be done in primary */
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+		return 0;
+
+	/* memalloc is locked, so it's safe to call thread-unsafe version */
+	if (rte_memseg_list_walk_thread_unsafe(sync_walk, NULL))
+		return -1;
+	return 0;
+}
+
+static int
+secondary_msl_create_walk(const struct rte_memseg_list *msl,
+		void *arg __rte_unused)
+{
+	struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+	struct rte_memseg_list *primary_msl, *local_msl;
+	char name[PATH_MAX];
+	int msl_idx, ret;
+
+	msl_idx = msl - mcfg->memsegs;
+	primary_msl = &mcfg->memsegs[msl_idx];
+	local_msl = &local_memsegs[msl_idx];
+
+	/* create distinct fbarrays for each secondary */
+	snprintf(name, RTE_FBARRAY_NAME_LEN, "%s_%i",
+		primary_msl->memseg_arr.name, _getpid());
+
+	ret = rte_fbarray_init(&local_msl->memseg_arr, name,
+		primary_msl->memseg_arr.len,
+		primary_msl->memseg_arr.elt_sz);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "Cannot initialize local memory map\n");
+		return -1;
+	}
+	local_msl->base_va = primary_msl->base_va;
+
+	return 0;
+}
+
+static int
+secondary_lock_list_create_walk(const struct rte_memseg_list *msl,
+		void *arg __rte_unused)
+{
+	struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+	unsigned int i, len;
+	int msl_idx;
+	int *data;
+
+	msl_idx = msl - mcfg->memsegs;
+	len = msl->memseg_arr.len;
+
+	/* ensure we have space to store lock fd per each possible segment */
+	data = malloc(sizeof(int) * len);
+	if (data == NULL) {
+		RTE_LOG(ERR, EAL, "Unable to allocate space for lock descriptors\n");
+		return -1;
+	}
+	/* set all fd's as invalid */
+	for (i = 0; i < len; i++)
+		data[i] = -1;
+
+	fd_list[msl_idx].fds = data;
+	fd_list[msl_idx].len = len;
+	fd_list[msl_idx].count = 0;
+	fd_list[msl_idx].memseg_list_fd = -1;
+
+	return 0;
+}
+
+int
+eal_memalloc_init(void)
+{
+	if (rte_eal_process_type() == RTE_PROC_SECONDARY)
+		if (rte_memseg_list_walk(secondary_msl_create_walk, NULL) < 0)
+			return -1;
+
+	/* initialize all of the lock fd lists */
+	if (internal_config.single_file_segments)
+		if (rte_memseg_list_walk(secondary_lock_list_create_walk, NULL))
+			return -1;
+	return 0;
+}
+
+int
+eal_memalloc_get_seg_fd(int list_idx, int seg_idx)
+{
+	int fd;
+	if (internal_config.single_file_segments) {
+		fd = fd_list[list_idx].memseg_list_fd;
+	}
+	else if (fd_list[list_idx].len == 0) {
+		/* list not initialized */
+		fd = -1;
+	}
+	else {
+		fd = fd_list[list_idx].fds[seg_idx];
+	}
+	if (fd < 0)
+		return -ENODEV;
+	return fd;
+}
+
+int
+eal_memalloc_get_seg_fd_offset(int list_idx, int seg_idx, size_t *offset)
+{
+	struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+
+	/* fd_list not initialized? */
+	if (fd_list[list_idx].len == 0)
+		return -ENODEV;
+	if (internal_config.single_file_segments) {
+		size_t pgsz = mcfg->memsegs[list_idx].page_sz;
+
+		/* segment not active? */
+		if (fd_list[list_idx].memseg_list_fd < 0)
+			return -ENOENT;
+		*offset = pgsz * seg_idx;
+	}
+	else {
+		/* segment not active? */
+		if (fd_list[list_idx].fds[seg_idx] < 0)
+			return -ENOENT;
+		*offset = 0;
+	}
+	return 0;
+}
\ No newline at end of file
diff --git a/lib/librte_eal/windows/eal/eal_memory.c b/lib/librte_eal/windows/eal/eal_memory.c
new file mode 100644
index 000000000..9077f5e9e
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal_memory.c
@@ -0,0 +1,140 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#include <sys/mman.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <inttypes.h>
+#include <fcntl.h>
+
+#include <rte_eal.h>
+#include <rte_eal_memconfig.h>
+#include <rte_log.h>
+#include <rte_string_fns.h>
+#include <rte_fbarray.h>
+#include <rte_errno.h>
+#include "eal_private.h"
+#include "eal_internal_cfg.h"
+#include "eal_filesystem.h"
+
+#define EAL_PAGE_SIZE	    (getpagesize())
+
+/*
+ * Get physical address of any mapped virtual address in the current process.
+ */
+phys_addr_t
+rte_mem_virt2iova(const void *virtaddr)
+{
+	/* This function is only used by rte_mempool_virt2phy() when hugepages are disabled. */
+	/* Get pointer to global configuration and calculate physical address offset */
+	phys_addr_t physaddr;
+	struct rte_memseg *ms;
+	struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+	if (mcfg) {
+		ms = rte_fbarray_get(&mcfg->memsegs[0].memseg_arr, 0);
+		if(ms == NULL)
+			return RTE_BAD_PHYS_ADDR;
+		physaddr = (phys_addr_t)((uintptr_t)ms->phys_addr + RTE_PTR_DIFF(virtaddr, mcfg->memsegs[0].base_va));
+		return physaddr;
+	}
+	else
+		return RTE_BAD_PHYS_ADDR;
+}
+
+int
+rte_eal_hugepage_init(void)
+{
+	/* We have already initialized our memory whilst in the
+	 * rte_pci_scan() call. Simply return here.
+	*/
+	return 0;
+}
+
+int
+rte_eal_hugepage_attach(void)
+{
+	/* This function is called if our process is a secondary process
+	 * and we need to attach to existing memory that has already
+	 * been allocated.
+	 * It has not been implemented on Windows
+	 */
+	return 0;
+}
+
+static int
+alloc_va_space(struct rte_memseg_list *msl)
+{
+	uint64_t page_sz;
+	size_t mem_sz;
+	void *addr;
+	int flags = 0;
+
+#ifdef RTE_ARCH_PPC_64
+	flags |= MAP_HUGETLB;
+#endif
+
+	page_sz = msl->page_sz;
+	mem_sz = page_sz * msl->memseg_arr.len;
+
+	addr = eal_get_virtual_area(msl->base_va, &mem_sz, page_sz, 0, flags);
+	if (addr == NULL) {
+		if (rte_errno == EADDRNOTAVAIL)
+			RTE_LOG(ERR, EAL, "Could not mmap %llu bytes at [%p] - please use '--base-virtaddr' option\n",
+			(unsigned long long)mem_sz, msl->base_va);
+		else
+			RTE_LOG(ERR, EAL, "Cannot reserve memory\n");
+		return -1;
+	}
+	msl->base_va = addr;
+
+	return 0;
+}
+
+static int __rte_unused
+memseg_primary_init(void)
+{
+	/*
+	*  Primary memory has already been initialized in store_memseg_info()
+	*  Keeping the stub function for integration with common code.
+	*/
+
+	return 0;
+}
+
+static int
+memseg_secondary_init(void)
+{
+	struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+	int msl_idx = 0;
+	struct rte_memseg_list *msl;
+
+	for (msl_idx = 0; msl_idx < RTE_MAX_MEMSEG_LISTS; msl_idx++) {
+
+		msl = &mcfg->memsegs[msl_idx];
+
+		/* skip empty memseg lists */
+		if (msl->memseg_arr.len == 0)
+			continue;
+
+		if (rte_fbarray_attach(&msl->memseg_arr)) {
+			RTE_LOG(ERR, EAL, "Cannot attach to primary process memseg lists\n");
+			return -1;
+		}
+
+		/* preallocate VA space */
+		if (alloc_va_space(msl)) {
+			RTE_LOG(ERR, EAL, "Cannot preallocate VA space for hugepage memory\n");
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+
+int
+rte_eal_memseg_init(void)
+{
+	return rte_eal_process_type() == RTE_PROC_PRIMARY ? memseg_primary_init() : memseg_secondary_init();
+}
diff --git a/lib/librte_eal/windows/eal/eal_proc.c b/lib/librte_eal/windows/eal/eal_proc.c
new file mode 100644
index 000000000..773bef46d
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal_proc.c
@@ -0,0 +1,1003 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2016-2018 Intel Corporation
+ */
+
+#include <winsock2.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <Intsafe.h>
+#include <unistd.h>
+
+#include <rte_alarm.h>
+#include <rte_common.h>
+#include <rte_cycles.h>
+#include <rte_eal.h>
+#include <rte_errno.h>
+#include <rte_lcore.h>
+#include <rte_log.h>
+#include <rte_tailq.h>
+
+#include "eal_private.h"
+#include "eal_filesystem.h"
+#include "eal_internal_cfg.h"
+
+static SOCKET mp_fd = INVALID_SOCKET;
+static char mp_filter[PATH_MAX];   /* Filter for secondary process sockets */
+static char mp_dir_path[PATH_MAX]; /* The directory path for all mp sockets */
+static INIT_ONCE initOnce_Lock = INIT_ONCE_STATIC_INIT;
+static INIT_ONCE initOnce_mp_mutex_action = INIT_ONCE_STATIC_INIT;
+static pthread_mutex_t mp_mutex_action;
+
+struct action_entry {
+	TAILQ_ENTRY(action_entry) next;
+	char action_name[RTE_MP_MAX_NAME_LEN];
+	rte_mp_t action;
+};
+
+/** Double linked list of actions. */
+TAILQ_HEAD(action_entry_list, action_entry);
+
+static struct action_entry_list action_entry_list =
+	TAILQ_HEAD_INITIALIZER(action_entry_list);
+
+enum mp_type {
+	MP_MSG, /* Share message with peers, will not block */
+	MP_REQ, /* Request for information, Will block for a reply */
+	MP_REP, /* Response to previously-received request */
+	MP_IGN, /* Response telling requester to ignore this response */
+};
+
+struct mp_msg_internal {
+	int type;
+	struct rte_mp_msg msg;
+};
+
+struct async_request_param {
+	rte_mp_async_reply_t clb;
+	struct rte_mp_reply user_reply;
+	struct timespec end;
+	int n_responses_processed;
+};
+
+struct pending_request {
+	TAILQ_ENTRY(pending_request) next;
+	enum {
+		REQUEST_TYPE_SYNC,
+		REQUEST_TYPE_ASYNC
+	} type;
+	char dst[PATH_MAX];
+	struct rte_mp_msg *request;
+	struct rte_mp_msg *reply;
+	int reply_received;
+	RTE_STD_C11
+	union {
+		struct {
+			struct async_request_param *param;
+		} async;
+		struct {
+			CONDITION_VARIABLE cond;
+		} sync;
+	};
+};
+
+TAILQ_HEAD(pending_request_list, pending_request);
+
+static struct {
+	struct pending_request_list requests;
+	HANDLE  lock;
+} pending_requests = {
+	.requests = TAILQ_HEAD_INITIALIZER(pending_requests.requests)/*,
+	.lock = NULL*/
+	/**< used in async requests only */
+};
+
+/* forward declarations */
+static int
+mp_send(struct rte_mp_msg *msg, const char *peer, int type);
+
+/* for use with alarm callback */
+static void
+async_reply_handle(void *arg);
+
+/* for use with process_msg */
+static struct pending_request *
+async_reply_handle_thread_unsafe(void *arg);
+
+static void
+trigger_async_action(struct pending_request *req);
+
+static struct pending_request *
+find_pending_request(const char *dst, const char *act_name)
+{
+	struct pending_request *r;
+
+	TAILQ_FOREACH(r, &pending_requests.requests, next) {
+		if (!strcmp(r->dst, dst) &&
+		    !strcmp(r->request->name, act_name))
+			break;
+	}
+
+	return r;
+}
+
+static void
+create_socket_path(const char *name, char *buf, int len)
+{
+	const char *prefix = eal_mp_socket_path();
+
+	if (strlen(name) > 0)
+		snprintf(buf, len, "%s_%s", prefix, name);
+	else
+		strlcpy(buf, prefix, len);
+}
+
+int
+rte_eal_primary_proc_alive(const char *config_file_path)
+{
+	int config_fd;
+
+	if (config_file_path)
+		config_fd = _open(config_file_path, O_RDONLY);
+	else {
+		const char *path;
+
+		path = eal_runtime_config_path();
+		config_fd = open(path, O_RDONLY);
+	}
+	if (config_fd < 0)
+		return 0;
+
+	int ret = 0;
+	/*lockf(config_fd, F_TEST, 0);*/
+	_close(config_fd);
+
+	return !!ret;
+}
+
+static struct action_entry *
+find_action_entry_by_name(const char *name)
+{
+	struct action_entry *entry;
+
+	TAILQ_FOREACH(entry, &action_entry_list, next) {
+		if (strncmp(entry->action_name, name, RTE_MP_MAX_NAME_LEN) == 0)
+			break;
+	}
+
+	return entry;
+}
+
+static int
+validate_action_name(const char *name)
+{
+	if (name == NULL) {
+		RTE_LOG(ERR, EAL, "Action name cannot be NULL\n");
+		rte_errno = EINVAL;
+		return -1;
+	}
+	if (strnlen(name, RTE_MP_MAX_NAME_LEN) == 0) {
+		RTE_LOG(ERR, EAL, "Length of action name is zero\n");
+		rte_errno = EINVAL;
+		return -1;
+	}
+	if (strnlen(name, RTE_MP_MAX_NAME_LEN) == RTE_MP_MAX_NAME_LEN) {
+		rte_errno = E2BIG;
+		return -1;
+	}
+	return 0;
+}
+
+int __rte_experimental
+rte_mp_action_register(const char *name, rte_mp_t action)
+{
+	struct action_entry *entry;
+
+	if (validate_action_name(name))
+		return -1;
+
+	entry = malloc(sizeof(struct action_entry));
+	if (entry == NULL) {
+		rte_errno = ENOMEM;
+		return -1;
+	}
+	strlcpy(entry->action_name, name, sizeof(entry->action_name));
+	entry->action = action;
+
+	pthread_mutex_lock(mp_mutex_action);
+	if (find_action_entry_by_name(name) != NULL) {
+		pthread_mutex_unlock(mp_mutex_action);
+		rte_errno = EEXIST;
+		free(entry);
+		return -1;
+	}
+	TAILQ_INSERT_TAIL(&action_entry_list, entry, next);
+	pthread_mutex_unlock(mp_mutex_action);
+	return 0;
+}
+
+void __rte_experimental
+rte_mp_action_unregister(const char *name)
+{
+	struct action_entry *entry;
+
+	if (validate_action_name(name))
+		return;
+
+	pthread_mutex_lock(mp_mutex_action);
+	entry = find_action_entry_by_name(name);
+	if (entry == NULL) {
+		pthread_mutex_unlock(mp_mutex_action);
+		return;
+	}
+	TAILQ_REMOVE(&action_entry_list, entry, next);
+	pthread_mutex_unlock(mp_mutex_action);
+	free(entry);
+}
+
+static int
+read_msg(struct mp_msg_internal *m, struct sockaddr *s)
+{
+	/* Multiple process workflow is not supported in windows implemention*/
+	return 0;
+}
+
+static void
+process_msg(struct mp_msg_internal *m, struct sockaddr_in *s)
+{
+	struct pending_request *pending_req;
+	struct action_entry *entry;
+	struct rte_mp_msg *msg = &m->msg;
+	rte_mp_t action = NULL;
+
+	RTE_LOG(DEBUG, EAL, "msg: %s\n", msg->name);
+
+	if (m->type == MP_REP || m->type == MP_IGN) {
+		struct pending_request *req = NULL;
+
+		pthread_mutex_lock(pending_requests.lock);
+		pending_req = find_pending_request(s->sun_path, msg->name);
+		if (pending_req) {
+			memcpy(pending_req->reply, msg, sizeof(*msg));
+			/* -1 indicates that we've been asked to ignore */
+			pending_req->reply_received =
+				m->type == MP_REP ? 1 : -1;
+
+			if (pending_req->type == REQUEST_TYPE_SYNC)
+				pthread_cond_signal(&pending_req->sync.cond);
+			else if (pending_req->type == REQUEST_TYPE_ASYNC)
+				req = async_reply_handle_thread_unsafe(
+						pending_req);
+		} else
+			RTE_LOG(ERR, EAL, "Drop mp reply: %s\n", msg->name);
+		pthread_mutex_unlock(pending_requests.lock);
+
+		if (req != NULL)
+			trigger_async_action(req);
+		return;
+	}
+
+	pthread_mutex_lock(mp_mutex_action);
+	entry = find_action_entry_by_name(msg->name);
+	if (entry != NULL)
+		action = entry->action;
+	pthread_mutex_unlock(mp_mutex_action);
+
+	if (!action) {
+		if (m->type == MP_REQ && !internal_config.init_complete) {
+			/* if this is a request, and init is not yet complete,
+			 * and callback wasn't registered, we should tell the
+			 * requester to ignore our existence because we're not
+			 * yet ready to process this request.
+			 */
+			struct rte_mp_msg dummy;
+
+			memset(&dummy, 0, sizeof(dummy));
+			strlcpy(dummy.name, msg->name, sizeof(dummy.name));
+			/*mp_send(&dummy, s->sun_path, MP_IGN);*/
+		} else {
+			RTE_LOG(ERR, EAL, "Cannot find action: %s\n",
+				msg->name);
+		}
+	} /*else if (action(msg, s->sun_path) < 0) {
+		RTE_LOG(ERR, EAL, "Fail to handle message: %s\n", msg->name);
+	}*/
+}
+
+static void *
+mp_handle(void *arg __rte_unused)
+{
+	struct mp_msg_internal msg;
+	struct sockaddr sa;
+
+	while (1) {
+		if (read_msg(&msg, &sa) == 0)
+			process_msg(&msg, &sa);
+	}
+
+	return NULL;
+}
+
+static int
+timespec_cmp(const struct timespec *a, const struct timespec *b)
+{
+	if (a->tv_sec < b->tv_sec)
+		return -1;
+	if (a->tv_sec > b->tv_sec)
+		return 1;
+	if (a->tv_nsec < b->tv_nsec)
+		return -1;
+	if (a->tv_nsec > b->tv_nsec)
+		return 1;
+	return 0;
+}
+
+enum async_action {
+	ACTION_FREE, /**< free the action entry, but don't trigger callback */
+	ACTION_TRIGGER /**< trigger callback, then free action entry */
+};
+
+static enum async_action
+process_async_request(struct pending_request *sr, const struct timespec *now)
+{
+	struct async_request_param *param;
+	struct rte_mp_reply *reply;
+	bool timeout, last_msg;
+
+	param = sr->async.param;
+	reply = &param->user_reply;
+
+	/* did we timeout? */
+	timeout = timespec_cmp(&param->end, now) <= 0;
+
+	/* if we received a response, adjust relevant data and copy mesasge. */
+	if (sr->reply_received == 1 && sr->reply) {
+		struct rte_mp_msg *msg, *user_msgs, *tmp;
+
+		msg = sr->reply;
+		user_msgs = reply->msgs;
+
+		tmp = realloc(user_msgs, sizeof(*msg) *
+				(reply->nb_received + 1));
+		if (!tmp) {
+			RTE_LOG(ERR, EAL, "Fail to alloc reply for request %s:%s\n",
+				sr->dst, sr->request->name);
+			/* this entry is going to be removed and its message
+			 * dropped, but we don't want to leak memory, so
+			 * continue.
+			 */
+		} else {
+			user_msgs = tmp;
+			reply->msgs = user_msgs;
+			memcpy(&user_msgs[reply->nb_received],
+					msg, sizeof(*msg));
+			reply->nb_received++;
+		}
+
+		/* mark this request as processed */
+		param->n_responses_processed++;
+	} else if (sr->reply_received == -1) {
+		/* we were asked to ignore this process */
+		reply->nb_sent--;
+	} else if (timeout) {
+		/* count it as processed response, but don't increment
+		 * nb_received.
+		 */
+		param->n_responses_processed++;
+	}
+
+	free(sr->reply);
+
+	last_msg = param->n_responses_processed == reply->nb_sent;
+
+	return last_msg ? ACTION_TRIGGER : ACTION_FREE;
+}
+
+static void
+trigger_async_action(struct pending_request *sr)
+{
+	struct async_request_param *param;
+	struct rte_mp_reply *reply;
+
+	param = sr->async.param;
+	reply = &param->user_reply;
+
+	param->clb(sr->request, reply);
+
+	/* clean up */
+	free(sr->async.param->user_reply.msgs);
+	free(sr->async.param);
+	free(sr->request);
+	free(sr);
+}
+
+static struct pending_request *
+async_reply_handle_thread_unsafe(void *arg)
+{
+	struct pending_request *req = (struct pending_request *)arg;
+	enum async_action action;
+	struct timespec ts_now;
+
+	ts_now.tv_nsec = 0;
+	ts_now.tv_sec = 0;
+
+	action = process_async_request(req, &ts_now);
+
+	TAILQ_REMOVE(&pending_requests.requests, req, next);
+
+	if (rte_eal_alarm_cancel(async_reply_handle, req) < 0) {
+		/* if we failed to cancel the alarm because it's already in
+		 * progress, don't proceed because otherwise we will end up
+		 * handling the same message twice.
+		 */
+		if (rte_errno == EINPROGRESS) {
+			RTE_LOG(DEBUG, EAL, "Request handling is already in progress\n");
+			goto no_trigger;
+		}
+		RTE_LOG(ERR, EAL, "Failed to cancel alarm\n");
+	}
+
+	if (action == ACTION_TRIGGER)
+		return req;
+no_trigger:
+	free(req);
+	return NULL;
+}
+
+static void
+async_reply_handle(void *arg)
+{
+	struct pending_request *req;
+
+	pending_requests.lock = WinCreateAndLockStaticMutex(pending_requests.lock, &initOnce_Lock);
+	req = async_reply_handle_thread_unsafe(arg);
+	ReleaseMutex(pending_requests.lock);
+
+	if (req != NULL)
+		trigger_async_action(req);
+}
+
+static int
+open_socket_fd(void)
+{
+	char peer_name[PATH_MAX] = {0};
+	struct sockaddr_in un;
+
+	if (rte_eal_process_type() == RTE_PROC_SECONDARY)
+		snprintf(peer_name, sizeof(peer_name),
+				"%d_%"PRIx64, _getpid(), rte_rdtsc());
+
+	mp_fd = socket(AF_UNIX, SOCK_DGRAM, 0);
+	if (mp_fd < 0) {
+		RTE_LOG(ERR, EAL, "failed to create unix socket\n");
+		return -1;
+	}
+
+	memset(&un, 0, sizeof(un));
+	un.sin_family = AF_UNIX;
+
+	create_socket_path(peer_name, un.sin_path, sizeof(un.sin_path));
+
+	unlink(un.sun_path); /* May still exist since last run */
+
+	if (bind(mp_fd, (struct sockaddr *)&un, sizeof(un)) < 0) {
+		RTE_LOG(ERR, EAL, "failed to bind %s: %s\n",
+			un.sun_path, strerror(errno));
+		close(mp_fd);
+		return -1;
+	}
+
+	RTE_LOG(INFO, EAL, "Multi-process socket %u\n", un.sin_port);
+	return mp_fd;
+}
+
+static int
+unlink_sockets(const char *filter)
+{
+	int dir_fd;
+	DIR *mp_dir;
+	struct dirent *ent;
+
+	mp_dir = opendir(mp_dir_path);
+	if (!mp_dir) {
+		RTE_LOG(ERR, EAL, "Unable to open directory %s\n", mp_dir_path);
+		return -1;
+	}
+	dir_fd = dirfd(mp_dir);
+
+	while ((ent = readdir(mp_dir))) {
+		if (fnmatch(filter, ent->d_name, 0) == 0)
+			unlinkat(dir_fd, ent->d_name, 0);
+	}
+
+	closedir(mp_dir);
+	return 0;
+}
+
+int
+rte_mp_channel_init(void)
+{
+	char path[PATH_MAX];
+	int dir_fd = -1;
+	pthread_t mp_handle_tid;
+
+	/* in no shared files mode, we do not have secondary processes support,
+	 * so no need to initialize IPC.
+	 */
+	if (internal_config.no_shconf) {
+		RTE_LOG(DEBUG, EAL, "No shared files mode enabled, IPC will be disabled\n");
+		return 0;
+	}
+
+	/* create filter path */
+	create_socket_path("*", path, sizeof(path));
+	strlcpy(mp_filter, basename(path), sizeof(mp_filter));
+
+	/* path may have been modified, so recreate it */
+	create_socket_path("*", path, sizeof(path));
+	strlcpy(mp_dir_path, dirname(path), sizeof(mp_dir_path));
+
+	/* TODO dpdk-1808 open mp_dir_path in O_RDONLY the directory */
+
+	/* TODO dpdk-1808 lock the mp_dir_path directory with exculsive lock */
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY &&
+			unlink_sockets(mp_filter)) {
+		RTE_LOG(ERR, EAL, "failed to unlink mp sockets\n");
+		close(dir_fd);
+		return -1;
+	}
+
+	if (open_socket_fd() < 0) {
+		close(dir_fd);
+		return -1;
+	}
+
+	if (rte_ctrl_thread_create(&mp_handle_tid, "rte_mp_handle",
+			NULL, mp_handle, NULL) < 0) {
+		RTE_LOG(ERR, EAL, "failed to create mp thead: %s\n",
+			strerror(errno));
+		close(mp_fd);
+		close(dir_fd);
+		mp_fd = -1;
+		return -1;
+	}
+
+	/* TODO dpdk-1808 unlock and close the mp_dir_path directory */
+
+	return 0;
+}
+
+/**
+ * Return -1, as fail to send message and it's caused by the local side.
+ * Return 0, as fail to send message and it's caused by the remote side.
+ * Return 1, as succeed to send message.
+ *
+ */
+static int
+send_msg(const char *dst_path, struct rte_mp_msg *msg, int type)
+{
+	/* Multiple process workflow is not supported in windows implemention*/
+
+	return 1;
+}
+
+static int
+mp_send(struct rte_mp_msg *msg, const char *peer, int type)
+{
+	int dir_fd, ret = 0;
+	DIR *mp_dir;
+	struct dirent *ent;
+
+	if (!peer && (rte_eal_process_type() == RTE_PROC_SECONDARY))
+		peer = eal_mp_socket_path();
+
+	if (peer) {
+		if (send_msg(peer, msg, type) < 0)
+			return -1;
+		else
+			return 0;
+	}
+
+	/* broadcast to all secondary processes */
+	mp_dir = opendir(mp_dir_path);
+	if (!mp_dir) {
+		RTE_LOG(ERR, EAL, "Unable to open directory %s\n",
+				mp_dir_path);
+		rte_errno = errno;
+		return -1;
+	}
+
+	/* TODO dpdk-1808 lock the directory to prevent processes spinning up while we send */
+
+
+	while ((ent = readdir(mp_dir))) {
+		char path[PATH_MAX];
+
+		/*if (fnmatch(mp_filter, ent->d_name, 0) != 0)
+			continue;*/
+
+		snprintf(path, sizeof(path), "%s/%s", mp_dir_path,
+			 ent->d_name);
+		if (send_msg(path, msg, type) < 0)
+			ret = -1;
+	}
+	/* TODO dpdk-1808 unlock the dir */
+
+	/* dir_fd automatically closed on closedir */
+	closedir(mp_dir);
+	return ret;
+}
+
+static bool
+check_input(const struct rte_mp_msg *msg)
+{
+	if (msg == NULL) {
+		RTE_LOG(ERR, EAL, "Msg cannot be NULL\n");
+		rte_errno = EINVAL;
+		return false;
+	}
+
+	if (validate_action_name(msg->name))
+		return false;
+
+	if (msg->len_param > RTE_MP_MAX_PARAM_LEN) {
+		RTE_LOG(ERR, EAL, "Message data is too long\n");
+		rte_errno = E2BIG;
+		return false;
+	}
+
+	if (msg->num_fds > RTE_MP_MAX_FD_NUM) {
+		RTE_LOG(ERR, EAL, "Cannot send more than %d FDs\n",
+			RTE_MP_MAX_FD_NUM);
+		rte_errno = E2BIG;
+		return false;
+	}
+
+	return true;
+}
+
+int __rte_experimental
+rte_mp_sendmsg(struct rte_mp_msg *msg)
+{
+	if (!check_input(msg))
+		return -1;
+
+	RTE_LOG(DEBUG, EAL, "sendmsg: %s\n", msg->name);
+	return mp_send(msg, NULL, MP_MSG);
+}
+
+static int
+mp_request_async(const char *dst, struct rte_mp_msg *req,
+		struct async_request_param *param, const struct timespec *ts)
+{
+	struct rte_mp_msg *reply_msg;
+	struct pending_request *pending_req, *exist;
+	int ret;
+
+	pending_req = calloc(1, sizeof(*pending_req));
+	reply_msg = calloc(1, sizeof(*reply_msg));
+	if (pending_req == NULL || reply_msg == NULL) {
+		RTE_LOG(ERR, EAL, "Could not allocate space for sync request\n");
+		rte_errno = ENOMEM;
+		ret = -1;
+		goto fail;
+	}
+
+	pending_req->type = REQUEST_TYPE_ASYNC;
+	strlcpy(pending_req->dst, dst, sizeof(pending_req->dst));
+	pending_req->request = req;
+	pending_req->reply = reply_msg;
+	pending_req->async.param = param;
+
+	/* queue already locked by caller */
+
+	exist = find_pending_request(dst, req->name);
+	if (exist) {
+		RTE_LOG(ERR, EAL, "A pending request %s:%s\n", dst, req->name);
+		rte_errno = EEXIST;
+		ret = -1;
+		goto fail;
+	}
+
+	ret = send_msg(dst, req, MP_REQ);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "Fail to send request %s:%s\n",
+			dst, req->name);
+		ret = -1;
+		goto fail;
+	} else if (ret == 0) {
+		ret = 0;
+		goto fail;
+	}
+	TAILQ_INSERT_TAIL(&pending_requests.requests, pending_req, next);
+
+	param->user_reply.nb_sent++;
+
+	if (rte_eal_alarm_set(ts->tv_sec * 1000000 + ts->tv_nsec / 1000,
+			      async_reply_handle, pending_req) < 0) {
+		RTE_LOG(ERR, EAL, "Fail to set alarm for request %s:%s\n",
+			dst, req->name);
+		rte_panic("Fix the above shit to properly free all memory\n");
+	}
+
+	return 0;
+fail:
+	free(pending_req);
+	free(reply_msg);
+	return ret;
+}
+
+static int
+mp_request_sync(const char *dst, struct rte_mp_msg *req,
+	       struct rte_mp_reply *reply, const struct timespec *ts)
+{
+	int ret;
+	struct rte_mp_msg msg, *tmp;
+	struct pending_request pending_req, *exist;
+
+	pending_req.type = REQUEST_TYPE_SYNC;
+	pending_req.reply_received = 0;
+	strlcpy(pending_req.dst, dst, sizeof(pending_req.dst));
+	pending_req.request = req;
+	pending_req.reply = &msg;
+	pthread_cond_init(&pending_req.sync.cond, NULL);
+
+	exist = find_pending_request(dst, req->name);
+	if (exist) {
+		RTE_LOG(ERR, EAL, "A pending request %s:%s\n", dst, req->name);
+		rte_errno = EEXIST;
+		return -1;
+	}
+
+	ret = send_msg(dst, req, MP_REQ);
+	if (ret < 0) {
+		RTE_LOG(ERR, EAL, "Fail to send request %s:%s\n",
+			dst, req->name);
+		return -1;
+	} else if (ret == 0)
+		return 0;
+
+	TAILQ_INSERT_TAIL(&pending_requests.requests, &pending_req, next);
+
+	reply->nb_sent++;
+
+	do {
+		ret = pthread_cond_timedwait(&pending_req.sync.cond,
+				&pending_requests.lock, ts);
+	} while (ret != 0 && ret != ETIMEDOUT);
+
+	TAILQ_REMOVE(&pending_requests.requests, &pending_req, next);
+
+	if (pending_req.reply_received == 0) {
+		RTE_LOG(ERR, EAL, "Fail to recv reply for request %s:%s\n",
+			dst, req->name);
+		rte_errno = ETIMEDOUT;
+		return -1;
+	}
+	if (pending_req.reply_received == -1) {
+		RTE_LOG(DEBUG, EAL, "Asked to ignore response\n");
+		/* not receiving this message is not an error, so decrement
+		 * number of sent messages
+		 */
+		reply->nb_sent--;
+		return 0;
+	}
+
+	tmp = realloc(reply->msgs, sizeof(msg) * (reply->nb_received + 1));
+	if (!tmp) {
+		RTE_LOG(ERR, EAL, "Fail to alloc reply for request %s:%s\n",
+			dst, req->name);
+		rte_errno = ENOMEM;
+		return -1;
+	}
+	memcpy(&tmp[reply->nb_received], &msg, sizeof(msg));
+	reply->msgs = tmp;
+	reply->nb_received++;
+	return 0;
+}
+
+int __rte_experimental
+rte_mp_request_sync(struct rte_mp_msg *req, struct rte_mp_reply *reply,
+		const struct timespec *ts)
+{
+	int dir_fd, ret = 0;
+	DIR *mp_dir;
+	struct dirent *ent;
+	struct timeval now;
+	struct timespec end;
+
+	RTE_LOG(DEBUG, EAL, "request: %s\n", req->name);
+
+	if (check_input(req) == false)
+		return -1;
+
+	if (internal_config.no_shconf) {
+		RTE_LOG(DEBUG, EAL, "No shared files mode enabled, IPC is disabled\n");
+		return 0;
+	}
+
+
+	end.tv_nsec =ts->tv_nsec % 1000000000;
+	end.tv_sec = ts->tv_sec +
+			(ts->tv_nsec / 1000000000);
+
+	reply->nb_sent = 0;
+	reply->nb_received = 0;
+	reply->msgs = NULL;
+
+	/* for secondary process, send request to the primary process only */
+	if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
+		pthread_mutex_lock(&pending_requests.lock);
+		ret = mp_request_sync(eal_mp_socket_path(), req, reply, &end);
+		pthread_mutex_unlock(pending_requests.lock);
+		return ret;
+	}
+
+
+	return ret;
+}
+
+int __rte_experimental
+rte_mp_request_async(struct rte_mp_msg *req, const struct timespec *ts,
+		rte_mp_async_reply_t clb)
+{
+	struct rte_mp_msg *copy;
+	struct pending_request *dummy;
+	struct async_request_param *param;
+	struct rte_mp_reply *reply;
+	int dir_fd, ret = 0;
+	DIR *mp_dir;
+	struct dirent *ent;
+	/*struct timeval now;*/
+	struct timespec *end;
+	bool dummy_used = false;
+
+	RTE_LOG(DEBUG, EAL, "request: %s\n", req->name);
+
+	if (check_input(req) == false)
+		return -1;
+
+	if (internal_config.no_shconf) {
+		RTE_LOG(DEBUG, EAL, "No shared files mode enabled, IPC is disabled\n");
+		return 0;
+	}
+
+	copy = calloc(1, sizeof(*copy));
+	dummy = calloc(1, sizeof(*dummy));
+	param = calloc(1, sizeof(*param));
+	if (copy == NULL || dummy == NULL || param == NULL) {
+		RTE_LOG(ERR, EAL, "Failed to allocate memory for async reply\n");
+		rte_errno = ENOMEM;
+		goto fail;
+	}
+
+	/* copy message */
+	memcpy(copy, req, sizeof(*copy));
+
+	param->n_responses_processed = 0;
+	param->clb = clb;
+	/*end = &param->end;*/
+	reply = &param->user_reply;
+
+	reply->nb_sent = 0;
+	reply->nb_received = 0;
+	reply->msgs = NULL;
+
+	/* we have to lock the request queue here, as we will be adding a bunch
+	 * of requests to the queue at once, and some of the replies may arrive
+	 * before we add all of the requests to the queue.
+	 */
+	pending_requests.lock = WinCreateAndLockStaticMutex(pending_requests.lock,&initOnce_Lock);
+
+	/* we have to ensure that callback gets triggered even if we don't send
+	 * anything, therefore earlier we have allocated a dummy request. fill
+	 * it, and put it on the queue if we don't send any requests.
+	 */
+	dummy->type = REQUEST_TYPE_ASYNC;
+	dummy->request = copy;
+	dummy->reply = NULL;
+	dummy->async.param = param;
+	dummy->reply_received = 1; /* short-circuit the timeout */
+
+	/* for secondary process, send request to the primary process only */
+	if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
+		ret = mp_request_async(eal_mp_socket_path(), copy, param, ts);
+
+		/* if we didn't send anything, put dummy request on the queue */
+		if (ret == 0 && reply->nb_sent == 0) {
+			TAILQ_INSERT_TAIL(&pending_requests.requests, dummy,
+					next);
+			dummy_used = true;
+		}
+
+		ReleaseMutex(pending_requests.lock);
+
+		/* if we couldn't send anything, clean up */
+		if (ret != 0)
+			goto fail;
+		return 0;
+	}
+
+	/* for primary process, broadcast request */
+	mp_dir = opendir(mp_dir_path);
+	if (!mp_dir) {
+		RTE_LOG(ERR, EAL, "Unable to open directory %s\n", mp_dir_path);
+		rte_errno = errno;
+		goto unlock_fail;
+	}
+	dir_fd = dirfd(mp_dir);
+	/* TODO dpdk-1808 blocking writelock */
+
+	/* TODO dpdk-1808 lock the directory to prevent processes spinning up while we send */
+
+	while ((ent = readdir(mp_dir))) {
+		char path[PATH_MAX];
+
+		if (fnmatch(mp_filter, ent->d_name, 0) != 0)
+			continue;
+
+		snprintf(path, sizeof(path), "%s/%s", mp_dir_path,
+			 ent->d_name);
+
+		if (mp_request_async(path, copy, param, ts))
+			ret = -1;
+	}
+	/* if we didn't send anything, put dummy request on the queue */
+	if (ret == 0 && reply->nb_sent == 0) {
+		TAILQ_INSERT_HEAD(&pending_requests.requests, dummy, next);
+		dummy_used = true;
+	}
+
+	/* finally, unlock the queue */
+	ReleaseMutex(pending_requests.lock);
+
+	/* TODO dpdk-1808 unlock the directory */
+
+	/* dir_fd automatically closed on closedir */
+	closedir(mp_dir);
+
+	/* if dummy was unused, free it */
+	if (!dummy_used)
+		free(dummy);
+
+	return ret;
+closedir_fail:
+	closedir(mp_dir);
+unlock_fail:
+	ReleaseMutex(pending_requests.lock);
+fail:
+	free(dummy);
+	free(param);
+	free(copy);
+	return -1;
+}
+
+int __rte_experimental
+rte_mp_reply(struct rte_mp_msg *msg, const char *peer)
+{
+	RTE_LOG(DEBUG, EAL, "reply: %s\n", msg->name);
+
+	if (check_input(msg) == false)
+		return -1;
+
+	if (peer == NULL) {
+		RTE_LOG(ERR, EAL, "peer is not specified\n");
+		rte_errno = EINVAL;
+		return -1;
+	}
+
+	if (internal_config.no_shconf) {
+		RTE_LOG(DEBUG, EAL, "No shared files mode enabled, IPC is disabled\n");
+		return 0;
+	}
+
+	return mp_send(msg, peer, MP_REP);
+}
diff --git a/lib/librte_eal/windows/eal/eal_thread.c b/lib/librte_eal/windows/eal/eal_thread.c
new file mode 100644
index 000000000..1a82eb4a2
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal_thread.c
@@ -0,0 +1,167 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#include <unistd.h>
+
+#include <rte_debug.h>
+#include <rte_atomic.h>
+#include <rte_log.h>
+#include <rte_memzone.h>
+#include <rte_per_lcore.h>
+
+#include "eal_private.h"
+#include "eal_thread.h"
+
+RTE_DEFINE_PER_LCORE(unsigned, _lcore_id) = LCORE_ID_ANY;
+RTE_DEFINE_PER_LCORE(unsigned, _socket_id) = (unsigned)SOCKET_ID_ANY;
+RTE_DEFINE_PER_LCORE(rte_cpuset_t, _cpuset);
+
+/*
+ * Send a message to a slave lcore identified by slave_id to call a
+ * function f with argument arg. Once the execution is done, the
+ * remote lcore switch in FINISHED state.
+ */
+int
+rte_eal_remote_launch(int (*f)(void *), void *arg, unsigned slave_id)
+{
+	int n;
+	char c = 0;
+	int m2s = lcore_config[slave_id].pipe_master2slave[1];
+	int s2m = lcore_config[slave_id].pipe_slave2master[0];
+
+	if (lcore_config[slave_id].state != WAIT)
+		return -EBUSY;
+
+	lcore_config[slave_id].f = f;
+	lcore_config[slave_id].arg = arg;
+
+	/* send message */
+	n = 0;
+	while (n == 0 || (n < 0 && errno == EINTR))
+		n = write(m2s, &c, 1);
+	if (n < 0)
+		rte_panic("cannot write on configuration pipe\n");
+
+	/* wait ack */
+	do {
+		n = read(s2m, &c, 1);
+	} while (n < 0 && errno == EINTR);
+
+	if (n <= 0)
+		rte_panic("cannot read on configuration pipe\n");
+
+	return 0;
+}
+
+/* set affinity for current EAL thread */
+static int
+eal_thread_set_affinity(void)
+{
+	unsigned lcore_id = rte_lcore_id();
+
+	/* acquire system unique id  */
+	rte_gettid();
+
+	/* update EAL thread core affinity */
+	return rte_thread_set_affinity(&lcore_config[lcore_id].cpuset);
+}
+
+void eal_thread_init_master(unsigned lcore_id)
+{
+	/* set the lcore ID in per-lcore memory area */
+	RTE_PER_LCORE(_lcore_id) = lcore_id;
+
+	/* set CPU affinity */
+	if (eal_thread_set_affinity() < 0)
+		rte_panic("cannot set affinity\n");
+}
+
+/* main loop of threads */
+void *
+eal_thread_loop(void *arg)
+{
+	char c;
+	int n, ret;
+	unsigned lcore_id;
+	pthread_t thread_id;
+	int m2s, s2m;
+	char cpuset[RTE_CPU_AFFINITY_STR_LEN];
+
+	memset((void *)cpuset, 0, sizeof(cpuset));
+
+	thread_id = pthread_self();
+
+	/* retrieve our lcore_id from the configuration structure */
+	RTE_LCORE_FOREACH_SLAVE(lcore_id) {
+		if (thread_id == lcore_config[lcore_id].thread_id)
+			break;
+	}
+	if (lcore_id == RTE_MAX_LCORE)
+		rte_panic("cannot retrieve lcore id\n");
+
+	m2s = lcore_config[lcore_id].pipe_master2slave[0];
+	s2m = lcore_config[lcore_id].pipe_slave2master[1];
+
+	/* set the lcore ID in per-lcore memory area */
+	RTE_PER_LCORE(_lcore_id) = lcore_id;
+
+	/* set CPU affinity */
+	if (eal_thread_set_affinity() < 0)
+		rte_panic("cannot set affinity\n");
+
+	ret = eal_thread_dump_affinity(cpuset, RTE_CPU_AFFINITY_STR_LEN);
+
+	RTE_LOG(DEBUG, EAL, "lcore %u is ready (tid=%x;cpuset=[%s%s])\n",
+		lcore_id, (int)thread_id, cpuset, ret == 0 ? "" : "...");
+
+	/* read on our pipe to get commands */
+	while (1) {
+		void *fct_arg;
+
+		/* wait command */
+		do {
+			n = read(m2s, &c, 1);
+		} while (n < 0 && errno == EINTR);
+
+		if (n <= 0)
+			rte_panic("cannot read on configuration pipe\n");
+
+		lcore_config[lcore_id].state = RUNNING;
+
+		/* send ack */
+		n = 0;
+		while (n == 0 || (n < 0 && errno == EINTR))
+			n = write(s2m, &c, 1);
+		if (n < 0)
+			rte_panic("cannot write on configuration pipe\n");
+
+		if (lcore_config[lcore_id].f == NULL)
+			rte_panic("NULL function pointer\n");
+
+		/* call the function and store the return value */
+		fct_arg = lcore_config[lcore_id].arg;
+		ret = lcore_config[lcore_id].f(fct_arg);
+		lcore_config[lcore_id].ret = ret;
+		rte_wmb();
+		lcore_config[lcore_id].state = FINISHED;
+	}
+
+	/* never reached */
+	/* pthread_exit(NULL); */
+	/* return NULL; */
+}
+
+/* require calling thread tid by gettid() */
+int rte_sys_gettid(void)
+{
+	return 0; // (int)syscall(SYS_gettid);
+}
+
+int rte_thread_setname(pthread_t id, const char *name)
+{
+	int ret = 0;
+	RTE_SET_USED(id);
+	RTE_SET_USED(name);
+	return -ret;
+}
\ No newline at end of file
diff --git a/lib/librte_eal/windows/eal/eal_timer.c b/lib/librte_eal/windows/eal/eal_timer.c
new file mode 100644
index 000000000..3bf57b053
--- /dev/null
+++ b/lib/librte_eal/windows/eal/eal_timer.c
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#include <rte_windows.h>
+
+#include <rte_cycles.h>
+
+#include "eal_private.h"
+
+enum timer_source eal_timer_source;
+
+uint64_t
+get_tsc_freq_arch(void)
+{
+	/* This function is not supported on Windows */
+	return 0;
+}
+
+uint64_t
+get_tsc_freq(void)
+{
+	uint64_t tsc_freq;
+	LARGE_INTEGER Frequency;
+
+	QueryPerformanceFrequency(&Frequency);
+	/* mulitply by 1K to obtain the true frequency of the CPU */
+	tsc_freq = ((uint64_t)Frequency.QuadPart * 1024);
+
+	return tsc_freq;
+}
+
+int
+rte_eal_timer_init(void)
+{
+	eal_timer_source = EAL_TIMER_TSC;
+
+	set_tsc_freq();
+	return 0;
+}
diff --git a/lib/librte_eal/windows/eal/linux-emu/_rand48.c b/lib/librte_eal/windows/eal/linux-emu/_rand48.c
new file mode 100644
index 000000000..1694c19e1
--- /dev/null
+++ b/lib/librte_eal/windows/eal/linux-emu/_rand48.c
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 1993 Martin Birgmeier
+* All rights reserved.
+*
+* You may redistribute unmodified or modified versions of this source
+* code provided that the above copyright notice and this and the
+* following conditions are retained.
+*
+* This software is provided ``as is'', and comes with no warranties
+* of any kind. I shall in no event be liable for anything that happens
+* to anyone/anything when using this software.
+*/
+
+#include "rand48.h"
+
+unsigned short _rand48_seed[3] = {
+	RAND48_SEED_0,
+	RAND48_SEED_1,
+	RAND48_SEED_2
+};
+unsigned short _rand48_mult[3] = {
+	RAND48_MULT_0,
+	RAND48_MULT_1,
+	RAND48_MULT_2
+};
+unsigned short _rand48_add = RAND48_ADD;
+
+void
+_dorand48(unsigned short xseed[3])
+{
+	unsigned long accu;
+	unsigned short temp[2];
+
+	accu = (unsigned long)_rand48_mult[0] * (unsigned long)xseed[0] +
+		(unsigned long)_rand48_add;
+	temp[0] = (unsigned short)accu;	/* lower 16 bits */
+	accu >>= sizeof(unsigned short) * 8;
+	accu += (unsigned long)_rand48_mult[0] * (unsigned long)xseed[1] +
+		(unsigned long)_rand48_mult[1] * (unsigned long)xseed[0];
+	temp[1] = (unsigned short)accu;	/* middle 16 bits */
+	accu >>= sizeof(unsigned short) * 8;
+	accu += _rand48_mult[0] * xseed[2] + _rand48_mult[1] * xseed[1] + _rand48_mult[2] * xseed[0];
+	xseed[0] = temp[0];
+	xseed[1] = temp[1];
+	xseed[2] = (unsigned short)accu;
+}
diff --git a/lib/librte_eal/windows/eal/linux-emu/drand48.c b/lib/librte_eal/windows/eal/linux-emu/drand48.c
new file mode 100644
index 000000000..fec311d3a
--- /dev/null
+++ b/lib/librte_eal/windows/eal/linux-emu/drand48.c
@@ -0,0 +1,62 @@
+
+#define RAND48_SEED_0   (0x330e)
+#define RAND48_SEED_1 (0xabcd)
+#define RAND48_SEED_2 (0x1234)
+#define RAND48_MULT_0 (0xe66d)
+#define RAND48_MULT_1 (0xdeec)
+#define RAND48_MULT_2 (0x0005)
+#define RAND48_ADD (0x000b)
+
+unsigned short _rand48_seed[3] = {
+	RAND48_SEED_0,
+	RAND48_SEED_1,
+	RAND48_SEED_2
+};
+unsigned short _rand48_mult[3] = {
+	RAND48_MULT_0,
+	RAND48_MULT_1,
+	RAND48_MULT_2
+};
+unsigned short _rand48_add = RAND48_ADD;
+
+void
+_dorand48(unsigned short xseed[3])
+{
+	unsigned long accu;
+	unsigned short temp[2];
+
+	accu = (unsigned long)_rand48_mult[0] * (unsigned long)xseed[0] +
+		(unsigned long)_rand48_add;
+	temp[0] = (unsigned short)accu;        /* lower 16 bits */
+	accu >>= sizeof(unsigned short) * 8;
+	accu += (unsigned long)_rand48_mult[0] * (unsigned long)xseed[1] +
+		(unsigned long)_rand48_mult[1] * (unsigned long)xseed[0];
+	temp[1] = (unsigned short)accu;        /* middle 16 bits */
+	accu >>= sizeof(unsigned short) * 8;
+	accu += _rand48_mult[0] * xseed[2] + _rand48_mult[1] * xseed[1] + _rand48_mult[2] * xseed[0];
+	xseed[0] = temp[0];
+	xseed[1] = temp[1];
+	xseed[2] = (unsigned short)accu;
+}
+
+double erand48(unsigned short xseed[3])
+{
+	_dorand48(xseed);
+	return ldexp((double)xseed[0], -48) +
+		ldexp((double)xseed[1], -32) +
+		ldexp((double)xseed[2], -16);
+}
+
+double drand48() {
+	return erand48(_rand48_seed);
+}
+
+void srand48(long seed) {
+	_rand48_seed[0] = RAND48_SEED_0;
+	_rand48_seed[1] = (unsigned short)seed;
+	_rand48_seed[2] = (unsigned short)(seed >> 16);
+	_rand48_mult[0] = RAND48_MULT_0;
+	_rand48_mult[1] = RAND48_MULT_1;
+	_rand48_mult[2] = RAND48_MULT_2;
+	_rand48_add = RAND48_ADD;
+}
diff --git a/lib/librte_eal/windows/eal/linux-emu/fork.c b/lib/librte_eal/windows/eal/linux-emu/fork.c
new file mode 100644
index 000000000..55bd96087
--- /dev/null
+++ b/lib/librte_eal/windows/eal/linux-emu/fork.c
@@ -0,0 +1,111 @@
+/*
+* fork.c
+* Experimental fork() on Windows.  Requires NT 6 subsystem or
+* newer.
+*
+* Copyright (c) 2012 William Pitcock <nenolod@dereferenced.org>
+*
+* Permission to use, copy, modify, and/or distribute this software for any
+* purpose with or without fee is hereby granted, provided that the above
+* copyright notice and this permission notice appear in all copies.
+*
+* This software is provided 'as is' and without any warranty, express or
+* implied.  In no event shall the authors be liable for any damages arising
+* from the use of this software.
+*/
+
+//#define _WIN32_WINNT 0x0600
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <winnt.h>
+#include <winternl.h>
+#include <stdio.h>
+#include <errno.h>
+#include <assert.h>
+#include <process.h>
+
+typedef struct _SECTION_IMAGE_INFORMATION {
+	PVOID EntryPoint;
+	ULONG StackZeroBits;
+	ULONG StackReserved;
+	ULONG StackCommit;
+	ULONG ImageSubsystem;
+	WORD SubSystemVersionLow;
+	WORD SubSystemVersionHigh;
+	ULONG Unknown1;
+	ULONG ImageCharacteristics;
+	ULONG ImageMachineType;
+	ULONG Unknown2[3];
+} SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION;
+
+typedef struct _RTL_USER_PROCESS_INFORMATION {
+	ULONG Size;
+	HANDLE Process;
+	HANDLE Thread;
+	CLIENT_ID ClientId;
+	SECTION_IMAGE_INFORMATION ImageInformation;
+} RTL_USER_PROCESS_INFORMATION, *PRTL_USER_PROCESS_INFORMATION;
+
+#define RTL_CLONE_PROCESS_FLAGS_CREATE_SUSPENDED	0x00000001
+#define RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES		0x00000002
+#define RTL_CLONE_PROCESS_FLAGS_NO_SYNCHRONIZE		0x00000004
+
+#define RTL_CLONE_PARENT				0
+#define RTL_CLONE_CHILD					297
+
+typedef DWORD pid_t;
+
+typedef NTSTATUS(*RtlCloneUserProcess_f)(ULONG ProcessFlags,
+	PSECURITY_DESCRIPTOR ProcessSecurityDescriptor /* optional */,
+	PSECURITY_DESCRIPTOR ThreadSecurityDescriptor /* optional */,
+	HANDLE DebugPort /* optional */,
+	PRTL_USER_PROCESS_INFORMATION ProcessInformation);
+
+pid_t fork(void)
+{
+	HMODULE mod;
+	RtlCloneUserProcess_f clone_p;
+	RTL_USER_PROCESS_INFORMATION process_info;
+	NTSTATUS result;
+
+	mod = GetModuleHandle((LPCWSTR)"ntdll.dll");
+	if (!mod)
+		return -ENOSYS;
+
+	clone_p = (RtlCloneUserProcess_f)GetProcAddress(mod, "RtlCloneUserProcess");
+	if (clone_p == NULL)
+		return -ENOSYS;
+
+	/* lets do this */
+	result = clone_p(RTL_CLONE_PROCESS_FLAGS_CREATE_SUSPENDED | RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES, NULL, NULL, NULL, &process_info);
+
+	if (result == RTL_CLONE_PARENT)
+	{
+		HANDLE me, hp, ht, hcp = 0;
+		DWORD pi, ti, mi;
+		me = GetCurrentProcess();
+		pi = (DWORD)process_info.ClientId.UniqueProcess;
+		ti = (DWORD)process_info.ClientId.UniqueThread;
+
+		hp = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pi);
+		ht = OpenThread(THREAD_ALL_ACCESS, FALSE, ti);
+		assert(hp);
+		assert(ht);
+
+		ResumeThread(ht);
+		CloseHandle(ht);
+		CloseHandle(hp);
+		return (pid_t)pi;
+	}
+	else if (result == RTL_CLONE_CHILD)
+	{
+		/* fix stdio */
+		AllocConsole();
+		return 0;
+	}
+	else
+		return -1;
+
+	/* NOTREACHED */
+	return -1;
+}
diff --git a/lib/librte_eal/windows/eal/linux-emu/getopt.c b/lib/librte_eal/windows/eal/linux-emu/getopt.c
new file mode 100644
index 000000000..8383e85ae
--- /dev/null
+++ b/lib/librte_eal/windows/eal/linux-emu/getopt.c
@@ -0,0 +1,407 @@
+#include <getopt.h>
+
+#ifdef REPLACE_GETOPT
+int	opterr = 1;		/* if error message should be printed */
+int	optind = 1;		/* index into parent argv vector */
+int	optopt = '?';		/* character checked for validity */
+#undef	optreset		/* see getopt.h */
+#define	optreset		__mingw_optreset
+int	optreset;		/* reset getopt */
+char    *optarg;		/* argument associated with option */
+#endif
+
+static char *place = EMSG; /* option letter processing */
+
+						   /* XXX: set optreset to 1 rather than these two */
+static int nonopt_start = -1; /* first non option argument (for permute) */
+static int nonopt_end = -1;   /* first option after non options (for permute) */
+
+							  /* Error messages */
+static const char recargchar[] = "option requires an argument -- %c";
+static const char recargstring[] = "option requires an argument -- %s";
+static const char ambig[] = "ambiguous option -- %.*s";
+static const char noarg[] = "option doesn't take an argument -- %.*s";
+static const char illoptchar[] = "unknown option -- %c";
+static const char illoptstring[] = "unknown option -- %s";
+
+/*
+* parse_long_options --
+*	Parse long options in argc/argv argument vector.
+* Returns -1 if short_too is set and the option does not match long_options.
+*/
+static int
+parse_long_options(char * const *nargv, const char *options,
+	const struct option *long_options, int *idx, int short_too)
+{
+	char *current_argv, *has_equal;
+	size_t current_argv_len;
+	int i, ambiguous, match;
+
+#define IDENTICAL_INTERPRETATION(_x, _y)                                \
+	(long_options[(_x)].has_arg == long_options[(_y)].has_arg &&    \
+	 long_options[(_x)].flag == long_options[(_y)].flag &&          \
+	 long_options[(_x)].val == long_options[(_y)].val)
+
+	current_argv = place;
+	match = -1;
+	ambiguous = 0;
+
+	optind++;
+
+	if ((has_equal = strchr(current_argv, '=')) != NULL) {
+		/* argument found (--option=arg) */
+		current_argv_len = has_equal - current_argv;
+		has_equal++;
+	}
+	else
+		current_argv_len = strlen(current_argv);
+
+	for (i = 0; long_options[i].name; i++) {
+		/* find matching long option */
+		if (strncmp(current_argv, long_options[i].name,
+			current_argv_len))
+			continue;
+
+		if (strlen(long_options[i].name) == current_argv_len) {
+			/* exact match */
+			match = i;
+			ambiguous = 0;
+			break;
+		}
+		/*
+		* If this is a known short option, don't allow
+		* a partial match of a single character.
+		*/
+		if (short_too && current_argv_len == 1)
+			continue;
+
+		if (match == -1)	/* partial match */
+			match = i;
+		else if (!IDENTICAL_INTERPRETATION(i, match))
+			ambiguous = 1;
+	}
+	if (ambiguous) {
+		/* ambiguous abbreviation */
+		if (PRINT_ERROR)
+			warnx(ambig, (int)current_argv_len,
+				current_argv);
+		optopt = 0;
+		return (BADCH);
+	}
+	if (match != -1) {		/* option found */
+		if (long_options[match].has_arg == no_argument
+			&& has_equal) {
+			if (PRINT_ERROR)
+				warnx(noarg, (int)current_argv_len,
+					current_argv);
+			/*
+			* XXX: GNU sets optopt to val regardless of flag
+			*/
+			if (long_options[match].flag == NULL)
+				optopt = long_options[match].val;
+			else
+				optopt = 0;
+			return (BADARG);
+		}
+		if (long_options[match].has_arg == required_argument ||
+			long_options[match].has_arg == optional_argument) {
+			if (has_equal)
+				optarg = has_equal;
+			else if (long_options[match].has_arg ==
+				required_argument) {
+				/*
+				* optional argument doesn't use next nargv
+				*/
+				optarg = nargv[optind++];
+			}
+		}
+		if ((long_options[match].has_arg == required_argument)
+			&& (optarg == NULL)) {
+			/*
+			* Missing argument; leading ':' indicates no error
+			* should be generated.
+			*/
+			if (PRINT_ERROR)
+				warnx(recargstring,
+					current_argv);
+			/*
+			* XXX: GNU sets optopt to val regardless of flag
+			*/
+			if (long_options[match].flag == NULL)
+				optopt = long_options[match].val;
+			else
+				optopt = 0;
+			--optind;
+			return (BADARG);
+		}
+	}
+	else {			/* unknown option */
+		if (short_too) {
+			--optind;
+			return (-1);
+		}
+		if (PRINT_ERROR)
+			warnx(illoptstring, current_argv);
+		optopt = 0;
+		return (BADCH);
+	}
+	if (idx)
+		*idx = match;
+	if (long_options[match].flag) {
+		*long_options[match].flag = long_options[match].val;
+		return (0);
+	}
+	else
+		return (long_options[match].val);
+#undef IDENTICAL_INTERPRETATION
+}
+
+#ifdef REPLACE_GETOPT
+/*
+* getopt --
+*	Parse argc/argv argument vector.
+*
+* [eventually this will replace the BSD getopt]
+*/
+int
+getopt(int nargc, char * const *nargv, const char *options)
+{
+
+	/*
+	* We don't pass FLAG_PERMUTE to getopt_internal() since
+	* the BSD getopt(3) (unlike GNU) has never done this.
+	*
+	* Furthermore, since many privileged programs call getopt()
+	* before dropping privileges it makes sense to keep things
+	* as simple (and bug-free) as possible.
+	*/
+	return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
+}
+#endif /* REPLACE_GETOPT */
+
+/*
+* getopt_internal --
+*	Parse argc/argv argument vector.  Called by user level routines.
+*/
+static int
+getopt_internal(int nargc, char * const *nargv, const char *options,
+	const struct option *long_options, int *idx, int flags)
+{
+	char *oli;				/* option letter list index */
+	int optchar, short_too;
+	static int posixly_correct = -1;
+
+	if (options == NULL)
+		return (-1);
+
+	/*
+	* XXX Some GNU programs (like cvs) set optind to 0 instead of
+	* XXX using optreset.  Work around this braindamage.
+	*/
+	if (optind == 0)
+		optind = optreset = 1;
+
+	/*
+	* Disable GNU extensions if POSIXLY_CORRECT is set or options
+	* string begins with a '+'.
+	*
+	* CV, 2009-12-14: Check POSIXLY_CORRECT anew if optind == 0 or
+	*                 optreset != 0 for GNU compatibility.
+	*/
+	if (posixly_correct == -1 || optreset != 0)
+		posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
+	if (*options == '-')
+		flags |= FLAG_ALLARGS;
+	else if (posixly_correct || *options == '+')
+		flags &= ~FLAG_PERMUTE;
+	if (*options == '+' || *options == '-')
+		options++;
+
+	optarg = NULL;
+	if (optreset)
+		nonopt_start = nonopt_end = -1;
+start:
+	if (optreset || !*place) {		/* update scanning pointer */
+		optreset = 0;
+		if (optind >= nargc) {          /* end of argument vector */
+			place = EMSG;
+			if (nonopt_end != -1) {
+				/* do permutation, if we have to */
+				permute_args(nonopt_start, nonopt_end,
+					optind, nargv);
+				optind -= nonopt_end - nonopt_start;
+			}
+			else if (nonopt_start != -1) {
+				/*
+				* If we skipped non-options, set optind
+				* to the first of them.
+				*/
+				optind = nonopt_start;
+			}
+			nonopt_start = nonopt_end = -1;
+			return (-1);
+		}
+		if (*(place = nargv[optind]) != '-' ||
+			(place[1] == '\0' && strchr(options, '-') == NULL)) {
+			place = EMSG;		/* found non-option */
+			if (flags & FLAG_ALLARGS) {
+				/*
+				* GNU extension:
+				* return non-option as argument to option 1
+				*/
+				optarg = nargv[optind++];
+				return (INORDER);
+			}
+			if (!(flags & FLAG_PERMUTE)) {
+				/*
+				* If no permutation wanted, stop parsing
+				* at first non-option.
+				*/
+				return (-1);
+			}
+			/* do permutation */
+			if (nonopt_start == -1)
+				nonopt_start = optind;
+			else if (nonopt_end != -1) {
+				permute_args(nonopt_start, nonopt_end,
+					optind, nargv);
+				nonopt_start = optind -
+					(nonopt_end - nonopt_start);
+				nonopt_end = -1;
+			}
+			optind++;
+			/* process next argument */
+			goto start;
+		}
+		if (nonopt_start != -1 && nonopt_end == -1)
+			nonopt_end = optind;
+
+		/*
+		* If we have "-" do nothing, if "--" we are done.
+		*/
+		if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
+			optind++;
+			place = EMSG;
+			/*
+			* We found an option (--), so if we skipped
+			* non-options, we have to permute.
+			*/
+			if (nonopt_end != -1) {
+				permute_args(nonopt_start, nonopt_end,
+					optind, nargv);
+				optind -= nonopt_end - nonopt_start;
+			}
+			nonopt_start = nonopt_end = -1;
+			return (-1);
+		}
+	}
+
+	/*
+	* Check long options if:
+	*  1) we were passed some
+	*  2) the arg is not just "-"
+	*  3) either the arg starts with -- we are getopt_long_only()
+	*/
+	if (long_options != NULL && place != nargv[optind] &&
+		(*place == '-' || (flags & FLAG_LONGONLY))) {
+		short_too = 0;
+		if (*place == '-')
+			place++;		/* --foo long option */
+		else if (*place != ':' && strchr(options, *place) != NULL)
+			short_too = 1;		/* could be short option too */
+
+		optchar = parse_long_options(nargv, options, long_options,
+			idx, short_too);
+		if (optchar != -1) {
+			place = EMSG;
+			return (optchar);
+		}
+	}
+
+	if ((optchar = (int)*place++) == (int)':' ||
+		(optchar == (int)'-' && *place != '\0') ||
+		(oli = (char*)strchr(options, optchar)) == NULL) {
+		/*
+		* If the user specified "-" and  '-' isn't listed in
+		* options, return -1 (non-option) as per POSIX.
+		* Otherwise, it is an unknown option character (or ':').
+		*/
+		if (optchar == (int)'-' && *place == '\0')
+			return (-1);
+		if (!*place)
+			++optind;
+		if (PRINT_ERROR)
+			warnx(illoptchar, optchar);
+		optopt = optchar;
+		return (BADCH);
+	}
+	if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
+		/* -W long-option */
+		if (*place)			/* no space */
+			/* NOTHING */;
+		else if (++optind >= nargc) {	/* no arg */
+			place = EMSG;
+			if (PRINT_ERROR)
+				warnx(recargchar, optchar);
+			optopt = optchar;
+			return (BADARG);
+		}
+		else				/* white space */
+			place = nargv[optind];
+		optchar = parse_long_options(nargv, options, long_options,
+			idx, 0);
+		place = EMSG;
+		return (optchar);
+	}
+	if (*++oli != ':') {			/* doesn't take argument */
+		if (!*place)
+			++optind;
+	}
+	else {				/* takes (optional) argument */
+		optarg = NULL;
+		if (*place)			/* no white space */
+			optarg = place;
+		else if (oli[1] != ':') {	/* arg not optional */
+			if (++optind >= nargc) {	/* no arg */
+				place = EMSG;
+				if (PRINT_ERROR)
+					warnx(recargchar, optchar);
+				optopt = optchar;
+				return (BADARG);
+			}
+			else
+				optarg = nargv[optind];
+		}
+		place = EMSG;
+		++optind;
+	}
+	/* dump back option letter */
+	return (optchar);
+}
+
+
+/*
+* getopt_long --
+*	Parse argc/argv argument vector.
+*/
+int
+getopt_long(int nargc, char * const *nargv, const char *options,
+	const struct option *long_options, int *idx)
+{
+
+	return (getopt_internal(nargc, nargv, options, long_options, idx,
+		FLAG_PERMUTE));
+}
+
+/*
+* getopt_long_only --
+*	Parse argc/argv argument vector.
+*/
+int
+getopt_long_only(int nargc, char * const *nargv, const char *options,
+	const struct option *long_options, int *idx)
+{
+
+	return (getopt_internal(nargc, nargv, options, long_options, idx,
+		FLAG_PERMUTE | FLAG_LONGONLY));
+}
diff --git a/lib/librte_eal/windows/eal/linux-emu/lrand48.c b/lib/librte_eal/windows/eal/linux-emu/lrand48.c
new file mode 100644
index 000000000..687d0f7b2
--- /dev/null
+++ b/lib/librte_eal/windows/eal/linux-emu/lrand48.c
@@ -0,0 +1,23 @@
+/*
+* Copyright (c) 1993 Martin Birgmeier
+* All rights reserved.
+*
+* You may redistribute unmodified or modified versions of this source
+* code provided that the above copyright notice and this and the
+* following conditions are retained.
+*
+* This software is provided ``as is'', and comes with no warranties
+* of any kind. I shall in no event be liable for anything that happens
+* to anyone/anything when using this software.
+*/
+
+#include "rand48.h"
+
+extern unsigned short _rand48_seed[3];
+
+long
+lrand48(void)
+{
+	_dorand48(_rand48_seed);
+	return ((long)_rand48_seed[2] << 15) + ((long)_rand48_seed[1] >> 1);
+}
diff --git a/lib/librte_eal/windows/eal/linux-emu/mman.c b/lib/librte_eal/windows/eal/linux-emu/mman.c
new file mode 100644
index 000000000..0a8d39038
--- /dev/null
+++ b/lib/librte_eal/windows/eal/linux-emu/mman.c
@@ -0,0 +1,179 @@
+#include <windows.h>
+#include <errno.h>
+#include <io.h>
+
+#include <sys/mman.h>
+
+#ifndef FILE_MAP_EXECUTE
+#define FILE_MAP_EXECUTE    0x0020
+#endif /* FILE_MAP_EXECUTE */
+
+static int __map_mman_error(const DWORD err, const int deferr)
+{
+	if (err == 0)
+		return 0;
+	//TODO: implement
+	return err;
+}
+
+static DWORD __map_mmap_prot_page(const int prot)
+{
+	DWORD protect = 0;
+
+	if (prot == PROT_NONE)
+		return protect;
+
+	if ((prot & PROT_EXEC) != 0)
+	{
+		protect = ((prot & PROT_WRITE) != 0) ?
+			PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
+	}
+	else
+	{
+		protect = ((prot & PROT_WRITE) != 0) ?
+			PAGE_READWRITE : PAGE_READONLY;
+	}
+
+	return protect;
+}
+
+static DWORD __map_mmap_prot_file(const int prot)
+{
+	DWORD desiredAccess = 0;
+
+	if (prot == PROT_NONE)
+		return desiredAccess;
+
+	if ((prot & PROT_READ) != 0)
+		desiredAccess |= FILE_MAP_READ;
+	if ((prot & PROT_WRITE) != 0)
+		desiredAccess |= FILE_MAP_WRITE;
+	if ((prot & PROT_EXEC) != 0)
+		desiredAccess |= FILE_MAP_EXECUTE;
+
+	return desiredAccess;
+}
+
+void* mmap(void *addr, size_t len, int prot, int flags, int fildes, OffsetType off)
+{
+	HANDLE fm, h;
+
+	void * map = MAP_FAILED;
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4293)
+#endif
+
+	const DWORD dwFileOffsetLow = (sizeof(OffsetType) <= sizeof(DWORD)) ?
+		(DWORD)off : (DWORD)(off & 0xFFFFFFFFL);
+	const DWORD dwFileOffsetHigh = (sizeof(OffsetType) <= sizeof(DWORD)) ?
+		(DWORD)0 : (DWORD)((off >> 32) & 0xFFFFFFFFL);
+	const DWORD protect = __map_mmap_prot_page(prot);
+	const DWORD desiredAccess = __map_mmap_prot_file(prot);
+
+	const OffsetType maxSize = off + (OffsetType)len;
+
+	const DWORD dwMaxSizeLow = (sizeof(OffsetType) <= sizeof(DWORD)) ?
+		(DWORD)maxSize : (DWORD)(maxSize & 0xFFFFFFFFL);
+	const DWORD dwMaxSizeHigh = (sizeof(OffsetType) <= sizeof(DWORD)) ?
+		(DWORD)0 : (DWORD)((maxSize >> 32) & 0xFFFFFFFFL);
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+	errno = 0;
+
+	if (len == 0
+		/* Unsupported flag combinations */
+		|| (flags & MAP_FIXED) != 0
+		/* Usupported protection combinations */
+		|| prot == PROT_EXEC)
+	{
+		errno = EINVAL;
+		return MAP_FAILED;
+	}
+
+	h = ((flags & MAP_ANONYMOUS) == 0) ?
+		(HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE;
+
+	if ((flags & MAP_ANONYMOUS) == 0 && h == INVALID_HANDLE_VALUE)
+	{
+		errno = EBADF;
+		return MAP_FAILED;
+	}
+
+	fm = CreateFileMapping(h, NULL, protect, dwMaxSizeHigh, dwMaxSizeLow, NULL);
+
+	if (fm == NULL)
+	{
+		errno = __map_mman_error(GetLastError(), EPERM);
+		return MAP_FAILED;
+	}
+
+	map = MapViewOfFile(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len);
+
+	CloseHandle(fm);
+
+	if (map == NULL)
+	{
+		errno = __map_mman_error(GetLastError(), EPERM);
+		return MAP_FAILED;
+	}
+
+	return map;
+}
+
+int munmap(void *addr, size_t len)
+{
+	if (UnmapViewOfFile(addr))
+		return 0;
+
+	errno = __map_mman_error(GetLastError(), EPERM);
+
+	return -1;
+}
+
+int _mprotect(void *addr, size_t len, int prot)
+{
+	DWORD newProtect = __map_mmap_prot_page(prot);
+	DWORD oldProtect = 0;
+
+	if (VirtualProtect(addr, len, newProtect, &oldProtect))
+		return 0;
+
+	errno = __map_mman_error(GetLastError(), EPERM);
+
+	return -1;
+}
+
+int msync(void *addr, size_t len, int flags)
+{
+	if (FlushViewOfFile(addr, len))
+		return 0;
+
+	errno = __map_mman_error(GetLastError(), EPERM);
+
+	return -1;
+}
+
+int mlock(const void *addr, size_t len)
+{
+	if (VirtualLock((LPVOID)addr, len))
+		return 0;
+
+	errno = __map_mman_error(GetLastError(), EPERM);
+
+	return -1;
+}
+
+int munlock(const void *addr, size_t len)
+{
+	if (VirtualUnlock((LPVOID)addr, len))
+		return 0;
+
+	errno = __map_mman_error(GetLastError(), EPERM);
+
+	return -1;
+}
diff --git a/lib/librte_eal/windows/eal/linux-emu/setenv.c b/lib/librte_eal/windows/eal/linux-emu/setenv.c
new file mode 100644
index 000000000..bd54bfcb1
--- /dev/null
+++ b/lib/librte_eal/windows/eal/linux-emu/setenv.c
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#include <stdlib.h>
+
+int setenv(const char *name, const char *value, int overwrite)
+{
+	char * curenv;
+	size_t len;
+
+	// Does the environment variable already exist?
+	errno_t err = _dupenv_s(&curenv, &len, name);
+
+	// Free the allocated memory - it is okay to call free(NULL)
+	free(curenv);
+
+	if (err || overwrite)
+	{
+		char newval[128];
+		sprintf_s(newval, sizeof(newval), "%s=%s", name, value);
+		return _putenv(newval);
+	}
+
+	return 0;
+}
\ No newline at end of file
diff --git a/lib/librte_eal/windows/eal/linux-emu/srand48.c b/lib/librte_eal/windows/eal/linux-emu/srand48.c
new file mode 100644
index 000000000..071ef1df9
--- /dev/null
+++ b/lib/librte_eal/windows/eal/linux-emu/srand48.c
@@ -0,0 +1,30 @@
+/*
+* Copyright (c) 1993 Martin Birgmeier
+* All rights reserved.
+*
+* You may redistribute unmodified or modified versions of this source
+* code provided that the above copyright notice and this and the
+* following conditions are retained.
+*
+* This software is provided ``as is'', and comes with no warranties
+* of any kind. I shall in no event be liable for anything that happens
+* to anyone/anything when using this software.
+*/
+
+#include "rand48.h"
+
+extern unsigned short _rand48_seed[3];
+extern unsigned short _rand48_mult[3];
+extern unsigned short _rand48_add;
+
+void
+srand48(long seed)
+{
+	_rand48_seed[0] = RAND48_SEED_0;
+	_rand48_seed[1] = (unsigned short)seed;
+	_rand48_seed[2] = (unsigned short)(seed >> 16);
+	_rand48_mult[0] = RAND48_MULT_0;
+	_rand48_mult[1] = RAND48_MULT_1;
+	_rand48_mult[2] = RAND48_MULT_2;
+	_rand48_add = RAND48_ADD;
+}
diff --git a/lib/librte_eal/windows/eal/linux-emu/termios.c b/lib/librte_eal/windows/eal/linux-emu/termios.c
new file mode 100644
index 000000000..d81a26f53
--- /dev/null
+++ b/lib/librte_eal/windows/eal/linux-emu/termios.c
@@ -0,0 +1,11 @@
+#include <sys/_termios.h>
+
+int tcgetattr(int fd, struct termios *t)
+{
+	return 0;
+}
+
+int tcsetattr(int fd, int opt, struct termios *t)
+{
+	return 0;
+}
\ No newline at end of file
diff --git a/lib/librte_eal/windows/eal/linux-emu/unistd.c b/lib/librte_eal/windows/eal/linux-emu/unistd.c
new file mode 100644
index 000000000..fa0eee9c9
--- /dev/null
+++ b/lib/librte_eal/windows/eal/linux-emu/unistd.c
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#include <unistd.h>
+#include <windows.h>
+
+int getpagesize(void)
+{
+    SYSTEM_INFO si;
+
+    GetSystemInfo(&si);
+
+    return si.dwPageSize;
+}
+
+int getdtablesize(void)
+{
+	// Return OPEN_MAX (256)
+	return 256;
+}
\ No newline at end of file
diff --git a/lib/librte_eal/windows/eal/malloc_heap.c b/lib/librte_eal/windows/eal/malloc_heap.c
new file mode 100644
index 000000000..62b4c39c2
--- /dev/null
+++ b/lib/librte_eal/windows/eal/malloc_heap.c
@@ -0,0 +1,1068 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2014 Intel Corporation
+ */
+#include <stdint.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <sys/queue.h>
+
+#include <rte_memory.h>
+#include <rte_errno.h>
+#include <rte_eal.h>
+#include <rte_eal_memconfig.h>
+#include <rte_launch.h>
+#include <rte_per_lcore.h>
+#include <rte_lcore.h>
+#include <rte_common.h>
+#include <rte_string_fns.h>
+#include <rte_spinlock.h>
+#include <rte_memcpy.h>
+#include <rte_atomic.h>
+#include <rte_fbarray.h>
+
+#include "eal_internal_cfg.h"
+#include "eal_memalloc.h"
+#include "malloc_elem.h"
+#include "malloc_heap.h"
+#include "malloc_mp.h"
+
+static unsigned
+check_hugepage_sz(unsigned flags, uint64_t hugepage_sz)
+{
+	unsigned check_flag = 0;
+
+	if (!(flags & ~RTE_MEMZONE_SIZE_HINT_ONLY))
+		return 1;
+
+	switch (hugepage_sz) {
+	case RTE_PGSIZE_256K:
+		check_flag = RTE_MEMZONE_256KB;
+		break;
+	case RTE_PGSIZE_2M:
+		check_flag = RTE_MEMZONE_2MB;
+		break;
+	case RTE_PGSIZE_16M:
+		check_flag = RTE_MEMZONE_16MB;
+		break;
+	case RTE_PGSIZE_256M:
+		check_flag = RTE_MEMZONE_256MB;
+		break;
+	case RTE_PGSIZE_512M:
+		check_flag = RTE_MEMZONE_512MB;
+		break;
+	case RTE_PGSIZE_1G:
+		check_flag = RTE_MEMZONE_1GB;
+		break;
+	}
+
+	return check_flag & flags;
+}
+
+/*
+ * Expand the heap with a memory area.
+ */
+static struct malloc_elem *
+malloc_heap_add_memory(struct malloc_heap *heap, struct rte_memseg_list *msl,
+		void *start, size_t len)
+{
+	struct malloc_elem *elem = start;
+
+	malloc_elem_init(elem, heap, msl, len);
+
+	malloc_elem_insert(elem);
+
+	elem = malloc_elem_join_adjacent_free(elem);
+
+	malloc_elem_free_list_insert(elem);
+
+	return elem;
+}
+
+static int
+malloc_add_seg(const struct rte_memseg_list *msl,
+		const struct rte_memseg *ms, size_t len, void *arg __rte_unused)
+{
+	struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+	struct rte_memseg_list *found_msl;
+	struct malloc_heap *heap;
+	int msl_idx;
+
+	heap = &mcfg->malloc_heaps[msl->socket_id];
+
+	/* msl is const, so find it */
+	msl_idx = msl - mcfg->memsegs;
+
+	if (msl_idx < 0 || msl_idx >= RTE_MAX_MEMSEG_LISTS)
+		return -1;
+
+	found_msl = &mcfg->memsegs[msl_idx];
+
+	malloc_heap_add_memory(heap, found_msl, ms->addr, len);
+
+	heap->total_size += len;
+
+	RTE_LOG(DEBUG, EAL, "Added %zuM to heap on socket %i\n", len >> 20,
+			msl->socket_id);
+	return 0;
+}
+
+/*
+ * Iterates through the freelist for a heap to find a free element
+ * which can store data of the required size and with the requested alignment.
+ * If size is 0, find the biggest available elem.
+ * Returns null on failure, or pointer to element on success.
+ */
+static struct malloc_elem *
+find_suitable_element(struct malloc_heap *heap, size_t size,
+		unsigned int flags, size_t align, size_t bound, bool contig)
+{
+	size_t idx;
+	struct malloc_elem *elem, *alt_elem = NULL;
+
+	for (idx = malloc_elem_free_list_index(size);
+			idx < RTE_HEAP_NUM_FREELISTS; idx++) {
+		for (elem = LIST_FIRST(&heap->free_head[idx]);
+				!!elem; elem = LIST_NEXT(elem, free_list)) {
+			if (malloc_elem_can_hold(elem, size, align, bound,
+					contig)) {
+				if (check_hugepage_sz(flags,
+						elem->msl->page_sz))
+					return elem;
+				if (alt_elem == NULL)
+					alt_elem = elem;
+			}
+		}
+	}
+
+	if ((alt_elem != NULL) && (flags & RTE_MEMZONE_SIZE_HINT_ONLY))
+		return alt_elem;
+
+	return NULL;
+}
+
+/*
+ * Iterates through the freelist for a heap to find a free element with the
+ * biggest size and requested alignment. Will also set size to whatever element
+ * size that was found.
+ * Returns null on failure, or pointer to element on success.
+ */
+static struct malloc_elem *
+find_biggest_element(struct malloc_heap *heap, size_t *size,
+		unsigned int flags, size_t align, bool contig)
+{
+	struct malloc_elem *elem, *max_elem = NULL;
+	size_t idx, max_size = 0;
+
+	for (idx = 0; idx < RTE_HEAP_NUM_FREELISTS; idx++) {
+		for (elem = LIST_FIRST(&heap->free_head[idx]);
+				!!elem; elem = LIST_NEXT(elem, free_list)) {
+			size_t cur_size;
+			if (!check_hugepage_sz(flags, elem->msl->page_sz))
+				continue;
+			if (contig) {
+				cur_size =
+					malloc_elem_find_max_iova_contig(elem,
+							align);
+			} else {
+				void *data_start = RTE_PTR_ADD(elem,
+						MALLOC_ELEM_HEADER_LEN);
+				void *data_end = RTE_PTR_ADD(elem, elem->size -
+						MALLOC_ELEM_TRAILER_LEN);
+				void *aligned = RTE_PTR_ALIGN_CEIL(data_start,
+						align);
+				/* check if aligned data start is beyond end */
+				if (aligned >= data_end)
+					continue;
+				cur_size = RTE_PTR_DIFF(data_end, aligned);
+			}
+			if (cur_size > max_size) {
+				max_size = cur_size;
+				max_elem = elem;
+			}
+		}
+	}
+
+	*size = max_size;
+	return max_elem;
+}
+
+/*
+ * Main function to allocate a block of memory from the heap.
+ * It locks the free list, scans it, and adds a new memseg if the
+ * scan fails. Once the new memseg is added, it re-scans and should return
+ * the new element after releasing the lock.
+ */
+static void *
+heap_alloc(struct malloc_heap *heap, const char *type __rte_unused, size_t size,
+		unsigned int flags, size_t align, size_t bound, bool contig)
+{
+	struct malloc_elem *elem;
+
+	size = RTE_CACHE_LINE_ROUNDUP(size);
+	align = RTE_CACHE_LINE_ROUNDUP(align);
+
+	elem = find_suitable_element(heap, size, flags, align, bound, contig);
+	if (elem != NULL) {
+		elem = malloc_elem_alloc(elem, size, align, bound, contig);
+
+		/* increase heap's count of allocated elements */
+		heap->alloc_count++;
+	}
+
+	return elem == NULL ? NULL : (void *)(&elem[1]);
+}
+
+static void *
+heap_alloc_biggest(struct malloc_heap *heap, const char *type __rte_unused,
+		unsigned int flags, size_t align, bool contig)
+{
+	struct malloc_elem *elem;
+	size_t size;
+
+	align = RTE_CACHE_LINE_ROUNDUP(align);
+
+	elem = find_biggest_element(heap, &size, flags, align, contig);
+	if (elem != NULL) {
+		elem = malloc_elem_alloc(elem, size, align, 0, contig);
+
+		/* increase heap's count of allocated elements */
+		heap->alloc_count++;
+	}
+
+	return elem == NULL ? NULL : (void *)(&elem[1]);
+}
+
+/* this function is exposed in malloc_mp.h */
+void
+rollback_expand_heap(struct rte_memseg **ms, int n_segs,
+		struct malloc_elem *elem, void *map_addr, size_t map_len)
+{
+	if (elem != NULL) {
+		malloc_elem_free_list_remove(elem);
+		malloc_elem_hide_region(elem, map_addr, map_len);
+	}
+
+	eal_memalloc_free_seg_bulk(ms, n_segs);
+}
+
+/* this function is exposed in malloc_mp.h */
+struct malloc_elem *
+alloc_pages_on_heap(struct malloc_heap *heap, uint64_t pg_sz, size_t elt_size,
+		int socket, unsigned int flags, size_t align, size_t bound,
+		bool contig, struct rte_memseg **ms, int n_segs)
+{
+	struct rte_memseg_list *msl;
+	struct malloc_elem *elem = NULL;
+	size_t alloc_sz;
+	int allocd_pages;
+	void *ret, *map_addr;
+
+	alloc_sz = (size_t)pg_sz * n_segs;
+
+	/* first, check if we're allowed to allocate this memory */
+	if (eal_memalloc_mem_alloc_validate(socket,
+			heap->total_size + alloc_sz) < 0) {
+		RTE_LOG(DEBUG, EAL, "User has disallowed allocation\n");
+		return NULL;
+	}
+
+	allocd_pages = eal_memalloc_alloc_seg_bulk(ms, n_segs, pg_sz,
+			socket, true);
+
+	/* make sure we've allocated our pages... */
+	if (allocd_pages < 0)
+		return NULL;
+
+	map_addr = ms[0]->addr;
+	msl = rte_mem_virt2memseg_list(map_addr);
+
+	/* check if we wanted contiguous memory but didn't get it */
+	if (contig && !eal_memalloc_is_contig(msl, map_addr, alloc_sz)) {
+		RTE_LOG(DEBUG, EAL, "%s(): couldn't allocate physically contiguous space\n",
+				__func__);
+		goto fail;
+	}
+
+	/* add newly minted memsegs to malloc heap */
+	elem = malloc_heap_add_memory(heap, msl, map_addr, alloc_sz);
+
+	/* try once more, as now we have allocated new memory */
+	ret = find_suitable_element(heap, elt_size, flags, align, bound,
+			contig);
+
+	if (ret == NULL)
+		goto fail;
+
+	return elem;
+
+fail:
+	rollback_expand_heap(ms, n_segs, elem, map_addr, alloc_sz);
+	return NULL;
+}
+
+static int
+try_expand_heap_primary(struct malloc_heap *heap, uint64_t pg_sz,
+		size_t elt_size, int socket, unsigned int flags, size_t align,
+		size_t bound, bool contig)
+{
+	struct malloc_elem *elem;
+	struct rte_memseg **ms;
+	void *map_addr;
+	size_t alloc_sz;
+	int n_segs;
+	bool callback_triggered = false;
+
+	alloc_sz = RTE_ALIGN_CEIL(align + elt_size +
+			MALLOC_ELEM_TRAILER_LEN, pg_sz);
+	n_segs = alloc_sz / pg_sz;
+
+	/* we can't know in advance how many pages we'll need, so we malloc */
+	ms = malloc(sizeof(*ms) * n_segs);
+
+	memset(ms, 0, sizeof(*ms) * n_segs);
+
+	if (ms == NULL)
+		return -1;
+
+	elem = alloc_pages_on_heap(heap, pg_sz, elt_size, socket, flags, align,
+			bound, contig, ms, n_segs);
+
+	if (elem == NULL)
+		goto free_ms;
+
+	map_addr = ms[0]->addr;
+
+	/* notify user about changes in memory map */
+	eal_memalloc_mem_event_notify(RTE_MEM_EVENT_ALLOC, map_addr, alloc_sz);
+
+	/* notify other processes that this has happened */
+	if (request_sync()) {
+		/* we couldn't ensure all processes have mapped memory,
+		 * so free it back and notify everyone that it's been
+		 * freed back.
+		 *
+		 * technically, we could've avoided adding memory addresses to
+		 * the map, but that would've led to inconsistent behavior
+		 * between primary and secondary processes, as those get
+		 * callbacks during sync. therefore, force primary process to
+		 * do alloc-and-rollback syncs as well.
+		 */
+		callback_triggered = true;
+		goto free_elem;
+	}
+	heap->total_size += alloc_sz;
+
+	RTE_LOG(DEBUG, EAL, "Heap on socket %d was expanded by %zdMB\n",
+		socket, alloc_sz >> 20ULL);
+
+	free(ms);
+
+	return 0;
+
+free_elem:
+	if (callback_triggered)
+		eal_memalloc_mem_event_notify(RTE_MEM_EVENT_FREE,
+				map_addr, alloc_sz);
+
+	rollback_expand_heap(ms, n_segs, elem, map_addr, alloc_sz);
+
+	request_sync();
+free_ms:
+	free(ms);
+
+	return -1;
+}
+
+static int
+try_expand_heap_secondary(struct malloc_heap *heap, uint64_t pg_sz,
+		size_t elt_size, int socket, unsigned int flags, size_t align,
+		size_t bound, bool contig)
+{
+	struct malloc_mp_req req;
+	int req_result;
+
+	memset(&req, 0, sizeof(req));
+
+	req.t = REQ_TYPE_ALLOC;
+	req.alloc_req.align = align;
+	req.alloc_req.bound = bound;
+	req.alloc_req.contig = contig;
+	req.alloc_req.flags = flags;
+	req.alloc_req.elt_size = elt_size;
+	req.alloc_req.page_sz = pg_sz;
+	req.alloc_req.socket = socket;
+	req.alloc_req.heap = heap; /* it's in shared memory */
+
+	req_result = request_to_primary(&req);
+
+	if (req_result != 0)
+		return -1;
+
+	if (req.result != REQ_RESULT_SUCCESS)
+		return -1;
+
+	return 0;
+}
+
+static int
+try_expand_heap(struct malloc_heap *heap, uint64_t pg_sz, size_t elt_size,
+		int socket, unsigned int flags, size_t align, size_t bound,
+		bool contig)
+{
+	struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+	int ret;
+
+	rte_rwlock_write_lock(&mcfg->memory_hotplug_lock);
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		ret = try_expand_heap_primary(heap, pg_sz, elt_size, socket,
+				flags, align, bound, contig);
+	} else {
+		ret = try_expand_heap_secondary(heap, pg_sz, elt_size, socket,
+				flags, align, bound, contig);
+	}
+
+	rte_rwlock_write_unlock(&mcfg->memory_hotplug_lock);
+	return ret;
+}
+
+static int
+compare_pagesz(const void *a, const void *b)
+{
+	const struct rte_memseg_list * const*mpa = a;
+	const struct rte_memseg_list * const*mpb = b;
+	const struct rte_memseg_list *msla = *mpa;
+	const struct rte_memseg_list *mslb = *mpb;
+	uint64_t pg_sz_a = msla->page_sz;
+	uint64_t pg_sz_b = mslb->page_sz;
+
+	if (pg_sz_a < pg_sz_b)
+		return -1;
+	if (pg_sz_a > pg_sz_b)
+		return 1;
+	return 0;
+}
+
+static int
+alloc_more_mem_on_socket(struct malloc_heap *heap, size_t size, int socket,
+		unsigned int flags, size_t align, size_t bound, bool contig)
+{
+	struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+	struct rte_memseg_list *requested_msls[RTE_MAX_MEMSEG_LISTS];
+	struct rte_memseg_list *other_msls[RTE_MAX_MEMSEG_LISTS];
+	uint64_t requested_pg_sz[RTE_MAX_MEMSEG_LISTS];
+	uint64_t other_pg_sz[RTE_MAX_MEMSEG_LISTS];
+	uint64_t prev_pg_sz;
+	int i, n_other_msls, n_other_pg_sz, n_requested_msls, n_requested_pg_sz;
+	bool size_hint = (flags & RTE_MEMZONE_SIZE_HINT_ONLY) > 0;
+	unsigned int size_flags = flags & ~RTE_MEMZONE_SIZE_HINT_ONLY;
+	void *ret;
+
+	memset(requested_msls, 0, sizeof(requested_msls));
+	memset(other_msls, 0, sizeof(other_msls));
+	memset(requested_pg_sz, 0, sizeof(requested_pg_sz));
+	memset(other_pg_sz, 0, sizeof(other_pg_sz));
+
+	/*
+	 * go through memseg list and take note of all the page sizes available,
+	 * and if any of them were specifically requested by the user.
+	 */
+	n_requested_msls = 0;
+	n_other_msls = 0;
+	for (i = 0; i < RTE_MAX_MEMSEG_LISTS; i++) {
+		struct rte_memseg_list *msl = &mcfg->memsegs[i];
+
+		if (msl->socket_id != socket)
+			continue;
+
+		if (msl->base_va == NULL)
+			continue;
+
+		/* if pages of specific size were requested */
+		if (size_flags != 0 && check_hugepage_sz(size_flags,
+				msl->page_sz))
+			requested_msls[n_requested_msls++] = msl;
+		else if (size_flags == 0 || size_hint)
+			other_msls[n_other_msls++] = msl;
+	}
+
+	/* sort the lists, smallest first */
+	qsort(requested_msls, n_requested_msls, sizeof(requested_msls[0]),
+			compare_pagesz);
+	qsort(other_msls, n_other_msls, sizeof(other_msls[0]),
+			compare_pagesz);
+
+	/* now, extract page sizes we are supposed to try */
+	prev_pg_sz = 0;
+	n_requested_pg_sz = 0;
+	for (i = 0; i < n_requested_msls; i++) {
+		uint64_t pg_sz = requested_msls[i]->page_sz;
+
+		if (prev_pg_sz != pg_sz) {
+			requested_pg_sz[n_requested_pg_sz++] = pg_sz;
+			prev_pg_sz = pg_sz;
+		}
+	}
+	prev_pg_sz = 0;
+	n_other_pg_sz = 0;
+	for (i = 0; i < n_other_msls; i++) {
+		uint64_t pg_sz = other_msls[i]->page_sz;
+
+		if (prev_pg_sz != pg_sz) {
+			other_pg_sz[n_other_pg_sz++] = pg_sz;
+			prev_pg_sz = pg_sz;
+		}
+	}
+
+	/* finally, try allocating memory of specified page sizes, starting from
+	 * the smallest sizes
+	 */
+	for (i = 0; i < n_requested_pg_sz; i++) {
+		uint64_t pg_sz = requested_pg_sz[i];
+
+		/*
+		 * do not pass the size hint here, as user expects other page
+		 * sizes first, before resorting to best effort allocation.
+		 */
+		if (!try_expand_heap(heap, pg_sz, size, socket, size_flags,
+				align, bound, contig))
+			return 0;
+	}
+	if (n_other_pg_sz == 0)
+		return -1;
+
+	/* now, check if we can reserve anything with size hint */
+	ret = find_suitable_element(heap, size, flags, align, bound, contig);
+	if (ret != NULL)
+		return 0;
+
+	/*
+	 * we still couldn't reserve memory, so try expanding heap with other
+	 * page sizes, if there are any
+	 */
+	for (i = 0; i < n_other_pg_sz; i++) {
+		uint64_t pg_sz = other_pg_sz[i];
+
+		if (!try_expand_heap(heap, pg_sz, size, socket, flags,
+				align, bound, contig))
+			return 0;
+	}
+	return -1;
+}
+
+/* this will try lower page sizes first */
+static void *
+heap_alloc_on_socket(const char *type, size_t size, int socket,
+		unsigned int flags, size_t align, size_t bound, bool contig)
+{
+	struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+	struct malloc_heap *heap = &mcfg->malloc_heaps[socket];
+	unsigned int size_flags = flags & ~RTE_MEMZONE_SIZE_HINT_ONLY;
+	void *ret;
+
+	rte_spinlock_lock(&(heap->lock));
+
+	align = align == 0 ? 1 : align;
+
+	/* for legacy mode, try once and with all flags */
+	if (internal_config.legacy_mem) {
+		ret = heap_alloc(heap, type, size, flags, align, bound, contig);
+		goto alloc_unlock;
+	}
+
+	/*
+	 * we do not pass the size hint here, because even if allocation fails,
+	 * we may still be able to allocate memory from appropriate page sizes,
+	 * we just need to request more memory first.
+	 */
+	ret = heap_alloc(heap, type, size, size_flags, align, bound, contig);
+	if (ret != NULL)
+		goto alloc_unlock;
+
+	if (!alloc_more_mem_on_socket(heap, size, socket, flags, align, bound,
+			contig)) {
+		ret = heap_alloc(heap, type, size, flags, align, bound, contig);
+
+		/* this should have succeeded */
+		if (ret == NULL)
+			RTE_LOG(ERR, EAL, "Error allocating from heap\n");
+	}
+alloc_unlock:
+	rte_spinlock_unlock(&(heap->lock));
+	return ret;
+}
+
+void *
+malloc_heap_alloc(const char *type, size_t size, int socket_arg,
+		unsigned int flags, size_t align, size_t bound, bool contig)
+{
+	int socket, i, cur_socket;
+	void *ret;
+
+	/* return NULL if size is 0 or alignment is not power-of-2 */
+	if (size == 0 || (align && !rte_is_power_of_2(align)))
+		return NULL;
+
+	if (!rte_eal_has_hugepages())
+		socket_arg = SOCKET_ID_ANY;
+
+	if (socket_arg == SOCKET_ID_ANY)
+		socket = malloc_get_numa_socket();
+	else
+		socket = socket_arg;
+
+	/* Check socket parameter */
+	if (socket >= RTE_MAX_NUMA_NODES)
+		return NULL;
+
+	ret = heap_alloc_on_socket(type, size, socket, flags, align, bound,
+			contig);
+	if (ret != NULL || socket_arg != SOCKET_ID_ANY)
+		return ret;
+
+	/* try other heaps */
+	for (i = 0; i < (int) rte_socket_count(); i++) {
+		cur_socket = rte_socket_id_by_idx(i);
+		if (cur_socket == socket)
+			continue;
+		ret = heap_alloc_on_socket(type, size, cur_socket, flags,
+				align, bound, contig);
+		if (ret != NULL)
+			return ret;
+	}
+	return NULL;
+}
+
+static void *
+heap_alloc_biggest_on_socket(const char *type, int socket, unsigned int flags,
+		size_t align, bool contig)
+{
+	struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+	struct malloc_heap *heap = &mcfg->malloc_heaps[socket];
+	void *ret;
+
+	rte_spinlock_lock(&(heap->lock));
+
+	align = align == 0 ? 1 : align;
+
+	ret = heap_alloc_biggest(heap, type, flags, align, contig);
+
+	rte_spinlock_unlock(&(heap->lock));
+
+	return ret;
+}
+
+void *
+malloc_heap_alloc_biggest(const char *type, int socket_arg, unsigned int flags,
+		size_t align, bool contig)
+{
+	int socket, i, cur_socket;
+	void *ret;
+
+	/* return NULL if align is not power-of-2 */
+	if ((align && !rte_is_power_of_2(align)))
+		return NULL;
+
+	if (!rte_eal_has_hugepages())
+		socket_arg = SOCKET_ID_ANY;
+
+	if (socket_arg == SOCKET_ID_ANY)
+		socket = malloc_get_numa_socket();
+	else
+		socket = socket_arg;
+
+	/* Check socket parameter */
+	if (socket >= RTE_MAX_NUMA_NODES)
+		return NULL;
+
+	ret = heap_alloc_biggest_on_socket(type, socket, flags, align,
+			contig);
+	if (ret != NULL || socket_arg != SOCKET_ID_ANY)
+		return ret;
+
+	/* try other heaps */
+	for (i = 0; i < (int) rte_socket_count(); i++) {
+		cur_socket = rte_socket_id_by_idx(i);
+		if (cur_socket == socket)
+			continue;
+		ret = heap_alloc_biggest_on_socket(type, cur_socket, flags,
+				align, contig);
+		if (ret != NULL)
+			return ret;
+	}
+	return NULL;
+}
+
+/* this function is exposed in malloc_mp.h */
+int
+malloc_heap_free_pages(void *aligned_start, size_t aligned_len)
+{
+	int n_segs, seg_idx, max_seg_idx;
+	struct rte_memseg_list *msl;
+	size_t page_sz;
+
+	msl = rte_mem_virt2memseg_list(aligned_start);
+	if (msl == NULL)
+		return -1;
+
+	page_sz = (size_t)msl->page_sz;
+	n_segs = aligned_len / page_sz;
+	seg_idx = RTE_PTR_DIFF(aligned_start, msl->base_va) / page_sz;
+	max_seg_idx = seg_idx + n_segs;
+
+	for (; seg_idx < max_seg_idx; seg_idx++) {
+		struct rte_memseg *ms;
+
+		ms = rte_fbarray_get(&msl->memseg_arr, seg_idx);
+		eal_memalloc_free_seg(ms);
+	}
+	return 0;
+}
+
+int
+malloc_heap_free(struct malloc_elem *elem)
+{
+	struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+	struct malloc_heap *heap;
+	void *start, *aligned_start, *end, *aligned_end;
+	size_t len, aligned_len, page_sz;
+	struct rte_memseg_list *msl;
+	unsigned int i, n_segs, before_space, after_space;
+	int ret;
+
+	if (!malloc_elem_cookies_ok(elem) || elem->state != ELEM_BUSY)
+		return -1;
+
+	/* elem may be merged with previous element, so keep heap address */
+	heap = elem->heap;
+	msl = elem->msl;
+	page_sz = (size_t)msl->page_sz;
+
+	rte_spinlock_lock(&(heap->lock));
+
+	/* mark element as free */
+	elem->state = ELEM_FREE;
+
+	elem = malloc_elem_free(elem);
+
+	/* anything after this is a bonus */
+	ret = 0;
+
+	/* ...of which we can't avail if we are in legacy mode */
+	if (internal_config.legacy_mem)
+		goto free_unlock;
+
+	/* Removed extra code to keep windows implementation simple. */
+
+free_unlock:
+	rte_spinlock_unlock(&(heap->lock));
+	return ret;
+}
+
+int
+malloc_heap_resize(struct malloc_elem *elem, size_t size)
+{
+	int ret;
+
+	if (!malloc_elem_cookies_ok(elem) || elem->state != ELEM_BUSY)
+		return -1;
+
+	rte_spinlock_lock(&(elem->heap->lock));
+
+	ret = malloc_elem_resize(elem, size);
+
+	rte_spinlock_unlock(&(elem->heap->lock));
+
+	return ret;
+}
+
+/*
+ * Function to retrieve data for heap on given socket
+ */
+int
+malloc_heap_get_stats(struct malloc_heap *heap,
+		struct rte_malloc_socket_stats *socket_stats)
+{
+	size_t idx;
+	struct malloc_elem *elem;
+
+	rte_spinlock_lock(&heap->lock);
+
+	/* Initialise variables for heap */
+	socket_stats->free_count = 0;
+	socket_stats->heap_freesz_bytes = 0;
+	socket_stats->greatest_free_size = 0;
+
+	/* Iterate through free list */
+	for (idx = 0; idx < RTE_HEAP_NUM_FREELISTS; idx++) {
+		for (elem = LIST_FIRST(&heap->free_head[idx]);
+			!!elem; elem = LIST_NEXT(elem, free_list))
+		{
+			socket_stats->free_count++;
+			socket_stats->heap_freesz_bytes += elem->size;
+			if (elem->size > socket_stats->greatest_free_size)
+				socket_stats->greatest_free_size = elem->size;
+		}
+	}
+	/* Get stats on overall heap and allocated memory on this heap */
+	socket_stats->heap_totalsz_bytes = heap->total_size;
+	socket_stats->heap_allocsz_bytes = (socket_stats->heap_totalsz_bytes -
+			socket_stats->heap_freesz_bytes);
+	socket_stats->alloc_count = heap->alloc_count;
+
+	rte_spinlock_unlock(&heap->lock);
+	return 0;
+}
+
+/*
+ * Function to retrieve data for heap on given socket
+ */
+void
+malloc_heap_dump(struct malloc_heap *heap, FILE *f)
+{
+	struct malloc_elem *elem;
+
+	rte_spinlock_lock(&heap->lock);
+
+	fprintf(f, "Heap size: 0x%zx\n", heap->total_size);
+	fprintf(f, "Heap alloc count: %u\n", heap->alloc_count);
+
+	elem = heap->first;
+	while (elem) {
+		malloc_elem_dump(elem, f);
+		elem = elem->next;
+	}
+
+	rte_spinlock_unlock(&heap->lock);
+}
+
+int
+rte_eal_malloc_heap_init(void)
+{
+	struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+
+	if (register_mp_requests()) {
+		RTE_LOG(ERR, EAL, "Couldn't register malloc multiprocess actions\n");
+		rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock);
+		return -1;
+	}
+
+	/* unlock mem hotplug here. it's safe for primary as no requests can
+	 * even come before primary itself is fully initialized, and secondaries
+	 * do not need to initialize the heap.
+	 */
+	rte_rwlock_read_unlock(&mcfg->memory_hotplug_lock);
+
+	/* secondary process does not need to initialize anything */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+
+	/* add all IOVA-contiguous areas to the heap */
+	return rte_memseg_contig_walk(malloc_add_seg, NULL);
+}
+
+static int
+destroy_seg(struct malloc_elem *elem, size_t len)
+{
+	struct malloc_heap *heap = elem->heap;
+	struct rte_memseg_list *msl;
+
+	msl = elem->msl;
+
+	/* notify all subscribers that a memory area is going to be removed */
+	eal_memalloc_mem_event_notify(RTE_MEM_EVENT_FREE, elem, len);
+
+	/* this element can be removed */
+	malloc_elem_free_list_remove(elem);
+	malloc_elem_hide_region(elem, elem, len);
+
+	heap->total_size -= len;
+
+	memset(elem, 0, sizeof(*elem));
+
+	/* destroy the fbarray backing this memory */
+	if (rte_fbarray_destroy(&msl->memseg_arr) < 0)
+		return -1;
+
+	/* reset the memseg list */
+	memset(msl, 0, sizeof(*msl));
+
+	return 0;
+}
+
+int
+malloc_heap_add_external_memory(struct malloc_heap *heap, void *va_addr,
+	rte_iova_t iova_addrs[], unsigned int n_pages, size_t page_sz)
+{
+	struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+	char fbarray_name[RTE_FBARRAY_NAME_LEN];
+	struct rte_memseg_list *msl = NULL;
+	struct rte_fbarray *arr;
+	size_t seg_len = n_pages * page_sz;
+	unsigned int i;
+
+	/* first, find a free memseg list */
+	for (i = 0; i < RTE_MAX_MEMSEG_LISTS; i++) {
+		struct rte_memseg_list *tmp = &mcfg->memsegs[i];
+		if (tmp->base_va == NULL) {
+			msl = tmp;
+			break;
+		}
+	}
+	if (msl == NULL) {
+		RTE_LOG(ERR, EAL, "Couldn't find empty memseg list\n");
+		rte_errno = ENOSPC;
+		return -1;
+	}
+
+	snprintf(fbarray_name, sizeof(fbarray_name) - 1, "%s_%p",
+		heap->name, va_addr);
+
+	/* create the backing fbarray */
+	if (rte_fbarray_init(&msl->memseg_arr, fbarray_name, n_pages,
+		sizeof(struct rte_memseg)) < 0) {
+		RTE_LOG(ERR, EAL, "Couldn't create fbarray backing the memseg list\n");
+		return -1;
+	}
+	arr = &msl->memseg_arr;
+
+	/* fbarray created, fill it up */
+	for (i = 0; i < n_pages; i++) {
+		struct rte_memseg *ms;
+
+		rte_fbarray_set_used(arr, i);
+		ms = rte_fbarray_get(arr, i);
+		ms->addr = RTE_PTR_ADD(va_addr, i * page_sz);
+		ms->iova = iova_addrs == NULL ? RTE_BAD_IOVA : iova_addrs[i];
+		ms->hugepage_sz = page_sz;
+		ms->len = page_sz;
+		ms->nchannel = rte_memory_get_nchannel();
+		ms->nrank = rte_memory_get_nrank();
+		ms->socket_id = heap->socket_id;
+	}
+
+	/* set up the memseg list */
+	msl->base_va = va_addr;
+	msl->page_sz = page_sz;
+	msl->socket_id = heap->socket_id;
+	msl->len = seg_len;
+	msl->version = 0;
+	msl->external = 1;
+
+	/* erase contents of new memory */
+	memset(va_addr, 0, seg_len);
+
+	/* now, add newly minted memory to the malloc heap */
+	malloc_heap_add_memory(heap, msl, va_addr, seg_len);
+
+	heap->total_size += seg_len;
+
+	/* all done! */
+	RTE_LOG(DEBUG, EAL, "Added segment for heap %s starting at %p\n",
+		heap->name, va_addr);
+
+	/* notify all subscribers that a new memory area has been added */
+	eal_memalloc_mem_event_notify(RTE_MEM_EVENT_ALLOC,
+		va_addr, seg_len);
+
+	return 0;
+}
+
+int
+malloc_heap_remove_external_memory(struct malloc_heap *heap, void *va_addr,
+	size_t len)
+{
+	struct malloc_elem *elem = heap->first;
+
+	/* find element with specified va address */
+	while (elem != NULL && elem != va_addr) {
+		elem = elem->next;
+		/* stop if we've blown past our VA */
+		if (elem > (struct malloc_elem *)va_addr) {
+			rte_errno = ENOENT;
+			return -1;
+		}
+	}
+	/* check if element was found */
+	if (elem == NULL || elem->msl->len != len) {
+		rte_errno = ENOENT;
+		return -1;
+	}
+	/* if element's size is not equal to segment len, segment is busy */
+	if (elem->state == ELEM_BUSY || elem->size != len) {
+		rte_errno = EBUSY;
+		return -1;
+	}
+	return destroy_seg(elem, len);
+}
+
+int
+malloc_heap_create(struct malloc_heap *heap, const char *heap_name)
+{
+	struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+	uint32_t next_socket_id = mcfg->next_socket_id;
+
+	/* prevent overflow. did you really create 2 billion heaps??? */
+	if (next_socket_id > INT32_MAX) {
+		RTE_LOG(ERR, EAL, "Cannot assign new socket ID's\n");
+		rte_errno = ENOSPC;
+		return -1;
+	}
+
+	/* initialize empty heap */
+	heap->alloc_count = 0;
+	heap->first = NULL;
+	heap->last = NULL;
+	LIST_INIT(heap->free_head);
+	rte_spinlock_init(&heap->lock);
+	heap->total_size = 0;
+	heap->socket_id = next_socket_id;
+
+	/* we hold a global mem hotplug writelock, so it's safe to increment */
+	mcfg->next_socket_id++;
+
+	/* set up name */
+	strlcpy(heap->name, heap_name, RTE_HEAP_NAME_MAX_LEN);
+
+	return 0;
+}
+
+int
+malloc_heap_destroy(struct malloc_heap *heap)
+{
+	if (heap->alloc_count != 0) {
+		RTE_LOG(ERR, EAL, "Heap is still in use\n");
+		rte_errno = EBUSY;
+		return -1;
+	}
+	if (heap->first != NULL || heap->last != NULL) {
+		RTE_LOG(ERR, EAL, "Heap still contains memory segments\n");
+		rte_errno = EBUSY;
+		return -1;
+	}
+	if (heap->total_size != 0)
+		RTE_LOG(ERR, EAL, "Total size not zero, heap is likely corrupt\n");
+
+	/* after this, the lock will be dropped */
+	memset(heap, 0, sizeof(*heap));
+
+	return 0;
+}
+
+int
+malloc_socket_to_heap_id(unsigned int socket_id)
+{
+	struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
+	int i;
+
+	for (i = 0; i < RTE_MAX_HEAPS; i++) {
+		struct malloc_heap *heap = &mcfg->malloc_heaps[i];
+
+		if (heap->socket_id == socket_id)
+			return i;
+	}
+	return -1;
+}
diff --git a/lib/librte_eal/windows/eal/malloc_mp.c b/lib/librte_eal/windows/eal/malloc_mp.c
new file mode 100644
index 000000000..15227e2ae
--- /dev/null
+++ b/lib/librte_eal/windows/eal/malloc_mp.c
@@ -0,0 +1,645 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <string.h>
+
+#include <rte_alarm.h>
+#include <rte_errno.h>
+#include <rte_string_fns.h>
+
+#include "eal_memalloc.h"
+
+#include "malloc_elem.h"
+#include "malloc_mp.h"
+
+#define MP_ACTION_SYNC "mp_malloc_sync"
+/**< request sent by primary process to notify of changes in memory map */
+#define MP_ACTION_ROLLBACK "mp_malloc_rollback"
+/**< request sent by primary process to notify of changes in memory map. this is
+ * essentially a regular sync request, but we cannot send sync requests while
+ * another one is in progress, and we might have to - therefore, we do this as
+ * a separate callback.
+ */
+#define MP_ACTION_REQUEST "mp_malloc_request"
+/**< request sent by secondary process to ask for allocation/deallocation */
+#define MP_ACTION_RESPONSE "mp_malloc_response"
+/**< response sent to secondary process to indicate result of request */
+
+/* forward declarations */
+static int
+handle_sync_response(const struct rte_mp_msg *request,
+		const struct rte_mp_reply *reply);
+static int
+handle_rollback_response(const struct rte_mp_msg *request,
+		const struct rte_mp_reply *reply);
+
+#define MP_TIMEOUT_S 5 /**< 5 seconds timeouts */
+
+/* when we're allocating, we need to store some state to ensure that we can
+ * roll back later
+ */
+struct primary_alloc_req_state {
+	struct malloc_heap *heap;
+	struct rte_memseg **ms;
+	int ms_len;
+	struct malloc_elem *elem;
+	void *map_addr;
+	size_t map_len;
+};
+
+enum req_state {
+	REQ_STATE_INACTIVE = 0,
+	REQ_STATE_ACTIVE,
+	REQ_STATE_COMPLETE
+};
+
+struct mp_request {
+	TAILQ_ENTRY(mp_request) next;
+	struct malloc_mp_req user_req; /**< contents of request */
+	CONDITION_VARIABLE cond; /**< variable we use to time out on this request */
+	enum req_state state; /**< indicate status of this request */
+	struct primary_alloc_req_state alloc_state;
+};
+
+/*
+ * We could've used just a single request, but it may be possible for
+ * secondaries to timeout earlier than the primary, and send a new request while
+ * primary is still expecting replies to the old one. Therefore, each new
+ * request will get assigned a new ID, which is how we will distinguish between
+ * expected and unexpected messages.
+ */
+TAILQ_HEAD(mp_request_list, mp_request);
+static struct {
+	struct mp_request_list list;
+	SRWLOCK  lock;
+} mp_request_list = {
+	.list = TAILQ_HEAD_INITIALIZER(mp_request_list.list),
+	.lock = SRWLOCK_INIT
+};
+
+/**
+ * General workflow is the following:
+ *
+ * Allocation:
+ * S: send request to primary
+ * P: attempt to allocate memory
+ *    if failed, sendmsg failure
+ *    if success, send sync request
+ * S: if received msg of failure, quit
+ *    if received sync request, synchronize memory map and reply with result
+ * P: if received sync request result
+ *    if success, sendmsg success
+ *    if failure, roll back allocation and send a rollback request
+ * S: if received msg of success, quit
+ *    if received rollback request, synchronize memory map and reply with result
+ * P: if received sync request result
+ *    sendmsg sync request result
+ * S: if received msg, quit
+ *
+ * Aside from timeouts, there are three points where we can quit:
+ *  - if allocation failed straight away
+ *  - if allocation and sync request succeeded
+ *  - if allocation succeeded, sync request failed, allocation rolled back and
+ *    rollback request received (irrespective of whether it succeeded or failed)
+ *
+ * Deallocation:
+ * S: send request to primary
+ * P: attempt to deallocate memory
+ *    if failed, sendmsg failure
+ *    if success, send sync request
+ * S: if received msg of failure, quit
+ *    if received sync request, synchronize memory map and reply with result
+ * P: if received sync request result
+ *    sendmsg sync request result
+ * S: if received msg, quit
+ *
+ * There is no "rollback" from deallocation, as it's safe to have some memory
+ * mapped in some processes - it's absent from the heap, so it won't get used.
+ */
+
+static struct mp_request *
+find_request_by_id(uint64_t id)
+{
+	struct mp_request *req;
+	TAILQ_FOREACH(req, &mp_request_list.list, next) {
+		if (req->user_req.id == id)
+			break;
+	}
+	return req;
+}
+
+/* this ID is, like, totally guaranteed to be absolutely unique. pinky swear. */
+static uint64_t
+get_unique_id(void)
+{
+	uint64_t id;
+	do {
+		id = rte_rand();
+	} while (find_request_by_id(id) != NULL);
+	return id;
+}
+
+/* secondary will respond to sync requests thusly */
+static int
+handle_sync(const struct rte_mp_msg *msg, const void *peer)
+{
+	/* TODO dpdk-1808 Not implemented in Windows*/
+	return 0;
+}
+
+static int
+handle_alloc_request(const struct malloc_mp_req *m,
+		struct mp_request *req)
+{
+	const struct malloc_req_alloc *ar = &m->alloc_req;
+	struct malloc_heap *heap;
+	struct malloc_elem *elem;
+	struct rte_memseg **ms;
+	size_t alloc_sz;
+	int n_segs;
+	void *map_addr;
+
+	alloc_sz = RTE_ALIGN_CEIL(ar->align + ar->elt_size +
+			MALLOC_ELEM_TRAILER_LEN, ar->page_sz);
+	n_segs = alloc_sz / ar->page_sz;
+
+	heap = ar->heap;
+
+	/* we can't know in advance how many pages we'll need, so we malloc */
+	ms = malloc(sizeof(*ms) * n_segs);
+
+	memset(ms, 0, sizeof(*ms) * n_segs);
+
+	if (ms == NULL) {
+		RTE_LOG(ERR, EAL, "Couldn't allocate memory for request state\n");
+		goto fail;
+	}
+
+	elem = alloc_pages_on_heap(heap, ar->page_sz, ar->elt_size, ar->socket,
+			ar->flags, ar->align, ar->bound, ar->contig, ms,
+			n_segs);
+
+	if (elem == NULL)
+		goto fail;
+
+	map_addr = ms[0]->addr;
+
+	/* we have succeeded in allocating memory, but we still need to sync
+	 * with other processes. however, since DPDK IPC is single-threaded, we
+	 * send an asynchronous request and exit this callback.
+	 */
+
+	req->alloc_state.ms = ms;
+	req->alloc_state.ms_len = n_segs;
+	req->alloc_state.map_addr = map_addr;
+	req->alloc_state.map_len = alloc_sz;
+	req->alloc_state.elem = elem;
+	req->alloc_state.heap = heap;
+
+	return 0;
+fail:
+	free(ms);
+	return -1;
+}
+
+/* first stage of primary handling requests from secondary */
+static int
+handle_request(const struct rte_mp_msg *msg, const void *peer __rte_unused)
+{
+	const struct malloc_mp_req *m =
+			(const struct malloc_mp_req *)msg->param;
+	struct mp_request *entry;
+	int ret;
+
+	/* lock access to request */
+	AcquireSRWLockExclusive(&mp_request_list.lock);
+
+	/* make sure it's not a dupe */
+	entry = find_request_by_id(m->id);
+	if (entry != NULL) {
+		RTE_LOG(ERR, EAL, "Duplicate request id\n");
+		goto fail;
+	}
+
+	entry = malloc(sizeof(*entry));
+	if (entry == NULL) {
+		RTE_LOG(ERR, EAL, "Unable to allocate memory for request\n");
+		goto fail;
+	}
+
+	/* erase all data */
+	memset(entry, 0, sizeof(*entry));
+
+	if (m->t == REQ_TYPE_ALLOC) {
+		ret = handle_alloc_request(m, entry);
+	} else if (m->t == REQ_TYPE_FREE) {
+		ret = malloc_heap_free_pages(m->free_req.addr,
+				m->free_req.len);
+	} else {
+		RTE_LOG(ERR, EAL, "Unexpected request from secondary\n");
+		goto fail;
+	}
+
+	if (ret != 0) {
+		struct rte_mp_msg resp_msg;
+		struct malloc_mp_req *resp =
+				(struct malloc_mp_req *)resp_msg.param;
+
+		/* send failure message straight away */
+		resp_msg.num_fds = 0;
+		resp_msg.len_param = sizeof(*resp);
+		strlcpy(resp_msg.name, MP_ACTION_RESPONSE,
+				sizeof(resp_msg.name));
+
+		resp->t = m->t;
+		resp->result = REQ_RESULT_FAIL;
+		resp->id = m->id;
+
+		/* TODO dpdk-1808 send msg across to the other process using rte_mp_sendmsg(&resp_msg) */
+		/* we did not modify the request */
+		free(entry);
+	} else {
+		struct rte_mp_msg sr_msg;
+		struct malloc_mp_req *sr =
+				(struct malloc_mp_req *)sr_msg.param;
+		struct timespec ts;
+
+		memset(&sr_msg, 0, sizeof(sr_msg));
+
+		/* we can do something, so send sync request asynchronously */
+		sr_msg.num_fds = 0;
+		sr_msg.len_param = sizeof(*sr);
+		strlcpy(sr_msg.name, MP_ACTION_SYNC, sizeof(sr_msg.name));
+
+		ts.tv_nsec = 0;
+		ts.tv_sec = MP_TIMEOUT_S;
+
+		/* sync requests carry no data */
+		sr->t = REQ_TYPE_SYNC;
+		sr->id = m->id;
+
+		/* TODO dpdk-1808 check if there may be stray timeout still waiting */
+
+		/* mark request as in progress */
+		memcpy(&entry->user_req, m, sizeof(*m));
+		entry->state = REQ_STATE_ACTIVE;
+
+		TAILQ_INSERT_TAIL(&mp_request_list.list, entry, next);
+	}
+	ReleaseSRWLockExclusive(&mp_request_list.lock);
+	return 0;
+fail:
+	ReleaseSRWLockExclusive(&mp_request_list.lock);
+	free(entry);
+	return -1;
+}
+
+/* callback for asynchronous sync requests for primary. this will either do a
+ * sendmsg with results, or trigger rollback request.
+ */
+static int
+handle_sync_response(const struct rte_mp_msg *request,
+		const struct rte_mp_reply *reply)
+{
+	enum malloc_req_result result;
+	struct mp_request *entry;
+	const struct malloc_mp_req *mpreq =
+			(const struct malloc_mp_req *)request->param;
+	int i;
+
+	/* lock the request */
+	AcquireSRWLockExclusive(&mp_request_list.lock);
+
+	entry = find_request_by_id(mpreq->id);
+	if (entry == NULL) {
+		RTE_LOG(ERR, EAL, "Wrong request ID\n");
+		goto fail;
+	}
+
+	result = REQ_RESULT_SUCCESS;
+
+	if (reply->nb_received != reply->nb_sent)
+		result = REQ_RESULT_FAIL;
+
+	for (i = 0; i < reply->nb_received; i++) {
+		struct malloc_mp_req *resp =
+				(struct malloc_mp_req *)reply->msgs[i].param;
+
+		if (resp->t != REQ_TYPE_SYNC) {
+			RTE_LOG(ERR, EAL, "Unexpected response to sync request\n");
+			result = REQ_RESULT_FAIL;
+			break;
+		}
+		if (resp->id != entry->user_req.id) {
+			RTE_LOG(ERR, EAL, "Response to wrong sync request\n");
+			result = REQ_RESULT_FAIL;
+			break;
+		}
+		if (resp->result == REQ_RESULT_FAIL) {
+			result = REQ_RESULT_FAIL;
+			break;
+		}
+	}
+
+	if (entry->user_req.t == REQ_TYPE_FREE) {
+		struct rte_mp_msg msg;
+		struct malloc_mp_req *resp = (struct malloc_mp_req *)msg.param;
+
+		memset(&msg, 0, sizeof(msg));
+
+		/* this is a free request, just sendmsg result */
+		resp->t = REQ_TYPE_FREE;
+		resp->result = result;
+		resp->id = entry->user_req.id;
+		msg.num_fds = 0;
+		msg.len_param = sizeof(*resp);
+		strlcpy(msg.name, MP_ACTION_RESPONSE, sizeof(msg.name));
+
+		if (rte_mp_sendmsg(&msg))
+			RTE_LOG(ERR, EAL, "Could not send message to secondary process\n");
+
+		TAILQ_REMOVE(&mp_request_list.list, entry, next);
+		free(entry);
+	} else if (entry->user_req.t == REQ_TYPE_ALLOC &&
+			result == REQ_RESULT_SUCCESS) {
+		struct malloc_heap *heap = entry->alloc_state.heap;
+		struct rte_mp_msg msg;
+		struct malloc_mp_req *resp =
+				(struct malloc_mp_req *)msg.param;
+
+		memset(&msg, 0, sizeof(msg));
+
+		heap->total_size += entry->alloc_state.map_len;
+
+		/* result is success, so just notify secondary about this */
+		resp->t = REQ_TYPE_ALLOC;
+		resp->result = result;
+		resp->id = entry->user_req.id;
+		msg.num_fds = 0;
+		msg.len_param = sizeof(*resp);
+		strlcpy(msg.name, MP_ACTION_RESPONSE, sizeof(msg.name));
+
+		if (rte_mp_sendmsg(&msg))
+			RTE_LOG(ERR, EAL, "Could not send message to secondary process\n");
+
+		TAILQ_REMOVE(&mp_request_list.list, entry, next);
+		free(entry->alloc_state.ms);
+		free(entry);
+	} else if (entry->user_req.t == REQ_TYPE_ALLOC &&
+			result == REQ_RESULT_FAIL) {
+		struct rte_mp_msg rb_msg;
+		struct malloc_mp_req *rb =
+				(struct malloc_mp_req *)rb_msg.param;
+		struct timespec ts;
+		struct primary_alloc_req_state *state =
+				&entry->alloc_state;
+		int ret;
+
+		memset(&rb_msg, 0, sizeof(rb_msg));
+
+		/* we've failed to sync, so do a rollback */
+		rollback_expand_heap(state->ms, state->ms_len, state->elem,
+				state->map_addr, state->map_len);
+
+		/* send rollback request */
+		rb_msg.num_fds = 0;
+		rb_msg.len_param = sizeof(*rb);
+		strlcpy(rb_msg.name, MP_ACTION_ROLLBACK, sizeof(rb_msg.name));
+
+		ts.tv_nsec = 0;
+		ts.tv_sec = MP_TIMEOUT_S;
+
+		/* sync requests carry no data */
+		rb->t = REQ_TYPE_SYNC;
+		rb->id = entry->user_req.id;
+
+		/* TODO dpdk-1808 check if there may be stray timeout still waiting */
+	} else {
+		RTE_LOG(ERR, EAL, " to sync request of unknown type\n");
+		goto fail;
+	}
+
+	ReleaseSRWLockExclusive(&mp_request_list.lock);
+	return 0;
+fail:
+	ReleaseSRWLockExclusive(&mp_request_list.lock);
+	return -1;
+}
+
+static int
+handle_rollback_response(const struct rte_mp_msg *request,
+		const struct rte_mp_reply *reply __rte_unused)
+{
+	struct rte_mp_msg msg;
+	struct malloc_mp_req *resp = (struct malloc_mp_req *)msg.param;
+	const struct malloc_mp_req *mpreq =
+			(const struct malloc_mp_req *)request->param;
+	struct mp_request *entry;
+
+	/* lock the request */
+	AcquireSRWLockExclusive(&mp_request_list.lock);
+
+	memset(&msg, 0, sizeof(0));
+
+	entry = find_request_by_id(mpreq->id);
+	if (entry == NULL) {
+		RTE_LOG(ERR, EAL, "Wrong request ID\n");
+		goto fail;
+	}
+
+	if (entry->user_req.t != REQ_TYPE_ALLOC) {
+		RTE_LOG(ERR, EAL, "Unexpected active request\n");
+		goto fail;
+	}
+
+	/* we don't care if rollback succeeded, request still failed */
+	resp->t = REQ_TYPE_ALLOC;
+	resp->result = REQ_RESULT_FAIL;
+	resp->id = mpreq->id;
+	msg.num_fds = 0;
+	msg.len_param = sizeof(*resp);
+	strlcpy(msg.name, MP_ACTION_RESPONSE, sizeof(msg.name));
+
+	if (rte_mp_sendmsg(&msg))
+		RTE_LOG(ERR, EAL, "Could not send message to secondary process\n");
+
+	/* clean up */
+	TAILQ_REMOVE(&mp_request_list.list, entry, next);
+	free(entry->alloc_state.ms);
+	free(entry);
+
+	ReleaseSRWLockExclusive(&mp_request_list.lock);
+	return 0;
+fail:
+	ReleaseSRWLockExclusive(&mp_request_list.lock);
+	return -1;
+}
+
+/* final stage of the request from secondary */
+static int
+handle_response(const struct rte_mp_msg *msg, const void *peer  __rte_unused)
+{
+	const struct malloc_mp_req *m =
+			(const struct malloc_mp_req *)msg->param;
+	struct mp_request *entry;
+
+	AcquireSRWLockExclusive(&mp_request_list.lock);
+
+	entry = find_request_by_id(m->id);
+	if (entry != NULL) {
+		/* update request status */
+		entry->user_req.result = m->result;
+
+		entry->state = REQ_STATE_COMPLETE;
+
+		/* trigger thread wakeup */
+		WakeConditionVariable(&entry->cond);
+	}
+
+	ReleaseSRWLockExclusive(&mp_request_list.lock);
+
+	return 0;
+}
+
+/* synchronously request memory map sync, this is only called whenever primary
+ * process initiates the allocation.
+ */
+int
+request_sync(void)
+{
+	struct rte_mp_msg msg;
+	struct rte_mp_reply reply;
+	struct malloc_mp_req *req = (struct malloc_mp_req *)msg.param;
+	struct timespec ts;
+	int i, ret;
+
+	memset(&msg, 0, sizeof(msg));
+	memset(&reply, 0, sizeof(reply));
+
+	/* no need to create tailq entries as this is entirely synchronous */
+
+	msg.num_fds = 0;
+	msg.len_param = sizeof(*req);
+	strlcpy(msg.name, MP_ACTION_SYNC, sizeof(msg.name));
+
+	/* sync request carries no data */
+	req->t = REQ_TYPE_SYNC;
+	req->id = get_unique_id();
+
+	ts.tv_nsec = 0;
+	ts.tv_sec = MP_TIMEOUT_S;
+
+	/* TODO dpdk-1808 check if there may be stray timeout still waiting */
+
+	if (reply.nb_received != reply.nb_sent) {
+		RTE_LOG(ERR, EAL, "Not all secondaries have responded\n");
+		ret = -1;
+		goto out;
+	}
+
+	for (i = 0; i < reply.nb_received; i++) {
+		struct malloc_mp_req *resp =
+				(struct malloc_mp_req *)reply.msgs[i].param;
+		if (resp->t != REQ_TYPE_SYNC) {
+			RTE_LOG(ERR, EAL, "Unexpected response from secondary\n");
+			ret = -1;
+			goto out;
+		}
+		if (resp->id != req->id) {
+			RTE_LOG(ERR, EAL, "Wrong request ID\n");
+			ret = -1;
+			goto out;
+		}
+		if (resp->result != REQ_RESULT_SUCCESS) {
+			RTE_LOG(ERR, EAL, "Secondary process failed to synchronize\n");
+			ret = -1;
+			goto out;
+		}
+	}
+
+	ret = 0;
+out:
+	free(reply.msgs);
+	return ret;
+}
+
+/* this is a synchronous wrapper around a bunch of asynchronous requests to
+ * primary process. this will initiate a request and wait until responses come.
+ */
+int
+request_to_primary(struct malloc_mp_req *user_req)
+{
+	struct rte_mp_msg msg;
+	struct malloc_mp_req *msg_req = (struct malloc_mp_req *)msg.param;
+	struct mp_request *entry;
+
+	DWORD milliseconds;
+	int ret;
+
+	memset(&msg, 0, sizeof(msg));
+
+	AcquireSRWLockExclusive(&mp_request_list.lock);
+
+	entry = malloc(sizeof(*entry));
+	if (entry == NULL) {
+		RTE_LOG(ERR, EAL, "Cannot allocate memory for request\n");
+		goto fail;
+	}
+
+	memset(entry, 0, sizeof(*entry));
+
+
+	milliseconds = MP_TIMEOUT_S * 1000000;
+	/* initialize the request */
+	InitializeConditionVariable(&entry->cond);
+
+	msg.num_fds = 0;
+	msg.len_param = sizeof(*msg_req);
+	strlcpy(msg.name, MP_ACTION_REQUEST, sizeof(msg.name));
+
+	/* (attempt to) get a unique id */
+	user_req->id = get_unique_id();
+
+	/* copy contents of user request into the message */
+	memcpy(msg_req, user_req, sizeof(*msg_req));
+
+	/* TODO dpdk-1808 send msg across to the other process using rte_mp_sendmsg(&resp_msg) */
+	/* copy contents of user request into active request */
+	memcpy(&entry->user_req, user_req, sizeof(*user_req));
+
+	/* mark request as in progress */
+	entry->state = REQ_STATE_ACTIVE;
+
+	TAILQ_INSERT_TAIL(&mp_request_list.list, entry, next);
+
+	/* finally, wait on timeout */
+	do {
+		ret = SleepConditionVariableSRW(&entry->cond,
+				&mp_request_list.lock, milliseconds,0);
+	} while (ret != 0 && ret != ETIMEDOUT);
+
+	if (entry->state != REQ_STATE_COMPLETE) {
+		RTE_LOG(ERR, EAL, "Request timed out\n");
+		ret = -1;
+	} else {
+		ret = 0;
+		user_req->result = entry->user_req.result;
+	}
+	TAILQ_REMOVE(&mp_request_list.list, entry, next);
+	free(entry);
+
+	ReleaseSRWLockExclusive(&mp_request_list.lock);
+	return ret;
+fail:
+	ReleaseSRWLockExclusive(&mp_request_list.lock);
+	free(entry);
+	return -1;
+}
+
+int
+register_mp_requests(void)
+{
+	/* TODO dpdk-1808 Not implemented in Windows*/
+	return 0;
+}
diff --git a/lib/librte_eal/windows/include_override/dirent.h b/lib/librte_eal/windows/include_override/dirent.h
new file mode 100644
index 000000000..47d17fd9a
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/dirent.h
@@ -0,0 +1,950 @@
+/*
+* Dirent interface for Microsoft Visual Studio
+* Version 1.21
+*
+* Copyright (C) 2006-2012 Toni Ronkko
+* This file is part of dirent.  Dirent may be freely distributed
+* under the MIT license.  For all details and documentation, see
+* https://github.com/tronkko/dirent
+*/
+#ifndef DIRENT_H
+#define DIRENT_H
+
+/*
+* Include windows.h without Windows Sockets 1.1 to prevent conflicts with
+* Windows Sockets 2.0.
+*/
+#ifndef WIN32_LEAN_AND_MEAN
+#   define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <wchar.h>
+#include <string.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+/* Indicates that d_type field is available in dirent structure */
+#define _DIRENT_HAVE_D_TYPE
+
+/* Indicates that d_namlen field is available in dirent structure */
+#define _DIRENT_HAVE_D_NAMLEN
+
+/* Entries missing from MSVC 6.0 */
+#if !defined(FILE_ATTRIBUTE_DEVICE)
+#   define FILE_ATTRIBUTE_DEVICE 0x40
+#endif
+
+/* File type and permission flags for stat(), general mask */
+#if !defined(S_IFMT)
+#   define S_IFMT _S_IFMT
+#endif
+
+/* Directory bit */
+#if !defined(S_IFDIR)
+#   define S_IFDIR _S_IFDIR
+#endif
+
+/* Character device bit */
+#if !defined(S_IFCHR)
+#   define S_IFCHR _S_IFCHR
+#endif
+
+/* Pipe bit */
+#if !defined(S_IFFIFO)
+#   define S_IFFIFO _S_IFFIFO
+#endif
+
+/* Regular file bit */
+#if !defined(S_IFREG)
+#   define S_IFREG _S_IFREG
+#endif
+
+/* Read permission */
+#if !defined(S_IREAD)
+#   define S_IREAD _S_IREAD
+#endif
+
+/* Write permission */
+#if !defined(S_IWRITE)
+#   define S_IWRITE _S_IWRITE
+#endif
+
+/* Execute permission */
+#if !defined(S_IEXEC)
+#   define S_IEXEC _S_IEXEC
+#endif
+
+/* Pipe */
+#if !defined(S_IFIFO)
+#   define S_IFIFO _S_IFIFO
+#endif
+
+/* Block device */
+#if !defined(S_IFBLK)
+#   define S_IFBLK 0
+#endif
+
+/* Link */
+#if !defined(S_IFLNK)
+#   define S_IFLNK 0
+#endif
+
+/* Socket */
+#if !defined(S_IFSOCK)
+#   define S_IFSOCK 0
+#endif
+
+/* Read user permission */
+#if !defined(S_IRUSR)
+#   define S_IRUSR S_IREAD
+#endif
+
+/* Write user permission */
+#if !defined(S_IWUSR)
+#   define S_IWUSR S_IWRITE
+#endif
+
+/* Execute user permission */
+#if !defined(S_IXUSR)
+#   define S_IXUSR 0
+#endif
+
+/* Read group permission */
+#if !defined(S_IRGRP)
+#   define S_IRGRP 0
+#endif
+
+/* Write group permission */
+#if !defined(S_IWGRP)
+#   define S_IWGRP 0
+#endif
+
+/* Execute group permission */
+#if !defined(S_IXGRP)
+#   define S_IXGRP 0
+#endif
+
+/* Read others permission */
+#if !defined(S_IROTH)
+#   define S_IROTH 0
+#endif
+
+/* Write others permission */
+#if !defined(S_IWOTH)
+#   define S_IWOTH 0
+#endif
+
+/* Execute others permission */
+#if !defined(S_IXOTH)
+#   define S_IXOTH 0
+#endif
+
+/* Maximum length of file name */
+#if !defined(PATH_MAX)
+#   define PATH_MAX MAX_PATH
+#endif
+#if !defined(FILENAME_MAX)
+#   define FILENAME_MAX MAX_PATH
+#endif
+#if !defined(NAME_MAX)
+#   define NAME_MAX FILENAME_MAX
+#endif
+
+/* File type flags for d_type */
+#define DT_UNKNOWN 0
+#define DT_REG S_IFREG
+#define DT_DIR S_IFDIR
+#define DT_FIFO S_IFIFO
+#define DT_SOCK S_IFSOCK
+#define DT_CHR S_IFCHR
+#define DT_BLK S_IFBLK
+#define DT_LNK S_IFLNK
+
+/* Macros for converting between st_mode and d_type */
+#define IFTODT(mode) ((mode) & S_IFMT)
+#define DTTOIF(type) (type)
+
+/*
+* File type macros.  Note that block devices, sockets and links cannot be
+* distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are
+* only defined for compatibility.  These macros should always return false
+* on Windows.
+*/
+#if !defined(S_ISFIFO)
+#   define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
+#endif
+#if !defined(S_ISDIR)
+#   define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
+#endif
+#if !defined(S_ISREG)
+#   define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
+#endif
+#if !defined(S_ISLNK)
+#   define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
+#endif
+#if !defined(S_ISSOCK)
+#   define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
+#endif
+#if !defined(S_ISCHR)
+#   define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
+#endif
+#if !defined(S_ISBLK)
+#   define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
+#endif
+
+/* Return the exact length of d_namlen without zero terminator */
+#define _D_EXACT_NAMLEN(p) ((p)->d_namlen)
+
+/* Return number of bytes needed to store d_namlen */
+#define _D_ALLOC_NAMLEN(p) (PATH_MAX)
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+	/* Wide-character version */
+	struct _wdirent {
+		/* Always zero */
+		long d_ino;
+
+		/* Structure size */
+		unsigned short d_reclen;
+
+		/* Length of name without \0 */
+		size_t d_namlen;
+
+		/* File type */
+		int d_type;
+
+		/* File name */
+		wchar_t d_name[PATH_MAX];
+	};
+	typedef struct _wdirent _wdirent;
+
+	struct _WDIR {
+		/* Current directory entry */
+		struct _wdirent ent;
+
+		/* Private file data */
+		WIN32_FIND_DATAW data;
+
+		/* True if data is valid */
+		int cached;
+
+		/* Win32 search handle */
+		HANDLE handle;
+
+		/* Initial directory name */
+		wchar_t *patt;
+	};
+	typedef struct _WDIR _WDIR;
+
+	static _WDIR *_wopendir(const wchar_t *dirname);
+	static struct _wdirent *_wreaddir(_WDIR *dirp);
+	static int _wclosedir(_WDIR *dirp);
+	static void _wrewinddir(_WDIR* dirp);
+
+
+	/* For compatibility with Symbian */
+#define wdirent _wdirent
+#define WDIR _WDIR
+#define wopendir _wopendir
+#define wreaddir _wreaddir
+#define wclosedir _wclosedir
+#define wrewinddir _wrewinddir
+
+
+	/* Multi-byte character versions */
+	struct dirent {
+		/* Always zero */
+		long d_ino;
+
+		/* Structure size */
+		unsigned short d_reclen;
+
+		/* Length of name without \0 */
+		size_t d_namlen;
+
+		/* File type */
+		int d_type;
+
+		/* File name */
+		char d_name[PATH_MAX];
+	};
+	typedef struct dirent dirent;
+
+	struct DIR {
+		struct dirent ent;
+		struct _WDIR *wdirp;
+	};
+	typedef struct DIR DIR;
+
+	static DIR *opendir(const char *dirname);
+	static struct dirent *readdir(DIR *dirp);
+	static int closedir(DIR *dirp);
+	static void rewinddir(DIR* dirp);
+
+
+	/* Internal utility functions */
+	static WIN32_FIND_DATAW *dirent_first(_WDIR *dirp);
+	static WIN32_FIND_DATAW *dirent_next(_WDIR *dirp);
+
+	static int dirent_mbstowcs_s(
+		size_t *pReturnValue,
+		wchar_t *wcstr,
+		size_t sizeInWords,
+		const char *mbstr,
+		size_t count);
+
+	static int dirent_wcstombs_s(
+		size_t *pReturnValue,
+		char *mbstr,
+		size_t sizeInBytes,
+		const wchar_t *wcstr,
+		size_t count);
+
+	static void dirent_set_errno(int error);
+
+	/*
+	* Open directory stream DIRNAME for read and return a pointer to the
+	* internal working area that is used to retrieve individual directory
+	* entries.
+	*/
+	static _WDIR*
+		_wopendir(
+			const wchar_t *dirname)
+	{
+		_WDIR *dirp = NULL;
+		int error;
+
+		/* Must have directory name */
+		if (dirname == NULL || dirname[0] == '\0') {
+			dirent_set_errno(ENOENT);
+			return NULL;
+		}
+
+		/* Allocate new _WDIR structure */
+		dirp = (_WDIR*)malloc(sizeof(struct _WDIR));
+		if (dirp != NULL) {
+			DWORD n;
+
+			/* Reset _WDIR structure */
+			dirp->handle = INVALID_HANDLE_VALUE;
+			dirp->patt = NULL;
+			dirp->cached = 0;
+
+			/* Compute the length of full path plus zero terminator
+			*
+			* Note that on WinRT there's no way to convert relative paths
+			* into absolute paths, so just assume its an absolute path.
+			*/
+#       if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+			n = wcslen(dirname);
+#       else
+			n = GetFullPathNameW(dirname, 0, NULL, NULL);
+#       endif
+
+			/* Allocate room for absolute directory name and search pattern */
+			dirp->patt = (wchar_t*)malloc(sizeof(wchar_t) * n + 16);
+			if (dirp->patt) {
+
+				/*
+				* Convert relative directory name to an absolute one.  This
+				* allows rewinddir() to function correctly even when current
+				* working directory is changed between opendir() and rewinddir().
+				*
+				* Note that on WinRT there's no way to convert relative paths
+				* into absolute paths, so just assume its an absolute path.
+				*/
+#           if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
+				wcsncpy_s(dirp->patt, n + 1, dirname, n);
+#           else
+				n = GetFullPathNameW(dirname, n, dirp->patt, NULL);
+#           endif
+				if (n > 0) {
+					wchar_t *p;
+
+					/* Append search pattern \* to the directory name */
+					p = dirp->patt + n;
+					if (dirp->patt < p) {
+						switch (p[-1]) {
+						case '\\':
+						case '/':
+						case ':':
+							/* Directory ends in path separator, e.g. c:\temp\ */
+							/*NOP*/;
+							break;
+
+						default:
+							/* Directory name doesn't end in path separator */
+							*p++ = '\\';
+						}
+					}
+					*p++ = '*';
+					*p = '\0';
+
+					/* Open directory stream and retrieve the first entry */
+					if (dirent_first(dirp)) {
+						/* Directory stream opened successfully */
+						error = 0;
+					}
+					else {
+						/* Cannot retrieve first entry */
+						error = 1;
+						dirent_set_errno(ENOENT);
+					}
+
+				}
+				else {
+					/* Cannot retrieve full path name */
+					dirent_set_errno(ENOENT);
+					error = 1;
+				}
+
+			}
+			else {
+				/* Cannot allocate memory for search pattern */
+				error = 1;
+			}
+
+		}
+		else {
+			/* Cannot allocate _WDIR structure */
+			error = 1;
+		}
+
+		/* Clean up in case of error */
+		if (error  &&  dirp) {
+			_wclosedir(dirp);
+			dirp = NULL;
+		}
+
+		return dirp;
+	}
+
+	/*
+	* Read next directory entry.  The directory entry is returned in dirent
+	* structure in the d_name field.  Individual directory entries returned by
+	* this function include regular files, sub-directories, pseudo-directories
+	* "." and ".." as well as volume labels, hidden files and system files.
+	*/
+	static struct _wdirent*
+		_wreaddir(
+			_WDIR *dirp)
+	{
+		WIN32_FIND_DATAW *datap;
+		struct _wdirent *entp;
+
+		/* Read next directory entry */
+		datap = dirent_next(dirp);
+		if (datap) {
+			size_t n;
+			DWORD attr;
+
+			/* Pointer to directory entry to return */
+			entp = &dirp->ent;
+
+			/*
+			* Copy file name as wide-character string.  If the file name is too
+			* long to fit in to the destination buffer, then truncate file name
+			* to PATH_MAX characters and zero-terminate the buffer.
+			*/
+			n = 0;
+			while (n + 1 < PATH_MAX  &&  datap->cFileName[n] != 0) {
+				entp->d_name[n] = datap->cFileName[n];
+				n++;
+			}
+			dirp->ent.d_name[n] = 0;
+
+			/* Length of file name excluding zero terminator */
+			entp->d_namlen = n;
+
+			/* File type */
+			attr = datap->dwFileAttributes;
+			if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
+				entp->d_type = DT_CHR;
+			}
+			else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
+				entp->d_type = DT_DIR;
+			}
+			else {
+				entp->d_type = DT_REG;
+			}
+
+			/* Reset dummy fields */
+			entp->d_ino = 0;
+			entp->d_reclen = sizeof(struct _wdirent);
+
+		}
+		else {
+
+			/* Last directory entry read */
+			entp = NULL;
+
+		}
+
+		return entp;
+	}
+
+	/*
+	* Close directory stream opened by opendir() function.  This invalidates the
+	* DIR structure as well as any directory entry read previously by
+	* _wreaddir().
+	*/
+	static int
+		_wclosedir(
+			_WDIR *dirp)
+	{
+		int ok;
+		if (dirp) {
+
+			/* Release search handle */
+			if (dirp->handle != INVALID_HANDLE_VALUE) {
+				FindClose(dirp->handle);
+				dirp->handle = INVALID_HANDLE_VALUE;
+			}
+
+			/* Release search pattern */
+			if (dirp->patt) {
+				free(dirp->patt);
+				dirp->patt = NULL;
+			}
+
+			/* Release directory structure */
+			free(dirp);
+			ok = /*success*/0;
+
+		}
+		else {
+			/* Invalid directory stream */
+			dirent_set_errno(EBADF);
+			ok = /*failure*/-1;
+		}
+		return ok;
+	}
+
+	/*
+	* Rewind directory stream such that _wreaddir() returns the very first
+	* file name again.
+	*/
+	static void
+		_wrewinddir(
+			_WDIR* dirp)
+	{
+		if (dirp) {
+			/* Release existing search handle */
+			if (dirp->handle != INVALID_HANDLE_VALUE) {
+				FindClose(dirp->handle);
+			}
+
+			/* Open new search handle */
+			dirent_first(dirp);
+		}
+	}
+
+	/* Get first directory entry (internal) */
+	static WIN32_FIND_DATAW*
+		dirent_first(
+			_WDIR *dirp)
+	{
+		WIN32_FIND_DATAW *datap;
+
+		/* Open directory and retrieve the first entry */
+		dirp->handle = FindFirstFileExW(
+			dirp->patt, FindExInfoStandard, &dirp->data,
+			FindExSearchNameMatch, NULL, 0);
+		if (dirp->handle != INVALID_HANDLE_VALUE) {
+
+			/* a directory entry is now waiting in memory */
+			datap = &dirp->data;
+			dirp->cached = 1;
+
+		}
+		else {
+
+			/* Failed to re-open directory: no directory entry in memory */
+			dirp->cached = 0;
+			datap = NULL;
+
+		}
+		return datap;
+	}
+
+	/* Get next directory entry (internal) */
+	static WIN32_FIND_DATAW*
+		dirent_next(
+			_WDIR *dirp)
+	{
+		WIN32_FIND_DATAW *p;
+
+		/* Get next directory entry */
+		if (dirp->cached != 0) {
+
+			/* A valid directory entry already in memory */
+			p = &dirp->data;
+			dirp->cached = 0;
+
+		}
+		else if (dirp->handle != INVALID_HANDLE_VALUE) {
+
+			/* Get the next directory entry from stream */
+			if (FindNextFileW(dirp->handle, &dirp->data) != FALSE) {
+				/* Got a file */
+				p = &dirp->data;
+			}
+			else {
+				/* The very last entry has been processed or an error occured */
+				FindClose(dirp->handle);
+				dirp->handle = INVALID_HANDLE_VALUE;
+				p = NULL;
+			}
+
+		}
+		else {
+
+			/* End of directory stream reached */
+			p = NULL;
+
+		}
+
+		return p;
+	}
+
+	/*
+	* Open directory stream using plain old C-string.
+	*/
+	static DIR*
+		opendir(
+			const char *dirname)
+	{
+		struct DIR *dirp;
+		int error;
+
+		/* Must have directory name */
+		if (dirname == NULL || dirname[0] == '\0') {
+			dirent_set_errno(ENOENT);
+			return NULL;
+		}
+
+		/* Allocate memory for DIR structure */
+		dirp = (DIR*)malloc(sizeof(struct DIR));
+		if (dirp) {
+			wchar_t wname[PATH_MAX];
+			size_t n;
+
+			/* Convert directory name to wide-character string */
+			error = dirent_mbstowcs_s(&n, wname, PATH_MAX, dirname, PATH_MAX);
+			if (!error) {
+
+				/* Open directory stream using wide-character name */
+				dirp->wdirp = _wopendir(wname);
+				if (dirp->wdirp) {
+					/* Directory stream opened */
+					error = 0;
+				}
+				else {
+					/* Failed to open directory stream */
+					error = 1;
+				}
+
+			}
+			else {
+				/*
+				* Cannot convert file name to wide-character string.  This
+				* occurs if the string contains invalid multi-byte sequences or
+				* the output buffer is too small to contain the resulting
+				* string.
+				*/
+				error = 1;
+			}
+
+		}
+		else {
+			/* Cannot allocate DIR structure */
+			error = 1;
+		}
+
+		/* Clean up in case of error */
+		if (error  &&  dirp) {
+			free(dirp);
+			dirp = NULL;
+		}
+
+		return dirp;
+	}
+
+	/*
+	* Read next directory entry.
+	*
+	* When working with text consoles, please note that file names returned by
+	* readdir() are represented in the default ANSI code page while any output to
+	* console is typically formatted on another code page.  Thus, non-ASCII
+	* characters in file names will not usually display correctly on console.  The
+	* problem can be fixed in two ways: (1) change the character set of console
+	* to 1252 using chcp utility and use Lucida Console font, or (2) use
+	* _cprintf function when writing to console.  The _cprinf() will re-encode
+	* ANSI strings to the console code page so many non-ASCII characters will
+	* display correcly.
+	*/
+	static struct dirent*
+		readdir(
+			DIR *dirp)
+	{
+		WIN32_FIND_DATAW *datap;
+		struct dirent *entp;
+
+		/* Read next directory entry */
+		datap = dirent_next(dirp->wdirp);
+		if (datap) {
+			size_t n;
+			int error;
+
+			/* Attempt to convert file name to multi-byte string */
+			error = dirent_wcstombs_s(
+				&n, dirp->ent.d_name, PATH_MAX, datap->cFileName, PATH_MAX);
+
+			/*
+			* If the file name cannot be represented by a multi-byte string,
+			* then attempt to use old 8+3 file name.  This allows traditional
+			* Unix-code to access some file names despite of unicode
+			* characters, although file names may seem unfamiliar to the user.
+			*
+			* Be ware that the code below cannot come up with a short file
+			* name unless the file system provides one.  At least
+			* VirtualBox shared folders fail to do this.
+			*/
+			if (error  &&  datap->cAlternateFileName[0] != '\0') {
+				error = dirent_wcstombs_s(
+					&n, dirp->ent.d_name, PATH_MAX,
+					datap->cAlternateFileName, PATH_MAX);
+			}
+
+			if (!error) {
+				DWORD attr;
+
+				/* Initialize directory entry for return */
+				entp = &dirp->ent;
+
+				/* Length of file name excluding zero terminator */
+				entp->d_namlen = n - 1;
+
+				/* File attributes */
+				attr = datap->dwFileAttributes;
+				if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
+					entp->d_type = DT_CHR;
+				}
+				else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
+					entp->d_type = DT_DIR;
+				}
+				else {
+					entp->d_type = DT_REG;
+				}
+
+				/* Reset dummy fields */
+				entp->d_ino = 0;
+				entp->d_reclen = sizeof(struct dirent);
+
+			}
+			else {
+				/*
+				* Cannot convert file name to multi-byte string so construct
+				* an errornous directory entry and return that.  Note that
+				* we cannot return NULL as that would stop the processing
+				* of directory entries completely.
+				*/
+				entp = &dirp->ent;
+				entp->d_name[0] = '?';
+				entp->d_name[1] = '\0';
+				entp->d_namlen = 1;
+				entp->d_type = DT_UNKNOWN;
+				entp->d_ino = 0;
+				entp->d_reclen = 0;
+			}
+
+		}
+		else {
+			/* No more directory entries */
+			entp = NULL;
+		}
+
+		return entp;
+	}
+
+	/*
+	* Close directory stream.
+	*/
+	static int
+		closedir(
+			DIR *dirp)
+	{
+		int ok;
+		if (dirp) {
+
+			/* Close wide-character directory stream */
+			ok = _wclosedir(dirp->wdirp);
+			dirp->wdirp = NULL;
+
+			/* Release multi-byte character version */
+			free(dirp);
+
+		}
+		else {
+
+			/* Invalid directory stream */
+			dirent_set_errno(EBADF);
+			ok = /*failure*/-1;
+
+		}
+		return ok;
+	}
+
+	/*
+	* Rewind directory stream to beginning.
+	*/
+	static void
+		rewinddir(
+			DIR* dirp)
+	{
+		/* Rewind wide-character string directory stream */
+		_wrewinddir(dirp->wdirp);
+	}
+
+	/* Convert multi-byte string to wide character string */
+	static int
+		dirent_mbstowcs_s(
+			size_t *pReturnValue,
+			wchar_t *wcstr,
+			size_t sizeInWords,
+			const char *mbstr,
+			size_t count)
+	{
+		int error;
+
+#if defined(_MSC_VER)  &&  _MSC_VER >= 1400
+
+		/* Microsoft Visual Studio 2005 or later */
+		error = mbstowcs_s(pReturnValue, wcstr, sizeInWords, mbstr, count);
+
+#else
+
+		/* Older Visual Studio or non-Microsoft compiler */
+		size_t n;
+
+		/* Convert to wide-character string (or count characters) */
+		n = mbstowcs(wcstr, mbstr, sizeInWords);
+		if (!wcstr || n < count) {
+
+			/* Zero-terminate output buffer */
+			if (wcstr  &&  sizeInWords) {
+				if (n >= sizeInWords) {
+					n = sizeInWords - 1;
+				}
+				wcstr[n] = 0;
+			}
+
+			/* Length of resuting multi-byte string WITH zero terminator */
+			if (pReturnValue) {
+				*pReturnValue = n + 1;
+			}
+
+			/* Success */
+			error = 0;
+
+		}
+		else {
+
+			/* Could not convert string */
+			error = 1;
+
+		}
+
+#endif
+
+		return error;
+	}
+
+	/* Convert wide-character string to multi-byte string */
+	static int
+		dirent_wcstombs_s(
+			size_t *pReturnValue,
+			char *mbstr,
+			size_t sizeInBytes, /* max size of mbstr */
+			const wchar_t *wcstr,
+			size_t count)
+	{
+		int error;
+
+#if defined(_MSC_VER)  &&  _MSC_VER >= 1400
+
+		/* Microsoft Visual Studio 2005 or later */
+		error = wcstombs_s(pReturnValue, mbstr, sizeInBytes, wcstr, count);
+
+#else
+
+		/* Older Visual Studio or non-Microsoft compiler */
+		size_t n;
+
+		/* Convert to multi-byte string (or count the number of bytes needed) */
+		n = wcstombs(mbstr, wcstr, sizeInBytes);
+		if (!mbstr || n < count) {
+
+			/* Zero-terminate output buffer */
+			if (mbstr  &&  sizeInBytes) {
+				if (n >= sizeInBytes) {
+					n = sizeInBytes - 1;
+				}
+				mbstr[n] = '\0';
+			}
+
+			/* Length of resulting multi-bytes string WITH zero-terminator */
+			if (pReturnValue) {
+				*pReturnValue = n + 1;
+			}
+
+			/* Success */
+			error = 0;
+
+		}
+		else {
+
+			/* Cannot convert string */
+			error = 1;
+
+		}
+
+#endif
+
+		return error;
+	}
+
+	/* Set errno variable */
+	static void
+		dirent_set_errno(
+			int error)
+	{
+#if defined(_MSC_VER)  &&  _MSC_VER >= 1400
+
+		/* Microsoft Visual Studio 2005 and later */
+		_set_errno(error);
+
+#else
+
+		/* Non-Microsoft compiler or older Microsoft compiler */
+		errno = error;
+
+#endif
+	}
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*DIRENT_H*/
diff --git a/lib/librte_eal/windows/include_override/getopt.h b/lib/librte_eal/windows/include_override/getopt.h
new file mode 100644
index 000000000..19bc18f9a
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/getopt.h
@@ -0,0 +1,252 @@
+#ifndef __GETOPT_H__
+/**
+ * DISCLAIMER
+ * This file is a part of the w64 mingw-runtime package.
+ *
+ * The w64 mingw-runtime package and its code is distributed in the hope that it
+ * will be useful but WITHOUT ANY WARRANTY.  ALL WARRANTIES, EXPRESSED OR
+ * IMPLIED ARE HEREBY DISCLAIMED.  This includes but is not limited to
+ * warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+/*
+* Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
+*
+* Permission to use, copy, modify, and distribute this software for any
+* purpose with or without fee is hereby granted, provided that the above
+* copyright notice and this permission notice appear in all copies.
+*
+* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*
+* Sponsored in part by the Defense Advanced Research Projects
+* Agency (DARPA) and Air Force Research Laboratory, Air Force
+* Materiel Command, USAF, under agreement number F39502-99-1-0512.
+*/
+/*-
+* Copyright (c) 2000 The NetBSD Foundation, Inc.
+* All rights reserved.
+*
+* This code is derived from software contributed to The NetBSD Foundation
+* by Dieter Baron and Thomas Klausner.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+* PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#pragma warning(disable:4996);
+
+#define __GETOPT_H__
+
+/* All the headers include this file. */
+#include <crtdefs.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#include <windows.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define	REPLACE_GETOPT		/* use this getopt as the system getopt(3) */
+
+#define PRINT_ERROR	((opterr) && (*options != ':'))
+
+#define FLAG_PERMUTE	0x01	/* permute non-options to the end of argv */
+#define FLAG_ALLARGS	0x02	/* treat non-options as args to option "-1" */
+#define FLAG_LONGONLY	0x04	/* operate as getopt_long_only */
+
+/* return values */
+#define	BADCH		(int)'?'
+#define	BADARG		((*options == ':') ? (int)':' : (int)'?')
+#define	INORDER 	(int)1
+
+#ifndef __CYGWIN__
+#define __progname __argv[0]
+#else
+	extern char __declspec(dllimport) *__progname;
+#endif
+
+#ifdef __CYGWIN__
+	static char EMSG[] = "";
+#else
+#define	EMSG		""
+#endif
+extern int optind;		/* index of first non-option in argv      */
+extern int optopt;		/* single option character, as parsed     */
+extern int opterr;		/* flag to enable built-in diagnostics... */
+				/* (user may set to zero, to suppress)    */
+
+extern char *optarg;		/* pointer to argument of current option  */
+
+extern int getopt(int nargc, char * const *nargv, const char *options);
+
+static int getopt_internal(int, char * const *, const char *,
+                           const struct option *, int *, int);
+static int gcd(int, int);
+static void permute_args(int, int, int, char * const *);
+
+static void
+_vwarnx(const char *fmt, va_list ap)
+{
+    (void)fprintf(stderr, "%s: ", __progname);
+    if (fmt != NULL)
+	(void)vfprintf(stderr, fmt, ap);
+    (void)fprintf(stderr, "\n");
+}
+
+static void
+warnx(const char *fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+    _vwarnx(fmt, ap);
+    va_end(ap);
+}
+
+/*
+* Compute the greatest common divisor of a and b.
+*/
+static int
+gcd(int a, int b)
+{
+    int c;
+
+    c = a % b;
+    while (c != 0) {
+	    a = b;
+	    b = c;
+	    c = a % b;
+    }
+
+    return (b);
+}
+
+/*
+* Exchange the block from nonopt_start to nonopt_end with the block
+* from nonopt_end to opt_end (keeping the same order of arguments
+* in each block).
+*/
+static void
+permute_args(int panonopt_start, int panonopt_end, int opt_end, char * const *nargv)
+{
+    int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
+    char *swap;
+
+    /*
+    * compute lengths of blocks and number and size of cycles
+    */
+    nnonopts = panonopt_end - panonopt_start;
+    nopts = opt_end - panonopt_end;
+    ncycle = gcd(nnonopts, nopts);
+    cyclelen = (opt_end - panonopt_start) / ncycle;
+
+    for (i = 0; i < ncycle; i++) {
+	cstart = panonopt_end + i;
+	pos = cstart;
+	for (j = 0; j < cyclelen; j++) {
+	    if (pos >= panonopt_end)
+		pos -= nnonopts;
+	    else
+		pos += nopts;
+	    swap = nargv[pos];
+	    /* LINTED const cast */
+	    ((char **)nargv)[pos] = nargv[cstart];
+	    /* LINTED const cast */
+	    ((char **)nargv)[cstart] = swap;
+	}
+    }
+}
+
+
+#ifdef _BSD_SOURCE
+/*
+ * BSD adds the non-standard `optreset' feature, for reinitialisation
+ * of `getopt' parsing.  We support this feature, for applications which
+ * proclaim their BSD heritage, before including this header; however,
+ * to maintain portability, developers are advised to avoid it.
+ */
+# define optreset  __mingw_optreset
+extern int optreset;
+#endif
+#ifdef __cplusplus
+}
+#endif
+/*
+ * POSIX requires the `getopt' API to be specified in `unistd.h';
+ * thus, `unistd.h' includes this header.  However, we do not want
+ * to expose the `getopt_long' or `getopt_long_only' APIs, when
+ * included in this manner.  Thus, close the standard __GETOPT_H__
+ * declarations block, and open an additional __GETOPT_LONG_H__
+ * specific block, only when *not* __UNISTD_H_SOURCED__, in which
+ * to declare the extended API.
+ */
+#endif /* !defined(__GETOPT_H__) */
+
+#if !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__)
+#define __GETOPT_LONG_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct option		/* specification for a long form option...	*/
+{
+  const char *name;		/* option name, without leading hyphens */
+  int         has_arg;		/* does it take an argument?		*/
+  int        *flag;		/* where to save its status, or NULL	*/
+  int         val;		/* its associated status value		*/
+};
+
+enum    		/* permitted values for its `has_arg' field...	*/
+{
+  no_argument = 0,      	/* option never takes an argument	*/
+  required_argument,		/* option always requires an argument	*/
+  optional_argument		/* option may take an argument		*/
+};
+
+extern int getopt_long(int nargc, char * const *nargv, const char *options,
+    const struct option *long_options, int *idx);
+extern int getopt_long_only(int nargc, char * const *nargv, const char *options,
+    const struct option *long_options, int *idx);
+/*
+ * Previous MinGW implementation had...
+ */
+#ifndef HAVE_DECL_GETOPT
+/*
+ * ...for the long form API only; keep this for compatibility.
+ */
+# define HAVE_DECL_GETOPT	1
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) */
diff --git a/lib/librte_eal/windows/include_override/net/ethernet.h b/lib/librte_eal/windows/include_override/net/ethernet.h
new file mode 100644
index 000000000..ae7341ee8
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/net/ethernet.h
@@ -0,0 +1,405 @@
+/*
+ * Fundamental constants relating to ethernet.
+ *
+ * $FreeBSD$
+ *
+ */
+
+#ifndef _NET_ETHERNET_H_
+#define _NET_ETHERNET_H_
+
+/*
+ * Some basic Ethernet constants.
+ */
+#define	ETHER_ADDR_LEN		6	/* length of an Ethernet address */
+#define	ETHER_TYPE_LEN		2	/* length of the Ethernet type field */
+#define	ETHER_CRC_LEN		4	/* length of the Ethernet CRC */
+#define	ETHER_HDR_LEN		(ETHER_ADDR_LEN*2+ETHER_TYPE_LEN)
+#define	ETHER_MIN_LEN		64	/* minimum frame len, including CRC */
+#define	ETHER_MAX_LEN		1518	/* maximum frame len, including CRC */
+#define	ETHER_MAX_LEN_JUMBO	9018	/* max jumbo frame len, including CRC */
+
+#define	ETHER_VLAN_ENCAP_LEN	4	/* len of 802.1Q VLAN encapsulation */
+/*
+ * Mbuf adjust factor to force 32-bit alignment of IP header.
+ * Drivers should do m_adj(m, ETHER_ALIGN) when setting up a
+ * receive so the upper layers get the IP header properly aligned
+ * past the 14-byte Ethernet header.
+ */
+#define	ETHER_ALIGN		2	/* driver adjust for IP hdr alignment */
+
+/*
+ * Compute the maximum frame size based on ethertype (i.e. possible
+ * encapsulation) and whether or not an FCS is present.
+ */
+#define	ETHER_MAX_FRAME(ifp, etype, hasfcs)				\
+	((ifp)->if_mtu + ETHER_HDR_LEN +				\
+	 ((hasfcs) ? ETHER_CRC_LEN : 0) +				\
+	 (((etype) == ETHERTYPE_VLAN) ? ETHER_VLAN_ENCAP_LEN : 0))
+
+/*
+ * Ethernet-specific mbuf flags.
+ */
+#define	M_HASFCS	M_PROTO5	/* FCS included at end of frame */
+
+/*
+ * Ethernet CRC32 polynomials (big- and little-endian verions).
+ */
+#define	ETHER_CRC_POLY_LE	0xedb88320
+#define	ETHER_CRC_POLY_BE	0x04c11db6
+
+/*
+ * A macro to validate a length with
+ */
+#define	ETHER_IS_VALID_LEN(foo)	\
+	((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN)
+
+/*
+ * Structure of a 10Mb/s Ethernet header.
+ */
+struct ether_header {
+	u_char	ether_dhost[ETHER_ADDR_LEN];
+	u_char	ether_shost[ETHER_ADDR_LEN];
+	u_short	ether_type;
+} __packed;
+
+/*
+ * Structure of a 48-bit Ethernet address.
+ */
+struct ether_addr {
+	u_char octet[ETHER_ADDR_LEN];
+} __packed;
+
+#define	ETHER_IS_MULTICAST(addr) (*(addr) & 0x01) /* is address mcast/bcast? */
+
+/*
+ *  NOTE: 0x0000-0x05DC (0..1500) are generally IEEE 802.3 length fields.
+ *  However, there are some conflicts.
+ */
+
+#define	ETHERTYPE_8023		0x0004	/* IEEE 802.3 packet */
+		   /* 0x0101 .. 0x1FF	   Experimental */
+#define	ETHERTYPE_PUP		0x0200	/* Xerox PUP protocol - see 0A00 */
+#define	ETHERTYPE_PUPAT		0x0200	/* PUP Address Translation - see 0A01 */
+#define	ETHERTYPE_SPRITE	0x0500	/* ??? */
+			     /* 0x0400	   Nixdorf */
+#define	ETHERTYPE_NS		0x0600	/* XNS */
+#define	ETHERTYPE_NSAT		0x0601	/* XNS Address Translation (3Mb only) */
+#define	ETHERTYPE_DLOG1 	0x0660	/* DLOG (?) */
+#define	ETHERTYPE_DLOG2 	0x0661	/* DLOG (?) */
+#define	ETHERTYPE_IP		0x0800	/* IP protocol */
+#define	ETHERTYPE_X75		0x0801	/* X.75 Internet */
+#define	ETHERTYPE_NBS		0x0802	/* NBS Internet */
+#define	ETHERTYPE_ECMA		0x0803	/* ECMA Internet */
+#define	ETHERTYPE_CHAOS 	0x0804	/* CHAOSnet */
+#define	ETHERTYPE_X25		0x0805	/* X.25 Level 3 */
+#define	ETHERTYPE_ARP		0x0806	/* Address resolution protocol */
+#define	ETHERTYPE_NSCOMPAT	0x0807	/* XNS Compatibility */
+#define	ETHERTYPE_FRARP 	0x0808	/* Frame Relay ARP (RFC1701) */
+			     /* 0x081C	   Symbolics Private */
+		    /* 0x0888 - 0x088A	   Xyplex */
+#define	ETHERTYPE_UBDEBUG	0x0900	/* Ungermann-Bass network debugger */
+#define	ETHERTYPE_IEEEPUP	0x0A00	/* Xerox IEEE802.3 PUP */
+#define	ETHERTYPE_IEEEPUPAT	0x0A01	/* Xerox IEEE802.3 PUP Address Translation */
+#define	ETHERTYPE_VINES 	0x0BAD	/* Banyan VINES */
+#define	ETHERTYPE_VINESLOOP	0x0BAE	/* Banyan VINES Loopback */
+#define	ETHERTYPE_VINESECHO	0x0BAF	/* Banyan VINES Echo */
+
+/*		       0x1000 - 0x100F	   Berkeley Trailer */
+/*
+ * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have
+ * (type-ETHERTYPE_TRAIL)*512 bytes of data followed
+ * by an ETHER type (as given above) and then the (variable-length) header.
+ */
+#define	ETHERTYPE_TRAIL		0x1000	/* Trailer packet */
+#define	ETHERTYPE_NTRAILER	16
+
+#define	ETHERTYPE_DCA		0x1234	/* DCA - Multicast */
+#define	ETHERTYPE_VALID 	0x1600	/* VALID system protocol */
+#define	ETHERTYPE_DOGFIGHT	0x1989	/* Artificial Horizons ("Aviator" dogfight simulator [on Sun]) */
+#define	ETHERTYPE_RCL		0x1995	/* Datapoint Corporation (RCL lan protocol) */
+
+					/* The following 3C0x types
+					   are unregistered: */
+#define	ETHERTYPE_NBPVCD	0x3C00	/* 3Com NBP virtual circuit datagram (like XNS SPP) not registered */
+#define	ETHERTYPE_NBPSCD	0x3C01	/* 3Com NBP System control datagram not registered */
+#define	ETHERTYPE_NBPCREQ	0x3C02	/* 3Com NBP Connect request (virtual cct) not registered */
+#define	ETHERTYPE_NBPCRSP	0x3C03	/* 3Com NBP Connect response not registered */
+#define	ETHERTYPE_NBPCC		0x3C04	/* 3Com NBP Connect complete not registered */
+#define	ETHERTYPE_NBPCLREQ	0x3C05	/* 3Com NBP Close request (virtual cct) not registered */
+#define	ETHERTYPE_NBPCLRSP	0x3C06	/* 3Com NBP Close response not registered */
+#define	ETHERTYPE_NBPDG		0x3C07	/* 3Com NBP Datagram (like XNS IDP) not registered */
+#define	ETHERTYPE_NBPDGB	0x3C08	/* 3Com NBP Datagram broadcast not registered */
+#define	ETHERTYPE_NBPCLAIM	0x3C09	/* 3Com NBP Claim NetBIOS name not registered */
+#define	ETHERTYPE_NBPDLTE	0x3C0A	/* 3Com NBP Delete NetBIOS name not registered */
+#define	ETHERTYPE_NBPRAS	0x3C0B	/* 3Com NBP Remote adaptor status request not registered */
+#define	ETHERTYPE_NBPRAR	0x3C0C	/* 3Com NBP Remote adaptor response not registered */
+#define	ETHERTYPE_NBPRST	0x3C0D	/* 3Com NBP Reset not registered */
+
+#define	ETHERTYPE_PCS		0x4242	/* PCS Basic Block Protocol */
+#define	ETHERTYPE_IMLBLDIAG	0x424C	/* Information Modes Little Big LAN diagnostic */
+#define	ETHERTYPE_DIDDLE	0x4321	/* THD - Diddle */
+#define	ETHERTYPE_IMLBL		0x4C42	/* Information Modes Little Big LAN */
+#define	ETHERTYPE_SIMNET	0x5208	/* BBN Simnet Private */
+#define	ETHERTYPE_DECEXPER	0x6000	/* DEC Unassigned, experimental */
+#define	ETHERTYPE_MOPDL		0x6001	/* DEC MOP dump/load */
+#define	ETHERTYPE_MOPRC		0x6002	/* DEC MOP remote console */
+#define	ETHERTYPE_DECnet	0x6003	/* DEC DECNET Phase IV route */
+#define	ETHERTYPE_DN		ETHERTYPE_DECnet	/* libpcap, tcpdump */
+#define	ETHERTYPE_LAT		0x6004	/* DEC LAT */
+#define	ETHERTYPE_DECDIAG	0x6005	/* DEC diagnostic protocol (at interface initialization?) */
+#define	ETHERTYPE_DECCUST	0x6006	/* DEC customer protocol */
+#define	ETHERTYPE_SCA		0x6007	/* DEC LAVC, SCA */
+#define	ETHERTYPE_AMBER		0x6008	/* DEC AMBER */
+#define	ETHERTYPE_DECMUMPS	0x6009	/* DEC MUMPS */
+		    /* 0x6010 - 0x6014	   3Com Corporation */
+#define	ETHERTYPE_TRANSETHER	0x6558	/* Trans Ether Bridging (RFC1701)*/
+#define	ETHERTYPE_RAWFR		0x6559	/* Raw Frame Relay (RFC1701) */
+#define	ETHERTYPE_UBDL		0x7000	/* Ungermann-Bass download */
+#define	ETHERTYPE_UBNIU		0x7001	/* Ungermann-Bass NIUs */
+#define	ETHERTYPE_UBDIAGLOOP	0x7002	/* Ungermann-Bass diagnostic/loopback */
+#define	ETHERTYPE_UBNMC		0x7003	/* Ungermann-Bass ??? (NMC to/from UB Bridge) */
+#define	ETHERTYPE_UBBST		0x7005	/* Ungermann-Bass Bridge Spanning Tree */
+#define	ETHERTYPE_OS9		0x7007	/* OS/9 Microware */
+#define	ETHERTYPE_OS9NET	0x7009	/* OS/9 Net? */
+		    /* 0x7020 - 0x7029	   LRT (England) (now Sintrom) */
+#define	ETHERTYPE_RACAL		0x7030	/* Racal-Interlan */
+#define	ETHERTYPE_PRIMENTS	0x7031	/* Prime NTS (Network Terminal Service) */
+#define	ETHERTYPE_CABLETRON	0x7034	/* Cabletron */
+#define	ETHERTYPE_CRONUSVLN	0x8003	/* Cronus VLN */
+#define	ETHERTYPE_CRONUS	0x8004	/* Cronus Direct */
+#define	ETHERTYPE_HP		0x8005	/* HP Probe */
+#define	ETHERTYPE_NESTAR	0x8006	/* Nestar */
+#define	ETHERTYPE_ATTSTANFORD	0x8008	/* AT&T/Stanford (local use) */
+#define	ETHERTYPE_EXCELAN	0x8010	/* Excelan */
+#define	ETHERTYPE_SG_DIAG	0x8013	/* SGI diagnostic type */
+#define	ETHERTYPE_SG_NETGAMES	0x8014	/* SGI network games */
+#define	ETHERTYPE_SG_RESV	0x8015	/* SGI reserved type */
+#define	ETHERTYPE_SG_BOUNCE	0x8016	/* SGI bounce server */
+#define	ETHERTYPE_APOLLODOMAIN	0x8019	/* Apollo DOMAIN */
+#define	ETHERTYPE_TYMSHARE	0x802E	/* Tymeshare */
+#define	ETHERTYPE_TIGAN		0x802F	/* Tigan, Inc. */
+#define	ETHERTYPE_REVARP	0x8035	/* Reverse addr resolution protocol */
+#define	ETHERTYPE_AEONIC	0x8036	/* Aeonic Systems */
+#define	ETHERTYPE_IPXNEW	0x8037	/* IPX (Novell Netware?) */
+#define	ETHERTYPE_LANBRIDGE	0x8038	/* DEC LANBridge */
+#define	ETHERTYPE_DSMD	0x8039	/* DEC DSM/DDP */
+#define	ETHERTYPE_ARGONAUT	0x803A	/* DEC Argonaut Console */
+#define	ETHERTYPE_VAXELN	0x803B	/* DEC VAXELN */
+#define	ETHERTYPE_DECDNS	0x803C	/* DEC DNS Naming Service */
+#define	ETHERTYPE_ENCRYPT	0x803D	/* DEC Ethernet Encryption */
+#define	ETHERTYPE_DECDTS	0x803E	/* DEC Distributed Time Service */
+#define	ETHERTYPE_DECLTM	0x803F	/* DEC LAN Traffic Monitor */
+#define	ETHERTYPE_DECNETBIOS	0x8040	/* DEC PATHWORKS DECnet NETBIOS Emulation */
+#define	ETHERTYPE_DECLAST	0x8041	/* DEC Local Area System Transport */
+			     /* 0x8042	   DEC Unassigned */
+#define	ETHERTYPE_PLANNING	0x8044	/* Planning Research Corp. */
+		    /* 0x8046 - 0x8047	   AT&T */
+#define	ETHERTYPE_DECAM		0x8048	/* DEC Availability Manager for Distributed Systems DECamds (but someone at DEC says not) */
+#define	ETHERTYPE_EXPERDATA	0x8049	/* ExperData */
+#define	ETHERTYPE_VEXP		0x805B	/* Stanford V Kernel exp. */
+#define	ETHERTYPE_VPROD		0x805C	/* Stanford V Kernel prod. */
+#define	ETHERTYPE_ES		0x805D	/* Evans & Sutherland */
+#define	ETHERTYPE_LITTLE	0x8060	/* Little Machines */
+#define	ETHERTYPE_COUNTERPOINT	0x8062	/* Counterpoint Computers */
+		    /* 0x8065 - 0x8066	   Univ. of Mass @ Amherst */
+#define	ETHERTYPE_VEECO		0x8067	/* Veeco Integrated Auto. */
+#define	ETHERTYPE_GENDYN	0x8068	/* General Dynamics */
+#define	ETHERTYPE_ATT		0x8069	/* AT&T */
+#define	ETHERTYPE_AUTOPHON	0x806A	/* Autophon */
+#define	ETHERTYPE_COMDESIGN	0x806C	/* ComDesign */
+#define	ETHERTYPE_COMPUGRAPHIC	0x806D	/* Compugraphic Corporation */
+		    /* 0x806E - 0x8077	   Landmark Graphics Corp. */
+#define	ETHERTYPE_MATRA		0x807A	/* Matra */
+#define	ETHERTYPE_DDE		0x807B	/* Dansk Data Elektronik */
+#define	ETHERTYPE_MERIT		0x807C	/* Merit Internodal (or Univ of Michigan?) */
+		    /* 0x807D - 0x807F	   Vitalink Communications */
+#define	ETHERTYPE_VLTLMAN	0x8080	/* Vitalink TransLAN III Management */
+		    /* 0x8081 - 0x8083	   Counterpoint Computers */
+		    /* 0x8088 - 0x808A	   Xyplex */
+#define	ETHERTYPE_ATALK		0x809B	/* AppleTalk */
+#define	ETHERTYPE_AT		ETHERTYPE_ATALK		/* old NetBSD */
+#define	ETHERTYPE_APPLETALK	ETHERTYPE_ATALK		/* HP-UX */
+		    /* 0x809C - 0x809E	   Datability */
+#define	ETHERTYPE_SPIDER	0x809F	/* Spider Systems Ltd. */
+			     /* 0x80A3	   Nixdorf */
+		    /* 0x80A4 - 0x80B3	   Siemens Gammasonics Inc. */
+		    /* 0x80C0 - 0x80C3	   DCA (Digital Comm. Assoc.) Data Exchange Cluster */
+		    /* 0x80C4 - 0x80C5	   Banyan Systems */
+#define	ETHERTYPE_PACER		0x80C6	/* Pacer Software */
+#define	ETHERTYPE_APPLITEK	0x80C7	/* Applitek Corporation */
+		    /* 0x80C8 - 0x80CC	   Intergraph Corporation */
+		    /* 0x80CD - 0x80CE	   Harris Corporation */
+		    /* 0x80CF - 0x80D2	   Taylor Instrument */
+		    /* 0x80D3 - 0x80D4	   Rosemount Corporation */
+#define	ETHERTYPE_SNA		0x80D5	/* IBM SNA Services over Ethernet */
+#define	ETHERTYPE_VARIAN	0x80DD	/* Varian Associates */
+		    /* 0x80DE - 0x80DF	   TRFS (Integrated Solutions Transparent Remote File System) */
+		    /* 0x80E0 - 0x80E3	   Allen-Bradley */
+		    /* 0x80E4 - 0x80F0	   Datability */
+#define	ETHERTYPE_RETIX		0x80F2	/* Retix */
+#define	ETHERTYPE_AARP		0x80F3	/* AppleTalk AARP */
+		    /* 0x80F4 - 0x80F5	   Kinetics */
+#define	ETHERTYPE_APOLLO	0x80F7	/* Apollo Computer */
+#define ETHERTYPE_VLAN		0x8100	/* IEEE 802.1Q VLAN tagging (XXX conflicts) */
+		    /* 0x80FF - 0x8101	   Wellfleet Communications (XXX conflicts) */
+#define	ETHERTYPE_BOFL		0x8102	/* Wellfleet; BOFL (Breath OF Life) pkts [every 5-10 secs.] */
+#define	ETHERTYPE_WELLFLEET	0x8103	/* Wellfleet Communications */
+		    /* 0x8107 - 0x8109	   Symbolics Private */
+#define	ETHERTYPE_TALARIS	0x812B	/* Talaris */
+#define	ETHERTYPE_WATERLOO	0x8130	/* Waterloo Microsystems Inc. (XXX which?) */
+#define	ETHERTYPE_HAYES		0x8130	/* Hayes Microcomputers (XXX which?) */
+#define	ETHERTYPE_VGLAB		0x8131	/* VG Laboratory Systems */
+		    /* 0x8132 - 0x8137	   Bridge Communications */
+#define	ETHERTYPE_IPX		0x8137	/* Novell (old) NetWare IPX (ECONFIG E option) */
+#define	ETHERTYPE_NOVELL	0x8138	/* Novell, Inc. */
+		    /* 0x8139 - 0x813D	   KTI */
+#define	ETHERTYPE_MUMPS		0x813F	/* M/MUMPS data sharing */
+#define	ETHERTYPE_AMOEBA	0x8145	/* Vrije Universiteit (NL) Amoeba 4 RPC (obsolete) */
+#define	ETHERTYPE_FLIP		0x8146	/* Vrije Universiteit (NL) FLIP (Fast Local Internet Protocol) */
+#define	ETHERTYPE_VURESERVED	0x8147	/* Vrije Universiteit (NL) [reserved] */
+#define	ETHERTYPE_LOGICRAFT	0x8148	/* Logicraft */
+#define	ETHERTYPE_NCD		0x8149	/* Network Computing Devices */
+#define	ETHERTYPE_ALPHA		0x814A	/* Alpha Micro */
+#define	ETHERTYPE_SNMP		0x814C	/* SNMP over Ethernet (see RFC1089) */
+		    /* 0x814D - 0x814E	   BIIN */
+#define	ETHERTYPE_TEC	0x814F	/* Technically Elite Concepts */
+#define	ETHERTYPE_RATIONAL	0x8150	/* Rational Corp */
+		    /* 0x8151 - 0x8153	   Qualcomm */
+		    /* 0x815C - 0x815E	   Computer Protocol Pty Ltd */
+		    /* 0x8164 - 0x8166	   Charles River Data Systems */
+#define	ETHERTYPE_XTP		0x817D	/* Protocol Engines XTP */
+#define	ETHERTYPE_SGITW		0x817E	/* SGI/Time Warner prop. */
+#define	ETHERTYPE_HIPPI_FP	0x8180	/* HIPPI-FP encapsulation */
+#define	ETHERTYPE_STP		0x8181	/* Scheduled Transfer STP, HIPPI-ST */
+		    /* 0x8182 - 0x8183	   Reserved for HIPPI-6400 */
+		    /* 0x8184 - 0x818C	   SGI prop. */
+#define	ETHERTYPE_MOTOROLA	0x818D	/* Motorola */
+#define	ETHERTYPE_NETBEUI	0x8191	/* PowerLAN NetBIOS/NetBEUI (PC) */
+		    /* 0x819A - 0x81A3	   RAD Network Devices */
+		    /* 0x81B7 - 0x81B9	   Xyplex */
+		    /* 0x81CC - 0x81D5	   Apricot Computers */
+		    /* 0x81D6 - 0x81DD	   Artisoft Lantastic */
+		    /* 0x81E6 - 0x81EF	   Polygon */
+		    /* 0x81F0 - 0x81F2	   Comsat Labs */
+		    /* 0x81F3 - 0x81F5	   SAIC */
+		    /* 0x81F6 - 0x81F8	   VG Analytical */
+		    /* 0x8203 - 0x8205	   QNX Software Systems Ltd. */
+		    /* 0x8221 - 0x8222	   Ascom Banking Systems */
+		    /* 0x823E - 0x8240	   Advanced Encryption Systems */
+		    /* 0x8263 - 0x826A	   Charles River Data Systems */
+		    /* 0x827F - 0x8282	   Athena Programming */
+		    /* 0x829A - 0x829B	   Inst Ind Info Tech */
+		    /* 0x829C - 0x82AB	   Taurus Controls */
+		    /* 0x82AC - 0x8693	   Walker Richer & Quinn */
+#define	ETHERTYPE_ACCTON	0x8390	/* Accton Technologies (unregistered) */
+#define	ETHERTYPE_TALARISMC	0x852B	/* Talaris multicast */
+#define	ETHERTYPE_KALPANA	0x8582	/* Kalpana */
+		    /* 0x8694 - 0x869D	   Idea Courier */
+		    /* 0x869E - 0x86A1	   Computer Network Tech */
+		    /* 0x86A3 - 0x86AC	   Gateway Communications */
+#define	ETHERTYPE_SECTRA	0x86DB	/* SECTRA */
+#define	ETHERTYPE_IPV6		0x86DD	/* IP protocol version 6 */
+#define	ETHERTYPE_DELTACON	0x86DE	/* Delta Controls */
+#define	ETHERTYPE_ATOMIC	0x86DF	/* ATOMIC */
+		    /* 0x86E0 - 0x86EF	   Landis & Gyr Powers */
+		    /* 0x8700 - 0x8710	   Motorola */
+#define	ETHERTYPE_RDP		0x8739	/* Control Technology Inc. RDP Without IP */
+#define	ETHERTYPE_MICP		0x873A	/* Control Technology Inc. Mcast Industrial Ctrl Proto. */
+		    /* 0x873B - 0x873C	   Control Technology Inc. Proprietary */
+#define	ETHERTYPE_TCPCOMP	0x876B	/* TCP/IP Compression (RFC1701) */
+#define	ETHERTYPE_IPAS		0x876C	/* IP Autonomous Systems (RFC1701) */
+#define	ETHERTYPE_SECUREDATA	0x876D	/* Secure Data (RFC1701) */
+#define	ETHERTYPE_FLOWCONTROL	0x8808	/* 802.3x flow control packet */
+#define	ETHERTYPE_SLOW		0x8809	/* 802.3ad link aggregation (LACP) */
+#define	ETHERTYPE_PPP		0x880B	/* PPP (obsolete by PPPoE) */
+#define	ETHERTYPE_HITACHI	0x8820	/* Hitachi Cable (Optoelectronic Systems Laboratory) */
+#define	ETHERTYPE_MPLS		0x8847	/* MPLS Unicast */
+#define	ETHERTYPE_MPLS_MCAST	0x8848	/* MPLS Multicast */
+#define	ETHERTYPE_AXIS		0x8856	/* Axis Communications AB proprietary bootstrap/config */
+#define	ETHERTYPE_PPPOEDISC	0x8863	/* PPP Over Ethernet Discovery Stage */
+#define	ETHERTYPE_PPPOE		0x8864	/* PPP Over Ethernet Session Stage */
+#define	ETHERTYPE_LANPROBE	0x8888	/* HP LanProbe test? */
+#define	ETHERTYPE_PAE		0x888e	/* EAPOL PAE/802.1x */
+#define	ETHERTYPE_LOOPBACK	0x9000	/* Loopback: used to test interfaces */
+#define	ETHERTYPE_LBACK		ETHERTYPE_LOOPBACK	/* DEC MOP loopback */
+#define	ETHERTYPE_XNSSM		0x9001	/* 3Com (Formerly Bridge Communications), XNS Systems Management */
+#define	ETHERTYPE_TCPSM		0x9002	/* 3Com (Formerly Bridge Communications), TCP/IP Systems Management */
+#define	ETHERTYPE_BCLOOP	0x9003	/* 3Com (Formerly Bridge Communications), loopback detection */
+#define	ETHERTYPE_DEBNI		0xAAAA	/* DECNET? Used by VAX 6220 DEBNI */
+#define	ETHERTYPE_SONIX		0xFAF5	/* Sonix Arpeggio */
+#define	ETHERTYPE_VITAL		0xFF00	/* BBN VITAL-LanBridge cache wakeups */
+		    /* 0xFF00 - 0xFFOF	   ISC Bunker Ramo */
+
+#define	ETHERTYPE_MAX		0xFFFF	/* Maximum valid ethernet type, reserved */
+
+/*
+ * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have
+ * (type-ETHERTYPE_TRAIL)*512 bytes of data followed
+ * by an ETHER type (as given above) and then the (variable-length) header.
+ */
+#define	ETHERTYPE_TRAIL		0x1000		/* Trailer packet */
+#define	ETHERTYPE_NTRAILER	16
+
+#define	ETHERMTU	(ETHER_MAX_LEN-ETHER_HDR_LEN-ETHER_CRC_LEN)
+#define	ETHERMIN	(ETHER_MIN_LEN-ETHER_HDR_LEN-ETHER_CRC_LEN)
+#define	ETHERMTU_JUMBO	(ETHER_MAX_LEN_JUMBO - ETHER_HDR_LEN - ETHER_CRC_LEN)
+/*
+ * The ETHER_BPF_MTAP macro should be used by drivers which support hardware
+ * offload for VLAN tag processing.  It will check the mbuf to see if it has
+ * M_VLANTAG set, and if it does, will pass the packet along to
+ * ether_vlan_mtap.  This function will re-insert VLAN tags for the duration
+ * of the tap, so they show up properly for network analyzers.
+ */
+#define ETHER_BPF_MTAP(_ifp, _m) do {					\
+	if (bpf_peers_present((_ifp)->if_bpf)) {			\
+		M_ASSERTVALID(_m);					\
+		if (((_m)->m_flags & M_VLANTAG) != 0)			\
+			ether_vlan_mtap((_ifp)->if_bpf, (_m), NULL, 0);	\
+		else							\
+			bpf_mtap((_ifp)->if_bpf, (_m));			\
+	}								\
+} while (0)
+
+#ifdef _KERNEL
+
+struct ifnet;
+struct mbuf;
+struct route;
+struct sockaddr;
+struct bpf_if;
+
+extern	uint32_t ether_crc32_le(const uint8_t *, size_t);
+extern	uint32_t ether_crc32_be(const uint8_t *, size_t);
+extern	void ether_demux(struct ifnet *, struct mbuf *);
+extern	void ether_ifattach(struct ifnet *, const u_int8_t *);
+extern	void ether_ifdetach(struct ifnet *);
+extern	int  ether_ioctl(struct ifnet *, u_long, caddr_t);
+extern	int  ether_output(struct ifnet *,
+		   struct mbuf *, struct sockaddr *, struct route *);
+extern	int  ether_output_frame(struct ifnet *, struct mbuf *);
+extern	char *ether_sprintf(const u_int8_t *);
+void	ether_vlan_mtap(struct bpf_if *, struct mbuf *,
+	    void *, u_int);
+struct mbuf  *ether_vlanencap(struct mbuf *, uint16_t);
+
+#else /* _KERNEL */
+
+#include <sys/cdefs.h>
+
+/*
+ * Ethernet address conversion/parsing routines.
+ */
+__BEGIN_DECLS
+struct	ether_addr *ether_aton(const char *);
+struct	ether_addr *ether_aton_r(const char *, struct ether_addr *);
+int	ether_hostton(const char *, struct ether_addr *);
+int	ether_line(const char *, struct ether_addr *, char *);
+char 	*ether_ntoa(const struct ether_addr *);
+char 	*ether_ntoa_r(const struct ether_addr *, char *);
+int	ether_ntohost(char *, const struct ether_addr *);
+__END_DECLS
+
+#endif /* !_KERNEL */
+
+#endif /* !_NET_ETHERNET_H_ */
diff --git a/lib/librte_eal/windows/include_override/netinet/in.h b/lib/librte_eal/windows/include_override/netinet/in.h
new file mode 100644
index 000000000..5d4f411a3
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/netinet/in.h
@@ -0,0 +1,48 @@
+#ifndef _IN_H_
+#define _IN_H_
+
+/*
+ * IPv6 address
+ */
+struct in6_addr {
+	union {
+		uint8_t		__u6_addr8[16];
+		uint16_t	__u6_addr16[8];
+		uint32_t	__u6_addr32[4];
+	} __u6_addr;		/* 128-bit IP6 address */
+};
+
+#define INET6_ADDRSTRLEN	46
+
+#ifndef _IN_ADDR_T_DECLARED
+typedef uint32_t		in_addr_t;
+#define	_IN_ADDR_T_DECLARED
+#endif
+
+// #define	_STRUCT_IN_ADDR_DECLARED
+/* Internet address (a structure for historical reasons). */
+#ifndef	_STRUCT_IN_ADDR_DECLARED
+struct in_addr {
+	in_addr_t s_addr;
+};
+#define	_STRUCT_IN_ADDR_DECLARED
+#endif
+
+#define AF_INET			0
+
+#define IPPROTO_IP		0
+#define IPPROTO_HOPOPTS		0
+#define	IPPROTO_IPV4		4		/* IPv4 encapsulation */
+#define	IPPROTO_IPIP		IPPROTO_IPV4	/* for compatibility */
+#define IPPROTO_TCP		6
+#define IPPROTO_UDP		17
+#define	IPPROTO_IPV6		41		/* IP6 header */
+#define	IPPROTO_ROUTING		43		/* IP6 routing header */
+#define	IPPROTO_FRAGMENT	44		/* IP6 fragmentation header */
+#define	IPPROTO_GRE		47		/* General Routing Encap. */
+#define	IPPROTO_ESP		50		/* IP6 Encap Sec. Payload */
+#define	IPPROTO_AH		51		/* IP6 Auth Header */
+#define	IPPROTO_DSTOPTS		60		/* IP6 destination option */
+
+
+#endif
diff --git a/lib/librte_eal/windows/include_override/netinet/tcp.h b/lib/librte_eal/windows/include_override/netinet/tcp.h
new file mode 100644
index 000000000..250c4c354
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/netinet/tcp.h
@@ -0,0 +1,4 @@
+#ifndef NETINET_TCP_H
+#define NETINET_TCP_H
+
+#endif
diff --git a/lib/librte_eal/windows/include_override/pthread.h b/lib/librte_eal/windows/include_override/pthread.h
new file mode 100644
index 000000000..1505842e8
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/pthread.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#ifndef _PTHREAD_H_
+#define _PTHREAD_H_
+
+#define PTHREAD_BARRIER_SERIAL_THREAD TRUE
+
+typedef void* pthread_t;
+typedef void pthread_attr_t;
+typedef SYNCHRONIZATION_BARRIER pthread_barrier_t;
+typedef HANDLE pthread_mutex_t;
+
+#define pthread_barrier_init(barrier,attr,count) InitializeSynchronizationBarrier(barrier,count,-1)
+#define pthread_barrier_wait(barrier) EnterSynchronizationBarrier(barrier,SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY)
+#define pthread_barrier_destroy(barrier) DeleteSynchronizationBarrier(barrier)
+#define pthread_cancel(thread) TerminateThread(thread,0)
+#define pthread_mutex_lock(mutex) WaitForSingleObject(mutex,INFINITE)
+#define pthread_mutex_unlock(mutex) ReleaseMutex(mutex)
+#define pthread_cond_signal(condition_variable) WakeConditionVariable(condition_variable)
+
+
+// pthread function overrides
+#define pthread_self()                                          ((pthread_t)GetCurrentThreadId())
+#define pthread_setaffinity_np(thread,size,cpuset)              WinSetThreadAffinityMask(thread, cpuset)
+#define pthread_getaffinity_np(thread,size,cpuset)              WinGetThreadAffinityMask(thread, cpuset)
+#define pthread_create(threadID, threadattr, threadfunc, args)  WinCreateThreadOverride(threadID, threadattr, threadfunc, args)
+
+typedef int pid_t;
+pid_t fork(void);
+
+static inline int WinSetThreadAffinityMask(void* threadID, unsigned long *cpuset)
+{
+	DWORD dwPrevAffinityMask = SetThreadAffinityMask(threadID, *cpuset);
+	return 0;
+}
+
+static inline int WinGetThreadAffinityMask(void* threadID, unsigned long *cpuset)
+{
+	/* Workaround for the lack of a GetThreadAffinityMask() API in Windows */
+	DWORD dwPrevAffinityMask = SetThreadAffinityMask(threadID, 0x1); /* obtain previous mask by setting dummy mask */
+	SetThreadAffinityMask(threadID, dwPrevAffinityMask); /* set it back! */
+	*cpuset = dwPrevAffinityMask;
+	return 0;
+}
+
+static inline int WinCreateThreadOverride(void* threadID, const void* threadattr, void* threadfunc, void* args)
+{
+	HANDLE hThread;
+	hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadfunc, args, 0, (LPDWORD)threadID);
+	if (hThread)
+	{
+		SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
+		SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);
+	}
+	return ((hThread != NULL) ? 0 : E_FAIL);
+}
+
+static inline int pthread_join(void* thread, void **value_ptr)
+{
+	return 0;
+}
+
+#endif /* _PTHREAD_H_ */
diff --git a/lib/librte_eal/windows/include_override/rand48.h b/lib/librte_eal/windows/include_override/rand48.h
new file mode 100644
index 000000000..4adabb794
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/rand48.h
@@ -0,0 +1,32 @@
+/*
+* Copyright (c) 1993 Martin Birgmeier
+* All rights reserved.
+*
+* You may redistribute unmodified or modified versions of this source
+* code provided that the above copyright notice and this and the
+* following conditions are retained.
+*
+* This software is provided ``as is'', and comes with no warranties
+* of any kind. I shall in no event be liable for anything that happens
+* to anyone/anything when using this software.
+*/
+
+#ifndef _RAND48_H_
+#define _RAND48_H_
+
+#include <math.h>
+#include <stdlib.h>
+
+void _dorand48(unsigned short[3]);
+void srand48(long seed);
+long lrand48(void);
+
+#define	RAND48_SEED_0	(0x330e)
+#define	RAND48_SEED_1	(0xabcd)
+#define	RAND48_SEED_2	(0x1234)
+#define	RAND48_MULT_0	(0xe66d)
+#define	RAND48_MULT_1	(0xdeec)
+#define	RAND48_MULT_2	(0x0005)
+#define	RAND48_ADD	(0x000b)
+
+#endif /* _RAND48_H_ */
diff --git a/lib/librte_eal/windows/include_override/sched.h b/lib/librte_eal/windows/include_override/sched.h
new file mode 100644
index 000000000..1a2df795c
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/sched.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+
+#ifndef _SCHED_H_
+#define _SCHED_H_
+
+/* Re-defined for Windows */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int sched_yield(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SCHED_H_ */
diff --git a/lib/librte_eal/windows/include_override/sys/_iovec.h b/lib/librte_eal/windows/include_override/sys/_iovec.h
new file mode 100644
index 000000000..bd7207332
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/sys/_iovec.h
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 1982, 1986, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)uio.h	8.5 (Berkeley) 2/22/94
+ * $FreeBSD$
+ */
+
+#ifndef _SYS__IOVEC_H_
+#define	_SYS__IOVEC_H_
+
+#include <sys/_types.h>
+
+#ifndef _SIZE_T_DECLARED
+typedef	__size_t	size_t;
+#define	_SIZE_T_DECLARED
+#endif
+
+struct iovec {
+	void	*iov_base;	/* Base address. */
+	size_t	 iov_len;	/* Length. */
+};
+
+#endif /* !_SYS__IOVEC_H_ */
diff --git a/lib/librte_eal/windows/include_override/sys/_sockaddr_storage.h b/lib/librte_eal/windows/include_override/sys/_sockaddr_storage.h
new file mode 100644
index 000000000..5c0048b56
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/sys/_sockaddr_storage.h
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 1982, 1985, 1986, 1988, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)socket.h	8.4 (Berkeley) 2/21/94
+ * $FreeBSD$
+ */
+
+#ifndef _SYS__SOCKADDR_STORAGE_H_
+#define	_SYS__SOCKADDR_STORAGE_H_
+
+/*
+ * RFC 2553: protocol-independent placeholder for socket addresses
+ */
+#define	_SS_MAXSIZE	128U
+#define	_SS_ALIGNSIZE	(sizeof(__int64_t))
+#define	_SS_PAD1SIZE	(_SS_ALIGNSIZE - sizeof(unsigned char) - \
+			    sizeof(sa_family_t))
+#define	_SS_PAD2SIZE	(_SS_MAXSIZE - sizeof(unsigned char) - \
+			    sizeof(sa_family_t) - _SS_PAD1SIZE - _SS_ALIGNSIZE)
+
+struct sockaddr_storage {
+	unsigned char	ss_len;		/* address length */
+	sa_family_t	ss_family;	/* address family */
+	char		__ss_pad1[_SS_PAD1SIZE];
+	__int64_t	__ss_align;	/* force desired struct alignment */
+	char		__ss_pad2[_SS_PAD2SIZE];
+};
+
+#endif /* !_SYS__SOCKADDR_STORAGE_H_ */
diff --git a/lib/librte_eal/windows/include_override/sys/_termios.h b/lib/librte_eal/windows/include_override/sys/_termios.h
new file mode 100644
index 000000000..ae07158a9
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/sys/_termios.h
@@ -0,0 +1,222 @@
+/*-
+ * Copyright (c) 1988, 1989, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)termios.h	8.3 (Berkeley) 3/28/94
+ * $FreeBSD: release/9.1.0/sys/sys/_termios.h 199898 2009-11-28 23:50:48Z ed $
+ */
+
+#ifndef _SYS__TERMIOS_H_
+#define	_SYS__TERMIOS_H_
+
+/*
+ * Special Control Characters
+ *
+ * Index into c_cc[] character array.
+ *
+ *	Name	     Subscript	Enabled by
+ */
+#define	VEOF		0	/* ICANON */
+#define	VEOL		1	/* ICANON */
+#ifndef _POSIX_SOURCE
+#define	VEOL2		2	/* ICANON together with IEXTEN */
+#endif
+#define	VERASE		3	/* ICANON */
+#ifndef _POSIX_SOURCE
+#define	VWERASE 	4	/* ICANON together with IEXTEN */
+#endif
+#define	VKILL		5	/* ICANON */
+#ifndef _POSIX_SOURCE
+#define	VREPRINT 	6	/* ICANON together with IEXTEN */
+#define	VERASE2 	7	/* ICANON */
+#endif
+/*			7	   ex-spare 1 */
+#define	VINTR		8	/* ISIG */
+#define	VQUIT		9	/* ISIG */
+#define	VSUSP		10	/* ISIG */
+#ifndef _POSIX_SOURCE
+#define	VDSUSP		11	/* ISIG together with IEXTEN */
+#endif
+#define	VSTART		12	/* IXON, IXOFF */
+#define	VSTOP		13	/* IXON, IXOFF */
+#ifndef _POSIX_SOURCE
+#define	VLNEXT		14	/* IEXTEN */
+#define	VDISCARD	15	/* IEXTEN */
+#endif
+#define	VMIN		16	/* !ICANON */
+#define	VTIME		17	/* !ICANON */
+#ifndef _POSIX_SOURCE
+#define	VSTATUS		18	/* ICANON together with IEXTEN */
+/*			19	   spare 2 */
+#endif
+#define	NCCS		20
+
+#define	_POSIX_VDISABLE	0xff
+
+/*
+ * Input flags - software input processing
+ */
+#define	IGNBRK		0x00000001	/* ignore BREAK condition */
+#define	BRKINT		0x00000002	/* map BREAK to SIGINTR */
+#define	IGNPAR		0x00000004	/* ignore (discard) parity errors */
+#define	PARMRK		0x00000008	/* mark parity and framing errors */
+#define	INPCK		0x00000010	/* enable checking of parity errors */
+#define	ISTRIP		0x00000020	/* strip 8th bit off chars */
+#define	INLCR		0x00000040	/* map NL into CR */
+#define	IGNCR		0x00000080	/* ignore CR */
+#define	ICRNL		0x00000100	/* map CR to NL (ala CRMOD) */
+#define	IXON		0x00000200	/* enable output flow control */
+#define	IXOFF		0x00000400	/* enable input flow control */
+#ifndef _POSIX_SOURCE
+#define	IXANY		0x00000800	/* any char will restart after stop */
+#define	IMAXBEL		0x00002000	/* ring bell on input queue full */
+#endif  /*_POSIX_SOURCE */
+
+/*
+ * Output flags - software output processing
+ */
+#define	OPOST		0x00000001	/* enable following output processing */
+#ifndef _POSIX_SOURCE
+#define	ONLCR		0x00000002	/* map NL to CR-NL (ala CRMOD) */
+#define	TABDLY		0x00000004	/* tab delay mask */
+#define	    TAB0	    0x00000000	    /* no tab delay and expansion */
+#define	    TAB3	    0x00000004	    /* expand tabs to spaces */
+#define	ONOEOT		0x00000008	/* discard EOT's (^D) on output) */
+#define	OCRNL		0x00000010	/* map CR to NL on output */
+#define	ONOCR		0x00000020	/* no CR output at column 0 */
+#define	ONLRET		0x00000040	/* NL performs CR function */
+#endif  /*_POSIX_SOURCE */
+
+/*
+ * Control flags - hardware control of terminal
+ */
+#ifndef _POSIX_SOURCE
+#define	CIGNORE		0x00000001	/* ignore control flags */
+#endif
+#define	CSIZE		0x00000300	/* character size mask */
+#define	    CS5		    0x00000000	    /* 5 bits (pseudo) */
+#define	    CS6		    0x00000100	    /* 6 bits */
+#define	    CS7		    0x00000200	    /* 7 bits */
+#define	    CS8		    0x00000300	    /* 8 bits */
+#define	CSTOPB		0x00000400	/* send 2 stop bits */
+#define	CREAD		0x00000800	/* enable receiver */
+#define	PARENB		0x00001000	/* parity enable */
+#define	PARODD		0x00002000	/* odd parity, else even */
+#define	HUPCL		0x00004000	/* hang up on last close */
+#define	CLOCAL		0x00008000	/* ignore modem status lines */
+#ifndef _POSIX_SOURCE
+#define	CCTS_OFLOW	0x00010000	/* CTS flow control of output */
+#define	CRTSCTS		(CCTS_OFLOW | CRTS_IFLOW)
+#define	CRTS_IFLOW	0x00020000	/* RTS flow control of input */
+#define	CDTR_IFLOW	0x00040000	/* DTR flow control of input */
+#define	CDSR_OFLOW	0x00080000	/* DSR flow control of output */
+#define	CCAR_OFLOW	0x00100000	/* DCD flow control of output */
+#endif
+
+
+/*
+ * "Local" flags - dumping ground for other state
+ *
+ * Warning: some flags in this structure begin with
+ * the letter "I" and look like they belong in the
+ * input flag.
+ */
+
+#ifndef _POSIX_SOURCE
+#define	ECHOKE		0x00000001	/* visual erase for line kill */
+#endif  /*_POSIX_SOURCE */
+#define	ECHOE		0x00000002	/* visually erase chars */
+#define	ECHOK		0x00000004	/* echo NL after line kill */
+#define	ECHO		0x00000008	/* enable echoing */
+#define	ECHONL		0x00000010	/* echo NL even if ECHO is off */
+#ifndef _POSIX_SOURCE
+#define	ECHOPRT		0x00000020	/* visual erase mode for hardcopy */
+#define	ECHOCTL  	0x00000040	/* echo control chars as ^(Char) */
+#endif  /*_POSIX_SOURCE */
+#define	ISIG		0x00000080	/* enable signals INTR, QUIT, [D]SUSP */
+#define	ICANON		0x00000100	/* canonicalize input lines */
+#ifndef _POSIX_SOURCE
+#define	ALTWERASE	0x00000200	/* use alternate WERASE algorithm */
+#endif  /*_POSIX_SOURCE */
+#define	IEXTEN		0x00000400	/* enable DISCARD and LNEXT */
+#define	EXTPROC         0x00000800      /* external processing */
+#define	TOSTOP		0x00400000	/* stop background jobs from output */
+#ifndef _POSIX_SOURCE
+#define	FLUSHO		0x00800000	/* output being flushed (state) */
+#define	NOKERNINFO	0x02000000	/* no kernel output from VSTATUS */
+#define	PENDIN		0x20000000	/* XXX retype pending input (state) */
+#endif  /*_POSIX_SOURCE */
+#define	NOFLSH		0x80000000	/* don't flush after interrupt */
+
+/*
+ * Standard speeds
+ */
+#define	B0	0
+#define	B50	50
+#define	B75	75
+#define	B110	110
+#define	B134	134
+#define	B150	150
+#define	B200	200
+#define	B300	300
+#define	B600	600
+#define	B1200	1200
+#define	B1800	1800
+#define	B2400	2400
+#define	B4800	4800
+#define	B9600	9600
+#define	B19200	19200
+#define	B38400	38400
+#ifndef _POSIX_SOURCE
+#define	B7200	7200
+#define	B14400	14400
+#define	B28800	28800
+#define	B57600	57600
+#define	B76800	76800
+#define	B115200	115200
+#define	B230400	230400
+#define	B460800	460800
+#define	B921600	921600
+#define	EXTA	19200
+#define	EXTB	38400
+#endif  /* !_POSIX_SOURCE */
+
+typedef unsigned int	tcflag_t;
+typedef unsigned char	cc_t;
+typedef unsigned int	speed_t;
+
+struct termios {
+	tcflag_t	c_iflag;	/* input flags */
+	tcflag_t	c_oflag;	/* output flags */
+	tcflag_t	c_cflag;	/* control flags */
+	tcflag_t	c_lflag;	/* local flags */
+	cc_t		c_cc[NCCS];	/* control chars */
+	speed_t		c_ispeed;	/* input speed */
+	speed_t		c_ospeed;	/* output speed */
+};
+
+#endif /* !_SYS__TERMIOS_H_ */
diff --git a/lib/librte_eal/windows/include_override/sys/_types.h b/lib/librte_eal/windows/include_override/sys/_types.h
new file mode 100644
index 000000000..27ecaf4f0
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/sys/_types.h
@@ -0,0 +1,105 @@
+/*-
+ * Copyright (c) 2002 Mike Barcroft <mike@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS__TYPES_H_
+#define _SYS__TYPES_H_
+
+#include <sys/cdefs.h>
+#include <machine/_types.h>
+
+/*
+ * Standard type definitions.
+ */
+typedef	__uint32_t	__blksize_t;	/* file block size */
+typedef	__int64_t	__blkcnt_t;	/* file block count */
+typedef	__int32_t	__clockid_t;	/* clock_gettime()... */
+typedef	__uint64_t	__cap_rights_t;	/* capability rights */
+typedef	__uint32_t	__fflags_t;	/* file flags */
+typedef	__uint64_t	__fsblkcnt_t;
+typedef	__uint64_t	__fsfilcnt_t;
+typedef	__uint32_t	__gid_t;
+typedef	__int64_t	__id_t;		/* can hold a gid_t, pid_t, or uid_t */
+typedef	__uint32_t	__ino_t;	/* inode number */
+typedef	long		__key_t;	/* IPC key (for Sys V IPC) */
+typedef	__int32_t	__lwpid_t;	/* Thread ID (a.k.a. LWP) */
+typedef	__uint16_t	__mode_t;	/* permissions */
+typedef	int		__accmode_t;	/* access permissions */
+typedef	int		__nl_item;
+typedef	__uint16_t	__nlink_t;	/* link count */
+typedef	__int64_t	__off_t;	/* file offset */
+typedef	__int32_t	__pid_t;	/* process [group] */
+typedef	__int64_t	__rlim_t;	/* resource limit - intentionally */
+					/* signed, because of legacy code */
+					/* that uses -1 for RLIM_INFINITY */
+typedef	__uint8_t	__sa_family_t;
+typedef	__uint32_t	__socklen_t;
+typedef	long		__suseconds_t;	/* microseconds (signed) */
+typedef	struct __timer	*__timer_t;	/* timer_gettime()... */
+typedef	struct __mq	*__mqd_t;	/* mq_open()... */
+typedef	__uint32_t	__uid_t;
+typedef	unsigned int	__useconds_t;	/* microseconds (unsigned) */
+typedef	int		__cpuwhich_t;	/* which parameter for cpuset. */
+typedef	int		__cpulevel_t;	/* level parameter for cpuset. */
+typedef int		__cpusetid_t;	/* cpuset identifier. */
+
+/*
+ * Unusual type definitions.
+ */
+/*
+ * rune_t is declared to be an ``int'' instead of the more natural
+ * ``unsigned long'' or ``long''.  Two things are happening here.  It is not
+ * unsigned so that EOF (-1) can be naturally assigned to it and used.  Also,
+ * it looks like 10646 will be a 31 bit standard.  This means that if your
+ * ints cannot hold 32 bits, you will be in trouble.  The reason an int was
+ * chosen over a long is that the is*() and to*() routines take ints (says
+ * ANSI C), but they use __ct_rune_t instead of int.
+ *
+ * NOTE: rune_t is not covered by ANSI nor other standards, and should not
+ * be instantiated outside of lib/libc/locale.  Use wchar_t.  wint_t and
+ * rune_t must be the same type.  Also, wint_t should be able to hold all
+ * members of the largest character set plus one extra value (WEOF), and
+ * must be at least 16 bits.
+ */
+typedef	int		__ct_rune_t;	/* arg type for ctype funcs */
+typedef	__ct_rune_t	__rune_t;	/* rune_t (see above) */
+typedef	__ct_rune_t	__wint_t;	/* wint_t (see above) */
+
+typedef	__uint32_t	__dev_t;	/* device number */
+
+typedef	__uint32_t	__fixpt_t;	/* fixed point number */
+
+/*
+ * mbstate_t is an opaque object to keep conversion state during multibyte
+ * stream conversions.
+ */
+typedef union {
+	char		__mbstate8[128];
+	__int64_t	_mbstateL;	/* for alignment */
+} __mbstate_t;
+
+#endif /* !_SYS__TYPES_H_ */
diff --git a/lib/librte_eal/windows/include_override/sys/cdefs.h b/lib/librte_eal/windows/include_override/sys/cdefs.h
new file mode 100644
index 000000000..b4d2009c5
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/sys/cdefs.h
@@ -0,0 +1,3 @@
+#ifndef _SYS_CDEFS_H_
+#define _SYS_CDEFS_H_
+#endif
diff --git a/lib/librte_eal/windows/include_override/sys/mman.h b/lib/librte_eal/windows/include_override/sys/mman.h
new file mode 100644
index 000000000..7a0ff4258
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/sys/mman.h
@@ -0,0 +1,63 @@
+/*
+* sys/mman.h
+* mman-win32
+*/
+
+#ifndef _SYS_MMAN_H_
+#define _SYS_MMAN_H_
+
+#ifndef _WIN32_WINNT		// Allow use of features specific to Windows XP or later.
+#define _WIN32_WINNT 0x0501	// Change this to the appropriate value to target other versions of Windows.
+#endif
+
+/* All the headers include this file. */
+#ifndef _MSC_VER
+#include <_mingw.h>
+#endif
+
+/* Determine offset type */
+#include <stdint.h>
+#if defined(_WIN64)
+typedef int64_t OffsetType;
+#else
+typedef uint32_t OffsetType;
+#endif
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PROT_NONE       0
+#define PROT_READ       1
+#define PROT_WRITE      2
+#define PROT_EXEC       4
+
+#define MAP_FILE        0
+#define MAP_SHARED      1
+#define MAP_PRIVATE     2
+#define MAP_TYPE        0xf
+#define MAP_FIXED       0x10
+#define MAP_ANONYMOUS   0x20
+#define MAP_ANON        MAP_ANONYMOUS
+
+#define MAP_FAILED      ((void *)-1)
+
+	/* Flags for msync. */
+#define MS_ASYNC        1
+#define MS_SYNC         2
+#define MS_INVALIDATE   4
+
+	void*   mmap(void *addr, size_t len, int prot, int flags, int fildes, OffsetType off);
+	int     munmap(void *addr, size_t len);
+	int     _mprotect(void *addr, size_t len, int prot);
+	int     msync(void *addr, size_t len, int flags);
+	int     mlock(const void *addr, size_t len);
+	int     munlock(const void *addr, size_t len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*  _SYS_MMAN_H_ */
diff --git a/lib/librte_eal/windows/include_override/sys/netbsd/queue.h b/lib/librte_eal/windows/include_override/sys/netbsd/queue.h
new file mode 100644
index 000000000..99d01a55b
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/sys/netbsd/queue.h
@@ -0,0 +1,846 @@
+/*	$NetBSD: queue.h,v 1.68 2014/11/19 08:10:01 uebayasi Exp $	*/
+
+/*
+ * Copyright (c) 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)queue.h	8.5 (Berkeley) 8/20/94
+ */
+
+#ifndef	_SYS_QUEUE_H_
+#define	_SYS_QUEUE_H_
+
+/*
+ * This file defines five types of data structures: singly-linked lists,
+ * lists, simple queues, tail queues, and circular queues.
+ *
+ * A singly-linked list is headed by a single forward pointer. The
+ * elements are singly linked for minimum space and pointer manipulation
+ * overhead at the expense of O(n) removal for arbitrary elements. New
+ * elements can be added to the list after an existing element or at the
+ * head of the list.  Elements being removed from the head of the list
+ * should use the explicit macro for this purpose for optimum
+ * efficiency. A singly-linked list may only be traversed in the forward
+ * direction.  Singly-linked lists are ideal for applications with large
+ * datasets and few or no removals or for implementing a LIFO queue.
+ *
+ * A list is headed by a single forward pointer (or an array of forward
+ * pointers for a hash table header). The elements are doubly linked
+ * so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before
+ * or after an existing element or at the head of the list. A list
+ * may only be traversed in the forward direction.
+ *
+ * A simple queue is headed by a pair of pointers, one the head of the
+ * list and the other to the tail of the list. The elements are singly
+ * linked to save space, so elements can only be removed from the
+ * head of the list. New elements can be added to the list after
+ * an existing element, at the head of the list, or at the end of the
+ * list. A simple queue may only be traversed in the forward direction.
+ *
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ *
+ * A circle queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or after
+ * an existing element, at the head of the list, or at the end of the list.
+ * A circle queue may be traversed in either direction, but has a more
+ * complex end of list detection.
+ *
+ * For details on the use of these macros, see the queue(3) manual page.
+ */
+
+/*
+ * Include the definition of NULL only on NetBSD because sys/null.h
+ * is not available elsewhere.  This conditional makes the header
+ * portable and it can simply be dropped verbatim into any system.
+ * The caveat is that on other systems some other header
+ * must provide NULL before the macros can be used.
+ */
+#ifdef __NetBSD__
+#include <sys/null.h>
+#endif
+
+#if defined(QUEUEDEBUG)
+# if defined(_KERNEL)
+#  define QUEUEDEBUG_ABORT(...) panic(__VA_ARGS__)
+# else
+#  include <err.h>
+#  define QUEUEDEBUG_ABORT(...) err(1, __VA_ARGS__)
+# endif
+#endif
+
+/*
+ * Singly-linked List definitions.
+ */
+#define	SLIST_HEAD(name, type)						\
+struct name {								\
+	struct type *slh_first;	/* first element */			\
+}
+
+#define	SLIST_HEAD_INITIALIZER(head)					\
+	{ NULL }
+
+#define	SLIST_ENTRY(type)						\
+struct {								\
+	struct type *sle_next;	/* next element */			\
+}
+
+/*
+ * Singly-linked List access methods.
+ */
+#define	SLIST_FIRST(head)	((head)->slh_first)
+#define	SLIST_END(head)		NULL
+#define	SLIST_EMPTY(head)	((head)->slh_first == NULL)
+#define	SLIST_NEXT(elm, field)	((elm)->field.sle_next)
+
+#define	SLIST_FOREACH(var, head, field)					\
+	for((var) = (head)->slh_first;					\
+	    (var) != SLIST_END(head);					\
+	    (var) = (var)->field.sle_next)
+
+#define	SLIST_FOREACH_SAFE(var, head, field, tvar)			\
+	for ((var) = SLIST_FIRST((head));				\
+	    (var) != SLIST_END(head) &&					\
+	    ((tvar) = SLIST_NEXT((var), field), 1);			\
+	    (var) = (tvar))
+
+/*
+ * Singly-linked List functions.
+ */
+#define	SLIST_INIT(head) do {						\
+	(head)->slh_first = SLIST_END(head);				\
+} while (/*CONSTCOND*/0)
+
+#define	SLIST_INSERT_AFTER(slistelm, elm, field) do {			\
+	(elm)->field.sle_next = (slistelm)->field.sle_next;		\
+	(slistelm)->field.sle_next = (elm);				\
+} while (/*CONSTCOND*/0)
+
+#define	SLIST_INSERT_HEAD(head, elm, field) do {			\
+	(elm)->field.sle_next = (head)->slh_first;			\
+	(head)->slh_first = (elm);					\
+} while (/*CONSTCOND*/0)
+
+#define	SLIST_REMOVE_AFTER(slistelm, field) do {			\
+	(slistelm)->field.sle_next =					\
+	    SLIST_NEXT(SLIST_NEXT((slistelm), field), field);		\
+} while (/*CONSTCOND*/0)
+
+#define	SLIST_REMOVE_HEAD(head, field) do {				\
+	(head)->slh_first = (head)->slh_first->field.sle_next;		\
+} while (/*CONSTCOND*/0)
+
+#define	SLIST_REMOVE(head, elm, type, field) do {			\
+	if ((head)->slh_first == (elm)) {				\
+		SLIST_REMOVE_HEAD((head), field);			\
+	}								\
+	else {								\
+		struct type *curelm = (head)->slh_first;		\
+		while(curelm->field.sle_next != (elm))			\
+			curelm = curelm->field.sle_next;		\
+		curelm->field.sle_next =				\
+		    curelm->field.sle_next->field.sle_next;		\
+	}								\
+} while (/*CONSTCOND*/0)
+
+
+/*
+ * List definitions.
+ */
+#define	LIST_HEAD(name, type)						\
+struct name {								\
+	struct type *lh_first;	/* first element */			\
+}
+
+#define	LIST_HEAD_INITIALIZER(head)					\
+	{ NULL }
+
+#define	LIST_ENTRY(type)						\
+struct {								\
+	struct type *le_next;	/* next element */			\
+	struct type **le_prev;	/* address of previous next element */	\
+}
+
+/*
+ * List access methods.
+ */
+#define	LIST_FIRST(head)		((head)->lh_first)
+#define	LIST_END(head)			NULL
+#define	LIST_EMPTY(head)		((head)->lh_first == LIST_END(head))
+#define	LIST_NEXT(elm, field)		((elm)->field.le_next)
+
+#define	LIST_FOREACH(var, head, field)					\
+	for ((var) = ((head)->lh_first);				\
+	    (var) != LIST_END(head);					\
+	    (var) = ((var)->field.le_next))
+
+#define	LIST_FOREACH_SAFE(var, head, field, tvar)			\
+	for ((var) = LIST_FIRST((head));				\
+	    (var) != LIST_END(head) &&					\
+	    ((tvar) = LIST_NEXT((var), field), 1);			\
+	    (var) = (tvar))
+
+#define	LIST_MOVE(head1, head2) do {					\
+	LIST_INIT((head2));						\
+	if (!LIST_EMPTY((head1))) {					\
+		(head2)->lh_first = (head1)->lh_first;			\
+		LIST_INIT((head1));					\
+	}								\
+} while (/*CONSTCOND*/0)
+
+/*
+ * List functions.
+ */
+#if defined(QUEUEDEBUG)
+#define	QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)			\
+	if ((head)->lh_first &&						\
+	    (head)->lh_first->field.le_prev != &(head)->lh_first)	\
+		QUEUEDEBUG_ABORT("LIST_INSERT_HEAD %p %s:%d", (head),	\
+		    __FILE__, __LINE__);
+#define	QUEUEDEBUG_LIST_OP(elm, field)					\
+	if ((elm)->field.le_next &&					\
+	    (elm)->field.le_next->field.le_prev !=			\
+	    &(elm)->field.le_next)					\
+		QUEUEDEBUG_ABORT("LIST_* forw %p %s:%d", (elm),		\
+		    __FILE__, __LINE__);				\
+	if (*(elm)->field.le_prev != (elm))				\
+		QUEUEDEBUG_ABORT("LIST_* back %p %s:%d", (elm),		\
+		    __FILE__, __LINE__);
+#define	QUEUEDEBUG_LIST_POSTREMOVE(elm, field)				\
+	(elm)->field.le_next = (void *)1L;				\
+	(elm)->field.le_prev = (void *)1L;
+#else
+#define	QUEUEDEBUG_LIST_INSERT_HEAD(head, elm, field)
+#define	QUEUEDEBUG_LIST_OP(elm, field)
+#define	QUEUEDEBUG_LIST_POSTREMOVE(elm, field)
+#endif
+
+#define	LIST_INIT(head) do {						\
+	(head)->lh_first = LIST_END(head);				\
+} while (/*CONSTCOND*/0)
+
+#define	LIST_INSERT_AFTER(listelm, elm, field) do {			\
+	QUEUEDEBUG_LIST_OP((listelm), field)				\
+	if (((elm)->field.le_next = (listelm)->field.le_next) != 	\
+	    LIST_END(head))						\
+		(listelm)->field.le_next->field.le_prev =		\
+		    &(elm)->field.le_next;				\
+	(listelm)->field.le_next = (elm);				\
+	(elm)->field.le_prev = &(listelm)->field.le_next;		\
+} while (/*CONSTCOND*/0)
+
+#define	LIST_INSERT_BEFORE(listelm, elm, field) do {			\
+	QUEUEDEBUG_LIST_OP((listelm), field)				\
+	(elm)->field.le_prev = (listelm)->field.le_prev;		\
+	(elm)->field.le_next = (listelm);				\
+	*(listelm)->field.le_prev = (elm);				\
+	(listelm)->field.le_prev = &(elm)->field.le_next;		\
+} while (/*CONSTCOND*/0)
+
+#define	LIST_INSERT_HEAD(head, elm, field) do {				\
+	QUEUEDEBUG_LIST_INSERT_HEAD((head), (elm), field)		\
+	if (((elm)->field.le_next = (head)->lh_first) != LIST_END(head))\
+		(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
+	(head)->lh_first = (elm);					\
+	(elm)->field.le_prev = &(head)->lh_first;			\
+} while (/*CONSTCOND*/0)
+
+#define	LIST_REMOVE(elm, field) do {					\
+	QUEUEDEBUG_LIST_OP((elm), field)				\
+	if ((elm)->field.le_next != NULL)				\
+		(elm)->field.le_next->field.le_prev = 			\
+		    (elm)->field.le_prev;				\
+	*(elm)->field.le_prev = (elm)->field.le_next;			\
+	QUEUEDEBUG_LIST_POSTREMOVE((elm), field)			\
+} while (/*CONSTCOND*/0)
+
+#define LIST_REPLACE(elm, elm2, field) do {				\
+	if (((elm2)->field.le_next = (elm)->field.le_next) != NULL)	\
+		(elm2)->field.le_next->field.le_prev =			\
+		    &(elm2)->field.le_next;				\
+	(elm2)->field.le_prev = (elm)->field.le_prev;			\
+	*(elm2)->field.le_prev = (elm2);				\
+	QUEUEDEBUG_LIST_POSTREMOVE((elm), field)			\
+} while (/*CONSTCOND*/0)
+
+/*
+ * Simple queue definitions.
+ */
+#define	SIMPLEQ_HEAD(name, type)					\
+struct name {								\
+	struct type *sqh_first;	/* first element */			\
+	struct type **sqh_last;	/* addr of last next element */		\
+}
+
+#define	SIMPLEQ_HEAD_INITIALIZER(head)					\
+	{ NULL, &(head).sqh_first }
+
+#define	SIMPLEQ_ENTRY(type)						\
+struct {								\
+	struct type *sqe_next;	/* next element */			\
+}
+
+/*
+ * Simple queue access methods.
+ */
+#define	SIMPLEQ_FIRST(head)		((head)->sqh_first)
+#define	SIMPLEQ_END(head)		NULL
+#define	SIMPLEQ_EMPTY(head)		((head)->sqh_first == SIMPLEQ_END(head))
+#define	SIMPLEQ_NEXT(elm, field)	((elm)->field.sqe_next)
+
+#define	SIMPLEQ_FOREACH(var, head, field)				\
+	for ((var) = ((head)->sqh_first);				\
+	    (var) != SIMPLEQ_END(head);					\
+	    (var) = ((var)->field.sqe_next))
+
+#define	SIMPLEQ_FOREACH_SAFE(var, head, field, next)			\
+	for ((var) = ((head)->sqh_first);				\
+	    (var) != SIMPLEQ_END(head) &&				\
+	    ((next = ((var)->field.sqe_next)), 1);			\
+	    (var) = (next))
+
+/*
+ * Simple queue functions.
+ */
+#define	SIMPLEQ_INIT(head) do {						\
+	(head)->sqh_first = NULL;					\
+	(head)->sqh_last = &(head)->sqh_first;				\
+} while (/*CONSTCOND*/0)
+
+#define	SIMPLEQ_INSERT_HEAD(head, elm, field) do {			\
+	if (((elm)->field.sqe_next = (head)->sqh_first) == NULL)	\
+		(head)->sqh_last = &(elm)->field.sqe_next;		\
+	(head)->sqh_first = (elm);					\
+} while (/*CONSTCOND*/0)
+
+#define	SIMPLEQ_INSERT_TAIL(head, elm, field) do {			\
+	(elm)->field.sqe_next = NULL;					\
+	*(head)->sqh_last = (elm);					\
+	(head)->sqh_last = &(elm)->field.sqe_next;			\
+} while (/*CONSTCOND*/0)
+
+#define	SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
+	if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
+		(head)->sqh_last = &(elm)->field.sqe_next;		\
+	(listelm)->field.sqe_next = (elm);				\
+} while (/*CONSTCOND*/0)
+
+#define	SIMPLEQ_REMOVE_HEAD(head, field) do {				\
+	if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
+		(head)->sqh_last = &(head)->sqh_first;			\
+} while (/*CONSTCOND*/0)
+
+#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do {			\
+	if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \
+	    == NULL)							\
+		(head)->sqh_last = &(elm)->field.sqe_next;		\
+} while (/*CONSTCOND*/0)
+
+#define	SIMPLEQ_REMOVE(head, elm, type, field) do {			\
+	if ((head)->sqh_first == (elm)) {				\
+		SIMPLEQ_REMOVE_HEAD((head), field);			\
+	} else {							\
+		struct type *curelm = (head)->sqh_first;		\
+		while (curelm->field.sqe_next != (elm))			\
+			curelm = curelm->field.sqe_next;		\
+		if ((curelm->field.sqe_next =				\
+			curelm->field.sqe_next->field.sqe_next) == NULL) \
+			    (head)->sqh_last = &(curelm)->field.sqe_next; \
+	}								\
+} while (/*CONSTCOND*/0)
+
+#define	SIMPLEQ_CONCAT(head1, head2) do {				\
+	if (!SIMPLEQ_EMPTY((head2))) {					\
+		*(head1)->sqh_last = (head2)->sqh_first;		\
+		(head1)->sqh_last = (head2)->sqh_last;		\
+		SIMPLEQ_INIT((head2));					\
+	}								\
+} while (/*CONSTCOND*/0)
+
+#define	SIMPLEQ_LAST(head, type, field)					\
+	(SIMPLEQ_EMPTY((head)) ?						\
+		NULL :							\
+	        ((struct type *)(void *)				\
+		((char *)((head)->sqh_last) - offsetof(struct type, field))))
+
+/*
+ * Tail queue definitions.
+ */
+#define	_TAILQ_HEAD(name, type, qual)					\
+struct name {								\
+	qual type *tqh_first;		/* first element */		\
+	qual type *qual *tqh_last;	/* addr of last next element */	\
+}
+#define TAILQ_HEAD(name, type)	_TAILQ_HEAD(name, struct type,)
+
+#define	TAILQ_HEAD_INITIALIZER(head)					\
+	{ TAILQ_END(head), &(head).tqh_first }
+
+#define	_TAILQ_ENTRY(type, qual)					\
+struct {								\
+	qual type *tqe_next;		/* next element */		\
+	qual type *qual *tqe_prev;	/* address of previous next element */\
+}
+#define TAILQ_ENTRY(type)	_TAILQ_ENTRY(struct type,)
+
+/*
+ * Tail queue access methods.
+ */
+#define	TAILQ_FIRST(head)		((head)->tqh_first)
+#define	TAILQ_END(head)			(NULL)
+#define	TAILQ_NEXT(elm, field)		((elm)->field.tqe_next)
+#define	TAILQ_LAST(head, headname) \
+	(*(((struct headname *)((head)->tqh_last))->tqh_last))
+#define	TAILQ_PREV(elm, headname, field) \
+	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+#define	TAILQ_EMPTY(head)		(TAILQ_FIRST(head) == TAILQ_END(head))
+
+
+#define	TAILQ_FOREACH(var, head, field)					\
+	for ((var) = ((head)->tqh_first);				\
+	    (var) != TAILQ_END(head);					\
+	    (var) = ((var)->field.tqe_next))
+
+#define	TAILQ_FOREACH_SAFE(var, head, field, next)			\
+	for ((var) = ((head)->tqh_first);				\
+	    (var) != TAILQ_END(head) &&					\
+	    ((next) = TAILQ_NEXT(var, field), 1); (var) = (next))
+
+#define	TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
+	for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last));\
+	    (var) != TAILQ_END(head);					\
+	    (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
+
+#define	TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, prev)	\
+	for ((var) = TAILQ_LAST((head), headname);			\
+	    (var) != TAILQ_END(head) && 				\
+	    ((prev) = TAILQ_PREV((var), headname, field), 1); (var) = (prev))
+
+/*
+ * Tail queue functions.
+ */
+#if defined(QUEUEDEBUG)
+#define	QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)			\
+	if ((head)->tqh_first &&					\
+	    (head)->tqh_first->field.tqe_prev != &(head)->tqh_first)	\
+		QUEUEDEBUG_ABORT("TAILQ_INSERT_HEAD %p %s:%d", (head),	\
+		    __FILE__, __LINE__);
+#define	QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)			\
+	if (*(head)->tqh_last != NULL)					\
+		QUEUEDEBUG_ABORT("TAILQ_INSERT_TAIL %p %s:%d", (head),	\
+		    __FILE__, __LINE__);
+#define	QUEUEDEBUG_TAILQ_OP(elm, field)					\
+	if ((elm)->field.tqe_next &&					\
+	    (elm)->field.tqe_next->field.tqe_prev !=			\
+	    &(elm)->field.tqe_next)					\
+		QUEUEDEBUG_ABORT("TAILQ_* forw %p %s:%d", (elm),	\
+		    __FILE__, __LINE__);				\
+	if (*(elm)->field.tqe_prev != (elm))				\
+		QUEUEDEBUG_ABORT("TAILQ_* back %p %s:%d", (elm),	\
+		    __FILE__, __LINE__);
+#define	QUEUEDEBUG_TAILQ_PREREMOVE(head, elm, field)			\
+	if ((elm)->field.tqe_next == NULL &&				\
+	    (head)->tqh_last != &(elm)->field.tqe_next)			\
+		QUEUEDEBUG_ABORT("TAILQ_PREREMOVE head %p elm %p %s:%d",\
+		    (head), (elm), __FILE__, __LINE__);
+#define	QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)				\
+	(elm)->field.tqe_next = (void *)1L;				\
+	(elm)->field.tqe_prev = (void *)1L;
+#else
+#define	QUEUEDEBUG_TAILQ_INSERT_HEAD(head, elm, field)
+#define	QUEUEDEBUG_TAILQ_INSERT_TAIL(head, elm, field)
+#define	QUEUEDEBUG_TAILQ_OP(elm, field)
+#define	QUEUEDEBUG_TAILQ_PREREMOVE(head, elm, field)
+#define	QUEUEDEBUG_TAILQ_POSTREMOVE(elm, field)
+#endif
+
+#define	TAILQ_INIT(head) do {						\
+	(head)->tqh_first = TAILQ_END(head);				\
+	(head)->tqh_last = &(head)->tqh_first;				\
+} while (/*CONSTCOND*/0)
+
+#define	TAILQ_INSERT_HEAD(head, elm, field) do {			\
+	QUEUEDEBUG_TAILQ_INSERT_HEAD((head), (elm), field)		\
+	if (((elm)->field.tqe_next = (head)->tqh_first) != TAILQ_END(head))\
+		(head)->tqh_first->field.tqe_prev =			\
+		    &(elm)->field.tqe_next;				\
+	else								\
+		(head)->tqh_last = &(elm)->field.tqe_next;		\
+	(head)->tqh_first = (elm);					\
+	(elm)->field.tqe_prev = &(head)->tqh_first;			\
+} while (/*CONSTCOND*/0)
+
+#define	TAILQ_INSERT_TAIL(head, elm, field) do {			\
+	QUEUEDEBUG_TAILQ_INSERT_TAIL((head), (elm), field)		\
+	(elm)->field.tqe_next = TAILQ_END(head);			\
+	(elm)->field.tqe_prev = (head)->tqh_last;			\
+	*(head)->tqh_last = (elm);					\
+	(head)->tqh_last = &(elm)->field.tqe_next;			\
+} while (/*CONSTCOND*/0)
+
+#define	TAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
+	QUEUEDEBUG_TAILQ_OP((listelm), field)				\
+	if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != 	\
+	    TAILQ_END(head))						\
+		(elm)->field.tqe_next->field.tqe_prev = 		\
+		    &(elm)->field.tqe_next;				\
+	else								\
+		(head)->tqh_last = &(elm)->field.tqe_next;		\
+	(listelm)->field.tqe_next = (elm);				\
+	(elm)->field.tqe_prev = &(listelm)->field.tqe_next;		\
+} while (/*CONSTCOND*/0)
+
+#define	TAILQ_INSERT_BEFORE(listelm, elm, field) do {			\
+	QUEUEDEBUG_TAILQ_OP((listelm), field)				\
+	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
+	(elm)->field.tqe_next = (listelm);				\
+	*(listelm)->field.tqe_prev = (elm);				\
+	(listelm)->field.tqe_prev = &(elm)->field.tqe_next;		\
+} while (/*CONSTCOND*/0)
+
+#define	TAILQ_REMOVE(head, elm, field) do {				\
+	QUEUEDEBUG_TAILQ_PREREMOVE((head), (elm), field)		\
+	QUEUEDEBUG_TAILQ_OP((elm), field)				\
+	if (((elm)->field.tqe_next) != TAILQ_END(head))			\
+		(elm)->field.tqe_next->field.tqe_prev = 		\
+		    (elm)->field.tqe_prev;				\
+	else								\
+		(head)->tqh_last = (elm)->field.tqe_prev;		\
+	*(elm)->field.tqe_prev = (elm)->field.tqe_next;			\
+	QUEUEDEBUG_TAILQ_POSTREMOVE((elm), field);			\
+} while (/*CONSTCOND*/0)
+
+#define TAILQ_REPLACE(head, elm, elm2, field) do {			\
+        if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != 	\
+	    TAILQ_END(head))   						\
+                (elm2)->field.tqe_next->field.tqe_prev =		\
+                    &(elm2)->field.tqe_next;				\
+        else								\
+                (head)->tqh_last = &(elm2)->field.tqe_next;		\
+        (elm2)->field.tqe_prev = (elm)->field.tqe_prev;			\
+        *(elm2)->field.tqe_prev = (elm2);				\
+	QUEUEDEBUG_TAILQ_POSTREMOVE((elm), field);			\
+} while (/*CONSTCOND*/0)
+
+#define	TAILQ_CONCAT(head1, head2, field) do {				\
+	if (!TAILQ_EMPTY(head2)) {					\
+		*(head1)->tqh_last = (head2)->tqh_first;		\
+		(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;	\
+		(head1)->tqh_last = (head2)->tqh_last;			\
+		TAILQ_INIT((head2));					\
+	}								\
+} while (/*CONSTCOND*/0)
+
+/*
+ * Singly-linked Tail queue declarations.
+ */
+#define	STAILQ_HEAD(name, type)						\
+struct name {								\
+	struct type *stqh_first;	/* first element */		\
+	struct type **stqh_last;	/* addr of last next element */	\
+}
+
+#define	STAILQ_HEAD_INITIALIZER(head)					\
+	{ NULL, &(head).stqh_first }
+
+#define	STAILQ_ENTRY(type)						\
+struct {								\
+	struct type *stqe_next;	/* next element */			\
+}
+
+/*
+ * Singly-linked Tail queue access methods.
+ */
+#define	STAILQ_FIRST(head)	((head)->stqh_first)
+#define	STAILQ_END(head)	NULL
+#define	STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)
+#define	STAILQ_EMPTY(head)	(STAILQ_FIRST(head) == STAILQ_END(head))
+
+/*
+ * Singly-linked Tail queue functions.
+ */
+#define	STAILQ_INIT(head) do {						\
+	(head)->stqh_first = NULL;					\
+	(head)->stqh_last = &(head)->stqh_first;				\
+} while (/*CONSTCOND*/0)
+
+#define	STAILQ_INSERT_HEAD(head, elm, field) do {			\
+	if (((elm)->field.stqe_next = (head)->stqh_first) == NULL)	\
+		(head)->stqh_last = &(elm)->field.stqe_next;		\
+	(head)->stqh_first = (elm);					\
+} while (/*CONSTCOND*/0)
+
+#define	STAILQ_INSERT_TAIL(head, elm, field) do {			\
+	(elm)->field.stqe_next = NULL;					\
+	*(head)->stqh_last = (elm);					\
+	(head)->stqh_last = &(elm)->field.stqe_next;			\
+} while (/*CONSTCOND*/0)
+
+#define	STAILQ_INSERT_AFTER(head, listelm, elm, field) do {		\
+	if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\
+		(head)->stqh_last = &(elm)->field.stqe_next;		\
+	(listelm)->field.stqe_next = (elm);				\
+} while (/*CONSTCOND*/0)
+
+#define	STAILQ_REMOVE_HEAD(head, field) do {				\
+	if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == NULL) \
+		(head)->stqh_last = &(head)->stqh_first;			\
+} while (/*CONSTCOND*/0)
+
+#define	STAILQ_REMOVE(head, elm, type, field) do {			\
+	if ((head)->stqh_first == (elm)) {				\
+		STAILQ_REMOVE_HEAD((head), field);			\
+	} else {							\
+		struct type *curelm = (head)->stqh_first;		\
+		while (curelm->field.stqe_next != (elm))			\
+			curelm = curelm->field.stqe_next;		\
+		if ((curelm->field.stqe_next =				\
+			curelm->field.stqe_next->field.stqe_next) == NULL) \
+			    (head)->stqh_last = &(curelm)->field.stqe_next; \
+	}								\
+} while (/*CONSTCOND*/0)
+
+#define	STAILQ_FOREACH(var, head, field)				\
+	for ((var) = ((head)->stqh_first);				\
+		(var);							\
+		(var) = ((var)->field.stqe_next))
+
+#define	STAILQ_FOREACH_SAFE(var, head, field, tvar)			\
+	for ((var) = STAILQ_FIRST((head));				\
+	    (var) && ((tvar) = STAILQ_NEXT((var), field), 1);		\
+	    (var) = (tvar))
+
+#define	STAILQ_CONCAT(head1, head2) do {				\
+	if (!STAILQ_EMPTY((head2))) {					\
+		*(head1)->stqh_last = (head2)->stqh_first;		\
+		(head1)->stqh_last = (head2)->stqh_last;		\
+		STAILQ_INIT((head2));					\
+	}								\
+} while (/*CONSTCOND*/0)
+
+#define	STAILQ_LAST(head, type, field)					\
+	(STAILQ_EMPTY((head)) ?						\
+		NULL :							\
+	        ((struct type *)(void *)				\
+		((char *)((head)->stqh_last) - offsetof(struct type, field))))
+
+
+#ifndef _KERNEL
+/*
+ * Circular queue definitions. Do not use. We still keep the macros
+ * for compatibility but because of pointer aliasing issues their use
+ * is discouraged!
+ */
+
+/*
+ * __launder_type():  We use this ugly hack to work around the the compiler
+ * noticing that two types may not alias each other and elide tests in code.
+ * We hit this in the CIRCLEQ macros when comparing 'struct name *' and
+ * 'struct type *' (see CIRCLEQ_HEAD()).  Modern compilers (such as GCC
+ * 4.8) declare these comparisons as always false, causing the code to
+ * not run as designed.
+ *
+ * This hack is only to be used for comparisons and thus can be fully const.
+ * Do not use for assignment.
+ *
+ * If we ever choose to change the ABI of the CIRCLEQ macros, we could fix
+ * this by changing the head/tail sentinal values, but see the note above
+ * this one.
+ */
+static __inline const void * __launder_type(const void *);
+static __inline const void *
+__launder_type(const void *__x)
+{
+	__asm __volatile("" : "+r" (__x));
+	return __x;
+}
+
+#if defined(QUEUEDEBUG)
+#define QUEUEDEBUG_CIRCLEQ_HEAD(head, field)				\
+	if ((head)->cqh_first != CIRCLEQ_ENDC(head) &&			\
+	    (head)->cqh_first->field.cqe_prev != CIRCLEQ_ENDC(head))	\
+		QUEUEDEBUG_ABORT("CIRCLEQ head forw %p %s:%d", (head),	\
+		      __FILE__, __LINE__);				\
+	if ((head)->cqh_last != CIRCLEQ_ENDC(head) &&			\
+	    (head)->cqh_last->field.cqe_next != CIRCLEQ_ENDC(head))	\
+		QUEUEDEBUG_ABORT("CIRCLEQ head back %p %s:%d", (head),	\
+		      __FILE__, __LINE__);
+#define QUEUEDEBUG_CIRCLEQ_ELM(head, elm, field)			\
+	if ((elm)->field.cqe_next == CIRCLEQ_ENDC(head)) {		\
+		if ((head)->cqh_last != (elm))				\
+			QUEUEDEBUG_ABORT("CIRCLEQ elm last %p %s:%d",	\
+			    (elm), __FILE__, __LINE__);			\
+	} else {							\
+		if ((elm)->field.cqe_next->field.cqe_prev != (elm))	\
+			QUEUEDEBUG_ABORT("CIRCLEQ elm forw %p %s:%d",	\
+			    (elm), __FILE__, __LINE__);			\
+	}								\
+	if ((elm)->field.cqe_prev == CIRCLEQ_ENDC(head)) {		\
+		if ((head)->cqh_first != (elm))				\
+			QUEUEDEBUG_ABORT("CIRCLEQ elm first %p %s:%d",	\
+			    (elm), __FILE__, __LINE__);			\
+	} else {							\
+		if ((elm)->field.cqe_prev->field.cqe_next != (elm))	\
+			QUEUEDEBUG_ABORT("CIRCLEQ elm prev %p %s:%d",	\
+			    (elm), __FILE__, __LINE__);			\
+	}
+#define QUEUEDEBUG_CIRCLEQ_POSTREMOVE(elm, field)			\
+	(elm)->field.cqe_next = (void *)1L;				\
+	(elm)->field.cqe_prev = (void *)1L;
+#else
+#define QUEUEDEBUG_CIRCLEQ_HEAD(head, field)
+#define QUEUEDEBUG_CIRCLEQ_ELM(head, elm, field)
+#define QUEUEDEBUG_CIRCLEQ_POSTREMOVE(elm, field)
+#endif
+
+#define	CIRCLEQ_HEAD(name, type)					\
+struct name {								\
+	struct type *cqh_first;		/* first element */		\
+	struct type *cqh_last;		/* last element */		\
+}
+
+#define	CIRCLEQ_HEAD_INITIALIZER(head)					\
+	{ CIRCLEQ_END(&head), CIRCLEQ_END(&head) }
+
+#define	CIRCLEQ_ENTRY(type)						\
+struct {								\
+	struct type *cqe_next;		/* next element */		\
+	struct type *cqe_prev;		/* previous element */		\
+}
+
+/*
+ * Circular queue functions.
+ */
+#define	CIRCLEQ_INIT(head) do {						\
+	(head)->cqh_first = CIRCLEQ_END(head);				\
+	(head)->cqh_last = CIRCLEQ_END(head);				\
+} while (/*CONSTCOND*/0)
+
+#define	CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do {		\
+	QUEUEDEBUG_CIRCLEQ_HEAD((head), field)				\
+	QUEUEDEBUG_CIRCLEQ_ELM((head), (listelm), field)		\
+	(elm)->field.cqe_next = (listelm)->field.cqe_next;		\
+	(elm)->field.cqe_prev = (listelm);				\
+	if ((listelm)->field.cqe_next == CIRCLEQ_ENDC(head))		\
+		(head)->cqh_last = (elm);				\
+	else								\
+		(listelm)->field.cqe_next->field.cqe_prev = (elm);	\
+	(listelm)->field.cqe_next = (elm);				\
+} while (/*CONSTCOND*/0)
+
+#define	CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do {		\
+	QUEUEDEBUG_CIRCLEQ_HEAD((head), field)				\
+	QUEUEDEBUG_CIRCLEQ_ELM((head), (listelm), field)		\
+	(elm)->field.cqe_next = (listelm);				\
+	(elm)->field.cqe_prev = (listelm)->field.cqe_prev;		\
+	if ((listelm)->field.cqe_prev == CIRCLEQ_ENDC(head))		\
+		(head)->cqh_first = (elm);				\
+	else								\
+		(listelm)->field.cqe_prev->field.cqe_next = (elm);	\
+	(listelm)->field.cqe_prev = (elm);				\
+} while (/*CONSTCOND*/0)
+
+#define	CIRCLEQ_INSERT_HEAD(head, elm, field) do {			\
+	QUEUEDEBUG_CIRCLEQ_HEAD((head), field)				\
+	(elm)->field.cqe_next = (head)->cqh_first;			\
+	(elm)->field.cqe_prev = CIRCLEQ_END(head);			\
+	if ((head)->cqh_last == CIRCLEQ_ENDC(head))			\
+		(head)->cqh_last = (elm);				\
+	else								\
+		(head)->cqh_first->field.cqe_prev = (elm);		\
+	(head)->cqh_first = (elm);					\
+} while (/*CONSTCOND*/0)
+
+#define	CIRCLEQ_INSERT_TAIL(head, elm, field) do {			\
+	QUEUEDEBUG_CIRCLEQ_HEAD((head), field)				\
+	(elm)->field.cqe_next = CIRCLEQ_END(head);			\
+	(elm)->field.cqe_prev = (head)->cqh_last;			\
+	if ((head)->cqh_first == CIRCLEQ_ENDC(head))			\
+		(head)->cqh_first = (elm);				\
+	else								\
+		(head)->cqh_last->field.cqe_next = (elm);		\
+	(head)->cqh_last = (elm);					\
+} while (/*CONSTCOND*/0)
+
+#define	CIRCLEQ_REMOVE(head, elm, field) do {				\
+	QUEUEDEBUG_CIRCLEQ_HEAD((head), field)				\
+	QUEUEDEBUG_CIRCLEQ_ELM((head), (elm), field)			\
+	if ((elm)->field.cqe_next == CIRCLEQ_ENDC(head))		\
+		(head)->cqh_last = (elm)->field.cqe_prev;		\
+	else								\
+		(elm)->field.cqe_next->field.cqe_prev =			\
+		    (elm)->field.cqe_prev;				\
+	if ((elm)->field.cqe_prev == CIRCLEQ_ENDC(head))		\
+		(head)->cqh_first = (elm)->field.cqe_next;		\
+	else								\
+		(elm)->field.cqe_prev->field.cqe_next =			\
+		    (elm)->field.cqe_next;				\
+	QUEUEDEBUG_CIRCLEQ_POSTREMOVE((elm), field)			\
+} while (/*CONSTCOND*/0)
+
+#define	CIRCLEQ_FOREACH(var, head, field)				\
+	for ((var) = ((head)->cqh_first);				\
+		(var) != CIRCLEQ_ENDC(head);				\
+		(var) = ((var)->field.cqe_next))
+
+#define	CIRCLEQ_FOREACH_REVERSE(var, head, field)			\
+	for ((var) = ((head)->cqh_last);				\
+		(var) != CIRCLEQ_ENDC(head);				\
+		(var) = ((var)->field.cqe_prev))
+
+/*
+ * Circular queue access methods.
+ */
+#define	CIRCLEQ_FIRST(head)		((head)->cqh_first)
+#define	CIRCLEQ_LAST(head)		((head)->cqh_last)
+/* For comparisons */
+#define	CIRCLEQ_ENDC(head)		(__launder_type(head))
+/* For assignments */
+#define	CIRCLEQ_END(head)		((void *)(head))
+#define	CIRCLEQ_NEXT(elm, field)	((elm)->field.cqe_next)
+#define	CIRCLEQ_PREV(elm, field)	((elm)->field.cqe_prev)
+#define	CIRCLEQ_EMPTY(head)						\
+    (CIRCLEQ_FIRST(head) == CIRCLEQ_ENDC(head))
+
+#define CIRCLEQ_LOOP_NEXT(head, elm, field)				\
+	(((elm)->field.cqe_next == CIRCLEQ_ENDC(head))			\
+	    ? ((head)->cqh_first)					\
+	    : (elm->field.cqe_next))
+#define CIRCLEQ_LOOP_PREV(head, elm, field)				\
+	(((elm)->field.cqe_prev == CIRCLEQ_ENDC(head))			\
+	    ? ((head)->cqh_last)					\
+	    : (elm->field.cqe_prev))
+#endif /* !_KERNEL */
+
+#endif	/* !_SYS_QUEUE_H_ */
diff --git a/lib/librte_eal/windows/include_override/sys/queue.h b/lib/librte_eal/windows/include_override/sys/queue.h
new file mode 100644
index 000000000..485e86f9e
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/sys/queue.h
@@ -0,0 +1,11 @@
+#pragma once
+
+/*
+ * $NetBSD: queue.h,v 1.68 2014/11/19 08:10:01 uebayasi Exp $
+ *
+ * Need to define _KERNEL to avoid the __launder_type()_ function
+ *
+ */
+#define _KERNEL
+#include "netbsd\queue.h"
+#undef _KERNEL
diff --git a/lib/librte_eal/windows/include_override/syslog.h b/lib/librte_eal/windows/include_override/syslog.h
new file mode 100644
index 000000000..890491b24
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/syslog.h
@@ -0,0 +1,217 @@
+/*
+* Copyright (c) 1982, 1986, 1988, 1993
+*	The Regents of the University of California.  All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+* 4. Neither the name of the University nor the names of its contributors
+*    may be used to endorse or promote products derived from this software
+*    without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+* SUCH DAMAGE.
+*
+*	@(#)syslog.h	8.1 (Berkeley) 6/2/93
+*/
+
+#ifndef _SYS_SYSLOG_H
+#define _SYS_SYSLOG_H 1
+
+#include <stdarg.h>
+
+/*
+* priorities/facilities are encoded into a single 32-bit quantity, where the
+* bottom 3 bits are the priority (0-7) and the top 28 bits are the facility
+* (0-big number).  Both the priorities and the facilities map roughly
+* one-to-one to strings in the syslogd(8) source code.  This mapping is
+* included in this file.
+*
+* priorities (these are ordered)
+*/
+#define	LOG_EMERG	0	/* system is unusable */
+#define	LOG_ALERT	1	/* action must be taken immediately */
+#define	LOG_CRIT	2	/* critical conditions */
+#define	LOG_ERR		3	/* error conditions */
+#define	LOG_WARNING	4	/* warning conditions */
+#define	LOG_NOTICE	5	/* normal but significant condition */
+#define	LOG_INFO	6	/* informational */
+#define	LOG_DEBUG	7	/* debug-level messages */
+
+#define	LOG_PRIMASK	0x07	/* mask to extract priority part (internal) */
+/* extract priority */
+#define	LOG_PRI(p)	((p) & LOG_PRIMASK)
+#define	LOG_MAKEPRI(fac, pri)	(((fac) << 3) | (pri))
+
+#ifdef SYSLOG_NAMES
+#define	INTERNAL_NOPRI	0x10	/* the "no priority" priority */
+/* mark "facility" */
+#define	INTERNAL_MARK	LOG_MAKEPRI(LOG_NFACILITIES, 0)
+typedef struct _code {
+	char	*c_name;
+	int	c_val;
+} CODE;
+
+CODE prioritynames[] =
+{
+	{ "alert", LOG_ALERT },
+	{ "crit", LOG_CRIT },
+	{ "debug", LOG_DEBUG },
+	{ "emerg", LOG_EMERG },
+	{ "err", LOG_ERR },
+	{ "error", LOG_ERR },		/* DEPRECATED */
+	{ "info", LOG_INFO },
+	{ "none", INTERNAL_NOPRI },		/* INTERNAL */
+	{ "notice", LOG_NOTICE },
+	{ "panic", LOG_EMERG },		/* DEPRECATED */
+	{ "warn", LOG_WARNING },		/* DEPRECATED */
+	{ "warning", LOG_WARNING },
+	{ NULL, -1 }
+};
+#endif
+
+/* facility codes */
+#define	LOG_KERN	(0<<3)	/* kernel messages */
+#define	LOG_USER	(1<<3)	/* random user-level messages */
+#define	LOG_MAIL	(2<<3)	/* mail system */
+#define	LOG_DAEMON	(3<<3)	/* system daemons */
+#define	LOG_AUTH	(4<<3)	/* security/authorization messages */
+#define	LOG_SYSLOG	(5<<3)	/* messages generated internally by syslogd */
+#define	LOG_LPR		(6<<3)	/* line printer subsystem */
+#define	LOG_NEWS	(7<<3)	/* network news subsystem */
+#define	LOG_UUCP	(8<<3)	/* UUCP subsystem */
+#define	LOG_CRON	(9<<3)	/* clock daemon */
+#define	LOG_AUTHPRIV	(10<<3)	/* security/authorization messages (private) */
+#define	LOG_FTP		(11<<3)	/* ftp daemon */
+
+/* other codes through 15 reserved for system use */
+#define	LOG_LOCAL0	(16<<3)	/* reserved for local use */
+#define	LOG_LOCAL1	(17<<3)	/* reserved for local use */
+#define	LOG_LOCAL2	(18<<3)	/* reserved for local use */
+#define	LOG_LOCAL3	(19<<3)	/* reserved for local use */
+#define	LOG_LOCAL4	(20<<3)	/* reserved for local use */
+#define	LOG_LOCAL5	(21<<3)	/* reserved for local use */
+#define	LOG_LOCAL6	(22<<3)	/* reserved for local use */
+#define	LOG_LOCAL7	(23<<3)	/* reserved for local use */
+
+#define	LOG_NFACILITIES	24	/* current number of facilities */
+#define	LOG_FACMASK	0x03f8	/* mask to extract facility part */
+/* facility of pri */
+#define	LOG_FAC(p)	(((p) & LOG_FACMASK) >> 3)
+
+#ifdef SYSLOG_NAMES
+CODE facilitynames[] =
+{
+	{ "auth", LOG_AUTH },
+	{ "authpriv", LOG_AUTHPRIV },
+	{ "cron", LOG_CRON },
+	{ "daemon", LOG_DAEMON },
+	{ "ftp", LOG_FTP },
+	{ "kern", LOG_KERN },
+	{ "lpr", LOG_LPR },
+	{ "mail", LOG_MAIL },
+	{ "mark", INTERNAL_MARK },		/* INTERNAL */
+	{ "news", LOG_NEWS },
+	{ "security", LOG_AUTH },		/* DEPRECATED */
+	{ "syslog", LOG_SYSLOG },
+	{ "user", LOG_USER },
+	{ "uucp", LOG_UUCP },
+	{ "local0", LOG_LOCAL0 },
+	{ "local1", LOG_LOCAL1 },
+	{ "local2", LOG_LOCAL2 },
+	{ "local3", LOG_LOCAL3 },
+	{ "local4", LOG_LOCAL4 },
+	{ "local5", LOG_LOCAL5 },
+	{ "local6", LOG_LOCAL6 },
+	{ "local7", LOG_LOCAL7 },
+	{ NULL, -1 }
+};
+#endif
+
+/*
+* arguments to setlogmask.
+*/
+#define	LOG_MASK(pri)	(1 << (pri))		/* mask for one priority */
+#define	LOG_UPTO(pri)	((1 << ((pri)+1)) - 1)	/* all priorities through pri */
+
+/*
+* Option flags for openlog.
+*
+* LOG_ODELAY no longer does anything.
+* LOG_NDELAY is the inverse of what it used to be.
+*/
+#define	LOG_PID		0x01	/* log the pid with each message */
+#define	LOG_CONS	0x02	/* log on the console if errors in sending */
+#define	LOG_ODELAY	0x04	/* delay open until first syslog() (default) */
+#define	LOG_NDELAY	0x08	/* don't delay open */
+#define	LOG_NOWAIT	0x10	/* don't wait for console forks: DEPRECATED */
+#define	LOG_PERROR	0x20	/* log to stderr as well */
+
+#define SYSLOG_PORT     514
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+	/* Close desriptor used to write to system logger.  */
+	extern void closelog(void);
+
+	/* Open connection to system logger.  */
+	extern void openlog(char *__ident, int __option, int __facility);
+
+	/* Set the log mask level.  */
+	extern int setlogmask(int __mask);
+
+	/* Generate a log message using FMT string and option arguments.  */
+	extern void syslog(int __pri, char *__fmt, ...);
+
+	/* Generate a log message using FMT and using arguments pointed to by AP.  */
+	extern void vsyslog(int __pri, char *__fmt, va_list __ap);
+
+#ifdef _WIN32
+	/* Windows specific.
+
+	init_syslog() *must* be called before calling any of the above
+	functions.  exit_syslog() will be scheduled using atexit().
+	However, it is not an error and encouraged to call
+	exit_syslog() before the application exits.
+
+	During operation, the application is free to call exit_syslog()
+	followed by init_syslog() to re-initialize the library. i.e. if
+	a different syslog host is to be used.
+
+	*/
+
+	/* Initializes the syslog library and sets the syslog host.  The
+	hostname parameter is of the form "<hostname>[:<port>]".  The
+	<port> may be a numeric port or it may be a name of a service.
+	If the <port> is specified using a service name, it will be
+	looked up using getservbyname().
+
+	On failure, the hostname and port will be set to "localhost"
+	and SYSLOG_PORT respectively.
+	*/
+	extern void init_syslog(const char * hostname);
+
+	extern void exit_syslog(void);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* syslog.h */
diff --git a/lib/librte_eal/windows/include_override/termios.h b/lib/librte_eal/windows/include_override/termios.h
new file mode 100644
index 000000000..ece9cc5c9
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/termios.h
@@ -0,0 +1 @@
+#include <sys/_termios.h>
diff --git a/lib/librte_eal/windows/include_override/unistd.h b/lib/librte_eal/windows/include_override/unistd.h
new file mode 100644
index 000000000..e78a696ab
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/unistd.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#ifndef _UNISTD_H
+#define _UNISTD_H
+
+/* This header file is required to build other rte* libraries and applications */
+
+//#include <io.h>
+#include <getopt.h> /* getopt at: https://gist.github.com/bikerm16/1b75e2dd20d839dcea58 */
+
+/* Types used by Unix-y systems */
+typedef __int8            int8_t;
+typedef __int16           int16_t;
+typedef __int32           int32_t;
+typedef __int64           int64_t;
+typedef unsigned __int8   uint8_t;
+typedef unsigned __int16  uint16_t;
+typedef unsigned __int32  uint32_t;
+typedef unsigned __int64  uint64_t;
+
+#define srandom srand
+#define random rand
+#define _SC_PAGESIZE
+#define sysconf getpagesize
+/* function prototypes */
+int getpagesize(void);
+
+#endif /* unistd.h  */
diff --git a/lib/librte_eal/windows/include_override/x86intrin.h b/lib/librte_eal/windows/include_override/x86intrin.h
new file mode 100644
index 000000000..336aa0baa
--- /dev/null
+++ b/lib/librte_eal/windows/include_override/x86intrin.h
@@ -0,0 +1 @@
+#include <intrin.h>
\ No newline at end of file
diff --git a/lib/librte_eal/windows/rte_override/exec-env/rte_interrupts.h b/lib/librte_eal/windows/rte_override/exec-env/rte_interrupts.h
new file mode 100644
index 000000000..e731442aa
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/exec-env/rte_interrupts.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#include "..\..\..\linuxapp\eal\include\exec-env\rte_interrupts.h"
diff --git a/lib/librte_eal/windows/rte_override/rte_acl.h b/lib/librte_eal/windows/rte_override/rte_acl.h
new file mode 100644
index 000000000..f35b12c4f
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_acl.h
@@ -0,0 +1,7 @@
+#pragma once
+
+#include "..\..\..\librte_acl\rte_acl.h"
+
+#undef RTE_ACL_MASKLEN_TO_BITMASK
+#define	RTE_ACL_MASKLEN_TO_BITMASK(v, s)	\
+((v) == 0 ? (v) : ((uint64_t)-1 << ((s) * CHAR_BIT - (v))))
diff --git a/lib/librte_eal/windows/rte_override/rte_atomic.h b/lib/librte_eal/windows/rte_override/rte_atomic.h
new file mode 100644
index 000000000..936710726
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_atomic.h
@@ -0,0 +1,744 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#ifndef _RTE_ATOMIC_H_
+#define _RTE_ATOMIC_H_
+
+#include <emmintrin.h>
+
+/* Do not include any of the core rte_atomic.h includes. They cause compilation problems on Windows */
+/* Instead, duplicate some of the required definitions here - this is sub-optimal, but... */
+
+#define rte_mb() _mm_mfence()
+#define rte_wmb() _mm_sfence()
+#define rte_rmb() _mm_lfence()
+
+#define rte_smp_mb() rte_mb()
+#define rte_smp_rmb() _ReadBarrier()
+#define rte_smp_wmb() _WriteBarrier()
+
+
+#define rte_io_mb() rte_mb()
+#define rte_io_wmb() _ReadBarrier()
+#define rte_io_rmb() _WriteBarrier()
+
+/**
+* Compiler barrier.
+*
+* Guarantees that operation reordering does not occur at compile time
+* for operations directly before and after the barrier.
+*/
+#define	rte_compiler_barrier() do {		\
+	asm volatile ("" : : : "memory");	\
+} while(0)
+
+
+/* Inline Windows implementation of atomic operations */
+
+/*------------------------- 16 bit atomic operations -------------------------*/
+
+/**
+* Atomic compare and set.
+*
+* (atomic) equivalent to:
+*   if (*dst == exp)
+*     *dst = src (all 16-bit words)
+*
+* @param dst
+*   The destination location into which the value will be written.
+* @param exp
+*   The expected value.
+* @param src
+*   The new value.
+* @return
+*   Non-zero on success; 0 on failure.
+*/
+static inline int
+rte_atomic16_cmpset(volatile uint16_t *dst, uint16_t exp, uint16_t src)
+{
+    return (_InterlockedCompareExchange16((SHORT *)dst, src, exp) != src);
+}
+
+/**
+* The atomic counter structure.
+*/
+typedef struct {
+    volatile int16_t cnt; /**< An internal counter value. */
+} rte_atomic16_t;
+
+/**
+* Static initializer for an atomic counter.
+*/
+#define RTE_ATOMIC16_INIT(val) { (val) }
+
+/**
+* Initialize an atomic counter.
+*
+* @param v
+*   A pointer to the atomic counter.
+*/
+static inline void
+rte_atomic16_init(rte_atomic16_t *v)
+{
+    v->cnt = 0;
+}
+
+/**
+* Atomically read a 16-bit value from a counter.
+*
+* @param v
+*   A pointer to the atomic counter.
+* @return
+*   The value of the counter.
+*/
+static inline int16_t
+rte_atomic16_read(const rte_atomic16_t *v)
+{
+    return v->cnt;
+}
+
+/**
+* Atomically set a counter to a 16-bit value.
+*
+* @param v
+*   A pointer to the atomic counter.
+* @param new_value
+*   The new value for the counter.
+*/
+static inline void
+rte_atomic16_set(rte_atomic16_t *v, int16_t new_value)
+{
+    _InterlockedExchange16(&v->cnt, new_value);
+}
+
+/**
+* Atomically add a 16-bit value to an atomic counter.
+*
+* @param v
+*   A pointer to the atomic counter.
+* @param inc
+*   The value to be added to the counter.
+*/
+static inline void
+rte_atomic16_add(rte_atomic16_t *v, int16_t inc)
+{
+    _InterlockedExchangeAdd16(&v->cnt, inc);
+}
+
+/**
+* Atomically subtract a 16-bit value from an atomic counter.
+*
+* @param v
+*   A pointer to the atomic counter.
+* @param dec
+*   The value to be subtracted from the counter.
+*/
+static inline void
+rte_atomic16_sub(rte_atomic16_t *v, int16_t dec)
+{
+    _InterlockedExchangeAdd16(&v->cnt, (-dec));
+}
+
+/**
+* Atomically increment a counter by one.
+*
+* @param v
+*   A pointer to the atomic counter.
+*/
+static inline void
+rte_atomic16_inc(rte_atomic16_t *v)
+{
+    rte_atomic16_add(v, 1);
+}
+
+/**
+* Atomically decrement a counter by one.
+*
+* @param v
+*   A pointer to the atomic counter.
+*/
+static inline void
+rte_atomic16_dec(rte_atomic16_t *v)
+{
+    rte_atomic16_sub(v, 1);
+}
+
+/**
+* Atomically add a 16-bit value to a counter and return the result.
+*
+* Atomically adds the 16-bits value (inc) to the atomic counter (v) and
+* returns the value of v after addition.
+*
+* @param v
+*   A pointer to the atomic counter.
+* @param inc
+*   The value to be added to the counter.
+* @return
+*   The value of v after the addition.
+*/
+static inline int16_t
+rte_atomic16_add_return(rte_atomic16_t *v, int16_t inc)
+{
+    _InterlockedExchangeAdd16(&v->cnt, inc);
+    return v->cnt;
+}
+
+/**
+* Atomically subtract a 16-bit value from a counter and return
+* the result.
+*
+* Atomically subtracts the 16-bit value (inc) from the atomic counter
+* (v) and returns the value of v after the subtraction.
+*
+* @param v
+*   A pointer to the atomic counter.
+* @param dec
+*   The value to be subtracted from the counter.
+* @return
+*   The value of v after the subtraction.
+*/
+static inline int16_t
+rte_atomic16_sub_return(rte_atomic16_t *v, int16_t dec)
+{
+    _InterlockedExchangeAdd16(&v->cnt, (-dec));
+    return v->cnt;
+}
+
+/**
+* Atomically increment a 16-bit counter by one and test.
+*
+* Atomically increments the atomic counter (v) by one and returns true if
+* the result is 0, or false in all other cases.
+*
+* @param v
+*   A pointer to the atomic counter.
+* @return
+*   True if the result after the increment operation is 0; false otherwise.
+*/
+static inline int rte_atomic16_inc_and_test(rte_atomic16_t *v)
+{
+    return ((rte_atomic16_add_return(v, 1) == 0));
+}
+
+/**
+* Atomically decrement a 16-bit counter by one and test.
+*
+* Atomically decrements the atomic counter (v) by one and returns true if
+* the result is 0, or false in all other cases.
+*
+* @param v
+*   A pointer to the atomic counter.
+* @return
+*   True if the result after the decrement operation is 0; false otherwise.
+*/
+static inline int rte_atomic16_dec_and_test(rte_atomic16_t *v)
+{
+    return ((rte_atomic16_sub_return(v, 1) == 0));
+}
+
+/**
+* Atomically test and set a 16-bit atomic counter.
+*
+* If the counter value is already set, return 0 (failed). Otherwise, set
+* the counter value to 1 and return 1 (success).
+*
+* @param v
+*   A pointer to the atomic counter.
+* @return
+*   0 if failed; else 1, success.
+*/
+static inline int rte_atomic16_test_and_set(rte_atomic16_t *v)
+{
+    return rte_atomic16_cmpset((volatile uint16_t *)&v->cnt, 0, 1);
+}
+
+/**
+* Atomically set a 16-bit counter to 0.
+*
+* @param v
+*   A pointer to the atomic counter.
+*/
+static inline void rte_atomic16_clear(rte_atomic16_t *v)
+{
+    rte_atomic16_set(v, 0);
+}
+
+/*------------------------- 32 bit atomic operations -------------------------*/
+
+/**
+* Atomic compare and set.
+*
+* (atomic) equivalent to:
+*   if (*dst == exp)
+*     *dst = src (all 32-bit words)
+*
+* @param dst
+*   The destination location into which the value will be written.
+* @param exp
+*   The expected value.
+* @param src
+*   The new value.
+* @return
+*   Non-zero on success; 0 on failure.
+*/
+static inline int
+rte_atomic32_cmpset(volatile uint32_t *dst, uint32_t exp, uint32_t src)
+{
+    return (_InterlockedCompareExchange(dst, src, exp) != src);
+}
+
+/**
+* The atomic counter structure.
+*/
+typedef struct {
+    volatile int32_t cnt; /**< An internal counter value. */
+} rte_atomic32_t;
+
+/**
+* Static initializer for an atomic counter.
+*/
+#define RTE_ATOMIC32_INIT(val) { (val) }
+
+/**
+* Initialize an atomic counter.
+*
+* @param v
+*   A pointer to the atomic counter.
+*/
+static inline void
+rte_atomic32_init(rte_atomic32_t *v)
+{
+    v->cnt = 0;
+}
+
+/**
+* Atomically read a 32-bit value from a counter.
+*
+* @param v
+*   A pointer to the atomic counter.
+* @return
+*   The value of the counter.
+*/
+static inline int32_t
+rte_atomic32_read(const rte_atomic32_t *v)
+{
+    return v->cnt;
+}
+
+/**
+* Atomically set a counter to a 32-bit value.
+*
+* @param v
+*   A pointer to the atomic counter.
+* @param new_value
+*   The new value for the counter.
+*/
+static inline void
+rte_atomic32_set(rte_atomic32_t *v, int32_t new_value)
+{
+    _InterlockedExchange((LONG volatile *)&v->cnt, new_value);
+}
+
+/**
+* Atomically add a 32-bit value to an atomic counter.
+*
+* @param v
+*   A pointer to the atomic counter.
+* @param inc
+*   The value to be added to the counter.
+*/
+static inline void
+rte_atomic32_add(rte_atomic32_t *v, int32_t inc)
+{
+    _InterlockedExchangeAdd((LONG volatile *)&v->cnt, inc);
+}
+
+/**
+* Atomically subtract a 32-bit value from an atomic counter.
+*
+* @param v
+*   A pointer to the atomic counter.
+* @param dec
+*   The value to be subtracted from the counter.
+*/
+static inline void
+rte_atomic32_sub(rte_atomic32_t *v, int32_t dec)
+{
+    _InterlockedExchangeAdd((LONG volatile *)&v->cnt, (-dec));
+}
+
+/**
+* Atomically increment a counter by one.
+*
+* @param v
+*   A pointer to the atomic counter.
+*/
+static inline void
+rte_atomic32_inc(rte_atomic32_t *v)
+{
+    rte_atomic32_add(v, 1);
+}
+
+/**
+* Atomically decrement a counter by one.
+*
+* @param v
+*   A pointer to the atomic counter.
+*/
+static inline void
+rte_atomic32_dec(rte_atomic32_t *v)
+{
+    rte_atomic32_sub(v, 1);
+}
+
+/**
+* Atomically add a 32-bit value to a counter and return the result.
+*
+* Atomically adds the 32-bits value (inc) to the atomic counter (v) and
+* returns the value of v after addition.
+*
+* @param v
+*   A pointer to the atomic counter.
+* @param inc
+*   The value to be added to the counter.
+* @return
+*   The value of v after the addition.
+*/
+static inline int32_t
+rte_atomic32_add_return(rte_atomic32_t *v, int32_t inc)
+{
+    _InterlockedExchangeAdd((LONG volatile *)&v->cnt, inc);
+    return v->cnt;
+}
+
+/**
+* Atomically subtract a 32-bit value from a counter and return
+* the result.
+*
+* Atomically subtracts the 32-bit value (inc) from the atomic counter
+* (v) and returns the value of v after the subtraction.
+*
+* @param v
+*   A pointer to the atomic counter.
+* @param dec
+*   The value to be subtracted from the counter.
+* @return
+*   The value of v after the subtraction.
+*/
+static inline int32_t
+rte_atomic32_sub_return(rte_atomic32_t *v, int32_t dec)
+{
+    _InterlockedExchangeAdd((LONG volatile *)&v->cnt, (-dec));
+    return v->cnt;
+}
+
+/**
+* Atomically increment a 32-bit counter by one and test.
+*
+* Atomically increments the atomic counter (v) by one and returns true if
+* the result is 0, or false in all other cases.
+*
+* @param v
+*   A pointer to the atomic counter.
+* @return
+*   True if the result after the increment operation is 0; false otherwise.
+*/
+static inline int rte_atomic32_inc_and_test(rte_atomic32_t *v)
+{
+    return ((rte_atomic32_add_return(v, 1) == 0));
+}
+
+/**
+* Atomically decrement a 32-bit counter by one and test.
+*
+* Atomically decrements the atomic counter (v) by one and returns true if
+* the result is 0, or false in all other cases.
+*
+* @param v
+*   A pointer to the atomic counter.
+* @return
+*   True if the result after the decrement operation is 0; false otherwise.
+*/
+static inline int rte_atomic32_dec_and_test(rte_atomic32_t *v)
+{
+    return ((rte_atomic32_sub_return(v, 1) == 0));
+}
+
+/**
+* Atomically test and set a 32-bit atomic counter.
+*
+* If the counter value is already set, return 0 (failed). Otherwise, set
+* the counter value to 1 and return 1 (success).
+*
+* @param v
+*   A pointer to the atomic counter.
+* @return
+*   0 if failed; else 1, success.
+*/
+static inline int rte_atomic32_test_and_set(rte_atomic32_t *v)
+{
+    return rte_atomic32_cmpset((volatile uint32_t *)&v->cnt, 0, 1);
+}
+
+/**
+* Atomically set a 32-bit counter to 0.
+*
+* @param v
+*   A pointer to the atomic counter.
+*/
+static inline void rte_atomic32_clear(rte_atomic32_t *v)
+{
+    rte_atomic32_set(v, 0);
+}
+
+/*------------------------- 64 bit atomic operations -------------------------*/
+
+/**
+* An atomic compare and set function used by the mutex functions.
+* (atomic) equivalent to:
+*   if (*dst == exp)
+*     *dst = src (all 64-bit words)
+*
+* @param dst
+*   The destination into which the value will be written.
+* @param exp
+*   The expected value.
+* @param src
+*   The new value.
+* @return
+*   Non-zero on success; 0 on failure.
+*/
+static inline int
+rte_atomic64_cmpset(volatile uint64_t *dst, uint64_t exp, uint64_t src)
+{
+    return (_InterlockedCompareExchange64((volatile LONG64 *)dst, src, exp) != src);
+}
+
+/**
+* Atomic exchange.
+*
+* (atomic)equivalent to :
+*ret = *dst
+*   *dst = val;
+*return ret;
+*
+* @param dst
+*   The destination location into which the value will be written.
+* @param val
+*   The new value.
+* @return
+*   The original value at that location
+**/
+static inline uint64_t
+rte_atomic64_exchange(volatile uint64_t *dst, uint64_t val){
+	return _InterlockedExchange64((volatile LONG64 *)dst, val);
+}
+
+/**
+* The atomic counter structure.
+*/
+typedef struct {
+    volatile int64_t cnt;  /**< Internal counter value. */
+} rte_atomic64_t;
+
+/**
+* Static initializer for an atomic counter.
+*/
+#define RTE_ATOMIC64_INIT(val) { (val) }
+
+/**
+* Initialize the atomic counter.
+*
+* @param v
+*   A pointer to the atomic counter.
+*/
+static inline void
+rte_atomic64_init(rte_atomic64_t *v)
+{
+    v->cnt = 0;
+}
+
+/**
+* Atomically read a 64-bit counter.
+*
+* @param v
+*   A pointer to the atomic counter.
+* @return
+*   The value of the counter.
+*/
+static inline int64_t
+rte_atomic64_read(rte_atomic64_t *v)
+{
+    return v->cnt;
+}
+
+/**
+* Atomically set a 64-bit counter.
+*
+* @param v
+*   A pointer to the atomic counter.
+* @param new_value
+*   The new value of the counter.
+*/
+static inline void
+rte_atomic64_set(rte_atomic64_t *v, int64_t new_value)
+{
+    _InterlockedExchange64(&v->cnt, new_value);
+}
+
+/**
+* Atomically add a 64-bit value to a counter.
+*
+* @param v
+*   A pointer to the atomic counter.
+* @param inc
+*   The value to be added to the counter.
+*/
+static inline void
+rte_atomic64_add(rte_atomic64_t *v, int64_t inc)
+{
+    _InterlockedExchangeAdd64(&v->cnt, inc);
+}
+
+/**
+* Atomically subtract a 64-bit value from a counter.
+*
+* @param v
+*   A pointer to the atomic counter.
+* @param dec
+*   The value to be subtracted from the counter.
+*/
+static inline void
+rte_atomic64_sub(rte_atomic64_t *v, int64_t dec)
+{
+    _InterlockedExchangeAdd64(&v->cnt, (-dec));
+}
+
+/**
+* Atomically increment a 64-bit counter by one and test.
+*
+* @param v
+*   A pointer to the atomic counter.
+*/
+static inline void
+rte_atomic64_inc(rte_atomic64_t *v)
+{
+    _InterlockedIncrement64(&v->cnt);
+}
+
+/**
+* Atomically decrement a 64-bit counter by one and test.
+*
+* @param v
+*   A pointer to the atomic counter.
+*/
+static inline void
+rte_atomic64_dec(rte_atomic64_t *v)
+{
+    _InterlockedDecrement64(&v->cnt);
+}
+
+/**
+* Add a 64-bit value to an atomic counter and return the result.
+*
+* Atomically adds the 64-bit value (inc) to the atomic counter (v) and
+* returns the value of v after the addition.
+*
+* @param v
+*   A pointer to the atomic counter.
+* @param inc
+*   The value to be added to the counter.
+* @return
+*   The value of v after the addition.
+*/
+static inline int64_t
+rte_atomic64_add_return(rte_atomic64_t *v, int64_t inc)
+{
+    _InterlockedExchangeAdd64(&v->cnt, inc);
+    return v->cnt;
+}
+
+/**
+* Subtract a 64-bit value from an atomic counter and return the result.
+*
+* Atomically subtracts the 64-bit value (dec) from the atomic counter (v)
+* and returns the value of v after the subtraction.
+*
+* @param v
+*   A pointer to the atomic counter.
+* @param dec
+*   The value to be subtracted from the counter.
+* @return
+*   The value of v after the subtraction.
+*/
+static inline int64_t
+rte_atomic64_sub_return(rte_atomic64_t *v, int64_t dec)
+{
+    _InterlockedExchangeAdd64(&v->cnt, (-dec));
+    return v->cnt;
+}
+
+/**
+* Atomically increment a 64-bit counter by one and test.
+*
+* Atomically increments the atomic counter (v) by one and returns
+* true if the result is 0, or false in all other cases.
+*
+* @param v
+*   A pointer to the atomic counter.
+* @return
+*   True if the result after the addition is 0; false otherwise.
+*/
+static inline int rte_atomic64_inc_and_test(rte_atomic64_t *v)
+{
+    return ((rte_atomic64_add_return(v, 1) == 0));
+}
+
+/**
+* Atomically decrement a 64-bit counter by one and test.
+*
+* Atomically decrements the atomic counter (v) by one and returns true if
+* the result is 0, or false in all other cases.
+*
+* @param v
+*   A pointer to the atomic counter.
+* @return
+*   True if the result after subtraction is 0; false otherwise.
+*/
+static inline int rte_atomic64_dec_and_test(rte_atomic64_t *v)
+{
+    return ((rte_atomic64_sub_return(v, 1) == 0));
+}
+
+/**
+* Atomically test and set a 64-bit atomic counter.
+*
+* If the counter value is already set, return 0 (failed). Otherwise, set
+* the counter value to 1 and return 1 (success).
+*
+* @param v
+*   A pointer to the atomic counter.
+* @return
+*   0 if failed; else 1, success.
+*/
+static inline int rte_atomic64_test_and_set(rte_atomic64_t *v)
+{
+    return rte_atomic64_cmpset((volatile uint64_t *)&v->cnt, 0, 1);
+}
+
+/**
+* Atomically set a 64-bit counter to 0.
+*
+* @param v
+*   A pointer to the atomic counter.
+*/
+static inline void rte_atomic64_clear(rte_atomic64_t *v)
+{
+    rte_atomic64_set(v, 0);
+}
+
+#endif /* _RTE_ATOMIC_H_ */
+
+/* */
+/* */
diff --git a/lib/librte_eal/windows/rte_override/rte_bus_pci.h b/lib/librte_eal/windows/rte_override/rte_bus_pci.h
new file mode 100644
index 000000000..d7950e218
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_bus_pci.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#pragma once
+
+/* include the original file, so that we can re-define certain macros */
+#include "..\..\..\..\drivers\bus\pci\rte_bus_pci.h"
+
+/* Need to re-define RTE_PMD_REGISTER_PCI for Windows */
+#ifdef RTE_PMD_REGISTER_PCI(nm, pci_drv)
+#undef RTE_PMD_REGISTER_PCI(nm, pci_drv)
+#endif
+
+/*
+* Definition for registering PMDs
+* (This is a workaround for Windows in lieu of a constructor-like function)
+*/
+#define RTE_PMD_REGISTER_PCI(nm, pci_drv) \
+void pciinitfn_##nm(void); \
+void pciinitfn_##nm(void) \
+{\
+	(pci_drv).driver.name = RTE_STR(nm);\
+	rte_pci_register(&pci_drv); \
+}
diff --git a/lib/librte_eal/windows/rte_override/rte_byteorder.h b/lib/librte_eal/windows/rte_override/rte_byteorder.h
new file mode 100644
index 000000000..b87a42756
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_byteorder.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+#pragma once
+
+#ifndef RTE_BYTE_ORDER
+#define RTE_BYTE_ORDER RTE_LITTLE_ENDIAN
+#endif
+
+#include "..\..\common\include\arch\x86\rte_byteorder.h"
\ No newline at end of file
diff --git a/lib/librte_eal/windows/rte_override/rte_common.h b/lib/librte_eal/windows/rte_override/rte_common.h
new file mode 100644
index 000000000..564fe6f82
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_common.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#pragma once
+
+/* If rte_common.h has already been included, then we will have issues */
+#ifdef _RTE_COMMON_H_
+#error
+#endif
+
+#ifdef DPDKWIN_NO_WARNINGS
+#pragma warning (disable : 42)
+#endif
+
+#include <rte_wincompat.h>
+
+#include "../common/include/rte_common.h"
+
+#ifdef DPDKWIN_NO_WARNINGS
+#pragma warning (enable : 42)
+#endif
+
+#ifdef container_of
+/* undefine the existing definition, so that we can use the Windows-compliant version */
+#undef container_of
+#endif
+
+#define container_of(ptr, type, member)		CONTAINING_RECORD(ptr, type, member)
+
+
+/* Override RTE_MIN() / RTE_MAX() as defined, since the one in rte_common uses typeof....TODO: Diagnose this later */
+#undef RTE_MIN
+#define RTE_MIN(a, b)	(((a) < (b)) ? (a) : (b))
+
+#undef RTE_MAX
+#define RTE_MAX(a, b)	max(a, b)
+
+/* Redefine these macros with appropriate typecasting */
+#undef RTE_ALIGN_FLOOR
+#define RTE_ALIGN_FLOOR(val, align)		((uintptr_t)(val) & (~((uintptr_t)((align) - 1))))
+
+#undef RTE_ALIGN_CEIL
+#define RTE_ALIGN_CEIL(val, align)		RTE_ALIGN_FLOOR((val + ((uintptr_t)(align) - 1)), align)
+
+#undef RTE_ALIGN
+#define RTE_ALIGN(val, align)			RTE_ALIGN_CEIL(val, align)
+
+#undef RTE_PTR_ALIGN_FLOOR
+#define RTE_PTR_ALIGN_FLOOR(ptr, align)		(void *)(RTE_ALIGN_FLOOR((uintptr_t)ptr, align))
+
+#undef RTE_PTR_ALIGN_CEIL
+#define RTE_PTR_ALIGN_CEIL(ptr, align)		(void *)RTE_PTR_ALIGN_FLOOR((uintptr_t)RTE_PTR_ADD(ptr, (align) - 1), align)
+
+#undef RTE_LEN2MASK
+#define	RTE_LEN2MASK(ln, tp)			((uint64_t)-1 >> (sizeof(uint64_t) * CHAR_BIT - (ln)))
diff --git a/lib/librte_eal/windows/rte_override/rte_common.h.sav b/lib/librte_eal/windows/rte_override/rte_common.h.sav
new file mode 100644
index 000000000..6f067aa3f
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_common.h.sav
@@ -0,0 +1,372 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#ifndef _RTE_COMMON_H_
+#define _RTE_COMMON_H_
+
+/**
+ * @file
+ *
+ * Generic, commonly-used macro and inline function definitions
+ * for DPDK.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+
+#ifndef typeof
+#define typeof __typeof__
+#endif
+
+#ifndef asm
+#define asm __asm__
+#endif
+
+#ifdef RTE_ARCH_STRICT_ALIGN
+typedef uint64_t unaligned_uint64_t __attribute__ ((aligned(1)));
+typedef uint32_t unaligned_uint32_t __attribute__ ((aligned(1)));
+typedef uint16_t unaligned_uint16_t __attribute__ ((aligned(1)));
+#else
+typedef uint64_t unaligned_uint64_t;
+typedef uint32_t unaligned_uint32_t;
+typedef uint16_t unaligned_uint16_t;
+#endif
+
+/**
+ * Force alignment
+ */
+#define __rte_aligned(a) __attribute__((__aligned__(a)))
+
+/**
+ * Force a structure to be packed
+ */
+#define __rte_packed __attribute__((__packed__))
+
+/******* Macro to mark functions and fields scheduled for removal *****/
+#define __rte_deprecated	__attribute__((__deprecated__))
+
+/*********** Macros to eliminate unused variable warnings ********/
+
+/**
+ * short definition to mark a function parameter unused
+ */
+#define __rte_unused __attribute__((__unused__))
+
+/**
+ * definition to mark a variable or function parameter as used so
+ * as to avoid a compiler warning
+ */
+#define RTE_SET_USED(x) (void)(x)
+
+/*********** Macros for pointer arithmetic ********/
+
+/**
+ * add a byte-value offset from a pointer
+ */
+#define RTE_PTR_ADD(ptr, x) ((void*)((uintptr_t)(ptr) + (x)))
+
+/**
+ * subtract a byte-value offset from a pointer
+ */
+#define RTE_PTR_SUB(ptr, x) ((void*)((uintptr_t)ptr - (x)))
+
+/**
+ * get the difference between two pointer values, i.e. how far apart
+ * in bytes are the locations they point two. It is assumed that
+ * ptr1 is greater than ptr2.
+ */
+#define RTE_PTR_DIFF(ptr1, ptr2) ((uintptr_t)(ptr1) - (uintptr_t)(ptr2))
+
+/*********** Macros/static functions for doing alignment ********/
+
+
+/**
+ * Macro to align a pointer to a given power-of-two. The resultant
+ * pointer will be a pointer of the same type as the first parameter, and
+ * point to an address no higher than the first parameter. Second parameter
+ * must be a power-of-two value.
+ */
+#define RTE_PTR_ALIGN_FLOOR(ptr, align) \
+	((typeof(ptr))RTE_ALIGN_FLOOR((uintptr_t)ptr, align))
+
+/**
+ * Macro to align a value to a given power-of-two. The resultant value
+ * will be of the same type as the first parameter, and will be no
+ * bigger than the first parameter. Second parameter must be a
+ * power-of-two value.
+ */
+#define RTE_ALIGN_FLOOR(val, align) \
+	(typeof(val))((val) & (~((typeof(val))((align) - 1))))
+
+/**
+ * Macro to align a pointer to a given power-of-two. The resultant
+ * pointer will be a pointer of the same type as the first parameter, and
+ * point to an address no lower than the first parameter. Second parameter
+ * must be a power-of-two value.
+ */
+#define RTE_PTR_ALIGN_CEIL(ptr, align) \
+	RTE_PTR_ALIGN_FLOOR((typeof(ptr))RTE_PTR_ADD(ptr, (align) - 1), align)
+
+/**
+ * Macro to align a value to a given power-of-two. The resultant value
+ * will be of the same type as the first parameter, and will be no lower
+ * than the first parameter. Second parameter must be a power-of-two
+ * value.
+ */
+#define RTE_ALIGN_CEIL(val, align) \
+	RTE_ALIGN_FLOOR(((val) + ((typeof(val)) (align) - 1)), align)
+
+/**
+ * Macro to align a pointer to a given power-of-two. The resultant
+ * pointer will be a pointer of the same type as the first parameter, and
+ * point to an address no lower than the first parameter. Second parameter
+ * must be a power-of-two value.
+ * This function is the same as RTE_PTR_ALIGN_CEIL
+ */
+#define RTE_PTR_ALIGN(ptr, align) RTE_PTR_ALIGN_CEIL(ptr, align)
+
+/**
+ * Macro to align a value to a given power-of-two. The resultant
+ * value will be of the same type as the first parameter, and
+ * will be no lower than the first parameter. Second parameter
+ * must be a power-of-two value.
+ * This function is the same as RTE_ALIGN_CEIL
+ */
+#define RTE_ALIGN(val, align) RTE_ALIGN_CEIL(val, align)
+
+/**
+ * Checks if a pointer is aligned to a given power-of-two value
+ *
+ * @param ptr
+ *   The pointer whose alignment is to be checked
+ * @param align
+ *   The power-of-two value to which the ptr should be aligned
+ *
+ * @return
+ *   True(1) where the pointer is correctly aligned, false(0) otherwise
+ */
+static inline int
+rte_is_aligned(void *ptr, unsigned align)
+{
+	return (((uintptr_t)ptr % align) == 0);
+}
+
+/*********** Macros for compile type checks ********/
+
+/**
+ * Triggers an error at compilation time if the condition is true.
+ */
+#ifndef __OPTIMIZE__
+#define RTE_BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
+#else
+extern int RTE_BUILD_BUG_ON_detected_error;
+#define RTE_BUILD_BUG_ON(condition) do {             \
+	((void)sizeof(char[1 - 2*!!(condition)]));   \
+	if (condition)                               \
+		RTE_BUILD_BUG_ON_detected_error = 1; \
+} while(0)
+#endif
+
+/*********** Macros to work with powers of 2 ********/
+
+/**
+ * Returns true if n is a power of 2
+ * @param n
+ *     Number to check
+ * @return 1 if true, 0 otherwise
+ */
+static inline int
+rte_is_power_of_2(uint32_t n)
+{
+	return n && !(n & (n - 1));
+}
+
+/**
+ * Aligns input parameter to the next power of 2
+ *
+ * @param x
+ *   The integer value to algin
+ *
+ * @return
+ *   Input parameter aligned to the next power of 2
+ */
+static inline uint32_t
+rte_align32pow2(uint32_t x)
+{
+	x--;
+	x |= x >> 1;
+	x |= x >> 2;
+	x |= x >> 4;
+	x |= x >> 8;
+	x |= x >> 16;
+
+	return x + 1;
+}
+
+/**
+ * Aligns 64b input parameter to the next power of 2
+ *
+ * @param v
+ *   The 64b value to align
+ *
+ * @return
+ *   Input parameter aligned to the next power of 2
+ */
+static inline uint64_t
+rte_align64pow2(uint64_t v)
+{
+	v--;
+	v |= v >> 1;
+	v |= v >> 2;
+	v |= v >> 4;
+	v |= v >> 8;
+	v |= v >> 16;
+	v |= v >> 32;
+
+	return v + 1;
+}
+
+/*********** Macros for calculating min and max **********/
+
+/**
+ * Macro to return the minimum of two numbers
+ */
+#define RTE_MIN(a, b) ({ \
+		typeof (a) _a = (a); \
+		typeof (b) _b = (b); \
+		_a < _b ? _a : _b; \
+	})
+
+/**
+ * Macro to return the maximum of two numbers
+ */
+#define RTE_MAX(a, b) ({ \
+		typeof (a) _a = (a); \
+		typeof (b) _b = (b); \
+		_a > _b ? _a : _b; \
+	})
+
+/*********** Other general functions / macros ********/
+
+#ifdef __SSE2__
+#include <emmintrin.h>
+/**
+ * PAUSE instruction for tight loops (avoid busy waiting)
+ */
+static inline void
+rte_pause (void)
+{
+	_mm_pause();
+}
+#else
+static inline void
+rte_pause(void) {}
+#endif
+
+/**
+ * Searches the input parameter for the least significant set bit
+ * (starting from zero).
+ * If a least significant 1 bit is found, its bit index is returned.
+ * If the content of the input parameter is zero, then the content of the return
+ * value is undefined.
+ * @param v
+ *     input parameter, should not be zero.
+ * @return
+ *     least significant set bit in the input parameter.
+ */
+static inline uint32_t
+rte_bsf32(uint32_t v)
+{
+	return __builtin_ctz(v);
+}
+
+#ifndef offsetof
+/** Return the offset of a field in a structure. */
+#define offsetof(TYPE, MEMBER)  __builtin_offsetof (TYPE, MEMBER)
+#endif
+
+#define _RTE_STR(x) #x
+/** Take a macro value and get a string version of it */
+#define RTE_STR(x) _RTE_STR(x)
+
+/** Mask value of type "tp" for the first "ln" bit set. */
+#define	RTE_LEN2MASK(ln, tp)	\
+	((tp)((uint64_t)-1 >> (sizeof(uint64_t) * CHAR_BIT - (ln))))
+
+/** Number of elements in the array. */
+#define	RTE_DIM(a)	(sizeof (a) / sizeof ((a)[0]))
+
+/**
+ * Converts a numeric string to the equivalent uint64_t value.
+ * As well as straight number conversion, also recognises the suffixes
+ * k, m and g for kilobytes, megabytes and gigabytes respectively.
+ *
+ * If a negative number is passed in  i.e. a string with the first non-black
+ * character being "-", zero is returned. Zero is also returned in the case of
+ * an error with the strtoull call in the function.
+ *
+ * @param str
+ *     String containing number to convert.
+ * @return
+ *     Number.
+ */
+static inline uint64_t
+rte_str_to_size(const char *str)
+{
+	char *endptr;
+	unsigned long long size;
+
+	while (isspace((int)*str))
+		str++;
+	if (*str == '-')
+		return 0;
+
+	errno = 0;
+	size = strtoull(str, &endptr, 0);
+	if (errno)
+		return 0;
+
+	if (*endptr == ' ')
+		endptr++; /* allow 1 space gap */
+
+	switch (*endptr){
+	case 'G': case 'g': size *= 1024; /* fall-through */
+	case 'M': case 'm': size *= 1024; /* fall-through */
+	case 'K': case 'k': size *= 1024; /* fall-through */
+	default:
+		break;
+	}
+	return size;
+}
+
+/**
+ * Function to terminate the application immediately, printing an error
+ * message and returning the exit_code back to the shell.
+ *
+ * This function never returns
+ *
+ * @param exit_code
+ *     The exit code to be returned by the application
+ * @param format
+ *     The format string to be used for printing the message. This can include
+ *     printf format characters which will be expanded using any further parameters
+ *     to the function.
+ */
+void
+rte_exit(int exit_code, const char *format, ...)
+	__attribute__((noreturn))
+	__attribute__((format(printf, 2, 3)));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/librte_eal/windows/rte_override/rte_config.h b/lib/librte_eal/windows/rte_override/rte_config.h
new file mode 100644
index 000000000..d26f689b1
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_config.h
@@ -0,0 +1,328 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#define RTE_EXEC_ENV "windowsapp"
+#define RTE_EXEC_ENV_WINDOWSAPP 1
+#define RTE_MACHINE "native"
+#define RTE_ARCH "x86_64"
+#define RTE_ARCH_X86_64 1
+#define RTE_TOOLCHAIN "icc"
+#define RTE_TOOLCHAIN_ICC 1
+#undef RTE_LIBC
+#undef RTE_LIBC_NEWLIB_SRC
+#undef RTE_LIBC_NEWLIB_BIN
+#undef RTE_LIBC_NETINCS
+#undef RTE_LIBGLOSS
+
+#define RTE_MAX_HEAPS 32
+#define RTE_MAX_MEMSEG_LISTS 128
+#define RTE_MAX_MEMSEG_PER_LIST 8192
+#define RTE_LIBRTE_EAL 1
+#define RTE_MAX_LCORE 128
+#define RTE_MAX_NUMA_NODES 8
+#define RTE_MAX_MEMSEG 256
+#define RTE_MAX_MEMZONE 2560
+#define RTE_MAX_TAILQ 32
+#define RTE_LOG_LEVEL RTE_LOG_DEBUG
+#define RTE_LOG_DP_LEVEL RTE_LOG_DEBUG
+#define RTE_LOG_HISTORY 256
+#undef RTE_LIBEAL_USE_HPET
+#undef RTE_EAL_ALLOW_INV_SOCKET_ID
+#undef RTE_EAL_ALWAYS_PANIC_ON_ERROR
+#undef RTE_EAL_UNBIND_PORTS
+#define RTE_LIBRTE_EAL_LINUXAPP 1
+#undef RTE_LIBRTE_EAL_BAREMETAL
+#define RTE_ENABLE_AVX 1
+#undef RTE_ENABLE_AVX512
+#undef RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT
+#define RTE_LIBRTE_PCI 1
+#define RTE_LIBRTE_KVARGS 1
+#define RTE_LIBRTE_ETHDEV 1
+#undef RTE_LIBRTE_ETHDEV_DEBUG
+#define RTE_MAX_ETHPORTS 32
+#define RTE_MAX_QUEUES_PER_PORT 1024
+#undef RTE_LIBRTE_IEEE1588
+#define RTE_ETHDEV_QUEUE_STAT_CNTRS 16
+#define RTE_ETHDEV_RXTX_CALLBACKS 1
+#undef RTE_ETHDEV_PROFILE_ITT_WASTED_RX_ITERATIONS
+#undef RTE_ETHDEV_TX_PREPARE_NOOP
+#define RTE_LIBRTE_PCI_BUS 1
+#undef RTE_LIBRTE_ENA_PMD
+#undef RTE_LIBRTE_ENA_DEBUG_RX
+#undef RTE_LIBRTE_ENA_DEBUG_TX
+#undef RTE_LIBRTE_ENA_DEBUG_TX_FREE
+#undef RTE_LIBRTE_ENA_DEBUG_DRIVER
+#undef RTE_LIBRTE_ENA_COM_DEBUG
+#define RTE_LIBRTE_EM_PMD 1
+#define RTE_LIBRTE_IGB_PMD 1
+#undef RTE_LIBRTE_E1000_DEBUG_INIT
+#undef RTE_LIBRTE_E1000_DEBUG_RX
+#undef RTE_LIBRTE_E1000_DEBUG_TX
+#undef RTE_LIBRTE_E1000_DEBUG_TX_FREE
+#undef RTE_LIBRTE_E1000_DEBUG_DRIVER
+#undef RTE_LIBRTE_E1000_PF_DISABLE_STRIP_CRC
+#define RTE_LIBRTE_IXGBE_PMD 1
+#undef RTE_LIBRTE_IXGBE_DEBUG_INIT
+#undef RTE_LIBRTE_IXGBE_DEBUG_RX
+#undef RTE_LIBRTE_IXGBE_DEBUG_TX
+#undef RTE_LIBRTE_IXGBE_DEBUG_TX_FREE
+#undef RTE_LIBRTE_IXGBE_DEBUG_DRIVER
+#undef RTE_LIBRTE_IXGBE_PF_DISABLE_STRIP_CRC
+#define RTE_IXGBE_INC_VECTOR 1
+#undef RTE_LIBRTE_IXGBE_BYPASS
+#define RTE_LIBRTE_I40E_PMD 1
+#undef RTE_LIBRTE_I40E_DEBUG_RX
+#undef RTE_LIBRTE_I40E_DEBUG_TX
+#undef RTE_LIBRTE_I40E_DEBUG_TX_FREE
+#define RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC 1
+#define RTE_LIBRTE_I40E_INC_VECTOR 1
+#undef RTE_LIBRTE_I40E_16BYTE_RX_DESC
+#define RTE_LIBRTE_I40E_QUEUE_NUM_PER_PF 64
+#define RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF 4
+#define RTE_LIBRTE_I40E_QUEUE_NUM_PER_VM 4
+#define RTE_LIBRTE_I40E_ITR_INTERVAL -1
+#undef RTE_LIBRTE_FM10K_PMD
+#undef RTE_LIBRTE_FM10K_DEBUG_INIT
+#undef RTE_LIBRTE_FM10K_DEBUG_RX
+#undef RTE_LIBRTE_FM10K_DEBUG_TX
+#undef RTE_LIBRTE_FM10K_DEBUG_TX_FREE
+#undef RTE_LIBRTE_FM10K_DEBUG_DRIVER
+#define RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE 1
+#define RTE_LIBRTE_FM10K_INC_VECTOR 1
+#undef RTE_LIBRTE_MLX4_PMD
+#undef RTE_LIBRTE_MLX4_DEBUG
+#undef RTE_LIBRTE_MLX4_DEBUG_BROKEN_VERBS
+#define RTE_LIBRTE_MLX4_TX_MP_CACHE 8
+#undef RTE_LIBRTE_MLX5_PMD
+#undef RTE_LIBRTE_MLX5_DEBUG
+#define RTE_LIBRTE_MLX5_TX_MP_CACHE 8
+#undef RTE_LIBRTE_BNX2X_PMD
+#undef RTE_LIBRTE_BNX2X_DEBUG
+#undef RTE_LIBRTE_BNX2X_DEBUG_INIT
+#undef RTE_LIBRTE_BNX2X_DEBUG_RX
+#undef RTE_LIBRTE_BNX2X_DEBUG_TX
+#undef RTE_LIBRTE_BNX2X_MF_SUPPORT
+#undef RTE_LIBRTE_BNX2X_DEBUG_PERIODIC
+#undef RTE_LIBRTE_CXGBE_PMD
+#undef RTE_LIBRTE_CXGBE_DEBUG
+#undef RTE_LIBRTE_CXGBE_DEBUG_REG
+#undef RTE_LIBRTE_CXGBE_DEBUG_MBOX
+#undef RTE_LIBRTE_CXGBE_DEBUG_TX
+#undef RTE_LIBRTE_CXGBE_DEBUG_RX
+#undef RTE_LIBRTE_CXGBE_TPUT
+#undef RTE_LIBRTE_ENIC_PMD
+#undef RTE_LIBRTE_ENIC_DEBUG
+#undef RTE_LIBRTE_ENIC_DEBUG_FLOW
+#undef RTE_LIBRTE_NFP_PMD
+#undef RTE_LIBRTE_NFP_DEBUG
+#undef RTE_LIBRTE_MRVL_PMD
+#undef RTE_LIBRTE_BNXT_PMD
+#undef RTE_LIBRTE_SFC_EFX_PMD
+#undef RTE_LIBRTE_SFC_EFX_DEBUG
+#define RTE_LIBRTE_PMD_SOFTNIC 1
+#undef RTE_LIBRTE_PMD_SZEDATA2
+#define RTE_LIBRTE_PMD_SZEDATA2_AS 0
+#undef RTE_LIBRTE_THUNDERX_NICVF_PMD
+#undef RTE_LIBRTE_THUNDERX_NICVF_DEBUG_INIT
+#undef RTE_LIBRTE_THUNDERX_NICVF_DEBUG_RX
+#undef RTE_LIBRTE_THUNDERX_NICVF_DEBUG_TX
+#undef RTE_LIBRTE_THUNDERX_NICVF_DEBUG_DRIVER
+#undef RTE_LIBRTE_THUNDERX_NICVF_DEBUG_MBOX
+#undef RTE_LIBRTE_LIO_PMD
+#undef RTE_LIBRTE_LIO_DEBUG_DRIVER
+#undef RTE_LIBRTE_LIO_DEBUG_INIT
+#undef RTE_LIBRTE_LIO_DEBUG_RX
+#undef RTE_LIBRTE_LIO_DEBUG_TX
+#undef RTE_LIBRTE_LIO_DEBUG_MBOX
+#undef RTE_LIBRTE_LIO_DEBUG_REGS
+#undef RTE_LIBRTE_DPAA_BUS
+#undef RTE_LIBRTE_DPAA_MEMPOOL
+#undef RTE_LIBRTE_DPAA_PMD
+#undef RTE_LIBRTE_OCTEONTX_PMD
+#undef RTE_LIBRTE_OCTEONTX_DEBUG_INIT
+#undef RTE_LIBRTE_OCTEONTX_DEBUG_RX
+#undef RTE_LIBRTE_OCTEONTX_DEBUG_TX
+#undef RTE_LIBRTE_OCTEONTX_DEBUG_DRIVER
+#undef RTE_LIBRTE_OCTEONTX_DEBUG_MBOX
+#undef RTE_LIBRTE_FSLMC_BUS
+#undef RTE_LIBRTE_DPAA2_MEMPOOL
+#undef RTE_LIBRTE_DPAA2_USE_PHYS_IOVA
+#undef RTE_LIBRTE_DPAA2_PMD
+#undef RTE_LIBRTE_DPAA2_DEBUG_INIT
+#undef RTE_LIBRTE_DPAA2_DEBUG_DRIVER
+#undef RTE_LIBRTE_DPAA2_DEBUG_RX
+#undef RTE_LIBRTE_DPAA2_DEBUG_TX
+#undef RTE_LIBRTE_DPAA2_DEBUG_TX_FREE
+#undef RTE_LIBRTE_VIRTIO_PMD
+#undef RTE_LIBRTE_VIRTIO_DEBUG_INIT
+#undef RTE_LIBRTE_VIRTIO_DEBUG_RX
+#undef RTE_LIBRTE_VIRTIO_DEBUG_TX
+#undef RTE_LIBRTE_VIRTIO_DEBUG_DRIVER
+#undef RTE_LIBRTE_VIRTIO_DEBUG_DUMP
+#undef RTE_VIRTIO_USER
+#undef RTE_LIBRTE_VMXNET3_PMD
+#undef RTE_LIBRTE_VMXNET3_DEBUG_INIT
+#undef RTE_LIBRTE_VMXNET3_DEBUG_RX
+#undef RTE_LIBRTE_VMXNET3_DEBUG_TX
+#undef RTE_LIBRTE_VMXNET3_DEBUG_TX_FREE
+#undef RTE_LIBRTE_VMXNET3_DEBUG_DRIVER
+#define RTE_LIBRTE_PMD_RING 1
+#define RTE_PMD_RING_MAX_RX_RINGS 16
+#define RTE_PMD_RING_MAX_TX_RINGS 16
+#define RTE_LIBRTE_PMD_PCAP 1
+#undef RTE_LIBRTE_PMD_BOND
+#undef RTE_LIBRTE_BOND_DEBUG_ALB
+#undef RTE_LIBRTE_BOND_DEBUG_ALB_L1
+#undef RTE_LIBRTE_QEDE_PMD
+#undef RTE_LIBRTE_QEDE_DEBUG_INIT
+#undef RTE_LIBRTE_QEDE_DEBUG_INFO
+#undef RTE_LIBRTE_QEDE_DEBUG_DRIVER
+#undef RTE_LIBRTE_QEDE_DEBUG_TX
+#undef RTE_LIBRTE_QEDE_DEBUG_RX
+#define RTE_LIBRTE_QEDE_FW ""
+#undef RTE_LIBRTE_PMD_AF_PACKET
+#undef RTE_LIBRTE_ARK_PMD
+#undef RTE_LIBRTE_ARK_PAD_TX
+#undef RTE_LIBRTE_ARK_DEBUG_RX
+#undef RTE_LIBRTE_ARK_DEBUG_TX
+#undef RTE_LIBRTE_ARK_DEBUG_STATS
+#undef RTE_LIBRTE_ARK_DEBUG_TRACE
+#undef RTE_LIBRTE_AVP_PMD
+#undef RTE_LIBRTE_AVP_DEBUG_RX
+#undef RTE_LIBRTE_AVP_DEBUG_TX
+#undef RTE_LIBRTE_AVP_DEBUG_DRIVER
+#undef RTE_LIBRTE_AVP_DEBUG_BUFFERS
+#undef RTE_LIBRTE_PMD_TAP
+#undef RTE_LIBRTE_PMD_NULL
+#undef RTE_LIBRTE_PMD_FAILSAFE
+#define RTE_PMD_PACKET_PREFETCH 1
+#define RTE_LIBRTE_CRYPTODEV 1
+#undef RTE_LIBRTE_CRYPTODEV_DEBUG
+#define RTE_CRYPTO_MAX_DEVS 64
+#define RTE_CRYPTODEV_NAME_LEN 64
+#undef RTE_LIBRTE_PMD_ARMV8_CRYPTO
+#undef RTE_LIBRTE_PMD_ARMV8_CRYPTO_DEBUG
+#undef RTE_LIBRTE_PMD_DPAA2_SEC
+#undef RTE_LIBRTE_DPAA2_SEC_DEBUG_INIT
+#undef RTE_LIBRTE_DPAA2_SEC_DEBUG_DRIVER
+#undef RTE_LIBRTE_DPAA2_SEC_DEBUG_RX
+#undef RTE_LIBRTE_PMD_DPAA_SEC
+#undef RTE_LIBRTE_DPAA_SEC_DEBUG_INIT
+#undef RTE_LIBRTE_DPAA_SEC_DEBUG_DRIVER
+#undef RTE_LIBRTE_DPAA_SEC_DEBUG_RX
+#undef RTE_LIBRTE_PMD_QAT
+#undef RTE_LIBRTE_PMD_QAT_DEBUG_INIT
+#undef RTE_LIBRTE_PMD_QAT_DEBUG_TX
+#undef RTE_LIBRTE_PMD_QAT_DEBUG_RX
+#undef RTE_LIBRTE_PMD_QAT_DEBUG_DRIVER
+#define RTE_QAT_PMD_MAX_NB_SESSIONS 2048
+#undef RTE_LIBRTE_PMD_AESNI_MB
+#undef RTE_LIBRTE_PMD_AESNI_MB_DEBUG
+#undef RTE_LIBRTE_PMD_OPENSSL
+#undef RTE_LIBRTE_PMD_OPENSSL_DEBUG
+#undef RTE_LIBRTE_PMD_AESNI_GCM
+#undef RTE_LIBRTE_PMD_AESNI_GCM_DEBUG
+#undef RTE_LIBRTE_PMD_SNOW3G
+#undef RTE_LIBRTE_PMD_SNOW3G_DEBUG
+#undef RTE_LIBRTE_PMD_KASUMI
+#undef RTE_LIBRTE_PMD_KASUMI_DEBUG
+#undef RTE_LIBRTE_PMD_ZUC
+#undef RTE_LIBRTE_PMD_ZUC_DEBUG
+#undef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER
+#undef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER_DEBUG
+#undef RTE_LIBRTE_PMD_NULL_CRYPTO
+#undef RTE_LIBRTE_PMD_MRVL_CRYPTO
+#undef RTE_LIBRTE_PMD_MRVL_CRYPTO_DEBUG
+#define RTE_LIBRTE_SECURITY 1
+#define RTE_LIBRTE_EVENTDEV 1
+#undef RTE_LIBRTE_EVENTDEV_DEBUG
+#define RTE_EVENT_MAX_DEVS 16
+#define RTE_EVENT_MAX_QUEUES_PER_DEV 64
+#define RTE_LIBRTE_PMD_SKELETON_EVENTDEV 1
+#undef RTE_LIBRTE_PMD_SKELETON_EVENTDEV_DEBUG
+#define RTE_LIBRTE_PMD_SW_EVENTDEV 1
+#undef RTE_LIBRTE_PMD_SW_EVENTDEV_DEBUG
+#undef RTE_LIBRTE_PMD_OCTEONTX_SSOVF
+#undef RTE_LIBRTE_PMD_OCTEONTX_SSOVF_DEBUG
+#define RTE_LIBRTE_RING 1
+#undef RTE_LIBRTE_RING_DEBUG
+#define RTE_LIBRTE_MEMPOOL 1
+#define RTE_MEMPOOL_CACHE_MAX_SIZE 512
+#undef RTE_LIBRTE_MEMPOOL_DEBUG
+#define RTE_DRIVER_MEMPOOL_RING 1
+#define RTE_DRIVER_MEMPOOL_STACK 1
+#undef RTE_LIBRTE_OCTEONTX_MEMPOOL
+#undef RTE_LIBRTE_OCTEONTX_MEMPOOL_DEBUG
+#define RTE_LIBRTE_MBUF 1
+#undef RTE_LIBRTE_MBUF_DEBUG
+#define RTE_MBUF_DEFAULT_MEMPOOL_OPS "ring_mp_mc"
+#undef RTE_MBUF_SCATTER_GATHER 1
+#undef RTE_MBUF_REFCNT_ATOMIC 1
+#define RTE_PKTMBUF_HEADROOM 128
+#define RTE_LIBRTE_TIMER 1
+#undef RTE_LIBRTE_TIMER_DEBUG
+#define RTE_LIBRTE_CFGFILE 1
+#define RTE_LIBRTE_CMDLINE 1
+#undef RTE_LIBRTE_CMDLINE_DEBUG
+#define RTE_LIBRTE_HASH 1
+#undef RTE_LIBRTE_HASH_DEBUG
+#undef RTE_LIBRTE_EFD
+#undef RTE_LIBRTE_MEMBER
+#define RTE_LIBRTE_JOBSTATS 1
+#define RTE_LIBRTE_METRICS 1
+#define RTE_LIBRTE_BITRATE 1
+#define RTE_LIBRTE_LATENCY_STATS 1
+#define RTE_LIBRTE_LPM 1
+#undef RTE_LIBRTE_LPM_DEBUG
+#define RTE_LIBRTE_ACL 1
+#undef RTE_LIBRTE_ACL_DEBUG
+#undef RTE_LIBRTE_POWER
+#undef RTE_LIBRTE_POWER_DEBUG
+#define RTE_MAX_LCORE_FREQS 64
+#define RTE_LIBRTE_NET 1
+#define RTE_LIBRTE_IP_FRAG 1
+#undef CONFIG_RTE_LIBRTE_IP_FRAG_DEBUG
+#define RTE_LIBRTE_IP_FRAG_MAX_FRAG 4
+#undef RTE_LIBRTE_IP_FRAG_TBL_STAT
+#define RTE_LIBRTE_GRO 1
+#define RTE_LIBRTE_GSO 1
+#define RTE_LIBRTE_METER 1
+#define RTE_LIBRTE_FLOW_CLASSIFY 1
+#define RTE_LIBRTE_SCHED 1
+#undef CONFIG_RTE_SCHED_DEBUG
+#undef CONFIG_RTE_SCHED_RED
+#undef RTE_SCHED_COLLECT_STATS
+#undef RTE_SCHED_SUBPORT_TC_OV
+#define RTE_SCHED_PORT_N_GRINDERS 8
+#undef RTE_SCHED_VECTOR
+#define RTE_LIBRTE_DISTRIBUTOR 1
+#define RTE_LIBRTE_REORDER 1
+#define RTE_LIBRTE_PORT 1
+#undef RTE_PORT_STATS_COLLECT
+#undef RTE_PORT_PCAP
+#define RTE_LIBRTE_TABLE 1
+#undef RTE_TABLE_STATS_COLLECT
+#define RTE_LIBRTE_PIPELINE 1
+#undef RTE_PIPELINE_STATS_COLLECT
+#undef RTE_LIBRTE_KNI
+#undef RTE_LIBRTE_PMD_KNI
+#undef RTE_KNI_KMOD
+#undef RTE_KNI_KMOD_ETHTOOL
+#undef RTE_KNI_PREEMPT_DEFAULT
+#undef RTE_LIBRTE_PDUMP
+#undef RTE_LIBRTE_VHOST
+#undef RTE_LIBRTE_VHOST_NUMA
+#undef RTE_LIBRTE_VHOST_DEBUG
+#undef RTE_LIBRTE_PMD_VHOST
+#define RTE_APP_TEST 1
+#undef RTE_APP_TEST_RESOURCE_TAR
+#define RTE_APP_CHKINCS 1
+#define RTE_TEST_PMD 1
+#undef RTE_TEST_PMD_RECORD_CORE_CYCLES
+#undef RTE_TEST_PMD_RECORD_BURST_STATS
+#define RTE_APP_CRYPTO_PERF 1
+#define RTE_APP_EVENTDEV 1
+#define RTE_EAL_PMD_PATH ""
+#define RTE_CACHE_LINE_SIZE 64
+#define RTE_CACHE_LINE_MIN_SIZE 64
diff --git a/lib/librte_eal/windows/rte_override/rte_cpuflags.h b/lib/librte_eal/windows/rte_override/rte_cpuflags.h
new file mode 100644
index 000000000..23accc85b
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_cpuflags.h
@@ -0,0 +1,3 @@
+#define RTE_COMPILE_TIME_CPUFLAGS RTE_CPUFLAG_SSE4_1
+
+#include "..\common\include\arch\x86\rte_cpuflags.h"
diff --git a/lib/librte_eal/windows/rte_override/rte_cycles.h b/lib/librte_eal/windows/rte_override/rte_cycles.h
new file mode 100644
index 000000000..98e4cc426
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_cycles.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#pragma once
+
+#include "..\..\common\include\generic\rte_cycles.h"
+
+static inline uint64_t
+rte_rdtsc(void)
+{
+	return (uint64_t) __rdtsc();
+}
+
+static inline uint64_t
+rte_rdtsc_precise(void)
+{
+	rte_mb();
+	return rte_rdtsc();
+}
+
+static inline uint64_t
+rte_get_tsc_cycles(void)
+{
+	return rte_rdtsc();
+}
diff --git a/lib/librte_eal/windows/rte_override/rte_debug.h b/lib/librte_eal/windows/rte_override/rte_debug.h
new file mode 100644
index 000000000..3469ff3d7
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_debug.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#pragma once
+
+/* If rte_common.h has already been included, then we will have issues */
+#ifdef _RTE_DEBUG_H_
+#error
+#endif
+
+#include <stdio.h>
+#include "../common/include/rte_debug.h"
+
+#undef rte_panic
+#define rte_panic(fmt, ...)	{ printf (fmt, ##__VA_ARGS__); while(1); }
+
+#undef RTE_VERIFY
+#define	RTE_VERIFY(exp)	do {											\
+	if (!(exp))                                                         \
+		rte_panic("line %d\tassert \"" #exp "\" failed\n", __LINE__);	\
+} while (0)
diff --git a/lib/librte_eal/windows/rte_override/rte_io.h b/lib/librte_eal/windows/rte_override/rte_io.h
new file mode 100644
index 000000000..d111c4239
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_io.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+
+#pragma once
+
+#include "..\..\common\include\generic\rte_io.h"
diff --git a/lib/librte_eal/windows/rte_override/rte_lcore.h b/lib/librte_eal/windows/rte_override/rte_lcore.h
new file mode 100644
index 000000000..d2a2788c8
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_lcore.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#ifndef _RTE_WIN_LCORE_H_
+#define _RTE_WIN_LCORE_H_
+
+/* DPDK 1.8 */
+typedef	unsigned long rte_cpuset_t;
+
+/* Include the original rte_lcore.h from common */
+#include "../../common/include/rte_lcore.h"
+
+
+#endif
\ No newline at end of file
diff --git a/lib/librte_eal/windows/rte_override/rte_log.h.sav b/lib/librte_eal/windows/rte_override/rte_log.h.sav
new file mode 100644
index 000000000..e892a69ac
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_log.h.sav
@@ -0,0 +1,6 @@
+#pragma once
+
+#include "..\..\common\include\rte_log.h"
+
+#undef RTE_LOG
+#define RTE_LOG(l, t, ...)	printf (##__VA_ARGS__)
diff --git a/lib/librte_eal/windows/rte_override/rte_memcpy.h b/lib/librte_eal/windows/rte_override/rte_memcpy.h
new file mode 100644
index 000000000..6132df294
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_memcpy.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#define rte_memcpy(dest, src, n)	memcpy(dest, src,n)
diff --git a/lib/librte_eal/windows/rte_override/rte_memory.h b/lib/librte_eal/windows/rte_override/rte_memory.h
new file mode 100644
index 000000000..0df9dd822
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_memory.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#pragma once
+
+/* If rte_common.h has already been included, then we will have issues */
+#ifdef _RTE_MEMORY_H_
+#error
+#endif
+
+#ifdef DPDKWIN_NO_WARNINGS
+#pragma warning (disable : 66)	/*  warning #66: enumeration value is out of "int" range */
+#endif
+
+#include "../common/include/rte_memory.h"
+
+#ifdef DPDKWIN_NO_WARNINGS
+#pragma warning (enable : 66)
+#endif
diff --git a/lib/librte_eal/windows/rte_override/rte_pause.h b/lib/librte_eal/windows/rte_override/rte_pause.h
new file mode 100644
index 000000000..a8fa3bf51
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_pause.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#pragma once
+
+#include "..\..\common\include\generic\rte_pause.h"
+#if defined(RTE_ARCH_X86)
+#include "..\..\common\include\arch\x86\rte_pause.h"
+#endif
diff --git a/lib/librte_eal/windows/rte_override/rte_pci.h b/lib/librte_eal/windows/rte_override/rte_pci.h
new file mode 100644
index 000000000..fbf62b861
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_pci.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#pragma once
+
+#include "..\..\..\librte_pci\rte_pci.h"
diff --git a/lib/librte_eal/windows/rte_override/rte_per_lcore.h b/lib/librte_eal/windows/rte_override/rte_per_lcore.h
new file mode 100644
index 000000000..3dd629e68
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_per_lcore.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#pragma once
+
+#include "..\..\common\include\rte_per_lcore.h"
+
+/* Undefine the stuff that is problematic for windows and redefine */
+#undef RTE_DEFINE_PER_LCORE
+#undef RTE_DECLARE_PER_LCORE
+
+
+/**
+ * @file
+ * Per-lcore variables in RTE on windows environment
+ */
+
+/**
+ * Macro to define a per lcore variable "name" of type "type", don't
+ * use keywords like "static" or "volatile" in type, just prefix the
+ * whole macro.
+ */
+#define RTE_DEFINE_PER_LCORE(type, name)			__declspec(thread) type per_lcore_##name
+
+/**
+ * Macro to declare an extern per lcore variable "name" of type "type"
+ */
+#define RTE_DECLARE_PER_LCORE(type, name)			__declspec(thread) extern type per_lcore_##name
diff --git a/lib/librte_eal/windows/rte_override/rte_prefetch.h b/lib/librte_eal/windows/rte_override/rte_prefetch.h
new file mode 100644
index 000000000..c5a750715
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_prefetch.h
@@ -0,0 +1,29 @@
+#pragma once
+
+#ifdef DPDKWIN_NO_WARNINGS
+#pragma warning (disable : 2330)
+#endif
+
+static inline void rte_prefetch0(const volatile void *p)
+{
+	_mm_prefetch(p, _MM_HINT_T0);
+}
+
+static inline void rte_prefetch1(const volatile void *p)
+{
+	_mm_prefetch(p, _MM_HINT_T1);
+}
+
+static inline void rte_prefetch2(const volatile void *p)
+{
+	_mm_prefetch(p, _MM_HINT_T2);
+}
+
+static inline void rte_prefetch_non_temporal(const volatile void *p)
+{
+	_mm_prefetch(p, _MM_HINT_NTA);
+}
+
+#ifdef DPDKWIN_NO_WARNINGS
+#pragma warning (enable : 2330)
+#endif
diff --git a/lib/librte_eal/windows/rte_override/rte_rtm.h b/lib/librte_eal/windows/rte_override/rte_rtm.h
new file mode 100644
index 000000000..0313ca0b1
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_rtm.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+
+#pragma once
+
+#include "..\..\common\include\arch\x86\rte_rtm.h"
diff --git a/lib/librte_eal/windows/rte_override/rte_rwlock.h b/lib/librte_eal/windows/rte_override/rte_rwlock.h
new file mode 100644
index 000000000..1ea667d0c
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_rwlock.h
@@ -0,0 +1,40 @@
+
+
+#ifndef _RTE_RWLOCK_WIN_H_
+#define _RTE_RWLOCK_WIN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "generic/rte_rwlock.h"
+
+static inline void
+rte_rwlock_read_lock_tm(rte_rwlock_t *rwl)
+{
+	rte_rwlock_read_lock(rwl);
+}
+
+static inline void
+rte_rwlock_read_unlock_tm(rte_rwlock_t *rwl)
+{
+	rte_rwlock_read_unlock(rwl);
+}
+
+static inline void
+rte_rwlock_write_lock_tm(rte_rwlock_t *rwl)
+{
+	rte_rwlock_write_lock(rwl);
+}
+
+static inline void
+rte_rwlock_write_unlock_tm(rte_rwlock_t *rwl)
+{
+	rte_rwlock_write_unlock(rwl);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_RWLOCK_WIN_H_ */
\ No newline at end of file
diff --git a/lib/librte_eal/windows/rte_override/rte_spinlock.h b/lib/librte_eal/windows/rte_override/rte_spinlock.h
new file mode 100644
index 000000000..475a406e7
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_spinlock.h
@@ -0,0 +1,271 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+#pragma once
+
+#ifndef _RTE_SPINLOCK_H_
+#define _RTE_SPINLOCK_H_
+
+#include <rte_eal.h>
+#include <rte_pause.h>
+
+/**
+* The rte_spinlock_t type.
+*/
+typedef struct {
+	volatile long locked; /**< lock status 0 = unlocked, 1 = locked */
+} rte_spinlock_t;
+
+/**
+* A static spinlock initializer.
+*/
+#define RTE_SPINLOCK_INITIALIZER { 0 }
+
+/**
+* Initialize the spinlock to an unlocked state.
+*
+* @param sl
+*   A pointer to the spinlock.
+*/
+static inline void
+rte_spinlock_init(rte_spinlock_t *sl)
+{
+	sl->locked = 0;
+}
+
+/**
+* Take the spinlock.
+*
+* @param sl
+*   A pointer to the spinlock.
+*/
+static inline void
+rte_spinlock_lock(rte_spinlock_t *sl)
+{
+	while (_InterlockedExchange(&sl->locked, 1))
+		while (sl->locked)
+			rte_pause();
+}
+
+/**
+* Release the spinlock.
+*
+* @param sl
+*   A pointer to the spinlock.
+*/
+static inline void
+rte_spinlock_unlock(rte_spinlock_t *sl)
+{
+	_InterlockedExchange(&sl->locked, 0);
+}
+
+/**
+* Try to take the lock.
+*
+* @param sl
+*   A pointer to the spinlock.
+* @return
+*   1 if the lock is successfully taken; 0 otherwise.
+*/
+static inline int
+rte_spinlock_trylock(rte_spinlock_t *sl)
+{
+	return _InterlockedExchange(&sl->locked, 1) == 0;
+}
+
+/**
+* Test if the lock is taken.
+*
+* @param sl
+*   A pointer to the spinlock.
+* @return
+*   1 if the lock is currently taken; 0 otherwise.
+*/
+static inline int rte_spinlock_is_locked(rte_spinlock_t *sl)
+{
+	return sl->locked;
+}
+
+/**
+* Test if hardware transactional memory (lock elision) is supported
+*
+* @return
+*   1 if the hardware transactional memory is supported; 0 otherwise.
+*/
+static inline int rte_tm_supported(void)
+{
+	return 0;
+}
+
+/**
+* Try to execute critical section in a hardware memory transaction,
+* if it fails or not available take the spinlock.
+*
+* NOTE: An attempt to perform a HW I/O operation inside a hardware memory
+* transaction always aborts the transaction since the CPU is not able to
+* roll-back should the transaction fail. Therefore, hardware transactional
+* locks are not advised to be used around rte_eth_rx_burst() and
+* rte_eth_tx_burst() calls.
+*
+* @param sl
+*   A pointer to the spinlock.
+*/
+static inline void
+rte_spinlock_lock_tm(rte_spinlock_t *sl);
+
+/**
+* Commit hardware memory transaction or release the spinlock if
+* the spinlock is used as a fall-back
+*
+* @param sl
+*   A pointer to the spinlock.
+*/
+static inline void
+rte_spinlock_unlock_tm(rte_spinlock_t *sl);
+
+/**
+* Try to execute critical section in a hardware memory transaction,
+* if it fails or not available try to take the lock.
+*
+* NOTE: An attempt to perform a HW I/O operation inside a hardware memory
+* transaction always aborts the transaction since the CPU is not able to
+* roll-back should the transaction fail. Therefore, hardware transactional
+* locks are not advised to be used around rte_eth_rx_burst() and
+* rte_eth_tx_burst() calls.
+*
+* @param sl
+*   A pointer to the spinlock.
+* @return
+*   1 if the hardware memory transaction is successfully started
+*   or lock is successfully taken; 0 otherwise.
+*/
+static inline int
+rte_spinlock_trylock_tm(rte_spinlock_t *sl);
+
+/**
+* The rte_spinlock_recursive_t type.
+*/
+typedef struct {
+	rte_spinlock_t sl; /**< the actual spinlock */
+	volatile int user; /**< core id using lock, -1 for unused */
+	volatile int count; /**< count of time this lock has been called */
+} rte_spinlock_recursive_t;
+
+/**
+* A static recursive spinlock initializer.
+*/
+#define RTE_SPINLOCK_RECURSIVE_INITIALIZER {RTE_SPINLOCK_INITIALIZER, -1, 0}
+
+/**
+* Initialize the recursive spinlock to an unlocked state.
+*
+* @param slr
+*   A pointer to the recursive spinlock.
+*/
+static inline void rte_spinlock_recursive_init(rte_spinlock_recursive_t *slr)
+{
+	rte_spinlock_init(&slr->sl);
+	slr->user = -1;
+	slr->count = 0;
+}
+
+/**
+* Take the recursive spinlock.
+*
+* @param slr
+*   A pointer to the recursive spinlock.
+*/
+static inline void rte_spinlock_recursive_lock(rte_spinlock_recursive_t *slr)
+{
+	int id = rte_gettid();
+
+	if (slr->user != id) {
+		rte_spinlock_lock(&slr->sl);
+		slr->user = id;
+	}
+	slr->count++;
+}
+/**
+* Release the recursive spinlock.
+*
+* @param slr
+*   A pointer to the recursive spinlock.
+*/
+static inline void rte_spinlock_recursive_unlock(rte_spinlock_recursive_t *slr)
+{
+	if (--(slr->count) == 0) {
+		slr->user = -1;
+		rte_spinlock_unlock(&slr->sl);
+	}
+
+}
+
+/**
+* Try to take the recursive lock.
+*
+* @param slr
+*   A pointer to the recursive spinlock.
+* @return
+*   1 if the lock is successfully taken; 0 otherwise.
+*/
+static inline int rte_spinlock_recursive_trylock(rte_spinlock_recursive_t *slr)
+{
+	int id = rte_gettid();
+
+	if (slr->user != id) {
+		if (rte_spinlock_trylock(&slr->sl) == 0)
+			return 0;
+		slr->user = id;
+	}
+	slr->count++;
+	return 1;
+}
+
+
+/**
+* Try to execute critical section in a hardware memory transaction,
+* if it fails or not available take the recursive spinlocks
+*
+* NOTE: An attempt to perform a HW I/O operation inside a hardware memory
+* transaction always aborts the transaction since the CPU is not able to
+* roll-back should the transaction fail. Therefore, hardware transactional
+* locks are not advised to be used around rte_eth_rx_burst() and
+* rte_eth_tx_burst() calls.
+*
+* @param slr
+*   A pointer to the recursive spinlock.
+*/
+static inline void rte_spinlock_recursive_lock_tm(
+	rte_spinlock_recursive_t *slr);
+
+/**
+* Commit hardware memory transaction or release the recursive spinlock
+* if the recursive spinlock is used as a fall-back
+*
+* @param slr
+*   A pointer to the recursive spinlock.
+*/
+static inline void rte_spinlock_recursive_unlock_tm(
+	rte_spinlock_recursive_t *slr);
+
+/**
+* Try to execute critical section in a hardware memory transaction,
+* if it fails or not available try to take the recursive lock
+*
+* NOTE: An attempt to perform a HW I/O operation inside a hardware memory
+* transaction always aborts the transaction since the CPU is not able to
+* roll-back should the transaction fail. Therefore, hardware transactional
+* locks are not advised to be used around rte_eth_rx_burst() and
+* rte_eth_tx_burst() calls.
+*
+* @param slr
+*   A pointer to the recursive spinlock.
+* @return
+*   1 if the hardware memory transaction is successfully started
+*   or lock is successfully taken; 0 otherwise.
+*/
+static inline int rte_spinlock_recursive_trylock_tm(
+	rte_spinlock_recursive_t *slr);
+
+#endif /* _RTE_SPINLOCK_H_ */
diff --git a/lib/librte_eal/windows/rte_override/rte_vect.h b/lib/librte_eal/windows/rte_override/rte_vect.h
new file mode 100644
index 000000000..f2530147d
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_vect.h
@@ -0,0 +1,5 @@
+#pragma once
+
+#define __ICC	1600
+
+#include "..\..\common\include\arch\x86\rte_vect.h"
diff --git a/lib/librte_eal/windows/rte_override/rte_wincompat.h b/lib/librte_eal/windows/rte_override/rte_wincompat.h
new file mode 100644
index 000000000..2dff9f279
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_wincompat.h
@@ -0,0 +1,347 @@
+﻿/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+
+#ifndef _RTE_WINCOMPAT_H_
+#define _RTE_WINCOMPAT_H_
+
+#if !defined _M_IX86 && !defined _M_X64
+#error Unsupported architecture
+#endif
+
+#include <stdint.h>
+
+/* Required for definition of read(), write() */
+#include <io.h>
+#include <intrin.h>
+
+/* limits.h replacement */
+#include <stdlib.h>
+#ifndef PATH_MAX
+#define PATH_MAX _MAX_PATH
+#endif
+
+
+#ifndef EDQUOT
+#define EDQUOT 0xFE
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Quick generic implemetation of popcount - all architectures */
+static __forceinline int __popcount(unsigned int x)
+{
+	static const unsigned int m1 = 0x55555555;
+	static const unsigned int m2 = 0x33333333;
+	static const unsigned int m4 = 0x0f0f0f0f;
+	static const unsigned int h01 = 0x01010101;
+
+	x -= (x >> 1) & m1;
+	x = (x & m2) + ((x >> 2) & m2);
+	x = (x + (x >> 4)) & m4;
+	return (x * h01) >> 24;
+}
+
+static __forceinline int __builtin_popcountl(unsigned long x)
+{
+	return __popcount((unsigned int)x);
+}
+
+static __forceinline int __builtin_popcountll(unsigned long long x)
+{
+	static const unsigned long long m1 = 0x5555555555555555LL;
+	static const unsigned long long m2 = 0x3333333333333333LL;
+	static const unsigned long long m4 = 0x0f0f0f0f0f0f0f0fLL;
+	static const unsigned long long h01 = 0x0101010101010101LL;
+
+	x -= (x >> 1) & m1;
+	x = (x & m2) + ((x >> 2) & m2);
+	x = (x + (x >> 4)) & m4;
+	return (x * h01) >> 56;
+}
+
+static __forceinline int __builtin_popcount(unsigned int x)
+{
+	return __popcount(x);
+}
+
+// __builtin_ctz - count of trailing zeroes
+// _BitScanForward returns the bit number of first bit that is 1 starting from the LSB to MSB
+static __forceinline int __builtin_ctz(unsigned int x)
+{
+	unsigned long index = 0;
+
+	if (_BitScanForward(&index, x))
+		return index;
+
+	return 32;
+}
+
+// __builtin_ctzl - count of trailing zeroes for long
+static __forceinline int __builtin_ctzl(unsigned long x)
+{
+	return __builtin_ctz((unsigned int) x);
+}
+
+// __builtin_ctzll - count of trailing zeroes for long long (64 bits)
+static __forceinline int __builtin_ctzll(unsigned long long x)
+{
+	unsigned long index = 0;
+
+	if (_BitScanForward64(&index, x))
+		return (int) index;
+
+	return 64;
+}
+
+
+// __builtin_clz - count of leading zeroes
+// _BitScanReverse returns the bit number of first bit that is 1 starting from the MSB to LSB
+static __forceinline int __builtin_clz(unsigned int x)
+{
+	unsigned long index = 0;
+
+	if (_BitScanReverse(&index, x))
+		return ((sizeof(x) * CHAR_BIT) -1 - index);
+
+	return 32;
+}
+
+// __builtin_clzl - count of leading zeroes for long
+static __forceinline int __builtin_clzl(unsigned long x)
+{
+	return __builtin_clz((unsigned int) x);
+}
+
+// __builtin_clzll - count of leading zeroes for long long (64 bits)
+static __forceinline int __builtin_clzll(unsigned long long x)
+{
+	unsigned long index = 0;
+
+	if (_BitScanReverse64(&index, x))
+		return ((sizeof(x) * CHAR_BIT) - 1 - index);
+
+	return 64;
+}
+
+static __forceinline uint32_t __builtin_bswap32(uint32_t val)
+{
+	return (uint32_t)_byteswap_ulong((unsigned long)val);
+}
+
+static __forceinline uint64_t __builtin_bswap64(uint64_t val)
+{
+	return (uint64_t) _byteswap_uint64((unsigned long long)val);
+}
+
+typedef int useconds_t;
+static void usleep(useconds_t us)
+{
+	LARGE_INTEGER cntr, start, current;
+	useconds_t curr_time;
+
+	QueryPerformanceFrequency(&cntr);
+	QueryPerformanceCounter(&start);
+
+	do {
+		QueryPerformanceCounter(&current);
+
+		// Compute current time.
+		curr_time = ((current.QuadPart - start.QuadPart) / (float)cntr.QuadPart * 1000 * 1000);
+	} while (curr_time < us);
+
+}
+
+static inline int getuid (void)
+{
+	return 0;
+}
+
+#include <string.h>
+static inline char* strtok_r(char *str, const char *delim, char **nextp)
+{
+	char *ret;
+
+	if (str == NULL)
+		str = *nextp;
+
+	str += strspn(str, delim);
+	if (*str == '\0')
+		return NULL;
+
+	ret = str;
+	str += strcspn(str, delim);
+
+	if (*str)
+		*str++ = '\0';
+
+	*nextp = str;
+	return ret;
+}
+
+#define index(a, b)     strchr(a, b)
+#define rindex(a, b)    strrchr(a, b)
+
+#define pipe(i)         _pipe(i, 8192, _O_BINARY)
+
+#define siglongjmp(a, err)  /* NO-OP */
+
+#define strncasecmp(s1,s2,count)        _strnicmp(s1,s2,count)
+
+// Replacement with safe string functions
+#define strcpy(dest,src)                strcpy_s(dest,sizeof(dest),src)
+#define strncpy(dest,src,count)         strncpy_s(dest,sizeof(dest),src,count)
+#define strlcpy(dest,src,count)			strncpy_s(dest,sizeof(dest),src,count)
+#define strerror(errnum)                WinSafeStrError(errnum)
+#define strsep(str,sep)                 WinStrSep(str,sep)
+#define strdup(str)                     _strdup(str)
+#define strcat(dest,src)                strcat_s(dest,sizeof(dest),src)
+#define sscanf(source,pattern, ...)		sscanf_s(source,pattern, __VA_ARGS__)
+
+
+static inline char* WinSafeStrError(int errnum)
+{
+	static char buffer[256];
+
+	ZeroMemory(buffer, sizeof(buffer));
+	strerror_s(buffer, sizeof(buffer), errnum);
+	return buffer;
+}
+
+static inline char* WinStrSep(char** ppString, char* pSeparator)
+{
+	char *pStrStart = NULL;
+
+	if ((ppString != NULL) && (*ppString != NULL) && (**ppString != '\0')) {
+		pStrStart = *ppString;
+		char *pStr = pStrStart + strcspn(pStrStart, pSeparator);
+
+		if (pStr == NULL)
+			*ppString = NULL;
+		else {
+			*pStr = '\0';
+			*ppString = pStr + 1;
+		}
+	}
+
+	return pStrStart;
+}
+
+#define sleep(secs)                 Sleep((secs)*1000)   // Windows Sleep() requires milliseconds
+#define ftruncate(fd,len)			_chsize_s(fd,len)
+
+// CPU set function overrides
+#define CPU_ZERO(cpuset)                {*cpuset = 0;}
+#define CPU_SET(cpucore, cpuset)        { *cpuset |= (1 << cpucore); }
+#define CPU_ISSET(cpucore, cpuset)      ((*cpuset & (1 << cpucore)) ? 1 : 0)
+
+/* Winsock IP protocol Numbers (not available on Windows) */
+#define IPPROTO_NONE	59       /* No next header for IPv6 */
+#define IPPROTO_SCTP	132      /* Stream Control Transmission Protocol */
+
+/* signal definitions - defined in signal.h */
+#define SIGUSR1		30
+#define SIGUSR2		31
+
+/* Definitions for access() */
+#define F_OK	0	/* Check for existence */
+#define W_OK	2	/* Write permission */
+#define R_OK	4	/* Read permission */
+#define X_OK	8	/* DO NOT USE */
+
+#ifndef AF_INET6
+#define AF_INET6	28
+#endif
+
+/* stdlib extensions that aren't defined in windows */
+int setenv(const char *name, const char *value, int overwrite);
+
+// Returns a handle to an mutex object that is created only once
+static inline HANDLE OpenMutexHandleAsync(INIT_ONCE *g_InitOnce)
+{
+	PVOID  lpContext;
+	BOOL   fStatus;
+	BOOL   fPending;
+	HANDLE hMutex;
+
+	// Begin one-time initialization
+	fStatus = InitOnceBeginInitialize(g_InitOnce,       // Pointer to one-time initialization structure
+		INIT_ONCE_ASYNC,   // Asynchronous one-time initialization
+		&fPending,         // Receives initialization status
+		&lpContext);       // Receives pointer to data in g_InitOnce
+
+						   // InitOnceBeginInitialize function failed.
+	if (!fStatus)
+	{
+		return (INVALID_HANDLE_VALUE);
+	}
+
+	// Initialization has already completed and lpContext contains mutex object.
+	if (!fPending)
+	{
+		return (HANDLE)lpContext;
+	}
+
+	// Create Mutex object for one-time initialization.
+	hMutex = CreateMutex(NULL,    // Default security descriptor
+		FALSE,    // Manual-reset mutex object
+		NULL);   // Object is unnamed
+
+				 // mutex object creation failed.
+	if (NULL == hMutex)
+	{
+		return (INVALID_HANDLE_VALUE);
+	}
+
+	// Complete one-time initialization.
+	fStatus = InitOnceComplete(g_InitOnce,             // Pointer to one-time initialization structure
+		INIT_ONCE_ASYNC,         // Asynchronous initialization
+		(PVOID)hMutex);          // Pointer to mutex object to be stored in g_InitOnce
+
+								 // InitOnceComplete function succeeded. Return mutex object.
+	if (fStatus)
+	{
+		return hMutex;
+	}
+
+	// Initialization has already completed. Free the local mutex.
+	CloseHandle(hMutex);
+
+
+	// Retrieve the final context data.
+	fStatus = InitOnceBeginInitialize(g_InitOnce,            // Pointer to one-time initialization structure
+		INIT_ONCE_CHECK_ONLY,   // Check whether initialization is complete
+		&fPending,              // Receives initialization status
+		&lpContext);            // Receives pointer to mutex object in g_InitOnce
+
+								// Initialization is complete. Return mutex.
+	if (fStatus && !fPending)
+	{
+		return (HANDLE)lpContext;
+	}
+	else
+	{
+		return INVALID_HANDLE_VALUE;
+	}
+}
+
+/*
+ * Used to statically create and lock a mutex
+*/
+static inline HANDLE WinCreateAndLockStaticMutex(HANDLE mutex, INIT_ONCE *g_InitOnce) {
+	mutex = OpenMutexHandleAsync(g_InitOnce);
+	WaitForSingleObject(mutex, INFINITE);
+	return mutex;
+}
+
+//#include <rte_gcc_builtins.h>
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/librte_eal/windows/rte_override/rte_windows.h b/lib/librte_eal/windows/rte_override/rte_windows.h
new file mode 100644
index 000000000..8e7f5299a
--- /dev/null
+++ b/lib/librte_eal/windows/rte_override/rte_windows.h
@@ -0,0 +1,497 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+* Copyright(c) 2017-2018 Intel Corporation
+*/
+
+
+#pragma once
+
+#ifndef _RTE_WINDOWS_H_
+#define _RTE_WINDOWS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _MSC_VER
+#error
+#endif
+
+#ifndef _WINDOWS
+#define _WINDOWS
+#endif
+
+// If we define WIN32_LEAN_AND_MEAN, winsock isn't included by default. We can then include it in specific header files as we need later.
+#define WIN32_LEAN_AND_MEAN
+
+#include <windows.h>
+
+// This isn't a complete replacement for typeof in GCC. For example, it doesn't work in cases where you have typeof(x) _val = 0. However,
+// it does allow us to remove some of the windows specific changes that need to be put into a lot of files to allow compilation.
+#define typeof(x)	_Generic((x),			\
+	void *			: void *,		\
+	char			: char,			\
+	unsigned char		: unsigned char		\
+	char *			: char *,		\
+	unsigned char *		: unsigned char *,	\
+	short			: short,		\
+	unsigned short		: unsigned short,	\
+	short *			: short *,		\
+	unsigned short *	: unsigned short *,	\
+	int			: int,			\
+	int *			: int *,		\
+	unsigned int		: unsigned int		\
+	unsigned int *		: unsigned int *,	\
+	long 			: long,			\
+	long *			: long *,		\
+	unsigned long		: unsigned long,	\
+	unsigned long *		: unsigned long *,	\
+	long long		: long long,		\
+	unsigned long long	: unsigned long long,	\
+	unsigned long long *	: unsigned long long *, \
+	default			: void			\
+)
+
+/*
+* Globally driven over-rides.
+*/
+#define __attribute__(x)
+
+#define __func__ __FUNCTION__
+
+#define NORETURN __declspec(noreturn)
+#define ATTR_UNUSED
+#define __AVX__    1
+
+#define E_RTE_NO_TAILQ	(-1)
+
+/* Include this header here, so that we can re-define EAL_REGISTER_TAILQ */
+#include <rte_tailq.h>
+#ifdef EAL_REGISTER_TAILQ(t)
+#undef EAL_REGISTER_TAILQ(t)
+#endif
+
+/*
+* Definition for registering TAILQs
+* (This is a workaround for Windows in lieu of a constructor-like function)
+*/
+#define EAL_REGISTER_TAILQ(t) \
+void init_##t(void); \
+void init_##t(void) \
+{ \
+	if (rte_eal_tailq_register(&t) < 0) \
+		rte_panic("Cannot initialize tailq: %s\n", t.name); \
+}
+
+/* Include this header here, so that we can re-define RTE_REGISTER_BUS */
+#include <rte_bus.h>
+#ifdef RTE_REGISTER_BUS(nm, bus)
+#undef RTE_REGISTER_BUS(nm, bus)
+#endif
+
+/*
+* Definition for registering a bus
+* (This is a workaround for Windows in lieu of a constructor-like function)
+*/
+#define RTE_REGISTER_BUS(nm, bus) \
+void businitfn_ ##nm(void) \
+{\
+	(bus).name = RTE_STR(nm);\
+	rte_bus_register(&bus); \
+}
+
+
+/*
+* Global warnings control. Disable this to see warnings in the
+* include/rte_override files
+*/
+#define DPDKWIN_NO_WARNINGS
+
+#ifdef DPDKWIN_NO_WARNINGS
+#pragma warning (disable : 94)	/* warning #94: the size of an array must be greater than zero */
+#pragma warning (disable : 169)	/* warning #169: expected a declaration */
+#endif
+
+
+/*
+* These definitions are to force a specific version of the defined function.
+* For Windows, we'll always stick with the latest defined version.
+*/
+#define rte_lpm_create			rte_lpm_create_v1604
+#define rte_lpm_add			rte_lpm_add_v1604
+#define rte_lpm6_add			rte_lpm6_add_v1705
+#define rte_lpm6_lookup			rte_lpm6_lookup_v1705
+#define rte_lpm6_lookup_bulk_func	rte_lpm6_lookup_bulk_func_v1705
+#define rte_lpm6_is_rule_present	rte_lpm6_is_rule_present_v1705
+#define rte_lpm_find_existing		rte_lpm_find_existing_v1604
+
+#define rte_distributor_request_pkt	rte_distributor_request_pkt_v1705
+#define rte_distributor_poll_pkt	rte_distributor_poll_pkt_v1705
+#define rte_distributor_get_pkt		rte_distributor_get_pkt_v1705
+#define rte_distributor_return_pkt	rte_distributor_return_pkt_v1705
+#define rte_distributor_returned_pkts	rte_distributor_returned_pkts_v1705
+#define rte_distributor_clear_returns	rte_distributor_clear_returns_v1705
+#define rte_distributor_process		rte_distributor_process_v1705
+#define rte_distributor_flush		rte_distributor_flush_v1705
+#define rte_distributor_create		rte_distributor_create_v1705
+
+/*
+* Definitions and overrides for ethernet.h
+*/
+#define u_char uint8_t
+#define u_short uint16_t
+
+#define __packed
+
+#define __BEGIN_DECLS
+#define __END_DECLS
+
+/*
+* sys/_cdefs.h
+*/
+#define __extension__
+
+/*
+* sys/_iovec.h
+*/
+#define ssize_t size_t
+#define SSIZE_T_DECLARED
+#define _SSIZE_T_DECLARED
+#define _SIZE_T_DECLARED
+
+/*
+* Linux to BSD termios differences
+*/
+#define TCSANOW 0
+
+/* Support X86 architecture */
+#define RTE_ARCH_X86
+
+/*
+* We can safely remove __attribute__((__packed__)). We will replace it with all structures
+* being packed
+*/
+#pragma pack(1)
+
+#include <rte_wincompat.h>
+
+/* Include rte_common.h first to get this out of the way controlled */
+#include "./rte_common.h"
+
+
+#include <sys/types.h>
+/* rte_pci.h must be included before we define typeof() to be nothing */
+//#include "./rte_pci.h"
+
+
+#define __attribute__(x)
+
+#define RTE_FORCE_INTRINSICS
+
+#include "rte_config.h"
+
+#define RTE_CACHE_ALIGN		__declspec(align(RTE_CACHE_LINE_SIZE))
+#define RTE_CACHE_MIN_ALIGN	__declspec(align(RTE_CACHE_LINE_MIN_SIZE))
+
+/* The windows port does not currently support dymamic loading of libraries, so fail these calls */
+#define dlopen(lib, flag)   (0)
+#define dlerror()           ("Not supported!")
+
+/* Include time.h for struct timespec */
+#include <time.h>
+#ifndef _TIMESPEC_DEFINED
+#define _TIMESPEC_DEFINED
+#endif
+
+typedef jmp_buf sigjmp_buf;
+#define sigsetjmp(env, savemask) _setjmp((env))
+
+/* function prototypes for those used exclusively by Windows */
+void eal_create_cpu_map();
+
+#define uint uint32_t
+
+#define RTE_APP_TEST_RESOURCE_TAR 1
+
+#if 0
+/* rte_config.h defines all the libraries that we have to include. For all the libraries that are enabled,
+generate a comment that will include it */
+#ifdef _RTE_WIN_DPDK_APP
+
+#ifdef RTE_LIBRTE_EAL
+#pragma comment (lib, "librte_eal.lib")
+#endif
+#ifdef RTE_LIBRTE_PCI
+#pragma comment (lib, "librte_pci.lib")
+#endif
+#ifdef RTE_LIBRTE_ETHDEV
+#pragma comment (lib, "librte_ethdev.lib")
+#endif
+#ifdef RTE_LIBRTE_KVARGS
+#pragma comment (lib, "librte_kvargs.lib")
+#endif
+#ifdef RTE_LIBRTE_IEEE1588
+#pragma comment (lib, "librte_ieee1588.lib")
+#endif
+#ifdef RTE_LIBRTE_PCI_BUS
+#pragma comment (lib, "librte_bus_pci.lib")
+#endif
+#ifdef RTE_LIBRTE_EM_PMD || RTE_LIBRTE_IGB_PMD
+#pragma comment (lib, "librte_pmd_e1000.lib")
+#endif
+#ifdef RTE_LIBRTE_IXGBE_PMD
+#pragma comment (lib, "librte_pmd_ixgbe.lib")
+#endif
+#ifdef RTE_LIBRTE_I40E_PMD
+#pragma comment (lib, "librte_pmd_i40e.lib")
+#endif
+#ifdef RTE_LIBRTE_FM10K_PMD
+#pragma comment (lib, "librte_pmd_fm10k.lib")
+#endif
+#ifdef RTE_LIBRTE_MLX4_PMD
+#pragma comment (lib, "librte_pmd_mlx4.lib")
+#endif
+#ifdef RTE_LIBRTE_MLX5_PMD
+#pragma comment (lib, "librte_pmd_mlx5.lib")
+#endif
+#ifdef RTE_LIBRTE_BNX2X_PMD
+#pragma comment (lib, "librte_pmd_bnx2x.lib")
+#endif
+#ifdef RTE_LIBRTE_CXGBE_PMD
+#pragma comment (lib, "librte_pmd_cxgbe.lib")
+#endif
+#ifdef RTE_LIBRTE_ENIC_PMD
+#pragma comment (lib, "librte_pmd_enic.lib")
+#endif
+#ifdef RTE_LIBRTE_NFP_PMD
+#pragma comment (lib, "librte_pmd_nfp.lib")
+#endif
+#ifdef RTE_LIBRTE_SFC_EFX_PMD
+#pragma comment (lib, "librte_pmd_sfc_efx.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_SOFTNIC
+//#pragma comment (lib, "librte_pmd_softnic.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_SZEDATA2
+#pragma comment (lib, "librte_pmd_szedata2.lib")
+#endif
+#ifdef RTE_LIBRTE_THUNDERX_NICVF_PMD
+#pragma comment (lib, "librte_pmd_thunderx_nicvf.lib")
+#endif
+#ifdef RTE_LIBRTE_LIO_PMD
+#pragma comment (lib, "librte_pmd_lio.lib")
+#endif
+#ifdef RTE_LIBRTE_DPAA_BUS
+#pragma comment (lib, "librte_dpaa_bus.lib")
+#endif
+#ifdef RTE_LIBRTE_DPAA_PMD
+#pragma comment (lib, "librte_pmd_dpaa.lib")
+#endif
+#ifdef RTE_LIBRTE_OCTEONTX_PMD
+#pragma comment (lib, "librte_pmd_octeontx.lib")
+#endif
+#ifdef RTE_LIBRTE_FSLMC_BUS
+#pragma comment (lib, "librte_fslmc_bus.lib")
+#endif
+#ifdef RTE_LIBRTE_DPAA2_PMD
+#pragma comment (lib, "librte_pmd_dpaa2.lib")
+#endif
+#ifdef RTE_LIBRTE_VIRTIO_PMD
+#pragma comment (lib, "librte_pmd_virtio.lib")
+#endif
+#ifdef RTE_VIRTIO_USER
+#pragma comment (lib, "librte_virtio_user.lib")
+#endif
+#ifdef RTE_LIBRTE_VMXNET3_PMD
+#pragma comment (lib, "librte_pmd_vmxnet3.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_RING
+//#pragma comment (lib, "librte_pmd_ring.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_BOND
+#pragma comment (lib, "librte_pmd_bond.lib")
+#endif
+#ifdef RTE_LIBRTE_QEDE_PMD
+#pragma comment (lib, "librte_pmd_qede.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_AF_PACKET
+#pragma comment (lib, "librte_pmd_af_packet.lib")
+#endif
+#ifdef RTE_LIBRTE_ARK_PMD
+#pragma comment (lib, "librte_pmd_ark.lib")
+#endif
+#ifdef RTE_LIBRTE_AVP_PMD
+#pragma comment (lib, "librte_pmd_avp.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_TAP
+#pragma comment (lib, "librte_pmd_tap.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_NULL
+#pragma comment (lib, "librte_pmd_null.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_FAILSAFE
+#pragma comment (lib, "librte_pmd_failsafe.lib")
+#endif
+#ifdef RTE_LIBRTE_CRYPTODEV
+#pragma comment (lib, "librte_cryptodev.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_ARMV8_CRYPTO
+#pragma comment (lib, "librte_pmd_armv8_crypto.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_DPAA2_SEC
+#pragma comment (lib, "librte_pmd_dpaa2_sec.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_QAT
+#pragma comment (lib, "librte_pmd_qat.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_AESNI_MB
+#pragma comment (lib, "librte_pmd_aesni_mb.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_OPENSSL
+#pragma comment (lib, "librte_pmd_openssl.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_AESNI_GCM
+#pragma comment (lib, "librte_pmd_aesni_gcm.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_SNOW3G
+#pragma comment (lib, "librte_pmd_snow3g.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_KASUMI
+#pragma comment (lib, "librte_pmd_kasumi.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_ZUC
+#pragma comment (lib, "librte_pmd_zuc.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER
+#pragma comment (lib, "librte_pmd_crypto_scheduler.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_NULL_CRYPTO
+#pragma comment (lib, "librte_pmd_null_crypto.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_MRVL_CRYPTO
+#pragma comment (lib, "librte_pmd_mrvl_crypto.lib")
+#endif
+#ifdef RTE_LIBRTE_SECURITY
+#pragma comment (lib, "librte_security.lib")
+#endif
+#ifdef RTE_LIBRTE_EVENTDEV
+#pragma comment (lib, "librte_eventdev.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_SKELETON_EVENTDEV
+//#pragma comment (lib, "librte_pmd_skeleton_eventdev.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_SW_EVENTDEV
+//#pragma comment (lib, "librte_pmd_sw_eventdev.lib")
+#endif
+#ifdef RTE_LIBRTE_RING
+#pragma comment (lib, "librte_ring.lib")
+#endif
+#ifdef RTE_LIBRTE_MEMPOOL
+#pragma comment (lib, "librte_mempool.lib")
+#pragma comment (lib, "librte_mempool_ring.lib")
+#endif
+#ifdef RTE_LIBRTE_MBUF
+#pragma comment (lib, "librte_mbuf.lib")
+#endif
+#ifdef RTE_LIBRTE_TIMER
+#pragma comment (lib, "librte_timer.lib")
+#endif
+#ifdef RTE_LIBRTE_CFGFILE
+#pragma comment (lib, "librte_cfgfile.lib")
+#endif
+#ifdef RTE_LIBRTE_CMDLINE
+#pragma comment (lib, "librte_cmdline.lib")
+#endif
+#ifdef RTE_LIBRTE_HASH
+#pragma comment (lib, "librte_hash.lib")
+#endif
+#ifdef RTE_LIBRTE_EFD
+#pragma comment (lib, "librte_efd.lib")
+#endif
+#ifdef RTE_LIBRTE_EFD
+#pragma comment (lib, "librte_efd.lib")
+#endif
+#ifdef RTE_LIBRTE_MEMBER
+#pragma comment (lib, "librte_member.lib")
+#endif
+#ifdef RTE_LIBRTE_JOBSTATS
+//#pragma comment (lib, "librte_jobstats.lib")
+#endif
+#ifdef RTE_LIBRTE_METRICS
+#pragma comment (lib, "librte_metrics.lib")
+#endif
+#ifdef RTE_LIBRTE_BITRATE
+#pragma comment (lib, "librte_bitratestats.lib")
+#endif
+#ifdef RTE_LIBRTE_LATENCY_STATS
+#pragma comment (lib, "librte_latencystats.lib")
+#endif
+#ifdef RTE_LIBRTE_LPM
+#pragma comment (lib, "librte_lpm.lib")
+#endif
+#ifdef RTE_LIBRTE_ACL
+#pragma comment (lib, "librte_acl.lib")
+#endif
+#ifdef RTE_LIBRTE_POWER
+#pragma comment (lib, "librte_power.lib")
+#endif
+#ifdef RTE_LIBRTE_NET
+#pragma comment (lib, "librte_net.lib")
+#endif
+#ifdef RTE_LIBRTE_IP_FRAG
+#pragma comment (lib, "librte_ipfrag.lib")
+#endif
+#ifdef RTE_LIBRTE_GRO
+#pragma comment (lib, "librte_gro.lib")
+#endif
+#ifdef RTE_LIBRTE_GSO
+#pragma comment (lib, "librte_gso.lib")
+#endif
+#ifdef RTE_LIBRTE_METER
+#pragma comment (lib, "librte_meter.lib")
+#endif
+#ifdef RTE_LIBRTE_FLOW_CLASSIFY
+#pragma comment (lib, "librte_flowclassify.lib")
+#endif
+#ifdef RTE_LIBRTE_SCHED
+#pragma comment (lib, "librte_sched.lib")
+#endif
+#ifdef RTE_LIBRTE_DISTRIBUTOR
+#pragma comment (lib, "librte_distributor.lib")
+#endif
+#ifdef RTE_LIBRTE_REORDER
+#pragma comment (lib, "librte_reorder.lib")
+#endif
+#ifdef RTE_LIBRTE_PORT
+#pragma comment (lib, "librte_port.lib")
+#endif
+#ifdef RTE_LIBRTE_TABLE
+#pragma comment (lib, "librte_table.lib")
+#endif
+#ifdef RTE_LIBRTE_PIPELINE
+#pragma comment (lib, "librte_pipeline.lib")
+#endif
+#ifdef RTE_LIBRTE_KNI
+#pragma comment (lib, "librte_kni.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_KNI
+#pragma comment (lib, "librte_pmd_kni.lib")
+#endif
+#ifdef RTE_LIBRTE_PDUMP
+#pragma comment (lib, "librte_pdump.lib")
+#endif
+#ifdef RTE_LIBRTE_VHOST
+#pragma comment (lib, "librte_vhost.lib")
+#endif
+#ifdef RTE_LIBRTE_PMD_VHOST
+#pragma comment (lib, "librte_pmd_vhost.lib")
+#endif
+
+
+#endif /* _RTE_WIN_DPDK_APP */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_WINDOWS_H_ */
diff --git a/mk/exec-env/windows/DpdkRteLib.props b/mk/exec-env/windows/DpdkRteLib.props
new file mode 100644
index 000000000..076253937
--- /dev/null
+++ b/mk/exec-env/windows/DpdkRteLib.props
@@ -0,0 +1,46 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ImportGroup Label="PropertySheets" />
+  <PropertyGroup Label="UserMacros">
+    <RTE_SDK>$(SolutionDir)..\..\..</RTE_SDK>
+  </PropertyGroup>
+  <PropertyGroup>
+    <OutDir>$(RTE_SDK)\$(Platform)\$(Configuration)\$(MSBuildProjectName)\</OutDir>
+    <IntDir>$(RTE_SDK)\mk\exec-env\windows\$(Platform)\$(Configuration)\$(MSBuildProjectName)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Label="Globals">
+    <WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
+  </PropertyGroup>
+  <ItemDefinitionGroup>
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup>
+    <ClCompile>
+      <PrecompiledHeaderFile />
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup>
+    <ClCompile>
+      <PrecompiledHeaderOutputFile />
+      <AdditionalIncludeDirectories>$(RTE_SDK)\lib\librte_eal\windows\include_override;$(RTE_SDK)\lib\librte_eal\windows\rte_override;$(RTE_SDK)\lib\librte_eal\common;$(RTE_SDK)\lib\librte_eal\common\include;$(RTE_SDK)\lib\librte_acl;$(RTE_SDK)\lib\librte_cmdline;$(RTE_SDK)\lib\librte_distributor;$(RTE_SDK)\lib\librte_ethdev;$(RTE_SDK)\lib\librte_hash;$(RTE_SDK)\lib\librte_ip_frag;$(RTE_SDK)\lib\librte_kvargs;$(RTE_SDK)\lib\librte_lpm;$(RTE_SDK)\lib\librte_malloc;$(RTE_SDK)\lib\librte_mempool;$(RTE_SDK)\lib\librte_mbuf;$(RTE_SDK)\lib\librte_meter;$(RTE_SDK)\lib\librte_net;$(RTE_SDK)\lib\librte_pipeline;$(RTE_SDK)\lib\librte_port;$(RTE_SDK)\lib\librte_reorder;$(RTE_SDK)\lib\librte_ring;$(RTE_SDK)\lib\librte_sched;$(RTE_SDK)\lib\librte_table;$(RTE_SDK)\lib\librte_timer;$(RTE_SDK)\lib\librte_vhost;$(RTE_SDK)\lib\librte_compat;$(RTE_SDK)\drivers\bus\pci;$(RTE_SDK)\lib\librte_security;$(RTE_SDK)\lib\librte_bitratestats;$(RTE_SDK)\lib\librte_metrics;$(RTE_SDK)\lib\librte_efd;$(RTE_SDK)\lib\librte_cryptodev;$(RTE_SDK)\lib\librte_flow_classify</AdditionalIncludeDirectories>
+      <ForcedIncludeFiles>$(RTE_SDK)\lib\librte_eal\windows\rte_override\rte_windows.h</ForcedIncludeFiles>
+      <CLanguageStandard>gnu11</CLanguageStandard>
+      <PrecompiledHeaderCompileAs>
+      </PrecompiledHeaderCompileAs>
+      <PrecompiledHeaderOutputFileDirectory />
+      <CompileAs>Default</CompileAs>
+      <C99Support>
+      </C99Support>
+      <StructMemberAlignment>1Byte</StructMemberAlignment>
+      <AdditionalOptions>/Qstd=c11 %(AdditionalOptions)</AdditionalOptions>
+      <WarningLevel>Level3</WarningLevel>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <BuildMacro Include="RTE_SDK">
+      <Value>$(RTE_SDK)</Value>
+    </BuildMacro>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/mk/exec-env/windows/dpdk.sln b/mk/exec-env/windows/dpdk.sln
new file mode 100644
index 000000000..8cbaa9e93
--- /dev/null
+++ b/mk/exec-env/windows/dpdk.sln
@@ -0,0 +1,43 @@
+﻿
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.27130.2010
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "librte_eal", "librte_eal\librte_eal.vcxproj", "{7380DC42-DE9A-4BA3-B153-FC0156DA20B7}"
+	ProjectSection(ProjectDependencies) = postProject
+		{F74A831C-CD22-4D19-BE6F-A318D0376EFA} = {F74A831C-CD22-4D19-BE6F-A318D0376EFA}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "librte_kvargs", "librte_kvargs\librte_kvargs.vcxproj", "{F74A831C-CD22-4D19-BE6F-A318D0376EFA}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "helloworld", "helloworld\helloworld.vcxproj", "{40B2A34F-A9EC-4420-8BD1-652883AA39E5}"
+	ProjectSection(ProjectDependencies) = postProject
+		{7380DC42-DE9A-4BA3-B153-FC0156DA20B7} = {7380DC42-DE9A-4BA3-B153-FC0156DA20B7}
+	EndProjectSection
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|x64 = Debug|x64
+		Release|x64 = Release|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{7380DC42-DE9A-4BA3-B153-FC0156DA20B7}.Debug|x64.ActiveCfg = Debug|x64
+		{7380DC42-DE9A-4BA3-B153-FC0156DA20B7}.Debug|x64.Build.0 = Debug|x64
+		{7380DC42-DE9A-4BA3-B153-FC0156DA20B7}.Release|x64.ActiveCfg = Release|x64
+		{7380DC42-DE9A-4BA3-B153-FC0156DA20B7}.Release|x64.Build.0 = Release|x64
+		{F74A831C-CD22-4D19-BE6F-A318D0376EFA}.Debug|x64.ActiveCfg = Debug|x64
+		{F74A831C-CD22-4D19-BE6F-A318D0376EFA}.Debug|x64.Build.0 = Debug|x64
+		{F74A831C-CD22-4D19-BE6F-A318D0376EFA}.Release|x64.ActiveCfg = Release|x64
+		{F74A831C-CD22-4D19-BE6F-A318D0376EFA}.Release|x64.Build.0 = Release|x64
+		{40B2A34F-A9EC-4420-8BD1-652883AA39E5}.Debug|x64.ActiveCfg = Debug|x64
+		{40B2A34F-A9EC-4420-8BD1-652883AA39E5}.Debug|x64.Build.0 = Debug|x64
+		{40B2A34F-A9EC-4420-8BD1-652883AA39E5}.Release|x64.ActiveCfg = Release|x64
+		{40B2A34F-A9EC-4420-8BD1-652883AA39E5}.Release|x64.Build.0 = Release|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {6CB597CF-1AD9-4A06-9C23-26B0EAEA3E63}
+	EndGlobalSection
+EndGlobal
diff --git a/mk/exec-env/windows/helloworld/helloworld.vcxproj b/mk/exec-env/windows/helloworld/helloworld.vcxproj
new file mode 100644
index 000000000..108d4b05b
--- /dev/null
+++ b/mk/exec-env/windows/helloworld/helloworld.vcxproj
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\examples\helloworld\main.c" />
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <VCProjectVersion>15.0</VCProjectVersion>
+    <ProjectGuid>{40B2A34F-A9EC-4420-8BD1-652883AA39E5}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>helloworld</RootNamespace>
+    <WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>Intel C++ Compiler 18.0</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>Intel C++ Compiler 18.0</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\DpdkRteLib.props" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\DpdkRteLib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeaderFile>
+      </PrecompiledHeaderFile>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>setupapi.lib;dbghelp.lib;$(RTE_SDK)\$(Platform)\$(Configuration)\librte_eal\librte_eal.lib;$(RTE_SDK)\$(Platform)\$(Configuration)\librte_kvargs\librte_kvargs.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <PrecompiledHeaderFile>
+      </PrecompiledHeaderFile>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>setupapi.lib;dbghelp.lib;$(RTE_SDK)\$(Platform)\$(Configuration)\librte_eal\librte_eal.lib;$(RTE_SDK)\$(Platform)\$(Configuration)\librte_kvargs\librte_kvargs.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/mk/exec-env/windows/helloworld/helloworld.vcxproj.filters b/mk/exec-env/windows/helloworld/helloworld.vcxproj.filters
new file mode 100644
index 000000000..cf332900f
--- /dev/null
+++ b/mk/exec-env/windows/helloworld/helloworld.vcxproj.filters
@@ -0,0 +1,22 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\examples\helloworld\main.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/mk/exec-env/windows/helloworld/helloworld.vcxproj.user b/mk/exec-env/windows/helloworld/helloworld.vcxproj.user
new file mode 100644
index 000000000..be2507870
--- /dev/null
+++ b/mk/exec-env/windows/helloworld/helloworld.vcxproj.user
@@ -0,0 +1,4 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup />
+</Project>
\ No newline at end of file
diff --git a/mk/exec-env/windows/librte_eal/librte_eal.vcxproj b/mk/exec-env/windows/librte_eal/librte_eal.vcxproj
new file mode 100644
index 000000000..5b456d351
--- /dev/null
+++ b/mk/exec-env/windows/librte_eal/librte_eal.vcxproj
@@ -0,0 +1,187 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{7380DC42-DE9A-4BA3-B153-FC0156DA20B7}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>librte_eal</RootNamespace>
+    <WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>Intel C++ Compiler 18.0</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>Intel C++ Compiler 18.0</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="..\DpdkRteLib.props" />
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="..\DpdkRteLib.props" />
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <OutDir>$(RTE_SDK)\$(Platform)\$(Configuration)\$(MSBuildProjectName)\</OutDir>
+    <IntDir>$(RTE_SDK)\mk\exec-env\windows\$(Platform)\$(Configuration)\$(MSBuildProjectName)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <OutDir>$(RTE_SDK)\$(Platform)\$(Configuration)\$(MSBuildProjectName)\</OutDir>
+    <IntDir>$(RTE_SDK)\mk\exec-env\windows\$(Platform)\$(Configuration)\$(MSBuildProjectName)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>C:\winddk\MSVS2015_SDK_WDK_Windows10_14393\Program Files\Microsoft Visual Studio 14.0\VC\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <UndefinePreprocessorDefinitions>__ICL</UndefinePreprocessorDefinitions>
+      <StructMemberAlignment>1Byte</StructMemberAlignment>
+      <CCppSupport>C99Support</CCppSupport>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>C:\winddk\MSVS2015_SDK_WDK_Windows10_14393\Program Files\Microsoft Visual Studio 14.0\VC\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <StructMemberAlignment>1Byte</StructMemberAlignment>
+      <CCppSupport>C99Support</CCppSupport>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_bus.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_class.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_cpuflags.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_dev.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_devargs.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_errno.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_hexdump.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_hypervisor.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_launch.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_lcore.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_memalloc.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_memory.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_memzone.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_options.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_string_fns.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_tailqs.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_thread.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_timer.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\malloc_elem.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\rte_keepalive.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\rte_malloc.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\rte_reciprocal.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_alarm.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_debug.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_fbarray.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_hugepage_info.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_interrupts.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_lcore.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_log.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_memalloc.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_memory.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_thread.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_timer.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\fork.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\getopt.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\lrand48.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\mman.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\setenv.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\srand48.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\termios.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\unistd.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\_rand48.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\malloc_heap.c" />
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\malloc_mp.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\eal_internal_cfg.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\eal_memalloc.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\eal_options.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\eal_private.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\eal_thread.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\generic\rte_cycles.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\generic\rte_rwlock.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_bus.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_common.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_debug.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_dev.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_eal.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_eal_memconfig.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_interrupts.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_launch.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_lcore.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_log.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_malloc_heap.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_memory.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_memzone.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_pci.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_pci_dev_feature_defs.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_per_lcore.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_random.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_string_fns.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_tailq.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_version.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\malloc_elem.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\malloc_heap.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\malloc_mp.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\eal\eal_filesystem.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\eal\eal_pci_private.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\include_override\rand48.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\include_override\unistd.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_atomic.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_common.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_cycles.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_debug.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_lcore.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_memory.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_pci.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_per_lcore.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_spinlock.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_wincompat.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_windows.h" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/mk/exec-env/windows/librte_eal/librte_eal.vcxproj.filters b/mk/exec-env/windows/librte_eal/librte_eal.vcxproj.filters
new file mode 100644
index 000000000..589392cf5
--- /dev/null
+++ b/mk/exec-env/windows/librte_eal/librte_eal.vcxproj.filters
@@ -0,0 +1,297 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+    <Filter Include="Header Files\windows override">
+      <UniqueIdentifier>{ba45c4dc-83b8-4fb0-9cec-e2b175fa8db4}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\windows override">
+      <UniqueIdentifier>{4ab5055a-d124-48a7-8801-14bc9f281934}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_cpuflags.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_dev.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_devargs.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_errno.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_hexdump.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_launch.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_lcore.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_memory.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_memzone.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_options.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_string_fns.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_tailqs.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_thread.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_timer.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\malloc_elem.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\rte_malloc.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\_rand48.c">
+      <Filter>Source Files\windows override</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\getopt.c">
+      <Filter>Source Files\windows override</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\lrand48.c">
+      <Filter>Source Files\windows override</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\mman.c">
+      <Filter>Source Files\windows override</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\srand48.c">
+      <Filter>Source Files\windows override</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\unistd.c">
+      <Filter>Source Files\windows override</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_debug.c">
+      <Filter>Source Files\windows override</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_log.c">
+      <Filter>Source Files\windows override</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_alarm.c">
+      <Filter>Source Files\windows override</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_interrupts.c">
+      <Filter>Source Files\windows override</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_timer.c">
+      <Filter>Source Files\windows override</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_lcore.c">
+      <Filter>Source Files\windows override</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal.c">
+      <Filter>Source Files\windows override</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_thread.c">
+      <Filter>Source Files\windows override</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_memory.c">
+      <Filter>Source Files\windows override</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_hugepage_info.c">
+      <Filter>Source Files\windows override</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_bus.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\fork.c">
+      <Filter>Source Files\windows override</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\setenv.c">
+      <Filter>Source Files\windows override</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\linux-emu\termios.c">
+      <Filter>Source Files\windows override</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_hypervisor.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\rte_keepalive.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\rte_reciprocal.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_class.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_fbarray.c">
+      <Filter>Source Files\windows override</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\common\eal_common_memalloc.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\eal_memalloc.c">
+      <Filter>Source Files\windows override</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\malloc_mp.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\lib\librte_eal\windows\eal\malloc_heap.c">
+      <Filter>Source Files\windows override</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\eal_private.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\eal_thread.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\eal_internal_cfg.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\malloc_heap.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\eal_options.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_eal.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_pci_dev_feature_defs.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_string_fns.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_pci.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_lcore.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_memory.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_per_lcore.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_launch.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_interrupts.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\include_override\rand48.h">
+      <Filter>Header Files\windows override</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_pci.h">
+      <Filter>Header Files\windows override</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_per_lcore.h">
+      <Filter>Header Files\windows override</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_lcore.h">
+      <Filter>Header Files\windows override</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_memory.h">
+      <Filter>Header Files\windows override</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_common.h">
+      <Filter>Header Files\windows override</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_common.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_cycles.h">
+      <Filter>Header Files\windows override</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\generic\rte_cycles.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\eal\eal_filesystem.h">
+      <Filter>Header Files\windows override</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_windows.h">
+      <Filter>Header Files\windows override</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\include_override\unistd.h">
+      <Filter>Header Files\windows override</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_eal_memconfig.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_log.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_random.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_spinlock.h">
+      <Filter>Header Files\windows override</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\generic\rte_rwlock.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_malloc_heap.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_memzone.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_debug.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_debug.h">
+      <Filter>Header Files\windows override</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_atomic.h">
+      <Filter>Header Files\windows override</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\rte_override\rte_wincompat.h">
+      <Filter>Header Files\windows override</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\windows\eal\eal_pci_private.h">
+      <Filter>Header Files\windows override</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_dev.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_bus.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_tailq.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_version.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\eal_memalloc.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\malloc_mp.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\malloc_elem.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/mk/exec-env/windows/librte_eal/librte_eal.vcxproj.user b/mk/exec-env/windows/librte_eal/librte_eal.vcxproj.user
new file mode 100644
index 000000000..abe8dd896
--- /dev/null
+++ b/mk/exec-env/windows/librte_eal/librte_eal.vcxproj.user
@@ -0,0 +1,4 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup />
+</Project>
\ No newline at end of file
diff --git a/mk/exec-env/windows/librte_kvargs/librte_kvargs.vcxproj b/mk/exec-env/windows/librte_kvargs/librte_kvargs.vcxproj
new file mode 100644
index 000000000..afd216f2d
--- /dev/null
+++ b/mk/exec-env/windows/librte_kvargs/librte_kvargs.vcxproj
@@ -0,0 +1,91 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\lib\librte_kvargs\rte_kvargs.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_log.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_string_fns.h" />
+    <ClInclude Include="..\..\..\..\lib\librte_kvargs\rte_kvargs.h" />
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{F74A831C-CD22-4D19-BE6F-A318D0376EFA}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>librte_kvargs</RootNamespace>
+    <WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>Intel C++ Compiler 18.0</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>Intel C++ Compiler 18.0</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\DpdkRteLib.props" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\DpdkRteLib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup />
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <StructMemberAlignment>1Byte</StructMemberAlignment>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <StructMemberAlignment>1Byte</StructMemberAlignment>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/mk/exec-env/windows/librte_kvargs/librte_kvargs.vcxproj.filters b/mk/exec-env/windows/librte_kvargs/librte_kvargs.vcxproj.filters
new file mode 100644
index 000000000..ce48d6391
--- /dev/null
+++ b/mk/exec-env/windows/librte_kvargs/librte_kvargs.vcxproj.filters
@@ -0,0 +1,33 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\lib\librte_kvargs\rte_kvargs.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\..\lib\librte_kvargs\rte_kvargs.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_log.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\lib\librte_eal\common\include\rte_string_fns.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/mk/exec-env/windows/librte_kvargs/librte_kvargs.vcxproj.user b/mk/exec-env/windows/librte_kvargs/librte_kvargs.vcxproj.user
new file mode 100644
index 000000000..be2507870
--- /dev/null
+++ b/mk/exec-env/windows/librte_kvargs/librte_kvargs.vcxproj.user
@@ -0,0 +1,4 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup />
+</Project>
\ No newline at end of file
