]> git.proxmox.com Git - mirror_ovs.git/blob - tests/learn.at
ofproto-dpif: Expose datapath capability to ovsdb.
[mirror_ovs.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(send_flow_rem)
7 actions=learn(delete_learned)
8 actions=learn(send_flow_rem,delete_learned)
9 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])
10 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,eth_dst=eth_src,load:in_port->reg1[16..31])
11 actions=learn(limit=4096)
12 actions=learn(limit=4096,result_dst=reg0[0])
13 ]])
14 AT_CHECK([ovs-ofctl parse-flows flows.txt], [0],
15 [[usable protocols: any
16 chosen protocol: OpenFlow10-table_id
17 OFPT_FLOW_MOD (xid=0x1): ADD actions=learn(table=1)
18 OFPT_FLOW_MOD (xid=0x2): ADD actions=learn(table=1,send_flow_rem)
19 OFPT_FLOW_MOD (xid=0x3): ADD actions=learn(table=1,delete_learned)
20 OFPT_FLOW_MOD (xid=0x4): ADD actions=learn(table=1,send_flow_rem,delete_learned)
21 OFPT_FLOW_MOD (xid=0x5): 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])
22 OFPT_FLOW_MOD (xid=0x6): 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])
23 OFPT_FLOW_MOD (xid=0x7): ADD actions=learn(table=1,limit=4096)
24 OFPT_FLOW_MOD (xid=0x8): ADD actions=learn(table=1,limit=4096,result_dst=NXM_NX_REG0[0])
25 ]])
26 AT_CLEANUP
27
28 AT_SETUP([learning action - parsing and formatting - illegal in_port_oxm])
29 AT_CHECK([[ovs-ofctl parse-flow 'actions=learn(table=1, in_port_oxm=123456)']],
30 [1], [], [stderr])
31 AT_CHECK([sed -e 's/.*|ofp_port|WARN|//' < stderr], [0],
32 [[port 123456 is outside the supported range 0 through ffff or 0xffffff00 through 0xffffffff
33 ovs-ofctl: table=1, in_port_oxm=123456: in_port_oxm value 123456 cannot be parsed as a subfield (123456: unknown field `123456') or an immediate value (123456: port value out of range for in_port_oxm)
34 ]], [[]])
35 AT_CLEANUP
36
37 AT_SETUP([learning action - parsing and formatting - OXM])
38 AT_DATA([flows.txt], [[
39 actions=learn(output:OXM_OF_IN_PORT[])
40 actions=learn(table=1, in_port=1, load:OXM_OF_IN_PORT[]->NXM_NX_REG1[], load:0xfffffffe->OXM_OF_IN_PORT[])
41 ]])
42 AT_CHECK([ovs-ofctl -O OpenFlow12 parse-flows flows.txt], [0],
43 [[usable protocols: any
44 chosen protocol: OXM-OpenFlow12
45 OFPT_FLOW_MOD (OF1.2) (xid=0x1): ADD actions=learn(table=1,output:OXM_OF_IN_PORT[])
46 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[])
47 ]])
48 AT_CLEANUP
49
50 AT_SETUP([learning action - examples])
51 AT_DATA([flows.txt], [[
52 # These are the examples from ofp-actions.c.
53 actions=learn(in_port=99,NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], load:NXM_OF_IN_PORT[]->NXM_NX_REG1[16..31])
54 actions=learn(NXM_OF_VLAN_TCI[0..11], NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],output:NXM_OF_IN_PORT[])
55 table=0 actions=learn(table=1,hard_timeout=10, NXM_OF_VLAN_TCI[0..11],output:NXM_OF_IN_PORT[]), resubmit(,1)
56 table=1 priority=0 actions=flood
57 ]])
58 AT_CHECK([ovs-ofctl parse-flows flows.txt], [0],
59 [[usable protocols: OXM,OpenFlow10+table_id,NXM+table_id,OpenFlow11
60 chosen protocol: OpenFlow10+table_id
61 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])
62 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[])
63 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)
64 OFPT_FLOW_MOD (xid=0x4): ADD table:1 priority=0 actions=FLOOD
65 ]])
66 AT_CLEANUP
67
68 AT_SETUP([learning action - satisfied prerequisites])
69 AT_DATA([flows.txt],
70 [[actions=learn(eth_type=0x800,load:5->NXM_OF_IP_DST[])
71 ip,actions=learn(load:NXM_OF_IP_DST[]->NXM_NX_REG1[])
72 ip,actions=learn(eth_type=0x800,OXM_OF_IPV4_DST[])
73 ]])
74 AT_CHECK([ovs-ofctl parse-flows flows.txt], [0],
75 [[usable protocols: any
76 chosen protocol: OpenFlow10-table_id
77 OFPT_FLOW_MOD (xid=0x1): ADD actions=learn(table=1,eth_type=0x800,load:0x5->NXM_OF_IP_DST[])
78 OFPT_FLOW_MOD (xid=0x2): ADD ip actions=learn(table=1,load:NXM_OF_IP_DST[]->NXM_NX_REG1[])
79 OFPT_FLOW_MOD (xid=0x3): ADD ip actions=learn(table=1,eth_type=0x800,NXM_OF_IP_DST[])
80 ]])
81 AT_CLEANUP
82
83 AT_SETUP([learning action - invalid prerequisites])
84 AT_CHECK([[ovs-ofctl parse-flow 'actions=learn(load:5->NXM_OF_IP_DST[])']],
85 [1], [], [stderr])
86 AT_CHECK([sed -e 's/.*|meta_flow|WARN|//' < stderr], [0],
87 [[destination field ip_dst lacks correct prerequisites
88 ovs-ofctl: actions are invalid with specified match (OFPBAC_MATCH_INCONSISTENT)
89 ]], [[]])
90 AT_CHECK([[ovs-ofctl parse-flow 'actions=learn(load:NXM_OF_IP_DST[]->NXM_NX_REG1[])']],
91 [1], [], [stderr])
92 AT_CHECK([sed -e 's/.*|meta_flow|WARN|//' < stderr], [0],
93 [[source field ip_dst lacks correct prerequisites
94 ovs-ofctl: actions are invalid with specified match (OFPBAC_MATCH_INCONSISTENT)
95 ]])
96 AT_CLEANUP
97
98 AT_SETUP([learning action - too-long immediate value])
99 dnl 129 bits is too long.
100 AT_CHECK([[ovs-ofctl parse-flow 'actions=learn(load:0x1fedbca9876543210fedbca9876543210->NXM_NX_IPV6_DST[])']],
101 [1], [], [[ovs-ofctl: 0x1fedbca9876543210fedbca9876543210->NXM_NX_IPV6_DST[]: value does not fit into 128 bits
102 ]])
103
104 dnl 128 bits is merely a bad prerequisite.
105 AT_CHECK([[ovs-ofctl parse-flow 'actions=learn(load:0xfedbca9876543210fedbca9876543210->NXM_NX_IPV6_DST[])']], [1], [], [stderr])
106 AT_CHECK([sed -e 's/.*|meta_flow|WARN|//' < stderr], [0],
107 [[destination field ipv6_dst lacks correct prerequisites
108 ovs-ofctl: actions are invalid with specified match (OFPBAC_MATCH_INCONSISTENT)
109 ]], [[]])
110 AT_CLEANUP
111
112 AT_SETUP([learning action - standard VLAN+MAC learning])
113 OVS_VSWITCHD_START(
114 [add-port br0 p1 -- set Interface p1 type=dummy ofport_request=1 -- \
115 add-port br0 p2 -- set Interface p2 type=dummy ofport_request=2 -- \
116 add-port br0 p3 -- set Interface p3 type=dummy ofport_request=3])
117 # Set up flow table for VLAN+MAC learning.
118 AT_DATA([flows.txt], [[
119 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)
120 table=1 priority=0 actions=flood
121 ]])
122 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
123
124 # Trace an ARP packet arriving on port 3, to create a MAC learning entry.
125 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)"
126 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], [stdout])
127 actual=`tail -1 stdout | sed 's/Datapath actions: //'`
128
129 expected="1,2,100"
130 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
131 mv stdout expout
132 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
133
134 # Check for the MAC learning entry.
135 AT_CHECK([ovs-ofctl dump-flows br0 table=1 --no-stats --sort], [0], [dnl
136 table=1, priority=0 actions=FLOOD
137 table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:05 actions=output:3
138 ])
139
140 # Trace a packet arrival destined for the learned MAC.
141 # (This will also learn a MAC.)
142 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])
143 AT_CHECK([tail -1 stdout], [0], [Datapath actions: 3
144 ])
145
146 # Check for both MAC learning entries.
147 AT_CHECK([ovs-ofctl dump-flows br0 table=1 --no-stats | sort], [0], [dnl
148 table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:05 actions=output:3
149 table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:06 actions=output:1
150 table=1, priority=0 actions=FLOOD
151 ])
152
153 # Trace a packet arrival that updates the first learned MAC entry.
154 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)"
155 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], [stdout])
156 actual=`tail -1 stdout | sed 's/Datapath actions: //'`
157
158 expected="1,3,100"
159 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
160 mv stdout expout
161 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
162
163 # Check that the MAC learning entry was updated.
164 AT_CHECK([ovs-ofctl dump-flows br0 table=1 --no-stats | sort], [0], [dnl
165 table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:05 actions=output:2
166 table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:06 actions=output:1
167 table=1, priority=0 actions=FLOOD
168 ])
169 OVS_VSWITCHD_STOP
170 AT_CLEANUP
171
172 dnl This test checks that repeated uses of a "learn" action cause the
173 dnl modified time of the learned flow to advance. Otherwise, the
174 dnl learned flow will expire after its hard timeout even though it's
175 dnl supposed to be refreshed. (The expiration can be hard to see since
176 dnl it gets re-learned again the next time a packet appears, but
177 dnl sometimes the expiration can cause temporary flooding etc.)
178 AT_SETUP([learning action - learn refreshes hard_age])
179 OVS_VSWITCHD_START(
180 [add-port br0 p1 -- set Interface p1 type=dummy ofport_request=1 -- \
181 add-port br0 p2 -- set Interface p2 type=dummy ofport_request=2 -- \
182 add-port br0 p3 -- set Interface p3 type=dummy ofport_request=3])
183
184 ovs-appctl time/stop
185
186 # Set up flow table for MAC learning.
187 AT_DATA([flows.txt], [[
188 table=0 actions=learn(table=1, hard_timeout=10, NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], output:NXM_OF_IN_PORT[]), resubmit(,1)
189 table=1 priority=0 actions=flood
190 ]])
191 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
192
193 # Trace an ICMP packet arriving on port 3, to create a MAC learning entry.
194 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)"
195 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], [stdout])
196 actual=`tail -1 stdout | sed 's/Datapath actions: //'`
197
198 expected="1,2,100"
199 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
200 mv stdout expout
201 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
202
203 # Check that the MAC learning entry appeared.
204 AT_CHECK([ovs-ofctl dump-flows br0 table=1 --no-stats | sort], [0], [dnl
205 table=1, hard_timeout=10, dl_dst=50:54:00:00:00:07 actions=output:3
206 table=1, priority=0 actions=FLOOD
207 ])
208
209 # For 25 seconds, make sure that the MAC learning entry doesn't
210 # disappear as long as we refresh it every second.
211 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
212 ovs-appctl time/warp 1000
213 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], [stdout])
214
215 # Check that the entry is there.
216 AT_CHECK([ovs-ofctl dump-flows br0 table=1], [0], [stdout])
217 AT_CHECK([ofctl_strip < stdout | sort], [0], [dnl
218 table=1, hard_timeout=10, dl_dst=50:54:00:00:00:07 actions=output:3
219 table=1, priority=0 actions=FLOOD
220 NXST_FLOW reply:
221 ])
222
223 if test $i != 1; then
224 # Check that hard_age has appeared. We need to do this separately
225 # from the above check because ofctl_strip removes it. dump-flows
226 # only prints hard_age when it is different from the flow's duration
227 # (that is, the number of seconds from the time it was created),
228 # so we only check for it after we've refreshed the flow once.
229 AT_CHECK([grep dl_dst=50:54:00:00:00:07 stdout | grep -c hard_age],
230 [0], [1
231 ])
232 fi
233 done
234
235 # Make sure that 15 seconds without refreshing makes the flow time out.
236 ovs-appctl time/warp 15000 5000
237 sleep 1
238 AT_CHECK([ovs-ofctl dump-flows br0 table=1 --no-stats | sort], [0], [dnl
239 table=1, priority=0 actions=FLOOD
240 ])
241 OVS_VSWITCHD_STOP
242 AT_CLEANUP
243
244 AT_SETUP([learning action - TCPv4 port learning])
245 OVS_VSWITCHD_START(
246 [add-port br0 p1 -- set Interface p1 type=dummy -- \
247 add-port br0 p2 -- set Interface p2 type=dummy -- \
248 add-port br0 p3 -- set Interface p3 type=dummy])
249 # Set up flow table for TCPv4 port learning.
250 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']])
251
252 # Trace a TCPv4 packet arriving on port 3.
253 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)"
254 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], [stdout])
255 actual=`tail -1 stdout | sed 's/Datapath actions: //'`
256
257 expected="1,2,100"
258 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
259 mv stdout expout
260 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
261
262 # Check for the learning entry.
263 AT_CHECK([ovs-ofctl dump-flows br0 table=1 --no-stats | sort], [0], [dnl
264 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
265 ])
266 OVS_VSWITCHD_STOP
267 AT_CLEANUP
268
269 AT_SETUP([learning action - TCPv6 port learning])
270 OVS_VSWITCHD_START(
271 [add-port br0 p1 -- set Interface p1 type=dummy -- \
272 add-port br0 p2 -- set Interface p2 type=dummy -- \
273 add-port br0 p3 -- set Interface p3 type=dummy])
274 # Set up flow table for TCPv6 port learning.
275 # Also add a 128-bit-wide "load" action and a 128-bit literal match to check
276 # that they work.
277 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']])
278
279 # Trace a TCPv6 packet arriving on port 3.
280 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)"
281 AT_CHECK([ovs-appctl ofproto/trace ovs-dummy "$flow" -generate], [0], [stdout])
282 actual=`tail -1 stdout | sed 's/Datapath actions: //'`
283
284 expected="1,2,100"
285 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
286 mv stdout expout
287 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
288
289 # Check for the learning entry.
290 AT_CHECK([ovs-ofctl dump-flows br0 --no-stats | sort], [0], [dnl
291 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]]
292 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
293 ])
294 OVS_VSWITCHD_STOP
295 AT_CLEANUP
296
297 # In this use of a learn action, the first packet in the flow creates
298 # a new flow that changes the behavior of subsequent packets in the
299 # flow.
300 AT_SETUP([learning action - self-modifying flow])
301 OVS_VSWITCHD_START
302 add_of_ports br0 1 2 3
303
304 ovs-appctl time/stop
305 # Set up flow table for TCPv4 port learning.
306 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']])
307
308 # Trace some packets arriving. The particular packets don't matter.
309 for i in 1 2 3 4 5 6 7 8 9 10; do
310 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)'
311 ovs-appctl time/warp 10
312 if [[ $i -eq 1 ]]; then
313 sleep 1
314 fi
315 done
316
317 # Check for the learning entry.
318 ovs-appctl time/warp 1000
319 AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0],
320 [[ n_packets=1, n_bytes=118, 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
321 n_packets=9, n_bytes=1062, priority=65535,vlan_tci=0x0000/0x0fff,dl_src=50:54:00:00:00:05 actions=output:3
322 NXST_FLOW reply:
323 ]])
324
325 # Check that the first packet went out port 2 and the rest out port 3.
326 AT_CHECK(
327 [(ovs-ofctl dump-ports br0 2; ovs-ofctl dump-ports br0 3) | strip_xids], [0],
328 [OFPST_PORT reply: 1 ports
329 port 2: rx pkts=0, bytes=0, drop=?, errs=?, frame=?, over=?, crc=?
330 tx pkts=1, bytes=118, drop=?, errs=?, coll=?
331 OFPST_PORT reply: 1 ports
332 port 3: rx pkts=0, bytes=0, drop=?, errs=?, frame=?, over=?, crc=?
333 tx pkts=9, bytes=1062, drop=?, errs=?, coll=?
334 ])
335
336 OVS_VSWITCHD_STOP
337 AT_CLEANUP
338
339 # This test is much like the previous, but adds idle timeouts and sends
340 # two different flows to the bridge. This tests that the statistics are
341 # attributed correctly.
342 AT_SETUP([learning action - self-modifying flow with idle_timeout])
343 OVS_VSWITCHD_START
344 add_of_ports br0 1 2 3
345
346 ovs-appctl time/stop
347 # Set up flow table for TCPv4 port learning.
348 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']])
349
350 # Trace some packets arriving. The particular packets don't matter.
351 for i in `seq 1 10`; do
352 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)'
353 ovs-appctl time/warp 10
354 if [[ $i -eq 1 ]]; then
355 sleep 1
356 fi
357 done
358
359 # Trace some packets arriving. This is is a different flow from the previous.
360 # Note that we advance time by 1 second between each packet here.
361 for i in `seq 1 10`; do
362 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)'
363 ovs-appctl time/warp 1000
364 # Note: netdev-dummy/receive merely queues the packet.
365 # We need to wait for other thread to process the packet
366 # and update the flow's 'used' for the packet.
367 # (i % 3 == 0) below is somehow arbitrary but chosen to ensure
368 # that we update the flow's 'used' frequently enough to prevent
369 # idle_timeout.
370 if [[ $i -eq 1 -o $((i % 3)) -eq 0 ]]; then
371 sleep 1
372 fi
373 done
374
375 # Check that the first packet of each flow went out port 2 and the rest out
376 # port 3.
377 AT_CHECK(
378 [(ovs-ofctl dump-ports br0 2; ovs-ofctl dump-ports br0 3) | strip_xids], [0],
379 [OFPST_PORT reply: 1 ports
380 port 2: rx pkts=0, bytes=0, drop=?, errs=?, frame=?, over=?, crc=?
381 tx pkts=2, bytes=236, drop=?, errs=?, coll=?
382 OFPST_PORT reply: 1 ports
383 port 3: rx pkts=0, bytes=0, drop=?, errs=?, frame=?, over=?, crc=?
384 tx pkts=18, bytes=2124, drop=?, errs=?, coll=?
385 ])
386
387 # Check for the learning entry.
388 ovs-appctl time/warp 1000
389 AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0],
390 [[ n_packets=2, n_bytes=236, 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
391 n_packets=9, n_bytes=1062, idle_timeout=5, priority=65535,vlan_tci=0x0000/0x0fff,dl_src=50:54:00:00:00:06 actions=output:3
392 NXST_FLOW reply:
393 ]])
394 OVS_VSWITCHD_STOP
395 AT_CLEANUP
396
397 # This test is much like the previous, but adds hard timeouts and sends
398 # two different flows to the bridge. This tests that the statistics are
399 # attributed correctly.
400 AT_SETUP([learning action - self-modifying flow with hard_timeout])
401 OVS_VSWITCHD_START
402 add_of_ports br0 1 2 3
403
404 ovs-appctl time/stop
405 # Set up flow table for TCPv4 port learning.
406 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']])
407
408 # Trace some packets arriving. The particular packets don't matter.
409 for i in `seq 1 10`; do
410 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)'
411 if [[ $i -eq 1 ]]; then
412 sleep 1
413 fi
414 ovs-appctl time/warp 10
415 done
416
417 # Check that the first packet of each flow went out port 2 and the rest out
418 # port 3.
419 AT_CHECK(
420 [(ovs-ofctl dump-ports br0 2; ovs-ofctl dump-ports br0 3) | strip_xids], [0],
421 [OFPST_PORT reply: 1 ports
422 port 2: rx pkts=0, bytes=0, drop=?, errs=?, frame=?, over=?, crc=?
423 tx pkts=1, bytes=118, drop=?, errs=?, coll=?
424 OFPST_PORT reply: 1 ports
425 port 3: rx pkts=0, bytes=0, drop=?, errs=?, frame=?, over=?, crc=?
426 tx pkts=9, bytes=1062, drop=?, errs=?, coll=?
427 ])
428
429 # Trace some packets arriving. This is is a different flow from the previous.
430 # Note that we advance time by 2 second between each packet here.
431 for i in `seq 1 10`; do
432 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)'
433 # Note: hard_timeout should fire immediately after #6 packet.
434 # #7 packet re-install the flow and the following 3 packets
435 # (#8, #9, #10) use the flow.
436 # it's difficult to predict the exact timing of rule expiry
437 # because it's affected by flow dumper thread via udpif_dump_seq.
438 # hard_timeout value for this test was chosen to overcome the uncertainty.
439 #
440 # receive #1 learn, install flow with hard_timeout=10
441 # sleep to ensure the flow installation
442 # (warp, timeout left 8s)
443 # receive #2 the learned flow
444 # (warp, timeout left 6s)
445 # receive #3
446 # (warp, timeout left 4s)
447 # receive #4
448 # (warp, timeout left 2s)
449 # receive #5
450 # (warp, timeout left 0s)
451 # NOTE: OVS does not consider this expired yet. cf. rule_expire()
452 # receive #6
453 # (warp, timeout left -2s)
454 # sleep to ensure flow expiration
455 # receive #7 learn, install flow with hard_timeout=10
456 # sleep to ensure the flow installation
457 # (warp, timeout left 8s)
458 # receive #8
459 # (warp, timeout left 6s)
460 # receive #9
461 # (warp, timeout left 4s)
462 # receive #10
463 # (warp, timeout left 2s)
464 if [[ $i -eq 1 -o $i -eq 7 ]]; then
465 sleep 1
466 fi
467 ovs-appctl time/warp 2000
468 if [[ $i -eq 6 ]]; then
469 sleep 1
470 fi
471 done
472
473 # Check that the first packet of each flow went out port 2 and the rest out
474 # port 3.
475 AT_CHECK(
476 [(ovs-ofctl dump-ports br0 2; ovs-ofctl dump-ports br0 3) | strip_xids], [0],
477 [OFPST_PORT reply: 1 ports
478 port 2: rx pkts=0, bytes=0, drop=?, errs=?, frame=?, over=?, crc=?
479 tx pkts=3, bytes=354, drop=?, errs=?, coll=?
480 OFPST_PORT reply: 1 ports
481 port 3: rx pkts=0, bytes=0, drop=?, errs=?, frame=?, over=?, crc=?
482 tx pkts=17, bytes=2006, drop=?, errs=?, coll=?
483 ])
484
485 # Check for the learning entry.
486 ovs-appctl time/warp 1000
487 sleep 1
488 AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0],
489 [[ n_packets=3, n_bytes=354, 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
490 n_packets=3, n_bytes=354, hard_timeout=10, priority=65535,vlan_tci=0x0000/0x0fff,dl_src=50:54:00:00:00:06 actions=output:3
491 NXST_FLOW reply:
492 ]])
493 OVS_VSWITCHD_STOP
494 AT_CLEANUP
495
496 AT_SETUP([learning action - fin_timeout feature])
497 # This is a totally artificial use of the "learn" action. The only purpose
498 # is to check that specifying fin_idle_timeout or fin_hard_timeout causes
499 # a corresponding fin_timeout action to end up in the learned flows.
500 OVS_VSWITCHD_START(
501 [add-port br0 p1 -- set Interface p1 type=dummy ofport_request=1])
502 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[])']])
503 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])
504 AT_CHECK([ovs-ofctl dump-flows br0 table=1 --no-stats], [0],
505 [ table=1, dl_dst=50:54:00:00:00:05 actions=fin_timeout(idle_timeout=5,hard_timeout=10),output:1
506 ])
507 OVS_VSWITCHD_STOP
508 AT_CLEANUP
509
510 AT_SETUP([learning action - delete_learned feature])
511 OVS_VSWITCHD_START
512
513 # Add some initial flows and check that it was successful.
514 AT_DATA([flows.txt], [dnl
515 reg0=0x1 actions=learn(delete_learned,cookie=0x123)
516 reg0=0x2 actions=learn(delete_learned,cookie=0x123)
517 cookie=0x123, table=1, reg0=0x3 actions=drop
518 cookie=0x123, table=1, reg0=0x4 actions=drop
519 cookie=0x123, table=2, reg0=0x5 actions=drop
520 cookie=0x234, table=1, reg0=0x6 actions=drop
521 ])
522 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
523 AT_CHECK([ovs-ofctl dump-flows br0 --no-stats | sort], [0], [dnl
524 cookie=0x123, table=1, reg0=0x3 actions=drop
525 cookie=0x123, table=1, reg0=0x4 actions=drop
526 cookie=0x123, table=2, reg0=0x5 actions=drop
527 cookie=0x234, table=1, reg0=0x6 actions=drop
528 reg0=0x1 actions=learn(table=1,delete_learned,cookie=0x123)
529 reg0=0x2 actions=learn(table=1,delete_learned,cookie=0x123)
530 ])
531
532 # Delete one of the learn actions. The learned flows should stay, since there
533 # is another learn action with the identical target.
534 AT_CHECK([ovs-ofctl del-flows br0 'table=0 reg0=1'])
535 AT_CHECK([ovs-ofctl dump-flows br0 --no-stats | sort], [0], [dnl
536 cookie=0x123, table=1, reg0=0x3 actions=drop
537 cookie=0x123, table=1, reg0=0x4 actions=drop
538 cookie=0x123, table=2, reg0=0x5 actions=drop
539 cookie=0x234, table=1, reg0=0x6 actions=drop
540 reg0=0x2 actions=learn(table=1,delete_learned,cookie=0x123)
541 ])
542
543 # Change the flow with the learn action by adding a second action. The learned
544 # flows should stay because the learn action is still there.
545 AT_CHECK([ovs-ofctl mod-flows br0 'table=0 reg0=2 actions=output:1,learn(delete_learned,cookie=0x123)'])
546 AT_CHECK([ovs-ofctl dump-flows br0 --no-stats | sort], [0], [dnl
547 cookie=0x123, table=1, reg0=0x3 actions=drop
548 cookie=0x123, table=1, reg0=0x4 actions=drop
549 cookie=0x123, table=2, reg0=0x5 actions=drop
550 cookie=0x234, table=1, reg0=0x6 actions=drop
551 reg0=0x2 actions=output:1,learn(table=1,delete_learned,cookie=0x123)
552 ])
553
554 # Change the flow with the learn action by replacing its learn action by one
555 # with a different target. The (previous) learned flows disappear.
556 AT_CHECK([ovs-ofctl mod-flows br0 'table=0 reg0=2 actions=learn(delete_learned,cookie=0x234)'])
557 AT_CHECK([ovs-ofctl dump-flows br0 --no-stats | sort], [0], [dnl
558 cookie=0x123, table=2, reg0=0x5 actions=drop
559 cookie=0x234, table=1, reg0=0x6 actions=drop
560 reg0=0x2 actions=learn(table=1,delete_learned,cookie=0x234)
561 ])
562
563 # Use add-flow to replace the flow with the learn action by one with the
564 # same learn action and an extra action. The (new) learned flow remains.
565 AT_CHECK([ovs-ofctl add-flow br0 'table=0 reg0=2 actions=learn(delete_learned,cookie=0x234),output:2'])
566 AT_CHECK([ovs-ofctl dump-flows br0 --no-stats | sort], [0], [dnl
567 cookie=0x123, table=2, reg0=0x5 actions=drop
568 cookie=0x234, table=1, reg0=0x6 actions=drop
569 reg0=0x2 actions=learn(table=1,delete_learned,cookie=0x234),output:2
570 ])
571
572 # Delete the flow with the learn action. The learned flow disappears too.
573 AT_CHECK([ovs-ofctl del-flows br0 table=0])
574 AT_CHECK([ovs-ofctl dump-flows br0 --no-stats | sort], [0], [dnl
575 cookie=0x123, table=2, reg0=0x5 actions=drop
576 ])
577
578 # Add a new set of flows to check on a corner case: the learned flows
579 # contain their own learn actions which cascade to further deletions.
580 # This can't happen if the learned flows were actually created by a
581 # learn action, since the learn action has very restricted action
582 # support, but there's no restriction that the deleted flows were
583 # created by a learn action.
584 AT_DATA([flows.txt], [dnl
585 reg0=0x1 actions=learn(table=1,delete_learned,cookie=0x123)
586 reg0=0x2 actions=learn(table=2,delete_learned,cookie=0x234)
587 cookie=0x123, table=1, reg0=0x3 actions=learn(table=3,delete_learned,cookie=0x345)
588 cookie=0x234, table=2, reg0=0x3 actions=learn(table=4,delete_learned,cookie=0x456)
589 cookie=0x345, table=3, reg0=0x4 actions=learn(table=5,delete_learned,cookie=0x567)
590 cookie=0x456, table=4, reg0=0x5 actions=learn(table=5,delete_learned,cookie=0x567)
591 cookie=0x567, table=5, reg0=0x6 actions=drop
592 cookie=0x567, table=5, reg0=0x7 actions=drop
593 cookie=0x567, table=5, reg0=0x8 actions=drop
594 ])
595 AT_CHECK([ovs-ofctl del-flows br0])
596 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
597 AT_CHECK([ovs-ofctl dump-flows br0 --no-stats | sort], [0], [dnl
598 cookie=0x123, table=1, reg0=0x3 actions=learn(table=3,delete_learned,cookie=0x345)
599 cookie=0x234, table=2, reg0=0x3 actions=learn(table=4,delete_learned,cookie=0x456)
600 cookie=0x345, table=3, reg0=0x4 actions=learn(table=5,delete_learned,cookie=0x567)
601 cookie=0x456, table=4, reg0=0x5 actions=learn(table=5,delete_learned,cookie=0x567)
602 cookie=0x567, table=5, reg0=0x6 actions=drop
603 cookie=0x567, table=5, reg0=0x7 actions=drop
604 cookie=0x567, table=5, reg0=0x8 actions=drop
605 reg0=0x1 actions=learn(table=1,delete_learned,cookie=0x123)
606 reg0=0x2 actions=learn(table=2,delete_learned,cookie=0x234)
607 ])
608
609 # Deleting the flow with reg0=1 should cascade to delete a few levels
610 # of learned flows, but the ones with cookie=0x567 stick around
611 # because of the flow with cookie=0x456.
612 AT_CHECK([ovs-ofctl del-flows br0 'table=0 reg0=1'])
613 AT_CHECK([ovs-ofctl dump-flows br0 --no-stats | sort], [0], [dnl
614 cookie=0x234, table=2, reg0=0x3 actions=learn(table=4,delete_learned,cookie=0x456)
615 cookie=0x456, table=4, reg0=0x5 actions=learn(table=5,delete_learned,cookie=0x567)
616 cookie=0x567, table=5, reg0=0x6 actions=drop
617 cookie=0x567, table=5, reg0=0x7 actions=drop
618 cookie=0x567, table=5, reg0=0x8 actions=drop
619 reg0=0x2 actions=learn(table=2,delete_learned,cookie=0x234)
620 ])
621
622 # Deleting the flow with reg0=2 should cascade to delete all the rest:
623 AT_CHECK([ovs-ofctl del-flows br0 'table=0 reg0=2'])
624 AT_CHECK([ovs-ofctl dump-flows br0 --no-stats | sort])
625 OVS_VSWITCHD_STOP
626 AT_CLEANUP
627
628 AT_SETUP([learning action - delete_learned/limit with packet])
629 OVS_VSWITCHD_START(
630 [add-port br0 p1 -- set Interface p1 type=dummy ofport_request=1 --\
631 add-port br0 p2 -- set Interface p2 type=dummy ofport_request=2])
632
633 # Add some initial flows and check that it was successful.
634 AT_DATA([flows.txt], [dnl
635 table=0 actions=set_field:0x2->reg7,set_field:0xabcdef01->metadata, resubmit(,1)
636 table=1 actions=learn(table=10,delete_learned,cookie=0x123,limit=3,result_dst=NXM_NX_REG6[[0]],NXM_OF_ETH_DST[[]]=NXM_OF_ETH_SRC[[]],OXM_OF_METADATA[[]],output:NXM_NX_REG7)
637 ])
638
639 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
640 AT_CHECK([ovs-ofctl dump-flows br0 --no-stats | sort], [0], [dnl
641 actions=load:0x2->NXM_NX_REG7[[]],load:0xabcdef01->OXM_OF_METADATA[[]],resubmit(,1)
642 table=1, actions=learn(table=10,delete_learned,cookie=0x123,limit=3,result_dst=NXM_NX_REG6[[0]],NXM_OF_ETH_DST[[]]=NXM_OF_ETH_SRC[[]],OXM_OF_METADATA[[]],output:NXM_NX_REG7[[]])
643 ])
644
645 dnl Each packet will generate its own flow at table=10, except last one
646 AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:01,dst=50:54:00:00:00:ff),eth_type(0x1234)'])
647 AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:02,dst=50:54:00:00:00:ff),eth_type(0x1234)'])
648 AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:03,dst=50:54:00:00:00:ff),eth_type(0x1234)'])
649 AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:04,dst=50:54:00:00:00:ff),eth_type(0x1234)'])
650
651 AT_CHECK([ovs-ofctl dump-flows br0 table=10 --no-stats | sort], [0], [dnl
652 cookie=0x123, table=10, metadata=0xabcdef01,dl_dst=50:54:00:00:00:01 actions=output:2
653 cookie=0x123, table=10, metadata=0xabcdef01,dl_dst=50:54:00:00:00:02 actions=output:2
654 cookie=0x123, table=10, metadata=0xabcdef01,dl_dst=50:54:00:00:00:03 actions=output:2
655 ])
656
657 ovs-appctl revalidator/wait
658
659 AT_CHECK([ovs-ofctl del-flows br0 'table=1'])
660 AT_CHECK([ovs-ofctl dump-flows br0 table=10 --no-stats | sort], [0], [dnl
661 ])
662
663 OVS_VSWITCHD_STOP
664 AT_CLEANUP
665
666 AT_SETUP([learning action - limit])
667 OVS_VSWITCHD_START
668 AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg])
669 add_of_ports br0 1 2
670 AT_DATA([flows.txt], [dnl
671 table=0 in_port=1 actions=learn(table=1,dl_dst=dl_src,cookie=0x1,limit=1),2
672 ])
673 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
674 AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:01,dst=50:54:00:00:00:ff),eth_type(0x1234)'])
675 AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:02,dst=50:54:00:00:00:ff),eth_type(0x1234)'])
676
677 OVS_WAIT_UNTIL([ovs-ofctl dump-ports br0 2 | grep -o 'tx pkts=2' >/dev/null])
678
679 AT_CHECK([ovs-ofctl dump-flows br0 table=1 --no-stats], [0], [dnl
680 cookie=0x1, table=1, dl_dst=50:54:00:00:00:01 actions=drop
681 ])
682
683 dnl Delete the learned flow
684 AT_CHECK([ovs-ofctl del-flows br0 table=1])
685
686 AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
687 NXST_FLOW reply:
688 ])
689
690 ovs-appctl revalidator/wait
691
692 AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:02,dst=50:54:00:00:00:ff),eth_type(0x1234)'])
693 AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:01,dst=50:54:00:00:00:ff),eth_type(0x1234)'])
694
695 OVS_WAIT_UNTIL([ovs-ofctl dump-ports br0 2 | grep -o 'tx pkts=4' >/dev/null])
696
697 AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
698 cookie=0x1, table=1, dl_dst=50:54:00:00:00:02 actions=drop
699 NXST_FLOW reply:
700 ])
701
702 OVS_VSWITCHD_STOP
703 AT_CLEANUP
704
705 AT_SETUP([learning action - limit result_dst])
706 OVS_VSWITCHD_START
707 AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg])
708 add_of_ports br0 1
709 AT_DATA([flows.txt], [dnl
710 table=0 in_port=1 actions=learn(table=1,dl_dst=dl_src,cookie=0x1,limit=1,result_dst=reg0[[0]]),controller
711 ])
712 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
713
714 AT_CAPTURE_FILE([ofctl_monitor.log])
715 AT_CHECK([ovs-ofctl monitor br0 65534 invalid_ttl -P nxt_packet_in --detach --no-chdir --pidfile 2> ofctl_monitor.log])
716
717 AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:01,dst=50:54:00:00:00:ff),eth_type(0x1234)'])
718 AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:02,dst=50:54:00:00:00:ff),eth_type(0x1234)'])
719
720 OVS_WAIT_UNTIL([test `wc -l < ofctl_monitor.log` -ge 4])
721 OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
722
723 AT_CHECK([cat ofctl_monitor.log], [0], [dnl
724 NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=14 reg0=0x1,in_port=1 (via action) data_len=14 (unbuffered)
725 vlan_tci=0x0000,dl_src=50:54:00:00:00:01,dl_dst=50:54:00:00:00:ff,dl_type=0x1234
726 NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=14 in_port=1 (via action) data_len=14 (unbuffered)
727 vlan_tci=0x0000,dl_src=50:54:00:00:00:02,dl_dst=50:54:00:00:00:ff,dl_type=0x1234
728 ])
729
730 AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
731 cookie=0x1, table=1, dl_dst=50:54:00:00:00:01 actions=drop
732 NXST_FLOW reply:
733 ])
734
735 OVS_VSWITCHD_STOP
736 AT_CLEANUP
737
738 AT_SETUP([learning action - different limits])
739 OVS_VSWITCHD_START
740 AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg])
741 add_of_ports br0 1 2 3
742 AT_DATA([flows.txt], [dnl
743 table=0 in_port=1 udp,actions=learn(table=11,dl_type=0x0800,nw_proto=17,udp_src=udp_dst,limit=1,result_dst=reg0[[0]]),resubmit(,1)
744 table=0 in_port=2 udp,actions=learn(table=12,dl_type=0x0800,nw_proto=17,udp_src=udp_dst,limit=10,result_dst=reg0[[0]]),resubmit(,1)
745 table=0 in_port=3 udp,actions=learn(table=13,dl_type=0x0800,nw_proto=17,udp_src=udp_dst,limit=20,result_dst=reg0[[0]]),resubmit(,1)
746 dnl
747 dnl These flows simply counts the packets that executed a successful learn action:
748 dnl
749 table=1 cookie=1,reg0=1,in_port=1 actions=drop
750 table=1 cookie=2,reg0=1,in_port=2 actions=drop
751 table=1 cookie=3,reg0=1,in_port=3 actions=drop
752 dnl
753 dnl These flows simply counts the packets that didn't execute a successful learn action:
754 dnl
755 table=1 cookie=1,reg0=0,in_port=1 actions=drop
756 table=1 cookie=2,reg0=0,in_port=2 actions=drop
757 table=1 cookie=3,reg0=0,in_port=3 actions=drop
758 ])
759 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
760
761 for i in `seq 1001 1030`; do
762 ovs-appctl netdev-dummy/receive p1 "in_port(1),eth(src=50:54:00:00:00:01,dst=50:54:00:00:00:ff),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=17,tos=0,ttl=64,frag=no),udp(src=1,dst=$i)"
763 ovs-appctl netdev-dummy/receive p2 "in_port(2),eth(src=50:54:00:00:00:01,dst=50:54:00:00:00:ff),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=17,tos=0,ttl=64,frag=no),udp(src=1,dst=$i)"
764 ovs-appctl netdev-dummy/receive p3 "in_port(3),eth(src=50:54:00:00:00:01,dst=50:54:00:00:00:ff),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=17,tos=0,ttl=64,frag=no),udp(src=1,dst=$i)"
765 done
766
767 dnl Check successful counters:
768 AT_CHECK([ovs-ofctl dump-flows br0 table=1,reg0=1 | ofctl_strip | sort], [0], [dnl
769 cookie=0x1, table=1, n_packets=1, n_bytes=106, reg0=0x1,in_port=1 actions=drop
770 cookie=0x2, table=1, n_packets=10, n_bytes=1060, reg0=0x1,in_port=2 actions=drop
771 cookie=0x3, table=1, n_packets=20, n_bytes=2120, reg0=0x1,in_port=3 actions=drop
772 NXST_FLOW reply:
773 ])
774
775 dnl Check failed counters:
776 AT_CHECK([ovs-ofctl dump-flows br0 table=1,reg0=0 | ofctl_strip | sort], [0], [dnl
777 cookie=0x1, table=1, n_packets=29, n_bytes=3074, reg0=0,in_port=1 actions=drop
778 cookie=0x2, table=1, n_packets=20, n_bytes=2120, reg0=0,in_port=2 actions=drop
779 cookie=0x3, table=1, n_packets=10, n_bytes=1060, reg0=0,in_port=3 actions=drop
780 NXST_FLOW reply:
781 ])
782
783 dnl Check learned flows:
784
785 AT_CHECK([ovs-ofctl dump-flows br0 table=13 | ofctl_strip | sort], [0], [dnl
786 table=13, udp,tp_src=1001 actions=drop
787 table=13, udp,tp_src=1002 actions=drop
788 table=13, udp,tp_src=1003 actions=drop
789 table=13, udp,tp_src=1004 actions=drop
790 table=13, udp,tp_src=1005 actions=drop
791 table=13, udp,tp_src=1006 actions=drop
792 table=13, udp,tp_src=1007 actions=drop
793 table=13, udp,tp_src=1008 actions=drop
794 table=13, udp,tp_src=1009 actions=drop
795 table=13, udp,tp_src=1010 actions=drop
796 table=13, udp,tp_src=1011 actions=drop
797 table=13, udp,tp_src=1012 actions=drop
798 table=13, udp,tp_src=1013 actions=drop
799 table=13, udp,tp_src=1014 actions=drop
800 table=13, udp,tp_src=1015 actions=drop
801 table=13, udp,tp_src=1016 actions=drop
802 table=13, udp,tp_src=1017 actions=drop
803 table=13, udp,tp_src=1018 actions=drop
804 table=13, udp,tp_src=1019 actions=drop
805 table=13, udp,tp_src=1020 actions=drop
806 NXST_FLOW reply:
807 ])
808
809 AT_CHECK([ovs-ofctl dump-flows br0 table=12 | ofctl_strip | sort], [0], [dnl
810 table=12, udp,tp_src=1001 actions=drop
811 table=12, udp,tp_src=1002 actions=drop
812 table=12, udp,tp_src=1003 actions=drop
813 table=12, udp,tp_src=1004 actions=drop
814 table=12, udp,tp_src=1005 actions=drop
815 table=12, udp,tp_src=1006 actions=drop
816 table=12, udp,tp_src=1007 actions=drop
817 table=12, udp,tp_src=1008 actions=drop
818 table=12, udp,tp_src=1009 actions=drop
819 table=12, udp,tp_src=1010 actions=drop
820 NXST_FLOW reply:
821 ])
822
823 AT_CHECK([ovs-ofctl dump-flows br0 table=11 | ofctl_strip | sort], [0], [dnl
824 table=11, udp,tp_src=1001 actions=drop
825 NXST_FLOW reply:
826 ])
827
828 AT_CHECK([ovs-vsctl del-br br0])
829
830 ovs-appctl time/warp 500
831 ovs-appctl time/warp 500
832 ovs-appctl time/warp 500
833 ovs-appctl time/warp 500
834
835 AT_CHECK([ovs-vsctl add-br br1 -- set b br1 datapath_type=dummy])
836
837 OVS_VSWITCHD_STOP
838 AT_CLEANUP