Setting tag sliver-openvswitch-2.2.90-1
[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,OXM-OpenFlow14
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,OXM-OpenFlow14
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[])
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,OXM-OpenFlow14
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,OXM-OpenFlow14
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 ovs-ofctl: actions are invalid with specified match (OFPBAC_MATCH_INCONSISTENT)
79 ]], [[]])
80 AT_CHECK([[ovs-ofctl parse-flow 'actions=learn(load:NXM_OF_IP_DST[]->NXM_NX_REG1[])']],
81   [1], [], [stderr])
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)
85 ]])
86 AT_CLEANUP
87
88 AT_SETUP([learning action - standard VLAN+MAC learning])
89 OVS_VSWITCHD_START(
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
97 ]])
98 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
99
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: //'`
104
105 expected="1,2,100"
106 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
107 mv stdout expout
108 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
109
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
114 NXST_FLOW reply:
115 ])
116
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
121 ])
122
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
128 NXST_FLOW reply:
129 ])
130
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: //'`
135
136 expected="1,3,100"
137 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
138 mv stdout expout
139 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
140
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
146 NXST_FLOW reply:
147 ])
148 OVS_VSWITCHD_STOP
149 AT_CLEANUP
150
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])
158 OVS_VSWITCHD_START(
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])
162
163 ovs-appctl time/stop
164
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
169 ]])
170 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
171
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: //'`
176
177 expected="1,2,100"
178 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
179 mv stdout expout
180 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
181
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
186 NXST_FLOW reply:
187 ])
188
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])
194
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
200 NXST_FLOW reply:
201 ])
202
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],
210                  [0], [1
211 ])
212     fi
213 done
214
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 sleep 1
220 AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
221  table=1, priority=0 actions=FLOOD
222 NXST_FLOW reply:
223 ])
224 OVS_VSWITCHD_STOP
225 AT_CLEANUP
226
227 AT_SETUP([learning action - TCPv4 port learning])
228 OVS_VSWITCHD_START(
229   [add-port br0 p1 -- set Interface p1 type=dummy -- \
230    add-port br0 p2 -- set Interface p2 type=dummy -- \
231    add-port br0 p3 -- set Interface p3 type=dummy])
232 # Set up flow table for TCPv4 port learning.
233 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
235 # Trace a TCPv4 packet arriving on port 3.
236 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)"
237 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], [stdout])
238 actual=`tail -1 stdout | sed 's/Datapath actions: //'`
239
240 expected="1,2,100"
241 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
242 mv stdout expout
243 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
244
245 # Check for the learning entry.
246 AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
247  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
248 NXST_FLOW reply:
249 ])
250 OVS_VSWITCHD_STOP
251 AT_CLEANUP
252
253 AT_SETUP([learning action - TCPv6 port learning])
254 OVS_VSWITCHD_START(
255   [add-port br0 p1 -- set Interface p1 type=dummy -- \
256    add-port br0 p2 -- set Interface p2 type=dummy -- \
257    add-port br0 p3 -- set Interface p3 type=dummy])
258 # Set up flow table for TCPv6 port learning.
259 # Also add a 128-bit-wide "load" action and a 128-bit literal match to check
260 # that they work.
261 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
263 # Trace a TCPv6 packet arriving on port 3.
264 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)"
265 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], [stdout])
266 actual=`tail -1 stdout | sed 's/Datapath actions: //'`
267
268 expected="1,2,100"
269 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
270 mv stdout expout
271 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
272
273 # Check for the learning entry.
274 AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl
275  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]]
276  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
277 NXST_FLOW reply:
278 ])
279 OVS_VSWITCHD_STOP
280 AT_CLEANUP
281
282 # In this use of a learn action, the first packet in the flow creates
283 # a new flow that changes the behavior of subsequent packets in the
284 # flow.
285 AT_SETUP([learning action - self-modifying flow])
286 OVS_VSWITCHD_START
287 ADD_OF_PORTS([br0], 1, 2, 3)
288
289 ovs-appctl time/stop
290 # Set up flow table for TCPv4 port learning.
291 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
293 # Trace some packets arriving.  The particular packets don't matter.
294 for i in 1 2 3 4 5 6 7 8 9 10; do
295     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)'
296     ovs-appctl time/warp 10
297     if [[ $i -eq 1 ]]; then
298         sleep 1
299     fi
300 done
301
302 # Check for the learning entry.
303 ovs-appctl time/warp 1000
304 AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0],
305 [[ 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
306  n_packets=9, n_bytes=540, priority=65535,vlan_tci=0x0000/0x0fff,dl_src=50:54:00:00:00:05 actions=output:3
307 NXST_FLOW reply:
308 ]])
309
310 # Check that the first packet went out port 2 and the rest out port 3.
311 AT_CHECK(
312   [(ovs-ofctl dump-ports br0 2; ovs-ofctl dump-ports br0 3) | STRIP_XIDS], [0],
313   [OFPST_PORT reply: 1 ports
314   port  2: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0
315            tx pkts=1, bytes=60, drop=0, errs=0, coll=0
316 OFPST_PORT reply: 1 ports
317   port  3: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0
318            tx pkts=9, bytes=540, drop=0, errs=0, coll=0
319 ])
320
321 OVS_VSWITCHD_STOP
322 AT_CLEANUP
323
324 # This test is much like the previous, but adds idle timeouts and sends
325 # two different flows to the bridge. This tests that the statistics are
326 # attributed correctly.
327 AT_SETUP([learning action - self-modifying flow with idle_timeout])
328 OVS_VSWITCHD_START
329 ADD_OF_PORTS([br0], 1, 2, 3)
330
331 ovs-appctl time/stop
332 # Set up flow table for TCPv4 port learning.
333 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
335 # Trace some packets arriving.  The particular packets don't matter.
336 for i in `seq 1 10`; do
337     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)'
338     ovs-appctl time/warp 10
339     if [[ $i -eq 1 ]]; then
340         sleep 1
341     fi
342 done
343
344 # Trace some packets arriving.  This is is a different flow from the previous.
345 # Note that we advance time by 1 second between each packet here.
346 for i in `seq 1 10`; do
347     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)'
348     ovs-appctl time/warp 1000
349     # Note: netdev-dummy/receive merely queues the packet.
350     # We need to wait for other thread to process the packet
351     # and update the flow's 'used' for the packet.
352     # (i % 3 == 0) below is somehow arbitrary but chosen to ensure
353     # that we update the flow's 'used' frequently enough to prevent
354     # idle_timeout.
355     if [[ $i -eq 1 -o $((i % 3)) -eq 0 ]]; then
356         sleep 1
357     fi
358 done
359
360 # Check that the first packet of each flow went out port 2 and the rest out
361 # port 3.
362 AT_CHECK(
363   [(ovs-ofctl dump-ports br0 2; ovs-ofctl dump-ports br0 3) | STRIP_XIDS], [0],
364   [OFPST_PORT reply: 1 ports
365   port  2: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0
366            tx pkts=2, bytes=120, drop=0, errs=0, coll=0
367 OFPST_PORT reply: 1 ports
368   port  3: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0
369            tx pkts=18, bytes=1080, drop=0, errs=0, coll=0
370 ])
371
372 # Check for the learning entry.
373 ovs-appctl time/warp 1000
374 AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0],
375 [[ 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
376  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
377 NXST_FLOW reply:
378 ]])
379 OVS_VSWITCHD_STOP
380 AT_CLEANUP
381
382 # This test is much like the previous, but adds hard timeouts and sends
383 # two different flows to the bridge. This tests that the statistics are
384 # attributed correctly.
385 AT_SETUP([learning action - self-modifying flow with hard_timeout])
386 OVS_VSWITCHD_START
387 ADD_OF_PORTS([br0], 1, 2, 3)
388
389 ovs-appctl time/stop
390 # Set up flow table for TCPv4 port learning.
391 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']])
392
393 # Trace some packets arriving.  The particular packets don't matter.
394 for i in `seq 1 10`; do
395     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)'
396     if [[ $i -eq 1 ]]; then
397         sleep 1
398     fi
399     ovs-appctl time/warp 10
400 done
401
402 # Trace some packets arriving.  This is is a different flow from the previous.
403 # Note that we advance time by 2 second between each packet here.
404 for i in `seq 1 10`; do
405     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)'
406     # Note: hard_timeout should fire immediately after #6 packet.
407     # #7 packet re-install the flow and the following 3 packets
408     # (#8, #9, #10) use the flow.
409     # it's difficult to predict the exact timing of rule expiry
410     # because it's affected by flow dumper thread via udpif_dump_seq.
411     # hard_timeout value for this test was chosen to overcome the uncertainty.
412     #
413     # receive #1  learn, install flow with hard_timeout=10
414     #  sleep to ensure the flow installation
415     #  (warp, timeout left 8s)
416     # receive #2   the learned flow
417     #  (warp, timeout left 6s)
418     # receive #3
419     #  (warp, timeout left 4s)
420     # receive #4
421     #  (warp, timeout left 2s)
422     # receive #5
423     #  (warp, timeout left 0s)
424     #  NOTE: OVS does not consider this expired yet.  cf. rule_expire()
425     # receive #6
426     #  (warp, timeout left -2s)
427     #  sleep to ensure flow expiration
428     # receive #7  learn, install flow with hard_timeout=10
429     #  sleep to ensure the flow installation
430     #  (warp, timeout left 8s)
431     # receive #8
432     #  (warp, timeout left 6s)
433     # receive #9
434     #  (warp, timeout left 4s)
435     # receive #10
436     #  (warp, timeout left 2s)
437     if [[ $i -eq 1 -o $i -eq 7 ]]; then
438         sleep 1
439     fi
440     ovs-appctl time/warp 2000
441     if [[ $i -eq 6 ]]; then
442         sleep 1
443     fi
444 done
445
446 # Check that the first packet of each flow went out port 2 and the rest out
447 # port 3.
448 AT_CHECK(
449   [(ovs-ofctl dump-ports br0 2; ovs-ofctl dump-ports br0 3) | STRIP_XIDS], [0],
450   [OFPST_PORT reply: 1 ports
451   port  2: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0
452            tx pkts=3, bytes=180, drop=0, errs=0, coll=0
453 OFPST_PORT reply: 1 ports
454   port  3: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0
455            tx pkts=17, bytes=1020, drop=0, errs=0, coll=0
456 ])
457
458 # Check for the learning entry.
459 ovs-appctl time/warp 1000
460 sleep 1
461 AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0],
462 [[ 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
463  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
464 NXST_FLOW reply:
465 ]])
466 OVS_VSWITCHD_STOP
467 AT_CLEANUP
468
469 AT_SETUP([learning action - fin_timeout feature])
470 # This is a totally artificial use of the "learn" action.  The only purpose
471 # is to check that specifying fin_idle_timeout or fin_hard_timeout causes
472 # a corresponding fin_timeout action to end up in the learned flows.
473 OVS_VSWITCHD_START(
474     [add-port br0 p1 -- set Interface p1 type=dummy ofport_request=1])
475 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[])']])
476 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])
477 AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip], [0],
478 [NXST_FLOW reply:
479  table=1, dl_dst=50:54:00:00:00:05 actions=fin_timeout(idle_timeout=5,hard_timeout=10),output:1
480 ])
481 OVS_VSWITCHD_STOP
482 AT_CLEANUP