This patch was enforced by the WHCK logo testing. In order to pass the Windows Filtering Platform tests we need to add a persistent system provider.
Signed-off-by: Sorin Vinturis <svintu...@cloudbasesolutions.com> Reported-by: Sorin Vinturis <svintu...@cloudbasesolutions.com> Reported-at: https://github.com/openvswitch/ovs-issues/issues/65 --- datapath-windows/ovsext/Datapath.c | 2 + datapath-windows/ovsext/Switch.c | 1 - datapath-windows/ovsext/Switch.h | 1 + datapath-windows/ovsext/TunnelFilter.c | 179 +++++++++++++++++++++++++++++---- datapath-windows/ovsext/TunnelIntf.h | 4 + 5 files changed, 169 insertions(+), 18 deletions(-) diff --git a/datapath-windows/ovsext/Datapath.c b/datapath-windows/ovsext/Datapath.c index a818ab9..12410ef 100644 --- a/datapath-windows/ovsext/Datapath.c +++ b/datapath-windows/ovsext/Datapath.c @@ -356,6 +356,7 @@ OvsInit() gOvsCtrlLock = &ovsCtrlLockObj; NdisAllocateSpinLock(gOvsCtrlLock); OvsInitEventQueue(); + OvsTunnelAddSystemProvider(); } VOID @@ -366,6 +367,7 @@ OvsCleanup() NdisFreeSpinLock(gOvsCtrlLock); gOvsCtrlLock = NULL; } + OvsTunnelRemoveSystemProvider(); } VOID diff --git a/datapath-windows/ovsext/Switch.c b/datapath-windows/ovsext/Switch.c index 2b68037..a228d8e 100644 --- a/datapath-windows/ovsext/Switch.c +++ b/datapath-windows/ovsext/Switch.c @@ -26,7 +26,6 @@ #include "Event.h" #include "Flow.h" #include "IpHelper.h" -#include "TunnelIntf.h" #include "Oid.h" #ifdef OVS_DBG_MOD diff --git a/datapath-windows/ovsext/Switch.h b/datapath-windows/ovsext/Switch.h index 61f74c4..7960072 100644 --- a/datapath-windows/ovsext/Switch.h +++ b/datapath-windows/ovsext/Switch.h @@ -23,6 +23,7 @@ #include "NetProto.h" #include "BufferMgmt.h" +#include "TunnelIntf.h" #define OVS_MAX_VPORT_ARRAY_SIZE 1024 #define OVS_MAX_PID_ARRAY_SIZE 1024 diff --git a/datapath-windows/ovsext/TunnelFilter.c b/datapath-windows/ovsext/TunnelFilter.c index 06c8709..5b81cd5 100644 --- a/datapath-windows/ovsext/TunnelFilter.c +++ b/datapath-windows/ovsext/TunnelFilter.c @@ -40,11 +40,25 @@ #define INITGUID #include <guiddef.h> +#define FWP_ERR_NOT_FOUND 0xC0220007L +/* Infinite timeout */ +#define INFINITE 0xFFFFFFFF +/* + * The provider name should always match the provider string from the install + * file. + */ +#define OVS_TUNNEL_PROVIDER_NAME L"Open vSwitch" +/* + * The provider description should always contain the OVS service description + * string from the install file. + */ +#define OVS_TUNNEL_PROVIDER_DESC L"Open vSwitch Extension tunnel provider" - +/* The session name isn't required but it's useful for diagnostics. */ +#define OVS_TUNNEL_SESSION_NAME L"OVS tunnel session" /* Configurable parameters (addresses and ports are in host order) */ UINT16 configNewDestPort = VXLAN_UDP_PORT; @@ -70,6 +84,15 @@ DEFINE_GUID( 0x94, 0xc9, 0xf0, 0xd5, 0x25, 0xbb, 0xc1, 0x69 ); +/* 6fc957d7-14e7-47c7-812b-4668be994ba1 */ +DEFINE_GUID( + OVS_TUNNEL_PROVIDER_KEY, + 0x6fc957d7, + 0x14e7, + 0x47c7, + 0x81, 0x2b, 0x46, 0x68, 0xbe, 0x99, 0x4b, 0xa1 + ); + /* bfd4814c-9650-4de3-a536-1eedb9e9ba6a */ DEFINE_GUID( OVS_TUNNEL_FILTER_KEY, @@ -84,7 +107,7 @@ DEFINE_GUID( */ PDEVICE_OBJECT gDeviceObject; -HANDLE gEngineHandle; +HANDLE gEngineHandle = NULL; UINT32 gCalloutIdV4; @@ -180,6 +203,116 @@ Exit: return status; } +VOID +OvsTunnelAddSystemProvider(VOID) +{ + NTSTATUS status = STATUS_SUCCESS; + FWPM_PROVIDER0 provider; + FWPM_SESSION session = { 0 }; + + /* The session name isn't required but may be useful for diagnostics. */ + session.displayData.name = OVS_TUNNEL_SESSION_NAME; + /* + * Set an infinite wait timeout, so we don't have to handle FWP_E_TIMEOUT + * errors while waiting to acquire the transaction lock. + */ + session.txnWaitTimeoutInMSec = INFINITE; + session.flags = FWPM_SESSION_FLAG_DYNAMIC; + + /* The authentication service should always be RPC_C_AUTHN_DEFAULT. */ + status = FwpmEngineOpen(NULL, + RPC_C_AUTHN_DEFAULT, + NULL, + &session, + &gEngineHandle); + + if (!NT_SUCCESS(status)) { + goto Exit; + } + + status = FwpmTransactionBegin(gEngineHandle, 0); + if (!NT_SUCCESS(status)) { + goto Exit; + } + + memset(&provider, 0, sizeof(provider)); + provider.providerKey = OVS_TUNNEL_PROVIDER_KEY; + provider.displayData.name = OVS_TUNNEL_PROVIDER_NAME; + provider.displayData.description = OVS_TUNNEL_PROVIDER_DESC; + /* + * Since we always want the provider to be present, it's easiest to add + * it as persistent objects during install. Alternatively, we could add + * non-persistent objects every time our service starts. + */ + provider.flags = FWPM_PROVIDER_FLAG_PERSISTENT; + + status = FwpmProviderAdd(gEngineHandle, + &provider, + NULL); + + FwpmTransactionCommit(gEngineHandle); + +Exit: + if (!NT_SUCCESS(status)) { + /* + * Any transaction in progress will be aborted when calling + * FwpmEngineClose. + */ + if (gEngineHandle) { + FwpmEngineClose(gEngineHandle); + gEngineHandle = NULL; + } + } +} + +VOID +OvsTunnelRemoveSystemProvider(VOID) +{ + NTSTATUS status = STATUS_SUCCESS; + + /* The authentication service should always be RPC_C_AUTHN_DEFAULT. */ + if (NULL == gEngineHandle) { + FWPM_SESSION session = { 0 }; + + /* The session name isn't required but may be useful for diagnostics. */ + session.displayData.name = OVS_TUNNEL_SESSION_NAME; + /* + * Set an infinite wait timeout, so we don't have to handle FWP_E_TIMEOUT + * errors while waiting to acquire the transaction lock. + */ + session.txnWaitTimeoutInMSec = INFINITE; + session.flags = FWPM_SESSION_FLAG_DYNAMIC; + + status = FwpmEngineOpen(NULL, + RPC_C_AUTHN_DEFAULT, + NULL, + &session, + &gEngineHandle); + if (!NT_SUCCESS(status)) { + goto Exit; + } + } + + status = FwpmTransactionBegin(gEngineHandle, 0); + if (!NT_SUCCESS(status)) { + goto Exit; + } + + status = FwpmProviderDeleteByKey(gEngineHandle, + &OVS_TUNNEL_PROVIDER_KEY); + if (!NT_SUCCESS(status)) { + goto Exit; + } + + FwpmTransactionCommit(gEngineHandle); + +Exit: + if (gEngineHandle) { + FwpmEngineClose(gEngineHandle); + gEngineHandle = NULL; + } +} + /* * -------------------------------------------------------------------------- * This function registers callouts and filters that intercept UDP traffic at @@ -271,18 +404,27 @@ OvsTunnelRegisterCallouts(VOID *deviceObject) BOOLEAN engineOpened = FALSE; BOOLEAN inTransaction = FALSE; - FWPM_SESSION session = {0}; - - session.flags = FWPM_SESSION_FLAG_DYNAMIC; - - status = FwpmEngineOpen(NULL, - RPC_C_AUTHN_WINNT, - NULL, - &session, - &gEngineHandle); - - if (!NT_SUCCESS(status)) { - goto Exit; + if (NULL == gEngineHandle) { + FWPM_SESSION session = {0}; + + /* The session name isn't required but may be useful for diagnostics. */ + session.displayData.name = OVS_TUNNEL_SESSION_NAME; + /* + * Set an infinite wait timeout, so we don't have to handle FWP_E_TIMEOUT + * errors while waiting to acquire the transaction lock. + */ + session.txnWaitTimeoutInMSec = INFINITE; + session.flags = FWPM_SESSION_FLAG_DYNAMIC; + + status = FwpmEngineOpen(NULL, + RPC_C_AUTHN_WINNT, + NULL, + &session, + &gEngineHandle); + + if (!NT_SUCCESS(status)) { + goto Exit; + } } engineOpened = TRUE; @@ -300,13 +442,18 @@ OvsTunnelRegisterCallouts(VOID *deviceObject) L"Sub-Layer for use by Datagram-Data OVS callouts"; OvsTunnelSubLayer.flags = 0; OvsTunnelSubLayer.weight = FWP_EMPTY; /* auto-weight */ + /* + * Link all objects to the tunnel provider. When multiple providers are + * installed on a computer, this makes it easy to determine who added what. + */ + OvsTunnelSubLayer.providerKey = (GUID*) &OVS_TUNNEL_PROVIDER_KEY; status = FwpmSubLayerAdd(gEngineHandle, &OvsTunnelSubLayer, NULL); if (!NT_SUCCESS(status)) { goto Exit; } - // In order to use this callout a socket must be opened + /* In order to use this callout a socket must be opened. */ status = OvsTunnelRegisterDatagramDataCallouts(&FWPM_LAYER_DATAGRAM_DATA_V4, &OVS_TUNNEL_CALLOUT_V4, deviceObject, @@ -341,8 +488,6 @@ OvsTunnelUnregisterCallouts(VOID) { OvsTunnelRemoveFilter(&OVS_TUNNEL_FILTER_KEY, &OVS_TUNNEL_SUBLAYER); - FwpmEngineClose(gEngineHandle); - gEngineHandle = NULL; FwpsCalloutUnregisterById(gCalloutIdV4); } diff --git a/datapath-windows/ovsext/TunnelIntf.h b/datapath-windows/ovsext/TunnelIntf.h index c622720..0718a0a 100644 --- a/datapath-windows/ovsext/TunnelIntf.h +++ b/datapath-windows/ovsext/TunnelIntf.h @@ -22,4 +22,8 @@ NTSTATUS OvsTunnelFilterInitialize(PDRIVER_OBJECT driverObject); VOID OvsTunnelFilterUninitialize(PDRIVER_OBJECT driverObject); +VOID OvsTunnelAddSystemProvider(VOID); + +VOID OvsTunnelRemoveSystemProvider(VOID); + #endif /* __TUNNEL_INTF_H_ */ -- 1.9.0.msysgit.0 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev