ofproto-dpif: Don't output to in_port even if in_port is OFPP_LOCAL.
[sliver-openvswitch.git] / tests / ofproto-dpif.at
1 AT_BANNER([ofproto-dpif])
2
3 AT_SETUP([ofproto-dpif - resubmit])
4 OVS_VSWITCHD_START
5 AT_DATA([flows.txt], [dnl
6 table=0 in_port=1 priority=1000 icmp actions=output(10),resubmit(2),output(19),resubmit(3),output(21)
7 table=0 in_port=2 priority=1500 icmp actions=output(11),resubmit(,1),output(16),resubmit(2,1),output(18)
8 table=0 in_port=3 priority=2000 icmp actions=output(20)
9 table=1 in_port=1 priority=1000 icmp actions=output(12),resubmit(4,1),output(13),resubmit(3),output(15)
10 table=1 in_port=2 priority=1500 icmp actions=output(17),resubmit(,2)
11 table=1 in_port=3 priority=1500 icmp actions=output(14),resubmit(,2)
12 ])
13 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
14 AT_CHECK([ovs-appctl ofproto/trace br0 '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=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)'], [0], [stdout])
15 AT_CHECK([tail -1 stdout], [0],
16   [Datapath actions: 10,11,12,13,14,15,16,17,18,19,20,21
17 ])
18 OVS_VSWITCHD_STOP
19 AT_CLEANUP
20
21 AT_SETUP([ofproto-dpif - registers])
22 OVS_VSWITCHD_START
23 AT_DATA([flows.txt], [dnl
24 in_port=90                 actions=resubmit:2,resubmit:3,resubmit:4,resubmit:91
25 in_port=91                 actions=resubmit:5,resubmit:6,resubmit:7,resubmit:92
26 in_port=92                 actions=resubmit:8,resubmit:9,resubmit:10,resubmit:11
27 in_port=2                  actions=load:0x000db000->NXM_NX_REG0[[]]
28 in_port=3                  actions=load:0xdea->NXM_NX_REG0[[20..31]]
29 in_port=4                  actions=load:0xeef->NXM_NX_REG0[[0..11]]
30 in_port=5                  actions=move:NXM_NX_REG0[[]]->NXM_NX_REG1[[]]
31 in_port=6                  actions=load:0x22222222->NXM_NX_REG2[[]]
32 in_port=7                  actions=move:NXM_NX_REG1[[20..31]]->NXM_NX_REG2[[0..11]]
33 in_port=8                  actions=move:NXM_NX_REG1[[0..11]]->NXM_NX_REG2[[20..31]]
34 in_port=9,reg0=0xdeadbeef  actions=output:20
35 in_port=10,reg1=0xdeadbeef actions=output:21
36 in_port=11,reg2=0xeef22dea actions=output:22
37 ])
38 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
39 AT_CHECK([ovs-appctl ofproto/trace br0 'in_port(90),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=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)'], [0], [stdout])
40 AT_CHECK([tail -1 stdout], [0],
41   [Datapath actions: 20,21,22
42 ])
43 OVS_VSWITCHD_STOP
44 AT_CLEANUP
45
46 AT_SETUP([ofproto-dpif - output])
47 OVS_VSWITCHD_START
48 AT_DATA([flows.txt], [dnl
49 in_port=1 actions=resubmit:2,resubmit:3,resubmit:4,resubmit:5,resubmit:6,resubmit:7
50 in_port=2 actions=output:9
51 in_port=3 actions=load:55->NXM_NX_REG0[[]],output:NXM_NX_REG0[[]],load:66->NXM_NX_REG1[[]]
52 in_port=4 actions=output:10,output:NXM_NX_REG0[[]],output:NXM_NX_REG1[[]],output:11
53 in_port=5 actions=load:77->NXM_NX_REG0[[0..15]],load:88->NXM_NX_REG0[[16..31]]
54 in_port=6 actions=output:NXM_NX_REG0[[0..15]],output:NXM_NX_REG0[[16..31]]
55 in_port=7 actions=load:0x110000ff->NXM_NX_REG0[[]],output:NXM_NX_REG0[[]]
56 ])
57 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
58 AT_CHECK([ovs-appctl ofproto/trace br0 '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=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)'], [0], [stdout])
59 AT_CHECK([tail -1 stdout], [0],
60   [Datapath actions: 9,55,10,55,66,11,77,88
61 ])
62 OVS_VSWITCHD_STOP
63 AT_CLEANUP
64
65 AT_SETUP([ofproto-dpif - dec_ttl])
66 OVS_VSWITCHD_START
67 AT_DATA([flows.txt], [dnl
68 table=0 in_port=1 action=dec_ttl,output:2,resubmit(1,1),output:4
69 table=1 in_port=1 action=dec_ttl,output:3
70 ])
71 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
72 AT_CHECK([ovs-appctl ofproto/trace br0 '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=1,tos=0,ttl=2,frag=no)' -generate], [0], [stdout])
73 AT_CHECK([tail -2 stdout], [0],
74   [Datapath actions: set(ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=1,frag=no)),2,4
75 This flow is not cachable.
76 ])
77 AT_CHECK([ovs-appctl ofproto/trace br0 '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=1,tos=0,ttl=3,frag=no)'], [0], [stdout])
78 AT_CHECK([tail -1 stdout], [0],
79   [Datapath actions: set(ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=2,frag=no)),2,set(ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=1,frag=no)),3,4
80 ])
81 AT_CHECK([ovs-appctl ofproto/trace br0 'in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x86dd),ipv6(src=::1,dst=::2,label=0,proto=10,tclass=0x70,hlimit=128,frag=no)'], [0], [stdout])
82 AT_CHECK([tail -1 stdout], [0],
83   [Datapath actions: set(ipv6(src=::1,dst=::2,label=0,proto=10,tclass=0x70,hlimit=127,frag=no)),2,set(ipv6(src=::1,dst=::2,label=0,proto=10,tclass=0x70,hlimit=126,frag=no)),3,4
84 ])
85
86 AT_CHECK([ovs-ofctl monitor br0 65534 invalid_ttl --detach --pidfile 2> ofctl_monitor.log])
87 AT_CHECK([ovs-appctl ofproto/trace br0 '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=1,tos=0,ttl=2,frag=no)' -generate], [0], [stdout])
88 OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
89 AT_CHECK([cat ofctl_monitor.log], [0], [dnl
90 NXT_PACKET_IN (xid=0x0): table_id=1 total_len=42 in_port=1 tun_id=0x0 reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 (via invalid_ttl) data_len=42 (unbuffered)
91 priority:0,tunnel:0,in_port:0000,tci(0) mac(50:54:00:00:00:05->50:54:00:00:00:07) type:0800 proto:1 tos:0 ttl:1 ip(192.168.0.1->192.168.0.2)
92 ])
93 OVS_VSWITCHD_STOP
94 AT_CLEANUP
95
96
97 AT_SETUP([ofproto-dpif - output, OFPP_NONE ingress port])
98 OVS_VSWITCHD_START(
99        [add-port br0 p1 -- set Interface p1 type=dummy --\
100         add-port br0 p2 -- set Interface p2 type=dummy])
101
102 AT_CHECK([ovs-ofctl add-flow br0 action=normal])
103
104 # "in_port" defaults to OFPP_NONE if it's not specified.
105 flow="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=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)"
106 AT_CHECK([ovs-appctl ofproto/trace br0 "$flow"], [0], [stdout])
107 actual=`tail -1 stdout | sed 's/Datapath actions: //'`
108
109 expected="0,1,2"
110 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
111 mv stdout expout
112 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
113
114 OVS_VSWITCHD_STOP
115 AT_CLEANUP
116
117 AT_SETUP([ofproto-dpif - DSCP])
118 OVS_VSWITCHD_START([add-port br0 p1 -- set Interface p1 type=dummy])
119 AT_DATA([flows.txt], [dnl
120 actions=output:65534,enqueue:1:1,enqueue:1:2,enqueue:1:2,enqueue:1:1,output:1,mod_nw_tos:0,output:1,output:65534
121 ])
122 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
123 AT_CHECK([ovs-vsctl -- \
124         set Port p1 qos=@newqos --\
125         --id=@newqos create QoS type=linux-htb queues=1=@q1,2=@q2 --\
126         --id=@q1 create Queue dscp=1 --\
127         --id=@q2 create Queue dscp=2], [0], [ignore])
128 AT_CHECK([ovs-appctl ofproto/trace br0 'in_port(9),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=1.1.1.1,dst=2.2.2.2,proto=1,tos=0xff,ttl=128,frag=no),icmp(type=8,code=0)'], [0], [stdout])
129 AT_CHECK([tail -1 stdout], [0],
130   [Datapath actions: dnl
131 0,dnl
132 set(ipv4(src=1.1.1.1,dst=2.2.2.2,proto=1,tos=0x7,ttl=128,frag=no)),set(priority(1)),1,dnl
133 set(ipv4(src=1.1.1.1,dst=2.2.2.2,proto=1,tos=0xb,ttl=128,frag=no)),set(priority(2)),1,dnl
134 1,dnl
135 set(ipv4(src=1.1.1.1,dst=2.2.2.2,proto=1,tos=0x7,ttl=128,frag=no)),set(priority(1)),1,dnl
136 set(ipv4(src=1.1.1.1,dst=2.2.2.2,proto=1,tos=0xff,ttl=128,frag=no)),set(priority(0)),1,dnl
137 set(ipv4(src=1.1.1.1,dst=2.2.2.2,proto=1,tos=0x3,ttl=128,frag=no)),1,dnl
138 0
139 ])
140 OVS_VSWITCHD_STOP
141 AT_CLEANUP
142
143 AT_SETUP([ofproto-dpif - output/flood flags])
144 OVS_VSWITCHD_START([dnl
145         add-port br0 p1 -- set Interface p1 type=dummy --\
146         add-port br0 p2 -- set Interface p2 type=dummy --\
147         add-port br0 p3 -- set Interface p3 type=dummy --\
148         add-port br0 p4 -- set Interface p4 type=dummy --\
149         add-port br0 p5 -- set Interface p5 type=dummy --\
150         add-port br0 p6 -- set Interface p6 type=dummy --\
151         add-port br0 p7 -- set Interface p7 type=dummy ])
152
153 AT_DATA([flows.txt], [dnl
154 in_port=local actions=local,flood
155 in_port=1 actions=flood
156 in_port=2 actions=all
157 in_port=3 actions=output:65534,output:1,output:2,output:3,output:4,output:5,output:6,output:7
158 in_port=4 actions=enqueue:65534:1,enqueue:1:1,enqueue:2:1,enqueue:3:2,enqueue:4:1,enqueue:5:1,enqueue:6:1,enqueue:7:1
159 ])
160 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
161 AT_CHECK([ovs-ofctl mod-port br0 5 noforward])
162 AT_CHECK([ovs-ofctl mod-port br0 6 noflood])
163
164 AT_CHECK([ovs-appctl ofproto/trace br0 'in_port(0),eth(src=00:00:00:00:00:01,dst=00:00:00:00:00:02),eth_type(0x0900)'], [0], [stdout])
165 AT_CHECK([tail -1 stdout \
166 | sed -e 's/Datapath actions: //' | tr ',' '\n' | sort], [0], [dnl
167 1
168 2
169 3
170 4
171 7
172 ])
173
174 AT_CHECK([ovs-appctl ofproto/trace br0 'in_port(1),eth(src=00:00:00:00:00:01,dst=00:00:00:00:00:02),eth_type(0x0900)'], [0], [stdout])
175 AT_CHECK([tail -1 stdout \
176 | sed -e 's/Datapath actions: //' | tr ',' '\n' | sort], [0], [dnl
177 0
178 2
179 3
180 4
181 7
182 ])
183
184 AT_CHECK([ovs-appctl ofproto/trace br0 'in_port(2),eth(src=00:00:00:00:00:01,dst=00:00:00:00:00:02),eth_type(0x0900)'], [0], [stdout])
185 AT_CHECK([tail -1 stdout \
186 | sed -e 's/Datapath actions: //' | tr ',' '\n' | sort], [0], [dnl
187 0
188 1
189 3
190 4
191 6
192 7
193 ])
194
195 AT_CHECK([ovs-appctl ofproto/trace br0 'in_port(3),eth(src=00:00:00:00:00:01,dst=00:00:00:00:00:02),eth_type(0x0900)'], [0], [stdout])
196 AT_CHECK([tail -1 stdout], [0],
197   [Datapath actions: 0,1,2,4,6,7
198 ])
199
200 AT_CHECK([ovs-appctl ofproto/trace br0 'in_port(4),eth(src=00:00:00:00:00:01,dst=00:00:00:00:00:02),eth_type(0x0900)'], [0], [stdout])
201 AT_CHECK([tail -1 stdout], [0],
202   [Datapath actions: set(priority(1)),0,1,2,set(priority(2)),3,set(priority(1)),6,7
203 ])
204 OVS_VSWITCHD_STOP
205 AT_CLEANUP
206
207 AT_SETUP([ofproto-dpif - set_tunnel])
208 OVS_VSWITCHD_START
209 AT_DATA([flows.txt], [dnl
210 in_port=90 actions=resubmit:1,resubmit:2,resubmit:3,resubmit:4,resubmit:5
211 in_port=1 actions=set_tunnel:1,output:1
212 in_port=2 actions=set_tunnel:1,output:2
213 in_port=3 actions=set_tunnel:2,set_tunnel:3,output:3
214 in_port=4 actions=set_tunnel:4,set_tunnel:3,output:4
215 in_port=5 actions=set_tunnel:5
216 ])
217 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
218 AT_CHECK([ovs-appctl ofproto/trace br0 'tun_id(0x1),in_port(90),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=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)'], [0], [stdout])
219 AT_CHECK([tail -1 stdout], [0],
220   [Datapath actions: set(tun_id(0x1)),1,2,set(tun_id(0x3)),3,4
221 ])
222 OVS_VSWITCHD_STOP
223 AT_CLEANUP
224
225 AT_SETUP([ofproto-dpif - controller])
226 OVS_VSWITCHD_START([dnl
227    add-port br0 p1 -- set Interface p1 type=dummy
228 ])
229
230 AT_CAPTURE_FILE([ofctl_monitor.log])
231 AT_DATA([flows.txt], [dnl
232 cookie=0x0 dl_src=10:11:11:11:11:11 actions=controller
233 cookie=0x1 dl_src=20:22:22:22:22:22 actions=controller,resubmit(80,1)
234 cookie=0x2 dl_src=30:33:33:33:33:33 actions=mod_vlan_vid:15,controller
235
236 cookie=0x3 table=1 in_port=80 actions=load:1->NXM_NX_REG0[[]],mod_vlan_vid:80,controller,resubmit(81,2)
237 cookie=0x4 table=2 in_port=81 actions=load:2->NXM_NX_REG1[[]],mod_dl_src:80:81:81:81:81:81,controller,resubmit(82,3)
238 cookie=0x5 table=3 in_port=82 actions=load:3->NXM_NX_REG2[[]],mod_dl_dst:82:82:82:82:82:82,controller,resubmit(83,4)
239 cookie=0x6 table=4 in_port=83 actions=load:4->NXM_NX_REG3[[]],mod_nw_src:83.83.83.83,controller,resubmit(84,5)
240 cookie=0x7 table=5 in_port=84 actions=load:5->NXM_NX_REG4[[]],load:6->NXM_NX_TUN_ID[[]],mod_nw_dst:84.84.84.84,controller,resubmit(85,6)
241 cookie=0x8 table=6 in_port=85 actions=mod_tp_src:85,controller,resubmit(86,7)
242 cookie=0x9 table=7 in_port=86 actions=mod_tp_dst:86,controller,controller
243 ])
244 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
245
246 dnl Flow miss.
247 AT_CHECK([ovs-ofctl monitor -P openflow10 br0 65534 --detach --pidfile 2> ofctl_monitor.log])
248
249 for i in 1 2 3 ; do
250     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)'
251 done
252
253 OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
254 AT_CHECK([cat ofctl_monitor.log], [0], [dnl
255 OFPT_PACKET_IN (xid=0x0): total_len=60 in_port=1 (via no_match) data_len=60 (unbuffered)
256 priority:0,tunnel:0,in_port:0000,tci(0) mac(50:54:00:00:00:05->50:54:00:00:00:07) type:0800 proto:6 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->9) tcp_csum:0
257 dnl
258 OFPT_PACKET_IN (xid=0x0): total_len=60 in_port=1 (via no_match) data_len=60 (unbuffered)
259 priority:0,tunnel:0,in_port:0000,tci(0) mac(50:54:00:00:00:05->50:54:00:00:00:07) type:0800 proto:6 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->9) tcp_csum:0
260 dnl
261 OFPT_PACKET_IN (xid=0x0): total_len=60 in_port=1 (via no_match) data_len=60 (unbuffered)
262 priority:0,tunnel:0,in_port:0000,tci(0) mac(50:54:00:00:00:05->50:54:00:00:00:07) type:0800 proto:6 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->9) tcp_csum:0
263 ])
264
265 dnl Singleton controller action.
266 AT_CHECK([ovs-ofctl monitor -P openflow10 br0 65534 --detach --pidfile 2> ofctl_monitor.log])
267
268 for i in 1 2 3 ; do
269     ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=10:11:11:11:11:11,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=10)'
270 done
271
272 OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
273 AT_CHECK([cat ofctl_monitor.log], [0], [dnl
274 OFPT_PACKET_IN (xid=0x0): total_len=60 in_port=1 (via action) data_len=60 (unbuffered)
275 priority:0,tunnel:0,in_port:0000,tci(0) mac(10:11:11:11:11:11->50:54:00:00:00:07) type:0800 proto:6 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->10) tcp_csum:0
276 dnl
277 OFPT_PACKET_IN (xid=0x0): total_len=60 in_port=1 (via action) data_len=60 (unbuffered)
278 priority:0,tunnel:0,in_port:0000,tci(0) mac(10:11:11:11:11:11->50:54:00:00:00:07) type:0800 proto:6 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->10) tcp_csum:0
279 dnl
280 OFPT_PACKET_IN (xid=0x0): total_len=60 in_port=1 (via action) data_len=60 (unbuffered)
281 priority:0,tunnel:0,in_port:0000,tci(0) mac(10:11:11:11:11:11->50:54:00:00:00:07) type:0800 proto:6 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->10) tcp_csum:0
282 ])
283
284 dnl Modified controller action.
285 AT_CHECK([ovs-ofctl monitor -P openflow10 br0 65534 --detach --pidfile 2> ofctl_monitor.log])
286
287 for i in 1 2 3 ; do
288     ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=30:33:33:33:33:33,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=10)'
289 done
290
291 OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
292 AT_CHECK([cat ofctl_monitor.log], [0], [dnl
293 OFPT_PACKET_IN (xid=0x0): total_len=64 in_port=1 (via action) data_len=64 (unbuffered)
294 priority:0,tunnel:0,in_port:0000,tci(vlan:15,pcp:0) mac(30:33:33:33:33:33->50:54:00:00:00:07) type:0800 proto:6 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->10) tcp_csum:0
295 dnl
296 OFPT_PACKET_IN (xid=0x0): total_len=64 in_port=1 (via action) data_len=64 (unbuffered)
297 priority:0,tunnel:0,in_port:0000,tci(vlan:15,pcp:0) mac(30:33:33:33:33:33->50:54:00:00:00:07) type:0800 proto:6 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->10) tcp_csum:0
298 dnl
299 OFPT_PACKET_IN (xid=0x0): total_len=64 in_port=1 (via action) data_len=64 (unbuffered)
300 priority:0,tunnel:0,in_port:0000,tci(vlan:15,pcp:0) mac(30:33:33:33:33:33->50:54:00:00:00:07) type:0800 proto:6 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->10) tcp_csum:0
301 ])
302
303 dnl Checksum TCP.
304 AT_CHECK([ovs-ofctl monitor br0 65534 -P nxm --detach --pidfile 2> ofctl_monitor.log])
305
306 for i in 1 ; do
307     ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=20:22:22:22:22:22,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=11)'
308 done
309
310 OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
311 AT_CHECK([cat ofctl_monitor.log], [0], [dnl
312 NXT_PACKET_IN (xid=0x0): cookie=0x1 total_len=60 in_port=1 tun_id=0x0 reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 (via action) data_len=60 (unbuffered)
313 priority:0,tunnel:0,in_port:0000,tci(0) mac(20:22:22:22:22:22->50:54:00:00:00:07) type:0800 proto:6 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->11) tcp_csum:0
314 dnl
315 NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x3 total_len=64 in_port=1 tun_id=0x0 reg0=0x1 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 (via action) data_len=64 (unbuffered)
316 priority:0,tunnel:0,in_port:0000,tci(vlan:80,pcp:0) mac(20:22:22:22:22:22->50:54:00:00:00:07) type:0800 proto:6 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->11) tcp_csum:0
317 dnl
318 NXT_PACKET_IN (xid=0x0): table_id=2 cookie=0x4 total_len=64 in_port=1 tun_id=0x0 reg0=0x1 reg1=0x2 reg2=0x0 reg3=0x0 reg4=0x0 (via action) data_len=64 (unbuffered)
319 priority:0,tunnel:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->50:54:00:00:00:07) type:0800 proto:6 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->11) tcp_csum:0
320 dnl
321 NXT_PACKET_IN (xid=0x0): table_id=3 cookie=0x5 total_len=64 in_port=1 tun_id=0x0 reg0=0x1 reg1=0x2 reg2=0x3 reg3=0x0 reg4=0x0 (via action) data_len=64 (unbuffered)
322 priority:0,tunnel:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->82:82:82:82:82:82) type:0800 proto:6 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->11) tcp_csum:0
323 dnl
324 NXT_PACKET_IN (xid=0x0): table_id=4 cookie=0x6 total_len=64 in_port=1 tun_id=0x0 reg0=0x1 reg1=0x2 reg2=0x3 reg3=0x4 reg4=0x0 (via action) data_len=64 (unbuffered)
325 priority:0,tunnel:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->82:82:82:82:82:82) type:0800 proto:6 tos:0 ttl:0 ip(83.83.83.83->192.168.0.2) port(8->11) tcp_csum:1a03
326 dnl
327 NXT_PACKET_IN (xid=0x0): table_id=5 cookie=0x7 total_len=64 in_port=1 tun_id=0x6 reg0=0x1 reg1=0x2 reg2=0x3 reg3=0x4 reg4=0x5 (via action) data_len=64 (unbuffered)
328 priority:0,tunnel:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->82:82:82:82:82:82) type:0800 proto:6 tos:0 ttl:0 ip(83.83.83.83->84.84.84.84) port(8->11) tcp_csum:3205
329 dnl
330 NXT_PACKET_IN (xid=0x0): table_id=6 cookie=0x8 total_len=64 in_port=1 tun_id=0x6 reg0=0x1 reg1=0x2 reg2=0x3 reg3=0x4 reg4=0x5 (via action) data_len=64 (unbuffered)
331 priority:0,tunnel:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->82:82:82:82:82:82) type:0800 proto:6 tos:0 ttl:0 ip(83.83.83.83->84.84.84.84) port(85->11) tcp_csum:31b8
332 dnl
333 NXT_PACKET_IN (xid=0x0): table_id=7 cookie=0x9 total_len=64 in_port=1 tun_id=0x6 reg0=0x1 reg1=0x2 reg2=0x3 reg3=0x4 reg4=0x5 (via action) data_len=64 (unbuffered)
334 priority:0,tunnel:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->82:82:82:82:82:82) type:0800 proto:6 tos:0 ttl:0 ip(83.83.83.83->84.84.84.84) port(85->86) tcp_csum:316d
335 dnl
336 NXT_PACKET_IN (xid=0x0): table_id=7 cookie=0x9 total_len=64 in_port=1 tun_id=0x6 reg0=0x1 reg1=0x2 reg2=0x3 reg3=0x4 reg4=0x5 (via action) data_len=64 (unbuffered)
337 priority:0,tunnel:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->82:82:82:82:82:82) type:0800 proto:6 tos:0 ttl:0 ip(83.83.83.83->84.84.84.84) port(85->86) tcp_csum:316d
338 ])
339
340 dnl Checksum UDP.
341 AT_CHECK([ovs-ofctl monitor br0 65534 --detach --pidfile 2> ofctl_monitor.log])
342
343 for i in 1 ; do
344     ovs-appctl netdev-dummy/receive p1 '50 54 00 00 00 07 20 22 22 22 22 22 08 00 45 00 00 1C 00 00 00 00 00 11 00 00 C0 A8 00 01 C0 A8 00 02 00 08 00 0B 00 00 12 34 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
345 done
346
347 OVS_WAIT_UNTIL([ovs-appctl -t ovs-ofctl exit])
348 AT_CHECK([cat ofctl_monitor.log], [0], [dnl
349 NXT_PACKET_IN (xid=0x0): cookie=0x1 total_len=60 in_port=1 tun_id=0x0 reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 (via action) data_len=60 (unbuffered)
350 priority:0,tunnel:0,in_port:0000,tci(0) mac(20:22:22:22:22:22->50:54:00:00:00:07) type:0800 proto:17 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->11) udp_csum:1234
351 dnl
352 NXT_PACKET_IN (xid=0x0): table_id=1 cookie=0x3 total_len=64 in_port=1 tun_id=0x0 reg0=0x1 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 (via action) data_len=64 (unbuffered)
353 priority:0,tunnel:0,in_port:0000,tci(vlan:80,pcp:0) mac(20:22:22:22:22:22->50:54:00:00:00:07) type:0800 proto:17 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->11) udp_csum:1234
354 dnl
355 NXT_PACKET_IN (xid=0x0): table_id=2 cookie=0x4 total_len=64 in_port=1 tun_id=0x0 reg0=0x1 reg1=0x2 reg2=0x0 reg3=0x0 reg4=0x0 (via action) data_len=64 (unbuffered)
356 priority:0,tunnel:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->50:54:00:00:00:07) type:0800 proto:17 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->11) udp_csum:1234
357 dnl
358 NXT_PACKET_IN (xid=0x0): table_id=3 cookie=0x5 total_len=64 in_port=1 tun_id=0x0 reg0=0x1 reg1=0x2 reg2=0x3 reg3=0x0 reg4=0x0 (via action) data_len=64 (unbuffered)
359 priority:0,tunnel:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->82:82:82:82:82:82) type:0800 proto:17 tos:0 ttl:0 ip(192.168.0.1->192.168.0.2) port(8->11) udp_csum:1234
360 dnl
361 NXT_PACKET_IN (xid=0x0): table_id=4 cookie=0x6 total_len=64 in_port=1 tun_id=0x0 reg0=0x1 reg1=0x2 reg2=0x3 reg3=0x4 reg4=0x0 (via action) data_len=64 (unbuffered)
362 priority:0,tunnel:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->82:82:82:82:82:82) type:0800 proto:17 tos:0 ttl:0 ip(83.83.83.83->192.168.0.2) port(8->11) udp_csum:2c37
363 dnl
364 NXT_PACKET_IN (xid=0x0): table_id=5 cookie=0x7 total_len=64 in_port=1 tun_id=0x6 reg0=0x1 reg1=0x2 reg2=0x3 reg3=0x4 reg4=0x5 (via action) data_len=64 (unbuffered)
365 priority:0,tunnel:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->82:82:82:82:82:82) type:0800 proto:17 tos:0 ttl:0 ip(83.83.83.83->84.84.84.84) port(8->11) udp_csum:4439
366 dnl
367 NXT_PACKET_IN (xid=0x0): table_id=6 cookie=0x8 total_len=64 in_port=1 tun_id=0x6 reg0=0x1 reg1=0x2 reg2=0x3 reg3=0x4 reg4=0x5 (via action) data_len=64 (unbuffered)
368 priority:0,tunnel:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->82:82:82:82:82:82) type:0800 proto:17 tos:0 ttl:0 ip(83.83.83.83->84.84.84.84) port(85->11) udp_csum:43ec
369 dnl
370 NXT_PACKET_IN (xid=0x0): table_id=7 cookie=0x9 total_len=64 in_port=1 tun_id=0x6 reg0=0x1 reg1=0x2 reg2=0x3 reg3=0x4 reg4=0x5 (via action) data_len=64 (unbuffered)
371 priority:0,tunnel:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->82:82:82:82:82:82) type:0800 proto:17 tos:0 ttl:0 ip(83.83.83.83->84.84.84.84) port(85->86) udp_csum:43a1
372 dnl
373 NXT_PACKET_IN (xid=0x0): table_id=7 cookie=0x9 total_len=64 in_port=1 tun_id=0x6 reg0=0x1 reg1=0x2 reg2=0x3 reg3=0x4 reg4=0x5 (via action) data_len=64 (unbuffered)
374 priority:0,tunnel:0,in_port:0000,tci(vlan:80,pcp:0) mac(80:81:81:81:81:81->82:82:82:82:82:82) type:0800 proto:17 tos:0 ttl:0 ip(83.83.83.83->84.84.84.84) port(85->86) udp_csum:43a1
375 ])
376
377 AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl
378  cookie=0x1, n_packets=2, n_bytes=120, dl_src=20:22:22:22:22:22 actions=CONTROLLER:65535,resubmit(80,1)
379  cookie=0x2, n_packets=3, n_bytes=180, dl_src=30:33:33:33:33:33 actions=mod_vlan_vid:15,CONTROLLER:65535
380  cookie=0x3, table=1, n_packets=2, n_bytes=120, in_port=80 actions=load:0x1->NXM_NX_REG0[[]],mod_vlan_vid:80,CONTROLLER:65535,resubmit(81,2)
381  cookie=0x4, table=2, n_packets=2, n_bytes=120, in_port=81 actions=load:0x2->NXM_NX_REG1[[]],mod_dl_src:80:81:81:81:81:81,CONTROLLER:65535,resubmit(82,3)
382  cookie=0x5, table=3, n_packets=2, n_bytes=120, in_port=82 actions=load:0x3->NXM_NX_REG2[[]],mod_dl_dst:82:82:82:82:82:82,CONTROLLER:65535,resubmit(83,4)
383  cookie=0x6, table=4, n_packets=2, n_bytes=120, in_port=83 actions=load:0x4->NXM_NX_REG3[[]],mod_nw_src:83.83.83.83,CONTROLLER:65535,resubmit(84,5)
384  cookie=0x7, table=5, n_packets=2, n_bytes=120, in_port=84 actions=load:0x5->NXM_NX_REG4[[]],load:0x6->NXM_NX_TUN_ID[[]],mod_nw_dst:84.84.84.84,CONTROLLER:65535,resubmit(85,6)
385  cookie=0x8, table=6, n_packets=2, n_bytes=120, in_port=85 actions=mod_tp_src:85,CONTROLLER:65535,resubmit(86,7)
386  cookie=0x9, table=7, n_packets=2, n_bytes=120, in_port=86 actions=mod_tp_dst:86,CONTROLLER:65535,CONTROLLER:65535
387  n_packets=3, n_bytes=180, dl_src=10:11:11:11:11:11 actions=CONTROLLER:65535
388 NXST_FLOW reply:
389 ])
390
391 OVS_VSWITCHD_STOP
392 AT_CLEANUP
393
394 AT_SETUP([ofproto-dpif - VLAN handling])
395 OVS_VSWITCHD_START(
396   [set Bridge br0 fail-mode=standalone -- \
397    add-port br0 p1                                  trunks=10,12 -- \
398    add-port br0 p2                           tag=10              -- \
399    add-port br0 p3                           tag=12              \
400                    other-config:priority-tags=true               -- \
401    add-port br0 p4                           tag=12              -- \
402    add-port br0 p5 vlan_mode=native-tagged   tag=10              -- \
403    add-port br0 p6 vlan_mode=native-tagged   tag=10 trunks=10,12 -- \
404    add-port br0 p7 vlan_mode=native-untagged tag=12              -- \
405    add-port br0 p8 vlan_mode=native-untagged tag=12 trunks=10,12 \
406                    other-config:priority-tags=true               -- \
407    set Interface p1 type=dummy -- \
408    set Interface p2 type=dummy -- \
409    set Interface p3 type=dummy -- \
410    set Interface p4 type=dummy -- \
411    set Interface p5 type=dummy -- \
412    set Interface p6 type=dummy -- \
413    set Interface p7 type=dummy -- \
414    set Interface p8 type=dummy --])
415
416 dnl Each of these specifies an in_port by number, a VLAN VID (or "none"),
417 dnl a VLAN PCP (used if the VID isn't "none") and the expected set of datapath
418 dnl actions.
419 for tuple in \
420         "0 none 0 drop" \
421         "0 0    0 drop" \
422         "0 0    1 drop" \
423         "0 10   0 1,5,6,7,8,pop_vlan,2" \
424         "0 10   1 1,5,6,7,8,pop_vlan,2" \
425         "0 11   0 5,7" \
426         "0 11   1 5,7" \
427         "0 12   0 1,5,6,pop_vlan,3,4,7,8" \
428         "0 12   1 1,5,6,pop_vlan,4,7,push_vlan(vid=0,pcp=1),3,8" \
429         "1  none 0 drop" \
430         "1  0    0 drop" \
431         "1  0    1 drop" \
432         "1  10   0 0,5,6,7,8,pop_vlan,2" \
433         "1  10   1 0,5,6,7,8,pop_vlan,2" \
434         "1  11   0 drop" \
435         "1  11   1 drop" \
436         "1  12   0 0,5,6,pop_vlan,3,4,7,8" \
437         "1  12   1 0,5,6,pop_vlan,4,7,push_vlan(vid=0,pcp=1),3,8" \
438         "2  none 0 push_vlan(vid=10,pcp=0),0,1,5,6,7,8" \
439         "2  0    0 pop_vlan,push_vlan(vid=10,pcp=0),0,1,5,6,7,8" \
440         "2  0    1 pop_vlan,push_vlan(vid=10,pcp=1),0,1,5,6,7,8" \
441         "2  10   0 drop" \
442         "2  10   1 drop" \
443         "2  11   0 drop" \
444         "2  11   1 drop" \
445         "2  12   0 drop" \
446         "2  12   1 drop" \
447         "3  none 0 4,7,8,push_vlan(vid=12,pcp=0),0,1,5,6" \
448         "3  0    0 pop_vlan,4,7,8,push_vlan(vid=12,pcp=0),0,1,5,6" \
449         "3  0    1 8,pop_vlan,4,7,push_vlan(vid=12,pcp=1),0,1,5,6" \
450         "3  10   0 drop" \
451         "3  10   1 drop" \
452         "3  11   0 drop" \
453         "3  11   1 drop" \
454         "3  12   0 drop" \
455         "3  12   1 drop" \
456         "4  none 0 3,7,8,push_vlan(vid=12,pcp=0),0,1,5,6" \
457         "4  0    0 pop_vlan,3,7,8,push_vlan(vid=12,pcp=0),0,1,5,6" \
458         "4  0    1 3,8,pop_vlan,7,push_vlan(vid=12,pcp=1),0,1,5,6" \
459         "4  10   0 drop" \
460         "4  10   1 drop" \
461         "4  11   0 drop" \
462         "4  11   1 drop" \
463         "4  12   0 drop" \
464         "4  12   1 drop" \
465         "5  none 0 2,push_vlan(vid=10,pcp=0),0,1,6,7,8" \
466         "5  0    0 pop_vlan,2,push_vlan(vid=10,pcp=0),0,1,6,7,8" \
467         "5  0    1 pop_vlan,2,push_vlan(vid=10,pcp=1),0,1,6,7,8" \
468         "5  10   0 0,1,6,7,8,pop_vlan,2" \
469         "5  10   1 0,1,6,7,8,pop_vlan,2" \
470         "5  11   0 0,7" \
471         "5  11   1 0,7" \
472         "5  12   0 0,1,6,pop_vlan,3,4,7,8" \
473         "5  12   1 0,1,6,pop_vlan,4,7,push_vlan(vid=0,pcp=1),3,8" \
474         "6  none 0 2,push_vlan(vid=10,pcp=0),0,1,5,7,8" \
475         "6  0    0 pop_vlan,2,push_vlan(vid=10,pcp=0),0,1,5,7,8" \
476         "6  0    1 pop_vlan,2,push_vlan(vid=10,pcp=1),0,1,5,7,8" \
477         "6  10   0 0,1,5,7,8,pop_vlan,2" \
478         "6  10   1 0,1,5,7,8,pop_vlan,2" \
479         "6  11   0 drop" \
480         "6  11   1 drop" \
481         "6  12   0 0,1,5,pop_vlan,3,4,7,8" \
482         "6  12   1 0,1,5,pop_vlan,4,7,push_vlan(vid=0,pcp=1),3,8" \
483         "7  none 0 3,4,8,push_vlan(vid=12,pcp=0),0,1,5,6" \
484         "7  0    0 pop_vlan,3,4,8,push_vlan(vid=12,pcp=0),0,1,5,6" \
485         "7  0    1 3,8,pop_vlan,4,push_vlan(vid=12,pcp=1),0,1,5,6" \
486         "7  10   0 0,1,5,6,8,pop_vlan,2" \
487         "7  10   1 0,1,5,6,8,pop_vlan,2" \
488         "7  11   0 0,5" \
489         "7  11   1 0,5" \
490         "7  12   0 0,1,5,6,pop_vlan,3,4,8" \
491         "7  12   1 0,1,5,6,pop_vlan,4,push_vlan(vid=0,pcp=1),3,8" \
492         "8  none 0 3,4,7,push_vlan(vid=12,pcp=0),0,1,5,6" \
493         "8  0    0 pop_vlan,3,4,7,push_vlan(vid=12,pcp=0),0,1,5,6" \
494         "8  0    1 3,pop_vlan,4,7,push_vlan(vid=12,pcp=1),0,1,5,6" \
495         "8  10   0 0,1,5,6,7,pop_vlan,2" \
496         "8  10   1 0,1,5,6,7,pop_vlan,2" \
497         "8  11   0 drop" \
498         "8  11   1 drop" \
499         "8  12   0 0,1,5,6,pop_vlan,3,4,7" \
500         "8  12   1 0,1,5,6,pop_vlan,4,7,push_vlan(vid=0,pcp=1),3"
501 do
502   set $tuple
503   in_port=$1
504   vlan=$2
505   pcp=$3
506   expected=$4
507
508   if test $vlan = none; then
509     flow="in_port($in_port),eth(src=50:54:00:00:00:01,dst=ff:ff:ff:ff:ff:ff),eth_type(0xabcd)"
510   else
511     flow="in_port($in_port),eth(src=50:54:00:00:00:01,dst=ff:ff:ff:ff:ff:ff),eth_type(0x8100),vlan(vid=$vlan,pcp=$pcp),encap(eth_type(0xabcd))"
512   fi
513
514   echo "----------------------------------------------------------------------"
515   echo "in_port=$in_port vlan=$vlan pcp=$pcp"
516
517   AT_CHECK([ovs-appctl ofproto/trace br0 "$flow"], [0], [stdout])
518   actual=`tail -1 stdout | sed 's/Datapath actions: //'`
519
520   AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
521   mv stdout expout
522   AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
523 done
524
525 OVS_VSWITCHD_STOP
526 AT_CLEANUP
527
528 AT_SETUP([ofproto-dpif - fragment handling])
529 OVS_VSWITCHD_START
530 AT_DATA([flows.txt], [dnl
531 priority=75 tcp ip_frag=no    tp_dst=80 actions=output:1
532 priority=75 tcp ip_frag=first tp_dst=80 actions=output:2
533 priority=75 tcp ip_frag=later tp_dst=80 actions=output:3
534 priority=50 tcp ip_frag=no              actions=output:4
535 priority=50 tcp ip_frag=first           actions=output:5
536 priority=50 tcp ip_frag=later           actions=output:6
537 ])
538 AT_CHECK([ovs-ofctl replace-flows br0 flows.txt])
539
540 base_flow="in_port(90),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=128"
541 no_flow="$base_flow,frag=no),tcp(src=12345,dst=80)"
542 first_flow="$base_flow,frag=first),tcp(src=12345,dst=80)"
543 later_flow="$base_flow,frag=later)"
544
545     # mode    no  first  later
546 for tuple in \
547     'normal    1     5      6' \
548     'drop      1  drop   drop' \
549     'nx-match  1     2      6'
550 do
551   set $tuple
552   mode=$1
553   no=$2
554   first=$3
555   later=$4
556
557   AT_CHECK([ovs-ofctl set-frags br0 $mode])
558   for type in no first later; do
559     eval flow=\$${type}_flow exp_output=\$$type
560     AT_CHECK([ovs-appctl ofproto/trace br0 "$flow"], [0], [stdout])
561     AT_CHECK_UNQUOTED([tail -1 stdout], [0], [Datapath actions: $exp_output
562 ])
563   done
564 done
565 OVS_VSWITCHD_STOP
566 AT_CLEANUP
567
568 AT_SETUP([ofproto-dpif - exit])
569 OVS_VSWITCHD_START
570 AT_DATA([flows.txt], [dnl
571 in_port=1 actions=output:10,exit,output:11
572 in_port=2 actions=output:12,resubmit:1,output:12
573 in_port=3 actions=output:13,resubmit:2,output:14
574 ])
575 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
576 AT_CHECK([ovs-appctl ofproto/trace br0 '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=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)'], [0], [stdout])
577 AT_CHECK([tail -1 stdout], [0],
578   [Datapath actions: 10
579 ])
580 AT_CHECK([ovs-appctl ofproto/trace br0 'in_port(2),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=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)'], [0], [stdout])
581 AT_CHECK([tail -1 stdout], [0],
582   [Datapath actions: 12,10
583 ])
584 AT_CHECK([ovs-appctl ofproto/trace br0 'in_port(3),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=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)'], [0], [stdout])
585 AT_CHECK([tail -1 stdout], [0],
586   [Datapath actions: 13,12,10
587 ])
588 OVS_VSWITCHD_STOP
589 AT_CLEANUP
590
591
592 AT_SETUP([ofproto-dpif - mirroring, select_all])
593 OVS_VSWITCHD_START(
594        [add-port br0 p1 -- set Interface p1 type=dummy --\
595         add-port br0 p2 -- set Interface p2 type=dummy --\
596         add-port br0 p3 -- set Interface p3 type=dummy --\
597         set Bridge br0 mirrors=@m --\
598         --id=@p3 get Port p3 --\
599         --id=@m create Mirror name=mymirror \
600         select_all=true output_port=@p3], [<0>
601 ])
602
603 AT_DATA([flows.txt], [dnl
604 in_port=1 actions=output:2
605 in_port=2 actions=output:1
606 ])
607 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
608
609 flow="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=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)"
610 AT_CHECK([ovs-appctl ofproto/trace br0 "$flow"], [0], [stdout])
611 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
612   [Datapath actions: 2,3
613 ])
614
615 flow="in_port(2),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=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)"
616 AT_CHECK([ovs-appctl ofproto/trace br0 "$flow"], [0], [stdout])
617 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
618   [Datapath actions: 1,3
619 ])
620
621 OVS_VSWITCHD_STOP
622 AT_CLEANUP
623
624
625 AT_SETUP([ofproto-dpif - mirroring, select_src])
626 OVS_VSWITCHD_START(
627        [add-port br0 p1 -- set Interface p1 type=dummy --\
628         add-port br0 p2 -- set Interface p2 type=dummy --\
629         add-port br0 p3 -- set Interface p3 type=dummy --\
630         set Bridge br0 mirrors=@m --\
631         --id=@p1 get Port p1 -- --id=@p3 get Port p3 --\
632         --id=@m create Mirror name=mymirror \
633         select_src_port=@p1 output_port=@p3], [<0>
634 ])
635
636 AT_DATA([flows.txt], [dnl
637 in_port=1 actions=output:2
638 in_port=2 actions=output:1
639 ])
640 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
641
642 flow="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=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)"
643 AT_CHECK([ovs-appctl ofproto/trace br0 "$flow"], [0], [stdout])
644 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
645   [Datapath actions: 2,3
646 ])
647
648 flow="in_port(2),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=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)"
649 AT_CHECK([ovs-appctl ofproto/trace br0 "$flow"], [0], [stdout])
650 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
651   [Datapath actions: 1
652 ])
653 OVS_VSWITCHD_STOP
654 AT_CLEANUP
655
656 AT_SETUP([ofproto-dpif - mirroring, OFPP_NONE ingress port])
657 OVS_VSWITCHD_START(
658        [add-port br0 p1 -- set Interface p1 type=dummy --\
659         add-port br0 p2 -- set Interface p2 type=dummy --\
660         set Bridge br0 mirrors=@m --\
661         --id=@p2 get Port p2 --\
662         --id=@m create Mirror name=mymirror \
663         select_all=true output_port=@p2], [<0>
664 ])
665
666 AT_CHECK([ovs-ofctl add-flow br0 action=output:1])
667
668 # "in_port" defaults to OFPP_NONE if it's not specified.
669 flow="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=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)"
670 AT_CHECK([ovs-appctl ofproto/trace br0 "$flow"], [0], [stdout])
671 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
672   [Datapath actions: 1,2
673 ])
674
675 OVS_VSWITCHD_STOP
676 AT_CLEANUP
677
678
679 AT_SETUP([ofproto-dpif - mirroring, select_dst])
680 OVS_VSWITCHD_START(
681        [add-port br0 p1 -- set Interface p1 type=dummy --\
682         add-port br0 p2 -- set Interface p2 type=dummy --\
683         add-port br0 p3 -- set Interface p3 type=dummy --\
684         set Bridge br0 mirrors=@m --\
685         --id=@p2 get Port p2 -- --id=@p3 get Port p3 --\
686         --id=@m create Mirror name=mymirror \
687         select_dst_port=@p2 output_port=@p3], [<0>
688 ])
689
690 AT_DATA([flows.txt], [dnl
691 in_port=1 actions=output:2
692 in_port=2 actions=output:1
693 ])
694 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
695
696 flow="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=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)"
697 AT_CHECK([ovs-appctl ofproto/trace br0 "$flow"], [0], [stdout])
698 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
699   [Datapath actions: 2,3
700 ])
701
702 flow="in_port(2),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=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)"
703 AT_CHECK([ovs-appctl ofproto/trace br0 "$flow"], [0], [stdout])
704 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
705   [Datapath actions: 1
706 ])
707
708 OVS_VSWITCHD_STOP
709 AT_CLEANUP
710
711
712 AT_SETUP([ofproto-dpif - mirroring, select_vlan])
713 OVS_VSWITCHD_START(
714        [add-port br0 p1 -- set Interface p1 type=dummy --\
715         add-port br0 p2 -- set Interface p2 type=dummy --\
716         add-port br0 p3 -- set Interface p3 type=dummy --\
717         set Bridge br0 mirrors=@m --\
718         --id=@p2 get Port p2 -- --id=@p3 get Port p3 --\
719         --id=@m create Mirror name=mymirror \
720         select_all=true select_vlan=11 output_port=@p3], [<0>
721 ])
722
723 AT_DATA([flows.txt], [dnl
724 in_port=1, actions=output:2
725 ])
726 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
727
728 flow="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=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)"
729 AT_CHECK([ovs-appctl ofproto/trace br0 "$flow"], [0], [stdout])
730 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
731   [Datapath actions: 2
732 ])
733
734 flow="in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x8100),vlan(vid=10,pcp=0),encap(eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0))"
735 AT_CHECK([ovs-appctl ofproto/trace br0 "$flow"], [0], [stdout])
736 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
737   [Datapath actions: 2
738 ])
739
740 flow="in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x8100),vlan(vid=11,pcp=0),encap(eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0))"
741 AT_CHECK([ovs-appctl ofproto/trace br0 "$flow"], [0], [stdout])
742 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
743   [Datapath actions: 2,3
744 ])
745
746 OVS_VSWITCHD_STOP
747 AT_CLEANUP
748
749
750 AT_SETUP([ofproto-dpif - mirroring, output_port])
751 OVS_VSWITCHD_START(
752        [add-port br0 p1 -- set Interface p1 type=dummy --\
753         add-port br0 p2 -- set Interface p2 type=dummy --\
754         add-port br0 p3 -- set Interface p3 type=dummy --\
755         set Bridge br0 mirrors=@m --\
756         --id=@p3 get Port p3 --\
757         --id=@m create Mirror name=mymirror \
758         select_all=true output_port=@p3], [<0>
759 ])
760
761 AT_DATA([flows.txt], [dnl
762 in_port=1 actions=mod_vlan_vid:17,output:2
763 in_port=2 actions=output:1
764 ])
765 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
766
767 flow="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=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)"
768 AT_CHECK([ovs-appctl ofproto/trace br0 "$flow"], [0], [stdout])
769 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
770   [Datapath actions: push_vlan(vid=17,pcp=0),2,pop_vlan,3
771 ])
772
773 flow="in_port(2),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=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)"
774 AT_CHECK([ovs-appctl ofproto/trace br0 "$flow"], [0], [stdout])
775 AT_CHECK_UNQUOTED([tail -1 stdout], [0],
776   [Datapath actions: 1,3
777 ])
778
779 OVS_VSWITCHD_STOP
780 AT_CLEANUP
781
782 AT_SETUP([ofproto-dpif - mirroring, output_vlan])
783 OVS_VSWITCHD_START(
784        [add-port br0 p1 -- set Interface p1 type=dummy --\
785         add-port br0 p2 -- set Interface p2 type=dummy --\
786         set Bridge br0 mirrors=@m --\
787         --id=@m create Mirror name=mymirror \
788         select_all=true output_vlan=12], [<0>
789 ])
790
791 AT_DATA([flows.txt], [dnl
792 in_port=1 actions=output:2
793 in_port=2 actions=mod_vlan_vid:17,output:1
794 ])
795 AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
796
797 flow="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=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)"
798 AT_CHECK([ovs-appctl ofproto/trace br0 "$flow"], [0], [stdout])
799 actual=`tail -1 stdout | sed 's/Datapath actions: //'`
800
801 expected="2,push_vlan(vid=12,pcp=0),0,1,2"
802 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
803 mv stdout expout
804 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
805
806 flow="in_port(2),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=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)"
807 AT_CHECK([ovs-appctl ofproto/trace br0 "$flow"], [0], [stdout])
808 actual=`tail -1 stdout | sed 's/Datapath actions: //'`
809
810 expected="push_vlan(vid=17,pcp=0),1,pop_vlan,push_vlan(vid=12,pcp=0),0,1,2"
811 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected"], [0], [stdout])
812 mv stdout expout
813 AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual"], [0], [expout])
814
815 OVS_VSWITCHD_STOP
816 AT_CLEANUP
817
818 m4_define([OFPROTO_TRACE],
819   [flow="$2"
820    AT_CHECK([ovs-appctl ofproto/trace $1 "$flow" $3], [0], [stdout])
821    actual=`tail -1 stdout | sed 's/Datapath actions: //'`
822    expected="$4"
823    AT_CHECK([ovs-dpctl normalize-actions "$flow" "$expected" $5],
824      [0], [stdout])
825    mv stdout expout
826    AT_CHECK([ovs-dpctl normalize-actions "$flow" "$actual" $5],
827      [0], [expout])])
828
829 AT_SETUP([ofproto-dpif - MAC learning])
830 OVS_VSWITCHD_START(
831   [set bridge br0 fail-mode=standalone -- \
832    add-port br0 p1 -- set Interface p1 type=dummy -- \
833    add-port br0 p2 -- set Interface p2 type=dummy -- \
834    add-port br0 p3 -- set Interface p3 type=dummy])
835
836 arp='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)'
837
838 # Trace an ARP packet arriving on p3, to create a MAC learning entry.
839 OFPROTO_TRACE(
840   [br0],
841   [in_port(3),eth(src=50:54:00:00:00:05,dst=ff:ff:ff:ff:ff:ff),$arp],
842   [-generate],
843   [0,1,2])
844
845 # Check for the MAC learning entry.
846 AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/[[0-9]]$/?/'], [0], [dnl
847  port  VLAN  MAC                Age
848     3     0  50:54:00:00:00:05    ?
849 ])
850
851 # Trace a packet arrival destined for the learned MAC.
852 # (This will also learn a MAC.)
853 OFPROTO_TRACE(
854   [br0],
855   [in_port(1),eth(src=50:54:00:00:00:06,dst=50:54:00:00:00:05),$arp],
856   [-generate],
857   [3])
858
859 # Check for both MAC learning entries.
860 AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/[[0-9]]$/?/'], [0], [dnl
861  port  VLAN  MAC                Age
862     3     0  50:54:00:00:00:05    ?
863     1     0  50:54:00:00:00:06    ?
864 ])
865
866 # Trace a packet arrival that updates the first learned MAC entry.
867 OFPROTO_TRACE(
868   [br0],
869   [in_port(2),eth(src=50:54:00:00:00:05,dst=ff:ff:ff:ff:ff:ff),$arp],
870   [-generate],
871   [0,1,3])
872
873 # Check that the MAC learning entry was updated.
874 AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/[[0-9]]$/?/'], [0], [dnl
875  port  VLAN  MAC                Age
876     1     0  50:54:00:00:00:06    ?
877     2     0  50:54:00:00:00:05    ?
878 ])
879
880 # Add another bridge.
881 AT_CHECK(
882   [ovs-vsctl \
883      -- add-br br1 \
884      -- set bridge br1 datapath-type=dummy \
885      -- add-port br1 p4 -- set interface p4 type=dummy \
886      -- add-port br1 p5 -- set interface p5 type=dummy])
887
888 # Trace some packet arrivals in br1 to create MAC learning entries there too.
889 OFPROTO_TRACE(
890   [br1],
891   [in_port(4),eth(src=50:54:00:00:00:06,dst=ff:ff:ff:ff:ff:ff),$arp],
892   [-generate],
893   [0,5])
894 OFPROTO_TRACE(
895   [br1],
896   [in_port(5),eth(src=50:54:00:00:00:07,dst=ff:ff:ff:ff:ff:ff),$arp],
897   [-generate],
898   [0,4])
899
900 # Check that the MAC learning entries were added.
901 AT_CHECK_UNQUOTED([ovs-appctl fdb/show br1 | sed 's/[[0-9]]$/?/'], [0], [dnl
902  port  VLAN  MAC                Age
903     4     0  50:54:00:00:00:06    ?
904     5     0  50:54:00:00:00:07    ?
905 ])
906
907 # Delete port p1 and see that its MAC learning entry disappeared, and
908 # that the MAC learning entry for the same MAC was also deleted from br1.
909 AT_CHECK([ovs-vsctl del-port p1])
910 AT_CHECK_UNQUOTED([ovs-appctl fdb/show br0 | sed 's/[[0-9]]$/?/'], [0], [dnl
911  port  VLAN  MAC                Age
912     2     0  50:54:00:00:00:05    ?
913 ])
914 AT_CHECK_UNQUOTED([ovs-appctl fdb/show br1 | sed 's/[[0-9]]$/?/'], [0], [dnl
915  port  VLAN  MAC                Age
916     5     0  50:54:00:00:00:07    ?
917 ])
918
919 OVS_VSWITCHD_STOP
920 AT_CLEANUP
921
922 dnl Test that basic NetFlow reports flow statistics correctly:
923 dnl - The initial packet of a flow are correctly accounted.
924 dnl - Later packets within a flow are correctly accounted.
925 dnl - Flow actions changing (in this case, due to MAC learning)
926 dnl   cause a record to be sent.
927 AT_SETUP([ofproto-dpif - NetFlow flow expiration])
928
929 AT_CHECK([perl $srcdir/choose-port.pl], [0], [stdout])
930 NETFLOW_PORT=`cat stdout`
931
932 OVS_VSWITCHD_START(
933   [set Bridge br0 fail-mode=standalone -- \
934    add-port br0 p1 -- set Interface p1 type=dummy -- \
935    add-port br0 p2 -- set Interface p2 type=dummy -- \
936    set Bridge br0 netflow=@nf -- \
937    --id=@nf create NetFlow targets=\"127.0.0.1:$NETFLOW_PORT\" \
938      engine_id=1 engine_type=2 active_timeout=30 \
939      add-id-to-interface=false], [<0>
940 ])
941
942 AT_CHECK([test-netflow --detach --pidfile $NETFLOW_PORT:127.0.0.1 > netflow.log])AT_CAPTURE_FILE([netflow.log])
943
944 for delay in 1000 30000; do
945     ovs-appctl netdev-dummy/receive p1 'in_port(2),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=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'
946     ovs-appctl netdev-dummy/receive p2 'in_port(1),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)'
947
948     ovs-appctl time/warp $delay
949 done
950
951 OVS_VSWITCHD_STOP
952 ovs-appctl -t test-netflow exit
953
954 AT_CHECK([[sed -e 's/, uptime [0-9]*//
955 s/, now [0-9.]*//
956 s/time \([0-9]*\)\.\.\.\1\b/time <moment>/
957 s/time [0-9]*\.\.\.[0-9]*/time <range>/
958 ' netflow.log]], [0],
959   [header: v5, seq 0, engine 2,1
960 rec: 192.168.0.1 > 192.168.0.2, if 1 > 65535, 1 pkts, 60 bytes, ICMP 8:0, time <moment>
961
962 header: v5, seq 1, engine 2,1
963 rec: 192.168.0.2 > 192.168.0.1, if 2 > 1, 2 pkts, 120 bytes, ICMP 0:0, time <range>
964 rec: 192.168.0.1 > 192.168.0.2, if 1 > 2, 1 pkts, 60 bytes, ICMP 8:0, time <moment>
965 ])
966 AT_CLEANUP
967
968 dnl Test that basic NetFlow reports active expirations correctly.
969 AT_SETUP([ofproto-dpif - NetFlow active expiration])
970
971 AT_CHECK([perl $srcdir/choose-port.pl], [0], [stdout])
972 NETFLOW_PORT=`cat stdout`
973
974 OVS_VSWITCHD_START(
975   [set Bridge br0 fail-mode=standalone -- \
976    add-port br0 p1 -- set Interface p1 type=dummy -- \
977    add-port br0 p2 -- set Interface p2 type=dummy -- \
978    set Bridge br0 netflow=@nf -- \
979    --id=@nf create NetFlow targets=\"127.0.0.1:$NETFLOW_PORT\" \
980      engine_id=1 engine_type=2 active_timeout=10 \
981      add-id-to-interface=false], [<0>
982 ])
983
984 AT_CHECK([test-netflow --detach --pidfile $NETFLOW_PORT:127.0.0.1 > netflow.log])AT_CAPTURE_FILE([netflow.log])
985
986 n=1
987 while test $n -le 60; do
988     n=`expr $n + 1`
989
990     ovs-appctl netdev-dummy/receive p1 'in_port(2),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=1234,dst=80)'
991     ovs-appctl netdev-dummy/receive p2 'in_port(1),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=6,tos=0,ttl=64,frag=no),tcp(src=80,dst=1234)'
992
993     ovs-appctl time/warp 1000
994 done
995
996 ovs-appctl time/warp 10000
997
998 OVS_VSWITCHD_STOP
999 ovs-appctl -t test-netflow exit
1000
1001 # Count the number of reported packets:
1002 # - From source to destination before MAC learning kicks in (just one).
1003 # - From source to destination after that.
1004 # - From destination to source.
1005 n_learn=0
1006 n_in=0
1007 n_out=0
1008 n_other=0
1009 n_recs=0
1010 none=0
1011 while read line; do
1012     pkts=`echo "$line" | sed 's/.*, \([[0-9]]*\) pkts,.*/\1/'`
1013     case $pkts in
1014          [[0-9]]*) ;;
1015          *) continue ;;
1016     esac
1017
1018     case $line in
1019         "rec: 192.168.0.1 > 192.168.0.2, if 1 > 65535, "*" pkts, "*" bytes, TCP 1234 > 80, time "*)
1020             counter=n_learn
1021             ;;
1022         "rec: 192.168.0.1 > 192.168.0.2, if 1 > 2, "*" pkts, "*" bytes, TCP 1234 > 80, time "*)
1023             counter=n_in
1024             ;;
1025         "rec: 192.168.0.2 > 192.168.0.1, if 2 > 1, "*" pkts, "*" bytes, TCP 80 > 1234, time "*)
1026             counter=n_out
1027             ;;
1028         *)
1029             counter=n_other
1030             ;;
1031     esac
1032     eval $counter=\`expr \$$counter + \$pkts\`
1033     n_recs=`expr $n_recs + 1`
1034 done < netflow.log
1035
1036 # There should be exactly 1 MAC learning packet,
1037 # exactly 59 other packets in that direction,
1038 # and exactly 60 packets in the other direction.
1039 AT_CHECK([echo $n_learn $n_in $n_out $n_other], [0], [1 59 60 0
1040 ])
1041
1042 # There should be 1 expiration for MAC learning,
1043 # at least 5 active and a final expiration in one direction,
1044 # and at least 5 active and a final expiration in the other direction.
1045 echo $n_recs
1046 AT_CHECK([test $n_recs -ge 13])
1047
1048 AT_CLEANUP
1049
1050 AT_SETUP([idle_age and hard_age increase over time])
1051 OVS_VSWITCHD_START
1052
1053 # get_ages DURATION HARD IDLE
1054 #
1055 # Fetch the flow duration, hard age, and idle age into the variables
1056 # whose names are given as arguments.  Rounds DURATION down to the
1057 # nearest integer.  If hard_age doesn't appear in the output, sets
1058 # HARD to "none".  If idle_age doesn't appear in the output, sets IDLE
1059 # to 0.
1060 get_ages () {
1061     AT_CHECK([ovs-ofctl dump-flows br0], [0], [stdout])
1062
1063     duration=`sed -n 's/.*duration=\([[0-9]]*\)\(\.[[0-9]]*\)\{0,1\}s.*/\1/p' stdout`
1064     AT_CHECK([[expr X"$duration" : 'X[0-9][0-9]*$']], [0], [ignore])
1065     AS_VAR_COPY([$1], [duration])
1066
1067     hard=`sed -n 's/.*hard_age=\([[0-9]]*\),.*/\1/p' stdout`
1068     if test X"$hard" = X; then
1069         hard=none
1070     else
1071         AT_CHECK([[expr X"$hard" : 'X[0-9][0-9]*$']], [0], [ignore])
1072     fi
1073     AS_VAR_COPY([$2], [hard])
1074
1075     idle=`sed -n 's/.*idle_age=\([[0-9]]*\),.*/\1/p' stdout`
1076     if test X"$idle" = X; then
1077         idle=0
1078     else
1079         AT_CHECK([[expr X"$idle" : 'X[0-9][0-9]*$']], [0], [ignore])
1080     fi
1081     AS_VAR_COPY([$3], [idle])
1082 }
1083
1084 # Add a flow and get its initial hard and idle age.
1085 AT_CHECK([ovs-ofctl add-flow br0 hard_timeout=199,idle_timeout=188,actions=drop])
1086 get_ages duration1 hard1 idle1
1087
1088 # Warp time forward by 10 seconds, then modify the flow's actions.
1089 ovs-appctl time/warp 10000
1090 get_ages duration2 hard2 idle2
1091 AT_CHECK([ovs-ofctl mod-flows br0 actions=flood])
1092
1093 # Warp time forward by 10 seconds.
1094 ovs-appctl time/warp 10000
1095 get_ages duration3 hard3 idle3
1096
1097 # Warp time forward 10 more seconds, then pass some packets through the flow,
1098 # then warp forward a few more times because idle times are only updated
1099 # occasionally.
1100 ovs-appctl time/warp 10000
1101 ovs-appctl netdev-dummy/receive br0 'in_port(0),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=6,tos=0,ttl=64,frag=no),tcp(src=80,dst=1234)'
1102 ovs-appctl time/warp 1000
1103 ovs-appctl time/warp 1000
1104 ovs-appctl time/warp 1000
1105 get_ages duration4 hard4 idle4
1106
1107 printf "duration: %4s => %4s => %4s => %4s\n" $duration1 $duration2 $duration3 $duration4
1108 printf "hard_age: %4s => %4s => %4s => %4s\n" $hard1 $hard2 $hard3 $hard4
1109 printf "idle_age: %4s => %4s => %4s => %4s\n" $idle1 $idle2 $idle3 $idle4
1110
1111 # Duration should increase steadily over time.
1112 AT_CHECK([test $duration1 -lt $duration2])
1113 AT_CHECK([test $duration2 -lt $duration3])
1114 AT_CHECK([test $duration3 -lt $duration4])
1115
1116 # Hard age should be "none" initially because it's the same as flow_duration,
1117 # then it should increase.
1118 AT_CHECK([test $hard1 = none])
1119 AT_CHECK([test $hard2 = none])
1120 AT_CHECK([test $hard3 != none])
1121 AT_CHECK([test $hard4 != none])
1122 AT_CHECK([test $hard3 -lt $hard4])
1123
1124 # Idle age should increase from 1 to 2 to 3, then decrease.
1125 AT_CHECK([test $idle1 -lt $idle2])
1126 AT_CHECK([test $idle2 -lt $idle3])
1127 AT_CHECK([test $idle3 -gt $idle4])
1128
1129 # Check some invariant relationships.
1130 AT_CHECK([test $duration1 = $idle1])
1131 AT_CHECK([test $duration2 = $idle2])
1132 AT_CHECK([test $duration3 = $idle3])
1133 AT_CHECK([test $idle3 -gt $hard3])
1134 AT_CHECK([test $idle4 -lt $hard4])
1135 AT_CHECK([test $hard4 -lt $duration4])
1136
1137 OVS_VSWITCHD_STOP
1138 AT_CLEANUP