From 59a33335dcc5c750b55dbd2a7961e91a816697b7 Mon Sep 17 00:00:00 2001 From: Sorin Vinturis Date: Tue, 24 Mar 2015 14:53:11 +0000 Subject: datapath-windows: Updated WFP system provider handling If the Base Filtering Engine (BFE) is not started, the WFP system provider failed to be added because no session to the engine could be acquired. The solution for this was to registered a BFE notification callback that is called whenever the BFE's state changes. Only if the BFE's state is running the WFP system provider is added. Signed-off-by: Sorin Vinturis Reported-by: Sorin Vinturis Reported-at: https://github.com/openvswitch/ovs-issues/issues/65 Acked-by: Eitan Eliahu Signed-off-by: Ben Pfaff --- datapath-windows/ovsext/TunnelFilter.c | 99 ++++++++++++++++++++++++++++++++-- 1 file changed, 94 insertions(+), 5 deletions(-) (limited to 'datapath-windows/ovsext/TunnelFilter.c') diff --git a/datapath-windows/ovsext/TunnelFilter.c b/datapath-windows/ovsext/TunnelFilter.c index e0adc3726..4b879c059 100644 --- a/datapath-windows/ovsext/TunnelFilter.c +++ b/datapath-windows/ovsext/TunnelFilter.c @@ -111,6 +111,7 @@ DEFINE_GUID( PDEVICE_OBJECT gDeviceObject; HANDLE gEngineHandle = NULL; +HANDLE gBfeSubscriptionHandle = NULL; UINT32 gCalloutIdV4; @@ -173,17 +174,20 @@ OvsTunnelAddSystemProvider(HANDLE handle) 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 object during driver load. - */ + * Since we always want the provider to be present, it's easiest to add + * it as persistent object during driver load. + */ provider.flags = FWPM_PROVIDER_FLAG_PERSISTENT; status = FwpmProviderAdd(handle, &provider, NULL); if (!NT_SUCCESS(status)) { - OVS_LOG_ERROR("Fail to add WFP provider, status: %x.", status); - break; + if (STATUS_FWP_ALREADY_EXISTS != status) { + OVS_LOG_ERROR("Failed to add WFP provider, status: %x.", + status); + break; + } } status = FwpmTransactionCommit(handle); @@ -541,3 +545,88 @@ Exit: return status; } + +VOID NTAPI +OvsBfeStateChangeCallback(PVOID context, + FWPM_SERVICE_STATE bfeState) +{ + HANDLE handle = NULL; + + DBG_UNREFERENCED_PARAMETER(context); + + if (FWPM_SERVICE_RUNNING == bfeState) { + OvsTunnelEngineOpen(&handle); + if (handle) { + OvsTunnelAddSystemProvider(handle); + } + OvsTunnelEngineClose(&handle); + } +} + +NTSTATUS +OvsSubscribeBfeStateChanges(PVOID deviceObject) +{ + NTSTATUS status = STATUS_SUCCESS; + + if (!gBfeSubscriptionHandle) { + status = FwpmBfeStateSubscribeChanges(deviceObject, + OvsBfeStateChangeCallback, + NULL, + &gBfeSubscriptionHandle); + if (!NT_SUCCESS(status)) { + OVS_LOG_ERROR( + "Failed to open subscribe BFE state change callback, status: %x.", + status); + } + } + + return status; +} + +VOID +OvsUnsubscribeBfeStateChanges() +{ + NTSTATUS status = STATUS_SUCCESS; + + if (gBfeSubscriptionHandle) { + status = FwpmBfeStateUnsubscribeChanges(gBfeSubscriptionHandle); + if (!NT_SUCCESS(status)) { + OVS_LOG_ERROR( + "Failed to open unsubscribe BFE state change callback, status: %x.", + status); + } + gBfeSubscriptionHandle = NULL; + } +} + +VOID OvsRegisterSystemProvider(PVOID deviceObject) +{ + NTSTATUS status = STATUS_SUCCESS; + HANDLE handle = NULL; + + status = OvsSubscribeBfeStateChanges(deviceObject); + if (NT_SUCCESS(status)) { + if (FWPM_SERVICE_RUNNING == FwpmBfeStateGet()) { + OvsTunnelEngineOpen(&handle); + if (handle) { + OvsTunnelAddSystemProvider(handle); + } + OvsTunnelEngineClose(&handle); + + OvsUnsubscribeBfeStateChanges(); + } + } +} + +VOID OvsUnregisterSystemProvider() +{ + HANDLE handle = NULL; + + OvsTunnelEngineOpen(&handle); + if (handle) { + OvsTunnelRemoveSystemProvider(handle); + } + OvsTunnelEngineClose(&handle); + + OvsUnsubscribeBfeStateChanges(); +} -- cgit v1.2.1