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 <dlu...@gmail.com> --- v2: No change. lib/conntrack.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) 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); } -- 1.9.1 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev