On Wed, Apr 29, 2015 at 5:58 AM, Sorin Vinturis
<[email protected]> 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 <[email protected]>
> Reported-by: Sorin Vinturis <[email protected]>
> Reported-at: https://github.com/openvswitch/ovs-issues/issues/77
> Acked-by: Eitan Eliahu <[email protected]>
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
> [email protected]
> http://openvswitch.org/mailman/listinfo/dev
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev