helloworld: Windows DPDK sample application is compiled and built using eal and kvargs libraries in order to add windows support in the mainline repository.

Message ID 20181129050504.26996-1-pallavi.kadam@intel.com (mailing list archive)
State Changes Requested, archived
Delegated to: Thomas Monjalon
Headers
Series helloworld: Windows DPDK sample application is compiled and built using eal and kvargs libraries in order to add windows support in the mainline repository. |

Checks

Context Check Description
ci/checkpatch warning coding style issues
ci/Intel-compilation success Compilation OK
ci/mellanox-Performance-Testing success Performance Testing PASS
ci/intel-Performance-Testing success Performance Testing PASS

Commit Message

Kadam, Pallavi Nov. 29, 2018, 5:05 a.m. UTC
  Signed-off-by: Pallavi Kadam <pallavi.kadam@intel.com>
---
[RFC] This is a large patch that contains changes to build the HelloWorld
sample application on Windows. It also contains changes to build the
librte_eal and librte_kvargs libraries which are required to build the
sample application. To merge these changes, this patch will be split up
into multiple smaller patches and sent for review.

 lib/librte_eal/common/eal_common_errno.c      |    9 +
 lib/librte_eal/common/eal_common_log.c        |    2 +
 lib/librte_eal/common/eal_common_options.c    |    2 +
 lib/librte_eal/common/eal_common_timer.c      |    2 +
 .../common/include/arch/x86/rte_byteorder.h   |   14 +
 .../common/include/arch/x86/rte_rtm.h         |   22 +-
 lib/librte_eal/common/include/rte_common.h    |   11 +
 .../common/include/rte_malloc_heap.h          |    3 +
 lib/librte_eal/common/include/rte_random.h    |    4 +
 .../common/include/rte_string_fns.h           |    2 +
 lib/librte_eal/common/malloc_elem.h           |    3 +
 lib/librte_eal/common/malloc_heap.c           |    2 +
 lib/librte_eal/common/malloc_heap.h           |    4 +
 lib/librte_eal/windows/eal/eal.c              |  697 +++++++++
 lib/librte_eal/windows/eal/eal_alarm.c        |   29 +
 lib/librte_eal/windows/eal/eal_debug.c        |  102 ++
 lib/librte_eal/windows/eal/eal_fbarray.c      | 1273 +++++++++++++++++
 lib/librte_eal/windows/eal/eal_filesystem.h   |   97 ++
 .../windows/eal/eal_hugepage_info.c           |   20 +
 lib/librte_eal/windows/eal/eal_interrupts.c   |   90 ++
 lib/librte_eal/windows/eal/eal_lcore.c        |   83 ++
 lib/librte_eal/windows/eal/eal_log.c          |  415 ++++++
 lib/librte_eal/windows/eal/eal_memalloc.c     |  995 +++++++++++++
 lib/librte_eal/windows/eal/eal_memory.c       |  140 ++
 lib/librte_eal/windows/eal/eal_proc.c         | 1003 +++++++++++++
 lib/librte_eal/windows/eal/eal_thread.c       |  167 +++
 lib/librte_eal/windows/eal/eal_timer.c        |   40 +
 .../windows/eal/linux-emu/_rand48.c           |   46 +
 .../windows/eal/linux-emu/drand48.c           |   62 +
 lib/librte_eal/windows/eal/linux-emu/fork.c   |  111 ++
 lib/librte_eal/windows/eal/linux-emu/getopt.c |  407 ++++++
 .../windows/eal/linux-emu/lrand48.c           |   23 +
 lib/librte_eal/windows/eal/linux-emu/mman.c   |  179 +++
 lib/librte_eal/windows/eal/linux-emu/setenv.c |   26 +
 .../windows/eal/linux-emu/srand48.c           |   30 +
 .../windows/eal/linux-emu/termios.c           |   11 +
 lib/librte_eal/windows/eal/linux-emu/unistd.c |   21 +
 lib/librte_eal/windows/eal/malloc_heap.c      | 1068 ++++++++++++++
 lib/librte_eal/windows/eal/malloc_mp.c        |  645 +++++++++
 .../windows/include_override/dirent.h         |  950 ++++++++++++
 .../windows/include_override/getopt.h         |  252 ++++
 .../windows/include_override/net/ethernet.h   |  405 ++++++
 .../windows/include_override/netinet/in.h     |   48 +
 .../windows/include_override/netinet/tcp.h    |    4 +
 .../windows/include_override/pthread.h        |   65 +
 .../windows/include_override/rand48.h         |   32 +
 .../windows/include_override/sched.h          |   21 +
 .../windows/include_override/sys/_iovec.h     |   48 +
 .../include_override/sys/_sockaddr_storage.h  |   54 +
 .../windows/include_override/sys/_termios.h   |  222 +++
 .../windows/include_override/sys/_types.h     |  105 ++
 .../windows/include_override/sys/cdefs.h      |    3 +
 .../windows/include_override/sys/mman.h       |   63 +
 .../include_override/sys/netbsd/queue.h       |  846 +++++++++++
 .../windows/include_override/sys/queue.h      |   11 +
 .../windows/include_override/syslog.h         |  217 +++
 .../windows/include_override/termios.h        |    1 +
 .../windows/include_override/unistd.h         |   30 +
 .../windows/include_override/x86intrin.h      |    1 +
 .../rte_override/exec-env/rte_interrupts.h    |    3 +
 lib/librte_eal/windows/rte_override/rte_acl.h |    7 +
 .../windows/rte_override/rte_atomic.h         |  744 ++++++++++
 .../windows/rte_override/rte_bus_pci.h        |   25 +
 .../windows/rte_override/rte_byteorder.h      |   10 +
 .../windows/rte_override/rte_common.h         |   56 +
 .../windows/rte_override/rte_common.h.sav     |  372 +++++
 .../windows/rte_override/rte_config.h         |  328 +++++
 .../windows/rte_override/rte_cpuflags.h       |    3 +
 .../windows/rte_override/rte_cycles.h         |   26 +
 .../windows/rte_override/rte_debug.h          |   22 +
 lib/librte_eal/windows/rte_override/rte_io.h  |    8 +
 .../windows/rte_override/rte_lcore.h          |   15 +
 .../windows/rte_override/rte_log.h.sav        |    6 +
 .../windows/rte_override/rte_memcpy.h         |    3 +
 .../windows/rte_override/rte_memory.h         |   20 +
 .../windows/rte_override/rte_pause.h          |   10 +
 lib/librte_eal/windows/rte_override/rte_pci.h |    7 +
 .../windows/rte_override/rte_per_lcore.h      |   29 +
 .../windows/rte_override/rte_prefetch.h       |   29 +
 lib/librte_eal/windows/rte_override/rte_rtm.h |    8 +
 .../windows/rte_override/rte_rwlock.h         |   40 +
 .../windows/rte_override/rte_spinlock.h       |  271 ++++
 .../windows/rte_override/rte_vect.h           |    5 +
 .../windows/rte_override/rte_wincompat.h      |  347 +++++
 .../windows/rte_override/rte_windows.h        |  497 +++++++
 mk/exec-env/windows/DpdkRteLib.props          |   46 +
 mk/exec-env/windows/dpdk.sln                  |   43 +
 .../windows/helloworld/helloworld.vcxproj     |   98 ++
 .../helloworld/helloworld.vcxproj.filters     |   22 +
 .../helloworld/helloworld.vcxproj.user        |    4 +
 .../windows/librte_eal/librte_eal.vcxproj     |  187 +++
 .../librte_eal/librte_eal.vcxproj.filters     |  297 ++++
 .../librte_eal/librte_eal.vcxproj.user        |    4 +
 .../librte_kvargs/librte_kvargs.vcxproj       |   91 ++
 .../librte_kvargs.vcxproj.filters             |   33 +
 .../librte_kvargs/librte_kvargs.vcxproj.user  |    4 +
 96 files changed, 14955 insertions(+), 3 deletions(-)
 create mode 100644 lib/librte_eal/windows/eal/eal.c
 create mode 100644 lib/librte_eal/windows/eal/eal_alarm.c
 create mode 100644 lib/librte_eal/windows/eal/eal_debug.c
 create mode 100644 lib/librte_eal/windows/eal/eal_fbarray.c
 create mode 100644 lib/librte_eal/windows/eal/eal_filesystem.h
 create mode 100644 lib/librte_eal/windows/eal/eal_hugepage_info.c
 create mode 100644 lib/librte_eal/windows/eal/eal_interrupts.c
 create mode 100644 lib/librte_eal/windows/eal/eal_lcore.c
 create mode 100644 lib/librte_eal/windows/eal/eal_log.c
 create mode 100644 lib/librte_eal/windows/eal/eal_memalloc.c
 create mode 100644 lib/librte_eal/windows/eal/eal_memory.c
 create mode 100644 lib/librte_eal/windows/eal/eal_proc.c
 create mode 100644 lib/librte_eal/windows/eal/eal_thread.c
 create mode 100644 lib/librte_eal/windows/eal/eal_timer.c
 create mode 100644 lib/librte_eal/windows/eal/linux-emu/_rand48.c
 create mode 100644 lib/librte_eal/windows/eal/linux-emu/drand48.c
 create mode 100644 lib/librte_eal/windows/eal/linux-emu/fork.c
 create mode 100644 lib/librte_eal/windows/eal/linux-emu/getopt.c
 create mode 100644 lib/librte_eal/windows/eal/linux-emu/lrand48.c
 create mode 100644 lib/librte_eal/windows/eal/linux-emu/mman.c
 create mode 100644 lib/librte_eal/windows/eal/linux-emu/setenv.c
 create mode 100644 lib/librte_eal/windows/eal/linux-emu/srand48.c
 create mode 100644 lib/librte_eal/windows/eal/linux-emu/termios.c
 create mode 100644 lib/librte_eal/windows/eal/linux-emu/unistd.c
 create mode 100644 lib/librte_eal/windows/eal/malloc_heap.c
 create mode 100644 lib/librte_eal/windows/eal/malloc_mp.c
 create mode 100644 lib/librte_eal/windows/include_override/dirent.h
 create mode 100644 lib/librte_eal/windows/include_override/getopt.h
 create mode 100644 lib/librte_eal/windows/include_override/net/ethernet.h
 create mode 100644 lib/librte_eal/windows/include_override/netinet/in.h
 create mode 100644 lib/librte_eal/windows/include_override/netinet/tcp.h
 create mode 100644 lib/librte_eal/windows/include_override/pthread.h
 create mode 100644 lib/librte_eal/windows/include_override/rand48.h
 create mode 100644 lib/librte_eal/windows/include_override/sched.h
 create mode 100644 lib/librte_eal/windows/include_override/sys/_iovec.h
 create mode 100644 lib/librte_eal/windows/include_override/sys/_sockaddr_storage.h
 create mode 100644 lib/librte_eal/windows/include_override/sys/_termios.h
 create mode 100644 lib/librte_eal/windows/include_override/sys/_types.h
 create mode 100644 lib/librte_eal/windows/include_override/sys/cdefs.h
 create mode 100644 lib/librte_eal/windows/include_override/sys/mman.h
 create mode 100644 lib/librte_eal/windows/include_override/sys/netbsd/queue.h
 create mode 100644 lib/librte_eal/windows/include_override/sys/queue.h
 create mode 100644 lib/librte_eal/windows/include_override/syslog.h
 create mode 100644 lib/librte_eal/windows/include_override/termios.h
 create mode 100644 lib/librte_eal/windows/include_override/unistd.h
 create mode 100644 lib/librte_eal/windows/include_override/x86intrin.h
 create mode 100644 lib/librte_eal/windows/rte_override/exec-env/rte_interrupts.h
 create mode 100644 lib/librte_eal/windows/rte_override/rte_acl.h
 create mode 100644 lib/librte_eal/windows/rte_override/rte_atomic.h
 create mode 100644 lib/librte_eal/windows/rte_override/rte_bus_pci.h
 create mode 100644 lib/librte_eal/windows/rte_override/rte_byteorder.h
 create mode 100644 lib/librte_eal/windows/rte_override/rte_common.h
 create mode 100644 lib/librte_eal/windows/rte_override/rte_common.h.sav
 create mode 100644 lib/librte_eal/windows/rte_override/rte_config.h
 create mode 100644 lib/librte_eal/windows/rte_override/rte_cpuflags.h
 create mode 100644 lib/librte_eal/windows/rte_override/rte_cycles.h
 create mode 100644 lib/librte_eal/windows/rte_override/rte_debug.h
 create mode 100644 lib/librte_eal/windows/rte_override/rte_io.h
 create mode 100644 lib/librte_eal/windows/rte_override/rte_lcore.h
 create mode 100644 lib/librte_eal/windows/rte_override/rte_log.h.sav
 create mode 100644 lib/librte_eal/windows/rte_override/rte_memcpy.h
 create mode 100644 lib/librte_eal/windows/rte_override/rte_memory.h
 create mode 100644 lib/librte_eal/windows/rte_override/rte_pause.h
 create mode 100644 lib/librte_eal/windows/rte_override/rte_pci.h
 create mode 100644 lib/librte_eal/windows/rte_override/rte_per_lcore.h
 create mode 100644 lib/librte_eal/windows/rte_override/rte_prefetch.h
 create mode 100644 lib/librte_eal/windows/rte_override/rte_rtm.h
 create mode 100644 lib/librte_eal/windows/rte_override/rte_rwlock.h
 create mode 100644 lib/librte_eal/windows/rte_override/rte_spinlock.h
 create mode 100644 lib/librte_eal/windows/rte_override/rte_vect.h
 create mode 100644 lib/librte_eal/windows/rte_override/rte_wincompat.h
 create mode 100644 lib/librte_eal/windows/rte_override/rte_windows.h
 create mode 100644 mk/exec-env/windows/DpdkRteLib.props
 create mode 100644 mk/exec-env/windows/dpdk.sln
 create mode 100644 mk/exec-env/windows/helloworld/helloworld.vcxproj
 create mode 100644 mk/exec-env/windows/helloworld/helloworld.vcxproj.filters
 create mode 100644 mk/exec-env/windows/helloworld/helloworld.vcxproj.user
 create mode 100644 mk/exec-env/windows/librte_eal/librte_eal.vcxproj
 create mode 100644 mk/exec-env/windows/librte_eal/librte_eal.vcxproj.filters
 create mode 100644 mk/exec-env/windows/librte_eal/librte_eal.vcxproj.user
 create mode 100644 mk/exec-env/windows/librte_kvargs/librte_kvargs.vcxproj
 create mode 100644 mk/exec-env/windows/librte_kvargs/librte_kvargs.vcxproj.filters
 create mode 100644 mk/exec-env/windows/librte_kvargs/librte_kvargs.vcxproj.user
  

Comments

Stephen Hemminger Nov. 29, 2018, 6:15 p.m. UTC | #1
On Wed, 28 Nov 2018 21:05:04 -0800
Pallavi Kadam <pallavi.kadam@intel.com> wrote:

> +// 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

All this is Windows code, it would be best if the code style of the new code
matches the rest of the DPDK. The DPDK follows subset of Linux kernel style
standard. In that standard C++ style comments are not used.
  
Luca Boccassi Nov. 30, 2018, 4:04 p.m. UTC | #2
On Wed, 2018-11-28 at 21:05 -0800, Pallavi Kadam wrote:
> Signed-off-by: Pallavi Kadam <pallavi.kadam@intel.com>
> ---
> [RFC] This is a large patch that contains changes to build the
> HelloWorld
> sample application on Windows. It also contains changes to build the
> librte_eal and librte_kvargs libraries which are required to build
> the
> sample application. To merge these changes, this patch will be split
> up
> into multiple smaller patches and sent for review.
> 
>  lib/librte_eal/common/eal_common_errno.c      |    9 +
>  lib/librte_eal/common/eal_common_log.c        |    2 +
>  lib/librte_eal/common/eal_common_options.c    |    2 +
>  lib/librte_eal/common/eal_common_timer.c      |    2 +
>  .../common/include/arch/x86/rte_byteorder.h   |   14 +
>  .../common/include/arch/x86/rte_rtm.h         |   22 +-
>  lib/librte_eal/common/include/rte_common.h    |   11 +
>  .../common/include/rte_malloc_heap.h          |    3 +
>  lib/librte_eal/common/include/rte_random.h    |    4 +
>  .../common/include/rte_string_fns.h           |    2 +
>  lib/librte_eal/common/malloc_elem.h           |    3 +
>  lib/librte_eal/common/malloc_heap.c           |    2 +
>  lib/librte_eal/common/malloc_heap.h           |    4 +
>  lib/librte_eal/windows/eal/eal.c              |  697 +++++++++
>  lib/librte_eal/windows/eal/eal_alarm.c        |   29 +
>  lib/librte_eal/windows/eal/eal_debug.c        |  102 ++
>  lib/librte_eal/windows/eal/eal_fbarray.c      | 1273
> +++++++++++++++++
>  lib/librte_eal/windows/eal/eal_filesystem.h   |   97 ++
>  .../windows/eal/eal_hugepage_info.c           |   20 +
>  lib/librte_eal/windows/eal/eal_interrupts.c   |   90 ++
>  lib/librte_eal/windows/eal/eal_lcore.c        |   83 ++
>  lib/librte_eal/windows/eal/eal_log.c          |  415 ++++++
>  lib/librte_eal/windows/eal/eal_memalloc.c     |  995 +++++++++++++
>  lib/librte_eal/windows/eal/eal_memory.c       |  140 ++
>  lib/librte_eal/windows/eal/eal_proc.c         | 1003 +++++++++++++
>  lib/librte_eal/windows/eal/eal_thread.c       |  167 +++
>  lib/librte_eal/windows/eal/eal_timer.c        |   40 +
>  .../windows/eal/linux-emu/_rand48.c           |   46 +
>  .../windows/eal/linux-emu/drand48.c           |   62 +
>  lib/librte_eal/windows/eal/linux-emu/fork.c   |  111 ++
>  lib/librte_eal/windows/eal/linux-emu/getopt.c |  407 ++++++
>  .../windows/eal/linux-emu/lrand48.c           |   23 +
>  lib/librte_eal/windows/eal/linux-emu/mman.c   |  179 +++
>  lib/librte_eal/windows/eal/linux-emu/setenv.c |   26 +
>  .../windows/eal/linux-emu/srand48.c           |   30 +
>  .../windows/eal/linux-emu/termios.c           |   11 +
>  lib/librte_eal/windows/eal/linux-emu/unistd.c |   21 +
>  lib/librte_eal/windows/eal/malloc_heap.c      | 1068 ++++++++++++++
>  lib/librte_eal/windows/eal/malloc_mp.c        |  645 +++++++++
>  .../windows/include_override/dirent.h         |  950 ++++++++++++
>  .../windows/include_override/getopt.h         |  252 ++++
>  .../windows/include_override/net/ethernet.h   |  405 ++++++
>  .../windows/include_override/netinet/in.h     |   48 +
>  .../windows/include_override/netinet/tcp.h    |    4 +
>  .../windows/include_override/pthread.h        |   65 +
>  .../windows/include_override/rand48.h         |   32 +
>  .../windows/include_override/sched.h          |   21 +
>  .../windows/include_override/sys/_iovec.h     |   48 +
>  .../include_override/sys/_sockaddr_storage.h  |   54 +
>  .../windows/include_override/sys/_termios.h   |  222 +++
>  .../windows/include_override/sys/_types.h     |  105 ++
>  .../windows/include_override/sys/cdefs.h      |    3 +
>  .../windows/include_override/sys/mman.h       |   63 +
>  .../include_override/sys/netbsd/queue.h       |  846 +++++++++++
>  .../windows/include_override/sys/queue.h      |   11 +
>  .../windows/include_override/syslog.h         |  217 +++
>  .../windows/include_override/termios.h        |    1 +
>  .../windows/include_override/unistd.h         |   30 +
>  .../windows/include_override/x86intrin.h      |    1 +
>  .../rte_override/exec-env/rte_interrupts.h    |    3 +
>  lib/librte_eal/windows/rte_override/rte_acl.h |    7 +
>  .../windows/rte_override/rte_atomic.h         |  744 ++++++++++
>  .../windows/rte_override/rte_bus_pci.h        |   25 +
>  .../windows/rte_override/rte_byteorder.h      |   10 +
>  .../windows/rte_override/rte_common.h         |   56 +
>  .../windows/rte_override/rte_common.h.sav     |  372 +++++
>  .../windows/rte_override/rte_config.h         |  328 +++++
>  .../windows/rte_override/rte_cpuflags.h       |    3 +
>  .../windows/rte_override/rte_cycles.h         |   26 +
>  .../windows/rte_override/rte_debug.h          |   22 +
>  lib/librte_eal/windows/rte_override/rte_io.h  |    8 +
>  .../windows/rte_override/rte_lcore.h          |   15 +
>  .../windows/rte_override/rte_log.h.sav        |    6 +
>  .../windows/rte_override/rte_memcpy.h         |    3 +
>  .../windows/rte_override/rte_memory.h         |   20 +
>  .../windows/rte_override/rte_pause.h          |   10 +
>  lib/librte_eal/windows/rte_override/rte_pci.h |    7 +
>  .../windows/rte_override/rte_per_lcore.h      |   29 +
>  .../windows/rte_override/rte_prefetch.h       |   29 +
>  lib/librte_eal/windows/rte_override/rte_rtm.h |    8 +
>  .../windows/rte_override/rte_rwlock.h         |   40 +
>  .../windows/rte_override/rte_spinlock.h       |  271 ++++
>  .../windows/rte_override/rte_vect.h           |    5 +
>  .../windows/rte_override/rte_wincompat.h      |  347 +++++
>  .../windows/rte_override/rte_windows.h        |  497 +++++++
>  mk/exec-env/windows/DpdkRteLib.props          |   46 +
>  mk/exec-env/windows/dpdk.sln                  |   43 +
>  .../windows/helloworld/helloworld.vcxproj     |   98 ++
>  .../helloworld/helloworld.vcxproj.filters     |   22 +
>  .../helloworld/helloworld.vcxproj.user        |    4 +
>  .../windows/librte_eal/librte_eal.vcxproj     |  187 +++
>  .../librte_eal/librte_eal.vcxproj.filters     |  297 ++++
>  .../librte_eal/librte_eal.vcxproj.user        |    4 +
>  .../librte_kvargs/librte_kvargs.vcxproj       |   91 ++
>  .../librte_kvargs.vcxproj.filters             |   33 +
>  .../librte_kvargs/librte_kvargs.vcxproj.user  |    4 +
>  96 files changed, 14955 insertions(+), 3 deletions(-)

Hi,

In my (limited) experience managing cross-platform projects, having
manually defined Visual Studio files (*.vcxproj.*) manually checked in
git and maintained is always a pain. They invariably get out of sync
and rot, and they are massive and not very readable.

Given that we have now reasonably on-par support for Meson, which has
both a Visual Studio backend and a Ninja (which IIRC is supported by
VS) backend, wouldn't it be better to let the build be handled by Meson
itself? There might be a couple of places that needs fixing (we don't
always to the right thing of using join_path for directories for
example) but in the long run it would be much more maintainable IMHO.
Adding new libraries/PMDs would need to be done just once, etc etc.
  

Patch

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