summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--datapath-windows/ovsext/Datapath.c20
-rw-r--r--datapath-windows/ovsext/TunnelFilter.c99
-rw-r--r--datapath-windows/ovsext/TunnelIntf.h8
3 files changed, 100 insertions, 27 deletions
diff --git a/datapath-windows/ovsext/Datapath.c b/datapath-windows/ovsext/Datapath.c
index 8eb13f14a..c6fe89eb7 100644
--- a/datapath-windows/ovsext/Datapath.c
+++ b/datapath-windows/ovsext/Datapath.c
@@ -353,35 +353,19 @@ PNDIS_SPIN_LOCK gOvsCtrlLock;
VOID
OvsInit()
{
- HANDLE handle = NULL;
-
gOvsCtrlLock = &ovsCtrlLockObj;
NdisAllocateSpinLock(gOvsCtrlLock);
OvsInitEventQueue();
-
- OvsTunnelEngineOpen(&handle);
- if (handle) {
- OvsTunnelAddSystemProvider(handle);
- }
- OvsTunnelEngineClose(&handle);
}
VOID
OvsCleanup()
{
- HANDLE handle = NULL;
-
OvsCleanupEventQueue();
if (gOvsCtrlLock) {
NdisFreeSpinLock(gOvsCtrlLock);
gOvsCtrlLock = NULL;
}
-
- OvsTunnelEngineOpen(&handle);
- if (handle) {
- OvsTunnelRemoveSystemProvider(handle);
- }
- OvsTunnelEngineClose(&handle);
}
VOID
@@ -448,6 +432,8 @@ OvsCreateDeviceObject(NDIS_HANDLE ovsExtDriverHandle)
if (ovsExt) {
ovsExt->numberOpenInstance = 0;
}
+ } else {
+ OvsRegisterSystemProvider((PVOID)gOvsDeviceObject);
}
OVS_LOG_TRACE("DeviceObject: %p", gOvsDeviceObject);
@@ -471,6 +457,8 @@ OvsDeleteDeviceObject()
NdisDeregisterDeviceEx(gOvsDeviceHandle);
gOvsDeviceHandle = NULL;
gOvsDeviceObject = NULL;
+
+ OvsUnregisterSystemProvider();
}
}
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();
+}
diff --git a/datapath-windows/ovsext/TunnelIntf.h b/datapath-windows/ovsext/TunnelIntf.h
index b2bba308e..728a53f7f 100644
--- a/datapath-windows/ovsext/TunnelIntf.h
+++ b/datapath-windows/ovsext/TunnelIntf.h
@@ -22,12 +22,8 @@ NTSTATUS OvsTunnelFilterInitialize(PDRIVER_OBJECT driverObject);
VOID OvsTunnelFilterUninitialize(PDRIVER_OBJECT driverObject);
-NTSTATUS OvsTunnelEngineOpen(HANDLE *handle);
+VOID OvsRegisterSystemProvider(PVOID deviceObject);
-VOID OvsTunnelEngineClose(HANDLE *handle);
-
-VOID OvsTunnelAddSystemProvider(HANDLE handle);
-
-VOID OvsTunnelRemoveSystemProvider(HANDLE handle);
+VOID OvsUnregisterSystemProvider();
#endif /* __TUNNEL_INTF_H_ */