@@ -131,6 +131,8 @@ typedef struct _OVS_SWITCH_CONTEXT
* vport */
INT32 countInternalVports; /* the number of internal
* vports */
+ UINT32 ipHelperBoundVportNo; /* vportNo bound to
+ * IpHelper */
/*
* 'portIdHashArray' ONLY contains ports that exist on the Hyper-V switch,
@@ -100,6 +100,12 @@ static NTSTATUS GetNICAlias(PNDIS_SWITCH_NIC_PARAMETERS nicParam,
static NTSTATUS OvsConvertIfCountedStrToAnsiStr(PIF_COUNTED_STRING wStr,
CHAR *str,
UINT16 maxStrLen);
+_Requires_lock_held_(switchContext->dispatchLock)
+static VOID OvsBindVportWithIpHelper(POVS_VPORT_ENTRY vport,
+ POVS_SWITCH_CONTEXT switchContext);
+_Requires_lock_held_(switchContext->dispatchLock)
+static VOID OvsUnBindVportWithIpHelper(POVS_VPORT_ENTRY vport,
+ POVS_SWITCH_CONTEXT switchContext);
/*
* --------------------------------------------------------------------------
@@ -453,7 +459,7 @@ HvConnectNic(POVS_SWITCH_CONTEXT switchContext,
vport->nicState = NdisSwitchNicStateConnected;
if (nicParam->NicType == NdisSwitchNicTypeInternal) {
- OvsInternalAdapterUp(vport->portNo, &vport->netCfgInstanceId);
+ OvsBindVportWithIpHelper(vport, switchContext);
}
NdisReleaseRWLock(switchContext->dispatchLock, &lockState);
@@ -633,7 +639,7 @@ HvDisconnectNic(POVS_SWITCH_CONTEXT switchContext,
}
if (isInternalPort) {
- OvsInternalAdapterDown(vport->portNo, vport->netCfgInstanceId);
+ OvsUnBindVportWithIpHelper(vport, switchContext);
OvsRemoveAndDeleteVport(NULL, switchContext, vport, TRUE, TRUE);
OvsPostVportEvent(&event);
}
@@ -1308,7 +1314,7 @@ OvsRemoveAndDeleteVport(PVOID usrParamsContext,
if (hvDelete && vport->isAbsentOnHv == FALSE) {
switchContext->countInternalVports--;
ASSERT(switchContext->countInternalVports >= 0);
- OvsInternalAdapterDown(vport->portNo, vport->netCfgInstanceId);
+ OvsUnBindVportWithIpHelper(vport, switchContext);
}
hvSwitchPort = TRUE;
break;
@@ -2814,3 +2820,25 @@ OvsTunnelVportPendingInit(PVOID context,
ASSERT(*replyLen != 0);
}
}
+
+_Use_decl_annotations_
+static VOID
+OvsBindVportWithIpHelper(POVS_VPORT_ENTRY vport,
+ POVS_SWITCH_CONTEXT switchContext)
+{
+ OVS_LOG_TRACE("OvsBindVportWithIpHelper: %d", vport->portNo);
+ ASSERT(switchContext->ipHelperBoundVportNo == 0);
+ switchContext->ipHelperBoundVportNo = vport->portNo;
+ OvsInternalAdapterUp(vport->portNo, &vport->netCfgInstanceId);
+}
+
+_Use_decl_annotations_
+static VOID
+OvsUnBindVportWithIpHelper(POVS_VPORT_ENTRY vport,
+ POVS_SWITCH_CONTEXT switchContext)
+{
+ OVS_LOG_TRACE("OvsUnBindVportWithIpHelper: %d", vport->portNo);
+ ASSERT(switchContext->ipHelperBoundVportNo == vport->portNo);
+ switchContext->ipHelperBoundVportNo = 0;
+ OvsInternalAdapterDown(vport->portNo, vport->netCfgInstanceId);
+}
Protect internal adapter up/down calls with a dispatch lock. It was observed that the InternalAdapter bind calls could happen out of order thereby causing encap packets to not be sent properly. Add assert around the IpHelper bind calls to ensure Up/Down gets called only for the appropriate vports. Signed-off-by: Sairam Venugopal <vsairam@vmware.com> --- datapath-windows/ovsext/Switch.h | 2 ++ datapath-windows/ovsext/Vport.c | 34 +++++++++++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 3 deletions(-)