diff --git a/dp-core/SConscript b/dp-core/SConscript index 0674ed41a..4d4605098 100644 --- a/dp-core/SConscript +++ b/dp-core/SConscript @@ -7,13 +7,6 @@ import platform Import('VRouterEnv') env = VRouterEnv.Clone() -if platform.system() == 'Windows': - env.Append(CPPDEFINES = '__KERNEL__') - env.Append(CPPPATH = [env['TOP_INCLUDE'], '../test/windows/kernel_impl/include']) - - # Treat warnings as errors - env.Append(CPPFLAGS = '/WX') - env.Library('dp_core', Glob('*.c')) if 'install' in COMMAND_LINE_TARGETS: diff --git a/test/windows/SConscript b/test/windows/SConscript index 972968c82..66f45d8dd 100644 --- a/test/windows/SConscript +++ b/test/windows/SConscript @@ -5,26 +5,23 @@ Import('VRouterEnv') env = VRouterEnv.Clone() -env.Append(CPPPATH = [env['TOP_INCLUDE'], 'kernel_impl/include']) -env.Append(CPPDEFINES = '__KERNEL__') +env.Append(CPPPATH = [env['TOP_INCLUDE'], 'include']) # Treat warnings as errors env.Append(CPPFLAGS = '/WX') env.Replace(LIBPATH = env['TOP_LIB']) -env.Append(LIBPATH = ['.', '../../windows', '../../dp-core', '../../sandesh']) - -vrouter_stubs = env.Object('vrouter_stubs.c') -env.StaticLibrary('kernel_stubs', ['kernel_impl/src/wdm.c', 'kernel_impl/src/ndis.c']) +env.Append(LIBPATH = ['.', '../../windows']) # vRouter code -env.Replace(LIBS = ['windows_vrouter', 'dp_core', 'dp_sandesh_c', 'kernel_stubs']) +env.Replace(LIBS = ['win_packet']) # 3rd party libs env.Append(LIBS = 'cmocka') -# OS libs -env.Append(LIBS = ['ws2_32.lib', 'ntdll.lib']) env.AppendENVPath('Path', Dir('#build/bin')) -example_test = env.UnitTest('example_test', ['test.c', 'fake_win_packet.c', vrouter_stubs]) -kernel_tests = env.TestSuite('kernel-tests', [example_test]) + +win_packet_clone_tests_src = ['test_win_packet_clone.c', 'fake_win_packet_raw.c'] +win_packet_clone_tests = env.UnitTest('win_packet_clone_tests', win_packet_clone_tests_src) + +kernel_tests = env.TestSuite('kernel-tests', [win_packet_clone_tests]) env.Requires(kernel_tests, '#build/bin/cmocka.dll') diff --git a/test/windows/fake_win_packet.c b/test/windows/fake_win_packet.c deleted file mode 100644 index 52b10aeae..000000000 --- a/test/windows/fake_win_packet.c +++ /dev/null @@ -1,18 +0,0 @@ -/* - * fake_win_packet.c -- test double for vRouter OS layer unit testing - * - * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved. - */ -#include "win_packet.h" - -struct _WIN_PACKET { - // TODO: Added temporarily, to fix unit test compilation - void *ptr; -}; - -// TODO: Added temporarily, to fix unit test compilation -PNET_BUFFER_LIST -WinPacketToNBL(PWIN_PACKET Packet) -{ - return Packet->ptr; -} diff --git a/test/windows/fake_win_packet_raw.c b/test/windows/fake_win_packet_raw.c new file mode 100644 index 000000000..73e1aef7a --- /dev/null +++ b/test/windows/fake_win_packet_raw.c @@ -0,0 +1,62 @@ +/* + * fake_win_packet_raw.c + * + * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved. + */ +#include "fake_win_packet.h" + +#include +#include +#include +#include + +struct _WIN_PACKET { + PWIN_PACKET Parent; + LONG ChildRefCount; +}; + +PWIN_PACKET +Fake_WinPacketAllocate() +{ + PWIN_PACKET packet = test_malloc(sizeof(*packet)); + assert(packet != NULL); + memset(packet, 0, sizeof(*packet)); + return packet; +} + +VOID +Fake_WinPacketFree(PWIN_PACKET Packet) +{ + test_free(Packet); +} + +PWIN_PACKET +WinPacketRawGetParentOf(PWIN_PACKET Packet) +{ + return Packet->Parent; +} + +VOID +WinPacketRawSetParentOf(PWIN_PACKET Packet, PWIN_PACKET Parent) +{ + Packet->Parent = Parent; +} + +LONG +WinPacketRawGetChildCountOf(PWIN_PACKET Packet) +{ + return Packet->ChildRefCount; +} + +VOID +WinPacketRawIncrementChildCountOf(PWIN_PACKET Packet) +{ + Packet->ChildRefCount++; +} + +static PWIN_PACKET +WinPacketRawAllocateClone_Impl(PWIN_PACKET Packet) +{ + return NULL; +} +PWIN_PACKET (*WinPacketRawAllocateClone)(PWIN_PACKET Packet) = WinPacketRawAllocateClone_Impl; diff --git a/test/windows/include/fake_win_packet.h b/test/windows/include/fake_win_packet.h new file mode 100644 index 000000000..f0abcc1b5 --- /dev/null +++ b/test/windows/include/fake_win_packet.h @@ -0,0 +1,14 @@ +/* + * fake_win_packet.h + * + * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved. + */ +#ifndef _FAKE_WIN_PACKET_H_ +#define _FAKE_WIN_PACKET_H_ + +#include "win_packet.h" + +PWIN_PACKET Fake_WinPacketAllocate(); +VOID Fake_WinPacketFree(PWIN_PACKET Packet); + +#endif // _FAKE_WIN_PACKET_H_ diff --git a/test/windows/include/ndis.h b/test/windows/include/ndis.h new file mode 100644 index 000000000..b549419a1 --- /dev/null +++ b/test/windows/include/ndis.h @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved. + */ +#ifndef _FAKE_NDIS_H_ +#define _FAKE_NDIS_H_ + +typedef struct _NET_BUFFER_LIST NET_BUFFER_LIST, *PNET_BUFFER_LIST; + +#endif // _FAKE_NDIS_H_ diff --git a/test/windows/kernel_impl/include/ndis.h b/test/windows/kernel_impl/include/ndis.h deleted file mode 100644 index 195dc467c..000000000 --- a/test/windows/kernel_impl/include/ndis.h +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved. - */ - -#pragma once - -#include -#include -#include - -#include "wdm.h" -#include "ntstrsafe.h" - -// fake types - -#define NDIS_STATUS_SUCCESS 0 -#define NDIS_STATUS_FAILURE 1 - -#define NDIS_PROTOCOL_ID_DEFAULT 0 -#define NDIS_OBJECT_TYPE_DEFAULT 0 -#define NDIS_DEFAULT_PORT_NUMBER 0 - -#define NDIS_OBJECT_TYPE_DEVICE_OBJECT_ATTRIBUTES 0 -#define NDIS_DEVICE_OBJECT_ATTRIBUTES_REVISION_1 0 -#define NDIS_SIZEOF_DEVICE_OBJECT_ATTRIBUTES_REVISION_1 0 -#define NDIS_OBJECT_TYPE_FILTER_DRIVER_CHARACTERISTICS 0 -#define NDIS_SIZEOF_FILTER_DRIVER_CHARACTERISTICS_REVISION_2 0 -#define NDIS_FILTER_CHARACTERISTICS_REVISION_2 0 -#define NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1 0 -#define NDIS_SIZEOF_NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1 0 - -#define NDIS_INIT_MUTEX(x) -#define NDIS_RELEASE_MUTEX(x) -#define NDIS_WAIT_FOR_MUTEX(x) -#define NET_BUFFER_LIST_FIRST_NB(x) NULL -#define NET_BUFFER_DATA_LENGTH(x) 0 -#define NET_BUFFER_LIST_SWITCH_FORWARDING_DETAIL(x) NULL - -typedef int NDIS_MUTEX; -typedef int NDIS_SWITCH_CONTEXT; -typedef int NDIS_EVENT; -typedef int NDIS_STATUS; -typedef int NDIS_PORT_NUMBER; -typedef int NDIS_SWITCH_PORT_ID; -typedef int NDIS_SWITCH_NIC_INDEX; - -typedef void *PNDIS_RW_LOCK_EX; -typedef void *PNDIS_SWITCH_NIC_ARRAY; -typedef void *PNDIS_FILTER_ATTACH_PARAMETERS; -typedef void *PNDIS_FILTER_PAUSE_PARAMETERS; -typedef void *PNDIS_FILTER_RESTART_PARAMETERS; -typedef void *PNDIS_OID_REQUEST; -typedef void *PNET_BUFFER; - -// real types - -#define NDIS_FILTER_MAJOR_VERSION 6 -#define NDIS_FILTER_MINOR_VERSION 4 - -#define NET_BUFFER_LIST_INFO(_NBL, _Id) ((_NBL)->NetBufferListInfo[(_Id)]) - -struct _NET_BUFFER_LIST; -typedef struct _NET_BUFFER_LIST *PNET_BUFFER_LIST; - -typedef enum _NDIS_NET_BUFFER_LIST_INFO { - TcpIpChecksumNetBufferListInfo, - TcpOffloadBytesTransferred = TcpIpChecksumNetBufferListInfo, - IPsecOffloadV1NetBufferListInfo, - IPsecOffloadV2NetBufferListInfo = IPsecOffloadV1NetBufferListInfo, - TcpLargeSendNetBufferListInfo, - TcpReceiveNoPush = TcpLargeSendNetBufferListInfo, - ClassificationHandleNetBufferListInfo, - Ieee8021QNetBufferListInfo, - NetBufferListCancelId, - MediaSpecificInformation, - NetBufferListFrameType, - NetBufferListProtocolId = NetBufferListFrameType, - NetBufferListHashValue, - NetBufferListHashInfo, - WfpNetBufferListInfo, - IPsecOffloadV2TunnelNetBufferListInfo, - IPsecOffloadV2HeaderNetBufferListInfo, - NetBufferListCorrelationId, - NetBufferListFilteringInfo, - MediaSpecificInformationEx, - NblOriginalInterfaceIfIndex, - NblReAuthWfpFlowContext = NblOriginalInterfaceIfIndex, - TcpReceiveBytesTransferred, - SwitchForwardingReserved, - SwitchForwardingDetail, - VirtualSubnetInfo, - IMReserved, - TcpRecvSegCoalesceInfo, - RscTcpTimestampDelta, - TcpSendOffloadsSupplementalNetBufferListInfo = RscTcpTimestampDelta, - MaxNetBufferListInfo -} NDIS_NET_BUFFER_LIST_INFO, *PNDIS_NET_BUFFER_LIST_INFO; - -typedef UNICODE_STRING NDIS_STRING, *PNDIS_STRING; -typedef PVOID NDIS_HANDLE, *PNDIS_HANDLE; - -typedef struct _NDIS_OBJECT_HEADER { - UCHAR Type; - UCHAR Revision; - USHORT Size; -} NDIS_OBJECT_HEADER, *PNDIS_OBJECT_HEADER; - -typedef struct _NDIS_DEVICE_OBJECT_ATTRIBUTES { - NDIS_OBJECT_HEADER Header; - PNDIS_STRING DeviceName; - PNDIS_STRING SymbolicName; - PDRIVER_DISPATCH *MajorFunctions; - ULONG ExtensionSize; - PCUNICODE_STRING DefaultSDDLString; - LPCGUID DeviceClassGuid; -} NDIS_DEVICE_OBJECT_ATTRIBUTES, *PNDIS_DEVICE_OBJECT_ATTRIBUTES; - -typedef void FILTER_SEND_NET_BUFFER_LISTS( - NDIS_HANDLE FilterModuleContext, - PNET_BUFFER_LIST NetBufferList, - NDIS_PORT_NUMBER PortNumber, - ULONG SendFlags -); - -typedef void FILTER_SEND_NET_BUFFER_LISTS_COMPLETE( - NDIS_HANDLE FilterModuleContext, - PNET_BUFFER_LIST NetBufferList, - ULONG SendCompleteFlags -); - -typedef NDIS_STATUS FILTER_ATTACH( - NDIS_HANDLE NdisFilterHandle, - NDIS_HANDLE FilterDriverContext, - PNDIS_FILTER_ATTACH_PARAMETERS AttachParameters -); - -typedef void FILTER_DETACH( - NDIS_HANDLE FilterModuleContext -); - -typedef NDIS_STATUS FILTER_RESTART( - NDIS_HANDLE FilterModuleContext, - PNDIS_FILTER_RESTART_PARAMETERS RestartParameters -); - -typedef NDIS_STATUS FILTER_PAUSE( - NDIS_HANDLE FilterModuleContext, - PNDIS_FILTER_PAUSE_PARAMETERS PauseParameters -); - -typedef void FILTER_SEND_NET_BUFFER_LISTS( - NDIS_HANDLE FilterModuleContext, - PNET_BUFFER_LIST NetBufferList, - NDIS_PORT_NUMBER PortNumber, - ULONG SendFlags -); - -typedef void FILTER_SEND_NET_BUFFER_LISTS_COMPLETE( - NDIS_HANDLE FilterModuleContext, - PNET_BUFFER_LIST NetBufferList, - ULONG SendCompleteFlags -); - -typedef NDIS_STATUS FILTER_OID_REQUEST( - NDIS_HANDLE FilterModuleContext, - PNDIS_OID_REQUEST OidRequest -); - -typedef void FILTER_OID_REQUEST_COMPLETE( - NDIS_HANDLE FilterModuleContext, - PNDIS_OID_REQUEST OidRequest, - NDIS_STATUS Status -); - -typedef void FILTER_CANCEL_OID_REQUEST( - NDIS_HANDLE FilterModuleContext, - PVOID RequestId -); - -typedef FILTER_ATTACH *FILTER_ATTACH_HANDLER; -typedef FILTER_DETACH *FILTER_DETACH_HANDLER; -typedef FILTER_RESTART *FILTER_RESTART_HANDLER; -typedef FILTER_PAUSE *FILTER_PAUSE_HANDLER; -typedef FILTER_SEND_NET_BUFFER_LISTS *FILTER_SEND_NET_BUFFER_LISTS_HANDLER; -typedef FILTER_SEND_NET_BUFFER_LISTS_COMPLETE *FILTER_SEND_NET_BUFFER_LISTS_COMPLETE_HANDLER; -typedef FILTER_OID_REQUEST *FILTER_OID_REQUEST_HANDLER; -typedef FILTER_OID_REQUEST_COMPLETE *FILTER_OID_REQUEST_COMPLETE_HANDLER; -typedef FILTER_CANCEL_OID_REQUEST *FILTER_CANCEL_OID_REQUEST_HANDLER; - -typedef struct _NDIS_FILTER_DRIVER_CHARACTERISTICS { - NDIS_OBJECT_HEADER Header; - UCHAR MajorNdisVersion; - UCHAR MinorNdisVersion; - UCHAR MajorDriverVersion; - UCHAR MinorDriverVersion; - ULONG Flags; - NDIS_STRING FriendlyName; - NDIS_STRING UniqueName; - NDIS_STRING ServiceName; -// SET_OPTIONS_HANDLER SetOptionsHandler; -// FILTER_SET_FILTER_MODULE_OPTIONS_HANDLER SetFilterModuleOptionsHandler; - FILTER_ATTACH_HANDLER AttachHandler; - FILTER_DETACH_HANDLER DetachHandler; - FILTER_RESTART_HANDLER RestartHandler; - FILTER_PAUSE_HANDLER PauseHandler; - FILTER_SEND_NET_BUFFER_LISTS_HANDLER SendNetBufferListsHandler; - FILTER_SEND_NET_BUFFER_LISTS_COMPLETE_HANDLER SendNetBufferListsCompleteHandler; -// FILTER_CANCEL_SEND_HANDLER CancelSendNetBufferListsHandler; -// FILTER_RECEIVE_NET_BUFFER_LISTS_HANDLER ReceiveNetBufferListsHandler; -// FILTER_RETURN_NET_BUFFER_LISTS_HANDLER ReturnNetBufferListsHandler; - FILTER_OID_REQUEST_HANDLER OidRequestHandler; - FILTER_OID_REQUEST_COMPLETE_HANDLER OidRequestCompleteHandler; - FILTER_CANCEL_OID_REQUEST_HANDLER CancelOidRequestHandler; -/* FILTER_DEVICE_PNP_EVENT_NOTIFY_HANDLER DevicePnPEventNotifyHandler; - FILTER_NET_PNP_EVENT_HANDLER NetPnPEventHandler; - FILTER_STATUS_HANDLER StatusHandler; -#if (NDIS_SUPPORT_NDIS61) - FILTER_DIRECT_OID_REQUEST_HANDLER DirectOidRequestHandler; - FILTER_DIRECT_OID_REQUEST_COMPLETE_HANDLER DirectOidRequestCompleteHandler; - FILTER_CANCEL_DIRECT_OID_REQUEST_HANDLER CancelDirectOidRequestHandler; -#endif -#if (NDIS_SUPPORT_NDIS680) - FILTER_SYNCHRONOUS_OID_REQUEST_HANDLER SynchronousOidRequestHandler; - FILTER_SYNCHRONOUS_OID_REQUEST_COMPLETE_HANDLER SynchronousOidRequestHandlerComplete; -#endif */ -} NDIS_FILTER_DRIVER_CHARACTERISTICS, *PNDIS_FILTER_DRIVER_CHARACTERISTICS; - -typedef struct _NET_BUFFER_LIST_POOL_PARAMETERS { - NDIS_OBJECT_HEADER Header; - UCHAR ProtocolId; - BOOLEAN fAllocateNetBuffer; - USHORT ContextSize; - ULONG PoolTag; - ULONG DataSize; -} NET_BUFFER_LIST_POOL_PARAMETERS, *PNET_BUFFER_LIST_POOL_PARAMETERS; - -typedef struct _NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO { - union { - struct { - ULONG IsIPv4 :1; - ULONG IsIPv6 :1; - ULONG TcpChecksum :1; - ULONG UdpChecksum :1; - ULONG IpHeaderChecksum :1; - ULONG Reserved :11; - ULONG TcpHeaderOffset :10; - } Transmit; - struct { - ULONG TcpChecksumFailed :1; - ULONG UdpChecksumFailed :1; - ULONG IpChecksumFailed :1; - ULONG TcpChecksumSucceeded :1; - ULONG UdpChecksumSucceeded :1; - ULONG IpChecksumSucceeded :1; - ULONG Loopback :1; - ULONG TcpChecksumValueInvalid :1; - ULONG IpChecksumValueInvalid :1; - } Receive; - PVOID Value; - }; -} NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO, *PNDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO; - -typedef struct _NET_BUFFER_LIST_CONTEXT { - struct NET_BUFFER_LIST_CONTEXT *Next; - USHORT Size; - USHORT Offset; - UCHAR ContextData[]; -} NET_BUFFER_LIST_CONTEXT, *PNET_BUFFER_LIST_CONTEXT; - -typedef struct _NET_BUFFER_LIST_DATA { - PNET_BUFFER_LIST Next; - PNET_BUFFER FirstNetBuffer; -} NET_BUFFER_LIST_DATA, *PNET_BUFFER_LIST_DATA; - -typedef union _NET_BUFFER_LIST_HEADER { - NET_BUFFER_LIST_DATA NetBufferListData; - SLIST_HEADER Link; -} NET_BUFFER_LIST_HEADER, *PNET_BUFFER_LIST_HEADER; - -typedef struct _NET_BUFFER_LIST { - NET_BUFFER_LIST_HEADER NetBufferListHeader; - PNET_BUFFER_LIST_CONTEXT Context; - PNET_BUFFER_LIST ParentNetBufferList; - NDIS_HANDLE NdisPoolHandle; - PVOID NdisReserved[2]; - PVOID ProtocolReserved[4]; - PVOID MiniportReserved[2]; - PVOID Scratch; - NDIS_HANDLE SourceHandle; - ULONG NblFlags; - LONG ChildRefCount; - ULONG Flags; - NDIS_STATUS Status; - PVOID NetBufferListInfo[MaxNetBufferListInfo]; -} NET_BUFFER_LIST, *PNET_BUFFER_LIST; - -typedef struct _NDIS_SWITCH_PORT_DESTINATION { - NDIS_SWITCH_PORT_ID PortId; - NDIS_SWITCH_NIC_INDEX NicIndex; - USHORT IsExcluded :1; - UINT32 PreserveVLAN :1; - UINT32 PreservePriority :1; - USHORT Reserved :13; -} NDIS_SWITCH_PORT_DESTINATION, *PNDIS_SWITCH_PORT_DESTINATION; - -typedef NDIS_STATUS NDIS_SWITCH_ADD_NET_BUFFER_LIST_DESTINATION( - NDIS_SWITCH_CONTEXT NdisSwitchContext, - PNET_BUFFER_LIST NetBufferList, - PNDIS_SWITCH_PORT_DESTINATION Destination -); - -typedef NDIS_SWITCH_ADD_NET_BUFFER_LIST_DESTINATION *NDIS_SWITCH_ADD_NET_BUFFER_LIST_DESTINATION_HANDLER; - -typedef union _NDIS_SWITCH_FORWARDING_DETAIL_NET_BUFFER_LIST_INFO { - UINT64 AsUINT64; - struct { - UINT32 NumAvailableDestinations :16; - UINT32 SourcePortId :16; - UINT32 SourceNicIndex :8; - UINT32 NativeForwardingRequired :1; - UINT32 Reserved1 :1; - UINT32 IsPacketDataSafe :1; - UINT32 SafePacketDataSize :12; - UINT32 Reserved2 :9; - }; -} NDIS_SWITCH_FORWARDING_DETAIL_NET_BUFFER_LIST_INFO, *PNDIS_SWITCH_FORWARDING_DETAIL_NET_BUFFER_LIST_INFO; - -typedef void NET_BUFFER_FREE_MDL_HANDLER( - PMDL Mdl -); - -PVOID NdisGetDataBuffer( - PNET_BUFFER NetBuffer, - ULONG BytesNeeded, - PVOID Storage, - UINT AlignMultiple, - UINT AlignOffset -); - -// fake types - -typedef struct _NDIS_SWITCH_OPTIONAL_HANDLERS { - NDIS_SWITCH_ADD_NET_BUFFER_LIST_DESTINATION_HANDLER AddNetBufferListDestination; -} NDIS_SWITCH_OPTIONAL_HANDLERS, *PNDIS_SWITCH_OPTIONAL_HANDLERS; diff --git a/test/windows/kernel_impl/include/ntddk.h b/test/windows/kernel_impl/include/ntddk.h deleted file mode 100644 index 555957b27..000000000 --- a/test/windows/kernel_impl/include/ntddk.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved. - */ - -#pragma once - -extern void mock_assert(const int result, const char* const expression, - const char * const file, const int line); - -#define ASSERT(expression) \ - mock_assert((int)(expression), #expression, __FILE__, __LINE__) -#define ASSERTMSG(_Msg, _Expr) ASSERT((_Expr) && (_Msg)) -#define assert ASSERT diff --git a/test/windows/kernel_impl/include/ntintsafe.h b/test/windows/kernel_impl/include/ntintsafe.h deleted file mode 100644 index 6fad57656..000000000 --- a/test/windows/kernel_impl/include/ntintsafe.h +++ /dev/null @@ -1,5 +0,0 @@ -/* - * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved. - */ - -#pragma once diff --git a/test/windows/kernel_impl/include/ntstrsafe.h b/test/windows/kernel_impl/include/ntstrsafe.h deleted file mode 100644 index c3a89a87b..000000000 --- a/test/windows/kernel_impl/include/ntstrsafe.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved. - */ - -#pragma once - -#include - -#define DECLARE_CONST_UNICODE_STRING(_var, _string) \ -const WCHAR _var ## _buffer[] = _string; \ -__pragma(warning(push)) \ -__pragma(warning(disable:4221)) __pragma(warning(disable:4204)) \ -const UNICODE_STRING _var = { sizeof(_string) - sizeof(WCHAR), sizeof(_string), (PWCH) _var ## _buffer } \ -__pragma(warning(pop)) - -typedef const UNICODE_STRING *PCUNICODE_STRING; diff --git a/test/windows/kernel_impl/include/wdm.h b/test/windows/kernel_impl/include/wdm.h deleted file mode 100644 index 79c407367..000000000 --- a/test/windows/kernel_impl/include/wdm.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved. - */ - -#pragma once - -#include - -#include "ntddk.h" -#include "ntstrsafe.h" - -// fake types - -#define DO_DIRECT_IO 0 -#define PAGE_SHIFT 0 - -enum { - IRP_MJ_CREATE, - IRP_MJ_CLEANUP, - IRP_MJ_CLOSE, - IRP_MJ_WRITE, - IRP_MJ_READ, - IRP_MJ_DEVICE_CONTROL, - IRP_MJ_MAXIMUM_FUNCTION, -}; - -typedef void *PMDL; -typedef void *PDRIVER_DISPATCH; -typedef void *PDRIVER_UNLOAD; - -typedef struct _DEVICE_OBJECT { - ULONG Flags; -} DEVICE_OBJECT, *PDEVICE_OBJECT; - -typedef struct _DRIVER_OBJECT { - PDRIVER_UNLOAD DriverUnload; -} DRIVER_OBJECT, *PDRIVER_OBJECT; - -// real types - -typedef enum _POOL_TYPE { - NonPagedPool, - NonPagedPoolExecute = NonPagedPool, - PagedPool, - NonPagedPoolMustSucceed = NonPagedPool + 2, - DontUseThisType, - NonPagedPoolCacheAligned = NonPagedPool + 4, - PagedPoolCacheAligned, - NonPagedPoolCacheAlignedMustS = NonPagedPool + 6, - MaxPoolType, - NonPagedPoolBase = 0, - NonPagedPoolBaseMustSucceed = NonPagedPoolBase + 2, - NonPagedPoolBaseCacheAligned = NonPagedPoolBase + 4, - NonPagedPoolBaseCacheAlignedMustS = NonPagedPoolBase + 6, - NonPagedPoolSession = 32, - PagedPoolSession = NonPagedPoolSession + 1, - NonPagedPoolMustSucceedSession = PagedPoolSession + 1, - DontUseThisTypeSession = NonPagedPoolMustSucceedSession + 1, - NonPagedPoolCacheAlignedSession = DontUseThisTypeSession + 1, - PagedPoolCacheAlignedSession = NonPagedPoolCacheAlignedSession + 1, - NonPagedPoolCacheAlignedMustSSession = PagedPoolCacheAlignedSession + 1, - NonPagedPoolNx = 512, - NonPagedPoolNxCacheAligned = NonPagedPoolNx + 4, - NonPagedPoolSessionNx = NonPagedPoolNx + 32 -} POOL_TYPE; - -typedef NTSTATUS DRIVER_INITIALIZE( - PDRIVER_OBJECT DriverObject, - PUNICODE_STRING RegistryPath -); - -typedef VOID DRIVER_UNLOAD( - DRIVER_OBJECT *DriverObject -); - -PVOID ExAllocatePoolWithTag(POOL_TYPE PoolType, SIZE_T NumberOfBytes, ULONG Tag); -VOID ExFreePool(PVOID P); -USHORT RtlUshortByteSwap(USHORT Source); -ULONG RtlUlongByteSwap(ULONG Source); diff --git a/test/windows/kernel_impl/include/wdmsec.h b/test/windows/kernel_impl/include/wdmsec.h deleted file mode 100644 index a1c86bf24..000000000 --- a/test/windows/kernel_impl/include/wdmsec.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved. - */ - -#pragma once - -#include "ntstrsafe.h" - -DECLARE_CONST_UNICODE_STRING( - SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RWX_RES_RWX, - L"D:P(A;;GA;;;SY)(A;;GRGWGX;;;BA)(A;;GRGWGX;;;WD)(A;;GRGWGX;;;RC)" -); diff --git a/test/windows/kernel_impl/src/ndis.c b/test/windows/kernel_impl/src/ndis.c deleted file mode 100644 index 744b59cce..000000000 --- a/test/windows/kernel_impl/src/ndis.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved. - */ - -#include - -VOID NdisAdvanceNetBufferListDataStart( - PNET_BUFFER_LIST NetBufferList, - ULONG DataOffsetDelta, - BOOLEAN FreeMdl, - NET_BUFFER_FREE_MDL_HANDLER FreeMdlHandler -) { - assert(0); -} - -PVOID NdisGetDataBuffer( - PNET_BUFFER NetBuffer, - ULONG BytesNeeded, - PVOID Storage, - UINT AlignMultiple, - UINT AlignOffset -) { - assert(0); - return NULL; -} - -VOID NdisFSendNetBufferLists( - NDIS_HANDLE NdisFilterHandle, - PNET_BUFFER_LIST NetBufferLists, - NDIS_PORT_NUMBER PortNumber, - ULONG SendFlags -) { - assert(0); -} diff --git a/test/windows/kernel_impl/src/wdm.c b/test/windows/kernel_impl/src/wdm.c deleted file mode 100644 index 180bd077d..000000000 --- a/test/windows/kernel_impl/src/wdm.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved. - */ - -#include -#include -#include - -PVOID ExAllocatePoolWithTag(POOL_TYPE PoolType, SIZE_T NumberOfBytes, ULONG Tag) { - return malloc(NumberOfBytes); -} - -VOID ExFreePool(PVOID P) { - free(P); -} - -USHORT RtlUshortByteSwap(USHORT Source) { - return ntohs(Source); -} - -ULONG RtlUlongByteSwap(ULONG Source) { - return ntohl(Source); -} diff --git a/test/windows/test.c b/test/windows/test.c deleted file mode 100644 index 528b5e248..000000000 --- a/test/windows/test.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved. - */ - -#include -#include -#include -#include - -static void test_example(void **state) { - struct vr_ip iph; - iph.ip_proto = VR_IP_PROTO_ICMP; - assert_true(vr_ip_proto_pull(&iph)); -} - -int main(void) { - const struct CMUnitTest tests[] = { - cmocka_unit_test(test_example), - }; - return cmocka_run_group_tests(tests, NULL, NULL); -} diff --git a/test/windows/test_win_packet_clone.c b/test/windows/test_win_packet_clone.c new file mode 100644 index 000000000..e6290d5fc --- /dev/null +++ b/test/windows/test_win_packet_clone.c @@ -0,0 +1,133 @@ +/* + * test_win_packet_clone.c + * + * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved. + */ +#include +#include +#include +#include +#include +#include + +#include "win_packet.h" +#include "fake_win_packet.h" + +static PWIN_PACKET (*Saved_WinPacketRawAllocateClone)(PWIN_PACKET Packet); + +static PWIN_PACKET +Fake_WinPacketRawAllocateClone_ReturnsNull(PWIN_PACKET Packet) +{ + return NULL; +} + +static PWIN_PACKET +Fake_WinPacketRawAllocateClone_ReturnsNewPacket(PWIN_PACKET Packet) +{ + return Fake_WinPacketAllocate(); +} + +int +Test_WinPacketClone_SetUp(void **state) +{ + Saved_WinPacketRawAllocateClone = WinPacketRawAllocateClone; + return 0; +} + +int +Test_WinPacketClone_TearDown(void **state) +{ + WinPacketRawAllocateClone = Saved_WinPacketRawAllocateClone; + return 0; +} + +void +Test_WinPacketClone_ReturnsNullWhenCloneFails(void **state) +{ + WinPacketRawAllocateClone = Fake_WinPacketRawAllocateClone_ReturnsNull; + + PWIN_PACKET packet = Fake_WinPacketAllocate(); + PWIN_PACKET cloned = WinPacketClone(packet); + + assert_null(cloned); + assert_int_equal(WinPacketRawGetChildCountOf(packet), 0); + + Fake_WinPacketFree(packet); +} + +void +Test_WinPacketClone_ReturnsPacketWhenCloneSucceeds(void **state) +{ + WinPacketRawAllocateClone = Fake_WinPacketRawAllocateClone_ReturnsNewPacket; + + PWIN_PACKET packet = Fake_WinPacketAllocate(); + PWIN_PACKET cloned = WinPacketClone(packet); + + assert_non_null(cloned); + assert_ptr_equal(WinPacketRawGetParentOf(cloned), packet); + assert_int_equal(WinPacketRawGetChildCountOf(packet), 1); + + Fake_WinPacketFree(cloned); + Fake_WinPacketFree(packet); +} + +void +Test_WinPacketClone_RefCountIsValidAfterMultipleClones(void **state) +{ + WinPacketRawAllocateClone = Fake_WinPacketRawAllocateClone_ReturnsNewPacket; + + PWIN_PACKET packet = Fake_WinPacketAllocate(); + + PWIN_PACKET cloned1 = WinPacketClone(packet); + PWIN_PACKET cloned2 = WinPacketClone(packet); + PWIN_PACKET cloned3 = WinPacketClone(packet); + + assert_ptr_equal(WinPacketRawGetParentOf(cloned1), packet); + assert_ptr_equal(WinPacketRawGetParentOf(cloned2), packet); + assert_ptr_equal(WinPacketRawGetParentOf(cloned3), packet); + + assert_int_equal(WinPacketRawGetChildCountOf(packet), 3); + assert_int_equal(WinPacketRawGetChildCountOf(cloned1), 0); + assert_int_equal(WinPacketRawGetChildCountOf(cloned2), 0); + assert_int_equal(WinPacketRawGetChildCountOf(cloned3), 0); + + Fake_WinPacketFree(cloned1); + Fake_WinPacketFree(cloned2); + Fake_WinPacketFree(cloned3); + Fake_WinPacketFree(packet); +} + +void +Test_WinPacketClone_RefCountIsValidAfterCloneOfClone(void **state) +{ + WinPacketRawAllocateClone = Fake_WinPacketRawAllocateClone_ReturnsNewPacket; + + PWIN_PACKET packet = Fake_WinPacketAllocate(); + + PWIN_PACKET cloned1 = WinPacketClone(packet); + PWIN_PACKET cloned2 = WinPacketClone(cloned1); + + assert_ptr_equal(WinPacketRawGetParentOf(cloned1), packet); + assert_ptr_equal(WinPacketRawGetParentOf(cloned2), cloned1); + + assert_int_equal(WinPacketRawGetChildCountOf(packet), 1); + assert_int_equal(WinPacketRawGetChildCountOf(cloned1), 1); + assert_int_equal(WinPacketRawGetChildCountOf(cloned2), 0); + + Fake_WinPacketFree(cloned2); + Fake_WinPacketFree(cloned1); + Fake_WinPacketFree(packet); +} + +#define WinPacketClone_UnitTest_(p, f) cmocka_unit_test_setup_teardown(p##f, p##SetUp, p##TearDown) +#define WinPacketClone_UnitTest(f) WinPacketClone_UnitTest_(Test_WinPacketClone_, f) + +int main(void) { + const struct CMUnitTest tests[] = { + WinPacketClone_UnitTest(ReturnsNullWhenCloneFails), + WinPacketClone_UnitTest(ReturnsPacketWhenCloneSucceeds), + WinPacketClone_UnitTest(RefCountIsValidAfterMultipleClones), + WinPacketClone_UnitTest(RefCountIsValidAfterCloneOfClone), + }; + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/test/windows/vrouter_stubs.c b/test/windows/vrouter_stubs.c deleted file mode 100644 index ed038d366..000000000 --- a/test/windows/vrouter_stubs.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved. - */ - -#include - -unsigned int vr_num_cpus = 1; -const ULONG VrAllocationTag = 'TSET'; -PSWITCH_OBJECT VrSwitchObject = NULL; - -void get_random_bytes(void *buf, int nbytes) { -} - -struct host_os * vrouter_get_host(void) { - return NULL; -} - -// Needed because we don't compile vr_nbl.c in tests yet. -void win_free_packet(struct vr_packet *pkt) { -} - -int pkt0_if_tx(struct vr_interface *vif, struct vr_packet *pkt) { - return 0; -} diff --git a/windows/SConscript b/windows/SConscript index 6518e6705..a2d0b4123 100644 --- a/windows/SConscript +++ b/windows/SConscript @@ -7,16 +7,14 @@ Import('VRouterEnv') env = VRouterEnv.Clone() -env.Append(CPPPATH = [env['TOP_INCLUDE'], '../test/windows/kernel_impl/include']) -env.Append(CPPDEFINES = '__KERNEL__') -env.Append(CPPDEFINES = 'CMOCKA_UNIT_TESTING') +env.Append(CPPPATH = [env['TOP_INCLUDE'], '../test/windows/include']) # Treat warnings as errors env.Append(CPPFLAGS = '/WX') # Files should be added when needed to this list sources = [ - 'vr_host_interface.c', + 'win_packet.c', ] -env.StaticLibrary('windows_vrouter', source = sources) +env.StaticLibrary('win_packet', source = sources) diff --git a/windows/vRouter.vcxproj b/windows/vRouter.vcxproj index b3fbcdf16..4cd2950f8 100644 --- a/windows/vRouter.vcxproj +++ b/windows/vRouter.vcxproj @@ -220,7 +220,9 @@ ndis.lib;ntstrsafe.lib;Wdmsec.lib;%(AdditionalDependencies) - + + /debug + @@ -514,7 +516,12 @@ NotUsing - + + NotUsing + + + NotUsing + diff --git a/windows/vRouter.vcxproj.filters b/windows/vRouter.vcxproj.filters index a70cde9b8..24cd34335 100644 --- a/windows/vRouter.vcxproj.filters +++ b/windows/vRouter.vcxproj.filters @@ -294,6 +294,9 @@ Source Files + + Source Files + diff --git a/windows/vr_nbl.c b/windows/vr_nbl.c index a02c5fc4c..3e96af71d 100644 --- a/windows/vr_nbl.c +++ b/windows/vr_nbl.c @@ -33,7 +33,7 @@ FILTER_SEND_NET_BUFFER_LISTS FilterSendNetBufferLists; FILTER_SEND_NET_BUFFER_LISTS_COMPLETE FilterSendNetBufferListsComplete; -static NDIS_STATUS +NDIS_STATUS CreateForwardingContext(PNET_BUFFER_LIST nbl) { ASSERT(nbl != NULL); @@ -42,7 +42,7 @@ CreateForwardingContext(PNET_BUFFER_LIST nbl) nbl); } -static void +void FreeForwardingContext(PNET_BUFFER_LIST nbl) { ASSERT(nbl != NULL); diff --git a/windows/win_packet.c b/windows/win_packet.c index f7ccce62f..019969946 100644 --- a/windows/win_packet.c +++ b/windows/win_packet.c @@ -3,23 +3,18 @@ * * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved. */ -#include "precomp.h" #include "win_packet.h" -#include - -struct _WIN_PACKET { - NET_BUFFER_LIST NetBufferList; -}; - -PNET_BUFFER_LIST -WinPacketToNBL(PWIN_PACKET Packet) -{ - return &Packet->NetBufferList; -} - PWIN_PACKET -WinPacketFromNBL(PNET_BUFFER_LIST NetBufferList) +WinPacketClone(PWIN_PACKET Packet) { - return (PWIN_PACKET)NetBufferList; + PWIN_PACKET cloned = WinPacketRawAllocateClone(Packet); + if (cloned == NULL) { + return NULL; + } + + WinPacketRawSetParentOf(cloned, Packet); + WinPacketRawIncrementChildCountOf(Packet); + + return cloned; } diff --git a/windows/win_packet.h b/windows/win_packet.h index 78ad5b1cc..7222bd7ee 100644 --- a/windows/win_packet.h +++ b/windows/win_packet.h @@ -32,6 +32,16 @@ GetWinPacketFromVrPacket(struct vr_packet *VrPacket) return wrapper->WinPacket; } +PWIN_PACKET WinPacketClone(PWIN_PACKET Packet); + +PWIN_PACKET WinPacketRawGetParentOf(PWIN_PACKET Packet); +VOID WinPacketRawSetParentOf(PWIN_PACKET Packet, PWIN_PACKET Parent); + +LONG WinPacketRawGetChildCountOf(PWIN_PACKET Packet); +VOID WinPacketRawIncrementChildCountOf(PWIN_PACKET Packet); + +extern PWIN_PACKET (*WinPacketRawAllocateClone)(PWIN_PACKET Packet); + // TODO: Remove when callback layer is independent of NDIS PNET_BUFFER_LIST WinPacketToNBL(PWIN_PACKET Packet); PWIN_PACKET WinPacketFromNBL(PNET_BUFFER_LIST NetBufferList); diff --git a/windows/win_packet_raw.c b/windows/win_packet_raw.c new file mode 100644 index 000000000..fde1e9128 --- /dev/null +++ b/windows/win_packet_raw.c @@ -0,0 +1,78 @@ +/* + * win_packet_raw.c -- wrapper interface for Windows packet subsystem + * + * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved. + */ +#include "win_packet.h" +#include "windows_nbl.h" + +#include + +struct _WIN_PACKET { + NET_BUFFER_LIST NetBufferList; +}; + +VOID +WinPacketRawSetParentOf(PWIN_PACKET Packet, PWIN_PACKET Parent) +{ + PNET_BUFFER_LIST parentNbl = WinPacketToNBL(Parent); + PNET_BUFFER_LIST childNbl = WinPacketToNBL(Packet); + + childNbl->ParentNetBufferList = parentNbl; +} + +VOID +WinPacketRawIncrementChildCountOf(PWIN_PACKET Packet) +{ + PNET_BUFFER_LIST nbl = WinPacketToNBL(Packet); + InterlockedIncrement(&nbl->ChildRefCount); +} + +static PWIN_PACKET +WinPacketRawAllocateClone_Impl(PWIN_PACKET Packet) +{ + NDIS_STATUS status; + + PNET_BUFFER_LIST originalNbl = WinPacketToNBL(Packet); + PNET_BUFFER_LIST clonedNbl = NdisAllocateCloneNetBufferList(originalNbl, VrNBLPool, NULL, 0); + if (clonedNbl == NULL) { + goto failure; + } + + clonedNbl->SourceHandle = VrSwitchObject->NdisFilterHandle; + + status = CreateForwardingContext(clonedNbl); + if (status != NDIS_STATUS_SUCCESS) { + goto cleanup_cloned_nbl; + } + + status = VrSwitchObject->NdisSwitchHandlers.CopyNetBufferListInfo( + VrSwitchObject->NdisSwitchContext, clonedNbl, originalNbl, 0); + if (status != NDIS_STATUS_SUCCESS) { + goto cleanup_forwarding_context; + } + + return WinPacketFromNBL(clonedNbl); + +cleanup_forwarding_context: + FreeForwardingContext(clonedNbl); + +cleanup_cloned_nbl: + NdisFreeCloneNetBufferList(clonedNbl, 0); + +failure: + return NULL; +} +PWIN_PACKET (*WinPacketRawAllocateClone)(PWIN_PACKET Packet) = WinPacketRawAllocateClone_Impl; + +PNET_BUFFER_LIST +WinPacketToNBL(PWIN_PACKET Packet) +{ + return &Packet->NetBufferList; +} + +PWIN_PACKET +WinPacketFromNBL(PNET_BUFFER_LIST NetBufferList) +{ + return (PWIN_PACKET)NetBufferList; +} diff --git a/windows/windows_nbl.h b/windows/windows_nbl.h index 3c2ba3f5b..40f437fee 100644 --- a/windows/windows_nbl.h +++ b/windows/windows_nbl.h @@ -25,7 +25,10 @@ extern VOID FreeNetBufferList(PNET_BUFFER_LIST nbl); extern VOID FreeCreatedNetBufferList(PNET_BUFFER_LIST nbl); extern VOID FreeClonedNetBufferListRecursive(PNET_BUFFER_LIST nbl); extern VOID FreeClonedNetBufferListPreservingParent(PNET_BUFFER_LIST nbl); -PNET_BUFFER_LIST SplitMultiNetBufferNetBufferList(PNET_BUFFER_LIST origNbl); +extern PNET_BUFFER_LIST SplitMultiNetBufferNetBufferList(PNET_BUFFER_LIST origNbl); + +extern NDIS_STATUS CreateForwardingContext(PNET_BUFFER_LIST nbl); +extern VOID FreeForwardingContext(PNET_BUFFER_LIST nbl); extern struct vr_packet *win_get_packet(PNET_BUFFER_LIST nbl, struct vr_interface *vif); extern void win_packet_map_from_mdl(struct vr_packet *pkt, PMDL mdl, ULONG mdl_offset, ULONG data_length);