Example OpenFlow actions:

  ct(commit,zone=2,nat(src=10.0.0.1:1000),table=1)
  ct(commit,zone=3,nat)

An empty nat nest on ct(commit) passes nat_action_info with
nat_action unset.  conn_not_found() treated any non-NULL pointer as
configured NAT and allocated bindings via nat_get_unique_tuple(),
producing entries with zero reply tuples:

  orig=(src=10.0.0.1,dst=10.1.1.2,sport=1000,dport=5201)
  reply=(src=0.0.0.0,dst=10.0.0.1,sport=5201,dport=0)

Only create NAT bindings when OVS_NAT_ATTR_SRC or OVS_NAT_ATTR_DST was
parsed.  Keep passing nat_action_info for an empty nest so ct(nat) still
triggers reverse NAT on established flows.

Add an ofproto-dpif testsuite case.

Fixes: 286de2729955 ("dpdk: Userspace Datapath: Introduce NAT Support.")
Signed-off-by: Eli Britstein <[email protected]>
---
 lib/conntrack.c       | 22 +++++++++++++---------
 tests/ofproto-dpif.at | 22 ++++++++++++++++++++++
 2 files changed, 35 insertions(+), 9 deletions(-)

diff --git a/lib/conntrack.c b/lib/conntrack.c
index f84cdd216..7e09537b9 100644
--- a/lib/conntrack.c
+++ b/lib/conntrack.c
@@ -1095,8 +1095,6 @@ conn_not_found(struct conntrack *ct, struct dp_packet 
*pkt,
         }
 
         if (nat_action_info) {
-            nc->nat_action = nat_action_info->nat_action;
-
             if (alg_exp) {
                 if (alg_exp->nat_rpl_dst) {
                     rev_key_node->key.dst.addr = alg_exp->alg_nat_repl_addr;
@@ -1105,18 +1103,24 @@ conn_not_found(struct conntrack *ct, struct dp_packet 
*pkt,
                     rev_key_node->key.src.addr = alg_exp->alg_nat_repl_addr;
                     nc->nat_action = NAT_ACTION_DST;
                 }
-            } else {
-                bool nat_res = nat_get_unique_tuple(ct, nc, nat_action_info);
+            } else if (nat_action_info->nat_action) {
+                bool nat_res;
+
+                nc->nat_action = nat_action_info->nat_action;
+                nat_res = nat_get_unique_tuple(ct, nc, nat_action_info);
                 if (!nat_res) {
                     goto nat_res_exhaustion;
                 }
             }
 
-            nat_packet(pkt, nc, false, ctx->icmp_related);
-            uint32_t rev_hash = conn_key_hash(&rev_key_node->key,
-                                              ct->hash_basis);
-            cmap_insert(&ct->conns[ctx->key.zone],
-                        &rev_key_node->cm_node, rev_hash);
+            if (nc->nat_action) {
+                uint32_t rev_hash;
+
+                nat_packet(pkt, nc, false, ctx->icmp_related);
+                rev_hash = conn_key_hash(&rev_key_node->key, ct->hash_basis);
+                cmap_insert(&ct->conns[ctx->key.zone],
+                            &rev_key_node->cm_node, rev_hash);
+            }
         }
 
         cmap_insert(&ct->conns[ctx->key.zone],
diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
index 9e64e8ee4..9a48f5013 100644
--- a/tests/ofproto-dpif.at
+++ b/tests/ofproto-dpif.at
@@ -13364,6 +13364,28 @@ AT_CHECK([tail -1 stdout], [0],
 OVS_VSWITCHD_STOP
 AT_CLEANUP
 
+AT_SETUP([ofproto-dpif - nat - empty nat on ct(commit)])
+OVS_VSWITCHD_START
+
+add_of_ports br0 1 2
+
+dnl SNAT in zone 2, then empty ct(commit,nat) in zone 3.
+AT_DATA([flows.txt], [dnl
+table=0,priority=100,in_port=1,tcp,ct_state=-trk,action=ct(commit,zone=2,nat(src=10.0.0.1:1000),table=1)
+table=1,priority=100,ct_zone=2,tcp,action=ct(commit,zone=3,nat)
+])
+
+AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
+
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 
'in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.1.1.1,dst=10.1.1.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=12345,dst=5201),tcp_flags(syn)'])
+
+AT_CHECK([ovs-appctl dpctl/dump-conntrack zone=3], [0], [dnl
+tcp,orig=(src=10.0.0.1,dst=10.1.1.2,sport=1000,dport=5201),reply=(src=10.1.1.2,dst=10.0.0.1,sport=5201,dport=1000),zone=3,protoinfo=(state=SYN_SENT)
+])
+
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
 dnl Checks the get/set sweep interval
 AT_SETUP([ofproto-dpif - conntrack - change sweep interval])
 OVS_VSWITCHD_START
-- 
2.43.0

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to