diff options
Diffstat (limited to 'datapath-windows/ovsext/TunnelFilter.c')
-rw-r--r-- | datapath-windows/ovsext/TunnelFilter.c | 99 |
1 files changed, 94 insertions, 5 deletions
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(); +} |