python/ovs/poller.py: workaround an eventlet bug
[cascardo/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(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 - examples])
19 AT_DATA([flows.txt], [[
20 # These are the examples from nicira-ext.h.
21 actions=learn(in_port=99,NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], load:NXM_OF_IN_PORT[]->NXM_NX_REG1[16..31])
22 actions=learn(NXM_OF_VLAN_TCI[0..11], NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],output:NXM_OF_IN_PORT[])
23 table=0 actions=learn(table=1,hard_timeout=10, NXM_OF_VLAN_TCI[0..11],output:NXM_OF_IN_PORT[]), resubmit(,1)
24 table=1 priority=0 actions=flood
25 ]])
26 AT_CHECK([ovs-ofctl parse-flows flows.txt], [0],
27 [[usable protocols: OpenFlow10+table_id,NXM+table_id
28 chosen protocol: OpenFlow10+table_id
29 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])
30 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[])
31 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)
32 OFPT_FLOW_MOD (xid=0x4): ADD table:1 priority=0 actions=FLOOD
33 ]])
34 AT_CLEANUP
35
36 AT_SETUP([learning action - satisfied prerequisites])
37 AT_DATA([flows.txt],
38 [[actions=learn(eth_type=0x800,load:5->NXM_OF_IP_DST[])
39 ip,actions=learn(load:NXM_OF_IP_DST[]->NXM_NX_REG1[])
40 ip,actions=learn(eth_type=0x800,OXM_OF_IPV4_DST[])
41 ]])
42 AT_CHECK([ovs-ofctl parse-flows flows.txt], [0],
43 [[usable protocols: any
44 chosen protocol: OpenFlow10-table_id
45 OFPT_FLOW_MOD (xid=0x1): ADD actions=learn(table=1,eth_type=0x800,load:0x5->NXM_OF_IP_DST[])
46 OFPT_FLOW_MOD (xid=0x2): ADD ip actions=learn(table=1,load:NXM_OF_IP_DST[]->NXM_NX_REG1[])
47 OFPT_FLOW_MOD (xid=0x3): ADD ip actions=learn(table=1,eth_type=0x800,NXM_OF_IP_DST[])
48 ]])
49 AT_CLEANUP
50
51 AT_SETUP([learning action - invalid prerequisites])
52 AT_CHECK([[ovs-ofctl parse-flow 'actions=learn(load:5->NXM_OF_IP_DST[])']],
53   [1], [],
54   [[ovs-ofctl: load:5->NXM_OF_IP_DST[]: cannot specify destination field ip_dst because prerequisites are not satisfied
55 ]])
56 AT_CHECK([[ovs-ofctl parse-flow 'actions=learn(load:NXM_OF_IP_DST[]->NXM_NX_REG1[])']],
57   [1], [],
58   [[ovs-ofctl: load:NXM_OF_IP_DST[]->NXM_NX_REG1[]: cannot specify source field ip_dst because prerequisites are not satisfied
59 ]])
60 AT_CLEANUP
61
62 AT_SETUP([learning action - standard VLAN+MAC learning])
63 OVS_VSWITCHD_START(
64   [add-port br0 eth0 -- set Interface eth0 type=dummy -- \
65    add-port br0 eth1 -- set Interface eth1 type=dummy -- \
66    add-port br0 eth2 -- set Interface eth2 type=dummy])
67 # Set up flow table for VLAN+MAC learning.
68 AT_DATA([flows.txt], [[
69 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)
70 table=1 priority=0 actions=flood
71 ]])
72 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
73
74 # Trace an ARP packet arriving on port 3, to create a MAC learning entry.
75 AT_CHECK([ovs-appctl ofproto/trace br0 '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)' -generate], [0], [stdout])
76 AT_CHECK([tail -1 stdout], [0], [Datapath actions: 2,0,1
77 ])
78
79 # Check for the MAC learning entry.
80 AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
81  table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:05 actions=output:3
82  table=1, priority=0 actions=FLOOD
83 NXST_FLOW reply:
84 ])
85
86 # Trace a packet arrival destined for the learned MAC.
87 # (This will also learn a MAC.)
88 AT_CHECK([ovs-appctl ofproto/trace br0 '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])
89 AT_CHECK([tail -1 stdout], [0], [Datapath actions: 3
90 ])
91
92 # Check for both MAC learning entries.
93 AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip |sort], [0], [dnl
94  table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:05 actions=output:3
95  table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:06 actions=output:1
96  table=1, priority=0 actions=FLOOD
97 NXST_FLOW reply:
98 ])
99
100 # Trace a packet arrival that updates the first learned MAC entry.
101 AT_CHECK([ovs-appctl ofproto/trace br0 '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)' -generate], [0], [stdout])
102 AT_CHECK([tail -1 stdout], [0], [Datapath actions: 3,0,1
103 ])
104
105 # Check that the MAC learning entry was updated.
106 AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
107  table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:05 actions=output:2
108  table=1, hard_timeout=60, vlan_tci=0x0000/0x0fff,dl_dst=50:54:00:00:00:06 actions=output:1
109  table=1, priority=0 actions=FLOOD
110 NXST_FLOW reply:
111 ])
112 OVS_VSWITCHD_STOP
113 AT_CLEANUP
114
115 dnl This test checks that repeated uses of a "learn" action cause the
116 dnl modified time of the learned flow to advance.  Otherwise, the
117 dnl learned flow will expire after its hard timeout even though it's
118 dnl supposed to be refreshed.  (The expiration can be hard to see since
119 dnl it gets re-learned again the next time a packet appears, but
120 dnl sometimes the expiration can cause temporary flooding etc.)
121 AT_SETUP([learning action - learn refreshes hard_age])
122 OVS_VSWITCHD_START(
123   [add-port br0 p1 -- set Interface p1 type=dummy -- \
124    add-port br0 p2 -- set Interface p2 type=dummy -- \
125    add-port br0 p3 -- set Interface p3 type=dummy])
126
127 ovs-appctl time/stop
128
129 # Set up flow table for MAC learning.
130 AT_DATA([flows.txt], [[
131 table=0 actions=learn(table=1, hard_timeout=10, NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], output:NXM_OF_IN_PORT[]), resubmit(,1)
132 table=1 priority=0 actions=flood
133 ]])
134 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
135
136 # Trace an ICMP packet arriving on port 3, to create a MAC learning entry.
137 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)"
138 AT_CHECK([ovs-appctl ofproto/trace br0 "$flow" -generate], [0], [stdout])
139 actual=`tail -1 stdout | sed 's/Datapath actions: //'`
140
141 expected="0,1,2"
142 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
143 mv stdout expout
144 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
145
146 # Check that the MAC learning entry appeared.
147 AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
148  table=1, hard_timeout=10, dl_dst=50:54:00:00:00:07 actions=output:3
149  table=1, priority=0 actions=FLOOD
150 NXST_FLOW reply:
151 ])
152
153 # For 25 seconds, make sure that the MAC learning entry doesn't
154 # disappear as long as we refresh it every second.
155 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
156     ovs-appctl time/warp 1000
157     AT_CHECK([ovs-appctl ofproto/trace br0 "$flow" -generate], [0], [stdout])
158
159     # Check that the entry is there.
160     AT_CHECK([ovs-ofctl dump-flows br0 table=1], [0], [stdout])
161     AT_CHECK([ofctl_strip < stdout | sort], [0], [dnl
162  table=1, hard_timeout=10, dl_dst=50:54:00:00:00:07 actions=output:3
163  table=1, priority=0 actions=FLOOD
164 NXST_FLOW reply:
165 ])
166
167     if test $i != 1; then
168         # Check that hard_age has appeared.  We need to do this separately
169         # from the above check because ofctl_strip removes it.  dump-flows
170         # only prints hard_age when it is different from the flow's duration
171         # (that is, the number of seconds from the time it was created),
172         # so we only check for it after we've refreshed the flow once.
173         AT_CHECK([grep dl_dst=50:54:00:00:00:07 stdout | grep -c hard_age],
174                  [0], [1
175 ])
176     fi
177 done
178
179 # Make sure that 15 seconds without refreshing makes the flow time out.
180 ovs-appctl time/warp 5000
181 ovs-appctl time/warp 5000
182 ovs-appctl time/warp 5000
183     AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
184  table=1, priority=0 actions=FLOOD
185 NXST_FLOW reply:
186 ])
187 OVS_VSWITCHD_STOP
188 AT_CLEANUP
189
190 AT_SETUP([learning action - TCPv4 port learning])
191 OVS_VSWITCHD_START(
192   [add-port br0 eth0 -- set Interface eth0 type=dummy -- \
193    add-port br0 eth1 -- set Interface eth1 type=dummy -- \
194    add-port br0 eth2 -- set Interface eth2 type=dummy])
195 # Set up flow table for TCPv4 port learning.
196 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']])
197
198 # Trace a TCPv4 packet arriving on port 3.
199 AT_CHECK([ovs-appctl ofproto/trace br0 '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)' -generate], [0], [stdout])
200 AT_CHECK([tail -1 stdout], [0], [Datapath actions: 2,0,1
201 ])
202
203 # Check for the learning entry.
204 AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip | sort], [0], [dnl
205  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
206 NXST_FLOW reply:
207 ])
208 OVS_VSWITCHD_STOP
209 AT_CLEANUP
210
211 AT_SETUP([learning action - TCPv6 port learning])
212 OVS_VSWITCHD_START(
213   [add-port br0 eth0 -- set Interface eth0 type=dummy -- \
214    add-port br0 eth1 -- set Interface eth1 type=dummy -- \
215    add-port br0 eth2 -- set Interface eth2 type=dummy])
216 # Set up flow table for TCPv6 port learning.
217 # Also add a 128-bit-wide "load" action and a 128-bit literal match to check
218 # that they work.
219 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']])
220
221 # Trace a TCPv6 packet arriving on port 3.
222 AT_CHECK([ovs-appctl ofproto/trace br0 '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)' -generate], [0], [stdout])
223 AT_CHECK([tail -1 stdout], [0], [Datapath actions: 2,0,1
224 ])
225
226 # Check for the learning entry.
227 AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl
228  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]]
229  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
230 NXST_FLOW reply:
231 ])
232 OVS_VSWITCHD_STOP
233 AT_CLEANUP
234
235 AT_SETUP([learning action - fin_timeout feature])
236 # This is a totally artificial use of the "learn" action.  The only purpose
237 # is to check that specifying fin_idle_timeout or fin_hard_timeout causes
238 # a corresponding fin_timeout action to end up in the learned flows.
239 OVS_VSWITCHD_START
240 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[])']])
241 AT_CHECK([ovs-appctl ofproto/trace br0 '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])
242 AT_CHECK([ovs-ofctl dump-flows br0 table=1 | ofctl_strip], [0],
243 [NXST_FLOW reply:
244  table=1, dl_dst=50:54:00:00:00:05 actions=fin_timeout(idle_timeout=5,hard_timeout=10),output:1
245 ])
246 OVS_VSWITCHD_STOP
247 AT_CLEANUP