1 AT_BANNER([learning action])
3 AT_SETUP([learning action - parsing and formatting])
4 AT_DATA([flows.txt], [[
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])
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])
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)']],
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
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[])
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 actions=learn(table=1,output:OXM_OF_IN_PORT[])
36 OFPT_FLOW_MOD (OF1.2) (xid=0x2): ADD actions=learn(table=1,in_port=1,load:OXM_OF_IN_PORT[]->NXM_NX_REG1[],load:0xfffffffe->OXM_OF_IN_PORT[])
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
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
58 AT_SETUP([learning action - satisfied prerequisites])
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[])
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[])
73 AT_SETUP([learning action - invalid prerequisites])
74 AT_CHECK([[ovs-ofctl parse-flow 'actions=learn(load:5->NXM_OF_IP_DST[])']],
76 AT_CHECK([sed -e 's/.*|meta_flow|WARN|//' < stderr], [0],
77 [[destination field ip_dst lacks correct prerequisites
78 ovs-ofctl: actions are invalid with specified match (OFPBAC_MATCH_INCONSISTENT)
80 AT_CHECK([[ovs-ofctl parse-flow 'actions=learn(load:NXM_OF_IP_DST[]->NXM_NX_REG1[])']],
82 AT_CHECK([sed -e 's/.*|meta_flow|WARN|//' < stderr], [0],
83 [[source field ip_dst lacks correct prerequisites
84 ovs-ofctl: actions are invalid with specified match (OFPBAC_MATCH_INCONSISTENT)
88 AT_SETUP([learning action - standard VLAN+MAC learning])
90 [add-port br0 p1 -- set Interface p1 type=dummy ofport_request=1 -- \
91 add-port br0 p2 -- set Interface p2 type=dummy ofport_request=2 -- \
92 add-port br0 p3 -- set Interface p3 type=dummy ofport_request=3])
93 # Set up flow table for VLAN+MAC learning.
94 AT_DATA([flows.txt], [[
95 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)
96 table=1 priority=0 actions=flood
98 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
100 # Trace an ARP packet arriving on port 3, to create a MAC learning entry.
101 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)"
102 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], [stdout])
103 actual=`tail -1 stdout | sed 's/Datapath actions: //'`
106 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
108 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
110 # Check for the MAC learning entry.
111 AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
112 table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:05 actions=output:3
113 table=1, priority=0 actions=FLOOD
117 # Trace a packet arrival destined for the learned MAC.
118 # (This will also learn a MAC.)
119 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])
120 AT_CHECK([tail -1 stdout], [0], [Datapath actions: 3
123 # Check for both MAC learning entries.
124 AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip |sort], [0], [dnl
125 table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:05 actions=output:3
126 table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:06 actions=output:1
127 table=1, priority=0 actions=FLOOD
131 # Trace a packet arrival that updates the first learned MAC entry.
132 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)"
133 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], [stdout])
134 actual=`tail -1 stdout | sed 's/Datapath actions: //'`
137 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
139 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
141 # Check that the MAC learning entry was updated.
142 AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
143 table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:05 actions=output:2
144 table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:06 actions=output:1
145 table=1, priority=0 actions=FLOOD
151 dnl This test checks that repeated uses of a "learn" action cause the
152 dnl modified time of the learned flow to advance. Otherwise, the
153 dnl learned flow will expire after its hard timeout even though it's
154 dnl supposed to be refreshed. (The expiration can be hard to see since
155 dnl it gets re-learned again the next time a packet appears, but
156 dnl sometimes the expiration can cause temporary flooding etc.)
157 AT_SETUP([learning action - learn refreshes hard_age])
159 [add-port br0 p1 -- set Interface p1 type=dummy ofport_request=1 -- \
160 add-port br0 p2 -- set Interface p2 type=dummy ofport_request=2 -- \
161 add-port br0 p3 -- set Interface p3 type=dummy ofport_request=3])
165 # Set up flow table for MAC learning.
166 AT_DATA([flows.txt], [[
167 table=0 actions=learn(table=1, hard_timeout=10, NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], output:NXM_OF_IN_PORT[]), resubmit(,1)
168 table=1 priority=0 actions=flood
170 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
172 # Trace an ICMP packet arriving on port 3, to create a MAC learning entry.
173 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)"
174 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], [stdout])
175 actual=`tail -1 stdout | sed 's/Datapath actions: //'`
178 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
180 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
182 # Check that the MAC learning entry appeared.
183 AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
184 table=1, hard_timeout=10, dl_dst=50:54:00:00:00:07 actions=output:3
185 table=1, priority=0 actions=FLOOD
189 # For 25 seconds, make sure that the MAC learning entry doesn't
190 # disappear as long as we refresh it every second.
191 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
192 ovs-appctl time/warp 1000
193 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], [stdout])
195 # Check that the entry is there.
196 AT_CHECK([ovs-ofctl dump-flows br0 table=1], [0], [stdout])
197 AT_CHECK([ofctl_strip < stdout | sort], [0], [dnl
198 table=1, hard_timeout=10, dl_dst=50:54:00:00:00:07 actions=output:3
199 table=1, priority=0 actions=FLOOD
203 if test $i != 1; then
204 # Check that hard_age has appeared. We need to do this separately
205 # from the above check because ofctl_strip removes it. dump-flows
206 # only prints hard_age when it is different from the flow's duration
207 # (that is, the number of seconds from the time it was created),
208 # so we only check for it after we've refreshed the flow once.
209 AT_CHECK([grep dl_dst=50:54:00:00:00:07 stdout | grep -c hard_age],
215 # Make sure that 15 seconds without refreshing makes the flow time out.
216 ovs-appctl time/warp 5000
217 ovs-appctl time/warp 5000
218 ovs-appctl time/warp 5000
219 AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
220 table=1, priority=0 actions=FLOOD
226 AT_SETUP([learning action - TCPv4 port learning])
228 [add-port br0 p1 -- set Interface p1 type=dummy -- \
229 add-port br0 p2 -- set Interface p2 type=dummy -- \
230 add-port br0 p3 -- set Interface p3 type=dummy])
231 # Set up flow table for TCPv4 port learning.
232 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']])
234 # Trace a TCPv4 packet arriving on port 3.
235 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)"
236 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], [stdout])
237 actual=`tail -1 stdout | sed 's/Datapath actions: //'`
240 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
242 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
244 # Check for the learning entry.
245 AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
246 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
252 AT_SETUP([learning action - TCPv6 port learning])
254 [add-port br0 p1 -- set Interface p1 type=dummy -- \
255 add-port br0 p2 -- set Interface p2 type=dummy -- \
256 add-port br0 p3 -- set Interface p3 type=dummy])
257 # Set up flow table for TCPv6 port learning.
258 # Also add a 128-bit-wide "load" action and a 128-bit literal match to check
260 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']])
262 # Trace a TCPv6 packet arriving on port 3.
263 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)"
264 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], [stdout])
265 actual=`tail -1 stdout | sed 's/Datapath actions: //'`
268 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
270 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
272 # Check for the learning entry.
273 AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl
274 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]]
275 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
281 # In this use of a learn action, the first packet in the flow creates
282 # a new flow that changes the behavior of subsequent packets in the
284 AT_SETUP([learning action - self-modifying flow])
286 ADD_OF_PORTS([br0], 1, 2, 3)
289 # Set up flow table for TCPv4 port learning.
290 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']])
292 # Trace some packets arriving. The particular packets don't matter.
293 for i in 1 2 3 4 5 6 7 8 9 10; do
294 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)'
295 ovs-appctl time/warp 10
296 if [[ $i -eq 1 ]]; then
301 # Check for the learning entry.
302 ovs-appctl time/warp 1000
303 AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0],
304 [[ 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
305 n_packets=9, n_bytes=540, priority=65535,vlan_tci=0x0000/0x0fff,dl_src=50:54:00:00:00:05 actions=output:3
309 # Check that the first packet went out port 2 and the rest out port 3.
311 [(ovs-ofctl dump-ports br0 2; ovs-ofctl dump-ports br0 3) | STRIP_XIDS], [0],
312 [OFPST_PORT reply: 1 ports
313 port 2: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0
314 tx pkts=1, bytes=60, drop=0, errs=0, coll=0
315 OFPST_PORT reply: 1 ports
316 port 3: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0
317 tx pkts=9, bytes=540, drop=0, errs=0, coll=0
323 # This test is much like the previous, but adds idle timeouts and sends
324 # two different flows to the bridge. This tests that the statistics are
325 # attributed correctly.
326 AT_SETUP([learning action - self-modifying flow with idle_timeout])
328 ADD_OF_PORTS([br0], 1, 2, 3)
331 # Set up flow table for TCPv4 port learning.
332 AT_CHECK([[ovs-ofctl add-flow br0 'actions=load:3->NXM_NX_REG0[0..15],learn(table=0,idle_timeout=5,priority=65535,NXM_OF_ETH_SRC[],NXM_OF_VLAN_TCI[0..11],output:NXM_NX_REG0[0..15]),output:2']])
334 # Trace some packets arriving. The particular packets don't matter.
335 for i in `seq 1 10`; do
336 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)'
337 ovs-appctl time/warp 10
338 if [[ $i -eq 1 ]]; then
343 # Trace some packets arriving. This is is a different flow from the previous.
344 # Note that we advance time by 1 second between each packet here.
345 for i in `seq 1 10`; do
346 ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:06,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)'
347 ovs-appctl time/warp 1000
348 if [[ $i -eq 1 ]]; then
353 # Check that the first packet of each flow went out port 2 and the rest out
356 [(ovs-ofctl dump-ports br0 2; ovs-ofctl dump-ports br0 3) | STRIP_XIDS], [0],
357 [OFPST_PORT reply: 1 ports
358 port 2: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0
359 tx pkts=2, bytes=120, drop=0, errs=0, coll=0
360 OFPST_PORT reply: 1 ports
361 port 3: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0
362 tx pkts=18, bytes=1080, drop=0, errs=0, coll=0
365 # Check for the learning entry.
366 ovs-appctl time/warp 1000
367 AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0],
368 [[ n_packets=2, n_bytes=120, actions=load:0x3->NXM_NX_REG0[0..15],learn(table=0,idle_timeout=5,priority=65535,NXM_OF_ETH_SRC[],NXM_OF_VLAN_TCI[0..11],output:NXM_NX_REG0[0..15]),output:2
369 n_packets=9, n_bytes=540, idle_timeout=5, priority=65535,vlan_tci=0x0000/0x0fff,dl_src=50:54:00:00:00:06 actions=output:3
375 # This test is much like the previous, but adds hard timeouts and sends
376 # two different flows to the bridge. This tests that the statistics are
377 # attributed correctly.
378 AT_SETUP([learning action - self-modifying flow with hard_timeout])
380 ADD_OF_PORTS([br0], 1, 2, 3)
383 # Set up flow table for TCPv4 port learning.
384 AT_CHECK([[ovs-ofctl add-flow br0 'actions=load:3->NXM_NX_REG0[0..15],learn(table=0,hard_timeout=10,priority=65535,NXM_OF_ETH_SRC[],NXM_OF_VLAN_TCI[0..11],output:NXM_NX_REG0[0..15]),output:2']])
386 # Trace some packets arriving. The particular packets don't matter.
387 for i in `seq 1 10`; do
388 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)'
389 if [[ $i -eq 1 ]]; then
392 ovs-appctl time/warp 10
395 # Trace some packets arriving. This is is a different flow from the previous.
396 # Note that we advance time by 2 second between each packet here.
397 for i in `seq 1 10`; do
398 ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:06,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)'
399 # Note: hard_timeout should fire immediately after #6 packet.
400 # #7 packet re-install the flow and the following 3 packets
401 # (#8, #9, #10) use the flow.
402 # it's difficult to predict the exact timing of rule expiry
403 # because it's affected by flow dumper thread via udpif_dump_seq.
404 # hard_timeout value for this test was chosen to overcome the uncertainty.
405 if [[ $i -eq 1 -o $i -eq 6 -o $i -eq 7 ]]; then
408 ovs-appctl time/warp 2000
411 # Check that the first packet of each flow went out port 2 and the rest out
414 [(ovs-ofctl dump-ports br0 2; ovs-ofctl dump-ports br0 3) | STRIP_XIDS], [0],
415 [OFPST_PORT reply: 1 ports
416 port 2: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0
417 tx pkts=3, bytes=180, drop=0, errs=0, coll=0
418 OFPST_PORT reply: 1 ports
419 port 3: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0
420 tx pkts=17, bytes=1020, drop=0, errs=0, coll=0
423 # Check for the learning entry.
424 ovs-appctl time/warp 1000
426 AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0],
427 [[ n_packets=3, n_bytes=180, actions=load:0x3->NXM_NX_REG0[0..15],learn(table=0,hard_timeout=10,priority=65535,NXM_OF_ETH_SRC[],NXM_OF_VLAN_TCI[0..11],output:NXM_NX_REG0[0..15]),output:2
428 n_packets=3, n_bytes=180, hard_timeout=10, priority=65535,vlan_tci=0x0000/0x0fff,dl_src=50:54:00:00:00:06 actions=output:3
434 AT_SETUP([learning action - fin_timeout feature])
435 # This is a totally artificial use of the "learn" action. The only purpose
436 # is to check that specifying fin_idle_timeout or fin_hard_timeout causes
437 # a corresponding fin_timeout action to end up in the learned flows.
439 [add-port br0 p1 -- set Interface p1 type=dummy ofport_request=1])
440 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[])']])
441 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])
442 AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip], [0],
444 table=1, dl_dst=50:54:00:00:00:05 actions=fin_timeout(idle_timeout=5,hard_timeout=10),output:1