blob: 342800c40a2c43e878be8595716861cc15845ff5 [file] [log] [blame]
Flavio Castro96646c62015-11-16 15:05:43 -05001import logging
2
3from oftest import config
4import oftest.base_tests as base_tests
5import ofp
6import time
7from oftest.testutils import *
8
9from ncclient import manager
10import ncclient
11
12OFDPA_GROUP_TYPE_SHIFT=28
13OFDPA_VLAN_ID_SHIFT =16
14OFDPA_TUNNEL_ID_SHIFT =12
15OFDPA_TUNNEL_SUBTYPE_SHIFT=10
16
17#VLAN_TABLE_FLAGS
18VLAN_TABLE_FLAG_ONLY_UNTAG=1
19VLAN_TABLE_FLAG_ONLY_TAG =2
20VLAN_TABLE_FLAG_ONLY_BOTH =3
21
22PORT_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
43def getSwitchCpuMACFromDPID(dpid):
44 str_datapath_id_f= "{:016x}".format(dpid)
45 str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
46 switch_cpu_mac_str=str_datapath_id[6:]
47 switch_cpu_mac = switch_cpu_mac_str.split(":")
48 switch_cpu_mac=[int(switch_cpu_mac[i],16) for i in range(0, len(switch_cpu_mac))]
49
50 return switch_cpu_mac_str, switch_cpu_mac
51
52def DumpGroup(stats, verify_group_stats, always_show=True):
53 if(len(stats) > len(verify_group_stats)):
54 min_len = len(verify_group_stats)
55 print "Stats Len is not the same, stats>verify_group_stats"
56 if(len(stats)< len(verify_group_stats)):
57 min_len = len(stats)
58 print "Stats Len is not the same, stats<verify_group_stats"
59 else:
60 min_len = len(stats)
61
62 print "\r\n"
63 for i in range(min_len):
64 gs = stats[i]
65 gv = verify_group_stats[i]
66 print "FromSwtich:(GID=%lx, TYPE=%lx)\r\nVerify :(GID=%lx, TYPE=%lx)"%(gs.group_id, gs.group_type, gv.group_id, gv.group_type)
67 if(len(gs.buckets) != len(gv.buckets)):
68 print "buckets len is not the same gs %lx, gv %lx",(len(gs.buckets), len(gv.buckets))
69
70 for j in range(len(gs.buckets)):
71 b1=gs.buckets[j]
72 b2=gv.buckets[j]
73 if(len(b1.actions) != len(b2.actions)):
74 print "action len is not the same"
75
76 for k in range(len(b1.actions)):
77 a1=b1.actions[k]
78 a2=b2.actions[k]
79 if(always_show == True):
80 print "a1:"+a1.show()
81 print "a2:"+a2.show()
82
83def AssertGroup(self, stats, verify_group_stats):
84 self.assertTrue(len(stats) ==len(verify_group_stats), "stats len is not the same")
85
86 for i in range(len(stats)):
87 gs = stats[i]
88 gv = verify_group_stats[i]
89 self.assertTrue(len(gs.buckets) == len(gv.buckets), "buckets len is not the same")
90
91 for j in range(len(gs.buckets)):
92 b1=gs.buckets[j]
93 b2=gv.buckets[j]
94 self.assertTrue(len(b1.actions) == len(b2.actions), "action len is not the same")
95
96 for k in range(len(b1.actions)):
97 a1=b1.actions[k]
98 a2=b2.actions[k]
99 self.assertEquals(a1, a2, "action is not the same")
100
101def encode_l2_interface_group_id(vlan, id):
102 return id + (vlan << OFDPA_VLAN_ID_SHIFT)
103
104def encode_l2_rewrite_group_id(id):
105 return id + (1 << OFDPA_GROUP_TYPE_SHIFT)
106
107def encode_l3_unicast_group_id(id):
108 return id + (2 << OFDPA_GROUP_TYPE_SHIFT)
109
110def encode_l2_mcast_group_id(vlan, id):
111 return id + (vlan << OFDPA_VLAN_ID_SHIFT) + (3 << OFDPA_GROUP_TYPE_SHIFT)
112
113def encode_l2_flood_group_id(vlan, id):
114 return id + (vlan << OFDPA_VLAN_ID_SHIFT) + (4 << OFDPA_GROUP_TYPE_SHIFT)
115
116def encode_l3_interface_group_id(id):
117 return id + (5 << OFDPA_GROUP_TYPE_SHIFT)
118
119def encode_l3_mcast_group_id(vlan, id):
120 return id + (vlan << OFDPA_VLAN_ID_SHIFT)+(6 << OFDPA_GROUP_TYPE_SHIFT)
121
122def encode_l3_ecmp_group_id(id):
123 return id + (7 << OFDPA_GROUP_TYPE_SHIFT)
124
125def encode_l2_overlay_group_id(tunnel_id, subtype, index):
126 tunnel_id=tunnel_id&0xffff #16 bits
127 subtype = subtype&3 #2 bits
128 index = index & 0x3f #10 bits
129 return index + (tunnel_id << OFDPA_TUNNEL_ID_SHIFT)+ (subtype<<OFDPA_TUNNEL_SUBTYPE_SHIFT)+(8 << OFDPA_GROUP_TYPE_SHIFT)
130
131def add_l2_interface_grouop(ctrl, ports, vlan_id=1, is_tagged=False, send_barrier=False):
132 # group table
133 # set up untag groups for each port
134 group_id_list=[]
135 msgs=[]
136 for of_port in ports:
137 # do stuff
138 group_id = encode_l2_interface_group_id(vlan_id, of_port)
139 group_id_list.append(group_id)
140 if is_tagged:
141 actions = [
142 ofp.action.output(of_port),
143 ]
144 else:
145 actions = [
146 ofp.action.pop_vlan(),
147 ofp.action.output(of_port),
148 ]
149
150 buckets = [
151 ofp.bucket(actions=actions),
152 ]
153
154 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
155 group_id=group_id,
156 buckets=buckets
157 )
158 ctrl.message_send(request)
159 msgs.append(request)
160
161 if send_barrier:
162 do_barrier(ctrl)
163
164 return group_id_list, msgs
165
castroflaviodd171472015-12-08 13:55:58 -0500166def add_one_l2_interface_group(ctrl, port, vlan_id=1, is_tagged=False, send_barrier=False):
Flavio Castro96646c62015-11-16 15:05:43 -0500167 # group table
168 # set up untag groups for each port
169 group_id = encode_l2_interface_group_id(vlan_id, port)
170
171 if is_tagged:
172 actions = [
173 ofp.action.output(port),
174 ]
175 else:
176 actions = [
177 ofp.action.pop_vlan(),
178 ofp.action.output(port),
179 ]
180
181 buckets = [
182 ofp.bucket(actions=actions),
183 ]
184
185 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
186 group_id=group_id,
187 buckets=buckets
188 )
189 ctrl.message_send(request)
190
191 if send_barrier:
192 do_barrier(ctrl)
193
194 return group_id, request
195
196def add_l2_mcast_group(ctrl, ports, vlanid, mcast_grp_index):
197 buckets=[]
198 for of_port in ports:
199 group_id = encode_l2_interface_group_id(vlanid, of_port)
200 action=[ofp.action.group(group_id)]
201 buckets.append(ofp.bucket(actions=action))
202
203 group_id =encode_l2_mcast_group_id(vlanid, mcast_grp_index)
204 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
205 group_id=group_id,
206 buckets=buckets
207 )
208 ctrl.message_send(request)
209 return request
210
211def add_l2_flood_group(ctrl, ports, vlanid, id):
212 buckets=[]
213 for of_port in ports:
214 group_id = encode_l2_interface_group_id(vlanid, of_port)
215 action=[ofp.action.group(group_id)]
216 buckets.append(ofp.bucket(actions=action))
217
218 group_id =encode_l2_flood_group_id(vlanid, id)
219 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
220 group_id=group_id,
221 buckets=buckets
222 )
223 ctrl.message_send(request)
224 return request
225
226def add_l2_rewrite_group(ctrl, port, vlanid, id, src_mac, dst_mac):
227 group_id = encode_l2_interface_group_id(vlanid, port)
228
229 action=[]
230 if src_mac is not None:
231 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
232
233 if dst_mac is not None:
234 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
235
236 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(vlanid)))
237
238 action.append(ofp.action.group(group_id))
239
240 buckets = [ofp.bucket(actions=action)]
241
242 group_id =encode_l2_rewrite_group_id(id)
243 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
244 group_id=group_id,
245 buckets=buckets
246 )
247 ctrl.message_send(request)
248 return request
249
250def add_l3_unicast_group(ctrl, port, vlanid, id, src_mac, dst_mac):
251 group_id = encode_l2_interface_group_id(vlanid, port)
252
253 action=[]
254 if src_mac is not None:
255 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
256
257 if dst_mac is not None:
258 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
259
260 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(vlanid)))
261
262 action.append(ofp.action.group(group_id))
263
264 buckets = [ofp.bucket(actions=action)]
265
266 group_id =encode_l3_unicast_group_id(id)
267 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
268 group_id=group_id,
269 buckets=buckets
270 )
271 ctrl.message_send(request)
272 return request
273
274def add_l3_interface_group(ctrl, port, vlanid, id, src_mac):
275 group_id = encode_l2_interface_group_id(vlanid, port)
276
277 action=[]
278 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
279 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(vlanid)))
280 action.append(ofp.action.group(group_id))
281
282 buckets = [ofp.bucket(actions=action)]
283
284 group_id =encode_l3_interface_group_id(id)
285 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
286 group_id=group_id,
287 buckets=buckets
288 )
289 ctrl.message_send(request)
290 return request
291
292def add_l3_ecmp_group(ctrl, id, l3_ucast_groups):
293 buckets=[]
294 for group in l3_ucast_groups:
295 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
296
297 group_id =encode_l3_ecmp_group_id(id)
298 request = ofp.message.group_add(group_type=ofp.OFPGT_SELECT,
299 group_id=group_id,
300 buckets=buckets
301 )
302 ctrl.message_send(request)
303 return request
304
305def add_l3_mcast_group(ctrl, vid, mcast_group_id, groups_on_buckets):
306 buckets=[]
307 for group in groups_on_buckets:
308 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
309
310 group_id =encode_l3_mcast_group_id(vid, mcast_group_id)
311 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
312 group_id=group_id,
313 buckets=buckets
314 )
315 ctrl.message_send(request)
316 return request
317
318def add_l2_overlay_flood_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
319 buckets=[]
320 for port in ports:
321 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
322
323 group_id=encode_l2_overlay_group_id(tunnel_id, 0, index)
324 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
325 group_id=group_id,
326 buckets=buckets
327 )
328 ctrl.message_send(request)
329 return request
330
331def add_l2_overlay_flood_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
332 buckets=[]
333 for port in ports:
334 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
335
336 group_id=encode_l2_overlay_group_id(tunnel_id, 1, index)
337 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
338 group_id=group_id,
339 buckets=buckets
340 )
341 ctrl.message_send(request)
342 return request
343
344def add_l2_overlay_mcast_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
345 buckets=[]
346 for port in ports:
347 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
348
349 group_id=encode_l2_overlay_group_id(tunnel_id, 2, index)
350 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
351 group_id=group_id,
352 buckets=buckets
353 )
354 ctrl.message_send(request)
355 return request
356
357def add_l2_overlay_mcast_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
358 buckets=[]
359 for port in ports:
360 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
361
362 group_id=encode_l2_overlay_group_id(tunnel_id, 3, index)
363 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
364 group_id=group_id,
365 buckets=buckets
366 )
367 ctrl.message_send(request)
368 return request
369
370def add_port_table_flow(ctrl, is_overlay=True):
371 match = ofp.match()
372
373 if is_overlay == True:
374 match.oxm_list.append(ofp.oxm.in_port(0x10000))
375 NEXT_TABLE=50
376 else:
377 match.oxm_list.append(ofp.oxm.in_port(0))
378 NEXT_TABLE=10
379
380 request = ofp.message.flow_add(
381 table_id=0,
382 cookie=42,
383 match=match,
384 instructions=[
385 ofp.instruction.goto_table(NEXT_TABLE)
386 ],
387 priority=0)
388 logging.info("Add port table, match port %lx" % 0x10000)
389 ctrl.message_send(request)
390
Flavio Castroe0b46012015-12-02 14:42:27 -0500391def pop_vlan_flow(ctrl, ports, vlan_id=1):
392 msgs=[]
393 for of_port in ports:
394 match = ofp.match()
395 match.oxm_list.append(ofp.oxm.in_port(of_port))
396 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
397 request = ofp.message.flow_add(
398 table_id=10,
399 cookie=42,
400 match=match,
401 instructions=[
402 ofp.instruction.apply_actions(
403 actions=[
404 ofp.action.pop_vlan()
405 ]
406 ),
407 ofp.instruction.goto_table(11)
408 ],
409 priority=0)
410 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
411 ctrl.message_send(request)
412
413 return msgs
Flavio Castro96646c62015-11-16 15:05:43 -0500414
415def add_vlan_table_flow(ctrl, ports, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
416 # table 10: vlan
417 # goto to table 20
418 msgs=[]
419 for of_port in ports:
420 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
421 match = ofp.match()
422 match.oxm_list.append(ofp.oxm.in_port(of_port))
423 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
Flavio Castro34352e72015-12-07 20:01:51 -0500424 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(value=vlan_id)))
Flavio Castro96646c62015-11-16 15:05:43 -0500425 request = ofp.message.flow_add(
426 table_id=10,
427 cookie=42,
428 match=match,
429 instructions=[
Flavio Castro34352e72015-12-07 20:01:51 -0500430 ofp.instruction.apply_actions(
431 actions=actions
432 ),
Flavio Castro96646c62015-11-16 15:05:43 -0500433 ofp.instruction.goto_table(20)
434 ],
435 priority=0)
436 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
437 ctrl.message_send(request)
438
439 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
440 match = ofp.match()
441 match.oxm_list.append(ofp.oxm.in_port(of_port))
442 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0xfff))
443 request = ofp.message.flow_add(
444 table_id=10,
445 cookie=42,
446 match=match,
447 instructions=[
448 ofp.instruction.apply_actions(
449 actions=[
450 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id))
451 ]
452 ),
453 ofp.instruction.goto_table(20)
454 ],
455 priority=0)
456 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
457 ctrl.message_send(request)
458 msgs.append(request)
459
460 if send_barrier:
461 do_barrier(ctrl)
462
463 return msgs
464
465def add_vlan_table_flow_pvid(ctrl, in_port, match_vid=None, pvid=1, send_barrier=False):
466 """it will tag pack as untagged packet wether it has tagg or not"""
467 match = ofp.match()
468 match.oxm_list.append(ofp.oxm.in_port(in_port))
469 actions=[]
470 if match_vid == None:
471 match.oxm_list.append(ofp.oxm.vlan_vid(0))
472 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+pvid)))
473 goto_table=20
474 else:
475 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+match_vid, 0x1fff))
476 actions.append(ofp.action.push_vlan(0x8100))
477 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+pvid)))
478 goto_table=20
479
480 request = ofp.message.flow_add(
481 table_id=10,
482 cookie=42,
483 match=match,
484 instructions=[
485 ofp.instruction.apply_actions(actions=actions)
486 ,ofp.instruction.goto_table(goto_table)
487 ],
488 priority=0)
489 logging.info("Add PVID %d on port %d and go to table %ld" %( pvid, in_port, goto_table))
490 ctrl.message_send(request)
491
492 if send_barrier:
493 do_barrier(ctrl)
494
495def add_vlan_table_flow_allow_all_vlan(ctrl, in_port, send_barrier=False):
496 """it st flow allow all vlan tag on this port"""
497 match = ofp.match()
498 match.oxm_list.append(ofp.oxm.in_port(in_port))
499 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1000))
500 request = ofp.message.flow_add(
501 table_id=10,
502 cookie=42,
503 match=match,
504 instructions=[
505 ofp.instruction.goto_table(20)
506 ],
507 priority=0)
508 logging.info("Add allow all vlan on port %d " %(in_port))
509 ctrl.message_send(request)
510
511
512def add_one_vlan_table_flow(ctrl, of_port, vlan_id=1, vrf=0, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
513 # table 10: vlan
514 # goto to table 20
515 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
516 match = ofp.match()
517 match.oxm_list.append(ofp.oxm.in_port(of_port))
518 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
519
520 actions=[]
521 if vrf!=0:
522 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
523
524 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(value=vlan_id)))
525
526 request = ofp.message.flow_add(
527 table_id=10,
528 cookie=42,
529 match=match,
530 instructions=[
531 ofp.instruction.apply_actions(
532 actions=actions
533 ),
534 ofp.instruction.goto_table(20)
535 ],
536 priority=0)
537 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
538 ctrl.message_send(request)
539
540 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
541 match = ofp.match()
542 match.oxm_list.append(ofp.oxm.in_port(of_port))
543 match.oxm_list.append(ofp.oxm.vlan_vid(0))
544
545 actions=[]
546 if vrf!=0:
547 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
548
549 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
550
551 request = ofp.message.flow_add(
552 table_id=10,
553 cookie=42,
554 match=match,
555 instructions=[
556 ofp.instruction.apply_actions(
557 actions=actions
558 ),
559 ofp.instruction.goto_table(20)
560 ],
561 priority=0)
562 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
563 ctrl.message_send(request)
564
565 if send_barrier:
566 do_barrier(ctrl)
567
568 return request
569
570def add_bridge_flow(ctrl, dst_mac, vlanid, group_id, send_barrier=False):
571 match = ofp.match()
572 if dst_mac!=None:
573 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
574
575 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
576
577 request = ofp.message.flow_add(
578 table_id=50,
579 cookie=42,
580 match=match,
581 instructions=[
582 ofp.instruction.write_actions(
583 actions=[
584 ofp.action.group(group_id)]),
585 ofp.instruction.goto_table(60)
586 ],
587 buffer_id=ofp.OFP_NO_BUFFER,
588 priority=1000)
589
590 logging.info("Inserting Brdige flow vlan %d, mac %s", vlanid, dst_mac)
591 ctrl.message_send(request)
592
593 if send_barrier:
594 do_barrier(ctrl)
595
596 return request
597
598def add_overlay_bridge_flow(ctrl, dst_mac, vnid, group_id, is_group=True, send_barrier=False):
599 match = ofp.match()
600 if dst_mac!=None:
601 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
602
603 match.oxm_list.append(ofp.oxm.tunnel_id(vnid))
604 if is_group == True:
605 actions=[ofp.action.group(group_id)]
606 else:
607 actions=[ofp.action.output(group_id)]
608
609 request = ofp.message.flow_add(
610 table_id=50,
611 cookie=42,
612 match=match,
613 instructions=[
614 ofp.instruction.write_actions(
615 actions=actions),
616 ofp.instruction.goto_table(60)
617 ],
618 buffer_id=ofp.OFP_NO_BUFFER,
619 priority=1000)
620
621 logging.info("Inserting Brdige flow vnid %d, mac %s", vnid, dst_mac)
622 ctrl.message_send(request)
623
624 if send_barrier:
625 do_barrier(ctrl)
626
627 return request
628
629def add_termination_flow(ctrl, in_port, eth_type, dst_mac, vlanid, goto_table=None, send_barrier=False):
630 match = ofp.match()
631 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
632 if dst_mac[0]&0x01 == 0x01:
633 match.oxm_list.append(ofp.oxm.eth_dst_masked(dst_mac, [0xff, 0xff, 0xff, 0x80, 0x00, 0x00]))
634 goto_table=40
635 else:
636 if in_port!=0:
637 match.oxm_list.append(ofp.oxm.in_port(in_port))
638 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
639 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
640 if goto_table == None:
641 goto_table=30
642
643 request = ofp.message.flow_add(
644 table_id=20,
645 cookie=42,
646 match=match,
647 instructions=[
648 ofp.instruction.goto_table(goto_table)
649 ],
650 buffer_id=ofp.OFP_NO_BUFFER,
651 priority=1)
652
653 logging.info("Inserting termination flow inport %d, eth_type %lx, vlan %d, mac %s", in_port, eth_type, vlanid, dst_mac)
654 ctrl.message_send(request)
655
656 if send_barrier:
657 do_barrier(ctrl)
658
659 return request
660
661def add_unicast_routing_flow(ctrl, eth_type, dst_ip, mask, action_group_id, vrf=0, send_barrier=False):
662 match = ofp.match()
663 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
664 if vrf != 0:
665 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_VRF, vrf))
666
667 if mask!=0:
668 match.oxm_list.append(ofp.oxm.ipv4_dst_masked(dst_ip, mask))
669 else:
670 match.oxm_list.append(ofp.oxm.ipv4_dst(dst_ip))
671
672
673 request = ofp.message.flow_add(
674 table_id=30,
675 cookie=42,
676 match=match,
677 instructions=[
678 ofp.instruction.write_actions(
679 actions=[ofp.action.group(action_group_id)]),
680 ofp.instruction.goto_table(60)
681 ],
682 buffer_id=ofp.OFP_NO_BUFFER,
683 priority=1)
684
685 logging.info("Inserting unicast routing flow eth_type %lx, dip %ld",eth_type, dst_ip)
686 ctrl.message_send(request)
687
688 if send_barrier:
689 do_barrier(ctrl)
690
691 return request
692
693def add_mcast4_routing_flow(ctrl, vlan_id, src_ip, src_ip_mask, dst_ip, action_group_id, send_barrier=False):
694 match = ofp.match()
695 match.oxm_list.append(ofp.oxm.eth_type(0x0800))
696 match.oxm_list.append(ofp.oxm.vlan_vid(vlan_id))
697 if src_ip_mask!=0:
698 match.oxm_list.append(ofp.oxm.ipv4_src_masked(src_ip, src_ip_mask))
699 else:
700 match.oxm_list.append(ofp.oxm.ipv4_src(src_ip))
701
702 match.oxm_list.append(ofp.oxm.ipv4_dst(dst_ip))
703
704 request = ofp.message.flow_add(
705 table_id=40,
706 cookie=42,
707 match=match,
708 instructions=[
709 ofp.instruction.write_actions(
710 actions=[ofp.action.group(action_group_id)]),
711 ofp.instruction.goto_table(60)
712 ],
713 buffer_id=ofp.OFP_NO_BUFFER,
714 priority=1)
715
716 logging.info("Inserting mcast routing flow eth_type %lx, dip %lx, sip %lx, sip_mask %lx",0x0800, dst_ip, src_ip, src_ip_mask)
717 ctrl.message_send(request)
718
719 if send_barrier:
720 do_barrier(ctrl)
721
722 return request
723
724#dpctl tcp:192.168.1.1:6633 flow-mod table=28,cmd=add,prio=281 eth_type=0x800,ip_dst=100.0.0.1,ip_proto=6,tcp_dst=5000 write:set_field=ip_dst:10.0.0.1,set_field=tcp_dst:2000,group=0x71000001 goto:60
725def add_dnat_flow(ctrl, eth_type, ip_dst, ip_proto, tcp_dst, set_ip_dst, set_tcp_dst, action_group_id):
726 match = ofp.match()
727 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
728 match.oxm_list.append(ofp.oxm.ipv4_dst(ip_dst))
729 match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
730 match.oxm_list.append(ofp.oxm.tcp_dst(tcp_dst))
731
732 request = ofp.message.flow_add(
733 table_id=28,
734 cookie=42,
735 match=match,
736 instructions=[
737 ofp.instruction.write_actions(
738 actions=[ofp.action.set_field(ofp.oxm.ipv4_dst(set_ip_dst)),
739 ofp.action.set_field(ofp.oxm.tcp_dst(set_tcp_dst)),
740 ofp.action.group(action_group_id)]),
741 ofp.instruction.goto_table(60)
742 ],
743 buffer_id=ofp.OFP_NO_BUFFER,
744 priority=1)
745 logging.info("Inserting DNAT flow eth_type %lx, dip %lx, ip_proto %ld, tcp_dst %ld, SetFeild: Dip %lx, tcp_dst %ld, action_gorup=%lx",eth_type, ip_dst, ip_proto, tcp_dst, set_ip_dst, set_tcp_dst, action_group_id)
746 ctrl.message_send(request)
747 return request
748
749#dpctl tcp:192.168.1.1:6633 flow-mod table=29,cmd=add,prio=291 eth_type=0x800,ip_src=10.0.0.1,ip_proto=6,tcp_src=2000 write:set_field=ip_src:100.0.0.1,set_field=tcp_src:5000 goto:30
750def add_snat_flow(ctrl, eth_type, ip_src, ip_proto, tcp_src, set_ip_src, set_tcp_src):
751 match = ofp.match()
752 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
753 match.oxm_list.append(ofp.oxm.ipv4_src(ip_src))
754 match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
755 match.oxm_list.append(ofp.oxm.tcp_src(tcp_src))
756
757 request = ofp.message.flow_add(
758 table_id=29,
759 cookie=42,
760 match=match,
761 instructions=[
762 ofp.instruction.write_actions(
763 actions=[ofp.action.set_field(ofp.oxm.ipv4_src(set_ip_src)),
764 ofp.action.set_field(ofp.oxm.tcp_src(set_tcp_src))]),
765 ofp.instruction.goto_table(30)
766 ],
767 buffer_id=ofp.OFP_NO_BUFFER,
768 priority=1)
769 logging.info("Inserting DNAT flow eth_type %lx, sip %lx, ip_proto %ld, tcp_src %ld, SetFeild: sip %lx, tcp_src %ld",eth_type, ip_src, ip_proto, tcp_src, set_ip_src, set_tcp_src)
770 ctrl.message_send(request)
771 return request
772
773def get_vtap_lport_config_xml(dp_id, lport, phy_port, vlan, vnid, operation='merge'):
774 """
775 Command Example:
776 of-agent vtap 10001 ethernet 1/1 vid 1
777 of-agent vtp 10001 vni 10
778 """
779 if vlan != 0:
780 config_vtap_xml="""
781 <config>
782 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
783 <id>capable-switch-1</id>
784 <resources>
785 <port xc:operation="OPERATION">
786 <resource-id >LPORT</resource-id>
787 <features>
788 <current>
789 <rate>10Gb</rate>
790 <medium>fiber</medium>
791 <pause>symmetric</pause>
792 </current>
793 <advertised>
794 <rate>10Gb</rate>
795 <rate>100Gb</rate>
796 <medium>fiber</medium>
797 <pause>symmetric</pause>
798 </advertised>
799 <supported>
800 <rate>10Gb</rate>
801 <rate>100Gb</rate>
802 <medium>fiber</medium>
803 <pause>symmetric</pause>
804 </supported>
805 <advertised-peer>
806 <rate>10Gb</rate>
807 <rate>100Gb</rate>
808 <medium>fiber</medium>
809 <pause>symmetric</pause>
810 </advertised-peer>
811 </features>
812 <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
813 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
814 <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
815 <ofdpa10:vni>VNID</ofdpa10:vni>
816 </ofdpa10:vtap>
817 </port>
818 </resources>
819 <logical-switches>
820 <switch>
821 <id>DATAPATH_ID</id>
822 <datapath-id>DATAPATH_ID</datapath-id>
823 <resources>
824 <port xc:operation="OPERATION">LPORT</port>
825 </resources>
826 </switch>
827 </logical-switches>
828 </capable-switch>
829 </config>
830 """
831 else:
832 config_vtap_xml="""
833 <config>
834 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
835 <id>capable-switch-1</id>
836 <resources>
837 <port xc:operation="OPERATION">
838 <resource-id >LPORT</resource-id>
839 <features>
840 <current>
841 <rate>10Gb</rate>
842 <medium>fiber</medium>
843 <pause>symmetric</pause>
844 </current>
845 <advertised>
846 <rate>10Gb</rate>
847 <rate>100Gb</rate>
848 <medium>fiber</medium>
849 <pause>symmetric</pause>
850 </advertised>
851 <supported>
852 <rate>10Gb</rate>
853 <rate>100Gb</rate>
854 <medium>fiber</medium>
855 <pause>symmetric</pause>
856 </supported>
857 <advertised-peer>
858 <rate>10Gb</rate>
859 <rate>100Gb</rate>
860 <medium>fiber</medium>
861 <pause>symmetric</pause>
862 </advertised-peer>
863 </features>
864 <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
865 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
866 <ofdpa10:vni>VNID</ofdpa10:vni>
867 </ofdpa10:vtap>
868 </port>
869 </resources>
870 <logical-switches>
871 <switch>
872 <id>DATAPATH_ID</id>
873 <datapath-id>DATAPATH_ID</datapath-id>
874 <resources>
875 <port xc:operation="OPERATION">LPORT</port>
876 </resources>
877 </switch>
878 </logical-switches>
879 </capable-switch>
880 </config>
881 """
882 str_datapath_id_f= "{:016x}".format(dp_id)
883 str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
884 config_vtap_xml=config_vtap_xml.replace("DATAPATH_ID", str_datapath_id)
885 config_vtap_xml=config_vtap_xml.replace("LPORT", str(int(lport)))
886 config_vtap_xml=config_vtap_xml.replace("PHY_PORT", str(phy_port))
887 config_vtap_xml=config_vtap_xml.replace("VLAN_ID", str(vlan))
888 config_vtap_xml=config_vtap_xml.replace("VNID", str(vnid))
889 config_vtap_xml=config_vtap_xml.replace("OPERATION", str(operation))
890 return config_vtap_xml
891
892def get_vtep_lport_config_xml(dp_id, lport, src_ip, dst_ip, next_hop_id, vnid, udp_src_port=6633, ttl=25, operation='merge'):
893 """
894 Command Example:
895 of-agent vtep 10002 source user-input-src-ip destination user-input-dst-ip udp-source-port 6633 nexthop 2 ttl 25
896 of-agent vtp 10001 vni 10
897 """
898
899 config_vtep_xml="""
900 <config>
901 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
902 <id>capable-switch-1</id>
903 <resources>
904 <port xc:operation="OPERATION">
905 <resource-id>LPORT</resource-id>
906 <features>
907 <current>
908 <rate>10Gb</rate>
909 <medium>fiber</medium>
910 <pause>symmetric</pause>
911 </current>
912 <advertised>
913 <rate>10Gb</rate>
914 <rate>100Gb</rate>
915 <medium>fiber</medium>
916 <pause>symmetric</pause>
917 </advertised>
918 <supported>
919 <rate>10Gb</rate>
920 <rate>100Gb</rate>
921 <medium>fiber</medium>
922 <pause>symmetric</pause>
923 </supported>
924 <advertised-peer>
925 <rate>10Gb</rate>
926 <rate>100Gb</rate>
927 <medium>fiber</medium>
928 <pause>symmetric</pause>
929 </advertised-peer>
930 </features>
931 <ofdpa10:vtep xmlns:ofdpa10="urn:bcm:ofdpa10:accton01">
932 <ofdpa10:src-ip>SRC_IP</ofdpa10:src-ip>
933 <ofdpa10:dest-ip>DST_IP</ofdpa10:dest-ip>
934 <ofdpa10:udp-src-port>UDP_SRC_PORT</ofdpa10:udp-src-port>
935 <ofdpa10:vni xc:operation="OPERATION">
936 <ofdpa10:id>VNID</ofdpa10:id>
937 </ofdpa10:vni>
938 <ofdpa10:nexthop-id>NEXT_HOP_ID</ofdpa10:nexthop-id>
939 <ofdpa10:ttl>TTL</ofdpa10:ttl>
940 </ofdpa10:vtep>
941 </port>
942 </resources>
943 <logical-switches>
944 <switch>
945 <id>DATAPATH_ID</id>
946 <datapath-id>DATAPATH_ID</datapath-id>
947 <resources>
948 <port xc:operation="OPERATION">LPORT</port>
949 </resources>
950 </switch>
951 </logical-switches>
952 </capable-switch>
953 </config>
954 """
955 str_datapath_id_f= "{:016x}".format(dp_id)
956 str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
957 config_vtep_xml=config_vtep_xml.replace("DATAPATH_ID", str_datapath_id)
958 config_vtep_xml=config_vtep_xml.replace("LPORT", str(int(lport)))
959 config_vtep_xml=config_vtep_xml.replace("SRC_IP", str(src_ip))
960 config_vtep_xml=config_vtep_xml.replace("DST_IP", str(dst_ip))
961 config_vtep_xml=config_vtep_xml.replace("UDP_SRC_PORT", str(udp_src_port))
962 config_vtep_xml=config_vtep_xml.replace("NEXT_HOP_ID", str(next_hop_id))
963 config_vtep_xml=config_vtep_xml.replace("TTL", str(ttl))
964 config_vtep_xml=config_vtep_xml.replace("VNID", str(vnid))
965 config_vtep_xml=config_vtep_xml.replace("OPERATION", str(operation))
966
967 return config_vtep_xml
968
969def get_next_hop_config_xml(next_hop_id, dst_mac, phy_port, vlan, operation='merge'):
970 #of-agent nexthop 2 destination user-input-dst-mac ethernet 1/2 vid 2
971 config_nexthop_xml="""
972 <config>
973 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
974 <ofdpa10:next-hop xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
975 <ofdpa10:id>NEXT_HOP_ID</ofdpa10:id>
976 <ofdpa10:dest-mac>DST_MAC</ofdpa10:dest-mac>
977 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
978 <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
979 </ofdpa10:next-hop>
980 </of11-config:capable-switch>
981 </config>
982 """
983 config_nexthop_xml=config_nexthop_xml.replace("VLAN_ID", str(vlan))
984 config_nexthop_xml=config_nexthop_xml.replace("PHY_PORT", str(phy_port))
985 config_nexthop_xml=config_nexthop_xml.replace("NEXT_HOP_ID", str(next_hop_id))
986 config_nexthop_xml=config_nexthop_xml.replace("DST_MAC", str(dst_mac))
987 config_nexthop_xml=config_nexthop_xml.replace("OPERATION", str(operation))
988 return config_nexthop_xml
989
990def get_vni_config_xml(vni_id, mcast_ipv4, next_hop_id, operation='merge'):
991 #of-agent vni 10 multicast 224.1.1.1 nexthop 20
992 if mcast_ipv4!=None:
993 config_vni_xml="""
994 <config>
995 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
996 <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
997 <ofdpa10:id>VNID</ofdpa10:id>
998 <ofdpa10:vni-multicast-group>MCAST_IP</ofdpa10:vni-multicast-group>
999 <ofdpa10:multicast-group-nexthop-id>NEXT_HOP_ID</ofdpa10:multicast-group-nexthop-id>
1000 </ofdpa10:vni>
1001 </of11-config:capable-switch>
1002 </config>
1003 """
1004 config_vni_xml=config_vni_xml.replace("NEXT_HOP_ID", str(next_hop_id))
1005 config_vni_xml=config_vni_xml.replace("MCAST_IP", str(mcast_ipv4))
1006 else:
1007 config_vni_xml="""
1008 <config>
1009 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1010 <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1011 <ofdpa10:id>VNID</ofdpa10:id>
1012 </ofdpa10:vni>
1013 </of11-config:capable-switch>
1014 </config>
1015 """
1016
1017 config_vni_xml=config_vni_xml.replace("VNID", str(vni_id))
1018 config_vni_xml=config_vni_xml.replace("OPERATION", str(operation))
1019 return config_vni_xml
1020
1021def get_featureReplay(self):
1022 req = ofp.message.features_request()
1023 res, raw = self.controller.transact(req)
1024 self.assertIsNotNone(res, "Did not receive a response from the DUT.")
1025 self.assertEqual(res.type, ofp.OFPT_FEATURES_REPLY,
1026 ("Unexpected packet type %d received in response to "
1027 "OFPT_FEATURES_REQUEST") % res.type)
1028 return res
1029
1030def send_edit_config(switch_ip, xml, target='runing'):
1031 NETCONF_ACCOUNT="netconfuser"
1032 NETCONF_PASSWD="netconfuser"
1033 with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
1034 try:
1035 m.edit_config(target='running',
1036 config=xml,
1037 default_operation='merge',
1038 error_option='stop-on-error')
1039
1040 except Exception as e:
1041 logging.info("Fail to set xml %s", xml)
1042 return False
1043
1044 #return m.get_config(source='running').data_xml
1045 return True
1046
1047def send_delete_config(switch_ip, xml, target='runing'):
1048 NETCONF_ACCOUNT="netconfuser"
1049 NETCONF_PASSWD="netconfuser"
1050 with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
1051 try:
1052 m.edit_config(target='running',
1053 config=xml,
1054 default_operation='delete',
1055 error_option='stop-on-error')
1056
1057 except Exception as e:
1058 logging.info("Fail to set xml %s", xml)
1059 return False
1060
1061 #return m.get_config(source='running').data_xml
1062 return True
1063
1064def get_edit_config(switch_ip, target='runing'):
1065 NETCONF_ACCOUNT="netconfuser"
1066 NETCONF_PASSWD="netconfuser"
1067 with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
1068 return m.get_config(source='running').data_xml
1069
1070
1071"""
1072MPLS
1073"""
1074
1075OFDPA_MPLS_SUBTYPE_SHIFT=24
1076OFDPA_MPLS_GROUP_SUBTYPE_L2_VPN_LABEL=1
1077OFDPA_MPLS_GROUP_SUBTYPE_L3_VPN_LABEL=2
1078OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL1=3
1079OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL2=4
1080OFDPA_MPLS_GROUP_SUBTYPE_SWAP_LABEL=5
1081OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP=6
1082OFDPA_MPLS_GROUP_SUBTYPE_ECMP=8
1083OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG=10
1084
1085def encode_mpls_interface_group_id(subtype, index):
1086 index=index&0x00ffffff
1087 assert(subtype==0)
1088 return index + (9 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
1089
1090def encode_mpls_label_group_id(subtype, index):
1091 index=index&0x00ffffff
1092 assert(subtype <=5 or subtype==0)
1093 #1: l2 vpn label
1094 #2: l3 vpn label
1095 #3: mpls tunnel label 1
1096 #4: mpls tunnel lable 2
1097 #5: mpls swap label
1098 return index + (9 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
1099
1100def encode_mpls_forwarding_group_id(subtype, index):
1101 index=index&0x00ffffff
1102 assert(subtype==6 or subtype==8 or subtype==10)
1103 return index + (10 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
1104
1105
1106def add_mpls_intf_group(ctrl, ref_gid, dst_mac, src_mac, vid, index, subtype=0):
1107 action=[]
1108 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
1109 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
1110 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(vid)))
1111 action.append(ofp.action.group(ref_gid))
1112
1113 buckets = [ofp.bucket(actions=action)]
1114
1115 mpls_group_id =encode_mpls_interface_group_id(subtype, index)
1116 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
1117 group_id=mpls_group_id,
1118 buckets=buckets
1119 )
1120 ctrl.message_send(request)
1121 return mpls_group_id, request
1122
1123def add_mpls_label_group(ctrl, subtype, index, ref_gid,
1124 lmep_id=-1,
1125 qos_index=-1,
1126 push_l2_header=False,
1127 push_vlan=False,
1128 push_mpls_header=False,
1129 push_cw=False,
1130 set_mpls_label=None,
1131 set_bos=None,
1132 set_tc=None,
1133 set_tc_from_table=False,
1134 cpy_tc_outward=False,
1135 set_ttl=None,
1136 cpy_ttl_outward=False,
1137 oam_lm_tx_count=False,
1138 set_pri_from_table=False
1139 ):
1140 """
1141 @ref_gid: only can be mpls intf group or mpls tunnel label 1/2 group
1142 """
1143 action=[]
1144
1145 if push_vlan== True:
1146 action.append(ofp.action.push_vlan(0x8100))
1147 if push_mpls_header== True:
1148 action.append(ofp.action.push_mpls(0x8847))
1149 if set_mpls_label != None:
1150 action.append(ofp.action.set_field(ofp.oxm.mpls_label(set_mpls_label)))
1151 if set_bos != None:
1152 action.append(ofp.action.set_field(ofp.oxm.mpls_bos(set_bos)))
1153 if set_tc != None:
1154 assert(set_tc_from_table==False)
1155 action.append(ofp.action.set_field(ofp.oxm.mpls_tc(set_tc)))
1156 if set_ttl != None:
1157 action.append(ofp.action.set_mpls_ttl(set_ttl))
1158 if cpy_ttl_outward == True:
1159 action.append(ofp.action.copy_ttl_out())
1160 """
1161 ofdpa experimenter
1162 """
1163 if push_l2_header== True:
1164 action.append(ofp.action.ofdpa_push_l2_header())
1165 if set_tc_from_table== True:
1166 assert(qos_index>=0)
1167 assert(set_tc == None)
1168 action.append(ofp.action.ofdpa_set_tc_from_table(qos_index))
1169 if cpy_tc_outward == True:
1170 action.append(ofp.action.ofdpa_copy_tc_out())
1171 if oam_lm_tx_count == True:
1172 assert(qos_index>=0 and lmep_id>=0)
1173 action.append(ofp.action.ofdpa_oam_lm_tx_count(lmep_id, qos_index))
1174 if set_pri_from_table == True:
1175 assert(qos_index>=0)
1176 action.append(ofp.action.ofdpa_set_qos_from_table(qos_index))
1177 if push_cw == True:
1178 action.append(ofp.action.ofdpa_push_cw())
1179
1180 action.append(ofp.action.group(ref_gid))
1181 buckets = [ofp.bucket(actions=action)]
1182
1183 mpls_group_id = encode_mpls_label_group_id(subtype, index)
1184 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
1185 group_id=mpls_group_id,
1186 buckets=buckets
1187 )
1188 ctrl.message_send(request)
1189
1190 return mpls_group_id, request
1191
1192def add_mpls_forwarding_group(ctrl, subtype, index, ref_gids,
1193 watch_port=None,
1194 watch_group=ofp.OFPP_ANY,
1195 push_vlan=None,
1196 pop_vlan=None,
1197 set_vid=None):
1198 assert(subtype == OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP
1199 or subtype == OFDPA_MPLS_GROUP_SUBTYPE_ECMP
1200 or subtype == OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG)
1201
1202 buckets=[]
1203 if subtype == OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP:
1204 group_type = ofp.OFPGT_FF
1205 for gid in ref_gids:
1206 action=[]
1207 action.append(ofp.action.group(gid))
1208 buckets.append(ofp.bucket(watch_port=watch_port, watch_group=watch_group,actions=action))
1209
1210 elif subtype == OFDPA_MPLS_GROUP_SUBTYPE_ECMP:
1211 group_type = ofp.OFPGT_SELECT
1212 for gid in ref_gids:
1213 action=[]
1214 action.append(ofp.action.group(gid))
1215 buckets.append(ofp.bucket(actions=action))
1216
1217 elif subtype == OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG:
1218 group_type = ofp.OFPGT_INDIRECT
1219 action=[]
1220 if set_vid!=None:
1221 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(set_vid)))
1222 if push_vlan!=None:
1223 action.append(ofp.action.push_vlan(push_vlan))
1224 if pop_vlan!=None:
1225 action.append(ofp.action.pop_vlan())
1226 action.append(ofp.action.group(ref_gids[0]))
1227 buckets.append(ofp.bucket(actions=action))
1228
1229 mpls_group_id = encode_mpls_forwarding_group_id(subtype, index)
1230 request = ofp.message.group_add(group_type=group_type,
1231 group_id=mpls_group_id,
1232 buckets=buckets
1233 )
1234 ctrl.message_send(request)
1235 return mpls_group_id, request
1236
1237
1238"""
1239dislay
1240"""
1241def print_current_table_flow_stat(ctrl, table_id=0xff):
1242 stat_req=ofp.message.flow_stats_request()
1243 response, pkt = ctrl.transact(stat_req)
1244 if response == None:
1245 print "no response"
1246 return None
1247 print len(response.entries)
1248 for obj in response.entries:
1249 print "match ", obj.match
1250 print "cookie", obj.cookie
1251 print "priority", obj.priority
1252 print "idle_timeout", obj.idle_timeout
1253 print "hard_timeout", obj.hard_timeout
1254 #obj.actions
Flavio Castroe0b46012015-12-02 14:42:27 -05001255 print "packet count: %lx"%obj.packet_count