The conntrack unit tests seem to generate different megaflow masks on
Windows.  The megaflow masks depend on the internal ordering of the
subtables, which are sorted using qsort(), based on their max priority.
If two subtables have the same priority the ordering between them depend
on the stability property of qsort(), which apparently are different
between Windows and Linux/*BSD.

This commit uses multiple OpenFlow tables to build our conntrack
pipelines in the tests, which gives us more control over the visited
subtables and also improves clarity

Reported-by: Alin Serdean <aserd...@cloudbasesolutions.com>
Signed-off-by: Daniele Di Proietto <diproiet...@vmware.com>
---
 tests/ofproto-dpif.at | 263 +++++++++++++++++++++++++++++++++-----------------
 1 file changed, 174 insertions(+), 89 deletions(-)

diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
index 5ce6439..b2373d3 100644
--- a/tests/ofproto-dpif.at
+++ b/tests/ofproto-dpif.at
@@ -8107,11 +8107,17 @@ AT_CHECK([ovs-appctl vlog/set dpif_netdev:dbg 
vconn:info ofproto_dpif:info])
 
 dnl Allow new connections on p1->p2, but not on p2->p1.
 AT_DATA([flows.txt], [dnl
-priority=1,action=drop
-priority=10,arp,action=normal
-priority=100,in_port=1,udp,action=ct(commit,zone=0),controller
-priority=100,in_port=2,ct_state=-trk,udp,action=ct(table=0,zone=0)
-priority=100,in_port=2,ct_state=+trk+est-new,udp,action=controller
+dnl Table 0
+dnl
+table=0,priority=100,arp,action=normal
+table=0,priority=10,in_port=1,udp,action=ct(commit,zone=0),controller
+table=0,priority=10,in_port=2,ct_state=-trk,udp,action=ct(table=1,zone=0)
+table=0,priority=1,action=drop
+dnl
+dnl Table 1
+dnl
+table=1,priority=10,in_port=2,ct_state=+trk+est-new,udp,action=controller
+table=1,priority=1,action=drop
 ])
 
 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
@@ -8137,7 +8143,7 @@ AT_CHECK([cat ofctl_monitor.log], [0], [dnl
 NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=42 in_port=1 (via action) 
data_len=42 (unbuffered)
 
udp,vlan_tci=0x0000,dl_src=50:54:00:00:00:09,dl_dst=50:54:00:00:00:0a,nw_src=10.1.1.1,nw_dst=10.1.1.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=1,tp_dst=2
 udp_csum:e9d6
 dnl
-NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=42 
ct_state=est|rpl|trk,in_port=2 (via action) data_len=42 (unbuffered)
+NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=42 
ct_state=est|rpl|trk,in_port=2 (via action) data_len=42 (unbuffered)
 
udp,vlan_tci=0x0000,dl_src=50:54:00:00:00:0a,dl_dst=50:54:00:00:00:09,nw_src=10.1.1.2,nw_dst=10.1.1.1,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=2,tp_dst=1
 udp_csum:e9d6
 ])
 
@@ -8160,7 +8166,7 @@ AT_CHECK([cat ofctl_monitor.log], [0], [dnl
 NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=42 in_port=1 (via action) 
data_len=42 (unbuffered)
 
udp,vlan_tci=0x0000,dl_src=50:54:00:00:00:09,dl_dst=50:54:00:00:00:0a,nw_src=10.1.1.1,nw_dst=10.1.1.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=3,tp_dst=4
 udp_csum:e9d2
 dnl
-NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=42 
ct_state=est|rpl|trk,in_port=2 (via action) data_len=42 (unbuffered)
+NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=42 
ct_state=est|rpl|trk,in_port=2 (via action) data_len=42 (unbuffered)
 
udp,vlan_tci=0x0000,dl_src=50:54:00:00:00:0a,dl_dst=50:54:00:00:00:09,nw_src=10.1.1.2,nw_dst=10.1.1.1,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4,tp_dst=3
 udp_csum:e9d2
 ])
 
@@ -8176,11 +8182,16 @@ AT_CHECK([ovs-appctl vlog/set dpif_netdev:dbg 
vconn:info ofproto_dpif:info])
 
 dnl Allow new connections on p1->p2, but not on p2->p1.
 AT_DATA([flows.txt], [dnl
-priority=1,action=drop
-priority=10,arp,action=normal
-priority=100,in_port=1,udp6,action=ct(commit,zone=0),controller
-priority=100,in_port=2,ct_state=-trk,udp6,action=ct(table=0,zone=0)
-priority=100,in_port=2,ct_state=+trk+est-new,udp6,action=controller
+dnl Table 0
+dnl
+table=0,priority=100,arp,action=normal
+table=0,priority=10,in_port=1,udp6,action=ct(commit,zone=0),controller
+table=0,priority=10,in_port=2,ct_state=-trk,udp6,action=ct(table=1,zone=0)
+table=0,priority=1,action=drop
+dnl Table 1
+dnl
+table=1,priority=10,in_port=2,ct_state=+trk+est-new,udp6,action=controller
+table=1,priority=1,action=drop
 ])
 
 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
@@ -8205,7 +8216,7 @@ dnl happens because the ct_state field is available only 
after recirc.
 AT_CHECK([cat ofctl_monitor.log], [0], [dnl
 NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=62 in_port=1 (via action) 
data_len=62 (unbuffered)
 
udp6,vlan_tci=0x0000,dl_src=50:54:00:00:00:09,dl_dst=50:54:00:00:00:0a,ipv6_src=2001:db8::1,ipv6_dst=2001:db8::2,ipv6_label=0x00000,nw_tos=112,nw_ecn=0,nw_ttl=128,tp_src=1,tp_dst=2
 udp_csum:a466
-NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=62 
ct_state=est|rpl|trk,in_port=2 (via action) data_len=62 (unbuffered)
+NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=62 
ct_state=est|rpl|trk,in_port=2 (via action) data_len=62 (unbuffered)
 
udp6,vlan_tci=0x0000,dl_src=50:54:00:00:00:0a,dl_dst=50:54:00:00:00:09,ipv6_src=2001:db8::2,ipv6_dst=2001:db8::1,ipv6_label=0x00000,nw_tos=112,nw_ecn=0,nw_ttl=128,tp_src=2,tp_dst=1
 udp_csum:a466
 ])
 
@@ -8221,11 +8232,26 @@ AT_CHECK([ovs-appctl vlog/set dpif_netdev:dbg 
vconn:info ofproto_dpif:info])
 
 dnl Allow new connections on p1->p2. Allow only established connections p2->p1
 AT_DATA([flows.txt], [dnl
-priority=1,action=drop
-priority=10,arp,action=normal
-priority=100,in_port=1,udp,action=ct(commit,zone=0),2
-priority=100,in_port=2,ct_state=-trk,udp,action=ct(table=0,zone=0)
-priority=100,in_port=2,ct_state=+trk+est-new,udp,action=1
+dnl The flows are in two separate tables for two reasons:
+dnl * To make the pipeline more clear.
+dnl * To make megaflows more consistent (we check megaflows below).  The
+dnl   unwildcarding in megaflows depends on the internal ordering of the
+dnl   subtables, which are sorted using the system qsort().  qsort()
+dnl   is provided by libc and may or may not be stable, so we can't rely
+dnl   on that.  By having separate tables we have more control over which
+dnl   subtables are visited, meaning consistent megaflows.
+dnl
+dnl Table 0
+dnl
+table=0,priority=100,arp,action=normal
+table=0,priority=10,in_port=1,udp,action=ct(commit,zone=0),2
+table=0,priority=10,in_port=2,ct_state=-trk,udp,action=ct(table=1,zone=0)
+table=0,priority=1,action=drop
+dnl
+dnl Table 1
+dnl
+table=1,priority=10,in_port=2,ct_state=+trk+est-new,udp,action=1
+table=1,priority=1,action=drop
 ])
 
 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
@@ -8265,11 +8291,17 @@ AT_CHECK([ovs-appctl vlog/set dpif_netdev:dbg 
vconn:info ofproto_dpif:info])
 
 dnl Allow new connections on p1->p2. Allow only established connections p2->p1
 AT_DATA([flows.txt], [dnl
-priority=1,action=drop
-priority=10,arp,action=normal
-priority=100,in_port=1,udp,action=ct(commit,zone=0)
-priority=100,in_port=2,ct_state=-trk,udp,action=ct(table=0,zone=0)
-priority=100,in_port=2,ct_state=+trk+est-new,udp,action=controller
+dnl Table 0
+dnl
+table=0,priority=100,arp,action=normal
+table=0,priority=10,in_port=1,udp,action=ct(commit,zone=0)
+table=0,priority=10,in_port=2,ct_state=-trk,udp,action=ct(table=1,zone=0)
+table=0,priority=1,action=drop
+dnl
+dnl Table 1
+dnl
+table=1,priority=10,in_port=2,ct_state=+trk+est-new,udp,action=controller
+table=1,priority=1,action=drop
 ])
 
 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
@@ -8295,7 +8327,7 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
 
 dnl Check this output. Only one reply must be there
 AT_CHECK([cat ofctl_monitor.log], [0], [dnl
-NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=42 
ct_state=est|rpl|trk,in_port=2 (via action) data_len=42 (unbuffered)
+NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=42 
ct_state=est|rpl|trk,in_port=2 (via action) data_len=42 (unbuffered)
 
udp,vlan_tci=0x0000,dl_src=50:54:00:00:00:0a,dl_dst=50:54:00:00:00:09,nw_src=10.1.1.2,nw_dst=10.1.1.1,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=2,tp_dst=1
 udp_csum:e9d6
 dnl
 OFPT_ECHO_REQUEST (xid=0x0): 0 bytes of payload
@@ -8347,14 +8379,20 @@ dnl Allow new connections on p1->p2 or p3->p4.
 dnl Allow only established connections p2->p1 and p4->p3
 dnl p1,p2 and p3,p4 are on different zones
 AT_DATA([flows.txt], [dnl
-priority=1,action=drop
-priority=10,arp,action=normal
-priority=100,in_port=1,udp,action=ct(commit,zone=0),controller
-priority=100,in_port=2,ct_state=-trk,udp,action=ct(table=0,zone=0)
-priority=100,in_port=2,ct_state=+trk+est-new,udp,action=controller
-priority=100,in_port=3,udp,action=ct(commit,zone=1),controller
-priority=100,in_port=4,ct_state=-trk,udp,action=ct(table=0,zone=1)
-priority=100,in_port=4,ct_state=+trk+est-new,udp,action=controller
+dnl Table 0
+dnl
+table=0,priority=100,arp,action=normal
+table=0,priority=10,in_port=1,udp,action=ct(commit,zone=0),controller
+table=0,priority=10,in_port=2,ct_state=-trk,udp,action=ct(table=1,zone=0)
+table=0,priority=10,in_port=3,udp,action=ct(commit,zone=1),controller
+table=0,priority=10,in_port=4,ct_state=-trk,udp,action=ct(table=1,zone=1)
+table=0,priority=1,action=drop
+dnl
+dnl Table 1
+dnl
+table=1,priority=10,in_port=2,ct_state=+trk+est-new,udp,action=controller
+table=1,priority=10,in_port=4,ct_state=+trk+est-new,udp,action=controller
+table=1,priority=1,action=drop
 ])
 
 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
@@ -8382,17 +8420,16 @@ AT_CHECK([cat ofctl_monitor.log], [0], [dnl
 NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=42 in_port=1 (via action) 
data_len=42 (unbuffered)
 
udp,vlan_tci=0x0000,dl_src=50:54:00:00:00:09,dl_dst=50:54:00:00:00:0a,nw_src=10.1.1.1,nw_dst=10.1.1.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=1,tp_dst=2
 udp_csum:e9d6
 dnl
-NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=42 
ct_state=est|rpl|trk,in_port=2 (via action) data_len=42 (unbuffered)
+NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=42 
ct_state=est|rpl|trk,in_port=2 (via action) data_len=42 (unbuffered)
 
udp,vlan_tci=0x0000,dl_src=50:54:00:00:00:0a,dl_dst=50:54:00:00:00:09,nw_src=10.1.1.2,nw_dst=10.1.1.1,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=2,tp_dst=1
 udp_csum:e9d6
 dnl
 NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=42 in_port=3 (via action) 
data_len=42 (unbuffered)
 
udp,vlan_tci=0x0000,dl_src=50:54:00:00:00:09,dl_dst=50:54:00:00:00:0a,nw_src=10.1.1.1,nw_dst=10.1.1.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=1,tp_dst=2
 udp_csum:e9d6
 dnl
-NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=42 
ct_state=est|rpl|trk,ct_zone=1,in_port=4 (via action) data_len=42 (unbuffered)
+NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=42 
ct_state=est|rpl|trk,ct_zone=1,in_port=4 (via action) data_len=42 (unbuffered)
 
udp,vlan_tci=0x0000,dl_src=50:54:00:00:00:0a,dl_dst=50:54:00:00:00:09,nw_src=10.1.1.2,nw_dst=10.1.1.1,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=2,tp_dst=1
 udp_csum:e9d6
 ])
 
-
 OVS_VSWITCHD_STOP
 AT_CLEANUP
 
@@ -8405,11 +8442,17 @@ AT_CHECK([ovs-appctl vlog/set dpif_netdev:dbg 
vconn:info ofproto_dpif:info])
 
 dnl Allow new connections on p1->p2. Allow only established connections p2->p1
 AT_DATA([flows.txt], [dnl
-priority=1,action=drop
-priority=10,arp,action=normal
-priority=100,ct_state=-trk,udp,action=ct(table=0,zone=0)
-priority=100,in_port=1,ct_state=+trk+new,udp,action=ct(commit,zone=0),controller
-priority=100,ct_state=+trk+est,udp,action=controller
+dnl Table 0
+dnl
+table=0,priority=100,arp,action=normal
+table=0,priority=10,ct_state=-trk,udp,action=ct(table=1,zone=0)
+table=0,priority=1,action=drop
+dnl
+dnl Table 1
+dnl
+table=1,priority=10,in_port=1,ct_state=+trk+new,udp,action=ct(commit,zone=0),controller
+table=1,priority=10,ct_state=+trk+est,udp,action=controller
+table=1,priority=1,action=drop
 ])
 
 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
@@ -8430,10 +8473,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
 
 dnl Check this output. We only see the latter two packets, not the first.
 AT_CHECK([cat ofctl_monitor.log], [0], [dnl
-NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=42 ct_state=new|trk,in_port=1 
(via action) data_len=42 (unbuffered)
+NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=42 
ct_state=new|trk,in_port=1 (via action) data_len=42 (unbuffered)
 
udp,vlan_tci=0x0000,dl_src=50:54:00:00:00:09,dl_dst=50:54:00:00:00:0a,nw_src=10.1.1.1,nw_dst=10.1.1.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=1,tp_dst=2
 udp_csum:e9d6
 dnl
-NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=42 
ct_state=est|rpl|trk,in_port=2 (via action) data_len=42 (unbuffered)
+NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=42 
ct_state=est|rpl|trk,in_port=2 (via action) data_len=42 (unbuffered)
 
udp,vlan_tci=0x0000,dl_src=50:54:00:00:00:0a,dl_dst=50:54:00:00:00:09,nw_src=10.1.1.2,nw_dst=10.1.1.1,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=2,tp_dst=1
 udp_csum:e9d6
 ])
 
@@ -8447,12 +8490,18 @@ add_of_ports br0 1 2
 
 dnl Allow any traffic from ns0->ns1. Only allow nd, return traffic from 
ns1->ns0.
 AT_DATA([flows.txt], [dnl
-priority=1,action=drop
-priority=10,arp,action=normal
-priority=100,in_port=1,ct_state=-trk,udp,action=ct(commit,zone=0,table=0)
-priority=100,in_port=1,ct_state=+trk,actions=controller
-priority=100,in_port=2,ct_state=-trk,action=ct(table=0,zone=0)
-priority=100,in_port=2,ct_state=+trk-inv-new,action=controller
+dnl Table 0
+dnl
+table=0,priority=100,arp,action=normal
+table=0,priority=10,in_port=1,ct_state=-trk,udp,action=ct(commit,table=1)
+table=0,priority=10,in_port=2,ct_state=-trk,action=ct(table=1)
+table=0,priority=1,action=drop
+dnl
+dnl Table 1
+dnl
+table=1,priority=10,in_port=1,ct_state=+trk,action=controller
+table=1,priority=10,in_port=2,ct_state=+trk-inv-new,action=controller
+table=1,priority=1,action=drop
 ])
 
 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
@@ -8461,23 +8510,23 @@ AT_CAPTURE_FILE([ofctl_monitor.log])
 AT_CHECK([ovs-ofctl monitor br0 65534 invalid_ttl -P nxt_packet_in --detach 
--no-chdir --pidfile 2> ofctl_monitor.log])
 
 dnl 1. Send an ICMP port unreach reply for port 8738, without any previous 
request
-AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 2 ct\(table=0,zone=0\) 
'f64c473528c9c6f54ecb72db080045c0003d2e8700004001f351ac100004ac1000030303553f0000000045000021317040004011b138ac100003ac10000411112222000da5a06369616f0a'])
+AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 2 ct\(table=1\) 
'f64c473528c9c6f54ecb72db080045c0003d2e8700004001f351ac100004ac1000030303553f0000000045000021317040004011b138ac100003ac10000411112222000da5a06369616f0a'])
 
 dnl 2. Send and UDP packet to port 5555
-AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 1 ct\(commit,zone=0,table=0\) 
'c6f94ecb72dbe64c473528c9080045000021317040004011b138ac100001ac100002a28e15b3000d20966369616f0a'])
+AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 1 ct\(commit,table=1\) 
'c6f94ecb72dbe64c473528c9080045000021317040004011b138ac100001ac100002a28e15b3000d20966369616f0a'])
 
 dnl 3. Send an ICMP port unreach reply for port 5555, related to the first 
packet
-AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 2 ct\(table=0,zone=0\) 
'e64c473528c9c6f94ecb72db080045c0003d2e8700004001f355ac100002ac1000010303553f0000000045000021317040004011b138ac100001ac100002a28e15b3000d20966369616f0a'])
+AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 2 ct\(table=1\) 
'e64c473528c9c6f94ecb72db080045c0003d2e8700004001f355ac100002ac1000010303553f0000000045000021317040004011b138ac100001ac100002a28e15b3000d20966369616f0a'])
 
 OVS_WAIT_UNTIL([test `wc -l < ofctl_monitor.log` -ge 4])
 OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
 
 dnl Check this output. We only see the first and the last packet
 AT_CHECK([cat ofctl_monitor.log], [0], [dnl
-NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=47 ct_state=new|trk,in_port=1 
(via action) data_len=47 (unbuffered)
+NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=47 
ct_state=new|trk,in_port=1 (via action) data_len=47 (unbuffered)
 
udp,vlan_tci=0x0000,dl_src=e6:4c:47:35:28:c9,dl_dst=c6:f9:4e:cb:72:db,nw_src=172.16.0.1,nw_dst=172.16.0.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=41614,tp_dst=5555
 udp_csum:2096
 dnl
-NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=75 
ct_state=rel|rpl|trk,in_port=2 (via action) data_len=75 (unbuffered)
+NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=75 
ct_state=rel|rpl|trk,in_port=2 (via action) data_len=75 (unbuffered)
 
icmp,vlan_tci=0x0000,dl_src=c6:f9:4e:cb:72:db,dl_dst=e6:4c:47:35:28:c9,nw_src=172.16.0.2,nw_dst=172.16.0.1,nw_tos=192,nw_ecn=0,nw_ttl=64,icmp_type=3,icmp_code=3
 icmp_csum:553f
 ])
 
@@ -8493,13 +8542,19 @@ AT_CHECK([ovs-appctl vlog/set dpif_netdev:dbg 
vconn:info ofproto_dpif:info])
 
 dnl Allow new connections on p1->p2. Allow only established connections p2->p1
 AT_DATA([flows.txt], [dnl
-priority=1,action=drop
-priority=10,arp,action=normal
-priority=100,in_port=1,ct_state=-trk,udp,tp_src=1,action=ct(commit,exec(set_field:1->ct_mark)),controller
-priority=100,in_port=1,ct_state=-trk,udp,tp_src=3,action=ct(commit,exec(set_field:3->ct_mark)),controller
-priority=100,in_port=1,ct_state=-trk,udp,tp_src=5,action=ct(commit,exec(set_field:5->ct_mark)),controller
-priority=100,in_port=2,ct_state=-trk,actions=ct(table=0)
-priority=100,ct_state=+trk+rpl,ct_mark=0/4,actions=controller
+dnl Table 0
+dnl
+table=0,priority=100,arp,action=normal
+table=0,priority=10,in_port=1,ct_state=-trk,udp,tp_src=1,action=ct(commit,exec(set_field:1->ct_mark)),controller
+table=0,priority=10,in_port=1,ct_state=-trk,udp,tp_src=3,action=ct(commit,exec(set_field:3->ct_mark)),controller
+table=0,priority=10,in_port=1,ct_state=-trk,udp,tp_src=5,action=ct(commit,exec(set_field:5->ct_mark)),controller
+table=0,priority=10,in_port=2,ct_state=-trk,actions=ct(table=1)
+table=0,priority=1,action=drop
+dnl
+dnl Table 1
+dnl
+table=1,priority=100,ct_state=+trk+rpl,ct_mark=0/4,actions=controller
+table=1,priority=1,action=drop
 ])
 
 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
@@ -8529,10 +8584,10 @@ dnl
 NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=42 ct_mark=0x5,in_port=1 (via 
action) data_len=42 (unbuffered)
 
udp,vlan_tci=0x0000,dl_src=50:54:00:00:00:09,dl_dst=50:54:00:00:00:0a,nw_src=10.1.1.1,nw_dst=10.1.1.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=5,tp_dst=6
 udp_csum:e9ce
 dnl
-NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=42 
ct_state=est|rpl|trk,ct_mark=0x1,in_port=2 (via action) data_len=42 (unbuffered)
+NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=42 
ct_state=est|rpl|trk,ct_mark=0x1,in_port=2 (via action) data_len=42 (unbuffered)
 
udp,vlan_tci=0x0000,dl_src=50:54:00:00:00:0a,dl_dst=50:54:00:00:00:09,nw_src=10.1.1.2,nw_dst=10.1.1.1,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=2,tp_dst=1
 udp_csum:e9d6
 dnl
-NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=42 
ct_state=est|rpl|trk,ct_mark=0x3,in_port=2 (via action) data_len=42 (unbuffered)
+NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=42 
ct_state=est|rpl|trk,ct_mark=0x3,in_port=2 (via action) data_len=42 (unbuffered)
 
udp,vlan_tci=0x0000,dl_src=50:54:00:00:00:0a,dl_dst=50:54:00:00:00:09,nw_src=10.1.1.2,nw_dst=10.1.1.1,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4,tp_dst=3
 udp_csum:e9d2
 ])
 
@@ -8548,12 +8603,17 @@ AT_CHECK([ovs-appctl vlog/set dpif_netdev:dbg 
vconn:info ofproto_dpif:info])
 
 dnl Allow new connections on p1->p2. Allow only established connections p2->p1
 AT_DATA([flows.txt], [dnl
-priority=1,action=drop
-priority=10,arp,action=normal
-priority=100,in_port=1,ct_state=-trk,udp,tp_src=1,action=ct(commit,exec(set_field:000000000000000001->ct_label))
-priority=100,in_port=1,ct_state=-trk,udp,tp_src=3,action=ct(commit,exec(set_field:000000000000000002->ct_label))
-priority=100,in_port=2,ct_state=-trk,actions=ct(table=0)
-priority=100,ct_state=+trk+rpl,actions=controller
+dnl Table 0
+dnl
+table=0,priority=100,arp,action=normal
+table=0,priority=10,in_port=1,ct_state=-trk,udp,tp_src=1,action=ct(commit,exec(set_field:000000000000000001->ct_label))
+table=0,priority=10,in_port=1,ct_state=-trk,udp,tp_src=3,action=ct(commit,exec(set_field:000000000000000002->ct_label))
+table=0,priority=10,in_port=2,ct_state=-trk,actions=ct(table=1)
+dnl
+dnl Table 1
+dnl
+table=1,priority=10,ct_state=+trk+rpl,actions=controller
+table=1,priority=1,action=drop
 ])
 
 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
@@ -8572,10 +8632,10 @@ OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
 
 dnl Check this output.
 AT_CHECK([cat ofctl_monitor.log], [0], [dnl
-NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=42 
ct_state=est|rpl|trk,ct_label=0x1,in_port=2 (via action) data_len=42 
(unbuffered)
+NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=42 
ct_state=est|rpl|trk,ct_label=0x1,in_port=2 (via action) data_len=42 
(unbuffered)
 
udp,vlan_tci=0x0000,dl_src=50:54:00:00:00:0a,dl_dst=50:54:00:00:00:09,nw_src=10.1.1.2,nw_dst=10.1.1.1,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=2,tp_dst=1
 udp_csum:e9d6
 dnl
-NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=42 
ct_state=est|rpl|trk,ct_label=0x2,in_port=2 (via action) data_len=42 
(unbuffered)
+NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x0 total_len=42 
ct_state=est|rpl|trk,ct_label=0x2,in_port=2 (via action) data_len=42 
(unbuffered)
 
udp,vlan_tci=0x0000,dl_src=50:54:00:00:00:0a,dl_dst=50:54:00:00:00:09,nw_src=10.1.1.2,nw_dst=10.1.1.1,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=4,tp_dst=3
 udp_csum:e9d2
 ])
 
@@ -8591,11 +8651,26 @@ AT_CHECK([ovs-appctl vlog/set dpif_netdev:dbg 
vconn:info ofproto_dpif:info])
 
 dnl Allow new connections on p1->p2. Allow only established connections p2->p1
 AT_DATA([flows.txt], [dnl
-priority=1,action=drop
-priority=10,arp,action=normal
-priority=100,in_port=1,ct_state=-trk,udp,tp_src=1,action=ct(commit,exec(set_field:1->ct_label)),2
-priority=100,in_port=2,ct_state=-trk,actions=ct(table=0)
-priority=100,ct_state=+trk+rpl,ct_label=0x1,actions=1
+dnl The flows are in two separate tables for two reasons:
+dnl * To make the pipeline more clear.
+dnl * To make megaflows more consistent (we check megaflows below).  The
+dnl   unwildcarding in megaflows depends on the internal ordering of the
+dnl   subtables, which are sorted using the system qsort().  qsort()
+dnl   is provided by libc and may or may not be stable, so we can't rely
+dnl   on that.  By having separate tables we have more control over which
+dnl   subtables are visited, meaning consistent megaflows.
+dnl
+dnl Table 0
+dnl
+table=0,priority=100,arp,action=normal
+table=0,priority=10,in_port=1,ct_state=-trk,udp,tp_src=1,action=ct(commit,exec(set_field:1->ct_label)),2
+table=0,priority=10,in_port=2,ct_state=-trk,actions=ct(table=1)
+table=0,priority=1,action=drop
+dnl
+dnl Table 1
+dnl
+table=1,priority=10,ct_state=+trk+rpl,ct_label=0x1,actions=1
+table=1,priority=1,action=drop
 ])
 
 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
@@ -8645,17 +8720,22 @@ AT_CHECK([ovs-appctl vlog/set dpif_netdev:dbg 
vconn:info ofproto_dpif:info])
 
 dnl Allow new connections on p1->p2. Allow only established connections p2->p1
 AT_DATA([flows.txt], [dnl
-priority=1,action=drop
-priority=10,arp,action=normal
-in_port=1,ip,ct_state=-trk,action=ct(commit,table=0)
+dnl Table 0
+dnl
+table=0,priority=100,arp,action=normal
+table=0,priority=10,in_port=1,ip,ct_state=-trk,action=ct(commit,table=1)
+table=0,priority=10,in_port=2,ip,ct_state=-trk,action=ct(table=1)
+table=0,priority=1,action=drop
+dnl
+dnl Table 1
+dnl
 dnl The following two flows are separated to explicitly count the packets
 dnl that create a new connection
-priority=100,cookie=0x1,in_port=1,ip,ct_state=+trk+new-inv-rpl,action=2
-priority=100,in_port=1,ip,ct_state=+trk-new-inv-rpl,action=2
+table=1,priority=100,cookie=0x1,in_port=1,ip,ct_state=+trk+new-inv-rpl,action=2
+table=1,priority=100,in_port=1,ip,ct_state=+trk-new-inv-rpl,action=2
 dnl
-priority=100,in_port=2,ip,ct_state=-trk,action=ct(table=0)
-priority=100,in_port=2,ip,ct_state=+trk+est+rpl-new-inv,action=1
-ip,ct_state=+trk+inv,action=drop
+table=1,priority=100,in_port=2,ip,ct_state=+trk+est+rpl-new-inv,action=1
+table=1,ip,ct_state=+trk+inv,action=drop
 ])
 
 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
@@ -8704,12 +8784,17 @@ AT_CHECK([ovs-appctl vlog/set dpif_netdev:dbg 
vconn:info ofproto_dpif:info])
 
 dnl Allow new connections on p1->p2. Allow only established connections p2->p1
 AT_DATA([flows.txt], [dnl
-priority=1,action=drop
-priority=10,arp,action=normal
-priority=100,in_port=1,tcp,ct_state=-trk,action=ct(commit,zone=0,table=0)
-priority=100,in_port=2,tcp,ct_state=-trk,action=ct(table=0,zone=0)
-priority=100,in_port=2,tcp,ct_state=+trk+est-new,action=drop
-cookie=0x1,ip,ct_state=+trk+inv,action=controller
+dnl Table 0
+dnl
+table=0,priority=100,arp,action=normal
+table=0,priority=10,in_port=1,tcp,ct_state=-trk,action=ct(commit,table=1)
+table=0,priority=10,in_port=2,tcp,ct_state=-trk,action=ct(table=1)
+table=0,priority=1,action=drop
+dnl
+dnl Table 1
+dnl
+table=1,priority=10,cookie=0x1,ip,ct_state=+trk+inv,action=controller
+table=1,priority=1,action=drop
 ])
 
 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
-- 
2.8.1

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to