On 8/2/22 06:01, [email protected] wrote:
> From: wenxu <[email protected]>
>
> There is a big scope ct_lock for new conn setup. The
> ct_lock should be hold only for conns map insert and
> expire rculist insert.
>
> Signed-off-by: wenxu <[email protected]>
> ---
> lib/conntrack.c | 32 ++++++++++++++++++++------------
> 1 file changed, 20 insertions(+), 12 deletions(-)
Paolo, Aaron, could you, please, take a look at this one?
Thanks!
Best regards, Ilya Maximets.
>
> diff --git a/lib/conntrack.c b/lib/conntrack.c
> index 13c5ab6..47d9aac 100644
> --- a/lib/conntrack.c
> +++ b/lib/conntrack.c
> @@ -48,6 +48,7 @@ COVERAGE_DEFINE(conntrack_full);
> COVERAGE_DEFINE(conntrack_l3csum_err);
> COVERAGE_DEFINE(conntrack_l4csum_err);
> COVERAGE_DEFINE(conntrack_lookup_natted_miss);
> +COVERAGE_DEFINE(conntrack_duplicate);
>
> struct conn_lookup_ctx {
> struct conn_key key;
> @@ -1010,10 +1011,10 @@ conn_not_found(struct conntrack *ct, struct dp_packet
> *pkt,
> const struct nat_action_info_t *nat_action_info,
> const char *helper, const struct alg_exp_node *alg_exp,
> enum ct_alg_ctl_type ct_alg_ctl, uint32_t tp_id)
> - OVS_REQUIRES(ct->ct_lock)
> {
> struct conn *nc = NULL;
> struct conn *nat_conn = NULL;
> + uint32_t nat_hash;
>
> if (!valid_new(pkt, &ctx->key)) {
> pkt->md.ct_state = CS_INVALID;
> @@ -1089,16 +1090,26 @@ conn_not_found(struct conntrack *ct, struct dp_packet
> *pkt,
> nat_conn->nat_action = 0;
> nat_conn->alg = NULL;
> nat_conn->nat_conn = NULL;
> - uint32_t nat_hash = conn_key_hash(&nat_conn->key,
> ct->hash_basis);
> - cmap_insert(&ct->conns, &nat_conn->cm_node, nat_hash);
> + nat_hash = conn_key_hash(&nat_conn->key, ct->hash_basis);
> }
>
> nc->nat_conn = nat_conn;
> ovs_mutex_init_adaptive(&nc->lock);
> nc->conn_type = CT_CONN_TYPE_DEFAULT;
> atomic_flag_clear(&nc->reclaimed);
> + ovs_mutex_lock(&ct->ct_lock);
> + if (conn_key_lookup(ct, &ctx->key, ctx->hash, now, NULL, NULL)) {
> + ovs_mutex_unlock(&ct->ct_lock);
> + COVERAGE_INC(conntrack_duplicate);
> + ovs_mutex_destroy(&nc->lock);
> + goto out;
> + }
> + if (nat_conn) {
> + cmap_insert(&ct->conns, &nat_conn->cm_node, nat_hash);
> + }
> cmap_insert(&ct->conns, &nc->cm_node, ctx->hash);
> conn_expire_push_front(ct, nc);
> + ovs_mutex_unlock(&ct->ct_lock);
> atomic_count_inc(&ct->n_conn);
> ctx->conn = nc; /* For completeness. */
> if (zl) {
> @@ -1117,12 +1128,13 @@ conn_not_found(struct conntrack *ct, struct dp_packet
> *pkt,
> * ephemeral ports. A DOS attack should be protected against with
> * firewall rules or a separate firewall. Also using zone partitioning
> * can limit DoS impact. */
> -nat_res_exhaustion:
> - free(nat_conn);
> - delete_conn__(nc);
> static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5);
> +nat_res_exhaustion:
> VLOG_WARN_RL(&rl, "Unable to NAT due to tuple space exhaustion - "
> "if DoS attack, use firewalling and/or zone partitioning.");
> +out:
> + free(nat_conn);
> + delete_conn__(nc);
> return NULL;
> }
>
> @@ -1437,12 +1449,8 @@ process_one(struct conntrack *ct, struct dp_packet
> *pkt,
> }
> ovs_rwlock_unlock(&ct->resources_lock);
>
> - ovs_mutex_lock(&ct->ct_lock);
> - if (!conn_lookup(ct, &ctx->key, now, NULL, NULL)) {
> - conn = conn_not_found(ct, pkt, ctx, commit, now, nat_action_info,
> - helper, alg_exp, ct_alg_ctl, tp_id);
> - }
> - ovs_mutex_unlock(&ct->ct_lock);
> + conn = conn_not_found(ct, pkt, ctx, commit, now, nat_action_info,
> + helper, alg_exp, ct_alg_ctl, tp_id);
> }
>
> write_ct_md(pkt, zone, conn, &ctx->key, alg_exp);
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev