]> git.proxmox.com Git - mirror_ovs.git/blobdiff - tests/ofproto-dpif.at
ofproto-dpif-xlate: Fix mirroring interaction with recirculation.
[mirror_ovs.git] / tests / ofproto-dpif.at
index fbc6fd9d8d08830f12e557a3eaac971eccf7583b..58c426b0a6a50336f6a62158e8157025b0be7344 100644 (file)
@@ -270,7 +270,7 @@ table=2 in_port=1,icmp6,icmpv6_type=135 actions=set_field:fe80::4->nd_target,set
 AT_CHECK([ovs-ofctl -O OpenFlow12 add-flows br0 flows.txt])
 AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,icmp6,ipv6_src=fe80::1,ipv6_dst=fe80::2,nw_tos=0,nw_ttl=128,icmpv6_type=135,nd_target=fe80::2020,nd_sll=66:55:44:33:22:11'], [0], [stdout])
 AT_CHECK([tail -4 stdout], [0],
-  [Megaflow: recirc_id=0,icmp6,in_port=1,nw_frag=no,icmp_type=135,icmp_code=0x0/0xff,nd_target=fe80::2020,nd_sll=66:55:44:33:22:11
+  [Megaflow: recirc_id=0,icmp6,in_port=1,nw_frag=no,icmp_type=0x87/0xff,icmp_code=0x0/0xff,nd_target=fe80::2020,nd_sll=66:55:44:33:22:11
 Datapath actions: 10,set(nd(target=fe80::4,sll=cc:cc:cc:cc:cc:cc)),11,set(nd(target=fe80::3,sll=aa:aa:aa:aa:aa:aa)),13
 This flow is handled by the userspace slow path because it:
        - Uses action(s) not supported by datapath.
@@ -294,13 +294,15 @@ Datapath actions: 10,set(tcp(src=91)),11
 OVS_VSWITCHD_STOP
 AT_CLEANUP
 
-AT_SETUP([ofproto-dpif - group chaining not supported])
+AT_SETUP([ofproto-dpif - group chaining])
 OVS_VSWITCHD_START
 ADD_OF_PORTS([br0], [1], [10], [11])
-AT_CHECK([ovs-ofctl -O OpenFlow12 add-group br0 'group_id=1234,type=all,bucket=output:10,set_field:192.168.3.90->ip_src,group:123,bucket=output:11'],
-  [1], [], [stderr])
-AT_CHECK([STRIP_XIDS stderr | sed 1q], [0],
-  [OFPT_ERROR (OF1.2): OFPGMFC_CHAINING_UNSUPPORTED
+AT_CHECK([ovs-ofctl -O OpenFlow12 add-group br0 'group_id=1234,type=all,bucket=set_field:192.168.3.90->ip_src,group:123,bucket=output:11'])
+AT_CHECK([ovs-ofctl -O OpenFlow12 add-group br0 'group_id=123,type=all,bucket=output:10'])
+AT_CHECK([ovs-ofctl -O OpenFlow12 add-flow br0 'ip actions=group:1234'])
+AT_CHECK([ovs-appctl ofproto/trace br0 'in_port=1,dl_src=50:54:00:00:00:05,dl_dst=50:54:00:00:00:07,dl_type=0x0800,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=1,nw_tos=0,nw_ttl=128,icmp_type=8,icmp_code=0'], [0], [stdout])
+AT_CHECK([tail -1 stdout], [0],
+  [Datapath actions: set(ipv4(src=192.168.3.90)),10,set(ipv4(src=192.168.0.1)),11
 ])
 OVS_VSWITCHD_STOP
 AT_CLEANUP
@@ -630,8 +632,9 @@ table=2,priority=10                  actions=5,goto_table(3)
 table=3,priority=20,xreg0=2  actions=6,goto_table(4)
 table=3,priority=10          actions=7,goto_table(4)
 
-# Verify that adding a group action unsets actset_output.
-table=4 actions=write_actions(group(5)),goto_table(5)
+# Verify that adding a group action unsets actset_output,
+# even if output follows group.
+table=4 actions=write_actions(group(5),output(10)),goto_table(5)
 table=5,priority=20,actset_output=unset  actions=8,goto_table(6)
 table=5,priority=10                      actions=9,goto_table(6)
 
@@ -958,7 +961,7 @@ AT_CHECK([ovs-ofctl -OOpenFlow12 add-flow br0 'table=0 actions=goto_table(1)'])
 AT_CHECK([ovs-ofctl monitor -P openflow10 br0 65534 --detach --no-chdir --pidfile 2> ofctl_monitor.log])
 
 for i in 1 2 3 ; do
-    ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=9),tcp_flags(urg,rst)'
+    ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=9),tcp_flags(urg|rst)'
 done
 OVS_WAIT_UNTIL([test `wc -l < ofctl_monitor.log` -ge 6])
 OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
@@ -3951,13 +3954,13 @@ AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
 flow="in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)"
 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow"], [0], [stdout])
 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
-  [Datapath actions: 2,3
+  [Datapath actions: 3,2
 ])
 
 flow="in_port(2),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)"
 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow"], [0], [stdout])
 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
-  [Datapath actions: 1,3
+  [Datapath actions: 3,1
 ])
 
 OVS_VSWITCHD_STOP
@@ -3981,7 +3984,7 @@ AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
 flow="in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)"
 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow"], [0], [stdout])
 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
-  [Datapath actions: 2,3
+  [Datapath actions: 3,2
 ])
 
 flow="in_port(2),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)"
@@ -4071,7 +4074,7 @@ AT_CHECK_UNQUOTED([tail -1 stdout], [0],
 flow="in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x8100),vlan(vid=11,pcp=0),encap(eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0))"
 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow"], [0], [stdout])
 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
-  [Datapath actions: 2,3
+  [Datapath actions: 3,2
 ])
 
 OVS_VSWITCHD_STOP
@@ -4095,13 +4098,13 @@ AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
 flow="in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)"
 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow"], [0], [stdout])
 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
-  [Datapath actions: push_vlan(vid=17,pcp=0),2,pop_vlan,3
+  [Datapath actions: 3,push_vlan(vid=17,pcp=0),2
 ])
 
 flow="in_port(2),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)"
 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow"], [0], [stdout])
 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
-  [Datapath actions: 1,3
+  [Datapath actions: 3,1
 ])
 
 OVS_VSWITCHD_STOP
@@ -4141,6 +4144,34 @@ AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
 OVS_VSWITCHD_STOP
 AT_CLEANUP
 
+# This test verifies that mirror state is preserved across recirculation.
+#
+# Otherwise, post-recirculation the ingress and the output to port 4
+# would cause the packet to be mirrored to port 3 a second time.
+AT_SETUP([ofproto-dpif - mirroring with recirculation])
+OVS_VSWITCHD_START
+ADD_OF_PORTS([br0], 1, 2, 3, 4)
+ovs-vsctl \
+        set Bridge br0 mirrors=@m --\
+        --id=@p3 get Port p3 --\
+        --id=@m create Mirror name=mymirror select_all=true output_port=@p3
+
+AT_DATA([flows.txt], [dnl
+in_port=1 actions=2,debug_recirc,4
+])
+AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
+
+flow="in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)"
+AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], [stdout])
+AT_CHECK_UNQUOTED([tail -1 stdout], [0], [Datapath actions: 3,2,recirc(0x1)
+])
+AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow,recirc_id(1)" -generate], [0], [stdout])
+AT_CHECK_UNQUOTED([tail -1 stdout], [0], [Datapath actions: 4
+])
+
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
 # Two testcases below are for the ofproto/trace command
 # The first one tests all correct syntax:
 # ofproto/trace [dp_name] odp_flow [-generate|packet]
@@ -4695,14 +4726,11 @@ AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/ *[[0-9]]\{1,\}$//' | sort],
 OVS_VSWITCHD_STOP
 AT_CLEANUP
 
-# CHECK_SFLOW_SAMPLING_PACKET(LOOPBACK_ADDR, ADDR_WITHOUT_BRACKETS)
+# CHECK_SFLOW_SAMPLING_PACKET(LOOPBACK_ADDR)
 #
 # Test that sFlow samples packets correctly using IPv4/IPv6 sFlow collector
-#
-# IP_VERSION_TYPE is used in AT_SETUP
 m4_define([CHECK_SFLOW_SAMPLING_PACKET],
-  [AT_SETUP([ofproto-dpif - sFlow packet sampling - $2 collector])
-  AT_XFAIL_IF([test "$IS_WIN32" = "yes"])
+  [AT_XFAIL_IF([test "$IS_WIN32" = "yes"])
   OVS_VSWITCHD_START([set Bridge br0 fail-mode=standalone])
 
   ON_EXIT([kill `cat test-sflow.pid`])
@@ -5019,14 +5047,19 @@ PORTNAME
        portName=p2
 PORTNAME
        portName=p2
-])
-  AT_CLEANUP])
+])])
 
-CHECK_SFLOW_SAMPLING_PACKET([127.0.0.1], [IPv4])
-CHECK_SFLOW_SAMPLING_PACKET([[[::1]]], [IPv6])
+AT_SETUP([ofproto-dpif - sFlow packet sampling - IPv4 collector])
+CHECK_SFLOW_SAMPLING_PACKET([127.0.0.1])
+AT_CLEANUP
+
+AT_SETUP([ofproto-dpif - sFlow packet sampling - IPv6 collector])
+AT_SKIP_IF([test $HAVE_IPV6 = no])
+CHECK_SFLOW_SAMPLING_PACKET([[[::1]]])
+AT_CLEANUP
 
 dnl Test sFlow LAG structures
-AT_SETUP([ofproto-dpif - sFlow LACP structures])
+AT_SETUP([ofproto-dpif - sFlow packet sampling - LACP structures])
 AT_SKIP_IF([test "$IS_WIN32" = "yes"])
 OVS_VSWITCHD_START([dnl
                    add-bond br0 bond p1 p2 --                          \
@@ -5083,18 +5116,278 @@ LACPCOUNTERS
 
 AT_CLEANUP
 
-# CHECK_NETFLOW_EXPIRATION(LOOPBACK_ADDR, IP_VERSION_TYPE)
+AT_SETUP([ofproto-dpif - sFlow packet sampling - tunnel set])
+AT_XFAIL_IF([test "$IS_WIN32" = "yes"])
+OVS_VSWITCHD_START([set Bridge br0 fail-mode=standalone])
+
+dnl set up sFlow logging
+dnl ON_EXIT([kill `cat test-sflow.pid`])
+AT_CHECK([ovstest test-sflow --log-file --detach --no-chdir --pidfile 0:127.0.0.1 > sflow.log], [0], [], [ignore])
+AT_CAPTURE_FILE([sflow.log])
+SFLOW_PORT=`parse_listening_port < test-sflow.log`
+ovs-appctl time/stop
+
+OVS_VSWITCHD_DISABLE_TUNNEL_PUSH_POP
+AT_CHECK([ovs-vsctl add-port br0 gre0 -- set Interface gre0 type=gre \
+                   options:remote_ip=1.1.1.1 options:key=456 ofport_request=3])
+AT_CHECK([ovs-vsctl add-port br0 p1 -- set Interface p1 type=dummy ofport_request=4])
+
+AT_CHECK([ovs-ofctl add-flow br0 action=3])
+
+dnl enable sflow
+ovs-vsctl \
+   set Bridge br0 sflow=@sf -- \
+   --id=@sf create sflow targets=\"127.0.0.1:$SFLOW_PORT\" \
+     header=128 sampling=1 polling=0
+
+dnl introduce a packet that will be flooded to the tunnel
+AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(4),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.10.10.2,dst=10.10.10.1,proto=1,tos=1,ttl=128,frag=no),icmp(type=8,code=0)'])
+
+dnl sleep long enough to get the sFlow datagram flushed out (may be delayed for up to 1 second)
+for i in `seq 1 30`; do
+    ovs-appctl time/warp 100
+done
+
+ovs-appctl -t test-sflow exit
+
+AT_CHECK_UNQUOTED([[sort sflow.log | $EGREP 'HEADER|ERROR' | sed 's/ /\
+       /g']], [0], [dnl
+HEADER
+       dgramSeqNo=1
+       ds=127.0.0.1>2:1000
+       fsSeqNo=1
+       tunnel4_out_length=0
+       tunnel4_out_protocol=47
+       tunnel4_out_src=0.0.0.0
+       tunnel4_out_dst=1.1.1.1
+       tunnel4_out_src_port=0
+       tunnel4_out_dst_port=0
+       tunnel4_out_tcp_flags=0
+       tunnel4_out_tos=1
+       tunnel_out_vni=456
+       in_vlan=0
+       in_priority=0
+       out_vlan=0
+       out_priority=0
+       meanSkip=1
+       samplePool=1
+       dropEvents=0
+       in_ifindex=0
+       in_format=0
+       out_ifindex=1
+       out_format=2
+       hdr_prot=1
+       pkt_len=64
+       stripped=4
+       hdr_len=60
+       hdr=50-54-00-00-00-0A-50-54-00-00-00-09-08-00-45-01-00-1C-00-00-00-00-80-01-12-CA-0A-0A-0A-02-0A-0A-0A-01-08-00-F7-FF-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
+])
+
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
+AT_SETUP([ofproto-dpif - sFlow packet sampling - tunnel push])
+AT_XFAIL_IF([test "$IS_WIN32" = "yes"])
+
+OVS_VSWITCHD_START([add-port br0 p0 -- set Interface p0 type=dummy ofport_request=1 options:ifindex=1010])
+
+dnl set up sFlow logging
+dnl ON_EXIT([kill `cat test-sflow.pid`])
+AT_CHECK([ovstest test-sflow --log-file --detach --no-chdir --pidfile 0:127.0.0.1 > sflow.log], [0], [], [ignore])
+AT_CAPTURE_FILE([sflow.log])
+SFLOW_PORT=`parse_listening_port < test-sflow.log`
+ovs-appctl time/stop
+
+AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg])
+AT_CHECK([ovs-vsctl add-br int-br -- set bridge int-br datapath_type=dummy], [0])
+AT_CHECK([ovs-vsctl -- add-port int-br t1 -- set Interface t1 type=gre \
+                       options:remote_ip=1.1.2.92 options:key=456 ofport_request=4\
+                   -- add-port int-br vm1 -- set Interface vm1 type=dummy \
+                      options:ifindex=2011 ofport_request=5
+                       ], [0])
+
+AT_CHECK([ovs-appctl dpif/show], [0], [dnl
+dummy@ovs-dummy: hit:0 missed:0
+       br0:
+               br0 65534/100: (dummy)
+               p0 1/1: (dummy: ifindex=1010)
+       int-br:
+               int-br 65534/2: (dummy)
+               t1 4/4: (gre: key=456, remote_ip=1.1.2.92)
+               vm1 5/3: (dummy: ifindex=2011)
+])
+
+dnl set up route to 1.1.2.92 via br0 and action=normal
+AT_CHECK([ovs-appctl ovs/route/add 1.1.2.92/24 br0], [0], [OK
+])
+AT_CHECK([ovs-appctl ovs/route/add 192.168.0.0/16 br0], [0], [OK
+])
+AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 1.1.2.88/24], [0], [OK
+])
+AT_CHECK([ovs-ofctl add-flow br0 action=normal])
+
+dnl Prime ARP Cache for 1.1.2.92
+AT_CHECK([ovs-appctl netdev-dummy/receive br0 'recirc_id(0),in_port(100),eth(src=f8:bc:12:44:34:b6,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=1.1.2.92,tip=1.1.2.88,op=1,sha=f8:bc:12:44:34:b6,tha=00:00:00:00:00:00)'])
+
+dnl configure sflow on int-br only
+ovs-vsctl \
+   set Bridge int-br sflow=@sf -- \
+   --id=@sf create sflow targets=\"127.0.0.1:$SFLOW_PORT\" \
+     header=128 sampling=1 polling=0
+
+dnl add rule for int-br to force packet onto tunnel. There is no ifindex
+dnl for this port so the sFlow output will just report that it went to
+dnl 1 output (out_format=2, out_ifindex=1)
+AT_CHECK([ovs-ofctl add-flow int-br "actions=4"])
+
+AT_CHECK([ovs-appctl netdev-dummy/receive vm1 'in_port(3),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=192.168.1.1,dst=192.168.2.2,proto=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)'])
+
+dnl sleep long enough to get the sFlow datagram flushed out (may be delayed for up to 1 second)
+for i in `seq 1 30`; do
+    ovs-appctl time/warp 100
+done
+
+ovs-appctl -t test-sflow exit
+
+AT_CHECK_UNQUOTED([[sort sflow.log | $EGREP 'HEADER|ERROR' | sed 's/ /\
+       /g']], [0], [dnl
+HEADER
+       dgramSeqNo=1
+       ds=127.0.0.1>2:1000
+       fsSeqNo=1
+       tunnel4_out_length=0
+       tunnel4_out_protocol=47
+       tunnel4_out_src=1.1.2.88
+       tunnel4_out_dst=1.1.2.92
+       tunnel4_out_src_port=0
+       tunnel4_out_dst_port=0
+       tunnel4_out_tcp_flags=0
+       tunnel4_out_tos=0
+       tunnel_out_vni=456
+       in_vlan=0
+       in_priority=0
+       out_vlan=0
+       out_priority=0
+       meanSkip=1
+       samplePool=1
+       dropEvents=0
+       in_ifindex=2011
+       in_format=0
+       out_ifindex=1
+       out_format=2
+       hdr_prot=1
+       pkt_len=64
+       stripped=4
+       hdr_len=60
+       hdr=50-54-00-00-00-0A-50-54-00-00-00-05-08-00-45-00-00-1C-00-00-00-00-80-01-B6-8D-C0-A8-01-01-C0-A8-02-02-08-00-F7-FF-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
+])
+
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
+AT_SETUP([ofproto-dpif - sFlow packet sampling - MPLS])
+AT_XFAIL_IF([test "$IS_WIN32" = "yes"])
+OVS_VSWITCHD_START
+AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg])
+ADD_OF_PORTS([br0], [1], [2])
+AT_DATA([flows.txt], [dnl
+table=0 dl_src=50:54:00:00:00:09 actions=push_mpls:0x8847,set_mpls_label:789,set_mpls_tc:4,set_mpls_ttl:32,2
+table=0 dl_src=50:54:00:00:00:0b actions=pop_mpls:0x0800,2
+])
+AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
+
+dnl set up sFlow logging
+dnl ON_EXIT([kill `cat test-sflow.pid`])
+AT_CHECK([ovstest test-sflow --log-file --detach --no-chdir --pidfile 0:127.0.0.1 > sflow.log], [0], [], [ignore])
+AT_CAPTURE_FILE([sflow.log])
+SFLOW_PORT=`parse_listening_port < test-sflow.log`
+ovs-appctl time/stop
+
+dnl configure sflow
+ovs-vsctl \
+   set Bridge br0 sflow=@sf -- \
+   --id=@sf create sflow targets=\"127.0.0.1:$SFLOW_PORT\" \
+     header=128 sampling=1 polling=0
+
+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(0x8847),mpls(label=11,tc=3,ttl=64,bos=1)'])
+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)'])
+
+dnl sleep long enough to get the sFlow datagram flushed out (may be delayed for up to 1 second)
+for i in `seq 1 30`; do
+    ovs-appctl time/warp 100
+done
+
+ovs-appctl -t test-sflow exit
+
+AT_CHECK_UNQUOTED([[sort sflow.log | $EGREP 'HEADER|ERROR' | sed 's/ /\
+       /g']], [0], [dnl
+HEADER
+       dgramSeqNo=1
+       ds=127.0.0.1>2:1000
+       fsSeqNo=1
+       mpls_label_0=789
+       mpls_tc_0=4
+       mpls_ttl_0=32
+       mpls_bos_0=0
+       mpls_label_1=11
+       mpls_tc_1=3
+       mpls_ttl_1=64
+       mpls_bos_1=1
+       in_vlan=0
+       in_priority=0
+       out_vlan=0
+       out_priority=0
+       meanSkip=1
+       samplePool=1
+       dropEvents=0
+       in_ifindex=0
+       in_format=0
+       out_ifindex=1
+       out_format=2
+       hdr_prot=1
+       pkt_len=64
+       stripped=4
+       hdr_len=60
+       hdr=50-54-00-00-00-0A-50-54-00-00-00-09-88-47-00-00-B7-40-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
+HEADER
+       dgramSeqNo=1
+       ds=127.0.0.1>2:1000
+       fsSeqNo=2
+       mpls_label_0=789
+       mpls_tc_0=4
+       mpls_ttl_0=32
+       mpls_bos_0=1
+       in_vlan=0
+       in_priority=0
+       out_vlan=0
+       out_priority=0
+       meanSkip=1
+       samplePool=2
+       dropEvents=0
+       in_ifindex=0
+       in_format=0
+       out_ifindex=1
+       out_format=2
+       hdr_prot=1
+       pkt_len=64
+       stripped=4
+       hdr_len=60
+       hdr=50-54-00-00-00-0A-50-54-00-00-00-09-08-00-45-00-00-14-00-00-00-00-00-00-BA-EB-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
+])
+
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
+
+# CHECK_NETFLOW_EXPIRATION(LOOPBACK_ADDR)
 #
 # Test that basic NetFlow reports flow statistics correctly:
 # The initial packet of a flow are correctly accounted.
 # Later packets within a flow are correctly accounted.
 # Flow actions changing (in this case, due to MAC learning)
 # cause a record to be sent.
-#
-# IP_VERSION_TYPE is used in AT_SETUP
 m4_define([CHECK_NETFLOW_EXPIRATION],
-  [AT_SETUP([ofproto-dpif - NetFlow flow expiration - $2 collector])
-  OVS_VSWITCHD_START([set Bridge br0 fail-mode=standalone])
+  [OVS_VSWITCHD_START([set Bridge br0 fail-mode=standalone])
   ADD_OF_PORTS([br0], 1, 2)
 
   ovs-appctl time/stop
@@ -5127,22 +5420,22 @@ m4_define([CHECK_NETFLOW_EXPIRATION],
 
   combined=`grep "192.168.0.2 > 192.168.0.1, if 2 > 1, 2 pkts, 120 bytes, ICMP 0:0" netflow.log | wc -l`
   separate=`grep "192.168.0.2 > 192.168.0.1, if 2 > 1, 1 pkts, 60 bytes, ICMP 0:0" netflow.log | wc -l`
-  AT_CHECK([test $separate = 2 || test $combined = 1], [0])
+  AT_CHECK([test $separate = 2 || test $combined = 1], [0])])
 
-  AT_CLEANUP])
+AT_SETUP([ofproto-dpif - NetFlow flow expiration - IPv4 collector])
+CHECK_NETFLOW_EXPIRATION([127.0.0.1])
+AT_CLEANUP
 
-CHECK_NETFLOW_EXPIRATION([127.0.0.1], [IPv4])
-CHECK_NETFLOW_EXPIRATION([[[::1]]], [IPv6])
+AT_SETUP([ofproto-dpif - NetFlow flow expiration - IPv6 collector])
+AT_SKIP_IF([test $HAVE_IPV6 = no])
+CHECK_NETFLOW_EXPIRATION([[[::1]]])
+AT_CLEANUP
 
-# CHECK_NETFLOW_ACTIVE_EXPIRATION(LOOPBACK_ADDR, IP_VERSION_TYPE)
+# CHECK_NETFLOW_ACTIVE_EXPIRATION(LOOPBACK_ADDR)
 #
 # Test that basic NetFlow reports active expirations correctly.
-#
-# IP_VERSION_TYPE is used in AT_SETUP
 m4_define([CHECK_NETFLOW_ACTIVE_EXPIRATION],
-  [AT_SETUP([ofproto-dpif - NetFlow active expiration - $2 collector])
-
-  OVS_VSWITCHD_START([set Bridge br0 fail-mode=standalone])
+  [OVS_VSWITCHD_START([set Bridge br0 fail-mode=standalone])
   ADD_OF_PORTS([br0], 1, 2)
 
   ON_EXIT([kill `cat test-netflow.pid`])
@@ -5211,12 +5504,16 @@ m4_define([CHECK_NETFLOW_ACTIVE_EXPIRATION],
   # exactly 59 other packets in that direction,
   # and exactly 60 packets in the other direction.
   AT_CHECK([echo $n_learn $n_in $n_out $n_other], [0], [1 59 60 0
-])
+])])
 
-  AT_CLEANUP])
+AT_SETUP([ofproto-dpif - NetFlow active expiration - IPv4 collector])
+CHECK_NETFLOW_ACTIVE_EXPIRATION([127.0.0.1])
+AT_CLEANUP
 
-CHECK_NETFLOW_ACTIVE_EXPIRATION([127.0.0.1], [IPv4])
-CHECK_NETFLOW_ACTIVE_EXPIRATION([[[::1]]], [IPv6])
+AT_SETUP([ofproto-dpif - NetFlow active expiration - IPv6 collector])
+AT_SKIP_IF([test $HAVE_IPV6 = no])
+CHECK_NETFLOW_ACTIVE_EXPIRATION([[[::1]]])
+AT_CLEANUP
 
 AT_SETUP([ofproto-dpif - flow stats])
 OVS_VSWITCHD_START
@@ -5460,7 +5757,7 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:
 ovs-appctl revalidator/wait
 AT_CHECK([ovs-appctl dpif/dump-flows -m br0], [0], [stdout])
 
-UFID=`sed -n 's/\(ufid:[[0-9a-fA-F]]*\).*/\1/p' stdout`
+UFID=`sed -n 's/\(ufid:[[-0-9a-fA-F]]*\).*/\1/p' stdout`
 AT_CHECK([ovs-appctl dpctl/get-flow $UFID], [0], [dnl
 recirc_id(0),in_port(1),eth_type(0x0800),ipv4(frag=no), packets:0, bytes:0, used:never, actions:drop
 ])
@@ -5812,12 +6109,9 @@ recirc_id=0,mpls,in_port=1,dl_src=50:54:00:00:00:0b,mpls_bos=1, actions: <del>
 OVS_VSWITCHD_STOP
 AT_CLEANUP
 
-# CHECK_MEGAFLOW_NETFLOW(LOOPBACK_ADDR, IP_VERSION_TYPE)
-#
-# IP_VERSION_TYPE is used in AT_SETUP
+# CHECK_MEGAFLOW_NETFLOW(LOOPBACK_ADDR)
 m4_define([CHECK_MEGAFLOW_NETFLOW],
-  [AT_SETUP([ofproto-dpif megaflow - netflow - $2 collector])
-  OVS_VSWITCHD_START
+  [OVS_VSWITCHD_START
   AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg])
   ADD_OF_PORTS([br0], [1], [2])
 
@@ -5839,11 +6133,16 @@ m4_define([CHECK_MEGAFLOW_NETFLOW],
 recirc_id=0,icmp,in_port=1,vlan_tci=0x0000/0x1fff,dl_src=50:54:00:00:00:09,dl_dst=50:54:00:00:00:0a,nw_src=10.0.0.2,nw_dst=10.0.0.1,nw_tos=0,nw_frag=no,icmp_type=0x8/0xff,icmp_code=0x0/0xff, actions: <del>
 recirc_id=0,icmp,in_port=1,vlan_tci=0x0000/0x1fff,dl_src=50:54:00:00:00:0b,dl_dst=50:54:00:00:00:0c,nw_src=10.0.0.4,nw_dst=10.0.0.3,nw_tos=0,nw_frag=no,icmp_type=0x8/0xff,icmp_code=0x0/0xff, actions: <del>
 ])
-  OVS_VSWITCHD_STOP
-  AT_CLEANUP])
+  OVS_VSWITCHD_STOP])
 
+AT_SETUP([ofproto-dpif megaflow - netflow - IPv4 collector])
 CHECK_MEGAFLOW_NETFLOW([127.0.0.1], [IPv4])
+AT_CLEANUP
+
+AT_SETUP([ofproto-dpif megaflow - netflow - IPv6 collector])
+AT_SKIP_IF([test $HAVE_IPV6 = no])
 CHECK_MEGAFLOW_NETFLOW([[[::1]]], [IPv6])
+AT_CLEANUP
 
 AT_SETUP([ofproto-dpif megaflow - normal, active-backup bonding])
 OVS_VSWITCHD_START(
@@ -6455,13 +6754,13 @@ NXST_FLOW reply:
 
 (echo "OFPST_TABLE reply (OF1.3) (xid=0x2):
   table 0:
-    active=1, lookup=0, matched=0"
- x=1
- while test $x -lt 254; do
-   echo "
-  table $x:
-    active=0, lookup=0, matched=0"
-   x=`expr $x + 1`
+    active=1, lookup=0, matched=0
+
+  table 1:
+    active=0, lookup=0, matched=0
+"
+ for i in `seq 2 253`; do
+     printf '  table %d: ditto\n' $i
  done) > expout
 AT_CHECK([ovs-ofctl -O OpenFlow13 dump-tables br0 ], [0], [expout])
 
@@ -6499,25 +6798,24 @@ NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=14 in_port=1 (via no_match) data_l
 vlan_tci=0x0000,dl_src=50:54:00:00:00:09,dl_dst=50:54:00:00:00:0a,dl_type=0x1234
 ])
 
-(printf "OFPST_TABLE reply (OF1.3) (xid=0x2):"
- x=0
- while test $x -lt 254; do
-   echo "
-  table $x:
-    active=0, lookup=0, matched=0"
-   x=`expr $x + 1`
+(echo "OFPST_TABLE reply (OF1.3) (xid=0x2):
+  table 0:
+    active=0, lookup=0, matched=0
+"
+ for i in `seq 1 253`; do
+     printf '  table %d: ditto\n' $i
  done) > expout
 AT_CHECK([ovs-ofctl -O OpenFlow13 dump-tables br0 ], [0], [expout])
 
 (echo "OFPST_TABLE reply (OF1.3) (xid=0x2):
   table 0:
-    active=0, lookup=3, matched=0"
- x=1
- while test $x -lt 254; do
-   echo "
-  table $x:
-    active=0, lookup=0, matched=0"
-   x=`expr $x + 1`
+    active=0, lookup=3, matched=0
+
+  table 1:
+    active=0, lookup=0, matched=0
+"
+ for i in `seq 2 253`; do
+     printf '  table %d: ditto\n' $i
  done) > expout
 AT_CHECK([ovs-ofctl -O OpenFlow13 dump-tables br1 ], [0], [expout])
 
@@ -6566,14 +6864,12 @@ OFPST_FLOW reply (OF1.3):
   table 0:
     active=1, lookup=3, matched=3
 
-  table 1:
-    active=1, lookup=3, matched=3"
- x=2
- while test $x -lt 254; do
-   echo "
-  table $x:
-    active=0, lookup=0, matched=0"
-   x=`expr $x + 1`
+  table 1: ditto
+  table 2:
+    active=0, lookup=0, matched=0
+"
+ for i in `seq 3 253`; do
+     printf '  table %d: ditto\n' $i
  done) > expout
 AT_CHECK([ovs-ofctl -O OpenFlow13 dump-tables br0 ], [0], [expout])
 
@@ -6619,13 +6915,13 @@ OFPST_FLOW reply (OF1.1):
     active=0, lookup=3, matched=0
 
   table 1:
-    active=1, lookup=3, matched=3"
- x=2
- while test $x -lt 254; do
-   echo "
-  table $x:
-    active=0, lookup=0, matched=0"
-   x=`expr $x + 1`
+    active=1, lookup=3, matched=3
+
+  table 2:
+    active=0, lookup=0, matched=0
+"
+ for i in `seq 3 253`; do
+     printf '  table %d: ditto\n' $i
  done) > expout
 AT_CHECK([ovs-ofctl -O OpenFlow13 dump-tables br0 ], [0], [expout])