blob: 39d41fb9e2f2aadc2586334147f4180025d5e33b [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
Flavio Castro91d1a552016-05-17 16:59:44 -0700125def encode_l2_unfiltered_group_id(id):
126 return id + (11 << OFDPA_GROUP_TYPE_SHIFT)
127
macauleyfddc4662015-07-27 17:40:30 +0800128def encode_l2_overlay_group_id(tunnel_id, subtype, index):
129 tunnel_id=tunnel_id&0xffff #16 bits
130 subtype = subtype&3 #2 bits
131 index = index & 0x3f #10 bits
132 return index + (tunnel_id << OFDPA_TUNNEL_ID_SHIFT)+ (subtype<<OFDPA_TUNNEL_SUBTYPE_SHIFT)+(8 << OFDPA_GROUP_TYPE_SHIFT)
macauley97557232015-07-16 17:28:07 +0800133
Flavio Castro91d1a552016-05-17 16:59:44 -0700134def add_l2_unfiltered_group(ctrl, ports, send_barrier=False):
135 # group table
136 # set up untag groups for each port
137 group_id_list=[]
138 msgs=[]
139 for of_port in ports:
140 # do stuff
141 group_id = encode_l2_unfiltered_group_id(of_port)
142 group_id_list.append(group_id)
143 actions = [ofp.action.output(of_port)]
144 actions.append(ofp.action.set_field(ofp.oxm.exp1ByteValue(exp_type=24, value=1)))
145
146 buckets = [ofp.bucket(actions=actions)]
147 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
148 group_id=group_id,
149 buckets=buckets
150 )
151 ctrl.message_send(request)
152 msgs.append(request)
153
154 if send_barrier:
155 do_barrier(ctrl)
156
157 return group_id_list, msgs
158
Flavio Castrod4c44d12015-12-08 14:44:18 -0500159def add_l2_interface_group(ctrl, ports, vlan_id=1, is_tagged=False, send_barrier=False):
macauley97557232015-07-16 17:28:07 +0800160 # group table
161 # set up untag groups for each port
macauley41904ed2015-07-16 17:38:35 +0800162 group_id_list=[]
macauley15909e72015-07-17 15:58:57 +0800163 msgs=[]
macauley97557232015-07-16 17:28:07 +0800164 for of_port in ports:
165 # do stuff
166 group_id = encode_l2_interface_group_id(vlan_id, of_port)
macauley41904ed2015-07-16 17:38:35 +0800167 group_id_list.append(group_id)
macauley97557232015-07-16 17:28:07 +0800168 if is_tagged:
169 actions = [
170 ofp.action.output(of_port),
171 ]
172 else:
173 actions = [
174 ofp.action.pop_vlan(),
175 ofp.action.output(of_port),
176 ]
177
178 buckets = [
179 ofp.bucket(actions=actions),
180 ]
181
182 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
183 group_id=group_id,
184 buckets=buckets
185 )
186 ctrl.message_send(request)
macauley15909e72015-07-17 15:58:57 +0800187 msgs.append(request)
macauley97557232015-07-16 17:28:07 +0800188
189 if send_barrier:
190 do_barrier(ctrl)
macauley41904ed2015-07-16 17:38:35 +0800191
macauley15909e72015-07-17 15:58:57 +0800192 return group_id_list, msgs
macauley97557232015-07-16 17:28:07 +0800193
Flavio Castrod4c44d12015-12-08 14:44:18 -0500194def add_one_l2_interface_group(ctrl, port, vlan_id=1, is_tagged=False, send_barrier=False):
macauley0f91a3e2015-07-17 18:09:59 +0800195 # group table
196 # set up untag groups for each port
197 group_id = encode_l2_interface_group_id(vlan_id, port)
198
199 if is_tagged:
200 actions = [
201 ofp.action.output(port),
202 ]
203 else:
204 actions = [
205 ofp.action.pop_vlan(),
206 ofp.action.output(port),
207 ]
208
209 buckets = [
210 ofp.bucket(actions=actions),
211 ]
212
213 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
214 group_id=group_id,
215 buckets=buckets
216 )
217 ctrl.message_send(request)
218
219 if send_barrier:
220 do_barrier(ctrl)
221
222 return group_id, request
223
macauley97557232015-07-16 17:28:07 +0800224def add_l2_mcast_group(ctrl, ports, vlanid, mcast_grp_index):
225 buckets=[]
226 for of_port in ports:
227 group_id = encode_l2_interface_group_id(vlanid, of_port)
228 action=[ofp.action.group(group_id)]
229 buckets.append(ofp.bucket(actions=action))
230
231 group_id =encode_l2_mcast_group_id(vlanid, mcast_grp_index)
232 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
233 group_id=group_id,
234 buckets=buckets
235 )
236 ctrl.message_send(request)
macauley15909e72015-07-17 15:58:57 +0800237 return request
macauley97557232015-07-16 17:28:07 +0800238
macauley15909e72015-07-17 15:58:57 +0800239def add_l2_flood_group(ctrl, ports, vlanid, id):
240 buckets=[]
241 for of_port in ports:
242 group_id = encode_l2_interface_group_id(vlanid, of_port)
243 action=[ofp.action.group(group_id)]
244 buckets.append(ofp.bucket(actions=action))
macauley97557232015-07-16 17:28:07 +0800245
macauley15909e72015-07-17 15:58:57 +0800246 group_id =encode_l2_flood_group_id(vlanid, id)
247 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
248 group_id=group_id,
249 buckets=buckets
250 )
251 ctrl.message_send(request)
252 return request
253
254def add_l2_rewrite_group(ctrl, port, vlanid, id, src_mac, dst_mac):
255 group_id = encode_l2_interface_group_id(vlanid, port)
256
257 action=[]
258 if src_mac is not None:
259 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
260
261 if dst_mac is not None:
262 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
263
Flavio Castro91d1a552016-05-17 16:59:44 -0700264 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlanid)))
macauley_cheng93f3fa52015-09-02 17:57:31 +0800265
macauley15909e72015-07-17 15:58:57 +0800266 action.append(ofp.action.group(group_id))
267
268 buckets = [ofp.bucket(actions=action)]
269
270 group_id =encode_l2_rewrite_group_id(id)
271 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
272 group_id=group_id,
273 buckets=buckets
274 )
275 ctrl.message_send(request)
276 return request
277
278def add_l3_unicast_group(ctrl, port, vlanid, id, src_mac, dst_mac):
279 group_id = encode_l2_interface_group_id(vlanid, port)
280
281 action=[]
282 if src_mac is not None:
283 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
284
285 if dst_mac is not None:
286 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
287
Flavio Castroaf2b4502016-02-02 17:41:32 -0500288 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlanid)))
macauley15909e72015-07-17 15:58:57 +0800289
290 action.append(ofp.action.group(group_id))
291
292 buckets = [ofp.bucket(actions=action)]
293
294 group_id =encode_l3_unicast_group_id(id)
295 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
296 group_id=group_id,
297 buckets=buckets
298 )
299 ctrl.message_send(request)
300 return request
301
302def add_l3_interface_group(ctrl, port, vlanid, id, src_mac):
303 group_id = encode_l2_interface_group_id(vlanid, port)
304
305 action=[]
306 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
Flavio Castro8ca52542016-04-11 11:24:49 -0400307 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlanid)))
macauley15909e72015-07-17 15:58:57 +0800308 action.append(ofp.action.group(group_id))
309
310 buckets = [ofp.bucket(actions=action)]
311
312 group_id =encode_l3_interface_group_id(id)
313 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
314 group_id=group_id,
315 buckets=buckets
316 )
317 ctrl.message_send(request)
318 return request
319
320def add_l3_ecmp_group(ctrl, id, l3_ucast_groups):
321 buckets=[]
322 for group in l3_ucast_groups:
323 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
324
325 group_id =encode_l3_ecmp_group_id(id)
326 request = ofp.message.group_add(group_type=ofp.OFPGT_SELECT,
327 group_id=group_id,
328 buckets=buckets
329 )
330 ctrl.message_send(request)
331 return request
332
333def add_l3_mcast_group(ctrl, vid, mcast_group_id, groups_on_buckets):
334 buckets=[]
335 for group in groups_on_buckets:
336 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
337
338 group_id =encode_l3_mcast_group_id(vid, mcast_group_id)
339 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
340 group_id=group_id,
341 buckets=buckets
342 )
343 ctrl.message_send(request)
344 return request
macauleyfddc4662015-07-27 17:40:30 +0800345
346def add_l2_overlay_flood_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
347 buckets=[]
348 for port in ports:
349 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
350
351 group_id=encode_l2_overlay_group_id(tunnel_id, 0, index)
352 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
353 group_id=group_id,
354 buckets=buckets
355 )
356 ctrl.message_send(request)
357 return request
358
359def add_l2_overlay_flood_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
360 buckets=[]
361 for port in ports:
362 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
363
364 group_id=encode_l2_overlay_group_id(tunnel_id, 1, index)
365 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
366 group_id=group_id,
367 buckets=buckets
368 )
369 ctrl.message_send(request)
370 return request
371
372def add_l2_overlay_mcast_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
373 buckets=[]
374 for port in ports:
375 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
376
377 group_id=encode_l2_overlay_group_id(tunnel_id, 2, index)
378 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
379 group_id=group_id,
380 buckets=buckets
381 )
382 ctrl.message_send(request)
383 return request
384
385def add_l2_overlay_mcast_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
386 buckets=[]
387 for port in ports:
388 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
389
390 group_id=encode_l2_overlay_group_id(tunnel_id, 3, index)
391 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
392 group_id=group_id,
393 buckets=buckets
394 )
395 ctrl.message_send(request)
396 return request
397
398def add_port_table_flow(ctrl, is_overlay=True):
399 match = ofp.match()
400
401 if is_overlay == True:
402 match.oxm_list.append(ofp.oxm.in_port(0x10000))
macauleydbff3272015-07-30 14:07:16 +0800403 NEXT_TABLE=50
macauleyfddc4662015-07-27 17:40:30 +0800404 else:
405 match.oxm_list.append(ofp.oxm.in_port(0))
macauleydbff3272015-07-30 14:07:16 +0800406 NEXT_TABLE=10
macauleyfddc4662015-07-27 17:40:30 +0800407
408 request = ofp.message.flow_add(
409 table_id=0,
410 cookie=42,
411 match=match,
412 instructions=[
macauleydbff3272015-07-30 14:07:16 +0800413 ofp.instruction.goto_table(NEXT_TABLE)
macauleyfddc4662015-07-27 17:40:30 +0800414 ],
415 priority=0)
416 logging.info("Add port table, match port %lx" % 0x10000)
417 ctrl.message_send(request)
macauleydbff3272015-07-30 14:07:16 +0800418
Flavio Castrod8f8af22015-12-02 18:19:26 -0500419
420def pop_vlan_flow(ctrl, ports, vlan_id=1):
421 # table 10: vlan
422 # goto to table 20
423 msgs=[]
424 for of_port in ports:
425 match = ofp.match()
426 match.oxm_list.append(ofp.oxm.in_port(of_port))
427 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
428 request = ofp.message.flow_add(
429 table_id=10,
430 cookie=42,
431 match=match,
432 instructions=[
433 ofp.instruction.apply_actions(
434 actions=[
435 ofp.action.pop_vlan()
436 ]
437 ),
438 ofp.instruction.goto_table(20)
439 ],
440 priority=0)
441 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
442 ctrl.message_send(request)
443
444
445 return msgs
macauleyfddc4662015-07-27 17:40:30 +0800446
macauley97557232015-07-16 17:28:07 +0800447def add_vlan_table_flow(ctrl, ports, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
448 # table 10: vlan
449 # goto to table 20
macauley15909e72015-07-17 15:58:57 +0800450 msgs=[]
macauley97557232015-07-16 17:28:07 +0800451 for of_port in ports:
Flavio Castro932014b2016-01-05 18:29:15 -0500452 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
macauley97557232015-07-16 17:28:07 +0800453 match = ofp.match()
454 match.oxm_list.append(ofp.oxm.in_port(of_port))
455 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
456 request = ofp.message.flow_add(
457 table_id=10,
458 cookie=42,
459 match=match,
460 instructions=[
Flavio Castrod8f8af22015-12-02 18:19:26 -0500461 ofp.instruction.apply_actions(
462 actions=[
463 ofp.action.pop_vlan()
464 ]
465 ),
macauley97557232015-07-16 17:28:07 +0800466 ofp.instruction.goto_table(20)
467 ],
468 priority=0)
469 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
470 ctrl.message_send(request)
471
472 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
473 match = ofp.match()
474 match.oxm_list.append(ofp.oxm.in_port(of_port))
Flavio Castro12296312015-12-15 17:48:26 -0500475 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0x1fff))
macauley97557232015-07-16 17:28:07 +0800476 request = ofp.message.flow_add(
477 table_id=10,
478 cookie=42,
479 match=match,
480 instructions=[
481 ofp.instruction.apply_actions(
482 actions=[
Flavio Castroaf2b4502016-02-02 17:41:32 -0500483 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id))
macauley97557232015-07-16 17:28:07 +0800484 ]
485 ),
486 ofp.instruction.goto_table(20)
487 ],
488 priority=0)
489 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
490 ctrl.message_send(request)
macauley15909e72015-07-17 15:58:57 +0800491 msgs.append(request)
macauley97557232015-07-16 17:28:07 +0800492
Flavio Castro932014b2016-01-05 18:29:15 -0500493 if (flag == 4) :
494 match = ofp.match()
495 match.oxm_list.append(ofp.oxm.in_port(of_port))
496 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1fff))
497 request = ofp.message.flow_add(
498 table_id=10,
499 cookie=42,
500 match=match,
501 instructions=[
502 ofp.instruction.apply_actions(
503 actions=[
Flavio Castroaf2b4502016-02-02 17:41:32 -0500504 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id))
Flavio Castro932014b2016-01-05 18:29:15 -0500505 ]
506 ),
507 ofp.instruction.goto_table(20)
508 ],
509 priority=0)
510 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
511 ctrl.message_send(request)
512 msgs.append(request)
513
macauley97557232015-07-16 17:28:07 +0800514 if send_barrier:
515 do_barrier(ctrl)
516
macauley15909e72015-07-17 15:58:57 +0800517 return msgs
macauley_cheng6e6a6122015-11-16 14:19:18 +0800518
519def del_vlan_table_flow(ctrl, ports, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
520 # table 10: vlan
521 # goto to table 20
522 msgs=[]
523 for of_port in ports:
524 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
525 match = ofp.match()
526 match.oxm_list.append(ofp.oxm.in_port(of_port))
527 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
528 request = ofp.message.flow_delete(
529 table_id=10,
530 cookie=42,
531 match=match,
532 priority=0)
533 logging.info("Del vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
534 ctrl.message_send(request)
macauley0f91a3e2015-07-17 18:09:59 +0800535
macauley_cheng6e6a6122015-11-16 14:19:18 +0800536 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
537 match = ofp.match()
538 match.oxm_list.append(ofp.oxm.in_port(of_port))
539 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0xfff))
540 request = ofp.message.flow_delete(
541 table_id=10,
542 cookie=42,
543 match=match,
544 priority=0)
545 logging.info("Del vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
546 ctrl.message_send(request)
547 msgs.append(request)
548
549 if send_barrier:
550 do_barrier(ctrl)
551
552 return msgs
553
macauley_cheng6b311612015-09-04 11:32:27 +0800554def add_vlan_table_flow_pvid(ctrl, in_port, match_vid=None, pvid=1, send_barrier=False):
555 """it will tag pack as untagged packet wether it has tagg or not"""
556 match = ofp.match()
557 match.oxm_list.append(ofp.oxm.in_port(in_port))
558 actions=[]
559 if match_vid == None:
560 match.oxm_list.append(ofp.oxm.vlan_vid(0))
561 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+pvid)))
562 goto_table=20
563 else:
564 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+match_vid, 0x1fff))
565 actions.append(ofp.action.push_vlan(0x8100))
566 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+pvid)))
567 goto_table=20
568
569 request = ofp.message.flow_add(
570 table_id=10,
571 cookie=42,
572 match=match,
573 instructions=[
574 ofp.instruction.apply_actions(actions=actions)
575 ,ofp.instruction.goto_table(goto_table)
576 ],
577 priority=0)
578 logging.info("Add PVID %d on port %d and go to table %ld" %( pvid, in_port, goto_table))
579 ctrl.message_send(request)
580
581 if send_barrier:
582 do_barrier(ctrl)
583
584def add_vlan_table_flow_allow_all_vlan(ctrl, in_port, send_barrier=False):
585 """it st flow allow all vlan tag on this port"""
586 match = ofp.match()
587 match.oxm_list.append(ofp.oxm.in_port(in_port))
588 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1000))
589 request = ofp.message.flow_add(
590 table_id=10,
591 cookie=42,
592 match=match,
593 instructions=[
594 ofp.instruction.goto_table(20)
595 ],
596 priority=0)
597 logging.info("Add allow all vlan on port %d " %(in_port))
598 ctrl.message_send(request)
599
macauley53d90fe2015-08-04 17:34:22 +0800600def 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 +0800601 # table 10: vlan
602 # goto to table 20
Flavio Castro932014b2016-01-05 18:29:15 -0500603 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
macauley0f91a3e2015-07-17 18:09:59 +0800604 match = ofp.match()
605 match.oxm_list.append(ofp.oxm.in_port(of_port))
Flavio Castro12296312015-12-15 17:48:26 -0500606 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id,0x1fff))
macauley7f89d962015-08-06 18:13:48 +0800607
608 actions=[]
609 if vrf!=0:
610 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
611
Flavio Castro6d498522015-12-15 14:05:04 -0500612 #actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(value=vlan_id)))
macauley7f89d962015-08-06 18:13:48 +0800613
macauley0f91a3e2015-07-17 18:09:59 +0800614 request = ofp.message.flow_add(
615 table_id=10,
616 cookie=42,
617 match=match,
618 instructions=[
macauley53d90fe2015-08-04 17:34:22 +0800619 ofp.instruction.apply_actions(
macauley7f89d962015-08-06 18:13:48 +0800620 actions=actions
macauley53d90fe2015-08-04 17:34:22 +0800621 ),
622 ofp.instruction.goto_table(20)
macauley0f91a3e2015-07-17 18:09:59 +0800623 ],
624 priority=0)
625 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
626 ctrl.message_send(request)
627
628 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
629 match = ofp.match()
630 match.oxm_list.append(ofp.oxm.in_port(of_port))
Flavio Castro12296312015-12-15 17:48:26 -0500631 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0x1fff))
macauley53d90fe2015-08-04 17:34:22 +0800632
macauley7f89d962015-08-06 18:13:48 +0800633 actions=[]
634 if vrf!=0:
635 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
636
Flavio Castro91d1a552016-05-17 16:59:44 -0700637 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
macauley7f89d962015-08-06 18:13:48 +0800638
macauley0f91a3e2015-07-17 18:09:59 +0800639 request = ofp.message.flow_add(
640 table_id=10,
641 cookie=42,
642 match=match,
643 instructions=[
644 ofp.instruction.apply_actions(
macauley7f89d962015-08-06 18:13:48 +0800645 actions=actions
macauley0f91a3e2015-07-17 18:09:59 +0800646 ),
647 ofp.instruction.goto_table(20)
648 ],
649 priority=0)
650 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
651 ctrl.message_send(request)
Flavio Castro932014b2016-01-05 18:29:15 -0500652
653 if (flag == 4) :
654 match = ofp.match()
655 match.oxm_list.append(ofp.oxm.in_port(of_port))
656 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000,0x1fff))
657
658 actions=[]
659 if vrf!=0:
660 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
661
Flavio Castro91d1a552016-05-17 16:59:44 -0700662 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
Flavio Castro932014b2016-01-05 18:29:15 -0500663
664 request = ofp.message.flow_add(
665 table_id=10,
666 cookie=42,
667 match=match,
668 instructions=[
669 ofp.instruction.apply_actions(
670 actions=actions
671 ),
672 ofp.instruction.goto_table(20)
673 ],
674 priority=0)
675 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
676 ctrl.message_send(request)
macauley0f91a3e2015-07-17 18:09:59 +0800677
678 if send_barrier:
679 do_barrier(ctrl)
680
681 return request
macauley15909e72015-07-17 15:58:57 +0800682
macauley97557232015-07-16 17:28:07 +0800683def add_bridge_flow(ctrl, dst_mac, vlanid, group_id, send_barrier=False):
684 match = ofp.match()
castroflavio21894482015-12-08 15:29:55 -0500685 priority=500
macauleyfddc4662015-07-27 17:40:30 +0800686 if dst_mac!=None:
castroflavio21894482015-12-08 15:29:55 -0500687 priority=1000
macauleyfddc4662015-07-27 17:40:30 +0800688 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
689
macauley97557232015-07-16 17:28:07 +0800690 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
macauleyfddc4662015-07-27 17:40:30 +0800691
macauley97557232015-07-16 17:28:07 +0800692 request = ofp.message.flow_add(
693 table_id=50,
694 cookie=42,
695 match=match,
696 instructions=[
697 ofp.instruction.write_actions(
698 actions=[
699 ofp.action.group(group_id)]),
700 ofp.instruction.goto_table(60)
701 ],
702 buffer_id=ofp.OFP_NO_BUFFER,
castroflavio21894482015-12-08 15:29:55 -0500703 priority=priority)
macauley97557232015-07-16 17:28:07 +0800704
705 logging.info("Inserting Brdige flow vlan %d, mac %s", vlanid, dst_mac)
706 ctrl.message_send(request)
707
708 if send_barrier:
macauley15909e72015-07-17 15:58:57 +0800709 do_barrier(ctrl)
710
macauley0f91a3e2015-07-17 18:09:59 +0800711 return request
macauleyfddc4662015-07-27 17:40:30 +0800712
713def add_overlay_bridge_flow(ctrl, dst_mac, vnid, group_id, is_group=True, send_barrier=False):
714 match = ofp.match()
715 if dst_mac!=None:
716 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
717
718 match.oxm_list.append(ofp.oxm.tunnel_id(vnid))
719 if is_group == True:
720 actions=[ofp.action.group(group_id)]
721 else:
722 actions=[ofp.action.output(group_id)]
723
724 request = ofp.message.flow_add(
725 table_id=50,
726 cookie=42,
727 match=match,
728 instructions=[
729 ofp.instruction.write_actions(
730 actions=actions),
731 ofp.instruction.goto_table(60)
732 ],
733 buffer_id=ofp.OFP_NO_BUFFER,
734 priority=1000)
735
736 logging.info("Inserting Brdige flow vnid %d, mac %s", vnid, dst_mac)
737 ctrl.message_send(request)
738
739 if send_barrier:
740 do_barrier(ctrl)
741
742 return request
macauley0f91a3e2015-07-17 18:09:59 +0800743
macauley_cheng6b133662015-11-09 13:52:39 +0800744def add_termination_flow(ctrl, in_port, eth_type, dst_mac, vlanid, goto_table=None, send_barrier=False):
macauley0f91a3e2015-07-17 18:09:59 +0800745 match = ofp.match()
macauley0f91a3e2015-07-17 18:09:59 +0800746 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
macauleyfddc4662015-07-27 17:40:30 +0800747 if dst_mac[0]&0x01 == 0x01:
748 match.oxm_list.append(ofp.oxm.eth_dst_masked(dst_mac, [0xff, 0xff, 0xff, 0x80, 0x00, 0x00]))
749 goto_table=40
750 else:
macauley53d90fe2015-08-04 17:34:22 +0800751 if in_port!=0:
752 match.oxm_list.append(ofp.oxm.in_port(in_port))
macauleyfddc4662015-07-27 17:40:30 +0800753 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
754 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
macauley_cheng6b133662015-11-09 13:52:39 +0800755 if goto_table == None:
756 goto_table=30
macauley0f91a3e2015-07-17 18:09:59 +0800757
758 request = ofp.message.flow_add(
759 table_id=20,
760 cookie=42,
761 match=match,
762 instructions=[
763 ofp.instruction.goto_table(goto_table)
764 ],
765 buffer_id=ofp.OFP_NO_BUFFER,
766 priority=1)
767
768 logging.info("Inserting termination flow inport %d, eth_type %lx, vlan %d, mac %s", in_port, eth_type, vlanid, dst_mac)
769 ctrl.message_send(request)
770
771 if send_barrier:
772 do_barrier(ctrl)
773
774 return request
775
Flavio Castroaf2b4502016-02-02 17:41:32 -0500776def add_unicast_routing_flow(ctrl, eth_type, dst_ip, mask, action_group_id, vrf=0, send_ctrl=False, send_barrier=False):
macauley0f91a3e2015-07-17 18:09:59 +0800777 match = ofp.match()
778 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
macauley53d90fe2015-08-04 17:34:22 +0800779 if vrf != 0:
780 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_VRF, vrf))
macauley0f91a3e2015-07-17 18:09:59 +0800781
Flavio Castroaf2b4502016-02-02 17:41:32 -0500782 match.oxm_list.append(ofp.oxm.ipv4_dst_masked(dst_ip, mask))
783
784 instructions = []
785 instructions.append(ofp.instruction.goto_table(60))
786 if send_ctrl:
Flavio Castro91d1a552016-05-17 16:59:44 -0700787 instructions.append(ofp.instruction.write_actions(
Flavio Castroaf2b4502016-02-02 17:41:32 -0500788 actions=[ofp.action.output( port=ofp.OFPP_CONTROLLER,
789 max_len=ofp.OFPCML_NO_BUFFER)]))
790 else:
791 instructions.append(ofp.instruction.write_actions(
792 actions=[ofp.action.group(action_group_id)]))
macauley53d90fe2015-08-04 17:34:22 +0800793
macauley0f91a3e2015-07-17 18:09:59 +0800794 request = ofp.message.flow_add(
795 table_id=30,
796 cookie=42,
797 match=match,
Flavio Castroaf2b4502016-02-02 17:41:32 -0500798 instructions=instructions,
macauley0f91a3e2015-07-17 18:09:59 +0800799 buffer_id=ofp.OFP_NO_BUFFER,
800 priority=1)
801
802 logging.info("Inserting unicast routing flow eth_type %lx, dip %ld",eth_type, dst_ip)
803 ctrl.message_send(request)
804
805 if send_barrier:
806 do_barrier(ctrl)
807
macauleyfddc4662015-07-27 17:40:30 +0800808 return request
Flavio Castrod8f8af22015-12-02 18:19:26 -0500809
Flavio Castro8ca52542016-04-11 11:24:49 -0400810def add_mpls_flow(ctrl, action_group_id=0x0, label=100 ,ethertype=0x0800, bos=1, vrf=1, goto_table=27, send_barrier=False):
Flavio Castrob702a2f2016-04-10 22:01:48 -0400811 match = ofp.match()
812 match.oxm_list.append(ofp.oxm.eth_type(0x8847))
813 match.oxm_list.append(ofp.oxm.mpls_label(label))
814 match.oxm_list.append(ofp.oxm.mpls_bos(bos))
815 actions = [ofp.action.dec_mpls_ttl(),
Flavio Castro8ca52542016-04-11 11:24:49 -0400816 ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf))]
817 if (goto_table == 29):
818 actions.append(ofp.action.set_field(
819 ofp.oxm.exp2ByteValue(exp_type=23, value=32)))
820 actions.append(ofp.action.group(action_group_id))
821 else:
Flavio Castrod80fbc32016-07-25 15:54:26 -0700822 actions.append(ofp.action.set_field(
823 ofp.oxm.exp2ByteValue(exp_type=23, value=32)))
824 actions.append(ofp.action.group(action_group_id))
Flavio Castro8ca52542016-04-11 11:24:49 -0400825 actions.append(ofp.action.copy_ttl_in())
826
Flavio Castrob702a2f2016-04-10 22:01:48 -0400827 request = ofp.message.flow_add(
828 table_id=24,
829 cookie=43,
830 match=match,
831 instructions=[
Flavio Castro8ca52542016-04-11 11:24:49 -0400832 ofp.instruction.apply_actions(actions=actions),
833 ofp.instruction.goto_table(goto_table)
Flavio Castrob702a2f2016-04-10 22:01:48 -0400834 ],
835 buffer_id=ofp.OFP_NO_BUFFER,
836 priority=1)
Flavio Castrob702a2f2016-04-10 22:01:48 -0400837 logging.info("Inserting MPLS flow , label %ld", label)
838 ctrl.message_send(request)
839
840 if send_barrier:
841 do_barrier(ctrl)
842
843 return request
844
macauleyfddc4662015-07-27 17:40:30 +0800845def add_mcast4_routing_flow(ctrl, vlan_id, src_ip, src_ip_mask, dst_ip, action_group_id, send_barrier=False):
846 match = ofp.match()
847 match.oxm_list.append(ofp.oxm.eth_type(0x0800))
848 match.oxm_list.append(ofp.oxm.vlan_vid(vlan_id))
849 if src_ip_mask!=0:
850 match.oxm_list.append(ofp.oxm.ipv4_src_masked(src_ip, src_ip_mask))
851 else:
852 match.oxm_list.append(ofp.oxm.ipv4_src(src_ip))
853
854 match.oxm_list.append(ofp.oxm.ipv4_dst(dst_ip))
855
856 request = ofp.message.flow_add(
857 table_id=40,
858 cookie=42,
859 match=match,
860 instructions=[
861 ofp.instruction.write_actions(
862 actions=[ofp.action.group(action_group_id)]),
863 ofp.instruction.goto_table(60)
864 ],
865 buffer_id=ofp.OFP_NO_BUFFER,
866 priority=1)
867
868 logging.info("Inserting mcast routing flow eth_type %lx, dip %lx, sip %lx, sip_mask %lx",0x0800, dst_ip, src_ip, src_ip_mask)
869 ctrl.message_send(request)
870
871 if send_barrier:
872 do_barrier(ctrl)
873
874 return request
macauley_cheng6b133662015-11-09 13:52:39 +0800875
876#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
macauley_chengeffc20a2015-11-09 16:14:56 +0800877def add_dnat_flow(ctrl, eth_type, ip_dst, ip_proto, tcp_dst, set_ip_dst, set_tcp_dst, action_group_id):
macauley_cheng6b133662015-11-09 13:52:39 +0800878 match = ofp.match()
879 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
880 match.oxm_list.append(ofp.oxm.ipv4_dst(ip_dst))
881 match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
882 match.oxm_list.append(ofp.oxm.tcp_dst(tcp_dst))
883
884 request = ofp.message.flow_add(
885 table_id=28,
886 cookie=42,
887 match=match,
888 instructions=[
889 ofp.instruction.write_actions(
890 actions=[ofp.action.set_field(ofp.oxm.ipv4_dst(set_ip_dst)),
891 ofp.action.set_field(ofp.oxm.tcp_dst(set_tcp_dst)),
892 ofp.action.group(action_group_id)]),
893 ofp.instruction.goto_table(60)
894 ],
895 buffer_id=ofp.OFP_NO_BUFFER,
896 priority=1)
897 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)
898 ctrl.message_send(request)
899 return request
macauley_chengeffc20a2015-11-09 16:14:56 +0800900
901#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
902def add_snat_flow(ctrl, eth_type, ip_src, ip_proto, tcp_src, set_ip_src, set_tcp_src):
903 match = ofp.match()
904 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
905 match.oxm_list.append(ofp.oxm.ipv4_src(ip_src))
906 match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
907 match.oxm_list.append(ofp.oxm.tcp_src(tcp_src))
908
909 request = ofp.message.flow_add(
910 table_id=29,
911 cookie=42,
912 match=match,
913 instructions=[
914 ofp.instruction.write_actions(
915 actions=[ofp.action.set_field(ofp.oxm.ipv4_src(set_ip_src)),
916 ofp.action.set_field(ofp.oxm.tcp_src(set_tcp_src))]),
917 ofp.instruction.goto_table(30)
918 ],
919 buffer_id=ofp.OFP_NO_BUFFER,
920 priority=1)
921 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)
922 ctrl.message_send(request)
923 return request
macauley_cheng6b133662015-11-09 13:52:39 +0800924
macauleyfddc4662015-07-27 17:40:30 +0800925def get_vtap_lport_config_xml(dp_id, lport, phy_port, vlan, vnid, operation='merge'):
926 """
927 Command Example:
928 of-agent vtap 10001 ethernet 1/1 vid 1
929 of-agent vtp 10001 vni 10
930 """
931 if vlan != 0:
932 config_vtap_xml="""
933 <config>
934 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
935 <id>capable-switch-1</id>
936 <resources>
937 <port xc:operation="OPERATION">
938 <resource-id >LPORT</resource-id>
939 <features>
940 <current>
941 <rate>10Gb</rate>
942 <medium>fiber</medium>
943 <pause>symmetric</pause>
944 </current>
945 <advertised>
946 <rate>10Gb</rate>
947 <rate>100Gb</rate>
948 <medium>fiber</medium>
949 <pause>symmetric</pause>
950 </advertised>
951 <supported>
952 <rate>10Gb</rate>
953 <rate>100Gb</rate>
954 <medium>fiber</medium>
955 <pause>symmetric</pause>
956 </supported>
957 <advertised-peer>
958 <rate>10Gb</rate>
959 <rate>100Gb</rate>
960 <medium>fiber</medium>
961 <pause>symmetric</pause>
962 </advertised-peer>
963 </features>
964 <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
965 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
966 <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
967 <ofdpa10:vni>VNID</ofdpa10:vni>
968 </ofdpa10:vtap>
969 </port>
970 </resources>
971 <logical-switches>
972 <switch>
973 <id>DATAPATH_ID</id>
974 <datapath-id>DATAPATH_ID</datapath-id>
975 <resources>
976 <port xc:operation="OPERATION">LPORT</port>
977 </resources>
978 </switch>
979 </logical-switches>
980 </capable-switch>
981 </config>
982 """
983 else:
984 config_vtap_xml="""
985 <config>
986 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
987 <id>capable-switch-1</id>
988 <resources>
989 <port xc:operation="OPERATION">
990 <resource-id >LPORT</resource-id>
991 <features>
992 <current>
993 <rate>10Gb</rate>
994 <medium>fiber</medium>
995 <pause>symmetric</pause>
996 </current>
997 <advertised>
998 <rate>10Gb</rate>
999 <rate>100Gb</rate>
1000 <medium>fiber</medium>
1001 <pause>symmetric</pause>
1002 </advertised>
1003 <supported>
1004 <rate>10Gb</rate>
1005 <rate>100Gb</rate>
1006 <medium>fiber</medium>
1007 <pause>symmetric</pause>
1008 </supported>
1009 <advertised-peer>
1010 <rate>10Gb</rate>
1011 <rate>100Gb</rate>
1012 <medium>fiber</medium>
1013 <pause>symmetric</pause>
1014 </advertised-peer>
1015 </features>
1016 <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1017 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
1018 <ofdpa10:vni>VNID</ofdpa10:vni>
1019 </ofdpa10:vtap>
1020 </port>
1021 </resources>
1022 <logical-switches>
1023 <switch>
1024 <id>DATAPATH_ID</id>
1025 <datapath-id>DATAPATH_ID</datapath-id>
1026 <resources>
1027 <port xc:operation="OPERATION">LPORT</port>
1028 </resources>
1029 </switch>
1030 </logical-switches>
1031 </capable-switch>
1032 </config>
1033 """
1034 str_datapath_id_f= "{:016x}".format(dp_id)
1035 str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
1036 config_vtap_xml=config_vtap_xml.replace("DATAPATH_ID", str_datapath_id)
macauley25999cf2015-08-07 17:03:24 +08001037 config_vtap_xml=config_vtap_xml.replace("LPORT", str(int(lport)))
macauleyfddc4662015-07-27 17:40:30 +08001038 config_vtap_xml=config_vtap_xml.replace("PHY_PORT", str(phy_port))
1039 config_vtap_xml=config_vtap_xml.replace("VLAN_ID", str(vlan))
1040 config_vtap_xml=config_vtap_xml.replace("VNID", str(vnid))
1041 config_vtap_xml=config_vtap_xml.replace("OPERATION", str(operation))
1042 return config_vtap_xml
1043
1044def get_vtep_lport_config_xml(dp_id, lport, src_ip, dst_ip, next_hop_id, vnid, udp_src_port=6633, ttl=25, operation='merge'):
1045 """
1046 Command Example:
1047 of-agent vtep 10002 source user-input-src-ip destination user-input-dst-ip udp-source-port 6633 nexthop 2 ttl 25
1048 of-agent vtp 10001 vni 10
1049 """
1050
1051 config_vtep_xml="""
1052 <config>
1053 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1054 <id>capable-switch-1</id>
1055 <resources>
1056 <port xc:operation="OPERATION">
1057 <resource-id>LPORT</resource-id>
1058 <features>
1059 <current>
1060 <rate>10Gb</rate>
1061 <medium>fiber</medium>
1062 <pause>symmetric</pause>
1063 </current>
1064 <advertised>
1065 <rate>10Gb</rate>
1066 <rate>100Gb</rate>
1067 <medium>fiber</medium>
1068 <pause>symmetric</pause>
1069 </advertised>
1070 <supported>
1071 <rate>10Gb</rate>
1072 <rate>100Gb</rate>
1073 <medium>fiber</medium>
1074 <pause>symmetric</pause>
1075 </supported>
1076 <advertised-peer>
1077 <rate>10Gb</rate>
1078 <rate>100Gb</rate>
1079 <medium>fiber</medium>
1080 <pause>symmetric</pause>
1081 </advertised-peer>
1082 </features>
1083 <ofdpa10:vtep xmlns:ofdpa10="urn:bcm:ofdpa10:accton01">
1084 <ofdpa10:src-ip>SRC_IP</ofdpa10:src-ip>
1085 <ofdpa10:dest-ip>DST_IP</ofdpa10:dest-ip>
1086 <ofdpa10:udp-src-port>UDP_SRC_PORT</ofdpa10:udp-src-port>
macauley25999cf2015-08-07 17:03:24 +08001087 <ofdpa10:vni xc:operation="OPERATION">
1088 <ofdpa10:id>VNID</ofdpa10:id>
1089 </ofdpa10:vni>
macauleyfddc4662015-07-27 17:40:30 +08001090 <ofdpa10:nexthop-id>NEXT_HOP_ID</ofdpa10:nexthop-id>
1091 <ofdpa10:ttl>TTL</ofdpa10:ttl>
1092 </ofdpa10:vtep>
1093 </port>
1094 </resources>
1095 <logical-switches>
1096 <switch>
1097 <id>DATAPATH_ID</id>
1098 <datapath-id>DATAPATH_ID</datapath-id>
1099 <resources>
1100 <port xc:operation="OPERATION">LPORT</port>
1101 </resources>
1102 </switch>
1103 </logical-switches>
1104 </capable-switch>
1105 </config>
1106 """
1107 str_datapath_id_f= "{:016x}".format(dp_id)
1108 str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
1109 config_vtep_xml=config_vtep_xml.replace("DATAPATH_ID", str_datapath_id)
macauley25999cf2015-08-07 17:03:24 +08001110 config_vtep_xml=config_vtep_xml.replace("LPORT", str(int(lport)))
macauleyfddc4662015-07-27 17:40:30 +08001111 config_vtep_xml=config_vtep_xml.replace("SRC_IP", str(src_ip))
1112 config_vtep_xml=config_vtep_xml.replace("DST_IP", str(dst_ip))
1113 config_vtep_xml=config_vtep_xml.replace("UDP_SRC_PORT", str(udp_src_port))
1114 config_vtep_xml=config_vtep_xml.replace("NEXT_HOP_ID", str(next_hop_id))
1115 config_vtep_xml=config_vtep_xml.replace("TTL", str(ttl))
1116 config_vtep_xml=config_vtep_xml.replace("VNID", str(vnid))
1117 config_vtep_xml=config_vtep_xml.replace("OPERATION", str(operation))
1118
1119 return config_vtep_xml
1120
1121def get_next_hop_config_xml(next_hop_id, dst_mac, phy_port, vlan, operation='merge'):
1122 #of-agent nexthop 2 destination user-input-dst-mac ethernet 1/2 vid 2
1123 config_nexthop_xml="""
1124 <config>
1125 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1126 <ofdpa10:next-hop xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1127 <ofdpa10:id>NEXT_HOP_ID</ofdpa10:id>
1128 <ofdpa10:dest-mac>DST_MAC</ofdpa10:dest-mac>
1129 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
1130 <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
1131 </ofdpa10:next-hop>
1132 </of11-config:capable-switch>
1133 </config>
1134 """
1135 config_nexthop_xml=config_nexthop_xml.replace("VLAN_ID", str(vlan))
1136 config_nexthop_xml=config_nexthop_xml.replace("PHY_PORT", str(phy_port))
1137 config_nexthop_xml=config_nexthop_xml.replace("NEXT_HOP_ID", str(next_hop_id))
1138 config_nexthop_xml=config_nexthop_xml.replace("DST_MAC", str(dst_mac))
1139 config_nexthop_xml=config_nexthop_xml.replace("OPERATION", str(operation))
1140 return config_nexthop_xml
1141
1142def get_vni_config_xml(vni_id, mcast_ipv4, next_hop_id, operation='merge'):
1143 #of-agent vni 10 multicast 224.1.1.1 nexthop 20
1144 if mcast_ipv4!=None:
1145 config_vni_xml="""
1146 <config>
1147 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1148 <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1149 <ofdpa10:id>VNID</ofdpa10:id>
1150 <ofdpa10:vni-multicast-group>MCAST_IP</ofdpa10:vni-multicast-group>
1151 <ofdpa10:multicast-group-nexthop-id>NEXT_HOP_ID</ofdpa10:multicast-group-nexthop-id>
1152 </ofdpa10:vni>
1153 </of11-config:capable-switch>
1154 </config>
1155 """
1156 config_vni_xml=config_vni_xml.replace("NEXT_HOP_ID", str(next_hop_id))
1157 config_vni_xml=config_vni_xml.replace("MCAST_IP", str(mcast_ipv4))
1158 else:
1159 config_vni_xml="""
1160 <config>
1161 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1162 <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1163 <ofdpa10:id>VNID</ofdpa10:id>
1164 </ofdpa10:vni>
1165 </of11-config:capable-switch>
1166 </config>
1167 """
1168
1169 config_vni_xml=config_vni_xml.replace("VNID", str(vni_id))
1170 config_vni_xml=config_vni_xml.replace("OPERATION", str(operation))
1171 return config_vni_xml
1172
1173def get_featureReplay(self):
1174 req = ofp.message.features_request()
1175 res, raw = self.controller.transact(req)
1176 self.assertIsNotNone(res, "Did not receive a response from the DUT.")
1177 self.assertEqual(res.type, ofp.OFPT_FEATURES_REPLY,
1178 ("Unexpected packet type %d received in response to "
1179 "OFPT_FEATURES_REQUEST") % res.type)
1180 return res
1181
1182def send_edit_config(switch_ip, xml, target='runing'):
1183 NETCONF_ACCOUNT="netconfuser"
1184 NETCONF_PASSWD="netconfuser"
1185 with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
1186 try:
1187 m.edit_config(target='running',
1188 config=xml,
1189 default_operation='merge',
1190 error_option='stop-on-error')
1191
1192 except Exception as e:
1193 logging.info("Fail to set xml %s", xml)
1194 return False
1195
1196 #return m.get_config(source='running').data_xml
1197 return True
1198
1199def send_delete_config(switch_ip, xml, target='runing'):
1200 NETCONF_ACCOUNT="netconfuser"
1201 NETCONF_PASSWD="netconfuser"
1202 with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
1203 try:
1204 m.edit_config(target='running',
1205 config=xml,
1206 default_operation='delete',
1207 error_option='stop-on-error')
1208
1209 except Exception as e:
1210 logging.info("Fail to set xml %s", xml)
1211 return False
1212
1213 #return m.get_config(source='running').data_xml
1214 return True
1215
1216def get_edit_config(switch_ip, target='runing'):
1217 NETCONF_ACCOUNT="netconfuser"
1218 NETCONF_PASSWD="netconfuser"
1219 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 +08001220 return m.get_config(source='running').data_xml
macauleydbff3272015-07-30 14:07:16 +08001221
macauley_cheng67da9262015-08-31 15:18:41 +08001222
1223"""
1224MPLS
1225"""
1226
1227OFDPA_MPLS_SUBTYPE_SHIFT=24
1228OFDPA_MPLS_GROUP_SUBTYPE_L2_VPN_LABEL=1
1229OFDPA_MPLS_GROUP_SUBTYPE_L3_VPN_LABEL=2
1230OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL1=3
1231OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL2=4
1232OFDPA_MPLS_GROUP_SUBTYPE_SWAP_LABEL=5
1233OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP=6
1234OFDPA_MPLS_GROUP_SUBTYPE_ECMP=8
1235OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG=10
1236
1237def encode_mpls_interface_group_id(subtype, index):
1238 index=index&0x00ffffff
1239 assert(subtype==0)
1240 return index + (9 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
1241
1242def encode_mpls_label_group_id(subtype, index):
1243 index=index&0x00ffffff
1244 assert(subtype <=5 or subtype==0)
1245 #1: l2 vpn label
1246 #2: l3 vpn label
1247 #3: mpls tunnel label 1
1248 #4: mpls tunnel lable 2
1249 #5: mpls swap label
1250 return index + (9 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
1251
1252def encode_mpls_forwarding_group_id(subtype, index):
1253 index=index&0x00ffffff
1254 assert(subtype==6 or subtype==8 or subtype==10)
1255 return index + (10 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
1256
1257
1258def add_mpls_intf_group(ctrl, ref_gid, dst_mac, src_mac, vid, index, subtype=0):
1259 action=[]
1260 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
1261 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
Flavio Castroaf2b4502016-02-02 17:41:32 -05001262 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vid)))
macauley_cheng67da9262015-08-31 15:18:41 +08001263 action.append(ofp.action.group(ref_gid))
1264
1265 buckets = [ofp.bucket(actions=action)]
1266
1267 mpls_group_id =encode_mpls_interface_group_id(subtype, index)
1268 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
1269 group_id=mpls_group_id,
1270 buckets=buckets
1271 )
1272 ctrl.message_send(request)
1273 return mpls_group_id, request
1274
1275def add_mpls_label_group(ctrl, subtype, index, ref_gid,
1276 lmep_id=-1,
1277 qos_index=-1,
1278 push_l2_header=False,
1279 push_vlan=False,
1280 push_mpls_header=False,
1281 push_cw=False,
1282 set_mpls_label=None,
1283 set_bos=None,
1284 set_tc=None,
1285 set_tc_from_table=False,
1286 cpy_tc_outward=False,
1287 set_ttl=None,
1288 cpy_ttl_outward=False,
1289 oam_lm_tx_count=False,
1290 set_pri_from_table=False
1291 ):
1292 """
1293 @ref_gid: only can be mpls intf group or mpls tunnel label 1/2 group
1294 """
1295 action=[]
1296
1297 if push_vlan== True:
1298 action.append(ofp.action.push_vlan(0x8100))
1299 if push_mpls_header== True:
1300 action.append(ofp.action.push_mpls(0x8847))
1301 if set_mpls_label != None:
1302 action.append(ofp.action.set_field(ofp.oxm.mpls_label(set_mpls_label)))
1303 if set_bos != None:
1304 action.append(ofp.action.set_field(ofp.oxm.mpls_bos(set_bos)))
1305 if set_tc != None:
1306 assert(set_tc_from_table==False)
1307 action.append(ofp.action.set_field(ofp.oxm.mpls_tc(set_tc)))
1308 if set_ttl != None:
1309 action.append(ofp.action.set_mpls_ttl(set_ttl))
1310 if cpy_ttl_outward == True:
1311 action.append(ofp.action.copy_ttl_out())
1312 """
1313 ofdpa experimenter
1314 """
1315 if push_l2_header== True:
1316 action.append(ofp.action.ofdpa_push_l2_header())
1317 if set_tc_from_table== True:
1318 assert(qos_index>=0)
1319 assert(set_tc == None)
1320 action.append(ofp.action.ofdpa_set_tc_from_table(qos_index))
1321 if cpy_tc_outward == True:
1322 action.append(ofp.action.ofdpa_copy_tc_out())
1323 if oam_lm_tx_count == True:
1324 assert(qos_index>=0 and lmep_id>=0)
1325 action.append(ofp.action.ofdpa_oam_lm_tx_count(lmep_id, qos_index))
1326 if set_pri_from_table == True:
1327 assert(qos_index>=0)
1328 action.append(ofp.action.ofdpa_set_qos_from_table(qos_index))
1329 if push_cw == True:
1330 action.append(ofp.action.ofdpa_push_cw())
1331
1332 action.append(ofp.action.group(ref_gid))
1333 buckets = [ofp.bucket(actions=action)]
1334
1335 mpls_group_id = encode_mpls_label_group_id(subtype, index)
1336 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
1337 group_id=mpls_group_id,
1338 buckets=buckets
1339 )
1340 ctrl.message_send(request)
1341
1342 return mpls_group_id, request
1343
1344def add_mpls_forwarding_group(ctrl, subtype, index, ref_gids,
1345 watch_port=None,
macauley_chengd17ce512015-08-31 17:45:51 +08001346 watch_group=ofp.OFPP_ANY,
macauley_cheng67da9262015-08-31 15:18:41 +08001347 push_vlan=None,
macauley_chengd17ce512015-08-31 17:45:51 +08001348 pop_vlan=None,
macauley_cheng67da9262015-08-31 15:18:41 +08001349 set_vid=None):
1350 assert(subtype == OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP
1351 or subtype == OFDPA_MPLS_GROUP_SUBTYPE_ECMP
1352 or subtype == OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG)
macauley_chengd17ce512015-08-31 17:45:51 +08001353
macauley_cheng67da9262015-08-31 15:18:41 +08001354 buckets=[]
1355 if subtype == OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP:
macauley_chengd17ce512015-08-31 17:45:51 +08001356 group_type = ofp.OFPGT_FF
macauley_cheng67da9262015-08-31 15:18:41 +08001357 for gid in ref_gids:
macauley_chengd17ce512015-08-31 17:45:51 +08001358 action=[]
1359 action.append(ofp.action.group(gid))
1360 buckets.append(ofp.bucket(watch_port=watch_port, watch_group=watch_group,actions=action))
1361
macauley_cheng67da9262015-08-31 15:18:41 +08001362 elif subtype == OFDPA_MPLS_GROUP_SUBTYPE_ECMP:
1363 group_type = ofp.OFPGT_SELECT
1364 for gid in ref_gids:
macauley_chengd17ce512015-08-31 17:45:51 +08001365 action=[]
macauley_cheng67da9262015-08-31 15:18:41 +08001366 action.append(ofp.action.group(gid))
1367 buckets.append(ofp.bucket(actions=action))
macauley_chengd17ce512015-08-31 17:45:51 +08001368
macauley_cheng67da9262015-08-31 15:18:41 +08001369 elif subtype == OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG:
1370 group_type = ofp.OFPGT_INDIRECT
macauley_chengd17ce512015-08-31 17:45:51 +08001371 action=[]
macauley_cheng67da9262015-08-31 15:18:41 +08001372 if set_vid!=None:
Flavio Castro91d1a552016-05-17 16:59:44 -07001373 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+set_vid)))
macauley_cheng67da9262015-08-31 15:18:41 +08001374 if push_vlan!=None:
1375 action.append(ofp.action.push_vlan(push_vlan))
1376 if pop_vlan!=None:
macauley_chengd17ce512015-08-31 17:45:51 +08001377 action.append(ofp.action.pop_vlan())
macauley_cheng67da9262015-08-31 15:18:41 +08001378 action.append(ofp.action.group(ref_gids[0]))
1379 buckets.append(ofp.bucket(actions=action))
macauley_chengd17ce512015-08-31 17:45:51 +08001380
1381 mpls_group_id = encode_mpls_forwarding_group_id(subtype, index)
macauley_cheng67da9262015-08-31 15:18:41 +08001382 request = ofp.message.group_add(group_type=group_type,
macauley_cheng67da9262015-08-31 15:18:41 +08001383 group_id=mpls_group_id,
1384 buckets=buckets
1385 )
1386 ctrl.message_send(request)
1387 return mpls_group_id, request
macauley_chengd17ce512015-08-31 17:45:51 +08001388
1389
macauley_cheng67da9262015-08-31 15:18:41 +08001390"""
1391dislay
1392"""
macauleydbff3272015-07-30 14:07:16 +08001393def print_current_table_flow_stat(ctrl, table_id=0xff):
1394 stat_req=ofp.message.flow_stats_request()
1395 response, pkt = ctrl.transact(stat_req)
1396 if response == None:
1397 print "no response"
1398 return None
1399 print len(response.entries)
1400 for obj in response.entries:
1401 print "match ", obj.match
1402 print "cookie", obj.cookie
1403 print "priority", obj.priority
1404 print "idle_timeout", obj.idle_timeout
1405 print "hard_timeout", obj.hard_timeout
1406 #obj.actions
Flavio Castro167f5bd2015-12-02 19:33:53 -05001407 print "packet count: %lx"%obj.packet_count