blob: fc9773af0dde83a04b2c2e33a00ae755bdae192e [file] [log] [blame]
macauley97557232015-07-16 17:28:07 +08001import logging
2
3from oftest import config
4import oftest.base_tests as base_tests
5import ofp
6import time
7from oftest.testutils import *
8
9OFDPA_GROUP_TYPE_SHIFT=28
10OFDPA_VLAN_ID_SHIFT =16
11OFDPA_TUNNEL_ID_SHIFT =16
12
13#VLAN_TABLE_FLAGS
14VLAN_TABLE_FLAG_ONLY_UNTAG=1
15VLAN_TABLE_FLAG_ONLY_TAG =2
16VLAN_TABLE_FLAG_ONLY_BOTH =3
17
18def encode_l2_interface_group_id(vlan, id):
19 return id + (vlan << OFDPA_VLAN_ID_SHIFT)
20
21def encode_l2_rewrite_group_id(id):
22 return id + (1 << OFDPA_GROUP_TYPE_SHIFT)
23
24def encode_l3_unicast_group_id(id):
25 return id + (2 << OFDPA_GROUP_TYPE_SHIFT)
26
27def encode_l2_mcast_group_id(vlan, id):
28 return id + (vlan << OFDPA_VLAN_ID_SHIFT) + (3 << OFDPA_GROUP_TYPE_SHIFT)
29
30def encode_l2_flood_group_id(vlan, id):
31 return id + (vlan << OFDPA_VLAN_ID_SHIFT) + (4 << OFDPA_GROUP_TYPE_SHIFT)
32
33def encode_l3_interface_group_id(id):
34 return id + (5 << OFDPA_GROUP_TYPE_SHIFT)
35
36def encode_l3_mcast_group_id(vlan, id):
37 return id + (vlan << OFDPA_VLAN_ID_SHIFT)+(6 << OFDPA_GROUP_TYPE_SHIFT)
38
39def encode_l3_ecmp_group_id(id):
40 return id + (7 << OFDPA_GROUP_TYPE_SHIFT)
41
42def encode_l2_overlay_flood_group_id(tunnel_id, index):
43 return id + (tunnel_id << OFDPA_TUNNEL_ID_SHIFT)+(8 << OFDPA_GROUP_TYPE_SHIFT)
44
45def encode_l2_overlay_mcast_group_id(tunnel_id, index):
46 return id + (tunnel_id << OFDPA_TUNNEL_ID_SHIFT)+(9 << OFDPA_GROUP_TYPE_SHIFT)
macauley97557232015-07-16 17:28:07 +080047
48def add_l2_interface_grouop(ctrl, ports, vlan_id=1, is_tagged=False, send_barrier=False):
49 # group table
50 # set up untag groups for each port
macauley41904ed2015-07-16 17:38:35 +080051 group_id_list=[]
macauley15909e72015-07-17 15:58:57 +080052 msgs=[]
macauley97557232015-07-16 17:28:07 +080053 for of_port in ports:
54 # do stuff
55 group_id = encode_l2_interface_group_id(vlan_id, of_port)
macauley41904ed2015-07-16 17:38:35 +080056 group_id_list.append(group_id)
macauley97557232015-07-16 17:28:07 +080057 if is_tagged:
58 actions = [
59 ofp.action.output(of_port),
60 ]
61 else:
62 actions = [
63 ofp.action.pop_vlan(),
64 ofp.action.output(of_port),
65 ]
66
67 buckets = [
68 ofp.bucket(actions=actions),
69 ]
70
71 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
72 group_id=group_id,
73 buckets=buckets
74 )
75 ctrl.message_send(request)
macauley15909e72015-07-17 15:58:57 +080076 msgs.append(request)
macauley97557232015-07-16 17:28:07 +080077
78 if send_barrier:
79 do_barrier(ctrl)
macauley41904ed2015-07-16 17:38:35 +080080
macauley15909e72015-07-17 15:58:57 +080081 return group_id_list, msgs
macauley97557232015-07-16 17:28:07 +080082
macauley0f91a3e2015-07-17 18:09:59 +080083def add_one_l2_interface_grouop(ctrl, port, vlan_id=1, is_tagged=False, send_barrier=False):
84 # group table
85 # set up untag groups for each port
86 group_id = encode_l2_interface_group_id(vlan_id, port)
87
88 if is_tagged:
89 actions = [
90 ofp.action.output(port),
91 ]
92 else:
93 actions = [
94 ofp.action.pop_vlan(),
95 ofp.action.output(port),
96 ]
97
98 buckets = [
99 ofp.bucket(actions=actions),
100 ]
101
102 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
103 group_id=group_id,
104 buckets=buckets
105 )
106 ctrl.message_send(request)
107
108 if send_barrier:
109 do_barrier(ctrl)
110
111 return group_id, request
112
macauley97557232015-07-16 17:28:07 +0800113def add_l2_mcast_group(ctrl, ports, vlanid, mcast_grp_index):
114 buckets=[]
115 for of_port in ports:
116 group_id = encode_l2_interface_group_id(vlanid, of_port)
117 action=[ofp.action.group(group_id)]
118 buckets.append(ofp.bucket(actions=action))
119
120 group_id =encode_l2_mcast_group_id(vlanid, mcast_grp_index)
121 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
122 group_id=group_id,
123 buckets=buckets
124 )
125 ctrl.message_send(request)
macauley15909e72015-07-17 15:58:57 +0800126 return request
macauley97557232015-07-16 17:28:07 +0800127
macauley15909e72015-07-17 15:58:57 +0800128def add_l2_flood_group(ctrl, ports, vlanid, id):
129 buckets=[]
130 for of_port in ports:
131 group_id = encode_l2_interface_group_id(vlanid, of_port)
132 action=[ofp.action.group(group_id)]
133 buckets.append(ofp.bucket(actions=action))
macauley97557232015-07-16 17:28:07 +0800134
macauley15909e72015-07-17 15:58:57 +0800135 group_id =encode_l2_flood_group_id(vlanid, id)
136 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
137 group_id=group_id,
138 buckets=buckets
139 )
140 ctrl.message_send(request)
141 return request
142
143def add_l2_rewrite_group(ctrl, port, vlanid, id, src_mac, dst_mac):
144 group_id = encode_l2_interface_group_id(vlanid, port)
145
146 action=[]
147 if src_mac is not None:
148 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
149
150 if dst_mac is not None:
151 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
152
153 action.append(ofp.action.group(group_id))
154
155 buckets = [ofp.bucket(actions=action)]
156
157 group_id =encode_l2_rewrite_group_id(id)
158 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
159 group_id=group_id,
160 buckets=buckets
161 )
162 ctrl.message_send(request)
163 return request
164
165def add_l3_unicast_group(ctrl, port, vlanid, id, src_mac, dst_mac):
166 group_id = encode_l2_interface_group_id(vlanid, port)
167
168 action=[]
169 if src_mac is not None:
170 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
171
172 if dst_mac is not None:
173 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
174
175 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(vlanid)))
176
177 action.append(ofp.action.group(group_id))
178
179 buckets = [ofp.bucket(actions=action)]
180
181 group_id =encode_l3_unicast_group_id(id)
182 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
183 group_id=group_id,
184 buckets=buckets
185 )
186 ctrl.message_send(request)
187 return request
188
189def add_l3_interface_group(ctrl, port, vlanid, id, src_mac):
190 group_id = encode_l2_interface_group_id(vlanid, port)
191
192 action=[]
193 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
194 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(vlanid)))
195 action.append(ofp.action.group(group_id))
196
197 buckets = [ofp.bucket(actions=action)]
198
199 group_id =encode_l3_interface_group_id(id)
200 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
201 group_id=group_id,
202 buckets=buckets
203 )
204 ctrl.message_send(request)
205 return request
206
207def add_l3_ecmp_group(ctrl, id, l3_ucast_groups):
208 buckets=[]
209 for group in l3_ucast_groups:
210 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
211
212 group_id =encode_l3_ecmp_group_id(id)
213 request = ofp.message.group_add(group_type=ofp.OFPGT_SELECT,
214 group_id=group_id,
215 buckets=buckets
216 )
217 ctrl.message_send(request)
218 return request
219
220def add_l3_mcast_group(ctrl, vid, mcast_group_id, groups_on_buckets):
221 buckets=[]
222 for group in groups_on_buckets:
223 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
224
225 group_id =encode_l3_mcast_group_id(vid, mcast_group_id)
226 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
227 group_id=group_id,
228 buckets=buckets
229 )
230 ctrl.message_send(request)
231 return request
232
macauley97557232015-07-16 17:28:07 +0800233def add_vlan_table_flow(ctrl, ports, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
234 # table 10: vlan
235 # goto to table 20
macauley15909e72015-07-17 15:58:57 +0800236 msgs=[]
macauley97557232015-07-16 17:28:07 +0800237 for of_port in ports:
238 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
239 match = ofp.match()
240 match.oxm_list.append(ofp.oxm.in_port(of_port))
241 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
242 request = ofp.message.flow_add(
243 table_id=10,
244 cookie=42,
245 match=match,
246 instructions=[
247 ofp.instruction.goto_table(20)
248 ],
249 priority=0)
250 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
251 ctrl.message_send(request)
252
253 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
254 match = ofp.match()
255 match.oxm_list.append(ofp.oxm.in_port(of_port))
256 match.oxm_list.append(ofp.oxm.vlan_vid(0))
257 request = ofp.message.flow_add(
258 table_id=10,
259 cookie=42,
260 match=match,
261 instructions=[
262 ofp.instruction.apply_actions(
263 actions=[
264 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id))
265 ]
266 ),
267 ofp.instruction.goto_table(20)
268 ],
269 priority=0)
270 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
271 ctrl.message_send(request)
macauley15909e72015-07-17 15:58:57 +0800272 msgs.append(request)
macauley97557232015-07-16 17:28:07 +0800273
274 if send_barrier:
275 do_barrier(ctrl)
276
macauley15909e72015-07-17 15:58:57 +0800277 return msgs
macauley0f91a3e2015-07-17 18:09:59 +0800278
279def add_one_vlan_table_flow(ctrl, of_port, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
280 # table 10: vlan
281 # goto to table 20
282 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
283 match = ofp.match()
284 match.oxm_list.append(ofp.oxm.in_port(of_port))
285 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
286 request = ofp.message.flow_add(
287 table_id=10,
288 cookie=42,
289 match=match,
290 instructions=[
291 ofp.instruction.goto_table(20)
292 ],
293 priority=0)
294 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
295 ctrl.message_send(request)
296
297 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
298 match = ofp.match()
299 match.oxm_list.append(ofp.oxm.in_port(of_port))
300 match.oxm_list.append(ofp.oxm.vlan_vid(0))
301 request = ofp.message.flow_add(
302 table_id=10,
303 cookie=42,
304 match=match,
305 instructions=[
306 ofp.instruction.apply_actions(
307 actions=[
308 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id))
309 ]
310 ),
311 ofp.instruction.goto_table(20)
312 ],
313 priority=0)
314 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
315 ctrl.message_send(request)
316
317 if send_barrier:
318 do_barrier(ctrl)
319
320 return request
macauley15909e72015-07-17 15:58:57 +0800321
macauley97557232015-07-16 17:28:07 +0800322def add_bridge_flow(ctrl, dst_mac, vlanid, group_id, send_barrier=False):
323 match = ofp.match()
324 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
325 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
326 request = ofp.message.flow_add(
327 table_id=50,
328 cookie=42,
329 match=match,
330 instructions=[
331 ofp.instruction.write_actions(
332 actions=[
333 ofp.action.group(group_id)]),
334 ofp.instruction.goto_table(60)
335 ],
336 buffer_id=ofp.OFP_NO_BUFFER,
337 priority=1000)
338
339 logging.info("Inserting Brdige flow vlan %d, mac %s", vlanid, dst_mac)
340 ctrl.message_send(request)
341
342 if send_barrier:
macauley15909e72015-07-17 15:58:57 +0800343 do_barrier(ctrl)
344
macauley0f91a3e2015-07-17 18:09:59 +0800345 return request
346
347def add_termination_flow(ctrl, in_port, eth_type, dst_mac, vlanid, send_barrier=False):
348 match = ofp.match()
349 match.oxm_list.append(ofp.oxm.in_port(in_port))
350 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
351 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
352 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
353
354 if dst_mac[0]&0x01 == 0x01: #macast
355 goto_table=40
356 else:
357 goto_table=30
358
359 request = ofp.message.flow_add(
360 table_id=20,
361 cookie=42,
362 match=match,
363 instructions=[
364 ofp.instruction.goto_table(goto_table)
365 ],
366 buffer_id=ofp.OFP_NO_BUFFER,
367 priority=1)
368
369 logging.info("Inserting termination flow inport %d, eth_type %lx, vlan %d, mac %s", in_port, eth_type, vlanid, dst_mac)
370 ctrl.message_send(request)
371
372 if send_barrier:
373 do_barrier(ctrl)
374
375 return request
376
377def add_unicast_routing_flow(ctrl, eth_type, dst_ip, action_group_id, send_barrier=False):
378 match = ofp.match()
379 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
380 match.oxm_list.append(ofp.oxm.ipv4_dst(dst_ip))
381
382 request = ofp.message.flow_add(
383 table_id=30,
384 cookie=42,
385 match=match,
386 instructions=[
387 ofp.instruction.write_actions(
388 actions=[ofp.action.group(action_group_id)]),
389 ofp.instruction.goto_table(60)
390 ],
391 buffer_id=ofp.OFP_NO_BUFFER,
392 priority=1)
393
394 logging.info("Inserting unicast routing flow eth_type %lx, dip %ld",eth_type, dst_ip)
395 ctrl.message_send(request)
396
397 if send_barrier:
398 do_barrier(ctrl)
399
macauley15909e72015-07-17 15:58:57 +0800400 return request