diff options
author | Anand Kumar <kumaranand@vmware.com> | 2018-06-22 10:09:26 -0700 |
---|---|---|
committer | Alin Gabriel Serdean <aserdean@ovn.org> | 2018-06-24 23:58:16 +0300 |
commit | 9726a016d9d6b2a8616fb407ce7df632c352cc66 (patch) | |
tree | 37bdfc02813b6ff636be9441d2e22d8f1e5763e8 /datapath-windows/ovsext/Conntrack-nat.c | |
parent | 9d7c8de9fe557efa9c55bfe4fe8947785f252c3a (diff) | |
download | openvswitch-9726a016d9d6b2a8616fb407ce7df632c352cc66.tar.gz |
datapath-windows: Implement locking in conntrack NAT.
This patch primarily replaces existing ndis RWlock based implementaion
for NAT in conntrack with a spinlock based implementation inside NAT,
module along with some conntrack optimization.
- The 'ovsNatTable' and 'ovsUnNatTable' tables are shared
between cleanup threads and packet processing thread.
In order to protect these two tables use a spinlock.
Also introduce counters to track number of nat entries.
- Introduce a new function OvsGetTcpHeader() to retrieve TCP header
and payload length, to optimize for TCP traffic.
- Optimize conntrack look up.
- Remove 'bucketlockRef' member from conntrack entry structure.
Testing:
Verified loading/unloading the driver with driver verified enabled.
Ran TCP/UDP and ICMP traffic.
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>
Diffstat (limited to 'datapath-windows/ovsext/Conntrack-nat.c')
-rw-r--r-- | datapath-windows/ovsext/Conntrack-nat.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/datapath-windows/ovsext/Conntrack-nat.c b/datapath-windows/ovsext/Conntrack-nat.c index da1814f96..1607d4c4f 100644 --- a/datapath-windows/ovsext/Conntrack-nat.c +++ b/datapath-windows/ovsext/Conntrack-nat.c @@ -3,7 +3,8 @@ PLIST_ENTRY ovsNatTable = NULL; PLIST_ENTRY ovsUnNatTable = NULL; - +static NDIS_SPIN_LOCK ovsCtNatLock; +static ULONG ovsNatEntries; /* *--------------------------------------------------------------------------- * OvsHashNatKey @@ -109,6 +110,8 @@ NTSTATUS OvsNatInit() InitializeListHead(&ovsUnNatTable[i]); } + NdisAllocateSpinLock(&ovsCtNatLock); + ovsNatEntries = 0; return STATUS_SUCCESS; } @@ -121,6 +124,11 @@ NTSTATUS OvsNatInit() VOID OvsNatFlush(UINT16 zone) { PLIST_ENTRY link, next; + if (!ovsNatEntries) { + return; + } + + NdisAcquireSpinLock(&ovsCtNatLock); for (int i = 0; i < NAT_HASH_TABLE_SIZE; i++) { LIST_FORALL_SAFE(&ovsNatTable[i], link, next) { POVS_NAT_ENTRY entry = @@ -131,6 +139,7 @@ VOID OvsNatFlush(UINT16 zone) } } } + NdisReleaseSpinLock(&ovsCtNatLock); } /* @@ -142,12 +151,17 @@ VOID OvsNatFlush(UINT16 zone) VOID OvsNatCleanup() { if (ovsNatTable == NULL) { + NdisFreeSpinLock(&ovsCtNatLock); return; } + + NdisAcquireSpinLock(&ovsCtNatLock); OvsFreeMemoryWithTag(ovsNatTable, OVS_CT_POOL_TAG); OvsFreeMemoryWithTag(ovsUnNatTable, OVS_CT_POOL_TAG); ovsNatTable = NULL; ovsUnNatTable = NULL; + NdisReleaseSpinLock(&ovsCtNatLock); + NdisFreeSpinLock(&ovsCtNatLock); } /* @@ -250,10 +264,13 @@ static UINT32 OvsNatHashRange(const OVS_CT_ENTRY *entry, UINT32 basis) VOID OvsNatAddEntry(OVS_NAT_ENTRY* entry) { + NdisAcquireSpinLock(&ovsCtNatLock); InsertHeadList(OvsNatGetBucket(&entry->key, FALSE), &entry->link); InsertHeadList(OvsNatGetBucket(&entry->value, TRUE), &entry->reverseLink); + NdisReleaseSpinLock(&ovsCtNatLock); + NdisInterlockedIncrement((PLONG)&ovsNatEntries); } /* @@ -399,21 +416,29 @@ OvsNatLookup(const OVS_CT_KEY *ctKey, BOOLEAN reverse) PLIST_ENTRY link; POVS_NAT_ENTRY entry; + if (!ovsNatEntries) { + return NULL; + } + + NdisAcquireSpinLock(&ovsCtNatLock); LIST_FORALL(OvsNatGetBucket(ctKey, reverse), link) { if (reverse) { entry = CONTAINING_RECORD(link, OVS_NAT_ENTRY, reverseLink); if (OvsNatKeyAreSame(ctKey, &entry->value)) { + NdisReleaseSpinLock(&ovsCtNatLock); return entry; } } else { entry = CONTAINING_RECORD(link, OVS_NAT_ENTRY, link); if (OvsNatKeyAreSame(ctKey, &entry->key)) { + NdisReleaseSpinLock(&ovsCtNatLock); return entry; } } } + NdisReleaseSpinLock(&ovsCtNatLock); return NULL; } @@ -432,6 +457,7 @@ OvsNatDeleteEntry(POVS_NAT_ENTRY entry) RemoveEntryList(&entry->link); RemoveEntryList(&entry->reverseLink); OvsFreeMemoryWithTag(entry, OVS_CT_POOL_TAG); + NdisInterlockedDecrement((PLONG)&ovsNatEntries); } /* |