[ovs-dev] [PATCH v4 1/2] datapath-windows: Enable extension after rrestart

Sorin Vinturis svinturis at cloudbasesolutions.com
Wed Apr 29 12:58:16 UTC 2015


The extension failed to be activated during booting due to the
failure to initialize tunnel filter. This happened because the Base
Filtering Engine (BFE) is not started and 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 tunnel filter is initialized.

Signed-off-by: Sorin Vinturis <svinturis at cloudbasesolutions.com>
Reported-by: Sorin Vinturis <svinturis at cloudbasesolutions.com>
Reported-at: https://github.com/openvswitch/ovs-issues/issues/77
Acked-by: Eitan Eliahu <eliahue at vmware.com>
---
v2: Splitted original patch into two patch series.

v3: Updated after review & added acked.

v4: Rebased the patch.
---
 datapath-windows/ovsext/Switch.c       |   6 +-
 datapath-windows/ovsext/TunnelFilter.c | 125 +++++++++++++++++++++++++++------
 datapath-windows/ovsext/TunnelIntf.h   |   4 +-
 3 files changed, 109 insertions(+), 26 deletions(-)

diff --git a/datapath-windows/ovsext/Switch.c b/datapath-windows/ovsext/Switch.c
index 4f784b8..032153d 100644
--- a/datapath-windows/ovsext/Switch.c
+++ b/datapath-windows/ovsext/Switch.c
@@ -40,6 +40,7 @@ UINT64 ovsTimeIncrementPerTick;
 
 extern NDIS_HANDLE gOvsExtDriverHandle;
 extern NDIS_HANDLE gOvsExtDriverObject;
+extern PDEVICE_OBJECT gOvsDeviceObject;
 
 /*
  * Reference count used to prevent premature deallocation of the global switch
@@ -203,11 +204,12 @@ OvsCreateSwitch(NDIS_HANDLE ndisFilterHandle,
         goto create_switch_done;
     }
 
-    status = OvsTunnelFilterInitialize(gOvsExtDriverObject);
+    status = OvsInitTunnelFilter(gOvsExtDriverObject, gOvsDeviceObject);
     if (status != NDIS_STATUS_SUCCESS) {
         OvsUninitSwitchContext(switchContext);
         goto create_switch_done;
     }
+
     *switchContextOut = switchContext;
 
 create_switch_done:
@@ -261,7 +263,7 @@ OvsDeleteSwitch(POVS_SWITCH_CONTEXT switchContext)
     if (switchContext)
     {
         dpNo = switchContext->dpNo;
-        OvsTunnelFilterUninitialize(gOvsExtDriverObject);
+        OvsUninitTunnelFilter(gOvsExtDriverObject);
         OvsClearAllSwitchVports(switchContext);
         OvsUninitSwitchContext(switchContext);
     }
diff --git a/datapath-windows/ovsext/TunnelFilter.c b/datapath-windows/ovsext/TunnelFilter.c
index 4b879c0..c2186eb 100644
--- a/datapath-windows/ovsext/TunnelFilter.c
+++ b/datapath-windows/ovsext/TunnelFilter.c
@@ -111,7 +111,8 @@ DEFINE_GUID(
 PDEVICE_OBJECT gDeviceObject;
 
 HANDLE gEngineHandle = NULL;
-HANDLE gBfeSubscriptionHandle = NULL;
+HANDLE gTunnelProviderBfeHandle = NULL;
+HANDLE gTunnelInitBfeHandle = NULL;
 UINT32 gCalloutIdV4;
 
 
@@ -448,11 +449,6 @@ 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)) {
@@ -547,8 +543,8 @@ Exit:
 }
 
 VOID NTAPI
-OvsBfeStateChangeCallback(PVOID context,
-                          FWPM_SERVICE_STATE bfeState)
+OvsTunnelProviderBfeCallback(PVOID context,
+                             FWPM_SERVICE_STATE bfeState)
 {
     HANDLE handle = NULL;
 
@@ -564,18 +560,18 @@ OvsBfeStateChangeCallback(PVOID context,
 }
 
 NTSTATUS
-OvsSubscribeBfeStateChanges(PVOID deviceObject)
+OvsSubscribeTunnelProviderBfeStateChanges(PVOID deviceObject)
 {
     NTSTATUS status = STATUS_SUCCESS;
 
-    if (!gBfeSubscriptionHandle) {
+    if (!gTunnelProviderBfeHandle) {
         status = FwpmBfeStateSubscribeChanges(deviceObject,
-                                              OvsBfeStateChangeCallback,
+                                              OvsTunnelProviderBfeCallback,
                                               NULL,
-                                              &gBfeSubscriptionHandle);
+                                              &gTunnelProviderBfeHandle);
         if (!NT_SUCCESS(status)) {
             OVS_LOG_ERROR(
-                "Failed to open subscribe BFE state change callback, status: %x.",
+                "Failed to subscribe BFE tunnel provider callback, status: %x.",
                 status);
         }
     }
@@ -584,27 +580,28 @@ OvsSubscribeBfeStateChanges(PVOID deviceObject)
 }
 
 VOID
-OvsUnsubscribeBfeStateChanges()
+OvsUnsubscribeTunnelProviderBfeStateChanges()
 {
     NTSTATUS status = STATUS_SUCCESS;
 
-    if (gBfeSubscriptionHandle) {
-        status = FwpmBfeStateUnsubscribeChanges(gBfeSubscriptionHandle);
+    if (gTunnelProviderBfeHandle) {
+        status = FwpmBfeStateUnsubscribeChanges(gTunnelProviderBfeHandle);
         if (!NT_SUCCESS(status)) {
             OVS_LOG_ERROR(
-                "Failed to open unsubscribe BFE state change callback, status: %x.",
+                "Failed to unsubscribe BFE tunnel provider callback, status: %x.",
                 status);
         }
-        gBfeSubscriptionHandle = NULL;
+        gTunnelProviderBfeHandle = NULL;
     }
 }
 
-VOID OvsRegisterSystemProvider(PVOID deviceObject)
+VOID
+OvsRegisterSystemProvider(PVOID deviceObject)
 {
     NTSTATUS status = STATUS_SUCCESS;
     HANDLE handle = NULL;
 
-    status = OvsSubscribeBfeStateChanges(deviceObject);
+    status = OvsSubscribeTunnelProviderBfeStateChanges(deviceObject);
     if (NT_SUCCESS(status)) {
         if (FWPM_SERVICE_RUNNING == FwpmBfeStateGet()) {
             OvsTunnelEngineOpen(&handle);
@@ -613,7 +610,7 @@ VOID OvsRegisterSystemProvider(PVOID deviceObject)
             }
             OvsTunnelEngineClose(&handle);
 
-            OvsUnsubscribeBfeStateChanges();
+            OvsUnsubscribeTunnelProviderBfeStateChanges();
         }
     }
 }
@@ -628,5 +625,89 @@ VOID OvsUnregisterSystemProvider()
     }
     OvsTunnelEngineClose(&handle);
 
-    OvsUnsubscribeBfeStateChanges();
+    OvsUnsubscribeTunnelProviderBfeStateChanges();
+}
+
+VOID NTAPI
+OvsTunnelInitBfeCallback(PVOID context,
+                         FWPM_SERVICE_STATE bfeState)
+{
+    NTSTATUS status = STATUS_SUCCESS;
+    PDRIVER_OBJECT driverObject = (PDRIVER_OBJECT) context;
+
+    if (FWPM_SERVICE_RUNNING == bfeState) {
+        status = OvsTunnelFilterInitialize(driverObject);
+        if (!NT_SUCCESS(status)) {
+            OVS_LOG_ERROR(
+                "Failed to initialize tunnel filter, status: %x.",
+                status);
+        }
+    }
+}
+
+NTSTATUS
+OvsSubscribeTunnelInitBfeStateChanges(PDRIVER_OBJECT driverObject,
+                                      PVOID deviceObject)
+{
+    NTSTATUS status = STATUS_SUCCESS;
+
+    if (!gTunnelInitBfeHandle) {
+        status = FwpmBfeStateSubscribeChanges(deviceObject,
+                                              OvsTunnelInitBfeCallback,
+                                              driverObject,
+                                              &gTunnelInitBfeHandle);
+        if (!NT_SUCCESS(status)) {
+            OVS_LOG_ERROR(
+                "Failed to subscribe BFE tunnel init callback, status: %x.",
+                status);
+        }
+    }
+
+    return status;
+}
+
+VOID
+OvsUnsubscribeTunnelInitBfeStateChanges()
+{
+    NTSTATUS status = STATUS_SUCCESS;
+
+    if (gTunnelInitBfeHandle) {
+        status = FwpmBfeStateUnsubscribeChanges(gTunnelInitBfeHandle);
+        if (!NT_SUCCESS(status)) {
+            OVS_LOG_ERROR(
+                "Failed to unsubscribe BFE tunnel init callback, status: %x.",
+                status);
+        }
+        gTunnelInitBfeHandle = NULL;
+    }
+}
+
+NTSTATUS
+OvsInitTunnelFilter(PDRIVER_OBJECT driverObject, PVOID deviceObject)
+{
+    NTSTATUS status = STATUS_SUCCESS;
+
+    status = OvsSubscribeTunnelInitBfeStateChanges(driverObject, deviceObject);
+    if (NT_SUCCESS(status)) {
+        if (FWPM_SERVICE_RUNNING == FwpmBfeStateGet()) {
+            status = OvsTunnelFilterInitialize(driverObject);
+            if (!NT_SUCCESS(status)) {
+                /* XXX: We need to decide what actions to take in case of
+                 * failure to initialize tunnel filter. */
+                ASSERT(status == NDIS_STATUS_SUCCESS);
+                OVS_LOG_ERROR(
+                    "Failed to initialize tunnel filter, status: %x.",
+                    status);
+            }
+            OvsUnsubscribeTunnelInitBfeStateChanges();
+        }
+    }
+
+    return status;
+}
+
+VOID OvsUninitTunnelFilter(PDRIVER_OBJECT driverObject)
+{
+    OvsTunnelFilterUninitialize(driverObject);
+    OvsUnsubscribeTunnelInitBfeStateChanges();
 }
diff --git a/datapath-windows/ovsext/TunnelIntf.h b/datapath-windows/ovsext/TunnelIntf.h
index 728a53f..82a5145 100644
--- a/datapath-windows/ovsext/TunnelIntf.h
+++ b/datapath-windows/ovsext/TunnelIntf.h
@@ -18,9 +18,9 @@
 #define __TUNNEL_INTF_H_ 1
 
 /* Tunnel callout driver load/unload functions */
-NTSTATUS OvsTunnelFilterInitialize(PDRIVER_OBJECT driverObject);
+NTSTATUS OvsInitTunnelFilter(PDRIVER_OBJECT driverObject, PVOID deviceObject);
 
-VOID OvsTunnelFilterUninitialize(PDRIVER_OBJECT driverObject);
+VOID OvsUninitTunnelFilter(PDRIVER_OBJECT driverObject);
 
 VOID OvsRegisterSystemProvider(PVOID deviceObject);
 
-- 
1.9.0.msysgit.0



More information about the dev mailing list