Currently NAT module relies on the existing conntrack lock.
This patch provides a basic lock implementation for NAT module
in conntrack.
Signed-off-by: Anand Kumar <kumaranand@vmware.com>
Acked-by: Alin Gabriel Serdean <aserdean@ovn.org>
Signed-off-by: Alin Gabriel Serdean <aserdean@ovn.org>
static PLIST_ENTRY ovsConntrackTable;
static OVS_CT_THREAD_CTX ctThreadCtx;
static PNDIS_RW_LOCK_EX ovsConntrackLockObj;
static PLIST_ENTRY ovsConntrackTable;
static OVS_CT_THREAD_CTX ctThreadCtx;
static PNDIS_RW_LOCK_EX ovsConntrackLockObj;
+static PNDIS_RW_LOCK_EX ovsCtNatLockObj;
extern POVS_SWITCH_CONTEXT gOvsSwitchContext;
static LONG ctTotalEntries;
extern POVS_SWITCH_CONTEXT gOvsSwitchContext;
static LONG ctTotalEntries;
return STATUS_INSUFFICIENT_RESOURCES;
}
return STATUS_INSUFFICIENT_RESOURCES;
}
+ ovsCtNatLockObj = NdisAllocateRWLock(context->NdisFilterHandle);
+ if (ovsCtNatLockObj == NULL) {
+ NdisFreeRWLock(ovsConntrackLockObj);
+ ovsConntrackLockObj = NULL;
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
/* Init the Hash Buffer */
ovsConntrackTable = OvsAllocateMemoryWithTag(sizeof(LIST_ENTRY)
* CT_HASH_TABLE_SIZE,
/* Init the Hash Buffer */
ovsConntrackTable = OvsAllocateMemoryWithTag(sizeof(LIST_ENTRY)
* CT_HASH_TABLE_SIZE,
if (ovsConntrackTable == NULL) {
NdisFreeRWLock(ovsConntrackLockObj);
ovsConntrackLockObj = NULL;
if (ovsConntrackTable == NULL) {
NdisFreeRWLock(ovsConntrackLockObj);
ovsConntrackLockObj = NULL;
+ NdisFreeRWLock(ovsCtNatLockObj);
+ ovsCtNatLockObj = NULL;
return STATUS_INSUFFICIENT_RESOURCES;
}
return STATUS_INSUFFICIENT_RESOURCES;
}
NdisFreeRWLock(ovsConntrackLockObj);
ovsConntrackLockObj = NULL;
NdisFreeRWLock(ovsConntrackLockObj);
ovsConntrackLockObj = NULL;
+ NdisFreeRWLock(ovsCtNatLockObj);
+ ovsCtNatLockObj = NULL;
+
OvsFreeMemoryWithTag(ovsConntrackTable, OVS_CT_POOL_TAG);
ovsConntrackTable = NULL;
OvsFreeMemoryWithTag(ovsConntrackTable, OVS_CT_POOL_TAG);
ovsConntrackTable = NULL;
VOID
OvsCleanupConntrack(VOID)
{
VOID
OvsCleanupConntrack(VOID)
{
- LOCK_STATE_EX lockState;
+ LOCK_STATE_EX lockState, lockStateNat;
NdisAcquireRWLockWrite(ovsConntrackLockObj, &lockState, 0);
ctThreadCtx.exit = 1;
KeSetEvent(&ctThreadCtx.event, 0, FALSE);
NdisAcquireRWLockWrite(ovsConntrackLockObj, &lockState, 0);
ctThreadCtx.exit = 1;
KeSetEvent(&ctThreadCtx.event, 0, FALSE);
NdisFreeRWLock(ovsConntrackLockObj);
ovsConntrackLockObj = NULL;
NdisFreeRWLock(ovsConntrackLockObj);
ovsConntrackLockObj = NULL;
+ NdisAcquireRWLockWrite(ovsCtNatLockObj, &lockStateNat, 0);
+ NdisReleaseRWLock(ovsCtNatLockObj, &lockStateNat);
+ NdisFreeRWLock(ovsCtNatLockObj);
+ ovsCtNatLockObj = NULL;
if (natInfo == NULL) {
entry->natInfo.natAction = NAT_ACTION_NONE;
} else {
if (natInfo == NULL) {
entry->natInfo.natAction = NAT_ACTION_NONE;
} else {
+ LOCK_STATE_EX lockStateNat;
+ NdisAcquireRWLockWrite(ovsCtNatLockObj, &lockStateNat, 0);
if (OvsIsForwardNat(natInfo->natAction)) {
entry->natInfo = *natInfo;
if (!OvsNatTranslateCtEntry(entry)) {
if (OvsIsForwardNat(natInfo->natAction)) {
entry->natInfo = *natInfo;
if (!OvsNatTranslateCtEntry(entry)) {
+ NdisReleaseRWLock(ovsCtNatLockObj, &lockStateNat);
return FALSE;
}
ctx->hash = OvsHashCtKey(&entry->key);
} else {
entry->natInfo.natAction = natInfo->natAction;
}
return FALSE;
}
ctx->hash = OvsHashCtKey(&entry->key);
} else {
entry->natInfo.natAction = natInfo->natAction;
}
+ NdisReleaseRWLock(ovsCtNatLockObj, &lockStateNat);
}
entry->timestampStart = now;
}
entry->timestampStart = now;
}
if (forceDelete || OvsCtEntryExpired(entry)) {
if (entry->natInfo.natAction) {
}
if (forceDelete || OvsCtEntryExpired(entry)) {
if (entry->natInfo.natAction) {
+ LOCK_STATE_EX lockStateNat;
+ NdisAcquireRWLockWrite(ovsCtNatLockObj, &lockStateNat, 0);
OvsNatDeleteKey(&entry->key);
OvsNatDeleteKey(&entry->key);
+ NdisReleaseRWLock(ovsCtNatLockObj, &lockStateNat);
}
OvsPostCtEventEntry(entry, OVS_EVENT_CT_DELETE);
RemoveEntryList(&entry->link);
}
OvsPostCtEventEntry(entry, OVS_EVENT_CT_DELETE);
RemoveEntryList(&entry->link);
return NDIS_STATUS_INVALID_PACKET;
}
return NDIS_STATUS_INVALID_PACKET;
}
+ LOCK_STATE_EX lockStateNat;
+ NdisAcquireRWLockRead(ovsCtNatLockObj, &lockStateNat, 0);
natEntry = OvsNatLookup(&ctx->key, TRUE);
natEntry = OvsNatLookup(&ctx->key, TRUE);
+ NdisReleaseRWLock(ovsCtNatLockObj, &lockStateNat);
if (natEntry) {
/* Translate address first for reverse NAT */
ctx->key = natEntry->ctEntry->key;
if (natEntry) {
/* Translate address first for reverse NAT */
ctx->key = natEntry->ctEntry->key;
*/
if (natInfo->natAction != NAT_ACTION_NONE)
{
*/
if (natInfo->natAction != NAT_ACTION_NONE)
{
+ LOCK_STATE_EX lockStateNat;
+ NdisAcquireRWLockWrite(ovsCtNatLockObj, &lockStateNat, 0);
OvsNatPacket(fwdCtx, entry, entry->natInfo.natAction,
key, ctx.reply);
OvsNatPacket(fwdCtx, entry, entry->natInfo.natAction,
key, ctx.reply);
+ NdisReleaseRWLock(ovsCtNatLockObj, &lockStateNat);
}
OvsCtSetMarkLabel(key, entry, mark, labels, &triggerUpdateEvent);
}
OvsCtSetMarkLabel(key, entry, mark, labels, &triggerUpdateEvent);
PLIST_ENTRY link, next;
POVS_CT_ENTRY entry;
PLIST_ENTRY link, next;
POVS_CT_ENTRY entry;
- LOCK_STATE_EX lockState;
+ LOCK_STATE_EX lockState, lockStateNat;
NdisAcquireRWLockWrite(ovsConntrackLockObj, &lockState, 0);
if (ctTotalEntries) {
NdisAcquireRWLockWrite(ovsConntrackLockObj, &lockState, 0);
if (ctTotalEntries) {
+ NdisAcquireRWLockWrite(ovsCtNatLockObj, &lockStateNat, 0);
+ NdisReleaseRWLock(ovsCtNatLockObj, &lockStateNat);
NdisReleaseRWLock(ovsConntrackLockObj, &lockState);
return NDIS_STATUS_SUCCESS;
}
NdisReleaseRWLock(ovsConntrackLockObj, &lockState);
return NDIS_STATUS_SUCCESS;
}