[ovs-dev,v2,1/6] conntrack: Handle self nat case.

Message ID 1536124490-86810-1-git-send-email-dlu998@gmail.com
State New
Headers show
Series
  • [ovs-dev,v2,1/6] conntrack: Handle self nat case.
Related show

Commit Message

Darrell Ball Sept. 5, 2018, 5:14 a.m.
Handle the 'unusual case' that the user requests natting to self.
This defaults to the legacy case, where a single conntrack entry is
used rather than having a separate reverse entry and can lead to
referencing freed memory in nat clean.
To handle this case, we only mark the conntrack entry as un_nat type
when we know we have a un_nat conn entry.
Also, a now unused api is removed.
Needs backporting to 2.8.

Fixes: 286de2729955 ("dpdk: Userspace Datapath: Introduce NAT Support.")
Signed-off-by: Darrell Ball <dlu998@gmail.com>
---
 lib/conntrack.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

Patch

diff --git a/lib/conntrack.c b/lib/conntrack.c
index be8debb..15984d2 100644
--- a/lib/conntrack.c
+++ b/lib/conntrack.c
@@ -852,7 +852,7 @@  conn_not_found(struct conntrack *ct, struct dp_packet *pkt,
                struct conn *conn_for_un_nat_copy,
                const char *helper,
                const struct alg_exp_node *alg_exp,
-               enum ct_alg_ctl_type ct_alg_ctl)
+               enum ct_alg_ctl_type ct_alg_ctl, bool *nat)
 {
     struct conn *nc = NULL;
 
@@ -932,7 +932,7 @@  conn_not_found(struct conntrack *ct, struct dp_packet *pkt,
                 *nc = *conn_for_un_nat_copy;
                 ct_rwlock_unlock(&ct->resources_lock);
             }
-            conn_for_un_nat_copy->conn_type = CT_CONN_TYPE_UN_NAT;
+            *nat = true;
             conn_for_un_nat_copy->nat_info = NULL;
             conn_for_un_nat_copy->alg = NULL;
             nat_packet(pkt, nc, ctx->icmp_related);
@@ -1013,6 +1013,7 @@  create_un_nat_conn(struct conntrack *ct, struct conn *conn_for_un_nat_copy,
     struct conn *nc = xmemdup(conn_for_un_nat_copy, sizeof *nc);
     nc->key = conn_for_un_nat_copy->rev_key;
     nc->rev_key = conn_for_un_nat_copy->key;
+    nc->conn_type = CT_CONN_TYPE_UN_NAT;
     uint32_t un_nat_hash = conn_key_hash(&nc->key, ct->hash_basis);
     unsigned un_nat_conn_bucket = hash_to_bucket(un_nat_hash);
     ct_lock_lock(&ct->buckets[un_nat_conn_bucket].lock);
@@ -1135,12 +1136,6 @@  check_orig_tuple(struct conntrack *ct, struct dp_packet *pkt,
 }
 
 static bool
-is_un_nat_conn_valid(const struct conn *un_nat_conn)
-{
-    return un_nat_conn->conn_type == CT_CONN_TYPE_UN_NAT;
-}
-
-static bool
 conn_update_state_alg(struct conntrack *ct, struct dp_packet *pkt,
                       struct conn_lookup_ctx *ctx, struct conn *conn,
                       const struct nat_action_info_t *nat_action_info,
@@ -1253,6 +1248,7 @@  process_one(struct conntrack *ct, struct dp_packet *pkt,
 
     const struct alg_exp_node *alg_exp = NULL;
     struct alg_exp_node alg_exp_entry;
+    bool nat = false;
 
     if (OVS_UNLIKELY(create_new_conn)) {
 
@@ -1268,7 +1264,7 @@  process_one(struct conntrack *ct, struct dp_packet *pkt,
 
         conn = conn_not_found(ct, pkt, ctx, commit, now, nat_action_info,
                               &conn_for_un_nat_copy, helper, alg_exp,
-                              ct_alg_ctl);
+                              ct_alg_ctl, &nat);
     }
 
     write_ct_md(pkt, zone, conn, &ctx->key, alg_exp);
@@ -1288,7 +1284,7 @@  process_one(struct conntrack *ct, struct dp_packet *pkt,
 
     ct_lock_unlock(&ct->buckets[bucket].lock);
 
-    if (is_un_nat_conn_valid(&conn_for_un_nat_copy)) {
+    if (nat) {
         create_un_nat_conn(ct, &conn_for_un_nat_copy, now, !!alg_exp);
     }