blob: 187184980ba349d17df4528c35cde7ce8412b509 [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
macauleyfddc4662015-07-27 17:40:30 +08009from ncclient import manager
10import ncclient
11
macauley97557232015-07-16 17:28:07 +080012OFDPA_GROUP_TYPE_SHIFT=28
13OFDPA_VLAN_ID_SHIFT =16
macauleyfddc4662015-07-27 17:40:30 +080014OFDPA_TUNNEL_ID_SHIFT =12
15OFDPA_TUNNEL_SUBTYPE_SHIFT=10
macauley97557232015-07-16 17:28:07 +080016
17#VLAN_TABLE_FLAGS
18VLAN_TABLE_FLAG_ONLY_UNTAG=1
19VLAN_TABLE_FLAG_ONLY_TAG =2
20VLAN_TABLE_FLAG_ONLY_BOTH =3
21
macauleye8b140e2015-08-03 13:35:45 +080022PORT_FLOW_TABLE=0
23VLAN_FLOW_TABLE=10
24TERMINATION_FLOW_TABLE=20
25UCAST_ROUTING_FLOW_TABLE=30
26MCAST_ROUTING_FLOW_TABLE=40
27BRIDGE_FLOW_TABLE=50
28ACL_FLOW_TABLE=60
29
30def convertIP4toStr(ip_addr):
31 a=(ip_addr&0xff000000)>>24
32 b=(ip_addr&0x00ff0000)>>16
33 c=(ip_addr&0x0000ff00)>>8
34 d=(ip_addr&0x000000ff)
35 return str(a)+"."+str(b)+"."+str(c)+"."+str(d)
36
37def convertMACtoStr(mac):
38 if not isinstance(mac, list):
39 assert(0)
40
41 return ':'.join(['%02X' % x for x in mac])
42
43
macauley97557232015-07-16 17:28:07 +080044def encode_l2_interface_group_id(vlan, id):
45 return id + (vlan << OFDPA_VLAN_ID_SHIFT)
46
47def encode_l2_rewrite_group_id(id):
48 return id + (1 << OFDPA_GROUP_TYPE_SHIFT)
49
50def encode_l3_unicast_group_id(id):
51 return id + (2 << OFDPA_GROUP_TYPE_SHIFT)
52
53def encode_l2_mcast_group_id(vlan, id):
54 return id + (vlan << OFDPA_VLAN_ID_SHIFT) + (3 << OFDPA_GROUP_TYPE_SHIFT)
55
56def encode_l2_flood_group_id(vlan, id):
57 return id + (vlan << OFDPA_VLAN_ID_SHIFT) + (4 << OFDPA_GROUP_TYPE_SHIFT)
58
59def encode_l3_interface_group_id(id):
60 return id + (5 << OFDPA_GROUP_TYPE_SHIFT)
61
62def encode_l3_mcast_group_id(vlan, id):
63 return id + (vlan << OFDPA_VLAN_ID_SHIFT)+(6 << OFDPA_GROUP_TYPE_SHIFT)
64
65def encode_l3_ecmp_group_id(id):
66 return id + (7 << OFDPA_GROUP_TYPE_SHIFT)
67
macauleyfddc4662015-07-27 17:40:30 +080068def encode_l2_overlay_group_id(tunnel_id, subtype, index):
69 tunnel_id=tunnel_id&0xffff #16 bits
70 subtype = subtype&3 #2 bits
71 index = index & 0x3f #10 bits
72 return index + (tunnel_id << OFDPA_TUNNEL_ID_SHIFT)+ (subtype<<OFDPA_TUNNEL_SUBTYPE_SHIFT)+(8 << OFDPA_GROUP_TYPE_SHIFT)
macauley97557232015-07-16 17:28:07 +080073
macauley97557232015-07-16 17:28:07 +080074def add_l2_interface_grouop(ctrl, ports, vlan_id=1, is_tagged=False, send_barrier=False):
75 # group table
76 # set up untag groups for each port
macauley41904ed2015-07-16 17:38:35 +080077 group_id_list=[]
macauley15909e72015-07-17 15:58:57 +080078 msgs=[]
macauley97557232015-07-16 17:28:07 +080079 for of_port in ports:
80 # do stuff
81 group_id = encode_l2_interface_group_id(vlan_id, of_port)
macauley41904ed2015-07-16 17:38:35 +080082 group_id_list.append(group_id)
macauley97557232015-07-16 17:28:07 +080083 if is_tagged:
84 actions = [
85 ofp.action.output(of_port),
86 ]
87 else:
88 actions = [
89 ofp.action.pop_vlan(),
90 ofp.action.output(of_port),
91 ]
92
93 buckets = [
94 ofp.bucket(actions=actions),
95 ]
96
97 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
98 group_id=group_id,
99 buckets=buckets
100 )
101 ctrl.message_send(request)
macauley15909e72015-07-17 15:58:57 +0800102 msgs.append(request)
macauley97557232015-07-16 17:28:07 +0800103
104 if send_barrier:
105 do_barrier(ctrl)
macauley41904ed2015-07-16 17:38:35 +0800106
macauley15909e72015-07-17 15:58:57 +0800107 return group_id_list, msgs
macauley97557232015-07-16 17:28:07 +0800108
macauley0f91a3e2015-07-17 18:09:59 +0800109def add_one_l2_interface_grouop(ctrl, port, vlan_id=1, is_tagged=False, send_barrier=False):
110 # group table
111 # set up untag groups for each port
112 group_id = encode_l2_interface_group_id(vlan_id, port)
113
114 if is_tagged:
115 actions = [
116 ofp.action.output(port),
117 ]
118 else:
119 actions = [
120 ofp.action.pop_vlan(),
121 ofp.action.output(port),
122 ]
123
124 buckets = [
125 ofp.bucket(actions=actions),
126 ]
127
128 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
129 group_id=group_id,
130 buckets=buckets
131 )
132 ctrl.message_send(request)
133
134 if send_barrier:
135 do_barrier(ctrl)
136
137 return group_id, request
138
macauley97557232015-07-16 17:28:07 +0800139def add_l2_mcast_group(ctrl, ports, vlanid, mcast_grp_index):
140 buckets=[]
141 for of_port in ports:
142 group_id = encode_l2_interface_group_id(vlanid, of_port)
143 action=[ofp.action.group(group_id)]
144 buckets.append(ofp.bucket(actions=action))
145
146 group_id =encode_l2_mcast_group_id(vlanid, mcast_grp_index)
147 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
148 group_id=group_id,
149 buckets=buckets
150 )
151 ctrl.message_send(request)
macauley15909e72015-07-17 15:58:57 +0800152 return request
macauley97557232015-07-16 17:28:07 +0800153
macauley15909e72015-07-17 15:58:57 +0800154def add_l2_flood_group(ctrl, ports, vlanid, id):
155 buckets=[]
156 for of_port in ports:
157 group_id = encode_l2_interface_group_id(vlanid, of_port)
158 action=[ofp.action.group(group_id)]
159 buckets.append(ofp.bucket(actions=action))
macauley97557232015-07-16 17:28:07 +0800160
macauley15909e72015-07-17 15:58:57 +0800161 group_id =encode_l2_flood_group_id(vlanid, id)
162 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
163 group_id=group_id,
164 buckets=buckets
165 )
166 ctrl.message_send(request)
167 return request
168
169def add_l2_rewrite_group(ctrl, port, vlanid, id, src_mac, dst_mac):
170 group_id = encode_l2_interface_group_id(vlanid, port)
171
172 action=[]
173 if src_mac is not None:
174 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
175
176 if dst_mac is not None:
177 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
178
179 action.append(ofp.action.group(group_id))
180
181 buckets = [ofp.bucket(actions=action)]
182
183 group_id =encode_l2_rewrite_group_id(id)
184 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
185 group_id=group_id,
186 buckets=buckets
187 )
188 ctrl.message_send(request)
189 return request
190
191def add_l3_unicast_group(ctrl, port, vlanid, id, src_mac, dst_mac):
192 group_id = encode_l2_interface_group_id(vlanid, port)
193
194 action=[]
195 if src_mac is not None:
196 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
197
198 if dst_mac is not None:
199 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
200
201 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(vlanid)))
202
203 action.append(ofp.action.group(group_id))
204
205 buckets = [ofp.bucket(actions=action)]
206
207 group_id =encode_l3_unicast_group_id(id)
208 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
209 group_id=group_id,
210 buckets=buckets
211 )
212 ctrl.message_send(request)
213 return request
214
215def add_l3_interface_group(ctrl, port, vlanid, id, src_mac):
216 group_id = encode_l2_interface_group_id(vlanid, port)
217
218 action=[]
219 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
220 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(vlanid)))
221 action.append(ofp.action.group(group_id))
222
223 buckets = [ofp.bucket(actions=action)]
224
225 group_id =encode_l3_interface_group_id(id)
226 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
227 group_id=group_id,
228 buckets=buckets
229 )
230 ctrl.message_send(request)
231 return request
232
233def add_l3_ecmp_group(ctrl, id, l3_ucast_groups):
234 buckets=[]
235 for group in l3_ucast_groups:
236 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
237
238 group_id =encode_l3_ecmp_group_id(id)
239 request = ofp.message.group_add(group_type=ofp.OFPGT_SELECT,
240 group_id=group_id,
241 buckets=buckets
242 )
243 ctrl.message_send(request)
244 return request
245
246def add_l3_mcast_group(ctrl, vid, mcast_group_id, groups_on_buckets):
247 buckets=[]
248 for group in groups_on_buckets:
249 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
250
251 group_id =encode_l3_mcast_group_id(vid, mcast_group_id)
252 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
253 group_id=group_id,
254 buckets=buckets
255 )
256 ctrl.message_send(request)
257 return request
macauleyfddc4662015-07-27 17:40:30 +0800258
259def add_l2_overlay_flood_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
260 buckets=[]
261 for port in ports:
262 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
263
264 group_id=encode_l2_overlay_group_id(tunnel_id, 0, index)
265 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
266 group_id=group_id,
267 buckets=buckets
268 )
269 ctrl.message_send(request)
270 return request
271
272def add_l2_overlay_flood_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
273 buckets=[]
274 for port in ports:
275 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
276
277 group_id=encode_l2_overlay_group_id(tunnel_id, 1, index)
278 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
279 group_id=group_id,
280 buckets=buckets
281 )
282 ctrl.message_send(request)
283 return request
284
285def add_l2_overlay_mcast_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
286 buckets=[]
287 for port in ports:
288 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
289
290 group_id=encode_l2_overlay_group_id(tunnel_id, 2, index)
291 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
292 group_id=group_id,
293 buckets=buckets
294 )
295 ctrl.message_send(request)
296 return request
297
298def add_l2_overlay_mcast_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
299 buckets=[]
300 for port in ports:
301 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
302
303 group_id=encode_l2_overlay_group_id(tunnel_id, 3, index)
304 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
305 group_id=group_id,
306 buckets=buckets
307 )
308 ctrl.message_send(request)
309 return request
310
311def add_port_table_flow(ctrl, is_overlay=True):
312 match = ofp.match()
313
314 if is_overlay == True:
315 match.oxm_list.append(ofp.oxm.in_port(0x10000))
macauleydbff3272015-07-30 14:07:16 +0800316 NEXT_TABLE=50
macauleyfddc4662015-07-27 17:40:30 +0800317 else:
318 match.oxm_list.append(ofp.oxm.in_port(0))
macauleydbff3272015-07-30 14:07:16 +0800319 NEXT_TABLE=10
macauleyfddc4662015-07-27 17:40:30 +0800320
321 request = ofp.message.flow_add(
322 table_id=0,
323 cookie=42,
324 match=match,
325 instructions=[
macauleydbff3272015-07-30 14:07:16 +0800326 ofp.instruction.goto_table(NEXT_TABLE)
macauleyfddc4662015-07-27 17:40:30 +0800327 ],
328 priority=0)
329 logging.info("Add port table, match port %lx" % 0x10000)
330 ctrl.message_send(request)
macauleydbff3272015-07-30 14:07:16 +0800331
332
macauleyfddc4662015-07-27 17:40:30 +0800333
macauley97557232015-07-16 17:28:07 +0800334def add_vlan_table_flow(ctrl, ports, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
335 # table 10: vlan
336 # goto to table 20
macauley15909e72015-07-17 15:58:57 +0800337 msgs=[]
macauley97557232015-07-16 17:28:07 +0800338 for of_port in ports:
339 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
340 match = ofp.match()
341 match.oxm_list.append(ofp.oxm.in_port(of_port))
342 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
343 request = ofp.message.flow_add(
344 table_id=10,
345 cookie=42,
346 match=match,
347 instructions=[
348 ofp.instruction.goto_table(20)
349 ],
350 priority=0)
351 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
352 ctrl.message_send(request)
353
354 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
355 match = ofp.match()
356 match.oxm_list.append(ofp.oxm.in_port(of_port))
357 match.oxm_list.append(ofp.oxm.vlan_vid(0))
358 request = ofp.message.flow_add(
359 table_id=10,
360 cookie=42,
361 match=match,
362 instructions=[
363 ofp.instruction.apply_actions(
364 actions=[
365 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id))
366 ]
367 ),
368 ofp.instruction.goto_table(20)
369 ],
370 priority=0)
371 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
372 ctrl.message_send(request)
macauley15909e72015-07-17 15:58:57 +0800373 msgs.append(request)
macauley97557232015-07-16 17:28:07 +0800374
375 if send_barrier:
376 do_barrier(ctrl)
377
macauley15909e72015-07-17 15:58:57 +0800378 return msgs
macauley0f91a3e2015-07-17 18:09:59 +0800379
macauley53d90fe2015-08-04 17:34:22 +0800380def add_one_vlan_table_flow(ctrl, of_port, vlan_id=1, vrf=0, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
macauley0f91a3e2015-07-17 18:09:59 +0800381 # table 10: vlan
382 # goto to table 20
383 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
384 match = ofp.match()
385 match.oxm_list.append(ofp.oxm.in_port(of_port))
386 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
macauley53d90fe2015-08-04 17:34:22 +0800387
macauley0f91a3e2015-07-17 18:09:59 +0800388 request = ofp.message.flow_add(
389 table_id=10,
390 cookie=42,
391 match=match,
392 instructions=[
macauley53d90fe2015-08-04 17:34:22 +0800393 ofp.instruction.apply_actions(
394 actions=[ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf))]
395 ),
396 ofp.instruction.goto_table(20)
macauley0f91a3e2015-07-17 18:09:59 +0800397 ],
398 priority=0)
399 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
400 ctrl.message_send(request)
401
402 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
403 match = ofp.match()
404 match.oxm_list.append(ofp.oxm.in_port(of_port))
405 match.oxm_list.append(ofp.oxm.vlan_vid(0))
macauley53d90fe2015-08-04 17:34:22 +0800406
macauley0f91a3e2015-07-17 18:09:59 +0800407 request = ofp.message.flow_add(
408 table_id=10,
409 cookie=42,
410 match=match,
411 instructions=[
412 ofp.instruction.apply_actions(
413 actions=[
414 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id))
415 ]
416 ),
417 ofp.instruction.goto_table(20)
418 ],
419 priority=0)
420 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
421 ctrl.message_send(request)
422
423 if send_barrier:
424 do_barrier(ctrl)
425
426 return request
macauley15909e72015-07-17 15:58:57 +0800427
macauley97557232015-07-16 17:28:07 +0800428def add_bridge_flow(ctrl, dst_mac, vlanid, group_id, send_barrier=False):
429 match = ofp.match()
macauleyfddc4662015-07-27 17:40:30 +0800430 if dst_mac!=None:
431 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
432
macauley97557232015-07-16 17:28:07 +0800433 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
macauleyfddc4662015-07-27 17:40:30 +0800434
macauley97557232015-07-16 17:28:07 +0800435 request = ofp.message.flow_add(
436 table_id=50,
437 cookie=42,
438 match=match,
439 instructions=[
440 ofp.instruction.write_actions(
441 actions=[
442 ofp.action.group(group_id)]),
443 ofp.instruction.goto_table(60)
444 ],
445 buffer_id=ofp.OFP_NO_BUFFER,
446 priority=1000)
447
448 logging.info("Inserting Brdige flow vlan %d, mac %s", vlanid, dst_mac)
449 ctrl.message_send(request)
450
451 if send_barrier:
macauley15909e72015-07-17 15:58:57 +0800452 do_barrier(ctrl)
453
macauley0f91a3e2015-07-17 18:09:59 +0800454 return request
macauleyfddc4662015-07-27 17:40:30 +0800455
456def add_overlay_bridge_flow(ctrl, dst_mac, vnid, group_id, is_group=True, send_barrier=False):
457 match = ofp.match()
458 if dst_mac!=None:
459 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
460
461 match.oxm_list.append(ofp.oxm.tunnel_id(vnid))
462 if is_group == True:
463 actions=[ofp.action.group(group_id)]
464 else:
465 actions=[ofp.action.output(group_id)]
466
467 request = ofp.message.flow_add(
468 table_id=50,
469 cookie=42,
470 match=match,
471 instructions=[
472 ofp.instruction.write_actions(
473 actions=actions),
474 ofp.instruction.goto_table(60)
475 ],
476 buffer_id=ofp.OFP_NO_BUFFER,
477 priority=1000)
478
479 logging.info("Inserting Brdige flow vnid %d, mac %s", vnid, dst_mac)
480 ctrl.message_send(request)
481
482 if send_barrier:
483 do_barrier(ctrl)
484
485 return request
macauley0f91a3e2015-07-17 18:09:59 +0800486
487def add_termination_flow(ctrl, in_port, eth_type, dst_mac, vlanid, send_barrier=False):
488 match = ofp.match()
macauley0f91a3e2015-07-17 18:09:59 +0800489 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
macauleyfddc4662015-07-27 17:40:30 +0800490 if dst_mac[0]&0x01 == 0x01:
491 match.oxm_list.append(ofp.oxm.eth_dst_masked(dst_mac, [0xff, 0xff, 0xff, 0x80, 0x00, 0x00]))
492 goto_table=40
493 else:
macauley53d90fe2015-08-04 17:34:22 +0800494 if in_port!=0:
495 match.oxm_list.append(ofp.oxm.in_port(in_port))
macauleyfddc4662015-07-27 17:40:30 +0800496 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
497 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
498 goto_table=30
macauley0f91a3e2015-07-17 18:09:59 +0800499
500 request = ofp.message.flow_add(
501 table_id=20,
502 cookie=42,
503 match=match,
504 instructions=[
505 ofp.instruction.goto_table(goto_table)
506 ],
507 buffer_id=ofp.OFP_NO_BUFFER,
508 priority=1)
509
510 logging.info("Inserting termination flow inport %d, eth_type %lx, vlan %d, mac %s", in_port, eth_type, vlanid, dst_mac)
511 ctrl.message_send(request)
512
513 if send_barrier:
514 do_barrier(ctrl)
515
516 return request
517
macauley53d90fe2015-08-04 17:34:22 +0800518def add_unicast_routing_flow(ctrl, eth_type, dst_ip, mask, action_group_id, vrf=0, send_barrier=False):
macauley0f91a3e2015-07-17 18:09:59 +0800519 match = ofp.match()
520 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
macauley53d90fe2015-08-04 17:34:22 +0800521 if vrf != 0:
522 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_VRF, vrf))
523
macauleyf8b1acd2015-07-23 15:13:13 +0800524 if mask!=0:
525 match.oxm_list.append(ofp.oxm.ipv4_dst_masked(dst_ip, mask))
526 else:
527 match.oxm_list.append(ofp.oxm.ipv4_dst(dst_ip))
macauley0f91a3e2015-07-17 18:09:59 +0800528
macauley53d90fe2015-08-04 17:34:22 +0800529
macauley0f91a3e2015-07-17 18:09:59 +0800530 request = ofp.message.flow_add(
531 table_id=30,
532 cookie=42,
533 match=match,
534 instructions=[
535 ofp.instruction.write_actions(
536 actions=[ofp.action.group(action_group_id)]),
537 ofp.instruction.goto_table(60)
538 ],
539 buffer_id=ofp.OFP_NO_BUFFER,
540 priority=1)
541
542 logging.info("Inserting unicast routing flow eth_type %lx, dip %ld",eth_type, dst_ip)
543 ctrl.message_send(request)
544
545 if send_barrier:
546 do_barrier(ctrl)
547
macauleyfddc4662015-07-27 17:40:30 +0800548 return request
549
550def add_mcast4_routing_flow(ctrl, vlan_id, src_ip, src_ip_mask, dst_ip, action_group_id, send_barrier=False):
551 match = ofp.match()
552 match.oxm_list.append(ofp.oxm.eth_type(0x0800))
553 match.oxm_list.append(ofp.oxm.vlan_vid(vlan_id))
554 if src_ip_mask!=0:
555 match.oxm_list.append(ofp.oxm.ipv4_src_masked(src_ip, src_ip_mask))
556 else:
557 match.oxm_list.append(ofp.oxm.ipv4_src(src_ip))
558
559 match.oxm_list.append(ofp.oxm.ipv4_dst(dst_ip))
560
561 request = ofp.message.flow_add(
562 table_id=40,
563 cookie=42,
564 match=match,
565 instructions=[
566 ofp.instruction.write_actions(
567 actions=[ofp.action.group(action_group_id)]),
568 ofp.instruction.goto_table(60)
569 ],
570 buffer_id=ofp.OFP_NO_BUFFER,
571 priority=1)
572
573 logging.info("Inserting mcast routing flow eth_type %lx, dip %lx, sip %lx, sip_mask %lx",0x0800, dst_ip, src_ip, src_ip_mask)
574 ctrl.message_send(request)
575
576 if send_barrier:
577 do_barrier(ctrl)
578
579 return request
580
581def get_vtap_lport_config_xml(dp_id, lport, phy_port, vlan, vnid, operation='merge'):
582 """
583 Command Example:
584 of-agent vtap 10001 ethernet 1/1 vid 1
585 of-agent vtp 10001 vni 10
586 """
587 if vlan != 0:
588 config_vtap_xml="""
589 <config>
590 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
591 <id>capable-switch-1</id>
592 <resources>
593 <port xc:operation="OPERATION">
594 <resource-id >LPORT</resource-id>
595 <features>
596 <current>
597 <rate>10Gb</rate>
598 <medium>fiber</medium>
599 <pause>symmetric</pause>
600 </current>
601 <advertised>
602 <rate>10Gb</rate>
603 <rate>100Gb</rate>
604 <medium>fiber</medium>
605 <pause>symmetric</pause>
606 </advertised>
607 <supported>
608 <rate>10Gb</rate>
609 <rate>100Gb</rate>
610 <medium>fiber</medium>
611 <pause>symmetric</pause>
612 </supported>
613 <advertised-peer>
614 <rate>10Gb</rate>
615 <rate>100Gb</rate>
616 <medium>fiber</medium>
617 <pause>symmetric</pause>
618 </advertised-peer>
619 </features>
620 <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
621 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
622 <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
623 <ofdpa10:vni>VNID</ofdpa10:vni>
624 </ofdpa10:vtap>
625 </port>
626 </resources>
627 <logical-switches>
628 <switch>
629 <id>DATAPATH_ID</id>
630 <datapath-id>DATAPATH_ID</datapath-id>
631 <resources>
632 <port xc:operation="OPERATION">LPORT</port>
633 </resources>
634 </switch>
635 </logical-switches>
636 </capable-switch>
637 </config>
638 """
639 else:
640 config_vtap_xml="""
641 <config>
642 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
643 <id>capable-switch-1</id>
644 <resources>
645 <port xc:operation="OPERATION">
646 <resource-id >LPORT</resource-id>
647 <features>
648 <current>
649 <rate>10Gb</rate>
650 <medium>fiber</medium>
651 <pause>symmetric</pause>
652 </current>
653 <advertised>
654 <rate>10Gb</rate>
655 <rate>100Gb</rate>
656 <medium>fiber</medium>
657 <pause>symmetric</pause>
658 </advertised>
659 <supported>
660 <rate>10Gb</rate>
661 <rate>100Gb</rate>
662 <medium>fiber</medium>
663 <pause>symmetric</pause>
664 </supported>
665 <advertised-peer>
666 <rate>10Gb</rate>
667 <rate>100Gb</rate>
668 <medium>fiber</medium>
669 <pause>symmetric</pause>
670 </advertised-peer>
671 </features>
672 <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
673 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
674 <ofdpa10:vni>VNID</ofdpa10:vni>
675 </ofdpa10:vtap>
676 </port>
677 </resources>
678 <logical-switches>
679 <switch>
680 <id>DATAPATH_ID</id>
681 <datapath-id>DATAPATH_ID</datapath-id>
682 <resources>
683 <port xc:operation="OPERATION">LPORT</port>
684 </resources>
685 </switch>
686 </logical-switches>
687 </capable-switch>
688 </config>
689 """
690 str_datapath_id_f= "{:016x}".format(dp_id)
691 str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
692 config_vtap_xml=config_vtap_xml.replace("DATAPATH_ID", str_datapath_id)
693 config_vtap_xml=config_vtap_xml.replace("LPORT", str(hex(lport)))
694 config_vtap_xml=config_vtap_xml.replace("PHY_PORT", str(phy_port))
695 config_vtap_xml=config_vtap_xml.replace("VLAN_ID", str(vlan))
696 config_vtap_xml=config_vtap_xml.replace("VNID", str(vnid))
697 config_vtap_xml=config_vtap_xml.replace("OPERATION", str(operation))
698 return config_vtap_xml
699
700def get_vtep_lport_config_xml(dp_id, lport, src_ip, dst_ip, next_hop_id, vnid, udp_src_port=6633, ttl=25, operation='merge'):
701 """
702 Command Example:
703 of-agent vtep 10002 source user-input-src-ip destination user-input-dst-ip udp-source-port 6633 nexthop 2 ttl 25
704 of-agent vtp 10001 vni 10
705 """
706
707 config_vtep_xml="""
708 <config>
709 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
710 <id>capable-switch-1</id>
711 <resources>
712 <port xc:operation="OPERATION">
713 <resource-id>LPORT</resource-id>
714 <features>
715 <current>
716 <rate>10Gb</rate>
717 <medium>fiber</medium>
718 <pause>symmetric</pause>
719 </current>
720 <advertised>
721 <rate>10Gb</rate>
722 <rate>100Gb</rate>
723 <medium>fiber</medium>
724 <pause>symmetric</pause>
725 </advertised>
726 <supported>
727 <rate>10Gb</rate>
728 <rate>100Gb</rate>
729 <medium>fiber</medium>
730 <pause>symmetric</pause>
731 </supported>
732 <advertised-peer>
733 <rate>10Gb</rate>
734 <rate>100Gb</rate>
735 <medium>fiber</medium>
736 <pause>symmetric</pause>
737 </advertised-peer>
738 </features>
739 <ofdpa10:vtep xmlns:ofdpa10="urn:bcm:ofdpa10:accton01">
740 <ofdpa10:src-ip>SRC_IP</ofdpa10:src-ip>
741 <ofdpa10:dest-ip>DST_IP</ofdpa10:dest-ip>
742 <ofdpa10:udp-src-port>UDP_SRC_PORT</ofdpa10:udp-src-port>
743 <ofdpa10:vni>VNID</ofdpa10:vni>
744 <ofdpa10:nexthop-id>NEXT_HOP_ID</ofdpa10:nexthop-id>
745 <ofdpa10:ttl>TTL</ofdpa10:ttl>
746 </ofdpa10:vtep>
747 </port>
748 </resources>
749 <logical-switches>
750 <switch>
751 <id>DATAPATH_ID</id>
752 <datapath-id>DATAPATH_ID</datapath-id>
753 <resources>
754 <port xc:operation="OPERATION">LPORT</port>
755 </resources>
756 </switch>
757 </logical-switches>
758 </capable-switch>
759 </config>
760 """
761 str_datapath_id_f= "{:016x}".format(dp_id)
762 str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
763 config_vtep_xml=config_vtep_xml.replace("DATAPATH_ID", str_datapath_id)
764 config_vtep_xml=config_vtep_xml.replace("LPORT", str(hex(lport)))
765 config_vtep_xml=config_vtep_xml.replace("SRC_IP", str(src_ip))
766 config_vtep_xml=config_vtep_xml.replace("DST_IP", str(dst_ip))
767 config_vtep_xml=config_vtep_xml.replace("UDP_SRC_PORT", str(udp_src_port))
768 config_vtep_xml=config_vtep_xml.replace("NEXT_HOP_ID", str(next_hop_id))
769 config_vtep_xml=config_vtep_xml.replace("TTL", str(ttl))
770 config_vtep_xml=config_vtep_xml.replace("VNID", str(vnid))
771 config_vtep_xml=config_vtep_xml.replace("OPERATION", str(operation))
772
773 return config_vtep_xml
774
775def get_next_hop_config_xml(next_hop_id, dst_mac, phy_port, vlan, operation='merge'):
776 #of-agent nexthop 2 destination user-input-dst-mac ethernet 1/2 vid 2
777 config_nexthop_xml="""
778 <config>
779 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
780 <ofdpa10:next-hop xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
781 <ofdpa10:id>NEXT_HOP_ID</ofdpa10:id>
782 <ofdpa10:dest-mac>DST_MAC</ofdpa10:dest-mac>
783 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
784 <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
785 </ofdpa10:next-hop>
786 </of11-config:capable-switch>
787 </config>
788 """
789 config_nexthop_xml=config_nexthop_xml.replace("VLAN_ID", str(vlan))
790 config_nexthop_xml=config_nexthop_xml.replace("PHY_PORT", str(phy_port))
791 config_nexthop_xml=config_nexthop_xml.replace("NEXT_HOP_ID", str(next_hop_id))
792 config_nexthop_xml=config_nexthop_xml.replace("DST_MAC", str(dst_mac))
793 config_nexthop_xml=config_nexthop_xml.replace("OPERATION", str(operation))
794 return config_nexthop_xml
795
796def get_vni_config_xml(vni_id, mcast_ipv4, next_hop_id, operation='merge'):
797 #of-agent vni 10 multicast 224.1.1.1 nexthop 20
798 if mcast_ipv4!=None:
799 config_vni_xml="""
800 <config>
801 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
802 <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
803 <ofdpa10:id>VNID</ofdpa10:id>
804 <ofdpa10:vni-multicast-group>MCAST_IP</ofdpa10:vni-multicast-group>
805 <ofdpa10:multicast-group-nexthop-id>NEXT_HOP_ID</ofdpa10:multicast-group-nexthop-id>
806 </ofdpa10:vni>
807 </of11-config:capable-switch>
808 </config>
809 """
810 config_vni_xml=config_vni_xml.replace("NEXT_HOP_ID", str(next_hop_id))
811 config_vni_xml=config_vni_xml.replace("MCAST_IP", str(mcast_ipv4))
812 else:
813 config_vni_xml="""
814 <config>
815 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
816 <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
817 <ofdpa10:id>VNID</ofdpa10:id>
818 </ofdpa10:vni>
819 </of11-config:capable-switch>
820 </config>
821 """
822
823 config_vni_xml=config_vni_xml.replace("VNID", str(vni_id))
824 config_vni_xml=config_vni_xml.replace("OPERATION", str(operation))
825 return config_vni_xml
826
827def get_featureReplay(self):
828 req = ofp.message.features_request()
829 res, raw = self.controller.transact(req)
830 self.assertIsNotNone(res, "Did not receive a response from the DUT.")
831 self.assertEqual(res.type, ofp.OFPT_FEATURES_REPLY,
832 ("Unexpected packet type %d received in response to "
833 "OFPT_FEATURES_REQUEST") % res.type)
834 return res
835
836def send_edit_config(switch_ip, xml, target='runing'):
837 NETCONF_ACCOUNT="netconfuser"
838 NETCONF_PASSWD="netconfuser"
839 with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
840 try:
841 m.edit_config(target='running',
842 config=xml,
843 default_operation='merge',
844 error_option='stop-on-error')
845
846 except Exception as e:
847 logging.info("Fail to set xml %s", xml)
848 return False
849
850 #return m.get_config(source='running').data_xml
851 return True
852
853def send_delete_config(switch_ip, xml, target='runing'):
854 NETCONF_ACCOUNT="netconfuser"
855 NETCONF_PASSWD="netconfuser"
856 with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
857 try:
858 m.edit_config(target='running',
859 config=xml,
860 default_operation='delete',
861 error_option='stop-on-error')
862
863 except Exception as e:
864 logging.info("Fail to set xml %s", xml)
865 return False
866
867 #return m.get_config(source='running').data_xml
868 return True
869
870def get_edit_config(switch_ip, target='runing'):
871 NETCONF_ACCOUNT="netconfuser"
872 NETCONF_PASSWD="netconfuser"
873 with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
874 print m.get_config(source='running').data_xml
macauleydbff3272015-07-30 14:07:16 +0800875
876
877def print_current_table_flow_stat(ctrl, table_id=0xff):
878 stat_req=ofp.message.flow_stats_request()
879 response, pkt = ctrl.transact(stat_req)
880 if response == None:
881 print "no response"
882 return None
883 print len(response.entries)
884 for obj in response.entries:
885 print "match ", obj.match
886 print "cookie", obj.cookie
887 print "priority", obj.priority
888 print "idle_timeout", obj.idle_timeout
889 print "hard_timeout", obj.hard_timeout
890 #obj.actions
891 print "packet count: %lx"%obj.packet_count