lib/ofp-actions: Enforce action consistency.
[sliver-openvswitch.git] / tests / learn.at
1 AT_BANNER([learning action])
2
3 AT_SETUP([learning action - parsing and formatting])
4 AT_DATA([flows.txt], [[
5 actions=learn()
6 actions=learn(NXM_OF_VLAN_TCI[0..11], NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], output:NXM_OF_IN_PORT[], load:10->NXM_NX_REG0[5..10])
7 actions=learn(table=1,idle_timeout=10, hard_timeout=20, fin_idle_timeout=5, fin_hard_timeout=10, priority=10, cookie=0xfedcba9876543210, in_port=99,NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:NXM_OF_IN_PORT[]->NXM_NX_REG1[16..31])
8 ]])
9 AT_CHECK([ovs-ofctl parse-flows flows.txt], [0],
10 [[usable protocols: any
11 chosen protocol: OpenFlow10-table_id
12 OFPT_FLOW_MOD (xid=0x1): ADD actions=learn(table=1)
13 OFPT_FLOW_MOD (xid=0x2): ADD actions=learn(table=1,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],output:NXM_OF_IN_PORT[],load:0xa->NXM_NX_REG0[5..10])
14 OFPT_FLOW_MOD (xid=0x3): ADD actions=learn(table=1,idle_timeout=10,hard_timeout=20,fin_idle_timeout=5,fin_hard_timeout=10,priority=10,cookie=0xfedcba9876543210,in_port=99,NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:NXM_OF_IN_PORT[]->NXM_NX_REG1[16..31])
15 ]])
16 AT_CLEANUP
17
18 AT_SETUP([learning action - parsing and formatting - illegal in_port_oxm])
19 AT_CHECK([[ovs-ofctl parse-flow 'actions=learn(table=1, in_port_oxm=123456)']],
20   [1], [], [stderr])
21 AT_CHECK([sed -e 's/.*|ofp_util|WARN|//' < stderr], [0],
22   [[port 123456 is outside the supported range 0 through ffff or 0xffffff00 through 0xffffffff
23 ovs-ofctl: 123456: port value out of range for in_port_oxm
24 ]], [[]])
25 AT_CLEANUP
26
27 AT_SETUP([learning action - parsing and formatting - OXM])
28 AT_DATA([flows.txt], [[
29 actions=learn(output:OXM_OF_IN_PORT[])
30 actions=learn(table=1, in_port=1, load:OXM_OF_IN_PORT[]->NXM_NX_REG1[], load:0xfffffffe->OXM_OF_IN_PORT[])
31 ]])
32 AT_CHECK([ovs-ofctl -O OpenFlow12 parse-flows flows.txt], [0],
33 [[usable protocols: any
34 chosen protocol: OXM-OpenFlow12
35 OFPT_FLOW_MOD (OF1.2) (xid=0x1): ADD table:255 actions=learn(table=1,output:OXM_OF_IN_PORT[])
36 OFPT_FLOW_MOD (OF1.2) (xid=0x2): ADD table:255 actions=learn(table=1,in_port=1,load:OXM_OF_IN_PORT[]->NXM_NX_REG1[],load:0xfffffffe->OXM_OF_IN_PORT[])
37 ]])
38 AT_CLEANUP
39
40 AT_SETUP([learning action - examples])
41 AT_DATA([flows.txt], [[
42 # These are the examples from nicira-ext.h.
43 actions=learn(in_port=99,NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], load:NXM_OF_IN_PORT[]->NXM_NX_REG1[16..31])
44 actions=learn(NXM_OF_VLAN_TCI[0..11], NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],output:NXM_OF_IN_PORT[])
45 table=0 actions=learn(table=1,hard_timeout=10, NXM_OF_VLAN_TCI[0..11],output:NXM_OF_IN_PORT[]), resubmit(,1)
46 table=1 priority=0 actions=flood
47 ]])
48 AT_CHECK([ovs-ofctl parse-flows flows.txt], [0],
49 [[usable protocols: OXM,OpenFlow10+table_id,NXM+table_id,OpenFlow11
50 chosen protocol: OpenFlow10+table_id
51 OFPT_FLOW_MOD (xid=0x1): ADD table:255 actions=learn(table=1,in_port=99,NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],load:NXM_OF_IN_PORT[]->NXM_NX_REG1[16..31])
52 OFPT_FLOW_MOD (xid=0x2): ADD table:255 actions=learn(table=1,NXM_OF_VLAN_TCI[0..11],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],output:NXM_OF_IN_PORT[])
53 OFPT_FLOW_MOD (xid=0x3): ADD actions=learn(table=1,hard_timeout=10,NXM_OF_VLAN_TCI[0..11],output:NXM_OF_IN_PORT[]),resubmit(,1)
54 OFPT_FLOW_MOD (xid=0x4): ADD table:1 priority=0 actions=FLOOD
55 ]])
56 AT_CLEANUP
57
58 AT_SETUP([learning action - satisfied prerequisites])
59 AT_DATA([flows.txt],
60 [[actions=learn(eth_type=0x800,load:5->NXM_OF_IP_DST[])
61 ip,actions=learn(load:NXM_OF_IP_DST[]->NXM_NX_REG1[])
62 ip,actions=learn(eth_type=0x800,OXM_OF_IPV4_DST[])
63 ]])
64 AT_CHECK([ovs-ofctl parse-flows flows.txt], [0],
65 [[usable protocols: any
66 chosen protocol: OpenFlow10-table_id
67 OFPT_FLOW_MOD (xid=0x1): ADD actions=learn(table=1,eth_type=0x800,load:0x5->NXM_OF_IP_DST[])
68 OFPT_FLOW_MOD (xid=0x2): ADD ip actions=learn(table=1,load:NXM_OF_IP_DST[]->NXM_NX_REG1[])
69 OFPT_FLOW_MOD (xid=0x3): ADD ip actions=learn(table=1,eth_type=0x800,NXM_OF_IP_DST[])
70 ]])
71 AT_CLEANUP
72
73 AT_SETUP([learning action - invalid prerequisites])
74 AT_CHECK([[ovs-ofctl parse-flow 'actions=learn(load:5->NXM_OF_IP_DST[])']],
75   [1], [], [stderr])
76 AT_CHECK([sed -e 's/.*|meta_flow|WARN|//' < stderr], [0],
77   [[destination field ip_dst lacks correct prerequisites
78 destination field ip_dst lacks correct prerequisites
79 ovs-ofctl: actions are invalid with specified match (OFPBAC_MATCH_INCONSISTENT)
80 ]], [[]])
81 AT_CHECK([[ovs-ofctl parse-flow 'actions=learn(load:NXM_OF_IP_DST[]->NXM_NX_REG1[])']],
82   [1], [], [stderr])
83 AT_CHECK([sed -e 's/.*|meta_flow|WARN|//' < stderr], [0],
84   [[source field ip_dst lacks correct prerequisites
85 source field ip_dst lacks correct prerequisites
86 ovs-ofctl: actions are invalid with specified match (OFPBAC_MATCH_INCONSISTENT)
87 ]])
88 AT_CLEANUP
89
90 AT_SETUP([learning action - standard VLAN+MAC learning])
91 OVS_VSWITCHD_START(
92   [add-port br0 p1 -- set Interface p1 type=dummy ofport_request=1 -- \
93    add-port br0 p2 -- set Interface p2 type=dummy ofport_request=2 -- \
94    add-port br0 p3 -- set Interface p3 type=dummy ofport_request=3])
95 # Set up flow table for VLAN+MAC learning.
96 AT_DATA([flows.txt], [[
97 table=0 actions=learn(table=1, hard_timeout=60, NXM_OF_VLAN_TCI[0..11], NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], output:NXM_OF_IN_PORT[]), resubmit(,1)
98 table=1 priority=0 actions=flood
99 ]])
100 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
101
102 # Trace an ARP packet arriving on port 3, to create a MAC learning entry.
103 flow="in_port(3),eth(src=50:54:00:00:00:05,dst=ff:ff:ff:ff:ff:ff),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)"
104 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], [stdout])
105 actual=`tail -1 stdout | sed 's/Datapath actions: //'`
106
107 expected="1,2,100"
108 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
109 mv stdout expout
110 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
111
112 # Check for the MAC learning entry.
113 AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
114  table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:05 actions=output:3
115  table=1, priority=0 actions=FLOOD
116 NXST_FLOW reply:
117 ])
118
119 # Trace a packet arrival destined for the learned MAC.
120 # (This will also learn a MAC.)
121 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=50:54:00:00:00:06,dst=50:54:00:00:00:05),eth_type(0x0806),arp(sip=192.168.0.2,tip=192.168.0.1,op=2,sha=50:54:00:00:00:06,tha=50:54:00:00:00:05)' -generate], [0], [stdout])
122 AT_CHECK([tail -1 stdout], [0], [Datapath actions: 3
123 ])
124
125 # Check for both MAC learning entries.
126 AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip |sort], [0], [dnl
127  table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:05 actions=output:3
128  table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:06 actions=output:1
129  table=1, priority=0 actions=FLOOD
130 NXST_FLOW reply:
131 ])
132
133 # Trace a packet arrival that updates the first learned MAC entry.
134 flow="in_port(2),eth(src=50:54:00:00:00:05,dst=ff:ff:ff:ff:ff:ff),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)"
135 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], [stdout])
136 actual=`tail -1 stdout | sed 's/Datapath actions: //'`
137
138 expected="1,3,100"
139 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
140 mv stdout expout
141 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
142
143 # Check that the MAC learning entry was updated.
144 AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
145  table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:05 actions=output:2
146  table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:06 actions=output:1
147  table=1, priority=0 actions=FLOOD
148 NXST_FLOW reply:
149 ])
150 OVS_VSWITCHD_STOP
151 AT_CLEANUP
152
153 dnl This test checks that repeated uses of a "learn" action cause the
154 dnl modified time of the learned flow to advance.  Otherwise, the
155 dnl learned flow will expire after its hard timeout even though it's
156 dnl supposed to be refreshed.  (The expiration can be hard to see since
157 dnl it gets re-learned again the next time a packet appears, but
158 dnl sometimes the expiration can cause temporary flooding etc.)
159 AT_SETUP([learning action - learn refreshes hard_age])
160 OVS_VSWITCHD_START(
161   [add-port br0 p1 -- set Interface p1 type=dummy ofport_request=1 -- \
162    add-port br0 p2 -- set Interface p2 type=dummy ofport_request=2 -- \
163    add-port br0 p3 -- set Interface p3 type=dummy ofport_request=3])
164
165 ovs-appctl time/stop
166
167 # Set up flow table for MAC learning.
168 AT_DATA([flows.txt], [[
169 table=0 actions=learn(table=1, hard_timeout=10, NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], output:NXM_OF_IN_PORT[]), resubmit(,1)
170 table=1 priority=0 actions=flood
171 ]])
172 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
173
174 # Trace an ICMP packet arriving on port 3, to create a MAC learning entry.
175 flow="in_port(3),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=1,tos=0,ttl=64,frag=no),icmp(type=0,code=0)"
176 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], [stdout])
177 actual=`tail -1 stdout | sed 's/Datapath actions: //'`
178
179 expected="1,2,100"
180 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
181 mv stdout expout
182 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
183
184 # Check that the MAC learning entry appeared.
185 AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
186  table=1, hard_timeout=10, dl_dst=50:54:00:00:00:07 actions=output:3
187  table=1, priority=0 actions=FLOOD
188 NXST_FLOW reply:
189 ])
190
191 # For 25 seconds, make sure that the MAC learning entry doesn't
192 # disappear as long as we refresh it every second.
193 for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25; do
194     ovs-appctl time/warp 1000
195     AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], [stdout])
196
197     # Check that the entry is there.
198     AT_CHECK([ovs-ofctl dump-flows br0 table=1], [0], [stdout])
199     AT_CHECK([ofctl_strip < stdout | sort], [0], [dnl
200  table=1, hard_timeout=10, dl_dst=50:54:00:00:00:07 actions=output:3
201  table=1, priority=0 actions=FLOOD
202 NXST_FLOW reply:
203 ])
204
205     if test $i != 1; then
206         # Check that hard_age has appeared.  We need to do this separately
207         # from the above check because ofctl_strip removes it.  dump-flows
208         # only prints hard_age when it is different from the flow's duration
209         # (that is, the number of seconds from the time it was created),
210         # so we only check for it after we've refreshed the flow once.
211         AT_CHECK([grep dl_dst=50:54:00:00:00:07 stdout | grep -c hard_age],
212                  [0], [1
213 ])
214     fi
215 done
216
217 # Make sure that 15 seconds without refreshing makes the flow time out.
218 ovs-appctl time/warp 5000
219 ovs-appctl time/warp 5000
220 ovs-appctl time/warp 5000
221     AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
222  table=1, priority=0 actions=FLOOD
223 NXST_FLOW reply:
224 ])
225 OVS_VSWITCHD_STOP
226 AT_CLEANUP
227
228 AT_SETUP([learning action - TCPv4 port learning])
229 OVS_VSWITCHD_START(
230   [add-port br0 p1 -- set Interface p1 type=dummy -- \
231    add-port br0 p2 -- set Interface p2 type=dummy -- \
232    add-port br0 p3 -- set Interface p3 type=dummy])
233 # Set up flow table for TCPv4 port learning.
234 AT_CHECK([[ovs-ofctl add-flow br0 'table=0 tcp actions=learn(table=1, hard_timeout=60, eth_type=0x800, nw_proto=6, NXM_OF_IP_SRC[]=NXM_OF_IP_DST[], NXM_OF_IP_DST[]=NXM_OF_IP_SRC[], NXM_OF_TCP_SRC[]=NXM_OF_TCP_DST[], NXM_OF_TCP_DST[]=NXM_OF_TCP_SRC[]), flood']])
235
236 # Trace a TCPv4 packet arriving on port 3.
237 flow="in_port(3),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:06),eth_type(0x0800),ipv4(src=192.168.0.2,dst=192.168.0.1,proto=6,tos=0,ttl=64,frag=no),tcp(src=40000,dst=80)"
238 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], [stdout])
239 actual=`tail -1 stdout | sed 's/Datapath actions: //'`
240
241 expected="1,2,100"
242 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
243 mv stdout expout
244 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
245
246 # Check for the learning entry.
247 AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
248  table=1, hard_timeout=60, tcp,nw_src=192.168.0.1,nw_dst=192.168.0.2,tp_src=80,tp_dst=40000 actions=drop
249 NXST_FLOW reply:
250 ])
251 OVS_VSWITCHD_STOP
252 AT_CLEANUP
253
254 AT_SETUP([learning action - TCPv6 port learning])
255 OVS_VSWITCHD_START(
256   [add-port br0 p1 -- set Interface p1 type=dummy -- \
257    add-port br0 p2 -- set Interface p2 type=dummy -- \
258    add-port br0 p3 -- set Interface p3 type=dummy])
259 # Set up flow table for TCPv6 port learning.
260 # Also add a 128-bit-wide "load" action and a 128-bit literal match to check
261 # that they work.
262 AT_CHECK([[ovs-ofctl add-flow br0 'table=0 tcp6 actions=learn(table=1, hard_timeout=60, eth_type=0x86dd, nw_proto=6, NXM_NX_IPV6_SRC[]=NXM_NX_IPV6_DST[], ipv6_dst=2001:0db8:85a3:0000:0000:8a2e:0370:7334, NXM_OF_TCP_SRC[]=NXM_OF_TCP_DST[], NXM_OF_TCP_DST[]=NXM_OF_TCP_SRC[], load(0x20010db885a308d313198a2e03707348->NXM_NX_IPV6_DST[])), flood']])
263
264 # Trace a TCPv6 packet arriving on port 3.
265 flow="in_port(3),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:06),eth_type(0x86dd),ipv6(src=fec0::2,dst=fec0::1,label=0,proto=6,tclass=0,hlimit=255,frag=no),tcp(src=40000,dst=80)"
266 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], [stdout])
267 actual=`tail -1 stdout | sed 's/Datapath actions: //'`
268
269 expected="1,2,100"
270 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
271 mv stdout expout
272 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
273
274 # Check for the learning entry.
275 AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl
276  table=1, hard_timeout=60, tcp6,ipv6_src=fec0::1,ipv6_dst=2001:db8:85a3::8a2e:370:7334,tp_src=80,tp_dst=40000 actions=load:0x13198a2e03707348->NXM_NX_IPV6_DST[[0..63]],load:0x20010db885a308d3->NXM_NX_IPV6_DST[[64..127]]
277  tcp6 actions=learn(table=1,hard_timeout=60,eth_type=0x86dd,nw_proto=6,NXM_NX_IPV6_SRC[[]]=NXM_NX_IPV6_DST[[]],ipv6_dst=2001:db8:85a3::8a2e:370:7334,NXM_OF_TCP_SRC[[]]=NXM_OF_TCP_DST[[]],NXM_OF_TCP_DST[[]]=NXM_OF_TCP_SRC[[]],load:0x20010db885a308d313198a2e03707348->NXM_NX_IPV6_DST[[]]),FLOOD
278 NXST_FLOW reply:
279 ])
280 OVS_VSWITCHD_STOP
281 AT_CLEANUP
282
283 # In this use of a learn action, the first packet in the flow creates
284 # a new flow that changes the behavior of subsequent packets in the
285 # flow.
286 AT_SETUP([learning action - self-modifying flow])
287 OVS_VSWITCHD_START
288 ADD_OF_PORTS([br0], 1, 2, 3)
289
290 ovs-appctl time/stop
291 # Set up flow table for TCPv4 port learning.
292 AT_CHECK([[ovs-ofctl add-flow br0 'actions=load:3->NXM_NX_REG0[0..15],learn(table=0,priority=65535,NXM_OF_ETH_SRC[],NXM_OF_VLAN_TCI[0..11],output:NXM_NX_REG0[0..15]),output:2']])
293
294 # Trace some packets arriving.  The particular packets don't matter.
295 for i in 1 2 3 4 5 6 7 8 9 10; do
296     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)'
297     ovs-appctl time/warp 10
298 done
299
300 # Check for the learning entry.
301 ovs-appctl time/warp 1000
302 AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0],
303 [[ n_packets=1, n_bytes=60, actions=load:0x3->NXM_NX_REG0[0..15],learn(table=0,priority=65535,NXM_OF_ETH_SRC[],NXM_OF_VLAN_TCI[0..11],output:NXM_NX_REG0[0..15]),output:2
304  n_packets=9, n_bytes=540, priority=65535,vlan_tci=0x0000/0x0fff,dl_src=50:54:00:00:00:05 actions=output:3
305 NXST_FLOW reply:
306 ]])
307
308 # Check that the first packet went out port 2 and the rest out port 3.
309 AT_CHECK(
310   [(ovs-ofctl dump-ports br0 2; ovs-ofctl dump-ports br0 3) | STRIP_XIDS], [0],
311   [OFPST_PORT reply: 1 ports
312   port  2: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0
313            tx pkts=1, bytes=60, drop=0, errs=0, coll=0
314 OFPST_PORT reply: 1 ports
315   port  3: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0
316            tx pkts=9, bytes=540, drop=0, errs=0, coll=0
317 ])
318 OVS_VSWITCHD_STOP
319 AT_CLEANUP
320
321 AT_SETUP([learning action - fin_timeout feature])
322 # This is a totally artificial use of the "learn" action.  The only purpose
323 # is to check that specifying fin_idle_timeout or fin_hard_timeout causes
324 # a corresponding fin_timeout action to end up in the learned flows.
325 OVS_VSWITCHD_START(
326     [add-port br0 p1 -- set Interface p1 type=dummy ofport_request=1])
327 AT_CHECK([[ovs-ofctl add-flow br0 'actions=learn(fin_hard_timeout=10, fin_idle_timeout=5, NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], output:NXM_OF_IN_PORT[])']])
328 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=50:54:00:00:00:05,dst=ff:ff:ff:ff:ff:ff),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)' -generate], [0], [ignore])
329 AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip], [0],
330 [NXST_FLOW reply:
331  table=1, dl_dst=50:54:00:00:00:05 actions=fin_timeout(idle_timeout=5,hard_timeout=10),output:1
332 ])
333 OVS_VSWITCHD_STOP
334 AT_CLEANUP