When using lb with allow-stateless and enable-stateless-acl-with-lb
enabled, there was an issue with hairpin traffic.
SYN and SYN/ACK were properly handled (DNATted and SNATted). However next ACK,
or PACKET, were not properly SNATted, resulting in the TCP connection
remaining in SYN-RECV/FIN-WAIT-1.
ACK was then retransmitted, potentially causing a new conntrack entry.

This caused test "enable-stateless-acl-with-lb usage" to randomly fail
due to this issue.

This patch properly sets REG_LB_IPV4/6 and REG_LB_PORT registers.
It also modifies the test so that it would also fail w/o the flow
modification.

Signed-off-by: Xavier Simonart <[email protected]>
---
 northd/northd.c     |  9 +++++++++
 tests/ovn-northd.at |  4 ++--
 tests/system-ovn.at | 13 ++++++++++++-
 3 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/northd/northd.c b/northd/northd.c
index bb3844c7f..d79fe40c9 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -8063,6 +8063,15 @@ build_lb_rules_pre_stateful(struct lflow_table *lflows,
                               lb_vip->port_str);
             }
 
+            if (lb->vips[i].address_family == AF_INET) {
+                ds_put_format(action, REG_LB_IPV4 " = %s; ", lb_vip->vip_str);
+            } else {
+                ds_put_format(action, REG_LB_IPV6 " = %s; ", lb_vip->vip_str);
+            }
+            if (lb_vip->port_str) {
+                ds_put_format(action, REG_LB_PORT " = %s; ", lb_vip->port_str);
+            }
+
             ds_put_cstr(action, "ct_lb_mark;");
 
             ovn_lflow_add(lflows, od, S_SWITCH_IN_PRE_STATEFUL, 150,
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 25655c456..3acd99183 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -17919,7 +17919,7 @@ AT_CHECK([grep -E 'ls_in_pre_stateful' sw0flows | 
ovn_strip_lflows], [0], [dnl
   table=??(ls_in_pre_stateful ), priority=110  , match=(reg0[[2]] == 1), 
action=(ct_lb_mark;)
   table=??(ls_in_pre_stateful ), priority=115  , match=(reg0[[2]] == 1 && 
ip.is_frag), action=(reg0[[19]] = 1; ct_lb_mark;)
   table=??(ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 && 
ip4.dst == 10.0.0.5), action=(reg4 = 10.0.0.5; ct_lb_mark;)
-  table=??(ls_in_pre_stateful ), priority=150  , match=(ip4.dst == 10.0.0.5), 
action=(ct_lb_mark;)
+  table=??(ls_in_pre_stateful ), priority=150  , match=(ip4.dst == 10.0.0.5), 
action=(reg4 = 10.0.0.5; ct_lb_mark;)
 ])
 
 AS_BOX([Set hairpin_snat_ip to Load Balancer without port.])
@@ -17933,7 +17933,7 @@ AT_CHECK([grep -E 'ls_in_pre_stateful' sw0flows | 
ovn_strip_lflows], [0], [dnl
   table=??(ls_in_pre_stateful ), priority=110  , match=(reg0[[2]] == 1), 
action=(ct_lb_mark;)
   table=??(ls_in_pre_stateful ), priority=115  , match=(reg0[[2]] == 1 && 
ip.is_frag), action=(reg0[[19]] = 1; ct_lb_mark;)
   table=??(ls_in_pre_stateful ), priority=120  , match=(reg0[[2]] == 1 && 
ip4.dst == 10.0.0.5), action=(reg4 = 10.0.0.5; ct_lb_mark;)
-  table=??(ls_in_pre_stateful ), priority=150  , match=(ip4.dst == 10.0.0.5), 
action=(ct_lb_mark;)
+  table=??(ls_in_pre_stateful ), priority=150  , match=(ip4.dst == 10.0.0.5), 
action=(reg4 = 10.0.0.5; ct_lb_mark;)
 ])
 
 AS_BOX([Create one more logical switch with load balancer.])
diff --git a/tests/system-ovn.at b/tests/system-ovn.at
index fc601dd1b..5b3dc47fd 100644
--- a/tests/system-ovn.at
+++ b/tests/system-ovn.at
@@ -4907,7 +4907,6 @@ AT_CLEANUP
 OVN_FOR_EACH_NORTHD([
 AT_SETUP([enable-stateless-acl-with-lb usage])
 AT_SKIP_IF([test $HAVE_NC = no])
-TAG_UNSTABLE
 
 CHECK_CONNTRACK()
 ovn_start
@@ -5018,6 +5017,7 @@ NETNS_DAEMONIZE([lsp1], [nc -u -l 192.168.0.101 4042], 
[lsp1_udp.pid])
 NETNS_DAEMONIZE([lsp1], [nc -l -k 192.168.0.101 4043], [lsp1_non_lb.pid])
 
 # Send the packet to VIP from private network.
+NETNS_START_TCPDUMP([lsp1], [-nnnei lsp1], [lsp1])
 NS_CHECK_EXEC([lsp1], [nc -z 192.168.0.1 8080], [0], [ignore], [ignore])
 
 # Udp connections
@@ -5033,6 +5033,17 @@ 
udp,orig=(src=192.168.0.101,dst=192.168.0.1,sport=<cleared>,dport=<cleared>),rep
 
 AT_CHECK([ovs-appctl dpctl/flush-conntrack])
 
+# Do the same sending a packet.
+NS_CHECK_EXEC([lsp1], [echo a | nc 192.168.0.1 8080], [0], [ignore], [ignore])
+
+# Check conntrack zone of lsp1 has tcp entry for lb
+AT_CHECK([ovs-appctl dpctl/dump-conntrack zone=$zone_lsp1_id | \
+FORMAT_CT(192.168.0.1) | \
+sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
+tcp,orig=(src=192.168.0.101,dst=192.168.0.1,sport=<cleared>,dport=<cleared>),reply=(src=192.168.0.101,dst=192.168.0.101,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>)
+])
+AT_CHECK([ovs-appctl dpctl/flush-conntrack])
+
 # Check that internal traffic not related to lb doesn't create conntrack 
records
 NS_CHECK_EXEC([external], [nc -z 192.168.0.101 4043], [0], [])
 
-- 
2.47.1

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

Reply via email to