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