blob: 784e654999237d5fa2672b13ee6113fe68fa0718 [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
Pierbbdf3782016-08-22 17:58:26 -070051
macauley_cheng67da9262015-08-31 15:18:41 +080052def 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)):
Pierbbdf3782016-08-22 17:58:26 -070057 min_len = len(stats)
macauley_cheng67da9262015-08-31 15:18:41 +080058 print "Stats Len is not the same, stats<verify_group_stats"
Pierbbdf3782016-08-22 17:58:26 -070059 else:
macauley_cheng67da9262015-08-31 15:18:41 +080060 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]
Pierbbdf3782016-08-22 17:58:26 -070065 gv = verify_group_stats[i]
macauley_cheng67da9262015-08-31 15:18:41 +080066 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]
Pierbbdf3782016-08-22 17:58:26 -070072 b2=gv.buckets[j]
macauley_cheng67da9262015-08-31 15:18:41 +080073 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()
Pierbbdf3782016-08-22 17:58:26 -070081 print "a2:"+a2.show()
macauley_cheng67da9262015-08-31 15:18:41 +080082
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]
Pierbbdf3782016-08-22 17:58:26 -070088 gv = verify_group_stats[i]
macauley_cheng67da9262015-08-31 15:18:41 +080089 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]
Pierbbdf3782016-08-22 17:58:26 -070093 b2=gv.buckets[j]
macauley_cheng67da9262015-08-31 15:18:41 +080094 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")
Pierbbdf3782016-08-22 17:58:26 -0700100
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)
Pierbbdf3782016-08-22 17:58:26 -0700115
macauley97557232015-07-16 17:28:07 +0800116def 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),
Pierbbdf3782016-08-22 17:58:26 -0700171 ]
macauley97557232015-07-16 17:28:07 +0800172 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)
Pierbbdf3782016-08-22 17:58:26 -0700191
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),
Pierbbdf3782016-08-22 17:58:26 -0700202 ]
macauley0f91a3e2015-07-17 18:09:59 +0800203 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)
Pierbbdf3782016-08-22 17:58:26 -0700221
macauley0f91a3e2015-07-17 18:09:59 +0800222 return group_id, request
Pierbbdf3782016-08-22 17:58:26 -0700223
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
Flavio Castroa7162bb2016-07-25 17:30:30 -0700254def mod_l2_flood_group(ctrl, ports, vlanid, id):
255 buckets=[]
256 for of_port in ports:
257 group_id = encode_l2_interface_group_id(vlanid, of_port)
258 action=[ofp.action.group(group_id)]
259 buckets.append(ofp.bucket(actions=action))
260
261 group_id =encode_l2_flood_group_id(vlanid, id)
262 request = ofp.message.group_modify(group_type=ofp.OFPGT_ALL,
263 group_id=group_id,
264 buckets=buckets
265 )
266 ctrl.message_send(request)
267 return request
268
269
macauley15909e72015-07-17 15:58:57 +0800270def add_l2_rewrite_group(ctrl, port, vlanid, id, src_mac, dst_mac):
271 group_id = encode_l2_interface_group_id(vlanid, port)
272
273 action=[]
274 if src_mac is not None:
275 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
276
277 if dst_mac is not None:
278 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
279
Flavio Castro91d1a552016-05-17 16:59:44 -0700280 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlanid)))
Pierbbdf3782016-08-22 17:58:26 -0700281
macauley15909e72015-07-17 15:58:57 +0800282 action.append(ofp.action.group(group_id))
Pierbbdf3782016-08-22 17:58:26 -0700283
macauley15909e72015-07-17 15:58:57 +0800284 buckets = [ofp.bucket(actions=action)]
285
286 group_id =encode_l2_rewrite_group_id(id)
287 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
288 group_id=group_id,
289 buckets=buckets
290 )
291 ctrl.message_send(request)
292 return request
Pierbbdf3782016-08-22 17:58:26 -0700293
macauley15909e72015-07-17 15:58:57 +0800294def add_l3_unicast_group(ctrl, port, vlanid, id, src_mac, dst_mac):
295 group_id = encode_l2_interface_group_id(vlanid, port)
296
297 action=[]
298 if src_mac is not None:
299 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
300
301 if dst_mac is not None:
302 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
303
Flavio Castroaf2b4502016-02-02 17:41:32 -0500304 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlanid)))
Pierbbdf3782016-08-22 17:58:26 -0700305
macauley15909e72015-07-17 15:58:57 +0800306 action.append(ofp.action.group(group_id))
Pierbbdf3782016-08-22 17:58:26 -0700307
macauley15909e72015-07-17 15:58:57 +0800308 buckets = [ofp.bucket(actions=action)]
309
310 group_id =encode_l3_unicast_group_id(id)
311 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
312 group_id=group_id,
313 buckets=buckets
314 )
315 ctrl.message_send(request)
316 return request
Pierbbdf3782016-08-22 17:58:26 -0700317
macauley15909e72015-07-17 15:58:57 +0800318def add_l3_interface_group(ctrl, port, vlanid, id, src_mac):
319 group_id = encode_l2_interface_group_id(vlanid, port)
320
321 action=[]
322 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
Pierbbdf3782016-08-22 17:58:26 -0700323 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlanid)))
macauley15909e72015-07-17 15:58:57 +0800324 action.append(ofp.action.group(group_id))
Pierbbdf3782016-08-22 17:58:26 -0700325
macauley15909e72015-07-17 15:58:57 +0800326 buckets = [ofp.bucket(actions=action)]
327
328 group_id =encode_l3_interface_group_id(id)
329 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
330 group_id=group_id,
331 buckets=buckets
332 )
333 ctrl.message_send(request)
334 return request
335
336def add_l3_ecmp_group(ctrl, id, l3_ucast_groups):
337 buckets=[]
338 for group in l3_ucast_groups:
339 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
340
341 group_id =encode_l3_ecmp_group_id(id)
342 request = ofp.message.group_add(group_type=ofp.OFPGT_SELECT,
343 group_id=group_id,
344 buckets=buckets
345 )
346 ctrl.message_send(request)
347 return request
Flavio Castroa7162bb2016-07-25 17:30:30 -0700348
349def mod_l3_ecmp_group(ctrl, id, l3_ucast_groups):
350 buckets=[]
351 for group in l3_ucast_groups:
352 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
353
354 group_id =encode_l3_ecmp_group_id(id)
355 request = ofp.message.group_modify(group_type=ofp.OFPGT_SELECT,
356 group_id=group_id,
357 buckets=buckets
358 )
359 ctrl.message_send(request)
360 return request
361
macauley15909e72015-07-17 15:58:57 +0800362def add_l3_mcast_group(ctrl, vid, mcast_group_id, groups_on_buckets):
363 buckets=[]
364 for group in groups_on_buckets:
365 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
Pierbbdf3782016-08-22 17:58:26 -0700366
macauley15909e72015-07-17 15:58:57 +0800367 group_id =encode_l3_mcast_group_id(vid, mcast_group_id)
368 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
369 group_id=group_id,
370 buckets=buckets
371 )
372 ctrl.message_send(request)
373 return request
macauleyfddc4662015-07-27 17:40:30 +0800374
375def add_l2_overlay_flood_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
376 buckets=[]
377 for port in ports:
378 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
379
380 group_id=encode_l2_overlay_group_id(tunnel_id, 0, index)
381 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
382 group_id=group_id,
383 buckets=buckets
384 )
385 ctrl.message_send(request)
386 return request
387
388def add_l2_overlay_flood_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
389 buckets=[]
390 for port in ports:
391 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
392
393 group_id=encode_l2_overlay_group_id(tunnel_id, 1, index)
394 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
395 group_id=group_id,
396 buckets=buckets
397 )
398 ctrl.message_send(request)
399 return request
400
401def add_l2_overlay_mcast_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
402 buckets=[]
403 for port in ports:
404 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
405
406 group_id=encode_l2_overlay_group_id(tunnel_id, 2, index)
407 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
408 group_id=group_id,
409 buckets=buckets
410 )
411 ctrl.message_send(request)
412 return request
413
414def add_l2_overlay_mcast_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
415 buckets=[]
416 for port in ports:
417 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
418
419 group_id=encode_l2_overlay_group_id(tunnel_id, 3, index)
420 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
421 group_id=group_id,
422 buckets=buckets
423 )
424 ctrl.message_send(request)
425 return request
Pierbbdf3782016-08-22 17:58:26 -0700426
macauleyfddc4662015-07-27 17:40:30 +0800427def add_port_table_flow(ctrl, is_overlay=True):
428 match = ofp.match()
429
430 if is_overlay == True:
431 match.oxm_list.append(ofp.oxm.in_port(0x10000))
macauleydbff3272015-07-30 14:07:16 +0800432 NEXT_TABLE=50
macauleyfddc4662015-07-27 17:40:30 +0800433 else:
434 match.oxm_list.append(ofp.oxm.in_port(0))
Pierbbdf3782016-08-22 17:58:26 -0700435 NEXT_TABLE=10
macauleyfddc4662015-07-27 17:40:30 +0800436
437 request = ofp.message.flow_add(
438 table_id=0,
439 cookie=42,
440 match=match,
441 instructions=[
macauleydbff3272015-07-30 14:07:16 +0800442 ofp.instruction.goto_table(NEXT_TABLE)
macauleyfddc4662015-07-27 17:40:30 +0800443 ],
444 priority=0)
445 logging.info("Add port table, match port %lx" % 0x10000)
446 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -0700447
Flavio Castrod8f8af22015-12-02 18:19:26 -0500448
449def pop_vlan_flow(ctrl, ports, vlan_id=1):
450 # table 10: vlan
451 # goto to table 20
452 msgs=[]
453 for of_port in ports:
454 match = ofp.match()
455 match.oxm_list.append(ofp.oxm.in_port(of_port))
456 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
457 request = ofp.message.flow_add(
458 table_id=10,
459 cookie=42,
460 match=match,
461 instructions=[
462 ofp.instruction.apply_actions(
463 actions=[
464 ofp.action.pop_vlan()
465 ]
466 ),
467 ofp.instruction.goto_table(20)
468 ],
469 priority=0)
470 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
471 ctrl.message_send(request)
472
473
474 return msgs
macauleyfddc4662015-07-27 17:40:30 +0800475
macauley97557232015-07-16 17:28:07 +0800476def add_vlan_table_flow(ctrl, ports, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
477 # table 10: vlan
478 # goto to table 20
macauley15909e72015-07-17 15:58:57 +0800479 msgs=[]
macauley97557232015-07-16 17:28:07 +0800480 for of_port in ports:
Flavio Castro932014b2016-01-05 18:29:15 -0500481 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
macauley97557232015-07-16 17:28:07 +0800482 match = ofp.match()
483 match.oxm_list.append(ofp.oxm.in_port(of_port))
484 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
485 request = ofp.message.flow_add(
486 table_id=10,
487 cookie=42,
488 match=match,
489 instructions=[
Flavio Castrod8f8af22015-12-02 18:19:26 -0500490 ofp.instruction.apply_actions(
491 actions=[
492 ofp.action.pop_vlan()
493 ]
494 ),
macauley97557232015-07-16 17:28:07 +0800495 ofp.instruction.goto_table(20)
496 ],
497 priority=0)
498 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
499 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -0700500
macauley97557232015-07-16 17:28:07 +0800501 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
502 match = ofp.match()
503 match.oxm_list.append(ofp.oxm.in_port(of_port))
Flavio Castro12296312015-12-15 17:48:26 -0500504 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0x1fff))
macauley97557232015-07-16 17:28:07 +0800505 request = ofp.message.flow_add(
506 table_id=10,
507 cookie=42,
508 match=match,
509 instructions=[
510 ofp.instruction.apply_actions(
511 actions=[
Flavio Castroaf2b4502016-02-02 17:41:32 -0500512 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id))
macauley97557232015-07-16 17:28:07 +0800513 ]
514 ),
515 ofp.instruction.goto_table(20)
516 ],
517 priority=0)
518 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
519 ctrl.message_send(request)
macauley15909e72015-07-17 15:58:57 +0800520 msgs.append(request)
macauley97557232015-07-16 17:28:07 +0800521
Flavio Castro932014b2016-01-05 18:29:15 -0500522 if (flag == 4) :
523 match = ofp.match()
524 match.oxm_list.append(ofp.oxm.in_port(of_port))
525 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1fff))
526 request = ofp.message.flow_add(
527 table_id=10,
528 cookie=42,
529 match=match,
530 instructions=[
531 ofp.instruction.apply_actions(
532 actions=[
Flavio Castroaf2b4502016-02-02 17:41:32 -0500533 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id))
Flavio Castro932014b2016-01-05 18:29:15 -0500534 ]
535 ),
536 ofp.instruction.goto_table(20)
537 ],
538 priority=0)
539 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
540 ctrl.message_send(request)
541 msgs.append(request)
542
macauley97557232015-07-16 17:28:07 +0800543 if send_barrier:
544 do_barrier(ctrl)
545
macauley15909e72015-07-17 15:58:57 +0800546 return msgs
Pierbbdf3782016-08-22 17:58:26 -0700547
macauley_cheng6e6a6122015-11-16 14:19:18 +0800548def del_vlan_table_flow(ctrl, ports, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
549 # table 10: vlan
550 # goto to table 20
551 msgs=[]
552 for of_port in ports:
553 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
554 match = ofp.match()
555 match.oxm_list.append(ofp.oxm.in_port(of_port))
556 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
557 request = ofp.message.flow_delete(
558 table_id=10,
559 cookie=42,
560 match=match,
561 priority=0)
562 logging.info("Del vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
563 ctrl.message_send(request)
macauley0f91a3e2015-07-17 18:09:59 +0800564
macauley_cheng6e6a6122015-11-16 14:19:18 +0800565 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
566 match = ofp.match()
567 match.oxm_list.append(ofp.oxm.in_port(of_port))
568 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0xfff))
569 request = ofp.message.flow_delete(
570 table_id=10,
571 cookie=42,
572 match=match,
573 priority=0)
574 logging.info("Del vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
575 ctrl.message_send(request)
576 msgs.append(request)
577
578 if send_barrier:
579 do_barrier(ctrl)
580
581 return msgs
Pierbbdf3782016-08-22 17:58:26 -0700582
macauley_cheng6b311612015-09-04 11:32:27 +0800583def add_vlan_table_flow_pvid(ctrl, in_port, match_vid=None, pvid=1, send_barrier=False):
584 """it will tag pack as untagged packet wether it has tagg or not"""
585 match = ofp.match()
586 match.oxm_list.append(ofp.oxm.in_port(in_port))
587 actions=[]
588 if match_vid == None:
Pierbbdf3782016-08-22 17:58:26 -0700589 match.oxm_list.append(ofp.oxm.vlan_vid(0))
macauley_cheng6b311612015-09-04 11:32:27 +0800590 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+pvid)))
591 goto_table=20
592 else:
593 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+match_vid, 0x1fff))
594 actions.append(ofp.action.push_vlan(0x8100))
Pierbbdf3782016-08-22 17:58:26 -0700595 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+pvid)))
macauley_cheng6b311612015-09-04 11:32:27 +0800596 goto_table=20
Pierbbdf3782016-08-22 17:58:26 -0700597
macauley_cheng6b311612015-09-04 11:32:27 +0800598 request = ofp.message.flow_add(
599 table_id=10,
600 cookie=42,
601 match=match,
602 instructions=[
603 ofp.instruction.apply_actions(actions=actions)
604 ,ofp.instruction.goto_table(goto_table)
605 ],
606 priority=0)
607 logging.info("Add PVID %d on port %d and go to table %ld" %( pvid, in_port, goto_table))
Pierbbdf3782016-08-22 17:58:26 -0700608 ctrl.message_send(request)
609
macauley_cheng6b311612015-09-04 11:32:27 +0800610 if send_barrier:
611 do_barrier(ctrl)
612
613def add_vlan_table_flow_allow_all_vlan(ctrl, in_port, send_barrier=False):
614 """it st flow allow all vlan tag on this port"""
615 match = ofp.match()
616 match.oxm_list.append(ofp.oxm.in_port(in_port))
617 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1000))
618 request = ofp.message.flow_add(
619 table_id=10,
620 cookie=42,
621 match=match,
622 instructions=[
Pierbbdf3782016-08-22 17:58:26 -0700623 ofp.instruction.goto_table(20)
macauley_cheng6b311612015-09-04 11:32:27 +0800624 ],
625 priority=0)
626 logging.info("Add allow all vlan on port %d " %(in_port))
Pierbbdf3782016-08-22 17:58:26 -0700627 ctrl.message_send(request)
macauley_cheng6b311612015-09-04 11:32:27 +0800628
Pier7b031af2016-08-25 15:00:22 -0700629def add_one_vlan_table_flow_translation(ctrl, of_port, vlan_id=1, new_vlan_id=-1, vrf=0, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
630 # Install a flow for VLAN translation
631 # in VLAN table.
632 # table 10: vlan
633 # goto to table 20
634 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
635 match = ofp.match()
636 match.oxm_list.append(ofp.oxm.in_port(of_port))
637 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id,0x1fff))
638
639 actions=[]
640 if vrf!=0:
641 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
642 if new_vlan_id != -1:
643 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_vlan_id)))
644
645 request = ofp.message.flow_add(
646 table_id=10,
647 cookie=42,
648 match=match,
649 instructions=[
650 ofp.instruction.apply_actions(
651 actions=actions
652 ),
653 ofp.instruction.goto_table(20)
654 ],
655 priority=0)
656 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
657 ctrl.message_send(request)
658
macauley53d90fe2015-08-04 17:34:22 +0800659def 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 +0800660 # table 10: vlan
661 # goto to table 20
Flavio Castro932014b2016-01-05 18:29:15 -0500662 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
macauley0f91a3e2015-07-17 18:09:59 +0800663 match = ofp.match()
664 match.oxm_list.append(ofp.oxm.in_port(of_port))
Flavio Castro12296312015-12-15 17:48:26 -0500665 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id,0x1fff))
macauley7f89d962015-08-06 18:13:48 +0800666
667 actions=[]
668 if vrf!=0:
669 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
Pierbbdf3782016-08-22 17:58:26 -0700670
Flavio Castro6d498522015-12-15 14:05:04 -0500671 #actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(value=vlan_id)))
macauley7f89d962015-08-06 18:13:48 +0800672
macauley0f91a3e2015-07-17 18:09:59 +0800673 request = ofp.message.flow_add(
674 table_id=10,
675 cookie=42,
676 match=match,
677 instructions=[
macauley53d90fe2015-08-04 17:34:22 +0800678 ofp.instruction.apply_actions(
macauley7f89d962015-08-06 18:13:48 +0800679 actions=actions
macauley53d90fe2015-08-04 17:34:22 +0800680 ),
681 ofp.instruction.goto_table(20)
macauley0f91a3e2015-07-17 18:09:59 +0800682 ],
683 priority=0)
684 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
685 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -0700686
macauley0f91a3e2015-07-17 18:09:59 +0800687 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
688 match = ofp.match()
689 match.oxm_list.append(ofp.oxm.in_port(of_port))
Flavio Castro12296312015-12-15 17:48:26 -0500690 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0x1fff))
Pierbbdf3782016-08-22 17:58:26 -0700691
macauley7f89d962015-08-06 18:13:48 +0800692 actions=[]
693 if vrf!=0:
694 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
Pierbbdf3782016-08-22 17:58:26 -0700695
Flavio Castro91d1a552016-05-17 16:59:44 -0700696 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
Pierbbdf3782016-08-22 17:58:26 -0700697
macauley0f91a3e2015-07-17 18:09:59 +0800698 request = ofp.message.flow_add(
699 table_id=10,
700 cookie=42,
701 match=match,
702 instructions=[
703 ofp.instruction.apply_actions(
macauley7f89d962015-08-06 18:13:48 +0800704 actions=actions
macauley0f91a3e2015-07-17 18:09:59 +0800705 ),
706 ofp.instruction.goto_table(20)
707 ],
708 priority=0)
709 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
710 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -0700711
Flavio Castro932014b2016-01-05 18:29:15 -0500712 if (flag == 4) :
713 match = ofp.match()
714 match.oxm_list.append(ofp.oxm.in_port(of_port))
715 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000,0x1fff))
716
717 actions=[]
718 if vrf!=0:
719 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
720
Flavio Castro91d1a552016-05-17 16:59:44 -0700721 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
Flavio Castro932014b2016-01-05 18:29:15 -0500722
723 request = ofp.message.flow_add(
724 table_id=10,
725 cookie=42,
726 match=match,
727 instructions=[
728 ofp.instruction.apply_actions(
729 actions=actions
730 ),
731 ofp.instruction.goto_table(20)
732 ],
733 priority=0)
734 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
735 ctrl.message_send(request)
macauley0f91a3e2015-07-17 18:09:59 +0800736
737 if send_barrier:
738 do_barrier(ctrl)
739
740 return request
Pierbbdf3782016-08-22 17:58:26 -0700741
macauley97557232015-07-16 17:28:07 +0800742def add_bridge_flow(ctrl, dst_mac, vlanid, group_id, send_barrier=False):
743 match = ofp.match()
castroflavio21894482015-12-08 15:29:55 -0500744 priority=500
macauleyfddc4662015-07-27 17:40:30 +0800745 if dst_mac!=None:
castroflavio21894482015-12-08 15:29:55 -0500746 priority=1000
macauleyfddc4662015-07-27 17:40:30 +0800747 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
748
macauley97557232015-07-16 17:28:07 +0800749 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
macauleyfddc4662015-07-27 17:40:30 +0800750
macauley97557232015-07-16 17:28:07 +0800751 request = ofp.message.flow_add(
752 table_id=50,
753 cookie=42,
754 match=match,
755 instructions=[
756 ofp.instruction.write_actions(
757 actions=[
758 ofp.action.group(group_id)]),
759 ofp.instruction.goto_table(60)
760 ],
761 buffer_id=ofp.OFP_NO_BUFFER,
castroflavio21894482015-12-08 15:29:55 -0500762 priority=priority)
macauley97557232015-07-16 17:28:07 +0800763
764 logging.info("Inserting Brdige flow vlan %d, mac %s", vlanid, dst_mac)
765 ctrl.message_send(request)
766
767 if send_barrier:
Pierbbdf3782016-08-22 17:58:26 -0700768 do_barrier(ctrl)
macauley15909e72015-07-17 15:58:57 +0800769
Pierbbdf3782016-08-22 17:58:26 -0700770 return request
macauleyfddc4662015-07-27 17:40:30 +0800771
772def add_overlay_bridge_flow(ctrl, dst_mac, vnid, group_id, is_group=True, send_barrier=False):
773 match = ofp.match()
774 if dst_mac!=None:
775 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
776
777 match.oxm_list.append(ofp.oxm.tunnel_id(vnid))
778 if is_group == True:
779 actions=[ofp.action.group(group_id)]
780 else:
781 actions=[ofp.action.output(group_id)]
782
783 request = ofp.message.flow_add(
784 table_id=50,
785 cookie=42,
786 match=match,
787 instructions=[
788 ofp.instruction.write_actions(
789 actions=actions),
790 ofp.instruction.goto_table(60)
791 ],
792 buffer_id=ofp.OFP_NO_BUFFER,
Pierbbdf3782016-08-22 17:58:26 -0700793 priority=1000)
macauleyfddc4662015-07-27 17:40:30 +0800794
795 logging.info("Inserting Brdige flow vnid %d, mac %s", vnid, dst_mac)
796 ctrl.message_send(request)
797
798 if send_barrier:
Pierbbdf3782016-08-22 17:58:26 -0700799 do_barrier(ctrl)
macauleyfddc4662015-07-27 17:40:30 +0800800
Pierbbdf3782016-08-22 17:58:26 -0700801 return request
802
macauley_cheng6b133662015-11-09 13:52:39 +0800803def add_termination_flow(ctrl, in_port, eth_type, dst_mac, vlanid, goto_table=None, send_barrier=False):
macauley0f91a3e2015-07-17 18:09:59 +0800804 match = ofp.match()
macauley0f91a3e2015-07-17 18:09:59 +0800805 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
macauleyfddc4662015-07-27 17:40:30 +0800806 if dst_mac[0]&0x01 == 0x01:
807 match.oxm_list.append(ofp.oxm.eth_dst_masked(dst_mac, [0xff, 0xff, 0xff, 0x80, 0x00, 0x00]))
808 goto_table=40
809 else:
macauley53d90fe2015-08-04 17:34:22 +0800810 if in_port!=0:
811 match.oxm_list.append(ofp.oxm.in_port(in_port))
macauleyfddc4662015-07-27 17:40:30 +0800812 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
813 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
macauley_cheng6b133662015-11-09 13:52:39 +0800814 if goto_table == None:
815 goto_table=30
macauley0f91a3e2015-07-17 18:09:59 +0800816
817 request = ofp.message.flow_add(
818 table_id=20,
819 cookie=42,
820 match=match,
821 instructions=[
822 ofp.instruction.goto_table(goto_table)
823 ],
824 buffer_id=ofp.OFP_NO_BUFFER,
Pierbbdf3782016-08-22 17:58:26 -0700825 priority=1)
macauley0f91a3e2015-07-17 18:09:59 +0800826
827 logging.info("Inserting termination flow inport %d, eth_type %lx, vlan %d, mac %s", in_port, eth_type, vlanid, dst_mac)
828 ctrl.message_send(request)
829
830 if send_barrier:
Pierbbdf3782016-08-22 17:58:26 -0700831 do_barrier(ctrl)
macauley0f91a3e2015-07-17 18:09:59 +0800832
Pierbbdf3782016-08-22 17:58:26 -0700833 return request
834
Flavio Castroaf2b4502016-02-02 17:41:32 -0500835def 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 +0800836 match = ofp.match()
837 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
macauley53d90fe2015-08-04 17:34:22 +0800838 if vrf != 0:
839 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_VRF, vrf))
macauley0f91a3e2015-07-17 18:09:59 +0800840
Flavio Castroaf2b4502016-02-02 17:41:32 -0500841 match.oxm_list.append(ofp.oxm.ipv4_dst_masked(dst_ip, mask))
842
843 instructions = []
844 instructions.append(ofp.instruction.goto_table(60))
845 if send_ctrl:
Piere0918ec2016-09-09 20:06:05 -0700846 instructions.append(ofp.instruction.apply_actions(
Flavio Castroaf2b4502016-02-02 17:41:32 -0500847 actions=[ofp.action.output( port=ofp.OFPP_CONTROLLER,
848 max_len=ofp.OFPCML_NO_BUFFER)]))
Pierbbdf3782016-08-22 17:58:26 -0700849 else:
Flavio Castroaf2b4502016-02-02 17:41:32 -0500850 instructions.append(ofp.instruction.write_actions(
851 actions=[ofp.action.group(action_group_id)]))
macauley53d90fe2015-08-04 17:34:22 +0800852
macauley0f91a3e2015-07-17 18:09:59 +0800853 request = ofp.message.flow_add(
854 table_id=30,
855 cookie=42,
856 match=match,
Flavio Castroaf2b4502016-02-02 17:41:32 -0500857 instructions=instructions,
macauley0f91a3e2015-07-17 18:09:59 +0800858 buffer_id=ofp.OFP_NO_BUFFER,
Pierbbdf3782016-08-22 17:58:26 -0700859 priority=1)
macauley0f91a3e2015-07-17 18:09:59 +0800860
861 logging.info("Inserting unicast routing flow eth_type %lx, dip %ld",eth_type, dst_ip)
862 ctrl.message_send(request)
863
864 if send_barrier:
Pierbbdf3782016-08-22 17:58:26 -0700865 do_barrier(ctrl)
macauley0f91a3e2015-07-17 18:09:59 +0800866
Flavio Castro9debaaa2016-07-26 19:37:50 -0700867 return request
Flavio Castrod8f8af22015-12-02 18:19:26 -0500868
Flavio Castro8ca52542016-04-11 11:24:49 -0400869def 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 -0400870 match = ofp.match()
871 match.oxm_list.append(ofp.oxm.eth_type(0x8847))
872 match.oxm_list.append(ofp.oxm.mpls_label(label))
873 match.oxm_list.append(ofp.oxm.mpls_bos(bos))
874 actions = [ofp.action.dec_mpls_ttl(),
Flavio Castro8ca52542016-04-11 11:24:49 -0400875 ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf))]
876 if (goto_table == 29):
Flavio Castro8ca52542016-04-11 11:24:49 -0400877 actions.append(ofp.action.group(action_group_id))
878 else:
Flavio Castrod80fbc32016-07-25 15:54:26 -0700879 actions.append(ofp.action.set_field(
880 ofp.oxm.exp2ByteValue(exp_type=23, value=32)))
881 actions.append(ofp.action.group(action_group_id))
Flavio Castro8ca52542016-04-11 11:24:49 -0400882 actions.append(ofp.action.copy_ttl_in())
Flavio Castro9debaaa2016-07-26 19:37:50 -0700883
Flavio Castrob702a2f2016-04-10 22:01:48 -0400884 request = ofp.message.flow_add(
885 table_id=24,
886 cookie=43,
887 match=match,
888 instructions=[
Flavio Castro8ca52542016-04-11 11:24:49 -0400889 ofp.instruction.apply_actions(actions=actions),
890 ofp.instruction.goto_table(goto_table)
Flavio Castrob702a2f2016-04-10 22:01:48 -0400891 ],
892 buffer_id=ofp.OFP_NO_BUFFER,
893 priority=1)
Flavio Castrob702a2f2016-04-10 22:01:48 -0400894 logging.info("Inserting MPLS flow , label %ld", label)
895 ctrl.message_send(request)
896
897 if send_barrier:
898 do_barrier(ctrl)
899
900 return request
901
macauleyfddc4662015-07-27 17:40:30 +0800902def add_mcast4_routing_flow(ctrl, vlan_id, src_ip, src_ip_mask, dst_ip, action_group_id, send_barrier=False):
903 match = ofp.match()
904 match.oxm_list.append(ofp.oxm.eth_type(0x0800))
Pierbbdf3782016-08-22 17:58:26 -0700905 match.oxm_list.append(ofp.oxm.vlan_vid(vlan_id))
macauleyfddc4662015-07-27 17:40:30 +0800906 if src_ip_mask!=0:
907 match.oxm_list.append(ofp.oxm.ipv4_src_masked(src_ip, src_ip_mask))
908 else:
909 match.oxm_list.append(ofp.oxm.ipv4_src(src_ip))
Pierbbdf3782016-08-22 17:58:26 -0700910
macauleyfddc4662015-07-27 17:40:30 +0800911 match.oxm_list.append(ofp.oxm.ipv4_dst(dst_ip))
Pierbbdf3782016-08-22 17:58:26 -0700912
macauleyfddc4662015-07-27 17:40:30 +0800913 request = ofp.message.flow_add(
914 table_id=40,
915 cookie=42,
916 match=match,
917 instructions=[
918 ofp.instruction.write_actions(
919 actions=[ofp.action.group(action_group_id)]),
920 ofp.instruction.goto_table(60)
921 ],
922 buffer_id=ofp.OFP_NO_BUFFER,
Pierbbdf3782016-08-22 17:58:26 -0700923 priority=1)
macauleyfddc4662015-07-27 17:40:30 +0800924
925 logging.info("Inserting mcast routing flow eth_type %lx, dip %lx, sip %lx, sip_mask %lx",0x0800, dst_ip, src_ip, src_ip_mask)
926 ctrl.message_send(request)
927
928 if send_barrier:
Pierbbdf3782016-08-22 17:58:26 -0700929 do_barrier(ctrl)
macauleyfddc4662015-07-27 17:40:30 +0800930
Pierbbdf3782016-08-22 17:58:26 -0700931 return request
macauley_cheng6b133662015-11-09 13:52:39 +0800932
933#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 +0800934def 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 +0800935 match = ofp.match()
936 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
937 match.oxm_list.append(ofp.oxm.ipv4_dst(ip_dst))
938 match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
939 match.oxm_list.append(ofp.oxm.tcp_dst(tcp_dst))
Pierbbdf3782016-08-22 17:58:26 -0700940
macauley_cheng6b133662015-11-09 13:52:39 +0800941 request = ofp.message.flow_add(
942 table_id=28,
943 cookie=42,
944 match=match,
945 instructions=[
946 ofp.instruction.write_actions(
947 actions=[ofp.action.set_field(ofp.oxm.ipv4_dst(set_ip_dst)),
948 ofp.action.set_field(ofp.oxm.tcp_dst(set_tcp_dst)),
949 ofp.action.group(action_group_id)]),
950 ofp.instruction.goto_table(60)
951 ],
952 buffer_id=ofp.OFP_NO_BUFFER,
Pierbbdf3782016-08-22 17:58:26 -0700953 priority=1)
macauley_cheng6b133662015-11-09 13:52:39 +0800954 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)
955 ctrl.message_send(request)
956 return request
macauley_chengeffc20a2015-11-09 16:14:56 +0800957
958#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
959def add_snat_flow(ctrl, eth_type, ip_src, ip_proto, tcp_src, set_ip_src, set_tcp_src):
960 match = ofp.match()
961 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
962 match.oxm_list.append(ofp.oxm.ipv4_src(ip_src))
963 match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
964 match.oxm_list.append(ofp.oxm.tcp_src(tcp_src))
Pierbbdf3782016-08-22 17:58:26 -0700965
macauley_chengeffc20a2015-11-09 16:14:56 +0800966 request = ofp.message.flow_add(
967 table_id=29,
968 cookie=42,
969 match=match,
970 instructions=[
971 ofp.instruction.write_actions(
972 actions=[ofp.action.set_field(ofp.oxm.ipv4_src(set_ip_src)),
973 ofp.action.set_field(ofp.oxm.tcp_src(set_tcp_src))]),
974 ofp.instruction.goto_table(30)
975 ],
976 buffer_id=ofp.OFP_NO_BUFFER,
Pierbbdf3782016-08-22 17:58:26 -0700977 priority=1)
macauley_chengeffc20a2015-11-09 16:14:56 +0800978 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)
979 ctrl.message_send(request)
980 return request
Pierbbdf3782016-08-22 17:58:26 -0700981
982def get_vtap_lport_config_xml(dp_id, lport, phy_port, vlan, vnid, operation='merge'):
macauleyfddc4662015-07-27 17:40:30 +0800983 """
984 Command Example:
985 of-agent vtap 10001 ethernet 1/1 vid 1
986 of-agent vtp 10001 vni 10
987 """
988 if vlan != 0:
989 config_vtap_xml="""
990 <config>
991 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
992 <id>capable-switch-1</id>
993 <resources>
994 <port xc:operation="OPERATION">
Pierbbdf3782016-08-22 17:58:26 -0700995 <resource-id >LPORT</resource-id>
macauleyfddc4662015-07-27 17:40:30 +0800996 <features>
997 <current>
998 <rate>10Gb</rate>
999 <medium>fiber</medium>
Pierbbdf3782016-08-22 17:58:26 -07001000 <pause>symmetric</pause>
macauleyfddc4662015-07-27 17:40:30 +08001001 </current>
1002 <advertised>
1003 <rate>10Gb</rate>
1004 <rate>100Gb</rate>
1005 <medium>fiber</medium>
1006 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001007 </advertised>
macauleyfddc4662015-07-27 17:40:30 +08001008 <supported>
1009 <rate>10Gb</rate>
1010 <rate>100Gb</rate>
1011 <medium>fiber</medium>
1012 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001013 </supported>
macauleyfddc4662015-07-27 17:40:30 +08001014 <advertised-peer>
1015 <rate>10Gb</rate>
1016 <rate>100Gb</rate>
1017 <medium>fiber</medium>
1018 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001019 </advertised-peer>
macauleyfddc4662015-07-27 17:40:30 +08001020 </features>
1021 <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1022 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
1023 <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
1024 <ofdpa10:vni>VNID</ofdpa10:vni>
1025 </ofdpa10:vtap>
Pierbbdf3782016-08-22 17:58:26 -07001026 </port>
macauleyfddc4662015-07-27 17:40:30 +08001027 </resources>
1028 <logical-switches>
1029 <switch>
1030 <id>DATAPATH_ID</id>
1031 <datapath-id>DATAPATH_ID</datapath-id>
1032 <resources>
1033 <port xc:operation="OPERATION">LPORT</port>
1034 </resources>
1035 </switch>
1036 </logical-switches>
1037 </capable-switch>
1038 </config>
Pierbbdf3782016-08-22 17:58:26 -07001039 """
macauleyfddc4662015-07-27 17:40:30 +08001040 else:
1041 config_vtap_xml="""
1042 <config>
1043 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1044 <id>capable-switch-1</id>
1045 <resources>
1046 <port xc:operation="OPERATION">
Pierbbdf3782016-08-22 17:58:26 -07001047 <resource-id >LPORT</resource-id>
macauleyfddc4662015-07-27 17:40:30 +08001048 <features>
1049 <current>
1050 <rate>10Gb</rate>
1051 <medium>fiber</medium>
Pierbbdf3782016-08-22 17:58:26 -07001052 <pause>symmetric</pause>
macauleyfddc4662015-07-27 17:40:30 +08001053 </current>
1054 <advertised>
1055 <rate>10Gb</rate>
1056 <rate>100Gb</rate>
1057 <medium>fiber</medium>
1058 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001059 </advertised>
macauleyfddc4662015-07-27 17:40:30 +08001060 <supported>
1061 <rate>10Gb</rate>
1062 <rate>100Gb</rate>
1063 <medium>fiber</medium>
1064 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001065 </supported>
macauleyfddc4662015-07-27 17:40:30 +08001066 <advertised-peer>
1067 <rate>10Gb</rate>
1068 <rate>100Gb</rate>
1069 <medium>fiber</medium>
1070 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001071 </advertised-peer>
macauleyfddc4662015-07-27 17:40:30 +08001072 </features>
1073 <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1074 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
1075 <ofdpa10:vni>VNID</ofdpa10:vni>
1076 </ofdpa10:vtap>
Pierbbdf3782016-08-22 17:58:26 -07001077 </port>
macauleyfddc4662015-07-27 17:40:30 +08001078 </resources>
1079 <logical-switches>
1080 <switch>
1081 <id>DATAPATH_ID</id>
1082 <datapath-id>DATAPATH_ID</datapath-id>
1083 <resources>
1084 <port xc:operation="OPERATION">LPORT</port>
1085 </resources>
1086 </switch>
1087 </logical-switches>
1088 </capable-switch>
1089 </config>
Pierbbdf3782016-08-22 17:58:26 -07001090 """
1091 str_datapath_id_f= "{:016x}".format(dp_id)
1092 str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
1093 config_vtap_xml=config_vtap_xml.replace("DATAPATH_ID", str_datapath_id)
1094 config_vtap_xml=config_vtap_xml.replace("LPORT", str(int(lport)))
1095 config_vtap_xml=config_vtap_xml.replace("PHY_PORT", str(phy_port))
1096 config_vtap_xml=config_vtap_xml.replace("VLAN_ID", str(vlan))
macauleyfddc4662015-07-27 17:40:30 +08001097 config_vtap_xml=config_vtap_xml.replace("VNID", str(vnid))
1098 config_vtap_xml=config_vtap_xml.replace("OPERATION", str(operation))
1099 return config_vtap_xml
Pierbbdf3782016-08-22 17:58:26 -07001100
1101def get_vtep_lport_config_xml(dp_id, lport, src_ip, dst_ip, next_hop_id, vnid, udp_src_port=6633, ttl=25, operation='merge'):
macauleyfddc4662015-07-27 17:40:30 +08001102 """
1103 Command Example:
1104 of-agent vtep 10002 source user-input-src-ip destination user-input-dst-ip udp-source-port 6633 nexthop 2 ttl 25
Pierbbdf3782016-08-22 17:58:26 -07001105 of-agent vtp 10001 vni 10
macauleyfddc4662015-07-27 17:40:30 +08001106 """
1107
1108 config_vtep_xml="""
1109 <config>
1110 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1111 <id>capable-switch-1</id>
1112 <resources>
1113 <port xc:operation="OPERATION">
Pierbbdf3782016-08-22 17:58:26 -07001114 <resource-id>LPORT</resource-id>
macauleyfddc4662015-07-27 17:40:30 +08001115 <features>
1116 <current>
1117 <rate>10Gb</rate>
1118 <medium>fiber</medium>
Pierbbdf3782016-08-22 17:58:26 -07001119 <pause>symmetric</pause>
macauleyfddc4662015-07-27 17:40:30 +08001120 </current>
1121 <advertised>
1122 <rate>10Gb</rate>
1123 <rate>100Gb</rate>
1124 <medium>fiber</medium>
1125 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001126 </advertised>
macauleyfddc4662015-07-27 17:40:30 +08001127 <supported>
1128 <rate>10Gb</rate>
1129 <rate>100Gb</rate>
1130 <medium>fiber</medium>
1131 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001132 </supported>
macauleyfddc4662015-07-27 17:40:30 +08001133 <advertised-peer>
1134 <rate>10Gb</rate>
1135 <rate>100Gb</rate>
1136 <medium>fiber</medium>
1137 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001138 </advertised-peer>
macauleyfddc4662015-07-27 17:40:30 +08001139 </features>
1140 <ofdpa10:vtep xmlns:ofdpa10="urn:bcm:ofdpa10:accton01">
1141 <ofdpa10:src-ip>SRC_IP</ofdpa10:src-ip>
1142 <ofdpa10:dest-ip>DST_IP</ofdpa10:dest-ip>
1143 <ofdpa10:udp-src-port>UDP_SRC_PORT</ofdpa10:udp-src-port>
macauley25999cf2015-08-07 17:03:24 +08001144 <ofdpa10:vni xc:operation="OPERATION">
1145 <ofdpa10:id>VNID</ofdpa10:id>
1146 </ofdpa10:vni>
macauleyfddc4662015-07-27 17:40:30 +08001147 <ofdpa10:nexthop-id>NEXT_HOP_ID</ofdpa10:nexthop-id>
1148 <ofdpa10:ttl>TTL</ofdpa10:ttl>
1149 </ofdpa10:vtep>
Pierbbdf3782016-08-22 17:58:26 -07001150 </port>
macauleyfddc4662015-07-27 17:40:30 +08001151 </resources>
1152 <logical-switches>
1153 <switch>
1154 <id>DATAPATH_ID</id>
1155 <datapath-id>DATAPATH_ID</datapath-id>
1156 <resources>
1157 <port xc:operation="OPERATION">LPORT</port>
1158 </resources>
1159 </switch>
1160 </logical-switches>
1161 </capable-switch>
Pierbbdf3782016-08-22 17:58:26 -07001162 </config>
macauleyfddc4662015-07-27 17:40:30 +08001163 """
Pierbbdf3782016-08-22 17:58:26 -07001164 str_datapath_id_f= "{:016x}".format(dp_id)
1165 str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
1166 config_vtep_xml=config_vtep_xml.replace("DATAPATH_ID", str_datapath_id)
macauley25999cf2015-08-07 17:03:24 +08001167 config_vtep_xml=config_vtep_xml.replace("LPORT", str(int(lport)))
Pierbbdf3782016-08-22 17:58:26 -07001168 config_vtep_xml=config_vtep_xml.replace("SRC_IP", str(src_ip))
1169 config_vtep_xml=config_vtep_xml.replace("DST_IP", str(dst_ip))
1170 config_vtep_xml=config_vtep_xml.replace("UDP_SRC_PORT", str(udp_src_port))
1171 config_vtep_xml=config_vtep_xml.replace("NEXT_HOP_ID", str(next_hop_id))
1172 config_vtep_xml=config_vtep_xml.replace("TTL", str(ttl))
macauleyfddc4662015-07-27 17:40:30 +08001173 config_vtep_xml=config_vtep_xml.replace("VNID", str(vnid))
Pierbbdf3782016-08-22 17:58:26 -07001174 config_vtep_xml=config_vtep_xml.replace("OPERATION", str(operation))
macauleyfddc4662015-07-27 17:40:30 +08001175
Pierbbdf3782016-08-22 17:58:26 -07001176 return config_vtep_xml
1177
1178def get_next_hop_config_xml(next_hop_id, dst_mac, phy_port, vlan, operation='merge'):
macauleyfddc4662015-07-27 17:40:30 +08001179 #of-agent nexthop 2 destination user-input-dst-mac ethernet 1/2 vid 2
1180 config_nexthop_xml="""
1181 <config>
1182 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1183 <ofdpa10:next-hop xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1184 <ofdpa10:id>NEXT_HOP_ID</ofdpa10:id>
1185 <ofdpa10:dest-mac>DST_MAC</ofdpa10:dest-mac>
1186 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
1187 <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
1188 </ofdpa10:next-hop>
1189 </of11-config:capable-switch>
1190 </config>
1191 """
1192 config_nexthop_xml=config_nexthop_xml.replace("VLAN_ID", str(vlan))
Pierbbdf3782016-08-22 17:58:26 -07001193 config_nexthop_xml=config_nexthop_xml.replace("PHY_PORT", str(phy_port))
1194 config_nexthop_xml=config_nexthop_xml.replace("NEXT_HOP_ID", str(next_hop_id))
1195 config_nexthop_xml=config_nexthop_xml.replace("DST_MAC", str(dst_mac))
1196 config_nexthop_xml=config_nexthop_xml.replace("OPERATION", str(operation))
1197 return config_nexthop_xml
macauleyfddc4662015-07-27 17:40:30 +08001198
Pierbbdf3782016-08-22 17:58:26 -07001199def get_vni_config_xml(vni_id, mcast_ipv4, next_hop_id, operation='merge'):
macauleyfddc4662015-07-27 17:40:30 +08001200 #of-agent vni 10 multicast 224.1.1.1 nexthop 20
Pierbbdf3782016-08-22 17:58:26 -07001201 if mcast_ipv4!=None:
macauleyfddc4662015-07-27 17:40:30 +08001202 config_vni_xml="""
1203 <config>
1204 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1205 <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1206 <ofdpa10:id>VNID</ofdpa10:id>
1207 <ofdpa10:vni-multicast-group>MCAST_IP</ofdpa10:vni-multicast-group>
1208 <ofdpa10:multicast-group-nexthop-id>NEXT_HOP_ID</ofdpa10:multicast-group-nexthop-id>
1209 </ofdpa10:vni>
1210 </of11-config:capable-switch>
1211 </config>
Pierbbdf3782016-08-22 17:58:26 -07001212 """
1213 config_vni_xml=config_vni_xml.replace("NEXT_HOP_ID", str(next_hop_id))
1214 config_vni_xml=config_vni_xml.replace("MCAST_IP", str(mcast_ipv4))
macauleyfddc4662015-07-27 17:40:30 +08001215 else:
1216 config_vni_xml="""
1217 <config>
1218 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1219 <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1220 <ofdpa10:id>VNID</ofdpa10:id>
1221 </ofdpa10:vni>
1222 </of11-config:capable-switch>
1223 </config>
Pierbbdf3782016-08-22 17:58:26 -07001224 """
1225
1226 config_vni_xml=config_vni_xml.replace("VNID", str(vni_id))
1227 config_vni_xml=config_vni_xml.replace("OPERATION", str(operation))
macauleyfddc4662015-07-27 17:40:30 +08001228 return config_vni_xml
Pierbbdf3782016-08-22 17:58:26 -07001229
1230def get_featureReplay(self):
macauleyfddc4662015-07-27 17:40:30 +08001231 req = ofp.message.features_request()
1232 res, raw = self.controller.transact(req)
Pierbbdf3782016-08-22 17:58:26 -07001233 self.assertIsNotNone(res, "Did not receive a response from the DUT.")
macauleyfddc4662015-07-27 17:40:30 +08001234 self.assertEqual(res.type, ofp.OFPT_FEATURES_REPLY,
1235 ("Unexpected packet type %d received in response to "
1236 "OFPT_FEATURES_REQUEST") % res.type)
Pierbbdf3782016-08-22 17:58:26 -07001237 return res
1238
macauleyfddc4662015-07-27 17:40:30 +08001239def send_edit_config(switch_ip, xml, target='runing'):
1240 NETCONF_ACCOUNT="netconfuser"
1241 NETCONF_PASSWD="netconfuser"
1242 with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
1243 try:
Pierbbdf3782016-08-22 17:58:26 -07001244 m.edit_config(target='running',
1245 config=xml,
1246 default_operation='merge',
macauleyfddc4662015-07-27 17:40:30 +08001247 error_option='stop-on-error')
1248
1249 except Exception as e:
1250 logging.info("Fail to set xml %s", xml)
1251 return False
1252
1253 #return m.get_config(source='running').data_xml
1254 return True
1255
1256def send_delete_config(switch_ip, xml, target='runing'):
1257 NETCONF_ACCOUNT="netconfuser"
1258 NETCONF_PASSWD="netconfuser"
1259 with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
1260 try:
Pierbbdf3782016-08-22 17:58:26 -07001261 m.edit_config(target='running',
1262 config=xml,
1263 default_operation='delete',
macauleyfddc4662015-07-27 17:40:30 +08001264 error_option='stop-on-error')
1265
1266 except Exception as e:
1267 logging.info("Fail to set xml %s", xml)
1268 return False
1269
1270 #return m.get_config(source='running').data_xml
1271 return True
Pierbbdf3782016-08-22 17:58:26 -07001272
macauleyfddc4662015-07-27 17:40:30 +08001273def get_edit_config(switch_ip, target='runing'):
1274 NETCONF_ACCOUNT="netconfuser"
1275 NETCONF_PASSWD="netconfuser"
1276 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 +08001277 return m.get_config(source='running').data_xml
macauleydbff3272015-07-30 14:07:16 +08001278
macauley_cheng67da9262015-08-31 15:18:41 +08001279
1280"""
1281MPLS
1282"""
1283
1284OFDPA_MPLS_SUBTYPE_SHIFT=24
Pierbbdf3782016-08-22 17:58:26 -07001285OFDPA_MPLS_GROUP_SUBTYPE_L2_VPN_LABEL=1
macauley_cheng67da9262015-08-31 15:18:41 +08001286OFDPA_MPLS_GROUP_SUBTYPE_L3_VPN_LABEL=2
1287OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL1=3
1288OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL2=4
1289OFDPA_MPLS_GROUP_SUBTYPE_SWAP_LABEL=5
1290OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP=6
1291OFDPA_MPLS_GROUP_SUBTYPE_ECMP=8
1292OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG=10
1293
1294def encode_mpls_interface_group_id(subtype, index):
1295 index=index&0x00ffffff
1296 assert(subtype==0)
1297 return index + (9 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
1298
1299def encode_mpls_label_group_id(subtype, index):
1300 index=index&0x00ffffff
1301 assert(subtype <=5 or subtype==0)
1302 #1: l2 vpn label
1303 #2: l3 vpn label
1304 #3: mpls tunnel label 1
1305 #4: mpls tunnel lable 2
1306 #5: mpls swap label
Pierbbdf3782016-08-22 17:58:26 -07001307 return index + (9 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
macauley_cheng67da9262015-08-31 15:18:41 +08001308
1309def encode_mpls_forwarding_group_id(subtype, index):
1310 index=index&0x00ffffff
1311 assert(subtype==6 or subtype==8 or subtype==10)
Pierbbdf3782016-08-22 17:58:26 -07001312 return index + (10 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
macauley_cheng67da9262015-08-31 15:18:41 +08001313
1314
1315def add_mpls_intf_group(ctrl, ref_gid, dst_mac, src_mac, vid, index, subtype=0):
1316 action=[]
1317 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
1318 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
Pierbbdf3782016-08-22 17:58:26 -07001319 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vid)))
macauley_cheng67da9262015-08-31 15:18:41 +08001320 action.append(ofp.action.group(ref_gid))
Pierbbdf3782016-08-22 17:58:26 -07001321
macauley_cheng67da9262015-08-31 15:18:41 +08001322 buckets = [ofp.bucket(actions=action)]
1323
1324 mpls_group_id =encode_mpls_interface_group_id(subtype, index)
1325 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
1326 group_id=mpls_group_id,
1327 buckets=buckets
1328 )
1329 ctrl.message_send(request)
1330 return mpls_group_id, request
1331
Pierbbdf3782016-08-22 17:58:26 -07001332def add_mpls_label_group(ctrl, subtype, index, ref_gid,
macauley_cheng67da9262015-08-31 15:18:41 +08001333 lmep_id=-1,
1334 qos_index=-1,
1335 push_l2_header=False,
1336 push_vlan=False,
1337 push_mpls_header=False,
1338 push_cw=False,
1339 set_mpls_label=None,
1340 set_bos=None,
1341 set_tc=None,
1342 set_tc_from_table=False,
1343 cpy_tc_outward=False,
1344 set_ttl=None,
1345 cpy_ttl_outward=False,
1346 oam_lm_tx_count=False,
1347 set_pri_from_table=False
1348 ):
1349 """
1350 @ref_gid: only can be mpls intf group or mpls tunnel label 1/2 group
Pierbbdf3782016-08-22 17:58:26 -07001351 """
macauley_cheng67da9262015-08-31 15:18:41 +08001352 action=[]
1353
1354 if push_vlan== True:
1355 action.append(ofp.action.push_vlan(0x8100))
1356 if push_mpls_header== True:
1357 action.append(ofp.action.push_mpls(0x8847))
1358 if set_mpls_label != None:
1359 action.append(ofp.action.set_field(ofp.oxm.mpls_label(set_mpls_label)))
1360 if set_bos != None:
1361 action.append(ofp.action.set_field(ofp.oxm.mpls_bos(set_bos)))
1362 if set_tc != None:
1363 assert(set_tc_from_table==False)
1364 action.append(ofp.action.set_field(ofp.oxm.mpls_tc(set_tc)))
1365 if set_ttl != None:
Pierbbdf3782016-08-22 17:58:26 -07001366 action.append(ofp.action.set_mpls_ttl(set_ttl))
macauley_cheng67da9262015-08-31 15:18:41 +08001367 if cpy_ttl_outward == True:
Pierbbdf3782016-08-22 17:58:26 -07001368 action.append(ofp.action.copy_ttl_out())
macauley_cheng67da9262015-08-31 15:18:41 +08001369 """
1370 ofdpa experimenter
Pierbbdf3782016-08-22 17:58:26 -07001371 """
macauley_cheng67da9262015-08-31 15:18:41 +08001372 if push_l2_header== True:
Pierbbdf3782016-08-22 17:58:26 -07001373 action.append(ofp.action.ofdpa_push_l2_header())
macauley_cheng67da9262015-08-31 15:18:41 +08001374 if set_tc_from_table== True:
1375 assert(qos_index>=0)
1376 assert(set_tc == None)
Pierbbdf3782016-08-22 17:58:26 -07001377 action.append(ofp.action.ofdpa_set_tc_from_table(qos_index))
macauley_cheng67da9262015-08-31 15:18:41 +08001378 if cpy_tc_outward == True:
Pierbbdf3782016-08-22 17:58:26 -07001379 action.append(ofp.action.ofdpa_copy_tc_out())
macauley_cheng67da9262015-08-31 15:18:41 +08001380 if oam_lm_tx_count == True:
Pierbbdf3782016-08-22 17:58:26 -07001381 assert(qos_index>=0 and lmep_id>=0)
1382 action.append(ofp.action.ofdpa_oam_lm_tx_count(lmep_id, qos_index))
macauley_cheng67da9262015-08-31 15:18:41 +08001383 if set_pri_from_table == True:
Pierbbdf3782016-08-22 17:58:26 -07001384 assert(qos_index>=0)
1385 action.append(ofp.action.ofdpa_set_qos_from_table(qos_index))
macauley_cheng67da9262015-08-31 15:18:41 +08001386 if push_cw == True:
1387 action.append(ofp.action.ofdpa_push_cw())
Pierbbdf3782016-08-22 17:58:26 -07001388
1389 action.append(ofp.action.group(ref_gid))
macauley_cheng67da9262015-08-31 15:18:41 +08001390 buckets = [ofp.bucket(actions=action)]
Pierbbdf3782016-08-22 17:58:26 -07001391
macauley_cheng67da9262015-08-31 15:18:41 +08001392 mpls_group_id = encode_mpls_label_group_id(subtype, index)
1393 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
1394 group_id=mpls_group_id,
1395 buckets=buckets
1396 )
1397 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -07001398
1399 return mpls_group_id, request
1400
1401def add_mpls_forwarding_group(ctrl, subtype, index, ref_gids,
1402 watch_port=None,
1403 watch_group=ofp.OFPP_ANY,
macauley_cheng67da9262015-08-31 15:18:41 +08001404 push_vlan=None,
macauley_chengd17ce512015-08-31 17:45:51 +08001405 pop_vlan=None,
macauley_cheng67da9262015-08-31 15:18:41 +08001406 set_vid=None):
1407 assert(subtype == OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP
1408 or subtype == OFDPA_MPLS_GROUP_SUBTYPE_ECMP
1409 or subtype == OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG)
macauley_chengd17ce512015-08-31 17:45:51 +08001410
macauley_cheng67da9262015-08-31 15:18:41 +08001411 buckets=[]
1412 if subtype == OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP:
macauley_chengd17ce512015-08-31 17:45:51 +08001413 group_type = ofp.OFPGT_FF
macauley_cheng67da9262015-08-31 15:18:41 +08001414 for gid in ref_gids:
macauley_chengd17ce512015-08-31 17:45:51 +08001415 action=[]
Pierbbdf3782016-08-22 17:58:26 -07001416 action.append(ofp.action.group(gid))
macauley_chengd17ce512015-08-31 17:45:51 +08001417 buckets.append(ofp.bucket(watch_port=watch_port, watch_group=watch_group,actions=action))
1418
macauley_cheng67da9262015-08-31 15:18:41 +08001419 elif subtype == OFDPA_MPLS_GROUP_SUBTYPE_ECMP:
1420 group_type = ofp.OFPGT_SELECT
1421 for gid in ref_gids:
macauley_chengd17ce512015-08-31 17:45:51 +08001422 action=[]
Pierbbdf3782016-08-22 17:58:26 -07001423 action.append(ofp.action.group(gid))
macauley_cheng67da9262015-08-31 15:18:41 +08001424 buckets.append(ofp.bucket(actions=action))
macauley_chengd17ce512015-08-31 17:45:51 +08001425
macauley_cheng67da9262015-08-31 15:18:41 +08001426 elif subtype == OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG:
1427 group_type = ofp.OFPGT_INDIRECT
macauley_chengd17ce512015-08-31 17:45:51 +08001428 action=[]
macauley_cheng67da9262015-08-31 15:18:41 +08001429 if set_vid!=None:
Flavio Castro91d1a552016-05-17 16:59:44 -07001430 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+set_vid)))
macauley_cheng67da9262015-08-31 15:18:41 +08001431 if push_vlan!=None:
Pierbbdf3782016-08-22 17:58:26 -07001432 action.append(ofp.action.push_vlan(push_vlan))
macauley_cheng67da9262015-08-31 15:18:41 +08001433 if pop_vlan!=None:
Pierbbdf3782016-08-22 17:58:26 -07001434 action.append(ofp.action.pop_vlan())
1435 action.append(ofp.action.group(ref_gids[0]))
macauley_cheng67da9262015-08-31 15:18:41 +08001436 buckets.append(ofp.bucket(actions=action))
macauley_chengd17ce512015-08-31 17:45:51 +08001437
1438 mpls_group_id = encode_mpls_forwarding_group_id(subtype, index)
macauley_cheng67da9262015-08-31 15:18:41 +08001439 request = ofp.message.group_add(group_type=group_type,
macauley_cheng67da9262015-08-31 15:18:41 +08001440 group_id=mpls_group_id,
1441 buckets=buckets
1442 )
1443 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -07001444 return mpls_group_id, request
macauley_chengd17ce512015-08-31 17:45:51 +08001445
1446
macauley_cheng67da9262015-08-31 15:18:41 +08001447"""
1448dislay
Pierbbdf3782016-08-22 17:58:26 -07001449"""
macauleydbff3272015-07-30 14:07:16 +08001450def print_current_table_flow_stat(ctrl, table_id=0xff):
1451 stat_req=ofp.message.flow_stats_request()
1452 response, pkt = ctrl.transact(stat_req)
1453 if response == None:
1454 print "no response"
1455 return None
1456 print len(response.entries)
1457 for obj in response.entries:
1458 print "match ", obj.match
1459 print "cookie", obj.cookie
1460 print "priority", obj.priority
1461 print "idle_timeout", obj.idle_timeout
1462 print "hard_timeout", obj.hard_timeout
1463 #obj.actions
Flavio Castro167f5bd2015-12-02 19:33:53 -05001464 print "packet count: %lx"%obj.packet_count