On Wed, Apr 29, 2015 at 5:58 AM, Sorin Vinturis
<svintu...@cloudbasesolutions.com> wrote:
> 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 <svintu...@cloudbasesolutions.com>
> Reported-by: Sorin Vinturis <svintu...@cloudbasesolutions.com>
> Reported-at: https://github.com/openvswitch/ovs-issues/issues/77
> Acked-by: Eitan Eliahu <elia...@vmware.com>

Thank you, applied!

> ---
> 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
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to