diff mbox series

[ovs-dev,v4,2/3] datapath-windows: Add a global level RW lock for NAT

Message ID 20180129182801.3360-3-kumaranand@vmware.com
State Accepted
Headers show
Series datapath-windows: New lock implementation in conntrack | expand

Commit Message

Anand Kumar Jan. 29, 2018, 6:28 p.m. UTC
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>
---
 datapath-windows/ovsext/Conntrack.c | 36 ++++++++++++++++++++++++++++++++++--
 1 file changed, 34 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/datapath-windows/ovsext/Conntrack.c b/datapath-windows/ovsext/Conntrack.c
index 3cde836..7d56a50 100644
--- a/datapath-windows/ovsext/Conntrack.c
+++ b/datapath-windows/ovsext/Conntrack.c
@@ -32,6 +32,7 @@  KSTART_ROUTINE OvsConntrackEntryCleaner;
 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;
 
@@ -58,6 +59,13 @@  OvsInitConntrack(POVS_SWITCH_CONTEXT context)
         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,
@@ -65,6 +73,8 @@  OvsInitConntrack(POVS_SWITCH_CONTEXT context)
     if (ovsConntrackTable == NULL) {
         NdisFreeRWLock(ovsConntrackLockObj);
         ovsConntrackLockObj = NULL;
+        NdisFreeRWLock(ovsCtNatLockObj);
+        ovsCtNatLockObj = NULL;
         return STATUS_INSUFFICIENT_RESOURCES;
     }
 
@@ -82,6 +92,9 @@  OvsInitConntrack(POVS_SWITCH_CONTEXT context)
         NdisFreeRWLock(ovsConntrackLockObj);
         ovsConntrackLockObj = NULL;
 
+        NdisFreeRWLock(ovsCtNatLockObj);
+        ovsCtNatLockObj = NULL;
+
         OvsFreeMemoryWithTag(ovsConntrackTable, OVS_CT_POOL_TAG);
         ovsConntrackTable = NULL;
 
@@ -111,7 +124,7 @@  OvsInitConntrack(POVS_SWITCH_CONTEXT context)
 VOID
 OvsCleanupConntrack(VOID)
 {
-    LOCK_STATE_EX lockState;
+    LOCK_STATE_EX lockState, lockStateNat;
     NdisAcquireRWLockWrite(ovsConntrackLockObj, &lockState, 0);
     ctThreadCtx.exit = 1;
     KeSetEvent(&ctThreadCtx.event, 0, FALSE);
@@ -131,7 +144,11 @@  OvsCleanupConntrack(VOID)
 
     NdisFreeRWLock(ovsConntrackLockObj);
     ovsConntrackLockObj = NULL;
+    NdisAcquireRWLockWrite(ovsCtNatLockObj, &lockStateNat, 0);
     OvsNatCleanup();
+    NdisReleaseRWLock(ovsCtNatLockObj, &lockStateNat);
+    NdisFreeRWLock(ovsCtNatLockObj);
+    ovsCtNatLockObj = NULL;
 }
 
 static __inline VOID
@@ -197,15 +214,19 @@  OvsCtAddEntry(POVS_CT_ENTRY entry, OvsConntrackKeyLookupCtx *ctx,
     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)) {
+                NdisReleaseRWLock(ovsCtNatLockObj, &lockStateNat);
                 return FALSE;
             }
             ctx->hash = OvsHashCtKey(&entry->key);
         } else {
             entry->natInfo.natAction = natInfo->natAction;
         }
+        NdisReleaseRWLock(ovsCtNatLockObj, &lockStateNat);
     }
 
     entry->timestampStart = now;
@@ -358,7 +379,10 @@  OvsCtEntryDelete(POVS_CT_ENTRY entry, BOOLEAN forceDelete)
     }
     if (forceDelete || OvsCtEntryExpired(entry)) {
         if (entry->natInfo.natAction) {
+            LOCK_STATE_EX lockStateNat;
+            NdisAcquireRWLockWrite(ovsCtNatLockObj, &lockStateNat, 0);
             OvsNatDeleteKey(&entry->key);
+            NdisReleaseRWLock(ovsCtNatLockObj, &lockStateNat);
         }
         OvsPostCtEventEntry(entry, OVS_EVENT_CT_DELETE);
         RemoveEntryList(&entry->link);
@@ -560,7 +584,10 @@  OvsCtSetupLookupCtx(OvsFlowKey *flowKey,
         return NDIS_STATUS_INVALID_PACKET;
     }
 
+    LOCK_STATE_EX lockStateNat;
+    NdisAcquireRWLockRead(ovsCtNatLockObj, &lockStateNat, 0);
     natEntry = OvsNatLookup(&ctx->key, TRUE);
+    NdisReleaseRWLock(ovsCtNatLockObj, &lockStateNat);
     if (natEntry) {
         /* Translate address first for reverse NAT */
         ctx->key = natEntry->ctEntry->key;
@@ -813,8 +840,11 @@  OvsCtExecute_(OvsForwardingContext *fwdCtx,
      */
     if (natInfo->natAction != NAT_ACTION_NONE)
     {
+        LOCK_STATE_EX lockStateNat;
+        NdisAcquireRWLockWrite(ovsCtNatLockObj, &lockStateNat, 0);
         OvsNatPacket(fwdCtx, entry, entry->natInfo.natAction,
                      key, ctx.reply);
+        NdisReleaseRWLock(ovsCtNatLockObj, &lockStateNat);
     }
 
     OvsCtSetMarkLabel(key, entry, mark, labels, &triggerUpdateEvent);
@@ -1052,7 +1082,7 @@  OvsCtFlush(UINT16 zone, struct ovs_key_ct_tuple_ipv4 *tuple)
     PLIST_ENTRY link, next;
     POVS_CT_ENTRY entry;
 
-    LOCK_STATE_EX lockState;
+    LOCK_STATE_EX lockState, lockStateNat;
     NdisAcquireRWLockWrite(ovsConntrackLockObj, &lockState, 0);
 
     if (ctTotalEntries) {
@@ -1083,7 +1113,9 @@  OvsCtFlush(UINT16 zone, struct ovs_key_ct_tuple_ipv4 *tuple)
         }
     }
 
+    NdisAcquireRWLockWrite(ovsCtNatLockObj, &lockStateNat, 0);
     OvsNatFlush(zone);
+    NdisReleaseRWLock(ovsCtNatLockObj, &lockStateNat);
     NdisReleaseRWLock(ovsConntrackLockObj, &lockState);
     return NDIS_STATUS_SUCCESS;
 }