blob: 3a5af5a35b6b526174efdee90a559c7b99ea1736 [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
macauley7f89d962015-08-06 18:13:48 +080043def 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
macauley_cheng67da9262015-08-31 15:18:41 +080051
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)
macauleye8b140e2015-08-03 13:35:45 +080061
macauley_cheng67da9262015-08-31 15:18:41 +080062 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
macauley97557232015-07-16 17:28:07 +0800101def 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
macauleyfddc4662015-07-27 17:40:30 +0800125def 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)
macauley97557232015-07-16 17:28:07 +0800130
macauley97557232015-07-16 17:28:07 +0800131def 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
macauley41904ed2015-07-16 17:38:35 +0800134 group_id_list=[]
macauley15909e72015-07-17 15:58:57 +0800135 msgs=[]
macauley97557232015-07-16 17:28:07 +0800136 for of_port in ports:
137 # do stuff
138 group_id = encode_l2_interface_group_id(vlan_id, of_port)
macauley41904ed2015-07-16 17:38:35 +0800139 group_id_list.append(group_id)
macauley97557232015-07-16 17:28:07 +0800140 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)
macauley15909e72015-07-17 15:58:57 +0800159 msgs.append(request)
macauley97557232015-07-16 17:28:07 +0800160
161 if send_barrier:
162 do_barrier(ctrl)
macauley41904ed2015-07-16 17:38:35 +0800163
macauley15909e72015-07-17 15:58:57 +0800164 return group_id_list, msgs
macauley97557232015-07-16 17:28:07 +0800165
macauley0f91a3e2015-07-17 18:09:59 +0800166def add_one_l2_interface_grouop(ctrl, port, vlan_id=1, is_tagged=False, send_barrier=False):
167 # 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
macauley97557232015-07-16 17:28:07 +0800196def 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)
macauley15909e72015-07-17 15:58:57 +0800209 return request
macauley97557232015-07-16 17:28:07 +0800210
macauley15909e72015-07-17 15:58:57 +0800211def 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))
macauley97557232015-07-16 17:28:07 +0800217
macauley15909e72015-07-17 15:58:57 +0800218 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.group(group_id))
237
238 buckets = [ofp.bucket(actions=action)]
239
240 group_id =encode_l2_rewrite_group_id(id)
241 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
242 group_id=group_id,
243 buckets=buckets
244 )
245 ctrl.message_send(request)
246 return request
247
248def add_l3_unicast_group(ctrl, port, vlanid, id, src_mac, dst_mac):
249 group_id = encode_l2_interface_group_id(vlanid, port)
250
251 action=[]
252 if src_mac is not None:
253 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
254
255 if dst_mac is not None:
256 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
257
258 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(vlanid)))
259
260 action.append(ofp.action.group(group_id))
261
262 buckets = [ofp.bucket(actions=action)]
263
264 group_id =encode_l3_unicast_group_id(id)
265 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
266 group_id=group_id,
267 buckets=buckets
268 )
269 ctrl.message_send(request)
270 return request
271
272def add_l3_interface_group(ctrl, port, vlanid, id, src_mac):
273 group_id = encode_l2_interface_group_id(vlanid, port)
274
275 action=[]
276 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
277 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(vlanid)))
278 action.append(ofp.action.group(group_id))
279
280 buckets = [ofp.bucket(actions=action)]
281
282 group_id =encode_l3_interface_group_id(id)
283 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
284 group_id=group_id,
285 buckets=buckets
286 )
287 ctrl.message_send(request)
288 return request
289
290def add_l3_ecmp_group(ctrl, id, l3_ucast_groups):
291 buckets=[]
292 for group in l3_ucast_groups:
293 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
294
295 group_id =encode_l3_ecmp_group_id(id)
296 request = ofp.message.group_add(group_type=ofp.OFPGT_SELECT,
297 group_id=group_id,
298 buckets=buckets
299 )
300 ctrl.message_send(request)
301 return request
302
303def add_l3_mcast_group(ctrl, vid, mcast_group_id, groups_on_buckets):
304 buckets=[]
305 for group in groups_on_buckets:
306 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
307
308 group_id =encode_l3_mcast_group_id(vid, mcast_group_id)
309 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
310 group_id=group_id,
311 buckets=buckets
312 )
313 ctrl.message_send(request)
314 return request
macauleyfddc4662015-07-27 17:40:30 +0800315
316def add_l2_overlay_flood_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
317 buckets=[]
318 for port in ports:
319 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
320
321 group_id=encode_l2_overlay_group_id(tunnel_id, 0, index)
322 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
323 group_id=group_id,
324 buckets=buckets
325 )
326 ctrl.message_send(request)
327 return request
328
329def add_l2_overlay_flood_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
330 buckets=[]
331 for port in ports:
332 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
333
334 group_id=encode_l2_overlay_group_id(tunnel_id, 1, index)
335 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
336 group_id=group_id,
337 buckets=buckets
338 )
339 ctrl.message_send(request)
340 return request
341
342def add_l2_overlay_mcast_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
343 buckets=[]
344 for port in ports:
345 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
346
347 group_id=encode_l2_overlay_group_id(tunnel_id, 2, index)
348 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
349 group_id=group_id,
350 buckets=buckets
351 )
352 ctrl.message_send(request)
353 return request
354
355def add_l2_overlay_mcast_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
356 buckets=[]
357 for port in ports:
358 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
359
360 group_id=encode_l2_overlay_group_id(tunnel_id, 3, index)
361 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
362 group_id=group_id,
363 buckets=buckets
364 )
365 ctrl.message_send(request)
366 return request
367
368def add_port_table_flow(ctrl, is_overlay=True):
369 match = ofp.match()
370
371 if is_overlay == True:
372 match.oxm_list.append(ofp.oxm.in_port(0x10000))
macauleydbff3272015-07-30 14:07:16 +0800373 NEXT_TABLE=50
macauleyfddc4662015-07-27 17:40:30 +0800374 else:
375 match.oxm_list.append(ofp.oxm.in_port(0))
macauleydbff3272015-07-30 14:07:16 +0800376 NEXT_TABLE=10
macauleyfddc4662015-07-27 17:40:30 +0800377
378 request = ofp.message.flow_add(
379 table_id=0,
380 cookie=42,
381 match=match,
382 instructions=[
macauleydbff3272015-07-30 14:07:16 +0800383 ofp.instruction.goto_table(NEXT_TABLE)
macauleyfddc4662015-07-27 17:40:30 +0800384 ],
385 priority=0)
386 logging.info("Add port table, match port %lx" % 0x10000)
387 ctrl.message_send(request)
macauleydbff3272015-07-30 14:07:16 +0800388
389
macauleyfddc4662015-07-27 17:40:30 +0800390
macauley97557232015-07-16 17:28:07 +0800391def add_vlan_table_flow(ctrl, ports, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
392 # table 10: vlan
393 # goto to table 20
macauley15909e72015-07-17 15:58:57 +0800394 msgs=[]
macauley97557232015-07-16 17:28:07 +0800395 for of_port in ports:
396 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
397 match = ofp.match()
398 match.oxm_list.append(ofp.oxm.in_port(of_port))
399 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
400 request = ofp.message.flow_add(
401 table_id=10,
402 cookie=42,
403 match=match,
404 instructions=[
405 ofp.instruction.goto_table(20)
406 ],
407 priority=0)
408 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
409 ctrl.message_send(request)
410
411 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
412 match = ofp.match()
413 match.oxm_list.append(ofp.oxm.in_port(of_port))
414 match.oxm_list.append(ofp.oxm.vlan_vid(0))
415 request = ofp.message.flow_add(
416 table_id=10,
417 cookie=42,
418 match=match,
419 instructions=[
420 ofp.instruction.apply_actions(
421 actions=[
422 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id))
423 ]
424 ),
425 ofp.instruction.goto_table(20)
426 ],
427 priority=0)
428 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
429 ctrl.message_send(request)
macauley15909e72015-07-17 15:58:57 +0800430 msgs.append(request)
macauley97557232015-07-16 17:28:07 +0800431
432 if send_barrier:
433 do_barrier(ctrl)
434
macauley15909e72015-07-17 15:58:57 +0800435 return msgs
macauley0f91a3e2015-07-17 18:09:59 +0800436
macauley53d90fe2015-08-04 17:34:22 +0800437def 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 +0800438 # table 10: vlan
439 # goto to table 20
440 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
441 match = ofp.match()
442 match.oxm_list.append(ofp.oxm.in_port(of_port))
443 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
macauley7f89d962015-08-06 18:13:48 +0800444
445 actions=[]
446 if vrf!=0:
447 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
448
449 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(value=vlan_id)))
450
macauley0f91a3e2015-07-17 18:09:59 +0800451 request = ofp.message.flow_add(
452 table_id=10,
453 cookie=42,
454 match=match,
455 instructions=[
macauley53d90fe2015-08-04 17:34:22 +0800456 ofp.instruction.apply_actions(
macauley7f89d962015-08-06 18:13:48 +0800457 actions=actions
macauley53d90fe2015-08-04 17:34:22 +0800458 ),
459 ofp.instruction.goto_table(20)
macauley0f91a3e2015-07-17 18:09:59 +0800460 ],
461 priority=0)
462 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
463 ctrl.message_send(request)
464
465 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
466 match = ofp.match()
467 match.oxm_list.append(ofp.oxm.in_port(of_port))
468 match.oxm_list.append(ofp.oxm.vlan_vid(0))
macauley53d90fe2015-08-04 17:34:22 +0800469
macauley7f89d962015-08-06 18:13:48 +0800470 actions=[]
471 if vrf!=0:
472 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
473
474 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
475
macauley0f91a3e2015-07-17 18:09:59 +0800476 request = ofp.message.flow_add(
477 table_id=10,
478 cookie=42,
479 match=match,
480 instructions=[
481 ofp.instruction.apply_actions(
macauley7f89d962015-08-06 18:13:48 +0800482 actions=actions
macauley0f91a3e2015-07-17 18:09:59 +0800483 ),
484 ofp.instruction.goto_table(20)
485 ],
486 priority=0)
487 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
488 ctrl.message_send(request)
489
490 if send_barrier:
491 do_barrier(ctrl)
492
493 return request
macauley15909e72015-07-17 15:58:57 +0800494
macauley97557232015-07-16 17:28:07 +0800495def add_bridge_flow(ctrl, dst_mac, vlanid, group_id, send_barrier=False):
496 match = ofp.match()
macauleyfddc4662015-07-27 17:40:30 +0800497 if dst_mac!=None:
498 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
499
macauley97557232015-07-16 17:28:07 +0800500 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
macauleyfddc4662015-07-27 17:40:30 +0800501
macauley97557232015-07-16 17:28:07 +0800502 request = ofp.message.flow_add(
503 table_id=50,
504 cookie=42,
505 match=match,
506 instructions=[
507 ofp.instruction.write_actions(
508 actions=[
509 ofp.action.group(group_id)]),
510 ofp.instruction.goto_table(60)
511 ],
512 buffer_id=ofp.OFP_NO_BUFFER,
513 priority=1000)
514
515 logging.info("Inserting Brdige flow vlan %d, mac %s", vlanid, dst_mac)
516 ctrl.message_send(request)
517
518 if send_barrier:
macauley15909e72015-07-17 15:58:57 +0800519 do_barrier(ctrl)
520
macauley0f91a3e2015-07-17 18:09:59 +0800521 return request
macauleyfddc4662015-07-27 17:40:30 +0800522
523def add_overlay_bridge_flow(ctrl, dst_mac, vnid, group_id, is_group=True, send_barrier=False):
524 match = ofp.match()
525 if dst_mac!=None:
526 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
527
528 match.oxm_list.append(ofp.oxm.tunnel_id(vnid))
529 if is_group == True:
530 actions=[ofp.action.group(group_id)]
531 else:
532 actions=[ofp.action.output(group_id)]
533
534 request = ofp.message.flow_add(
535 table_id=50,
536 cookie=42,
537 match=match,
538 instructions=[
539 ofp.instruction.write_actions(
540 actions=actions),
541 ofp.instruction.goto_table(60)
542 ],
543 buffer_id=ofp.OFP_NO_BUFFER,
544 priority=1000)
545
546 logging.info("Inserting Brdige flow vnid %d, mac %s", vnid, dst_mac)
547 ctrl.message_send(request)
548
549 if send_barrier:
550 do_barrier(ctrl)
551
552 return request
macauley0f91a3e2015-07-17 18:09:59 +0800553
554def add_termination_flow(ctrl, in_port, eth_type, dst_mac, vlanid, send_barrier=False):
555 match = ofp.match()
macauley0f91a3e2015-07-17 18:09:59 +0800556 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
macauleyfddc4662015-07-27 17:40:30 +0800557 if dst_mac[0]&0x01 == 0x01:
558 match.oxm_list.append(ofp.oxm.eth_dst_masked(dst_mac, [0xff, 0xff, 0xff, 0x80, 0x00, 0x00]))
559 goto_table=40
560 else:
macauley53d90fe2015-08-04 17:34:22 +0800561 if in_port!=0:
562 match.oxm_list.append(ofp.oxm.in_port(in_port))
macauleyfddc4662015-07-27 17:40:30 +0800563 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
564 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
565 goto_table=30
macauley0f91a3e2015-07-17 18:09:59 +0800566
567 request = ofp.message.flow_add(
568 table_id=20,
569 cookie=42,
570 match=match,
571 instructions=[
572 ofp.instruction.goto_table(goto_table)
573 ],
574 buffer_id=ofp.OFP_NO_BUFFER,
575 priority=1)
576
577 logging.info("Inserting termination flow inport %d, eth_type %lx, vlan %d, mac %s", in_port, eth_type, vlanid, dst_mac)
578 ctrl.message_send(request)
579
580 if send_barrier:
581 do_barrier(ctrl)
582
583 return request
584
macauley53d90fe2015-08-04 17:34:22 +0800585def add_unicast_routing_flow(ctrl, eth_type, dst_ip, mask, action_group_id, vrf=0, send_barrier=False):
macauley0f91a3e2015-07-17 18:09:59 +0800586 match = ofp.match()
587 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
macauley53d90fe2015-08-04 17:34:22 +0800588 if vrf != 0:
589 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_VRF, vrf))
590
macauleyf8b1acd2015-07-23 15:13:13 +0800591 if mask!=0:
592 match.oxm_list.append(ofp.oxm.ipv4_dst_masked(dst_ip, mask))
593 else:
594 match.oxm_list.append(ofp.oxm.ipv4_dst(dst_ip))
macauley0f91a3e2015-07-17 18:09:59 +0800595
macauley53d90fe2015-08-04 17:34:22 +0800596
macauley0f91a3e2015-07-17 18:09:59 +0800597 request = ofp.message.flow_add(
598 table_id=30,
599 cookie=42,
600 match=match,
601 instructions=[
602 ofp.instruction.write_actions(
603 actions=[ofp.action.group(action_group_id)]),
604 ofp.instruction.goto_table(60)
605 ],
606 buffer_id=ofp.OFP_NO_BUFFER,
607 priority=1)
608
609 logging.info("Inserting unicast routing flow eth_type %lx, dip %ld",eth_type, dst_ip)
610 ctrl.message_send(request)
611
612 if send_barrier:
613 do_barrier(ctrl)
614
macauleyfddc4662015-07-27 17:40:30 +0800615 return request
616
617def add_mcast4_routing_flow(ctrl, vlan_id, src_ip, src_ip_mask, dst_ip, action_group_id, send_barrier=False):
618 match = ofp.match()
619 match.oxm_list.append(ofp.oxm.eth_type(0x0800))
620 match.oxm_list.append(ofp.oxm.vlan_vid(vlan_id))
621 if src_ip_mask!=0:
622 match.oxm_list.append(ofp.oxm.ipv4_src_masked(src_ip, src_ip_mask))
623 else:
624 match.oxm_list.append(ofp.oxm.ipv4_src(src_ip))
625
626 match.oxm_list.append(ofp.oxm.ipv4_dst(dst_ip))
627
628 request = ofp.message.flow_add(
629 table_id=40,
630 cookie=42,
631 match=match,
632 instructions=[
633 ofp.instruction.write_actions(
634 actions=[ofp.action.group(action_group_id)]),
635 ofp.instruction.goto_table(60)
636 ],
637 buffer_id=ofp.OFP_NO_BUFFER,
638 priority=1)
639
640 logging.info("Inserting mcast routing flow eth_type %lx, dip %lx, sip %lx, sip_mask %lx",0x0800, dst_ip, src_ip, src_ip_mask)
641 ctrl.message_send(request)
642
643 if send_barrier:
644 do_barrier(ctrl)
645
646 return request
647
648def get_vtap_lport_config_xml(dp_id, lport, phy_port, vlan, vnid, operation='merge'):
649 """
650 Command Example:
651 of-agent vtap 10001 ethernet 1/1 vid 1
652 of-agent vtp 10001 vni 10
653 """
654 if vlan != 0:
655 config_vtap_xml="""
656 <config>
657 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
658 <id>capable-switch-1</id>
659 <resources>
660 <port xc:operation="OPERATION">
661 <resource-id >LPORT</resource-id>
662 <features>
663 <current>
664 <rate>10Gb</rate>
665 <medium>fiber</medium>
666 <pause>symmetric</pause>
667 </current>
668 <advertised>
669 <rate>10Gb</rate>
670 <rate>100Gb</rate>
671 <medium>fiber</medium>
672 <pause>symmetric</pause>
673 </advertised>
674 <supported>
675 <rate>10Gb</rate>
676 <rate>100Gb</rate>
677 <medium>fiber</medium>
678 <pause>symmetric</pause>
679 </supported>
680 <advertised-peer>
681 <rate>10Gb</rate>
682 <rate>100Gb</rate>
683 <medium>fiber</medium>
684 <pause>symmetric</pause>
685 </advertised-peer>
686 </features>
687 <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
688 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
689 <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
690 <ofdpa10:vni>VNID</ofdpa10:vni>
691 </ofdpa10:vtap>
692 </port>
693 </resources>
694 <logical-switches>
695 <switch>
696 <id>DATAPATH_ID</id>
697 <datapath-id>DATAPATH_ID</datapath-id>
698 <resources>
699 <port xc:operation="OPERATION">LPORT</port>
700 </resources>
701 </switch>
702 </logical-switches>
703 </capable-switch>
704 </config>
705 """
706 else:
707 config_vtap_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:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
740 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
741 <ofdpa10:vni>VNID</ofdpa10:vni>
742 </ofdpa10:vtap>
743 </port>
744 </resources>
745 <logical-switches>
746 <switch>
747 <id>DATAPATH_ID</id>
748 <datapath-id>DATAPATH_ID</datapath-id>
749 <resources>
750 <port xc:operation="OPERATION">LPORT</port>
751 </resources>
752 </switch>
753 </logical-switches>
754 </capable-switch>
755 </config>
756 """
757 str_datapath_id_f= "{:016x}".format(dp_id)
758 str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
759 config_vtap_xml=config_vtap_xml.replace("DATAPATH_ID", str_datapath_id)
macauley25999cf2015-08-07 17:03:24 +0800760 config_vtap_xml=config_vtap_xml.replace("LPORT", str(int(lport)))
macauleyfddc4662015-07-27 17:40:30 +0800761 config_vtap_xml=config_vtap_xml.replace("PHY_PORT", str(phy_port))
762 config_vtap_xml=config_vtap_xml.replace("VLAN_ID", str(vlan))
763 config_vtap_xml=config_vtap_xml.replace("VNID", str(vnid))
764 config_vtap_xml=config_vtap_xml.replace("OPERATION", str(operation))
765 return config_vtap_xml
766
767def get_vtep_lport_config_xml(dp_id, lport, src_ip, dst_ip, next_hop_id, vnid, udp_src_port=6633, ttl=25, operation='merge'):
768 """
769 Command Example:
770 of-agent vtep 10002 source user-input-src-ip destination user-input-dst-ip udp-source-port 6633 nexthop 2 ttl 25
771 of-agent vtp 10001 vni 10
772 """
773
774 config_vtep_xml="""
775 <config>
776 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
777 <id>capable-switch-1</id>
778 <resources>
779 <port xc:operation="OPERATION">
780 <resource-id>LPORT</resource-id>
781 <features>
782 <current>
783 <rate>10Gb</rate>
784 <medium>fiber</medium>
785 <pause>symmetric</pause>
786 </current>
787 <advertised>
788 <rate>10Gb</rate>
789 <rate>100Gb</rate>
790 <medium>fiber</medium>
791 <pause>symmetric</pause>
792 </advertised>
793 <supported>
794 <rate>10Gb</rate>
795 <rate>100Gb</rate>
796 <medium>fiber</medium>
797 <pause>symmetric</pause>
798 </supported>
799 <advertised-peer>
800 <rate>10Gb</rate>
801 <rate>100Gb</rate>
802 <medium>fiber</medium>
803 <pause>symmetric</pause>
804 </advertised-peer>
805 </features>
806 <ofdpa10:vtep xmlns:ofdpa10="urn:bcm:ofdpa10:accton01">
807 <ofdpa10:src-ip>SRC_IP</ofdpa10:src-ip>
808 <ofdpa10:dest-ip>DST_IP</ofdpa10:dest-ip>
809 <ofdpa10:udp-src-port>UDP_SRC_PORT</ofdpa10:udp-src-port>
macauley25999cf2015-08-07 17:03:24 +0800810 <ofdpa10:vni xc:operation="OPERATION">
811 <ofdpa10:id>VNID</ofdpa10:id>
812 </ofdpa10:vni>
macauleyfddc4662015-07-27 17:40:30 +0800813 <ofdpa10:nexthop-id>NEXT_HOP_ID</ofdpa10:nexthop-id>
814 <ofdpa10:ttl>TTL</ofdpa10:ttl>
815 </ofdpa10:vtep>
816 </port>
817 </resources>
818 <logical-switches>
819 <switch>
820 <id>DATAPATH_ID</id>
821 <datapath-id>DATAPATH_ID</datapath-id>
822 <resources>
823 <port xc:operation="OPERATION">LPORT</port>
824 </resources>
825 </switch>
826 </logical-switches>
827 </capable-switch>
828 </config>
829 """
830 str_datapath_id_f= "{:016x}".format(dp_id)
831 str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
832 config_vtep_xml=config_vtep_xml.replace("DATAPATH_ID", str_datapath_id)
macauley25999cf2015-08-07 17:03:24 +0800833 config_vtep_xml=config_vtep_xml.replace("LPORT", str(int(lport)))
macauleyfddc4662015-07-27 17:40:30 +0800834 config_vtep_xml=config_vtep_xml.replace("SRC_IP", str(src_ip))
835 config_vtep_xml=config_vtep_xml.replace("DST_IP", str(dst_ip))
836 config_vtep_xml=config_vtep_xml.replace("UDP_SRC_PORT", str(udp_src_port))
837 config_vtep_xml=config_vtep_xml.replace("NEXT_HOP_ID", str(next_hop_id))
838 config_vtep_xml=config_vtep_xml.replace("TTL", str(ttl))
839 config_vtep_xml=config_vtep_xml.replace("VNID", str(vnid))
840 config_vtep_xml=config_vtep_xml.replace("OPERATION", str(operation))
841
842 return config_vtep_xml
843
844def get_next_hop_config_xml(next_hop_id, dst_mac, phy_port, vlan, operation='merge'):
845 #of-agent nexthop 2 destination user-input-dst-mac ethernet 1/2 vid 2
846 config_nexthop_xml="""
847 <config>
848 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
849 <ofdpa10:next-hop xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
850 <ofdpa10:id>NEXT_HOP_ID</ofdpa10:id>
851 <ofdpa10:dest-mac>DST_MAC</ofdpa10:dest-mac>
852 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
853 <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
854 </ofdpa10:next-hop>
855 </of11-config:capable-switch>
856 </config>
857 """
858 config_nexthop_xml=config_nexthop_xml.replace("VLAN_ID", str(vlan))
859 config_nexthop_xml=config_nexthop_xml.replace("PHY_PORT", str(phy_port))
860 config_nexthop_xml=config_nexthop_xml.replace("NEXT_HOP_ID", str(next_hop_id))
861 config_nexthop_xml=config_nexthop_xml.replace("DST_MAC", str(dst_mac))
862 config_nexthop_xml=config_nexthop_xml.replace("OPERATION", str(operation))
863 return config_nexthop_xml
864
865def get_vni_config_xml(vni_id, mcast_ipv4, next_hop_id, operation='merge'):
866 #of-agent vni 10 multicast 224.1.1.1 nexthop 20
867 if mcast_ipv4!=None:
868 config_vni_xml="""
869 <config>
870 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
871 <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
872 <ofdpa10:id>VNID</ofdpa10:id>
873 <ofdpa10:vni-multicast-group>MCAST_IP</ofdpa10:vni-multicast-group>
874 <ofdpa10:multicast-group-nexthop-id>NEXT_HOP_ID</ofdpa10:multicast-group-nexthop-id>
875 </ofdpa10:vni>
876 </of11-config:capable-switch>
877 </config>
878 """
879 config_vni_xml=config_vni_xml.replace("NEXT_HOP_ID", str(next_hop_id))
880 config_vni_xml=config_vni_xml.replace("MCAST_IP", str(mcast_ipv4))
881 else:
882 config_vni_xml="""
883 <config>
884 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
885 <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
886 <ofdpa10:id>VNID</ofdpa10:id>
887 </ofdpa10:vni>
888 </of11-config:capable-switch>
889 </config>
890 """
891
892 config_vni_xml=config_vni_xml.replace("VNID", str(vni_id))
893 config_vni_xml=config_vni_xml.replace("OPERATION", str(operation))
894 return config_vni_xml
895
896def get_featureReplay(self):
897 req = ofp.message.features_request()
898 res, raw = self.controller.transact(req)
899 self.assertIsNotNone(res, "Did not receive a response from the DUT.")
900 self.assertEqual(res.type, ofp.OFPT_FEATURES_REPLY,
901 ("Unexpected packet type %d received in response to "
902 "OFPT_FEATURES_REQUEST") % res.type)
903 return res
904
905def send_edit_config(switch_ip, xml, target='runing'):
906 NETCONF_ACCOUNT="netconfuser"
907 NETCONF_PASSWD="netconfuser"
908 with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
909 try:
910 m.edit_config(target='running',
911 config=xml,
912 default_operation='merge',
913 error_option='stop-on-error')
914
915 except Exception as e:
916 logging.info("Fail to set xml %s", xml)
917 return False
918
919 #return m.get_config(source='running').data_xml
920 return True
921
922def send_delete_config(switch_ip, xml, target='runing'):
923 NETCONF_ACCOUNT="netconfuser"
924 NETCONF_PASSWD="netconfuser"
925 with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
926 try:
927 m.edit_config(target='running',
928 config=xml,
929 default_operation='delete',
930 error_option='stop-on-error')
931
932 except Exception as e:
933 logging.info("Fail to set xml %s", xml)
934 return False
935
936 #return m.get_config(source='running').data_xml
937 return True
938
939def get_edit_config(switch_ip, target='runing'):
940 NETCONF_ACCOUNT="netconfuser"
941 NETCONF_PASSWD="netconfuser"
942 with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
macauley6f6ceb22015-08-07 09:37:12 +0800943 return m.get_config(source='running').data_xml
macauleydbff3272015-07-30 14:07:16 +0800944
macauley_cheng67da9262015-08-31 15:18:41 +0800945
946"""
947MPLS
948"""
949
950OFDPA_MPLS_SUBTYPE_SHIFT=24
951OFDPA_MPLS_GROUP_SUBTYPE_L2_VPN_LABEL=1
952OFDPA_MPLS_GROUP_SUBTYPE_L3_VPN_LABEL=2
953OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL1=3
954OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL2=4
955OFDPA_MPLS_GROUP_SUBTYPE_SWAP_LABEL=5
956OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP=6
957OFDPA_MPLS_GROUP_SUBTYPE_ECMP=8
958OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG=10
959
960def encode_mpls_interface_group_id(subtype, index):
961 index=index&0x00ffffff
962 assert(subtype==0)
963 return index + (9 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
964
965def encode_mpls_label_group_id(subtype, index):
966 index=index&0x00ffffff
967 assert(subtype <=5 or subtype==0)
968 #1: l2 vpn label
969 #2: l3 vpn label
970 #3: mpls tunnel label 1
971 #4: mpls tunnel lable 2
972 #5: mpls swap label
973 return index + (9 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
974
975def encode_mpls_forwarding_group_id(subtype, index):
976 index=index&0x00ffffff
977 assert(subtype==6 or subtype==8 or subtype==10)
978 return index + (10 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
979
980
981def add_mpls_intf_group(ctrl, ref_gid, dst_mac, src_mac, vid, index, subtype=0):
982 action=[]
983 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
984 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
985 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(vid)))
986 action.append(ofp.action.group(ref_gid))
987
988 buckets = [ofp.bucket(actions=action)]
989
990 mpls_group_id =encode_mpls_interface_group_id(subtype, index)
991 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
992 group_id=mpls_group_id,
993 buckets=buckets
994 )
995 ctrl.message_send(request)
996 return mpls_group_id, request
997
998def add_mpls_label_group(ctrl, subtype, index, ref_gid,
999 lmep_id=-1,
1000 qos_index=-1,
1001 push_l2_header=False,
1002 push_vlan=False,
1003 push_mpls_header=False,
1004 push_cw=False,
1005 set_mpls_label=None,
1006 set_bos=None,
1007 set_tc=None,
1008 set_tc_from_table=False,
1009 cpy_tc_outward=False,
1010 set_ttl=None,
1011 cpy_ttl_outward=False,
1012 oam_lm_tx_count=False,
1013 set_pri_from_table=False
1014 ):
1015 """
1016 @ref_gid: only can be mpls intf group or mpls tunnel label 1/2 group
1017 """
1018 action=[]
1019
1020 if push_vlan== True:
1021 action.append(ofp.action.push_vlan(0x8100))
1022 if push_mpls_header== True:
1023 action.append(ofp.action.push_mpls(0x8847))
1024 if set_mpls_label != None:
1025 action.append(ofp.action.set_field(ofp.oxm.mpls_label(set_mpls_label)))
1026 if set_bos != None:
1027 action.append(ofp.action.set_field(ofp.oxm.mpls_bos(set_bos)))
1028 if set_tc != None:
1029 assert(set_tc_from_table==False)
1030 action.append(ofp.action.set_field(ofp.oxm.mpls_tc(set_tc)))
1031 if set_ttl != None:
1032 action.append(ofp.action.set_mpls_ttl(set_ttl))
1033 if cpy_ttl_outward == True:
1034 action.append(ofp.action.copy_ttl_out())
1035 """
1036 ofdpa experimenter
1037 """
1038 if push_l2_header== True:
1039 action.append(ofp.action.ofdpa_push_l2_header())
1040 if set_tc_from_table== True:
1041 assert(qos_index>=0)
1042 assert(set_tc == None)
1043 action.append(ofp.action.ofdpa_set_tc_from_table(qos_index))
1044 if cpy_tc_outward == True:
1045 action.append(ofp.action.ofdpa_copy_tc_out())
1046 if oam_lm_tx_count == True:
1047 assert(qos_index>=0 and lmep_id>=0)
1048 action.append(ofp.action.ofdpa_oam_lm_tx_count(lmep_id, qos_index))
1049 if set_pri_from_table == True:
1050 assert(qos_index>=0)
1051 action.append(ofp.action.ofdpa_set_qos_from_table(qos_index))
1052 if push_cw == True:
1053 action.append(ofp.action.ofdpa_push_cw())
1054
1055 action.append(ofp.action.group(ref_gid))
1056 buckets = [ofp.bucket(actions=action)]
1057
1058 mpls_group_id = encode_mpls_label_group_id(subtype, index)
1059 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
1060 group_id=mpls_group_id,
1061 buckets=buckets
1062 )
1063 ctrl.message_send(request)
1064
1065 return mpls_group_id, request
1066
1067def add_mpls_forwarding_group(ctrl, subtype, index, ref_gids,
1068 watch_port=None,
macauley_chengd17ce512015-08-31 17:45:51 +08001069 watch_group=ofp.OFPP_ANY,
macauley_cheng67da9262015-08-31 15:18:41 +08001070 push_vlan=None,
macauley_chengd17ce512015-08-31 17:45:51 +08001071 pop_vlan=None,
macauley_cheng67da9262015-08-31 15:18:41 +08001072 set_vid=None):
1073 assert(subtype == OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP
1074 or subtype == OFDPA_MPLS_GROUP_SUBTYPE_ECMP
1075 or subtype == OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG)
macauley_chengd17ce512015-08-31 17:45:51 +08001076
macauley_cheng67da9262015-08-31 15:18:41 +08001077 buckets=[]
1078 if subtype == OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP:
macauley_chengd17ce512015-08-31 17:45:51 +08001079 group_type = ofp.OFPGT_FF
macauley_cheng67da9262015-08-31 15:18:41 +08001080 for gid in ref_gids:
macauley_chengd17ce512015-08-31 17:45:51 +08001081 action=[]
1082 action.append(ofp.action.group(gid))
1083 buckets.append(ofp.bucket(watch_port=watch_port, watch_group=watch_group,actions=action))
1084
macauley_cheng67da9262015-08-31 15:18:41 +08001085 elif subtype == OFDPA_MPLS_GROUP_SUBTYPE_ECMP:
1086 group_type = ofp.OFPGT_SELECT
1087 for gid in ref_gids:
macauley_chengd17ce512015-08-31 17:45:51 +08001088 action=[]
macauley_cheng67da9262015-08-31 15:18:41 +08001089 action.append(ofp.action.group(gid))
1090 buckets.append(ofp.bucket(actions=action))
macauley_chengd17ce512015-08-31 17:45:51 +08001091
macauley_cheng67da9262015-08-31 15:18:41 +08001092 elif subtype == OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG:
1093 group_type = ofp.OFPGT_INDIRECT
macauley_chengd17ce512015-08-31 17:45:51 +08001094 action=[]
macauley_cheng67da9262015-08-31 15:18:41 +08001095 if set_vid!=None:
1096 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(set_vid)))
1097 if push_vlan!=None:
1098 action.append(ofp.action.push_vlan(push_vlan))
1099 if pop_vlan!=None:
macauley_chengd17ce512015-08-31 17:45:51 +08001100 action.append(ofp.action.pop_vlan())
macauley_cheng67da9262015-08-31 15:18:41 +08001101 action.append(ofp.action.group(ref_gids[0]))
1102 buckets.append(ofp.bucket(actions=action))
macauley_chengd17ce512015-08-31 17:45:51 +08001103
1104 mpls_group_id = encode_mpls_forwarding_group_id(subtype, index)
macauley_cheng67da9262015-08-31 15:18:41 +08001105 request = ofp.message.group_add(group_type=group_type,
macauley_cheng67da9262015-08-31 15:18:41 +08001106 group_id=mpls_group_id,
1107 buckets=buckets
1108 )
1109 ctrl.message_send(request)
1110 return mpls_group_id, request
macauley_chengd17ce512015-08-31 17:45:51 +08001111
1112
macauley_cheng67da9262015-08-31 15:18:41 +08001113"""
1114dislay
1115"""
macauleydbff3272015-07-30 14:07:16 +08001116def print_current_table_flow_stat(ctrl, table_id=0xff):
1117 stat_req=ofp.message.flow_stats_request()
1118 response, pkt = ctrl.transact(stat_req)
1119 if response == None:
1120 print "no response"
1121 return None
1122 print len(response.entries)
1123 for obj in response.entries:
1124 print "match ", obj.match
1125 print "cookie", obj.cookie
1126 print "priority", obj.priority
1127 print "idle_timeout", obj.idle_timeout
1128 print "hard_timeout", obj.hard_timeout
1129 #obj.actions
1130 print "packet count: %lx"%obj.packet_count