Do not include zeroed metadata fields in NXM/OXM packet-in messages.
[sliver-openvswitch.git] / tests / ofproto-dpif.at
index d58c531..1e5856f 100644 (file)
@@ -11,7 +11,7 @@ table=1 in_port=2 priority=1500 icmp actions=output(17),resubmit(,2)
 table=1 in_port=3 priority=1500 icmp actions=output(14),resubmit(,2)
 ])
 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
-AT_CHECK([ovs-appctl ofproto/trace br0 '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)'], [0], [stdout])
+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: 10,11,12,13,14,15,16,17,18,19,20,21
 ])
@@ -23,7 +23,9 @@ OVS_VSWITCHD_START
 AT_DATA([flows.txt], [dnl
 in_port=90                 actions=resubmit:2,resubmit:3,resubmit:4,resubmit:91
 in_port=91                 actions=resubmit:5,resubmit:6,resubmit:7,resubmit:92
-in_port=92                 actions=resubmit:8,resubmit:9,resubmit:10,resubmit:11
+in_port=92                 actions=resubmit:8,resubmit:9,resubmit:10,resubmit:11,resubmit:93
+in_port=93                 actions=resubmit:12,resubmit:13,resubmit:14,resubmit:15
+
 in_port=2                  actions=load:0x000db000->NXM_NX_REG0[[]]
 in_port=3                  actions=load:0xdea->NXM_NX_REG0[[20..31]]
 in_port=4                  actions=load:0xeef->NXM_NX_REG0[[0..11]]
@@ -34,11 +36,17 @@ in_port=8                  actions=move:NXM_NX_REG1[[0..11]]->NXM_NX_REG2[[20..3
 in_port=9,reg0=0xdeadbeef  actions=output:20
 in_port=10,reg1=0xdeadbeef actions=output:21
 in_port=11,reg2=0xeef22dea actions=output:22
+
+dnl Sanilty check all registers
+in_port=12 actions=load:0x10->NXM_NX_REG0[[]],load:0x11->NXM_NX_REG1[[]],load:0x12->NXM_NX_REG2[[]]
+in_port=13 actions=load:0x13->NXM_NX_REG3[[]],load:0x14->NXM_NX_REG4[[]],load:0x15->NXM_NX_REG5[[]]
+in_port=14 actions=load:0x16->NXM_NX_REG6[[]],load:0x17->NXM_NX_REG7[[]]
+in_port=15,reg0=0x10,reg1=0x11,reg2=0x12,reg3=0x13,reg4=0x14,reg5=0x15,reg6=0x16,reg7=0x17 actions=output:33
 ])
 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
 AT_CHECK([ovs-appctl ofproto/trace br0 'in_port(90),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)'], [0], [stdout])
 AT_CHECK([tail -1 stdout], [0],
-  [Datapath actions: 20,21,22
+  [Datapath actions: 20,21,22,33
 ])
 OVS_VSWITCHD_STOP
 AT_CLEANUP
@@ -62,19 +70,45 @@ AT_CHECK([tail -1 stdout], [0],
 OVS_VSWITCHD_STOP
 AT_CLEANUP
 
+AT_SETUP([ofproto-dpif - dec_ttl])
+OVS_VSWITCHD_START
+AT_DATA([flows.txt], [dnl
+table=0 in_port=1 action=dec_ttl,output:2,resubmit(1,1),output:4
+table=1 in_port=1 action=dec_ttl,output:3
+])
+AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
+AT_CHECK([ovs-appctl ofproto/trace br0 '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=2,frag=no)' -generate], [0], [stdout])
+AT_CHECK([tail -3 stdout], [0],
+  [Datapath actions: set(ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=1,frag=no)),2,4
+This flow is handled by the userspace slow path because it:
+       - Sends "packet-in" messages to the OpenFlow controller.
+])
+AT_CHECK([ovs-appctl ofproto/trace br0 '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=3,frag=no)'], [0], [stdout])
+AT_CHECK([tail -1 stdout], [0],
+  [Datapath actions: set(ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=2,frag=no)),2,set(ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=1,frag=no)),3,4
+])
+AT_CHECK([ovs-appctl ofproto/trace br0 'in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x86dd),ipv6(src=::1,dst=::2,label=0,proto=10,tclass=0x70,hlimit=128,frag=no)'], [0], [stdout])
+AT_CHECK([tail -1 stdout], [0],
+  [Datapath actions: set(ipv6(src=::1,dst=::2,label=0,proto=10,tclass=0x70,hlimit=127,frag=no)),2,set(ipv6(src=::1,dst=::2,label=0,proto=10,tclass=0x70,hlimit=126,frag=no)),3,4
+])
+
+AT_CAPTURE_FILE([ofctl_monitor.log])
+AT_CHECK([ovs-ofctl monitor br0 65534 invalid_ttl --detach --no-chdir --pidfile 2> ofctl_monitor.log])
+AT_CHECK([ovs-appctl ofproto/trace br0 '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=2,frag=no)' -generate], [0], [stdout])
+OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
+AT_CHECK([cat ofctl_monitor.log], [0], [dnl
+NXT_PACKET_IN (xid=0x0): table_id=1 total_len=42 in_port=1 (via invalid_ttl) data_len=42 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(0) mac(50:54:00:00:00:05->50:54:00:00:00:07) type:0800 proto:1 tos:0 ttl:1 ip(192.168.0.1->192.168.0.2)
+])
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
+
 AT_SETUP([ofproto-dpif - output, OFPP_NONE ingress port])
 OVS_VSWITCHD_START(
        [add-port br0 p1 -- set Interface p1 type=dummy --\
         add-port br0 p2 -- set Interface p2 type=dummy])
 
-AT_CHECK(
-  [ovs-vsctl \
-        -- get Interface p1 ofport \
-        -- get Interface p2 ofport],
-  [0], [stdout])
-set `cat stdout`
-br0=0 p1=$1 p2=$2
-
 AT_CHECK([ovs-ofctl add-flow br0 action=normal])
 
 # "in_port" defaults to OFPP_NONE if it's not specified.
@@ -82,16 +116,15 @@ flow="eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src
 AT_CHECK([ovs-appctl ofproto/trace br0 "$flow"], [0], [stdout])
 actual=`tail -1 stdout | sed 's/Datapath actions: //'`
 
-expected="$br0,$p1,$p2"
-AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected" br0=$br0 p1=$p1 p2=$p2], [0], [stdout])
+expected="0,1,2"
+AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
 mv stdout expout
-AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual" br0=$br0 p1=$p1 p2=$p2], [0], [expout])
+AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
 
 OVS_VSWITCHD_STOP
 AT_CLEANUP
 
 AT_SETUP([ofproto-dpif - DSCP])
-dnl This test assumes port p1 is allocated OpenFlow port number 1.
 OVS_VSWITCHD_START([add-port br0 p1 -- set Interface p1 type=dummy])
 AT_DATA([flows.txt], [dnl
 actions=output:65534,enqueue:1:1,enqueue:1:2,enqueue:1:2,enqueue:1:1,output:1,mod_nw_tos:0,output:1,output:65534
@@ -118,11 +151,6 @@ OVS_VSWITCHD_STOP
 AT_CLEANUP
 
 AT_SETUP([ofproto-dpif - output/flood flags])
-dnl This test assumes that OpenFlow port numbers are allocated in order
-dnl starting from one.  It does not necessarily require that they are allocated
-dnl in the same order that they are named in the database.  Just that the
-dnl following command guarantees OpenFlow port 65534, and ports 1-7 exist in
-dnl the bridge.
 OVS_VSWITCHD_START([dnl
         add-port br0 p1 -- set Interface p1 type=dummy --\
         add-port br0 p2 -- set Interface p2 type=dummy --\
@@ -133,6 +161,7 @@ OVS_VSWITCHD_START([dnl
         add-port br0 p7 -- set Interface p7 type=dummy ])
 
 AT_DATA([flows.txt], [dnl
+in_port=local actions=local,flood
 in_port=1 actions=flood
 in_port=2 actions=all
 in_port=3 actions=output:65534,output:1,output:2,output:3,output:4,output:5,output:6,output:7
@@ -142,6 +171,16 @@ AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
 AT_CHECK([ovs-ofctl mod-port br0 5 noforward])
 AT_CHECK([ovs-ofctl mod-port br0 6 noflood])
 
+AT_CHECK([ovs-appctl ofproto/trace br0 'in_port(0),eth(src=00:00:00:00:00:01,dst=00:00:00:00:00:02),eth_type(0x0900)'], [0], [stdout])
+AT_CHECK([tail -1 stdout \
+| sed -e 's/Datapath actions: //' | tr ',' '\n' | sort], [0], [dnl
+1
+2
+3
+4
+7
+])
+
 AT_CHECK([ovs-appctl ofproto/trace br0 'in_port(1),eth(src=00:00:00:00:00:01,dst=00:00:00:00:00:02),eth_type(0x0900)'], [0], [stdout])
 AT_CHECK([tail -1 stdout \
 | sed -e 's/Datapath actions: //' | tr ',' '\n' | sort], [0], [dnl
@@ -193,6 +232,175 @@ AT_CHECK([tail -1 stdout], [0],
 OVS_VSWITCHD_STOP
 AT_CLEANUP
 
+AT_SETUP([ofproto-dpif - controller])
+OVS_VSWITCHD_START([dnl
+   add-port br0 p1 -- set Interface p1 type=dummy
+])
+
+AT_CAPTURE_FILE([ofctl_monitor.log])
+AT_DATA([flows.txt], [dnl
+cookie=0x0 dl_src=10:11:11:11:11:11 actions=controller
+cookie=0x1 dl_src=20:22:22:22:22:22 actions=controller,resubmit(80,1)
+cookie=0x2 dl_src=30:33:33:33:33:33 actions=mod_vlan_vid:15,controller
+
+cookie=0x3 table=1 in_port=80 actions=load:1->NXM_NX_REG0[[]],mod_vlan_vid:80,controller,resubmit(81,2)
+cookie=0x4 table=2 in_port=81 actions=load:2->NXM_NX_REG1[[]],mod_dl_src:80:81:81:81:81:81,controller,resubmit(82,3)
+cookie=0x5 table=3 in_port=82 actions=load:3->NXM_NX_REG2[[]],mod_dl_dst:82:82:82:82:82:82,controller,resubmit(83,4)
+cookie=0x6 table=4 in_port=83 actions=load:4->NXM_NX_REG3[[]],mod_nw_src:83.83.83.83,controller,resubmit(84,5)
+cookie=0x7 table=5 in_port=84 actions=load:5->NXM_NX_REG4[[]],load:6->NXM_NX_TUN_ID[[]],mod_nw_dst:84.84.84.84,controller,resubmit(85,6)
+cookie=0x8 table=6 in_port=85 actions=mod_tp_src:85,controller,resubmit(86,7)
+cookie=0x9 table=7 in_port=86 actions=mod_tp_dst:86,controller,controller
+])
+AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
+
+dnl Flow miss.
+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)'
+done
+
+OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
+AT_CHECK([cat ofctl_monitor.log], [0], [dnl
+OFPT_PACKET_IN (xid=0x0): total_len=60 in_port=1 (via no_match) data_len=60 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(0) mac(50:54:00:00:00:05->50:54:00:00:00:07) type:0800 proto:6 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->9) tcp_csum:0
+dnl
+OFPT_PACKET_IN (xid=0x0): total_len=60 in_port=1 (via no_match) data_len=60 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(0) mac(50:54:00:00:00:05->50:54:00:00:00:07) type:0800 proto:6 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->9) tcp_csum:0
+dnl
+OFPT_PACKET_IN (xid=0x0): total_len=60 in_port=1 (via no_match) data_len=60 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(0) mac(50:54:00:00:00:05->50:54:00:00:00:07) type:0800 proto:6 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->9) tcp_csum:0
+])
+
+dnl Singleton controller action.
+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=10:11:11:11:11:11,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=10)'
+done
+
+OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
+AT_CHECK([cat ofctl_monitor.log], [0], [dnl
+OFPT_PACKET_IN (xid=0x0): total_len=60 in_port=1 (via action) data_len=60 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(0) mac(10:11:11:11:11:11->50:54:00:00:00:07) type:0800 proto:6 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->10) tcp_csum:0
+dnl
+OFPT_PACKET_IN (xid=0x0): total_len=60 in_port=1 (via action) data_len=60 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(0) mac(10:11:11:11:11:11->50:54:00:00:00:07) type:0800 proto:6 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->10) tcp_csum:0
+dnl
+OFPT_PACKET_IN (xid=0x0): total_len=60 in_port=1 (via action) data_len=60 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(0) mac(10:11:11:11:11:11->50:54:00:00:00:07) type:0800 proto:6 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->10) tcp_csum:0
+])
+
+dnl Modified controller action.
+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=30:33:33:33:33:33,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=10)'
+done
+
+OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
+AT_CHECK([cat ofctl_monitor.log], [0], [dnl
+OFPT_PACKET_IN (xid=0x0): total_len=64 in_port=1 (via action) data_len=64 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(vlan:15,pcp:0) mac(30:33:33:33:33:33->50:54:00:00:00:07) type:0800 proto:6 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->10) tcp_csum:0
+dnl
+OFPT_PACKET_IN (xid=0x0): total_len=64 in_port=1 (via action) data_len=64 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(vlan:15,pcp:0) mac(30:33:33:33:33:33->50:54:00:00:00:07) type:0800 proto:6 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->10) tcp_csum:0
+dnl
+OFPT_PACKET_IN (xid=0x0): total_len=64 in_port=1 (via action) data_len=64 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(vlan:15,pcp:0) mac(30:33:33:33:33:33->50:54:00:00:00:07) type:0800 proto:6 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->10) tcp_csum:0
+])
+
+dnl Checksum TCP.
+AT_CHECK([ovs-ofctl monitor br0 65534 -P nxm --detach --no-chdir --pidfile 2> ofctl_monitor.log])
+
+for i in 1 ; do
+    ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=20:22:22:22:22:22,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=11)'
+done
+
+OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
+AT_CHECK([cat ofctl_monitor.log], [0], [dnl
+NXT_PACKET_IN (xid=0x0): cookie=0x1 total_len=60 in_port=1 (via action) data_len=60 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(0) mac(20:22:22:22:22:22->50:54:00:00:00:07) type:0800 proto:6 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->11) tcp_csum:0
+dnl
+NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x3 total_len=64 in_port=1 reg0=0x1 (via action) data_len=64 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(vlan:80,pcp:0) mac(20:22:22:22:22:22->50:54:00:00:00:07) type:0800 proto:6 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->11) tcp_csum:0
+dnl
+NXT_PACKET_IN (xid=0x0): table_id=2 cookie=0x4 total_len=64 in_port=1 reg0=0x1 reg1=0x2 (via action) data_len=64 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->50:54:00:00:00:07) type:0800 proto:6 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->11) tcp_csum:0
+dnl
+NXT_PACKET_IN (xid=0x0): table_id=3 cookie=0x5 total_len=64 in_port=1 reg0=0x1 reg1=0x2 reg2=0x3 (via action) data_len=64 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->82:82:82:82:82:82) type:0800 proto:6 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->11) tcp_csum:0
+dnl
+NXT_PACKET_IN (xid=0x0): table_id=4 cookie=0x6 total_len=64 in_port=1 reg0=0x1 reg1=0x2 reg2=0x3 reg3=0x4 (via action) data_len=64 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->82:82:82:82:82:82) type:0800 proto:6 tos:0 ttl:0 ip(83.83.83.83->192.168.0.2) port(8->11) tcp_csum:1a03
+dnl
+NXT_PACKET_IN (xid=0x0): table_id=5 cookie=0x7 total_len=64 in_port=1 tun_id=0x6 reg0=0x1 reg1=0x2 reg2=0x3 reg3=0x4 reg4=0x5 (via action) data_len=64 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->82:82:82:82:82:82) type:0800 proto:6 tos:0 ttl:0 ip(83.83.83.83->84.84.84.84) port(8->11) tcp_csum:3205
+dnl
+NXT_PACKET_IN (xid=0x0): table_id=6 cookie=0x8 total_len=64 in_port=1 tun_id=0x6 reg0=0x1 reg1=0x2 reg2=0x3 reg3=0x4 reg4=0x5 (via action) data_len=64 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->82:82:82:82:82:82) type:0800 proto:6 tos:0 ttl:0 ip(83.83.83.83->84.84.84.84) port(85->11) tcp_csum:31b8
+dnl
+NXT_PACKET_IN (xid=0x0): table_id=7 cookie=0x9 total_len=64 in_port=1 tun_id=0x6 reg0=0x1 reg1=0x2 reg2=0x3 reg3=0x4 reg4=0x5 (via action) data_len=64 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->82:82:82:82:82:82) type:0800 proto:6 tos:0 ttl:0 ip(83.83.83.83->84.84.84.84) port(85->86) tcp_csum:316d
+dnl
+NXT_PACKET_IN (xid=0x0): table_id=7 cookie=0x9 total_len=64 in_port=1 tun_id=0x6 reg0=0x1 reg1=0x2 reg2=0x3 reg3=0x4 reg4=0x5 (via action) data_len=64 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->82:82:82:82:82:82) type:0800 proto:6 tos:0 ttl:0 ip(83.83.83.83->84.84.84.84) port(85->86) tcp_csum:316d
+])
+
+dnl Checksum UDP.
+AT_CHECK([ovs-ofctl monitor br0 65534 --detach --no-chdir --pidfile 2> ofctl_monitor.log])
+
+for i in 1 ; do
+    ovs-appctl netdev-dummy/receive p1 '50 54 00 00 00 07 20 22 22 22 22 22 08 00 45 00 00 1C 00 00 00 00 00 11 00 00 C0 A8 00 01 C0 A8 00 02 00 08 00 0B 00 00 12 34 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
+done
+
+OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
+AT_CHECK([cat ofctl_monitor.log], [0], [dnl
+NXT_PACKET_IN (xid=0x0): cookie=0x1 total_len=60 in_port=1 (via action) data_len=60 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(0) mac(20:22:22:22:22:22->50:54:00:00:00:07) type:0800 proto:17 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->11) udp_csum:1234
+dnl
+NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x3 total_len=64 in_port=1 reg0=0x1 (via action) data_len=64 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(vlan:80,pcp:0) mac(20:22:22:22:22:22->50:54:00:00:00:07) type:0800 proto:17 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->11) udp_csum:1234
+dnl
+NXT_PACKET_IN (xid=0x0): table_id=2 cookie=0x4 total_len=64 in_port=1 reg0=0x1 reg1=0x2 (via action) data_len=64 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->50:54:00:00:00:07) type:0800 proto:17 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->11) udp_csum:1234
+dnl
+NXT_PACKET_IN (xid=0x0): table_id=3 cookie=0x5 total_len=64 in_port=1 reg0=0x1 reg1=0x2 reg2=0x3 (via action) data_len=64 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->82:82:82:82:82:82) type:0800 proto:17 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->11) udp_csum:1234
+dnl
+NXT_PACKET_IN (xid=0x0): table_id=4 cookie=0x6 total_len=64 in_port=1 reg0=0x1 reg1=0x2 reg2=0x3 reg3=0x4 (via action) data_len=64 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->82:82:82:82:82:82) type:0800 proto:17 tos:0 ttl:0 ip(83.83.83.83->192.168.0.2) port(8->11) udp_csum:2c37
+dnl
+NXT_PACKET_IN (xid=0x0): table_id=5 cookie=0x7 total_len=64 in_port=1 tun_id=0x6 reg0=0x1 reg1=0x2 reg2=0x3 reg3=0x4 reg4=0x5 (via action) data_len=64 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->82:82:82:82:82:82) type:0800 proto:17 tos:0 ttl:0 ip(83.83.83.83->84.84.84.84) port(8->11) udp_csum:4439
+dnl
+NXT_PACKET_IN (xid=0x0): table_id=6 cookie=0x8 total_len=64 in_port=1 tun_id=0x6 reg0=0x1 reg1=0x2 reg2=0x3 reg3=0x4 reg4=0x5 (via action) data_len=64 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->82:82:82:82:82:82) type:0800 proto:17 tos:0 ttl:0 ip(83.83.83.83->84.84.84.84) port(85->11) udp_csum:43ec
+dnl
+NXT_PACKET_IN (xid=0x0): table_id=7 cookie=0x9 total_len=64 in_port=1 tun_id=0x6 reg0=0x1 reg1=0x2 reg2=0x3 reg3=0x4 reg4=0x5 (via action) data_len=64 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->82:82:82:82:82:82) type:0800 proto:17 tos:0 ttl:0 ip(83.83.83.83->84.84.84.84) port(85->86) udp_csum:43a1
+dnl
+NXT_PACKET_IN (xid=0x0): table_id=7 cookie=0x9 total_len=64 in_port=1 tun_id=0x6 reg0=0x1 reg1=0x2 reg2=0x3 reg3=0x4 reg4=0x5 (via action) data_len=64 (unbuffered)
+priority:0,tunnel:0,metadata:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->82:82:82:82:82:82) type:0800 proto:17 tos:0 ttl:0 ip(83.83.83.83->84.84.84.84) port(85->86) udp_csum:43a1
+])
+
+AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl
+ cookie=0x1, n_packets=2, n_bytes=120, dl_src=20:22:22:22:22:22 actions=CONTROLLER:65535,resubmit(80,1)
+ cookie=0x2, n_packets=3, n_bytes=180, dl_src=30:33:33:33:33:33 actions=mod_vlan_vid:15,CONTROLLER:65535
+ cookie=0x3, table=1, n_packets=2, n_bytes=120, in_port=80 actions=load:0x1->NXM_NX_REG0[[]],mod_vlan_vid:80,CONTROLLER:65535,resubmit(81,2)
+ cookie=0x4, table=2, n_packets=2, n_bytes=120, in_port=81 actions=load:0x2->NXM_NX_REG1[[]],mod_dl_src:80:81:81:81:81:81,CONTROLLER:65535,resubmit(82,3)
+ cookie=0x5, table=3, n_packets=2, n_bytes=120, in_port=82 actions=load:0x3->NXM_NX_REG2[[]],mod_dl_dst:82:82:82:82:82:82,CONTROLLER:65535,resubmit(83,4)
+ cookie=0x6, table=4, n_packets=2, n_bytes=120, in_port=83 actions=load:0x4->NXM_NX_REG3[[]],mod_nw_src:83.83.83.83,CONTROLLER:65535,resubmit(84,5)
+ cookie=0x7, table=5, n_packets=2, n_bytes=120, in_port=84 actions=load:0x5->NXM_NX_REG4[[]],load:0x6->NXM_NX_TUN_ID[[]],mod_nw_dst:84.84.84.84,CONTROLLER:65535,resubmit(85,6)
+ cookie=0x8, table=6, n_packets=2, n_bytes=120, in_port=85 actions=mod_tp_src:85,CONTROLLER:65535,resubmit(86,7)
+ cookie=0x9, table=7, n_packets=2, n_bytes=120, in_port=86 actions=mod_tp_dst:86,CONTROLLER:65535,CONTROLLER:65535
+ n_packets=3, n_bytes=180, dl_src=10:11:11:11:11:11 actions=CONTROLLER:65535
+NXST_FLOW reply:
+])
+
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
 AT_SETUP([ofproto-dpif - VLAN handling])
 OVS_VSWITCHD_START(
   [set Bridge br0 fail-mode=standalone -- \
@@ -215,105 +423,91 @@ OVS_VSWITCHD_START(
    set Interface p7 type=dummy -- \
    set Interface p8 type=dummy --])
 
-AT_CHECK(
-  [ovs-vsctl \
-        -- get Interface p1 ofport \
-        -- get Interface p2 ofport \
-        -- get Interface p3 ofport \
-        -- get Interface p4 ofport \
-        -- get Interface p5 ofport \
-        -- get Interface p6 ofport \
-        -- get Interface p7 ofport \
-        -- get Interface p8 ofport],
-  [0], [stdout])
-set `cat stdout`
-br0=0 p1=$1 p2=$2 p3=$3 p4=$4 p5=$5 p6=$6 p7=$7 p8=$8
-
-dnl Each of these specifies an in_port, a VLAN VID (or "none"), a VLAN
-dnl PCP (used if the VID isn't "none") and the expected set of datapath
+dnl Each of these specifies an in_port by number, a VLAN VID (or "none"),
+dnl a VLAN PCP (used if the VID isn't "none") and the expected set of datapath
 dnl actions.
 for tuple in \
-        "br0 none 0 drop" \
-        "br0 0    0 drop" \
-        "br0 0    1 drop" \
-        "br0 10   0 p1,p5,p6,p7,p8,pop_vlan,p2" \
-        "br0 10   1 p1,p5,p6,p7,p8,pop_vlan,p2" \
-        "br0 11   0 p5,p7" \
-        "br0 11   1 p5,p7" \
-        "br0 12   0 p1,p5,p6,pop_vlan,p3,p4,p7,p8" \
-        "br0 12   1 p1,p5,p6,pop_vlan,p4,p7,push_vlan(vid=0,pcp=1),p3,p8" \
-        "p1  none 0 drop" \
-        "p1  0    0 drop" \
-        "p1  0    1 drop" \
-        "p1  10   0 br0,p5,p6,p7,p8,pop_vlan,p2" \
-        "p1  10   1 br0,p5,p6,p7,p8,pop_vlan,p2" \
-        "p1  11   0 drop" \
-        "p1  11   1 drop" \
-        "p1  12   0 br0,p5,p6,pop_vlan,p3,p4,p7,p8" \
-        "p1  12   1 br0,p5,p6,pop_vlan,p4,p7,push_vlan(vid=0,pcp=1),p3,p8" \
-        "p2  none 0 push_vlan(vid=10,pcp=0),br0,p1,p5,p6,p7,p8" \
-        "p2  0    0 pop_vlan,push_vlan(vid=10,pcp=0),br0,p1,p5,p6,p7,p8" \
-        "p2  0    1 pop_vlan,push_vlan(vid=10,pcp=1),br0,p1,p5,p6,p7,p8" \
-        "p2  10   0 drop" \
-        "p2  10   1 drop" \
-        "p2  11   0 drop" \
-        "p2  11   1 drop" \
-        "p2  12   0 drop" \
-        "p2  12   1 drop" \
-        "p3  none 0 p4,p7,p8,push_vlan(vid=12,pcp=0),br0,p1,p5,p6" \
-        "p3  0    0 pop_vlan,p4,p7,p8,push_vlan(vid=12,pcp=0),br0,p1,p5,p6" \
-        "p3  0    1 p8,pop_vlan,p4,p7,push_vlan(vid=12,pcp=1),br0,p1,p5,p6" \
-        "p3  10   0 drop" \
-        "p3  10   1 drop" \
-        "p3  11   0 drop" \
-        "p3  11   1 drop" \
-        "p3  12   0 drop" \
-        "p3  12   1 drop" \
-        "p4  none 0 p3,p7,p8,push_vlan(vid=12,pcp=0),br0,p1,p5,p6" \
-        "p4  0    0 pop_vlan,p3,p7,p8,push_vlan(vid=12,pcp=0),br0,p1,p5,p6" \
-        "p4  0    1 p3,p8,pop_vlan,p7,push_vlan(vid=12,pcp=1),br0,p1,p5,p6" \
-        "p4  10   0 drop" \
-        "p4  10   1 drop" \
-        "p4  11   0 drop" \
-        "p4  11   1 drop" \
-        "p4  12   0 drop" \
-        "p4  12   1 drop" \
-        "p5  none 0 p2,push_vlan(vid=10,pcp=0),br0,p1,p6,p7,p8" \
-        "p5  0    0 pop_vlan,p2,push_vlan(vid=10,pcp=0),br0,p1,p6,p7,p8" \
-        "p5  0    1 pop_vlan,p2,push_vlan(vid=10,pcp=1),br0,p1,p6,p7,p8" \
-        "p5  10   0 br0,p1,p6,p7,p8,pop_vlan,p2" \
-        "p5  10   1 br0,p1,p6,p7,p8,pop_vlan,p2" \
-        "p5  11   0 br0,p7" \
-        "p5  11   1 br0,p7" \
-        "p5  12   0 br0,p1,p6,pop_vlan,p3,p4,p7,p8" \
-        "p5  12   1 br0,p1,p6,pop_vlan,p4,p7,push_vlan(vid=0,pcp=1),p3,p8" \
-        "p6  none 0 p2,push_vlan(vid=10,pcp=0),br0,p1,p5,p7,p8" \
-        "p6  0    0 pop_vlan,p2,push_vlan(vid=10,pcp=0),br0,p1,p5,p7,p8" \
-        "p6  0    1 pop_vlan,p2,push_vlan(vid=10,pcp=1),br0,p1,p5,p7,p8" \
-        "p6  10   0 br0,p1,p5,p7,p8,pop_vlan,p2" \
-        "p6  10   1 br0,p1,p5,p7,p8,pop_vlan,p2" \
-        "p6  11   0 drop" \
-        "p6  11   1 drop" \
-        "p6  12   0 br0,p1,p5,pop_vlan,p3,p4,p7,p8" \
-        "p6  12   1 br0,p1,p5,pop_vlan,p4,p7,push_vlan(vid=0,pcp=1),p3,p8" \
-        "p7  none 0 p3,p4,p8,push_vlan(vid=12,pcp=0),br0,p1,p5,p6" \
-        "p7  0    0 pop_vlan,p3,p4,p8,push_vlan(vid=12,pcp=0),br0,p1,p5,p6" \
-        "p7  0    1 p3,p8,pop_vlan,p4,push_vlan(vid=12,pcp=1),br0,p1,p5,p6" \
-        "p7  10   0 br0,p1,p5,p6,p8,pop_vlan,p2" \
-        "p7  10   1 br0,p1,p5,p6,p8,pop_vlan,p2" \
-        "p7  11   0 br0,p5" \
-        "p7  11   1 br0,p5" \
-        "p7  12   0 br0,p1,p5,p6,pop_vlan,p3,p4,p8" \
-        "p7  12   1 br0,p1,p5,p6,pop_vlan,p4,push_vlan(vid=0,pcp=1),p3,p8" \
-        "p8  none 0 p3,p4,p7,push_vlan(vid=12,pcp=0),br0,p1,p5,p6" \
-        "p8  0    0 pop_vlan,p3,p4,p7,push_vlan(vid=12,pcp=0),br0,p1,p5,p6" \
-        "p8  0    1 p3,pop_vlan,p4,p7,push_vlan(vid=12,pcp=1),br0,p1,p5,p6" \
-        "p8  10   0 br0,p1,p5,p6,p7,pop_vlan,p2" \
-        "p8  10   1 br0,p1,p5,p6,p7,pop_vlan,p2" \
-        "p8  11   0 drop" \
-        "p8  11   1 drop" \
-        "p8  12   0 br0,p1,p5,p6,pop_vlan,p3,p4,p7" \
-        "p8  12   1 br0,p1,p5,p6,pop_vlan,p4,p7,push_vlan(vid=0,pcp=1),p3"
+        "0 none 0 drop" \
+        "0 0    0 drop" \
+        "0 0    1 drop" \
+        "0 10   0 1,5,6,7,8,pop_vlan,2" \
+        "0 10   1 1,5,6,7,8,pop_vlan,2" \
+        "0 11   0 5,7" \
+        "0 11   1 5,7" \
+        "0 12   0 1,5,6,pop_vlan,3,4,7,8" \
+        "0 12   1 1,5,6,pop_vlan,4,7,push_vlan(vid=0,pcp=1),3,8" \
+        "1  none 0 drop" \
+        "1  0    0 drop" \
+        "1  0    1 drop" \
+        "1  10   0 0,5,6,7,8,pop_vlan,2" \
+        "1  10   1 0,5,6,7,8,pop_vlan,2" \
+        "1  11   0 drop" \
+        "1  11   1 drop" \
+        "1  12   0 0,5,6,pop_vlan,3,4,7,8" \
+        "1  12   1 0,5,6,pop_vlan,4,7,push_vlan(vid=0,pcp=1),3,8" \
+        "2  none 0 push_vlan(vid=10,pcp=0),0,1,5,6,7,8" \
+        "2  0    0 pop_vlan,push_vlan(vid=10,pcp=0),0,1,5,6,7,8" \
+        "2  0    1 pop_vlan,push_vlan(vid=10,pcp=1),0,1,5,6,7,8" \
+        "2  10   0 drop" \
+        "2  10   1 drop" \
+        "2  11   0 drop" \
+        "2  11   1 drop" \
+        "2  12   0 drop" \
+        "2  12   1 drop" \
+        "3  none 0 4,7,8,push_vlan(vid=12,pcp=0),0,1,5,6" \
+        "3  0    0 pop_vlan,4,7,8,push_vlan(vid=12,pcp=0),0,1,5,6" \
+        "3  0    1 8,pop_vlan,4,7,push_vlan(vid=12,pcp=1),0,1,5,6" \
+        "3  10   0 drop" \
+        "3  10   1 drop" \
+        "3  11   0 drop" \
+        "3  11   1 drop" \
+        "3  12   0 drop" \
+        "3  12   1 drop" \
+        "4  none 0 3,7,8,push_vlan(vid=12,pcp=0),0,1,5,6" \
+        "4  0    0 pop_vlan,3,7,8,push_vlan(vid=12,pcp=0),0,1,5,6" \
+        "4  0    1 3,8,pop_vlan,7,push_vlan(vid=12,pcp=1),0,1,5,6" \
+        "4  10   0 drop" \
+        "4  10   1 drop" \
+        "4  11   0 drop" \
+        "4  11   1 drop" \
+        "4  12   0 drop" \
+        "4  12   1 drop" \
+        "5  none 0 2,push_vlan(vid=10,pcp=0),0,1,6,7,8" \
+        "5  0    0 pop_vlan,2,push_vlan(vid=10,pcp=0),0,1,6,7,8" \
+        "5  0    1 pop_vlan,2,push_vlan(vid=10,pcp=1),0,1,6,7,8" \
+        "5  10   0 0,1,6,7,8,pop_vlan,2" \
+        "5  10   1 0,1,6,7,8,pop_vlan,2" \
+        "5  11   0 0,7" \
+        "5  11   1 0,7" \
+        "5  12   0 0,1,6,pop_vlan,3,4,7,8" \
+        "5  12   1 0,1,6,pop_vlan,4,7,push_vlan(vid=0,pcp=1),3,8" \
+        "6  none 0 2,push_vlan(vid=10,pcp=0),0,1,5,7,8" \
+        "6  0    0 pop_vlan,2,push_vlan(vid=10,pcp=0),0,1,5,7,8" \
+        "6  0    1 pop_vlan,2,push_vlan(vid=10,pcp=1),0,1,5,7,8" \
+        "6  10   0 0,1,5,7,8,pop_vlan,2" \
+        "6  10   1 0,1,5,7,8,pop_vlan,2" \
+        "6  11   0 drop" \
+        "6  11   1 drop" \
+        "6  12   0 0,1,5,pop_vlan,3,4,7,8" \
+        "6  12   1 0,1,5,pop_vlan,4,7,push_vlan(vid=0,pcp=1),3,8" \
+        "7  none 0 3,4,8,push_vlan(vid=12,pcp=0),0,1,5,6" \
+        "7  0    0 pop_vlan,3,4,8,push_vlan(vid=12,pcp=0),0,1,5,6" \
+        "7  0    1 3,8,pop_vlan,4,push_vlan(vid=12,pcp=1),0,1,5,6" \
+        "7  10   0 0,1,5,6,8,pop_vlan,2" \
+        "7  10   1 0,1,5,6,8,pop_vlan,2" \
+        "7  11   0 0,5" \
+        "7  11   1 0,5" \
+        "7  12   0 0,1,5,6,pop_vlan,3,4,8" \
+        "7  12   1 0,1,5,6,pop_vlan,4,push_vlan(vid=0,pcp=1),3,8" \
+        "8  none 0 3,4,7,push_vlan(vid=12,pcp=0),0,1,5,6" \
+        "8  0    0 pop_vlan,3,4,7,push_vlan(vid=12,pcp=0),0,1,5,6" \
+        "8  0    1 3,pop_vlan,4,7,push_vlan(vid=12,pcp=1),0,1,5,6" \
+        "8  10   0 0,1,5,6,7,pop_vlan,2" \
+        "8  10   1 0,1,5,6,7,pop_vlan,2" \
+        "8  11   0 drop" \
+        "8  11   1 drop" \
+        "8  12   0 0,1,5,6,pop_vlan,3,4,7" \
+        "8  12   1 0,1,5,6,pop_vlan,4,7,push_vlan(vid=0,pcp=1),3"
 do
   set $tuple
   in_port=$1
@@ -321,11 +515,10 @@ do
   pcp=$3
   expected=$4
 
-  eval n_in_port=\$$in_port
   if test $vlan = none; then
-    flow="in_port($n_in_port),eth(src=50:54:00:00:00:01,dst=ff:ff:ff:ff:ff:ff),eth_type(0xabcd)"
+    flow="in_port($in_port),eth(src=50:54:00:00:00:01,dst=ff:ff:ff:ff:ff:ff),eth_type(0xabcd)"
   else
-    flow="in_port($n_in_port),eth(src=50:54:00:00:00:01,dst=ff:ff:ff:ff:ff:ff),eth_type(0x8100),vlan(vid=$vlan,pcp=$pcp),encap(eth_type(0xabcd))"
+    flow="in_port($in_port),eth(src=50:54:00:00:00:01,dst=ff:ff:ff:ff:ff:ff),eth_type(0x8100),vlan(vid=$vlan,pcp=$pcp),encap(eth_type(0xabcd))"
   fi
 
   echo "----------------------------------------------------------------------"
@@ -334,9 +527,9 @@ do
   AT_CHECK([ovs-appctl ofproto/trace br0 "$flow"], [0], [stdout])
   actual=`tail -1 stdout | sed 's/Datapath actions: //'`
 
-  AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected" br0=$br0 p1=$p1 p2=$p2 p3=$p3 p4=$p4 p5=$p5 p6=$p6 p7=$p7 p8=$p8], [0], [stdout])
+  AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
   mv stdout expout
-  AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual" br0=$br0 p1=$p1 p2=$p2 p3=$p3 p4=$p4 p5=$p5 p6=$p6 p7=$p7 p8=$p8], [0], [expout])
+  AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
 done
 
 OVS_VSWITCHD_STOP
@@ -417,31 +610,22 @@ OVS_VSWITCHD_START(
         select_all=true output_port=@p3], [<0>
 ])
 
-AT_CHECK(
-  [ovs-vsctl \
-        -- get Interface p1 ofport \
-        -- get Interface p2 ofport \
-        -- get Interface p3 ofport],
-  [0], [stdout])
-set `cat stdout`
-p1=$1 p2=$2 p3=$3
-
 AT_DATA([flows.txt], [dnl
 in_port=1 actions=output:2
 in_port=2 actions=output:1
 ])
 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
 
-flow="in_port($p1),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)"
+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 br0 "$flow"], [0], [stdout])
 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
-  [Datapath actions: $p2,$p3
+  [Datapath actions: 2,3
 ])
 
-flow="in_port($p2),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)"
+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 br0 "$flow"], [0], [stdout])
 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
-  [Datapath actions: $p1,$p3
+  [Datapath actions: 1,3
 ])
 
 OVS_VSWITCHD_STOP
@@ -459,31 +643,22 @@ OVS_VSWITCHD_START(
         select_src_port=@p1 output_port=@p3], [<0>
 ])
 
-AT_CHECK(
-  [ovs-vsctl \
-        -- get Interface p1 ofport \
-        -- get Interface p2 ofport \
-        -- get Interface p3 ofport],
-  [0], [stdout])
-set `cat stdout`
-p1=$1 p2=$2 p3=$3
-
 AT_DATA([flows.txt], [dnl
 in_port=1 actions=output:2
 in_port=2 actions=output:1
 ])
 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
 
-flow="in_port($p1),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)"
+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 br0 "$flow"], [0], [stdout])
 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
-  [Datapath actions: $p2,$p3
+  [Datapath actions: 2,3
 ])
 
-flow="in_port($p2),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)"
+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 br0 "$flow"], [0], [stdout])
 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
-  [Datapath actions: $p1
+  [Datapath actions: 1
 ])
 OVS_VSWITCHD_STOP
 AT_CLEANUP
@@ -498,21 +673,13 @@ OVS_VSWITCHD_START(
         select_all=true output_port=@p2], [<0>
 ])
 
-AT_CHECK(
-  [ovs-vsctl \
-        -- get Interface p1 ofport \
-        -- get Interface p2 ofport],
-  [0], [stdout])
-set `cat stdout`
-p1=$1 p2=$2
-
 AT_CHECK([ovs-ofctl add-flow br0 action=output:1])
 
 # "in_port" defaults to OFPP_NONE if it's not specified.
 flow="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 br0 "$flow"], [0], [stdout])
 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
-  [Datapath actions: $p1,$p2
+  [Datapath actions: 1,2
 ])
 
 OVS_VSWITCHD_STOP
@@ -530,31 +697,22 @@ OVS_VSWITCHD_START(
         select_dst_port=@p2 output_port=@p3], [<0>
 ])
 
-AT_CHECK(
-  [ovs-vsctl \
-        -- get Interface p1 ofport \
-        -- get Interface p2 ofport \
-        -- get Interface p3 ofport],
-  [0], [stdout])
-set `cat stdout`
-p1=$1 p2=$2 p3=$3
-
 AT_DATA([flows.txt], [dnl
 in_port=1 actions=output:2
 in_port=2 actions=output:1
 ])
 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
 
-flow="in_port($p1),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)"
+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 br0 "$flow"], [0], [stdout])
 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
-  [Datapath actions: $p2,$p3
+  [Datapath actions: 2,3
 ])
 
-flow="in_port($p2),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)"
+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 br0 "$flow"], [0], [stdout])
 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
-  [Datapath actions: $p1
+  [Datapath actions: 1
 ])
 
 OVS_VSWITCHD_STOP
@@ -572,36 +730,27 @@ OVS_VSWITCHD_START(
         select_all=true select_vlan=11 output_port=@p3], [<0>
 ])
 
-AT_CHECK(
-  [ovs-vsctl \
-        -- get Interface p1 ofport \
-        -- get Interface p2 ofport \
-        -- get Interface p3 ofport],
-  [0], [stdout])
-set `cat stdout`
-p1=$1 p2=$2 p3=$3
-
 AT_DATA([flows.txt], [dnl
 in_port=1, actions=output:2
 ])
 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
 
-flow="in_port($p1),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)"
+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 br0 "$flow"], [0], [stdout])
 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
-  [Datapath actions: $p2
+  [Datapath actions: 2
 ])
 
-flow="in_port($p1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x8100),vlan(vid=10,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))"
+flow="in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x8100),vlan(vid=10,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 br0 "$flow"], [0], [stdout])
 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
-  [Datapath actions: $p2
+  [Datapath actions: 2
 ])
 
-flow="in_port($p1),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))"
+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 br0 "$flow"], [0], [stdout])
 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
-  [Datapath actions: $p2,$p3
+  [Datapath actions: 2,3
 ])
 
 OVS_VSWITCHD_STOP
@@ -619,31 +768,22 @@ OVS_VSWITCHD_START(
         select_all=true output_port=@p3], [<0>
 ])
 
-AT_CHECK(
-  [ovs-vsctl \
-        -- get Interface p1 ofport \
-        -- get Interface p2 ofport \
-        -- get Interface p3 ofport],
-  [0], [stdout])
-set `cat stdout`
-p1=$1 p2=$2 p3=$3
-
 AT_DATA([flows.txt], [dnl
 in_port=1 actions=mod_vlan_vid:17,output:2
 in_port=2 actions=output:1
 ])
 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
 
-flow="in_port($p1),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)"
+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 br0 "$flow"], [0], [stdout])
 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
-  [Datapath actions: push_vlan(vid=17,pcp=0),$p2,pop_vlan,$p3
+  [Datapath actions: push_vlan(vid=17,pcp=0),2,pop_vlan,3
 ])
 
-flow="in_port($p2),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)"
+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 br0 "$flow"], [0], [stdout])
 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
-  [Datapath actions: $p1,$p3
+  [Datapath actions: 1,3
 ])
 
 OVS_VSWITCHD_STOP
@@ -658,37 +798,29 @@ OVS_VSWITCHD_START(
         select_all=true output_vlan=12], [<0>
 ])
 
-AT_CHECK(
-  [ovs-vsctl \
-        -- get Interface p1 ofport \
-        -- get Interface p2 ofport],
-  [0], [stdout])
-set `cat stdout`
-br0=0 p1=$1 p2=$2
-
 AT_DATA([flows.txt], [dnl
 in_port=1 actions=output:2
 in_port=2 actions=mod_vlan_vid:17,output:1
 ])
 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
 
-flow="in_port($p1),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)"
+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 br0 "$flow"], [0], [stdout])
 actual=`tail -1 stdout | sed 's/Datapath actions: //'`
 
-expected="$p2,push_vlan(vid=12,pcp=0),$br0,$p1,$p2"
-AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected" br0=$br0 p1=$p1 p2=$p2], [0], [stdout])
+expected="2,push_vlan(vid=12,pcp=0),0,1,2"
+AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
 mv stdout expout
-AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual" br0=$br0 p1=$p1 p2=$p2], [0], [expout])
+AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
 
-flow="in_port($p2),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)"
+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 br0 "$flow"], [0], [stdout])
 actual=`tail -1 stdout | sed 's/Datapath actions: //'`
 
-expected="push_vlan(vid=17,pcp=0),$p1,pop_vlan,push_vlan(vid=12,pcp=0),$br0,$p1,$p2"
-AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected" br0=$br0 p1=$p1 p2=$p2], [0], [stdout])
+expected="push_vlan(vid=17,pcp=0),1,pop_vlan,push_vlan(vid=12,pcp=0),0,1,2"
+AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
 mv stdout expout
-AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual" br0=$br0 p1=$p1 p2=$p2], [0], [expout])
+AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
 
 OVS_VSWITCHD_STOP
 AT_CLEANUP
@@ -711,59 +843,48 @@ OVS_VSWITCHD_START(
    add-port br0 p2 -- set Interface p2 type=dummy -- \
    add-port br0 p3 -- set Interface p3 type=dummy])
 
-AT_CHECK(
-  [ovs-vsctl \
-        -- get Interface p1 ofport \
-        -- get Interface p2 ofport \
-        -- get Interface p3 ofport],
-  [0], [stdout])
-set `cat stdout`
-br0=0 p1=$1 p2=$2 p3=$3
 arp='eth_type(0x0806),arp(sip=192.168.0.1,tip=192.168.0.2,op=1,sha=50:54:00:00:00:05,tha=00:00:00:00:00:00)'
 
 # Trace an ARP packet arriving on p3, to create a MAC learning entry.
 OFPROTO_TRACE(
   [br0],
-  [in_port($p3),eth(src=50:54:00:00:00:05,dst=ff:ff:ff:ff:ff:ff),$arp],
+  [in_port(3),eth(src=50:54:00:00:00:05,dst=ff:ff:ff:ff:ff:ff),$arp],
   [-generate],
-  [$br0,$p1,$p2],
-  [br0=$br0 p1=$p1 p2=$p2 p3=$p3])
+  [0,1,2])
 
 # Check for the MAC learning entry.
-AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/[[0-9]]$/?/'], [0], [dnl
+AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/[[0-9]]\{1,\}$/?/'], [0], [dnl
  port  VLAN  MAC                Age
-    $p3     0  50:54:00:00:00:05    ?
+    3     0  50:54:00:00:00:05    ?
 ])
 
 # Trace a packet arrival destined for the learned MAC.
 # (This will also learn a MAC.)
 OFPROTO_TRACE(
   [br0],
-  [in_port($p1),eth(src=50:54:00:00:00:06,dst=50:54:00:00:00:05),$arp],
+  [in_port(1),eth(src=50:54:00:00:00:06,dst=50:54:00:00:00:05),$arp],
   [-generate],
-  [$p3],
-  [br0=$br0 p1=$p1 p2=$p2 p3=$p3])
+  [3])
 
 # Check for both MAC learning entries.
-AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/[[0-9]]$/?/'], [0], [dnl
+AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/[[0-9]]\{1,\}$/?/'], [0], [dnl
  port  VLAN  MAC                Age
-    $p3     0  50:54:00:00:00:05    ?
-    $p1     0  50:54:00:00:00:06    ?
+    3     0  50:54:00:00:00:05    ?
+    1     0  50:54:00:00:00:06    ?
 ])
 
 # Trace a packet arrival that updates the first learned MAC entry.
 OFPROTO_TRACE(
   [br0],
-  [in_port($p2),eth(src=50:54:00:00:00:05,dst=ff:ff:ff:ff:ff:ff),$arp],
+  [in_port(2),eth(src=50:54:00:00:00:05,dst=ff:ff:ff:ff:ff:ff),$arp],
   [-generate],
-  [$br0,$p1,$p3],
-  [br0=$br0 p1=$p1 p2=$p2 p3=$p3])
+  [0,1,3])
 
 # Check that the MAC learning entry was updated.
-AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/[[0-9]]$/?/'], [0], [dnl
+AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/[[0-9]]\{1,\}$/?/'], [0], [dnl
  port  VLAN  MAC                Age
-    $p1     0  50:54:00:00:00:06    ?
-    $p2     0  50:54:00:00:00:05    ?
+    1     0  50:54:00:00:00:06    ?
+    2     0  50:54:00:00:00:05    ?
 ])
 
 # Add another bridge.
@@ -773,45 +894,36 @@ AT_CHECK(
      -- set bridge br1 datapath-type=dummy \
      -- add-port br1 p4 -- set interface p4 type=dummy \
      -- add-port br1 p5 -- set interface p5 type=dummy])
-AT_CHECK(
-  [ovs-vsctl \
-        -- get Interface p4 ofport \
-        -- get Interface p5 ofport],
-  [0], [stdout])
-set `cat stdout`
-br1=0 p4=$1 p5=$2
 
 # Trace some packet arrivals in br1 to create MAC learning entries there too.
 OFPROTO_TRACE(
   [br1],
-  [in_port($p4),eth(src=50:54:00:00:00:06,dst=ff:ff:ff:ff:ff:ff),$arp],
+  [in_port(4),eth(src=50:54:00:00:00:06,dst=ff:ff:ff:ff:ff:ff),$arp],
   [-generate],
-  [$br1,$p5],
-  [br1=$br1 p4=$p4 p5=$p5])
+  [0,5])
 OFPROTO_TRACE(
   [br1],
-  [in_port($p5),eth(src=50:54:00:00:00:07,dst=ff:ff:ff:ff:ff:ff),$arp],
+  [in_port(5),eth(src=50:54:00:00:00:07,dst=ff:ff:ff:ff:ff:ff),$arp],
   [-generate],
-  [$br1,$p4],
-  [br1=$br1 p4=$p4 p5=$p5])
+  [0,4])
 
 # Check that the MAC learning entries were added.
-AT_CHECK_UNQUOTED([ovs-appctl fdb/show br1 | sed 's/[[0-9]]$/?/'], [0], [dnl
+AT_CHECK_UNQUOTED([ovs-appctl fdb/show br1 | sed 's/[[0-9]]\{1,\}$/?/'], [0], [dnl
  port  VLAN  MAC                Age
-    $p4     0  50:54:00:00:00:06    ?
-    $p5     0  50:54:00:00:00:07    ?
+    4     0  50:54:00:00:00:06    ?
+    5     0  50:54:00:00:00:07    ?
 ])
 
 # Delete port p1 and see that its MAC learning entry disappeared, and
 # that the MAC learning entry for the same MAC was also deleted from br1.
 AT_CHECK([ovs-vsctl del-port p1])
-AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/[[0-9]]$/?/'], [0], [dnl
+AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/[[0-9]]\{1,\}$/?/'], [0], [dnl
  port  VLAN  MAC                Age
-    $p2     0  50:54:00:00:00:05    ?
+    2     0  50:54:00:00:00:05    ?
 ])
-AT_CHECK_UNQUOTED([ovs-appctl fdb/show br1 | sed 's/[[0-9]]$/?/'], [0], [dnl
+AT_CHECK_UNQUOTED([ovs-appctl fdb/show br1 | sed 's/[[0-9]]\{1,\}$/?/'], [0], [dnl
  port  VLAN  MAC                Age
-    $p5     0  50:54:00:00:00:07    ?
+    5     0  50:54:00:00:00:07    ?
 ])
 
 OVS_VSWITCHD_STOP
@@ -824,8 +936,8 @@ dnl - Flow actions changing (in this case, due to MAC learning)
 dnl   cause a record to be sent.
 AT_SETUP([ofproto-dpif - NetFlow flow expiration])
 
-AT_SKIP_IF([test "x$RANDOM" = x])
-NETFLOW_PORT=`expr 32767 + \( $RANDOM % 32767 \)`
+AT_CHECK([perl $srcdir/choose-port.pl], [0], [stdout])
+NETFLOW_PORT=`cat stdout`
 
 OVS_VSWITCHD_START(
   [set Bridge br0 fail-mode=standalone -- \
@@ -837,7 +949,8 @@ OVS_VSWITCHD_START(
      add-id-to-interface=false], [<0>
 ])
 
-AT_CHECK([test-netflow --detach --pidfile $NETFLOW_PORT:127.0.0.1 > netflow.log])AT_CAPTURE_FILE([netflow.log])
+AT_CHECK([test-netflow --detach --no-chdir --pidfile $NETFLOW_PORT:127.0.0.1 > netflow.log])
+AT_CAPTURE_FILE([netflow.log])
 
 for delay in 1000 30000; do
     ovs-appctl netdev-dummy/receive p1 '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=64,frag=no),icmp(type=8,code=0)'
@@ -846,12 +959,13 @@ for delay in 1000 30000; do
     ovs-appctl time/warp $delay
 done
 
+sleep 1
 OVS_VSWITCHD_STOP
 ovs-appctl -t test-netflow exit
 
 AT_CHECK([[sed -e 's/, uptime [0-9]*//
 s/, now [0-9.]*//
-s/time \([0-9]*\)\.\.\.\1\b/time <moment>/
+s/time \([0-9]*\)\.\.\.\1$/time <moment>/
 s/time [0-9]*\.\.\.[0-9]*/time <range>/
 ' netflow.log]], [0],
   [header: v5, seq 0, engine 2,1
@@ -866,8 +980,8 @@ AT_CLEANUP
 dnl Test that basic NetFlow reports active expirations correctly.
 AT_SETUP([ofproto-dpif - NetFlow active expiration])
 
-AT_SKIP_IF([test "x$RANDOM" = x])
-NETFLOW_PORT=`expr 32767 + \( $RANDOM % 32767 \)`
+AT_CHECK([perl $srcdir/choose-port.pl], [0], [stdout])
+NETFLOW_PORT=`cat stdout`
 
 OVS_VSWITCHD_START(
   [set Bridge br0 fail-mode=standalone -- \
@@ -879,8 +993,9 @@ OVS_VSWITCHD_START(
      add-id-to-interface=false], [<0>
 ])
 
-AT_CHECK([test-netflow --detach --pidfile $NETFLOW_PORT:127.0.0.1 > netflow.log])AT_CAPTURE_FILE([netflow.log])
+AT_CHECK([test-netflow --detach --no-chdir --pidfile $NETFLOW_PORT:127.0.0.1 > netflow.log])AT_CAPTURE_FILE([netflow.log])
 
+AT_CHECK([ovs-appctl time/stop])
 n=1
 while test $n -le 60; do
     n=`expr $n + 1`
@@ -893,6 +1008,7 @@ done
 
 ovs-appctl time/warp 10000
 
+sleep 1
 OVS_VSWITCHD_STOP
 ovs-appctl -t test-netflow exit
 
@@ -944,3 +1060,130 @@ echo $n_recs
 AT_CHECK([test $n_recs -ge 13])
 
 AT_CLEANUP
+
+AT_SETUP([idle_age and hard_age increase over time])
+OVS_VSWITCHD_START
+
+# get_ages DURATION HARD IDLE
+#
+# Fetch the flow duration, hard age, and idle age into the variables
+# whose names are given as arguments.  Rounds DURATION down to the
+# nearest integer.  If hard_age doesn't appear in the output, sets
+# HARD to "none".  If idle_age doesn't appear in the output, sets IDLE
+# to 0.
+get_ages () {
+    AT_CHECK([ovs-ofctl dump-flows br0], [0], [stdout])
+
+    duration=`sed -n 's/.*duration=\([[0-9]]*\)\(\.[[0-9]]*\)\{0,1\}s.*/\1/p' stdout`
+    AT_CHECK([[expr X"$duration" : 'X[0-9][0-9]*$']], [0], [ignore])
+    AS_VAR_COPY([$1], [duration])
+
+    hard=`sed -n 's/.*hard_age=\([[0-9]]*\),.*/\1/p' stdout`
+    if test X"$hard" = X; then
+        hard=none
+    else
+        AT_CHECK([[expr X"$hard" : 'X[0-9][0-9]*$']], [0], [ignore])
+    fi
+    AS_VAR_COPY([$2], [hard])
+
+    idle=`sed -n 's/.*idle_age=\([[0-9]]*\),.*/\1/p' stdout`
+    if test X"$idle" = X; then
+        idle=0
+    else
+        AT_CHECK([[expr X"$idle" : 'X[0-9][0-9]*$']], [0], [ignore])
+    fi
+    AS_VAR_COPY([$3], [idle])
+}
+
+# Add a flow and get its initial hard and idle age.
+AT_CHECK([ovs-ofctl add-flow br0 hard_timeout=199,idle_timeout=188,actions=drop])
+get_ages duration1 hard1 idle1
+
+# Warp time forward by 10 seconds, then modify the flow's actions.
+ovs-appctl time/warp 10000
+get_ages duration2 hard2 idle2
+AT_CHECK([ovs-ofctl mod-flows br0 actions=flood])
+
+# Warp time forward by 10 seconds.
+ovs-appctl time/warp 10000
+get_ages duration3 hard3 idle3
+
+# Warp time forward 10 more seconds, then pass some packets through the flow,
+# then warp forward a few more times because idle times are only updated
+# occasionally.
+ovs-appctl time/warp 10000
+ovs-appctl netdev-dummy/receive br0 'in_port(0),eth(src=50:54:00:00:00:07,dst=50:54:00:00:00:05),eth_type(0x0800),ipv4(src=192.168.0.2,dst=192.168.0.1,proto=6,tos=0,ttl=64,frag=no),tcp(src=80,dst=1234)'
+ovs-appctl time/warp 1000
+ovs-appctl time/warp 1000
+ovs-appctl time/warp 1000
+get_ages duration4 hard4 idle4
+
+printf "duration: %4s => %4s => %4s => %4s\n" $duration1 $duration2 $duration3 $duration4
+printf "hard_age: %4s => %4s => %4s => %4s\n" $hard1 $hard2 $hard3 $hard4
+printf "idle_age: %4s => %4s => %4s => %4s\n" $idle1 $idle2 $idle3 $idle4
+
+# Duration should increase steadily over time.
+AT_CHECK([test $duration1 -lt $duration2])
+AT_CHECK([test $duration2 -lt $duration3])
+AT_CHECK([test $duration3 -lt $duration4])
+
+# Hard age should be "none" initially because it's the same as flow_duration,
+# then it should increase.
+AT_CHECK([test $hard1 = none])
+AT_CHECK([test $hard2 = none])
+AT_CHECK([test $hard3 != none])
+AT_CHECK([test $hard4 != none])
+AT_CHECK([test $hard3 -lt $hard4])
+
+# Idle age should increase from 1 to 2 to 3, then decrease.
+AT_CHECK([test $idle1 -lt $idle2])
+AT_CHECK([test $idle2 -lt $idle3])
+AT_CHECK([test $idle3 -gt $idle4])
+
+# Check some invariant relationships.
+AT_CHECK([test $duration1 = $idle1])
+AT_CHECK([test $duration2 = $idle2])
+AT_CHECK([test $duration3 = $idle3])
+AT_CHECK([test $idle3 -gt $hard3])
+AT_CHECK([test $idle4 -lt $hard4])
+AT_CHECK([test $hard4 -lt $duration4])
+
+OVS_VSWITCHD_STOP
+AT_CLEANUP
+
+AT_SETUP([ofproto-dpif - fin_timeout])
+OVS_VSWITCHD_START
+AT_DATA([flows.txt], [dnl
+in_port=1 actions=output:2
+in_port=2 actions=mod_vlan_vid:17,output:1
+])
+AT_CHECK([ovs-ofctl add-flow br0 'idle_timeout=60,actions=fin_timeout(idle_timeout=5)'])
+AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip], [0],
+[NXST_FLOW reply:
+ idle_timeout=60, actions=fin_timeout(idle_timeout=5)
+])
+# Check that a TCP SYN packet does not change the timeout.  (Because
+# flow stats updates are mainly what implements the fin_timeout
+# feature, we warp forward a couple of times to ensure that flow stats
+# run before re-checking the flow table.)
+AT_CHECK([ovs-appctl netdev-dummy/receive br0 0021853763af0026b98cb0f908004500003c2e2440004006465dac11370dac11370b828b0016751e267b00000000a00216d017360000020405b40402080a2d25085f0000000001030307], [0], [success
+])
+AT_CHECK([ovs-appctl time/warp 1000 && ovs-appctl time/warp 1000], [0], [warped
+warped
+])
+AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip], [0],
+[NXST_FLOW reply:
+ n_packets=1, n_bytes=74, idle_timeout=60, actions=fin_timeout(idle_timeout=5)
+])
+# Check that a TCP FIN packet does change the timeout.
+AT_CHECK([ovs-appctl netdev-dummy/receive br0 0021853763af0026b98cb0f90800451000342e3e40004006463bac11370dac11370b828b0016751e319dfc96399b801100717ae800000101080a2d250a9408579588], [0], [success
+])
+AT_CHECK([ovs-appctl time/warp 1000 && ovs-appctl time/warp 1000], [0], [warped
+warped
+])
+AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip], [0],
+[NXST_FLOW reply:
+ n_packets=2, n_bytes=140, idle_timeout=5, actions=fin_timeout(idle_timeout=5)
+])
+OVS_VSWITCHD_STOP
+AT_CLEANUP