[ovs-dev,v2,2/3] conntrack: Fix missed 'conn' lookup checks.
diff mbox series

Message ID 1559067284-48389-2-git-send-email-dlu998@gmail.com
State New
Headers show
Series
  • [ovs-dev,v2,1/3] conntrack: Don't re-add cleaned 'conn' to expiry list.
Related show

Commit Message

Darrell Ball May 28, 2019, 6:14 p.m. UTC
Whenever a 'conn' entry is removed or added, we need to reverify it's
existence status under lock protection.  There were some cases that
were missed, so fix them.

Fixes: 967bb5c5cd90 ("conntrack: Add rcu support.")
Signed-off-by: Darrell Ball <dlu998@gmail.com>
---

v2: No change.

 lib/conntrack.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

Patch
diff mbox series

diff --git a/lib/conntrack.c b/lib/conntrack.c
index c57d9fd..e9d6720 100644
--- a/lib/conntrack.c
+++ b/lib/conntrack.c
@@ -956,7 +956,10 @@  conn_update_state(struct conntrack *ct, struct dp_packet *pkt,
             break;
         case CT_UPDATE_NEW:
             ovs_mutex_lock(&ct->ct_lock);
-            conn_clean(ct, conn);
+            uint32_t hash = conn_key_hash(&conn->key, ct->hash_basis);
+            if (conn_key_lookup(ct, &conn->key, hash, now, NULL, NULL)) {
+                conn_clean(ct, conn);
+            }
             ovs_mutex_unlock(&ct->ct_lock);
             create_new_conn = true;
             break;
@@ -1089,11 +1092,15 @@  process_one(struct conntrack *ct, struct dp_packet *pkt,
     bool create_new_conn = false;
     conn_key_lookup(ct, &ctx->key, ctx->hash, now, &ctx->conn, &ctx->reply);
     struct conn *conn = ctx->conn;
+    uint32_t hash;
 
     /* Delete found entry if in wrong direction. 'force' implies commit. */
     if (OVS_UNLIKELY(force && ctx->reply && conn)) {
         ovs_mutex_lock(&ct->ct_lock);
-        conn_clean(ct, conn);
+        hash = conn_key_hash(&conn->key, ct->hash_basis);
+        if (conn_key_lookup(ct, &conn->key, hash, now, NULL, NULL)) {
+            conn_clean(ct, conn);
+        }
         ovs_mutex_unlock(&ct->ct_lock);
         conn = NULL;
     }
@@ -1103,7 +1110,7 @@  process_one(struct conntrack *ct, struct dp_packet *pkt,
 
             ctx->reply = true;
             struct conn *rev_conn = conn;  /* Save for debugging. */
-            uint32_t hash = conn_key_hash(&conn->rev_key, ct->hash_basis);
+            hash = conn_key_hash(&conn->rev_key, ct->hash_basis);
             conn_key_lookup(ct, &ctx->key, hash, now, &conn, &ctx->reply);
 
             if (!conn) {
@@ -1158,8 +1165,11 @@  process_one(struct conntrack *ct, struct dp_packet *pkt,
         ovs_rwlock_unlock(&ct->resources_lock);
 
         ovs_mutex_lock(&ct->ct_lock);
-        conn = conn_not_found(ct, pkt, ctx, commit, now, nat_action_info,
-                              helper, alg_exp, ct_alg_ctl);
+        hash = conn_key_hash(&ctx->key, ct->hash_basis);
+        if (!conn_key_lookup(ct, &ctx->key, hash, now, NULL, NULL)) {
+            conn = conn_not_found(ct, pkt, ctx, commit, now, nat_action_info,
+                                  helper, alg_exp, ct_alg_ctl);
+        }
         ovs_mutex_unlock(&ct->ct_lock);
     }