blob: 3d80de7873e0ffaa08dbb833fbb4b04aa6f24866 [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
Piere1308762016-09-12 15:29:56 -070021VLAN_TABLE_FLAG_ONLY_STACKED=5
22VLAN_TABLE_FLAG_PRIORITY=6
23VLAN_TABLE_FLAG_ONLY_UNTAG_PRIORITY=7
macauley97557232015-07-16 17:28:07 +080024
macauleye8b140e2015-08-03 13:35:45 +080025PORT_FLOW_TABLE=0
26VLAN_FLOW_TABLE=10
Piere1308762016-09-12 15:29:56 -070027VLAN_1_FLOW_TABLE=11
macauleye8b140e2015-08-03 13:35:45 +080028TERMINATION_FLOW_TABLE=20
29UCAST_ROUTING_FLOW_TABLE=30
30MCAST_ROUTING_FLOW_TABLE=40
31BRIDGE_FLOW_TABLE=50
32ACL_FLOW_TABLE=60
33
34def convertIP4toStr(ip_addr):
35 a=(ip_addr&0xff000000)>>24
36 b=(ip_addr&0x00ff0000)>>16
37 c=(ip_addr&0x0000ff00)>>8
38 d=(ip_addr&0x000000ff)
39 return str(a)+"."+str(b)+"."+str(c)+"."+str(d)
40
41def convertMACtoStr(mac):
42 if not isinstance(mac, list):
43 assert(0)
44
45 return ':'.join(['%02X' % x for x in mac])
46
macauley7f89d962015-08-06 18:13:48 +080047def getSwitchCpuMACFromDPID(dpid):
48 str_datapath_id_f= "{:016x}".format(dpid)
49 str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
50 switch_cpu_mac_str=str_datapath_id[6:]
51 switch_cpu_mac = switch_cpu_mac_str.split(":")
52 switch_cpu_mac=[int(switch_cpu_mac[i],16) for i in range(0, len(switch_cpu_mac))]
53
54 return switch_cpu_mac_str, switch_cpu_mac
Pierbbdf3782016-08-22 17:58:26 -070055
macauley_cheng67da9262015-08-31 15:18:41 +080056def DumpGroup(stats, verify_group_stats, always_show=True):
57 if(len(stats) > len(verify_group_stats)):
58 min_len = len(verify_group_stats)
59 print "Stats Len is not the same, stats>verify_group_stats"
60 if(len(stats)< len(verify_group_stats)):
Pierbbdf3782016-08-22 17:58:26 -070061 min_len = len(stats)
macauley_cheng67da9262015-08-31 15:18:41 +080062 print "Stats Len is not the same, stats<verify_group_stats"
Pierbbdf3782016-08-22 17:58:26 -070063 else:
macauley_cheng67da9262015-08-31 15:18:41 +080064 min_len = len(stats)
macauleye8b140e2015-08-03 13:35:45 +080065
macauley_cheng67da9262015-08-31 15:18:41 +080066 print "\r\n"
67 for i in range(min_len):
68 gs = stats[i]
Pierbbdf3782016-08-22 17:58:26 -070069 gv = verify_group_stats[i]
macauley_cheng67da9262015-08-31 15:18:41 +080070 print "FromSwtich:(GID=%lx, TYPE=%lx)\r\nVerify :(GID=%lx, TYPE=%lx)"%(gs.group_id, gs.group_type, gv.group_id, gv.group_type)
71 if(len(gs.buckets) != len(gv.buckets)):
72 print "buckets len is not the same gs %lx, gv %lx",(len(gs.buckets), len(gv.buckets))
73
74 for j in range(len(gs.buckets)):
75 b1=gs.buckets[j]
Pierbbdf3782016-08-22 17:58:26 -070076 b2=gv.buckets[j]
macauley_cheng67da9262015-08-31 15:18:41 +080077 if(len(b1.actions) != len(b2.actions)):
78 print "action len is not the same"
79
80 for k in range(len(b1.actions)):
81 a1=b1.actions[k]
82 a2=b2.actions[k]
83 if(always_show == True):
84 print "a1:"+a1.show()
Pierbbdf3782016-08-22 17:58:26 -070085 print "a2:"+a2.show()
macauley_cheng67da9262015-08-31 15:18:41 +080086
87def AssertGroup(self, stats, verify_group_stats):
88 self.assertTrue(len(stats) ==len(verify_group_stats), "stats len is not the same")
89
90 for i in range(len(stats)):
91 gs = stats[i]
Pierbbdf3782016-08-22 17:58:26 -070092 gv = verify_group_stats[i]
macauley_cheng67da9262015-08-31 15:18:41 +080093 self.assertTrue(len(gs.buckets) == len(gv.buckets), "buckets len is not the same")
94
95 for j in range(len(gs.buckets)):
96 b1=gs.buckets[j]
Pierbbdf3782016-08-22 17:58:26 -070097 b2=gv.buckets[j]
macauley_cheng67da9262015-08-31 15:18:41 +080098 self.assertTrue(len(b1.actions) == len(b2.actions), "action len is not the same")
99
100 for k in range(len(b1.actions)):
101 a1=b1.actions[k]
102 a2=b2.actions[k]
103 self.assertEquals(a1, a2, "action is not the same")
Pierbbdf3782016-08-22 17:58:26 -0700104
macauley97557232015-07-16 17:28:07 +0800105def encode_l2_interface_group_id(vlan, id):
106 return id + (vlan << OFDPA_VLAN_ID_SHIFT)
107
108def encode_l2_rewrite_group_id(id):
109 return id + (1 << OFDPA_GROUP_TYPE_SHIFT)
110
111def encode_l3_unicast_group_id(id):
112 return id + (2 << OFDPA_GROUP_TYPE_SHIFT)
113
114def encode_l2_mcast_group_id(vlan, id):
115 return id + (vlan << OFDPA_VLAN_ID_SHIFT) + (3 << OFDPA_GROUP_TYPE_SHIFT)
116
117def encode_l2_flood_group_id(vlan, id):
118 return id + (vlan << OFDPA_VLAN_ID_SHIFT) + (4 << OFDPA_GROUP_TYPE_SHIFT)
Pierbbdf3782016-08-22 17:58:26 -0700119
macauley97557232015-07-16 17:28:07 +0800120def encode_l3_interface_group_id(id):
121 return id + (5 << OFDPA_GROUP_TYPE_SHIFT)
122
123def encode_l3_mcast_group_id(vlan, id):
124 return id + (vlan << OFDPA_VLAN_ID_SHIFT)+(6 << OFDPA_GROUP_TYPE_SHIFT)
125
126def encode_l3_ecmp_group_id(id):
127 return id + (7 << OFDPA_GROUP_TYPE_SHIFT)
128
Flavio Castro91d1a552016-05-17 16:59:44 -0700129def encode_l2_unfiltered_group_id(id):
130 return id + (11 << OFDPA_GROUP_TYPE_SHIFT)
131
macauleyfddc4662015-07-27 17:40:30 +0800132def encode_l2_overlay_group_id(tunnel_id, subtype, index):
133 tunnel_id=tunnel_id&0xffff #16 bits
134 subtype = subtype&3 #2 bits
135 index = index & 0x3f #10 bits
136 return index + (tunnel_id << OFDPA_TUNNEL_ID_SHIFT)+ (subtype<<OFDPA_TUNNEL_SUBTYPE_SHIFT)+(8 << OFDPA_GROUP_TYPE_SHIFT)
macauley97557232015-07-16 17:28:07 +0800137
Flavio Castro91d1a552016-05-17 16:59:44 -0700138def add_l2_unfiltered_group(ctrl, ports, send_barrier=False):
139 # group table
140 # set up untag groups for each port
141 group_id_list=[]
142 msgs=[]
143 for of_port in ports:
144 # do stuff
145 group_id = encode_l2_unfiltered_group_id(of_port)
146 group_id_list.append(group_id)
147 actions = [ofp.action.output(of_port)]
148 actions.append(ofp.action.set_field(ofp.oxm.exp1ByteValue(exp_type=24, value=1)))
149
150 buckets = [ofp.bucket(actions=actions)]
151 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
152 group_id=group_id,
153 buckets=buckets
154 )
155 ctrl.message_send(request)
156 msgs.append(request)
157
158 if send_barrier:
159 do_barrier(ctrl)
160
161 return group_id_list, msgs
162
Flavio Castrod4c44d12015-12-08 14:44:18 -0500163def add_l2_interface_group(ctrl, ports, vlan_id=1, is_tagged=False, send_barrier=False):
macauley97557232015-07-16 17:28:07 +0800164 # group table
165 # set up untag groups for each port
macauley41904ed2015-07-16 17:38:35 +0800166 group_id_list=[]
macauley15909e72015-07-17 15:58:57 +0800167 msgs=[]
macauley97557232015-07-16 17:28:07 +0800168 for of_port in ports:
169 # do stuff
170 group_id = encode_l2_interface_group_id(vlan_id, of_port)
macauley41904ed2015-07-16 17:38:35 +0800171 group_id_list.append(group_id)
macauley97557232015-07-16 17:28:07 +0800172 if is_tagged:
173 actions = [
174 ofp.action.output(of_port),
Pierbbdf3782016-08-22 17:58:26 -0700175 ]
macauley97557232015-07-16 17:28:07 +0800176 else:
177 actions = [
178 ofp.action.pop_vlan(),
179 ofp.action.output(of_port),
180 ]
181
182 buckets = [
183 ofp.bucket(actions=actions),
184 ]
185
186 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
187 group_id=group_id,
188 buckets=buckets
189 )
190 ctrl.message_send(request)
macauley15909e72015-07-17 15:58:57 +0800191 msgs.append(request)
macauley97557232015-07-16 17:28:07 +0800192
193 if send_barrier:
194 do_barrier(ctrl)
Pierbbdf3782016-08-22 17:58:26 -0700195
macauley15909e72015-07-17 15:58:57 +0800196 return group_id_list, msgs
macauley97557232015-07-16 17:28:07 +0800197
Flavio Castrod4c44d12015-12-08 14:44:18 -0500198def add_one_l2_interface_group(ctrl, port, vlan_id=1, is_tagged=False, send_barrier=False):
macauley0f91a3e2015-07-17 18:09:59 +0800199 # group table
200 # set up untag groups for each port
201 group_id = encode_l2_interface_group_id(vlan_id, port)
202
203 if is_tagged:
204 actions = [
205 ofp.action.output(port),
Pierbbdf3782016-08-22 17:58:26 -0700206 ]
macauley0f91a3e2015-07-17 18:09:59 +0800207 else:
208 actions = [
209 ofp.action.pop_vlan(),
210 ofp.action.output(port),
211 ]
212
213 buckets = [
214 ofp.bucket(actions=actions),
215 ]
216
217 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
218 group_id=group_id,
219 buckets=buckets
220 )
221 ctrl.message_send(request)
222
223 if send_barrier:
224 do_barrier(ctrl)
Pierbbdf3782016-08-22 17:58:26 -0700225
macauley0f91a3e2015-07-17 18:09:59 +0800226 return group_id, request
Pierbbdf3782016-08-22 17:58:26 -0700227
macauley97557232015-07-16 17:28:07 +0800228def add_l2_mcast_group(ctrl, ports, vlanid, mcast_grp_index):
229 buckets=[]
230 for of_port in ports:
231 group_id = encode_l2_interface_group_id(vlanid, of_port)
232 action=[ofp.action.group(group_id)]
233 buckets.append(ofp.bucket(actions=action))
234
235 group_id =encode_l2_mcast_group_id(vlanid, mcast_grp_index)
236 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
237 group_id=group_id,
238 buckets=buckets
239 )
240 ctrl.message_send(request)
macauley15909e72015-07-17 15:58:57 +0800241 return request
macauley97557232015-07-16 17:28:07 +0800242
macauley15909e72015-07-17 15:58:57 +0800243def add_l2_flood_group(ctrl, ports, vlanid, id):
244 buckets=[]
245 for of_port in ports:
246 group_id = encode_l2_interface_group_id(vlanid, of_port)
247 action=[ofp.action.group(group_id)]
248 buckets.append(ofp.bucket(actions=action))
macauley97557232015-07-16 17:28:07 +0800249
macauley15909e72015-07-17 15:58:57 +0800250 group_id =encode_l2_flood_group_id(vlanid, id)
251 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
252 group_id=group_id,
253 buckets=buckets
254 )
255 ctrl.message_send(request)
256 return request
257
Flavio Castroa7162bb2016-07-25 17:30:30 -0700258def mod_l2_flood_group(ctrl, ports, vlanid, id):
259 buckets=[]
260 for of_port in ports:
261 group_id = encode_l2_interface_group_id(vlanid, of_port)
262 action=[ofp.action.group(group_id)]
263 buckets.append(ofp.bucket(actions=action))
264
265 group_id =encode_l2_flood_group_id(vlanid, id)
266 request = ofp.message.group_modify(group_type=ofp.OFPGT_ALL,
267 group_id=group_id,
268 buckets=buckets
269 )
270 ctrl.message_send(request)
271 return request
272
273
macauley15909e72015-07-17 15:58:57 +0800274def add_l2_rewrite_group(ctrl, port, vlanid, id, src_mac, dst_mac):
275 group_id = encode_l2_interface_group_id(vlanid, port)
276
277 action=[]
278 if src_mac is not None:
279 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
280
281 if dst_mac is not None:
282 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
283
Flavio Castro91d1a552016-05-17 16:59:44 -0700284 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlanid)))
Pierbbdf3782016-08-22 17:58:26 -0700285
macauley15909e72015-07-17 15:58:57 +0800286 action.append(ofp.action.group(group_id))
Pierbbdf3782016-08-22 17:58:26 -0700287
macauley15909e72015-07-17 15:58:57 +0800288 buckets = [ofp.bucket(actions=action)]
289
290 group_id =encode_l2_rewrite_group_id(id)
291 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
292 group_id=group_id,
293 buckets=buckets
294 )
295 ctrl.message_send(request)
296 return request
Pierbbdf3782016-08-22 17:58:26 -0700297
macauley15909e72015-07-17 15:58:57 +0800298def add_l3_unicast_group(ctrl, port, vlanid, id, src_mac, dst_mac):
299 group_id = encode_l2_interface_group_id(vlanid, port)
300
301 action=[]
302 if src_mac is not None:
303 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
304
305 if dst_mac is not None:
306 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
307
Flavio Castroaf2b4502016-02-02 17:41:32 -0500308 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlanid)))
Pierbbdf3782016-08-22 17:58:26 -0700309
macauley15909e72015-07-17 15:58:57 +0800310 action.append(ofp.action.group(group_id))
Pierbbdf3782016-08-22 17:58:26 -0700311
macauley15909e72015-07-17 15:58:57 +0800312 buckets = [ofp.bucket(actions=action)]
313
314 group_id =encode_l3_unicast_group_id(id)
315 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
316 group_id=group_id,
317 buckets=buckets
318 )
319 ctrl.message_send(request)
320 return request
Pierbbdf3782016-08-22 17:58:26 -0700321
macauley15909e72015-07-17 15:58:57 +0800322def add_l3_interface_group(ctrl, port, vlanid, id, src_mac):
323 group_id = encode_l2_interface_group_id(vlanid, port)
324
325 action=[]
326 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
Pierbbdf3782016-08-22 17:58:26 -0700327 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlanid)))
macauley15909e72015-07-17 15:58:57 +0800328 action.append(ofp.action.group(group_id))
Pierbbdf3782016-08-22 17:58:26 -0700329
macauley15909e72015-07-17 15:58:57 +0800330 buckets = [ofp.bucket(actions=action)]
331
332 group_id =encode_l3_interface_group_id(id)
333 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
334 group_id=group_id,
335 buckets=buckets
336 )
337 ctrl.message_send(request)
338 return request
339
340def add_l3_ecmp_group(ctrl, id, l3_ucast_groups):
341 buckets=[]
342 for group in l3_ucast_groups:
343 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
344
345 group_id =encode_l3_ecmp_group_id(id)
346 request = ofp.message.group_add(group_type=ofp.OFPGT_SELECT,
347 group_id=group_id,
348 buckets=buckets
349 )
350 ctrl.message_send(request)
351 return request
Flavio Castroa7162bb2016-07-25 17:30:30 -0700352
353def mod_l3_ecmp_group(ctrl, id, l3_ucast_groups):
354 buckets=[]
355 for group in l3_ucast_groups:
356 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
357
358 group_id =encode_l3_ecmp_group_id(id)
359 request = ofp.message.group_modify(group_type=ofp.OFPGT_SELECT,
360 group_id=group_id,
361 buckets=buckets
362 )
363 ctrl.message_send(request)
364 return request
365
macauley15909e72015-07-17 15:58:57 +0800366def add_l3_mcast_group(ctrl, vid, mcast_group_id, groups_on_buckets):
367 buckets=[]
368 for group in groups_on_buckets:
369 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
Pierbbdf3782016-08-22 17:58:26 -0700370
macauley15909e72015-07-17 15:58:57 +0800371 group_id =encode_l3_mcast_group_id(vid, mcast_group_id)
372 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
373 group_id=group_id,
374 buckets=buckets
375 )
376 ctrl.message_send(request)
377 return request
macauleyfddc4662015-07-27 17:40:30 +0800378
379def add_l2_overlay_flood_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
380 buckets=[]
381 for port in ports:
382 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
383
384 group_id=encode_l2_overlay_group_id(tunnel_id, 0, index)
385 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
386 group_id=group_id,
387 buckets=buckets
388 )
389 ctrl.message_send(request)
390 return request
391
392def add_l2_overlay_flood_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
393 buckets=[]
394 for port in ports:
395 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
396
397 group_id=encode_l2_overlay_group_id(tunnel_id, 1, index)
398 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
399 group_id=group_id,
400 buckets=buckets
401 )
402 ctrl.message_send(request)
403 return request
404
405def add_l2_overlay_mcast_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
406 buckets=[]
407 for port in ports:
408 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
409
410 group_id=encode_l2_overlay_group_id(tunnel_id, 2, index)
411 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
412 group_id=group_id,
413 buckets=buckets
414 )
415 ctrl.message_send(request)
416 return request
417
418def add_l2_overlay_mcast_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
419 buckets=[]
420 for port in ports:
421 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
422
423 group_id=encode_l2_overlay_group_id(tunnel_id, 3, index)
424 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
425 group_id=group_id,
426 buckets=buckets
427 )
428 ctrl.message_send(request)
429 return request
Pierbbdf3782016-08-22 17:58:26 -0700430
macauleyfddc4662015-07-27 17:40:30 +0800431def add_port_table_flow(ctrl, is_overlay=True):
432 match = ofp.match()
433
434 if is_overlay == True:
435 match.oxm_list.append(ofp.oxm.in_port(0x10000))
macauleydbff3272015-07-30 14:07:16 +0800436 NEXT_TABLE=50
macauleyfddc4662015-07-27 17:40:30 +0800437 else:
438 match.oxm_list.append(ofp.oxm.in_port(0))
Pierbbdf3782016-08-22 17:58:26 -0700439 NEXT_TABLE=10
macauleyfddc4662015-07-27 17:40:30 +0800440
441 request = ofp.message.flow_add(
442 table_id=0,
443 cookie=42,
444 match=match,
445 instructions=[
macauleydbff3272015-07-30 14:07:16 +0800446 ofp.instruction.goto_table(NEXT_TABLE)
macauleyfddc4662015-07-27 17:40:30 +0800447 ],
448 priority=0)
449 logging.info("Add port table, match port %lx" % 0x10000)
450 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -0700451
Flavio Castrod8f8af22015-12-02 18:19:26 -0500452def pop_vlan_flow(ctrl, ports, vlan_id=1):
453 # table 10: vlan
454 # goto to table 20
455 msgs=[]
456 for of_port in ports:
457 match = ofp.match()
458 match.oxm_list.append(ofp.oxm.in_port(of_port))
459 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
460 request = ofp.message.flow_add(
461 table_id=10,
462 cookie=42,
463 match=match,
464 instructions=[
465 ofp.instruction.apply_actions(
466 actions=[
467 ofp.action.pop_vlan()
468 ]
469 ),
470 ofp.instruction.goto_table(20)
471 ],
472 priority=0)
473 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
474 ctrl.message_send(request)
475
476
477 return msgs
macauleyfddc4662015-07-27 17:40:30 +0800478
macauley97557232015-07-16 17:28:07 +0800479def add_vlan_table_flow(ctrl, ports, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
480 # table 10: vlan
481 # goto to table 20
macauley15909e72015-07-17 15:58:57 +0800482 msgs=[]
macauley97557232015-07-16 17:28:07 +0800483 for of_port in ports:
Flavio Castro932014b2016-01-05 18:29:15 -0500484 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
macauley97557232015-07-16 17:28:07 +0800485 match = ofp.match()
486 match.oxm_list.append(ofp.oxm.in_port(of_port))
487 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
488 request = ofp.message.flow_add(
489 table_id=10,
490 cookie=42,
491 match=match,
492 instructions=[
Flavio Castrod8f8af22015-12-02 18:19:26 -0500493 ofp.instruction.apply_actions(
494 actions=[
495 ofp.action.pop_vlan()
496 ]
497 ),
macauley97557232015-07-16 17:28:07 +0800498 ofp.instruction.goto_table(20)
499 ],
500 priority=0)
501 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
502 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -0700503
macauley97557232015-07-16 17:28:07 +0800504 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
505 match = ofp.match()
506 match.oxm_list.append(ofp.oxm.in_port(of_port))
Flavio Castro12296312015-12-15 17:48:26 -0500507 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0x1fff))
macauley97557232015-07-16 17:28:07 +0800508 request = ofp.message.flow_add(
509 table_id=10,
510 cookie=42,
511 match=match,
512 instructions=[
513 ofp.instruction.apply_actions(
514 actions=[
Flavio Castroaf2b4502016-02-02 17:41:32 -0500515 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id))
macauley97557232015-07-16 17:28:07 +0800516 ]
517 ),
518 ofp.instruction.goto_table(20)
519 ],
520 priority=0)
521 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
522 ctrl.message_send(request)
macauley15909e72015-07-17 15:58:57 +0800523 msgs.append(request)
macauley97557232015-07-16 17:28:07 +0800524
Flavio Castro932014b2016-01-05 18:29:15 -0500525 if (flag == 4) :
526 match = ofp.match()
527 match.oxm_list.append(ofp.oxm.in_port(of_port))
528 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1fff))
529 request = ofp.message.flow_add(
530 table_id=10,
531 cookie=42,
532 match=match,
533 instructions=[
534 ofp.instruction.apply_actions(
535 actions=[
Flavio Castroaf2b4502016-02-02 17:41:32 -0500536 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id))
Flavio Castro932014b2016-01-05 18:29:15 -0500537 ]
538 ),
539 ofp.instruction.goto_table(20)
540 ],
541 priority=0)
542 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
543 ctrl.message_send(request)
544 msgs.append(request)
545
macauley97557232015-07-16 17:28:07 +0800546 if send_barrier:
547 do_barrier(ctrl)
548
macauley15909e72015-07-17 15:58:57 +0800549 return msgs
Pierbbdf3782016-08-22 17:58:26 -0700550
macauley_cheng6e6a6122015-11-16 14:19:18 +0800551def del_vlan_table_flow(ctrl, ports, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
552 # table 10: vlan
553 # goto to table 20
554 msgs=[]
555 for of_port in ports:
556 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
557 match = ofp.match()
558 match.oxm_list.append(ofp.oxm.in_port(of_port))
559 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
560 request = ofp.message.flow_delete(
561 table_id=10,
562 cookie=42,
563 match=match,
564 priority=0)
565 logging.info("Del vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
566 ctrl.message_send(request)
macauley0f91a3e2015-07-17 18:09:59 +0800567
macauley_cheng6e6a6122015-11-16 14:19:18 +0800568 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
569 match = ofp.match()
570 match.oxm_list.append(ofp.oxm.in_port(of_port))
571 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0xfff))
572 request = ofp.message.flow_delete(
573 table_id=10,
574 cookie=42,
575 match=match,
576 priority=0)
577 logging.info("Del vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
578 ctrl.message_send(request)
579 msgs.append(request)
580
581 if send_barrier:
582 do_barrier(ctrl)
583
584 return msgs
Pierbbdf3782016-08-22 17:58:26 -0700585
macauley_cheng6b311612015-09-04 11:32:27 +0800586def add_vlan_table_flow_pvid(ctrl, in_port, match_vid=None, pvid=1, send_barrier=False):
587 """it will tag pack as untagged packet wether it has tagg or not"""
588 match = ofp.match()
589 match.oxm_list.append(ofp.oxm.in_port(in_port))
590 actions=[]
591 if match_vid == None:
Pierbbdf3782016-08-22 17:58:26 -0700592 match.oxm_list.append(ofp.oxm.vlan_vid(0))
macauley_cheng6b311612015-09-04 11:32:27 +0800593 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+pvid)))
594 goto_table=20
595 else:
596 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+match_vid, 0x1fff))
597 actions.append(ofp.action.push_vlan(0x8100))
Pierbbdf3782016-08-22 17:58:26 -0700598 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+pvid)))
macauley_cheng6b311612015-09-04 11:32:27 +0800599 goto_table=20
Pierbbdf3782016-08-22 17:58:26 -0700600
macauley_cheng6b311612015-09-04 11:32:27 +0800601 request = ofp.message.flow_add(
602 table_id=10,
603 cookie=42,
604 match=match,
605 instructions=[
606 ofp.instruction.apply_actions(actions=actions)
607 ,ofp.instruction.goto_table(goto_table)
608 ],
609 priority=0)
610 logging.info("Add PVID %d on port %d and go to table %ld" %( pvid, in_port, goto_table))
Pierbbdf3782016-08-22 17:58:26 -0700611 ctrl.message_send(request)
612
macauley_cheng6b311612015-09-04 11:32:27 +0800613 if send_barrier:
614 do_barrier(ctrl)
615
616def add_vlan_table_flow_allow_all_vlan(ctrl, in_port, send_barrier=False):
617 """it st flow allow all vlan tag on this port"""
618 match = ofp.match()
619 match.oxm_list.append(ofp.oxm.in_port(in_port))
620 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1000))
621 request = ofp.message.flow_add(
622 table_id=10,
623 cookie=42,
624 match=match,
625 instructions=[
Pierbbdf3782016-08-22 17:58:26 -0700626 ofp.instruction.goto_table(20)
macauley_cheng6b311612015-09-04 11:32:27 +0800627 ],
628 priority=0)
629 logging.info("Add allow all vlan on port %d " %(in_port))
Pierbbdf3782016-08-22 17:58:26 -0700630 ctrl.message_send(request)
macauley_cheng6b311612015-09-04 11:32:27 +0800631
Pier7b031af2016-08-25 15:00:22 -0700632def 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):
633 # Install a flow for VLAN translation
634 # in VLAN table.
635 # table 10: vlan
636 # goto to table 20
637 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
638 match = ofp.match()
639 match.oxm_list.append(ofp.oxm.in_port(of_port))
640 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id,0x1fff))
641
642 actions=[]
643 if vrf!=0:
644 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
645 if new_vlan_id != -1:
646 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_vlan_id)))
647
648 request = ofp.message.flow_add(
649 table_id=10,
650 cookie=42,
651 match=match,
652 instructions=[
653 ofp.instruction.apply_actions(
654 actions=actions
655 ),
656 ofp.instruction.goto_table(20)
657 ],
658 priority=0)
659 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
660 ctrl.message_send(request)
661
Piere1308762016-09-12 15:29:56 -0700662def add_one_vlan_table_flow(ctrl, of_port, out_vlan_id=1, vlan_id=1, vrf=0, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
macauley0f91a3e2015-07-17 18:09:59 +0800663 # table 10: vlan
664 # goto to table 20
Flavio Castro932014b2016-01-05 18:29:15 -0500665 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
macauley0f91a3e2015-07-17 18:09:59 +0800666 match = ofp.match()
667 match.oxm_list.append(ofp.oxm.in_port(of_port))
Flavio Castro12296312015-12-15 17:48:26 -0500668 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id,0x1fff))
macauley7f89d962015-08-06 18:13:48 +0800669
670 actions=[]
671 if vrf!=0:
672 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
Pierbbdf3782016-08-22 17:58:26 -0700673
Flavio Castro6d498522015-12-15 14:05:04 -0500674 #actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(value=vlan_id)))
macauley7f89d962015-08-06 18:13:48 +0800675
macauley0f91a3e2015-07-17 18:09:59 +0800676 request = ofp.message.flow_add(
677 table_id=10,
678 cookie=42,
679 match=match,
680 instructions=[
macauley53d90fe2015-08-04 17:34:22 +0800681 ofp.instruction.apply_actions(
macauley7f89d962015-08-06 18:13:48 +0800682 actions=actions
macauley53d90fe2015-08-04 17:34:22 +0800683 ),
684 ofp.instruction.goto_table(20)
macauley0f91a3e2015-07-17 18:09:59 +0800685 ],
686 priority=0)
687 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
688 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -0700689
macauley0f91a3e2015-07-17 18:09:59 +0800690 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
691 match = ofp.match()
692 match.oxm_list.append(ofp.oxm.in_port(of_port))
Flavio Castro12296312015-12-15 17:48:26 -0500693 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0x1fff))
Pierbbdf3782016-08-22 17:58:26 -0700694
macauley7f89d962015-08-06 18:13:48 +0800695 actions=[]
696 if vrf!=0:
697 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
Pierbbdf3782016-08-22 17:58:26 -0700698
Flavio Castro91d1a552016-05-17 16:59:44 -0700699 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
Pierbbdf3782016-08-22 17:58:26 -0700700
macauley0f91a3e2015-07-17 18:09:59 +0800701 request = ofp.message.flow_add(
702 table_id=10,
703 cookie=42,
704 match=match,
705 instructions=[
706 ofp.instruction.apply_actions(
macauley7f89d962015-08-06 18:13:48 +0800707 actions=actions
macauley0f91a3e2015-07-17 18:09:59 +0800708 ),
709 ofp.instruction.goto_table(20)
710 ],
711 priority=0)
712 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
713 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -0700714
Flavio Castro932014b2016-01-05 18:29:15 -0500715 if (flag == 4) :
716 match = ofp.match()
717 match.oxm_list.append(ofp.oxm.in_port(of_port))
718 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000,0x1fff))
719
720 actions=[]
721 if vrf!=0:
722 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
723
Flavio Castro91d1a552016-05-17 16:59:44 -0700724 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
Flavio Castro932014b2016-01-05 18:29:15 -0500725
726 request = ofp.message.flow_add(
727 table_id=10,
728 cookie=42,
729 match=match,
730 instructions=[
731 ofp.instruction.apply_actions(
732 actions=actions
733 ),
734 ofp.instruction.goto_table(20)
735 ],
736 priority=0)
737 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
738 ctrl.message_send(request)
macauley0f91a3e2015-07-17 18:09:59 +0800739
Piere1308762016-09-12 15:29:56 -0700740 if (flag == VLAN_TABLE_FLAG_ONLY_STACKED):
741 # This flag is meant to managed stacked vlan packtes
742 # Matches on outer VLAN_ID, set OVID with outer VLAN.
743 # Finally expose inner VLAN_ID with a pop action and
744 # goto VLAN_1_FLOW_TABLE
745 match = ofp.match()
746 match.oxm_list.append(ofp.oxm.in_port(of_port))
747 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id,0x1fff))
748
749 actions=[]
750 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_OVID, value=0x1000+vlan_id)))
751 actions.append(ofp.action.pop_vlan())
752
753 request = ofp.message.flow_add(
754 table_id=10,
755 cookie=42,
756 match=match,
757 instructions=[
758 ofp.instruction.apply_actions(
759 actions=actions
760 ),
761 ofp.instruction.goto_table(VLAN_1_FLOW_TABLE)
762 ],
763 priority=0)
764 logging.info("Add vlan %d tagged packets on port %d and go to table %d" %( vlan_id, of_port, VLAN_1_FLOW_TABLE))
765 ctrl.message_send(request)
766
767 if (flag == VLAN_TABLE_FLAG_PRIORITY) :
768 match = ofp.match()
769 match.oxm_list.append(ofp.oxm.in_port(of_port))
770 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1fff))
771 request = ofp.message.flow_add(
772 table_id=10,
773 cookie=42,
774 match=match,
775 instructions=[
776 ofp.instruction.apply_actions(
777 actions=[
778 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)),
779 ofp.action.push_vlan(0x8100),
780 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+out_vlan_id)),
781 ]
782 ),
783 ofp.instruction.goto_table(20)
784 ],
785 priority=0)
786 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
787 ctrl.message_send(request)
788
789 if send_barrier:
790 do_barrier(ctrl)
791
792 return request
793
794def add_one_vlan_1_table_flow(ctrl, of_port, new_outer_vlan_id=-1, outer_vlan_id=1, inner_vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_TAG, send_barrier=False):
795 # table 11: vlan 1 table
796 # goto to table 20
797 if flag == VLAN_TABLE_FLAG_ONLY_TAG:
798 match = ofp.match()
799 match.oxm_list.append(ofp.oxm.in_port(of_port))
800 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
801 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
802
803 actions=[]
804 actions.append(ofp.action.push_vlan(0x8100))
805 if new_outer_vlan_id != -1:
806 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_outer_vlan_id)))
807 else:
808 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+outer_vlan_id)))
809
810 request = ofp.message.flow_add(
811 table_id=11,
812 cookie=42,
813 match=match,
814 instructions=[
815 ofp.instruction.apply_actions(
816 actions=actions
817 ),
818 ofp.instruction.goto_table(TERMINATION_FLOW_TABLE)
819 ],
820 priority=0)
821 logging.info("Add vlan 1 double tagged %d-%d packets on port %d and go to table %d" %( outer_vlan_id, inner_vlan_id, of_port, TERMINATION_FLOW_TABLE))
822 ctrl.message_send(request)
823
824 if flag == VLAN_TABLE_FLAG_ONLY_UNTAG:
825 match = ofp.match()
826 match.oxm_list.append(ofp.oxm.in_port(of_port))
827 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
828 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
829
830 actions=[]
831 request = ofp.message.flow_add(
832 table_id=11,
833 cookie=42,
834 match=match,
835 instructions=[
836 ofp.instruction.apply_actions(
837 actions=actions
838 ),
839 ofp.instruction.goto_table(TERMINATION_FLOW_TABLE)
840 ],
841 priority=0)
842 logging.info("Add vlan 1 double tagged %d-%d packets on port %d and go to table %d" %( outer_vlan_id, inner_vlan_id, of_port, TERMINATION_FLOW_TABLE))
843 ctrl.message_send(request)
844
macauley0f91a3e2015-07-17 18:09:59 +0800845 if send_barrier:
846 do_barrier(ctrl)
847
848 return request
Pierbbdf3782016-08-22 17:58:26 -0700849
macauley97557232015-07-16 17:28:07 +0800850def add_bridge_flow(ctrl, dst_mac, vlanid, group_id, send_barrier=False):
851 match = ofp.match()
castroflavio21894482015-12-08 15:29:55 -0500852 priority=500
macauleyfddc4662015-07-27 17:40:30 +0800853 if dst_mac!=None:
castroflavio21894482015-12-08 15:29:55 -0500854 priority=1000
macauleyfddc4662015-07-27 17:40:30 +0800855 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
856
macauley97557232015-07-16 17:28:07 +0800857 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
macauleyfddc4662015-07-27 17:40:30 +0800858
macauley97557232015-07-16 17:28:07 +0800859 request = ofp.message.flow_add(
860 table_id=50,
861 cookie=42,
862 match=match,
863 instructions=[
864 ofp.instruction.write_actions(
865 actions=[
866 ofp.action.group(group_id)]),
867 ofp.instruction.goto_table(60)
868 ],
869 buffer_id=ofp.OFP_NO_BUFFER,
castroflavio21894482015-12-08 15:29:55 -0500870 priority=priority)
macauley97557232015-07-16 17:28:07 +0800871
872 logging.info("Inserting Brdige flow vlan %d, mac %s", vlanid, dst_mac)
873 ctrl.message_send(request)
874
875 if send_barrier:
Pierbbdf3782016-08-22 17:58:26 -0700876 do_barrier(ctrl)
macauley15909e72015-07-17 15:58:57 +0800877
Pierbbdf3782016-08-22 17:58:26 -0700878 return request
macauleyfddc4662015-07-27 17:40:30 +0800879
880def add_overlay_bridge_flow(ctrl, dst_mac, vnid, group_id, is_group=True, send_barrier=False):
881 match = ofp.match()
882 if dst_mac!=None:
883 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
884
885 match.oxm_list.append(ofp.oxm.tunnel_id(vnid))
886 if is_group == True:
887 actions=[ofp.action.group(group_id)]
888 else:
889 actions=[ofp.action.output(group_id)]
890
891 request = ofp.message.flow_add(
892 table_id=50,
893 cookie=42,
894 match=match,
895 instructions=[
896 ofp.instruction.write_actions(
897 actions=actions),
898 ofp.instruction.goto_table(60)
899 ],
900 buffer_id=ofp.OFP_NO_BUFFER,
Pierbbdf3782016-08-22 17:58:26 -0700901 priority=1000)
macauleyfddc4662015-07-27 17:40:30 +0800902
903 logging.info("Inserting Brdige flow vnid %d, mac %s", vnid, dst_mac)
904 ctrl.message_send(request)
905
906 if send_barrier:
Pierbbdf3782016-08-22 17:58:26 -0700907 do_barrier(ctrl)
macauleyfddc4662015-07-27 17:40:30 +0800908
Pierbbdf3782016-08-22 17:58:26 -0700909 return request
910
macauley_cheng6b133662015-11-09 13:52:39 +0800911def add_termination_flow(ctrl, in_port, eth_type, dst_mac, vlanid, goto_table=None, send_barrier=False):
macauley0f91a3e2015-07-17 18:09:59 +0800912 match = ofp.match()
macauley0f91a3e2015-07-17 18:09:59 +0800913 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
macauleyfddc4662015-07-27 17:40:30 +0800914 if dst_mac[0]&0x01 == 0x01:
915 match.oxm_list.append(ofp.oxm.eth_dst_masked(dst_mac, [0xff, 0xff, 0xff, 0x80, 0x00, 0x00]))
916 goto_table=40
917 else:
macauley53d90fe2015-08-04 17:34:22 +0800918 if in_port!=0:
919 match.oxm_list.append(ofp.oxm.in_port(in_port))
macauleyfddc4662015-07-27 17:40:30 +0800920 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
921 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
macauley_cheng6b133662015-11-09 13:52:39 +0800922 if goto_table == None:
923 goto_table=30
macauley0f91a3e2015-07-17 18:09:59 +0800924
925 request = ofp.message.flow_add(
926 table_id=20,
927 cookie=42,
928 match=match,
929 instructions=[
930 ofp.instruction.goto_table(goto_table)
931 ],
932 buffer_id=ofp.OFP_NO_BUFFER,
Pierbbdf3782016-08-22 17:58:26 -0700933 priority=1)
macauley0f91a3e2015-07-17 18:09:59 +0800934
935 logging.info("Inserting termination flow inport %d, eth_type %lx, vlan %d, mac %s", in_port, eth_type, vlanid, dst_mac)
936 ctrl.message_send(request)
937
938 if send_barrier:
Pierbbdf3782016-08-22 17:58:26 -0700939 do_barrier(ctrl)
macauley0f91a3e2015-07-17 18:09:59 +0800940
Pierbbdf3782016-08-22 17:58:26 -0700941 return request
942
Flavio Castroaf2b4502016-02-02 17:41:32 -0500943def 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 +0800944 match = ofp.match()
945 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
macauley53d90fe2015-08-04 17:34:22 +0800946 if vrf != 0:
947 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_VRF, vrf))
macauley0f91a3e2015-07-17 18:09:59 +0800948
Flavio Castroaf2b4502016-02-02 17:41:32 -0500949 match.oxm_list.append(ofp.oxm.ipv4_dst_masked(dst_ip, mask))
950
951 instructions = []
952 instructions.append(ofp.instruction.goto_table(60))
953 if send_ctrl:
Piere0918ec2016-09-09 20:06:05 -0700954 instructions.append(ofp.instruction.apply_actions(
Flavio Castroaf2b4502016-02-02 17:41:32 -0500955 actions=[ofp.action.output( port=ofp.OFPP_CONTROLLER,
956 max_len=ofp.OFPCML_NO_BUFFER)]))
Pierbbdf3782016-08-22 17:58:26 -0700957 else:
Flavio Castroaf2b4502016-02-02 17:41:32 -0500958 instructions.append(ofp.instruction.write_actions(
959 actions=[ofp.action.group(action_group_id)]))
macauley53d90fe2015-08-04 17:34:22 +0800960
macauley0f91a3e2015-07-17 18:09:59 +0800961 request = ofp.message.flow_add(
962 table_id=30,
963 cookie=42,
964 match=match,
Flavio Castroaf2b4502016-02-02 17:41:32 -0500965 instructions=instructions,
macauley0f91a3e2015-07-17 18:09:59 +0800966 buffer_id=ofp.OFP_NO_BUFFER,
Pierbbdf3782016-08-22 17:58:26 -0700967 priority=1)
macauley0f91a3e2015-07-17 18:09:59 +0800968
969 logging.info("Inserting unicast routing flow eth_type %lx, dip %ld",eth_type, dst_ip)
970 ctrl.message_send(request)
971
972 if send_barrier:
Pierbbdf3782016-08-22 17:58:26 -0700973 do_barrier(ctrl)
macauley0f91a3e2015-07-17 18:09:59 +0800974
Flavio Castro9debaaa2016-07-26 19:37:50 -0700975 return request
Flavio Castrod8f8af22015-12-02 18:19:26 -0500976
Flavio Castro8ca52542016-04-11 11:24:49 -0400977def 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 -0400978 match = ofp.match()
979 match.oxm_list.append(ofp.oxm.eth_type(0x8847))
980 match.oxm_list.append(ofp.oxm.mpls_label(label))
981 match.oxm_list.append(ofp.oxm.mpls_bos(bos))
982 actions = [ofp.action.dec_mpls_ttl(),
Flavio Castro8ca52542016-04-11 11:24:49 -0400983 ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf))]
984 if (goto_table == 29):
Flavio Castro8ca52542016-04-11 11:24:49 -0400985 actions.append(ofp.action.group(action_group_id))
986 else:
Flavio Castrod80fbc32016-07-25 15:54:26 -0700987 actions.append(ofp.action.set_field(
988 ofp.oxm.exp2ByteValue(exp_type=23, value=32)))
989 actions.append(ofp.action.group(action_group_id))
Flavio Castro8ca52542016-04-11 11:24:49 -0400990 actions.append(ofp.action.copy_ttl_in())
Flavio Castro9debaaa2016-07-26 19:37:50 -0700991
Flavio Castrob702a2f2016-04-10 22:01:48 -0400992 request = ofp.message.flow_add(
993 table_id=24,
994 cookie=43,
995 match=match,
996 instructions=[
Flavio Castro8ca52542016-04-11 11:24:49 -0400997 ofp.instruction.apply_actions(actions=actions),
998 ofp.instruction.goto_table(goto_table)
Flavio Castrob702a2f2016-04-10 22:01:48 -0400999 ],
1000 buffer_id=ofp.OFP_NO_BUFFER,
1001 priority=1)
Flavio Castrob702a2f2016-04-10 22:01:48 -04001002 logging.info("Inserting MPLS flow , label %ld", label)
1003 ctrl.message_send(request)
1004
1005 if send_barrier:
1006 do_barrier(ctrl)
1007
1008 return request
1009
macauleyfddc4662015-07-27 17:40:30 +08001010def add_mcast4_routing_flow(ctrl, vlan_id, src_ip, src_ip_mask, dst_ip, action_group_id, send_barrier=False):
1011 match = ofp.match()
1012 match.oxm_list.append(ofp.oxm.eth_type(0x0800))
Pierbbdf3782016-08-22 17:58:26 -07001013 match.oxm_list.append(ofp.oxm.vlan_vid(vlan_id))
macauleyfddc4662015-07-27 17:40:30 +08001014 if src_ip_mask!=0:
1015 match.oxm_list.append(ofp.oxm.ipv4_src_masked(src_ip, src_ip_mask))
1016 else:
1017 match.oxm_list.append(ofp.oxm.ipv4_src(src_ip))
Pierbbdf3782016-08-22 17:58:26 -07001018
macauleyfddc4662015-07-27 17:40:30 +08001019 match.oxm_list.append(ofp.oxm.ipv4_dst(dst_ip))
Pierbbdf3782016-08-22 17:58:26 -07001020
macauleyfddc4662015-07-27 17:40:30 +08001021 request = ofp.message.flow_add(
1022 table_id=40,
1023 cookie=42,
1024 match=match,
1025 instructions=[
1026 ofp.instruction.write_actions(
1027 actions=[ofp.action.group(action_group_id)]),
1028 ofp.instruction.goto_table(60)
1029 ],
1030 buffer_id=ofp.OFP_NO_BUFFER,
Pierbbdf3782016-08-22 17:58:26 -07001031 priority=1)
macauleyfddc4662015-07-27 17:40:30 +08001032
1033 logging.info("Inserting mcast routing flow eth_type %lx, dip %lx, sip %lx, sip_mask %lx",0x0800, dst_ip, src_ip, src_ip_mask)
1034 ctrl.message_send(request)
1035
1036 if send_barrier:
Pierbbdf3782016-08-22 17:58:26 -07001037 do_barrier(ctrl)
macauleyfddc4662015-07-27 17:40:30 +08001038
Pierbbdf3782016-08-22 17:58:26 -07001039 return request
macauley_cheng6b133662015-11-09 13:52:39 +08001040
1041#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 +08001042def 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 +08001043 match = ofp.match()
1044 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
1045 match.oxm_list.append(ofp.oxm.ipv4_dst(ip_dst))
1046 match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
1047 match.oxm_list.append(ofp.oxm.tcp_dst(tcp_dst))
Pierbbdf3782016-08-22 17:58:26 -07001048
macauley_cheng6b133662015-11-09 13:52:39 +08001049 request = ofp.message.flow_add(
1050 table_id=28,
1051 cookie=42,
1052 match=match,
1053 instructions=[
1054 ofp.instruction.write_actions(
1055 actions=[ofp.action.set_field(ofp.oxm.ipv4_dst(set_ip_dst)),
1056 ofp.action.set_field(ofp.oxm.tcp_dst(set_tcp_dst)),
1057 ofp.action.group(action_group_id)]),
1058 ofp.instruction.goto_table(60)
1059 ],
1060 buffer_id=ofp.OFP_NO_BUFFER,
Pierbbdf3782016-08-22 17:58:26 -07001061 priority=1)
macauley_cheng6b133662015-11-09 13:52:39 +08001062 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)
1063 ctrl.message_send(request)
1064 return request
macauley_chengeffc20a2015-11-09 16:14:56 +08001065
1066#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
1067def add_snat_flow(ctrl, eth_type, ip_src, ip_proto, tcp_src, set_ip_src, set_tcp_src):
1068 match = ofp.match()
1069 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
1070 match.oxm_list.append(ofp.oxm.ipv4_src(ip_src))
1071 match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
1072 match.oxm_list.append(ofp.oxm.tcp_src(tcp_src))
Pierbbdf3782016-08-22 17:58:26 -07001073
macauley_chengeffc20a2015-11-09 16:14:56 +08001074 request = ofp.message.flow_add(
1075 table_id=29,
1076 cookie=42,
1077 match=match,
1078 instructions=[
1079 ofp.instruction.write_actions(
1080 actions=[ofp.action.set_field(ofp.oxm.ipv4_src(set_ip_src)),
1081 ofp.action.set_field(ofp.oxm.tcp_src(set_tcp_src))]),
1082 ofp.instruction.goto_table(30)
1083 ],
1084 buffer_id=ofp.OFP_NO_BUFFER,
Pierbbdf3782016-08-22 17:58:26 -07001085 priority=1)
macauley_chengeffc20a2015-11-09 16:14:56 +08001086 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)
1087 ctrl.message_send(request)
1088 return request
Pierbbdf3782016-08-22 17:58:26 -07001089
1090def get_vtap_lport_config_xml(dp_id, lport, phy_port, vlan, vnid, operation='merge'):
macauleyfddc4662015-07-27 17:40:30 +08001091 """
1092 Command Example:
1093 of-agent vtap 10001 ethernet 1/1 vid 1
1094 of-agent vtp 10001 vni 10
1095 """
1096 if vlan != 0:
1097 config_vtap_xml="""
1098 <config>
1099 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1100 <id>capable-switch-1</id>
1101 <resources>
1102 <port xc:operation="OPERATION">
Pierbbdf3782016-08-22 17:58:26 -07001103 <resource-id >LPORT</resource-id>
macauleyfddc4662015-07-27 17:40:30 +08001104 <features>
1105 <current>
1106 <rate>10Gb</rate>
1107 <medium>fiber</medium>
Pierbbdf3782016-08-22 17:58:26 -07001108 <pause>symmetric</pause>
macauleyfddc4662015-07-27 17:40:30 +08001109 </current>
1110 <advertised>
1111 <rate>10Gb</rate>
1112 <rate>100Gb</rate>
1113 <medium>fiber</medium>
1114 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001115 </advertised>
macauleyfddc4662015-07-27 17:40:30 +08001116 <supported>
1117 <rate>10Gb</rate>
1118 <rate>100Gb</rate>
1119 <medium>fiber</medium>
1120 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001121 </supported>
macauleyfddc4662015-07-27 17:40:30 +08001122 <advertised-peer>
1123 <rate>10Gb</rate>
1124 <rate>100Gb</rate>
1125 <medium>fiber</medium>
1126 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001127 </advertised-peer>
macauleyfddc4662015-07-27 17:40:30 +08001128 </features>
1129 <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1130 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
1131 <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
1132 <ofdpa10:vni>VNID</ofdpa10:vni>
1133 </ofdpa10:vtap>
Pierbbdf3782016-08-22 17:58:26 -07001134 </port>
macauleyfddc4662015-07-27 17:40:30 +08001135 </resources>
1136 <logical-switches>
1137 <switch>
1138 <id>DATAPATH_ID</id>
1139 <datapath-id>DATAPATH_ID</datapath-id>
1140 <resources>
1141 <port xc:operation="OPERATION">LPORT</port>
1142 </resources>
1143 </switch>
1144 </logical-switches>
1145 </capable-switch>
1146 </config>
Pierbbdf3782016-08-22 17:58:26 -07001147 """
macauleyfddc4662015-07-27 17:40:30 +08001148 else:
1149 config_vtap_xml="""
1150 <config>
1151 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1152 <id>capable-switch-1</id>
1153 <resources>
1154 <port xc:operation="OPERATION">
Pierbbdf3782016-08-22 17:58:26 -07001155 <resource-id >LPORT</resource-id>
macauleyfddc4662015-07-27 17:40:30 +08001156 <features>
1157 <current>
1158 <rate>10Gb</rate>
1159 <medium>fiber</medium>
Pierbbdf3782016-08-22 17:58:26 -07001160 <pause>symmetric</pause>
macauleyfddc4662015-07-27 17:40:30 +08001161 </current>
1162 <advertised>
1163 <rate>10Gb</rate>
1164 <rate>100Gb</rate>
1165 <medium>fiber</medium>
1166 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001167 </advertised>
macauleyfddc4662015-07-27 17:40:30 +08001168 <supported>
1169 <rate>10Gb</rate>
1170 <rate>100Gb</rate>
1171 <medium>fiber</medium>
1172 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001173 </supported>
macauleyfddc4662015-07-27 17:40:30 +08001174 <advertised-peer>
1175 <rate>10Gb</rate>
1176 <rate>100Gb</rate>
1177 <medium>fiber</medium>
1178 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001179 </advertised-peer>
macauleyfddc4662015-07-27 17:40:30 +08001180 </features>
1181 <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1182 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
1183 <ofdpa10:vni>VNID</ofdpa10:vni>
1184 </ofdpa10:vtap>
Pierbbdf3782016-08-22 17:58:26 -07001185 </port>
macauleyfddc4662015-07-27 17:40:30 +08001186 </resources>
1187 <logical-switches>
1188 <switch>
1189 <id>DATAPATH_ID</id>
1190 <datapath-id>DATAPATH_ID</datapath-id>
1191 <resources>
1192 <port xc:operation="OPERATION">LPORT</port>
1193 </resources>
1194 </switch>
1195 </logical-switches>
1196 </capable-switch>
1197 </config>
Pierbbdf3782016-08-22 17:58:26 -07001198 """
1199 str_datapath_id_f= "{:016x}".format(dp_id)
1200 str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
1201 config_vtap_xml=config_vtap_xml.replace("DATAPATH_ID", str_datapath_id)
1202 config_vtap_xml=config_vtap_xml.replace("LPORT", str(int(lport)))
1203 config_vtap_xml=config_vtap_xml.replace("PHY_PORT", str(phy_port))
1204 config_vtap_xml=config_vtap_xml.replace("VLAN_ID", str(vlan))
macauleyfddc4662015-07-27 17:40:30 +08001205 config_vtap_xml=config_vtap_xml.replace("VNID", str(vnid))
1206 config_vtap_xml=config_vtap_xml.replace("OPERATION", str(operation))
1207 return config_vtap_xml
Pierbbdf3782016-08-22 17:58:26 -07001208
1209def 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 +08001210 """
1211 Command Example:
1212 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 -07001213 of-agent vtp 10001 vni 10
macauleyfddc4662015-07-27 17:40:30 +08001214 """
1215
1216 config_vtep_xml="""
1217 <config>
1218 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1219 <id>capable-switch-1</id>
1220 <resources>
1221 <port xc:operation="OPERATION">
Pierbbdf3782016-08-22 17:58:26 -07001222 <resource-id>LPORT</resource-id>
macauleyfddc4662015-07-27 17:40:30 +08001223 <features>
1224 <current>
1225 <rate>10Gb</rate>
1226 <medium>fiber</medium>
Pierbbdf3782016-08-22 17:58:26 -07001227 <pause>symmetric</pause>
macauleyfddc4662015-07-27 17:40:30 +08001228 </current>
1229 <advertised>
1230 <rate>10Gb</rate>
1231 <rate>100Gb</rate>
1232 <medium>fiber</medium>
1233 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001234 </advertised>
macauleyfddc4662015-07-27 17:40:30 +08001235 <supported>
1236 <rate>10Gb</rate>
1237 <rate>100Gb</rate>
1238 <medium>fiber</medium>
1239 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001240 </supported>
macauleyfddc4662015-07-27 17:40:30 +08001241 <advertised-peer>
1242 <rate>10Gb</rate>
1243 <rate>100Gb</rate>
1244 <medium>fiber</medium>
1245 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001246 </advertised-peer>
macauleyfddc4662015-07-27 17:40:30 +08001247 </features>
1248 <ofdpa10:vtep xmlns:ofdpa10="urn:bcm:ofdpa10:accton01">
1249 <ofdpa10:src-ip>SRC_IP</ofdpa10:src-ip>
1250 <ofdpa10:dest-ip>DST_IP</ofdpa10:dest-ip>
1251 <ofdpa10:udp-src-port>UDP_SRC_PORT</ofdpa10:udp-src-port>
macauley25999cf2015-08-07 17:03:24 +08001252 <ofdpa10:vni xc:operation="OPERATION">
1253 <ofdpa10:id>VNID</ofdpa10:id>
1254 </ofdpa10:vni>
macauleyfddc4662015-07-27 17:40:30 +08001255 <ofdpa10:nexthop-id>NEXT_HOP_ID</ofdpa10:nexthop-id>
1256 <ofdpa10:ttl>TTL</ofdpa10:ttl>
1257 </ofdpa10:vtep>
Pierbbdf3782016-08-22 17:58:26 -07001258 </port>
macauleyfddc4662015-07-27 17:40:30 +08001259 </resources>
1260 <logical-switches>
1261 <switch>
1262 <id>DATAPATH_ID</id>
1263 <datapath-id>DATAPATH_ID</datapath-id>
1264 <resources>
1265 <port xc:operation="OPERATION">LPORT</port>
1266 </resources>
1267 </switch>
1268 </logical-switches>
1269 </capable-switch>
Pierbbdf3782016-08-22 17:58:26 -07001270 </config>
macauleyfddc4662015-07-27 17:40:30 +08001271 """
Pierbbdf3782016-08-22 17:58:26 -07001272 str_datapath_id_f= "{:016x}".format(dp_id)
1273 str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
1274 config_vtep_xml=config_vtep_xml.replace("DATAPATH_ID", str_datapath_id)
macauley25999cf2015-08-07 17:03:24 +08001275 config_vtep_xml=config_vtep_xml.replace("LPORT", str(int(lport)))
Pierbbdf3782016-08-22 17:58:26 -07001276 config_vtep_xml=config_vtep_xml.replace("SRC_IP", str(src_ip))
1277 config_vtep_xml=config_vtep_xml.replace("DST_IP", str(dst_ip))
1278 config_vtep_xml=config_vtep_xml.replace("UDP_SRC_PORT", str(udp_src_port))
1279 config_vtep_xml=config_vtep_xml.replace("NEXT_HOP_ID", str(next_hop_id))
1280 config_vtep_xml=config_vtep_xml.replace("TTL", str(ttl))
macauleyfddc4662015-07-27 17:40:30 +08001281 config_vtep_xml=config_vtep_xml.replace("VNID", str(vnid))
Pierbbdf3782016-08-22 17:58:26 -07001282 config_vtep_xml=config_vtep_xml.replace("OPERATION", str(operation))
macauleyfddc4662015-07-27 17:40:30 +08001283
Pierbbdf3782016-08-22 17:58:26 -07001284 return config_vtep_xml
1285
1286def get_next_hop_config_xml(next_hop_id, dst_mac, phy_port, vlan, operation='merge'):
macauleyfddc4662015-07-27 17:40:30 +08001287 #of-agent nexthop 2 destination user-input-dst-mac ethernet 1/2 vid 2
1288 config_nexthop_xml="""
1289 <config>
1290 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1291 <ofdpa10:next-hop xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1292 <ofdpa10:id>NEXT_HOP_ID</ofdpa10:id>
1293 <ofdpa10:dest-mac>DST_MAC</ofdpa10:dest-mac>
1294 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
1295 <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
1296 </ofdpa10:next-hop>
1297 </of11-config:capable-switch>
1298 </config>
1299 """
1300 config_nexthop_xml=config_nexthop_xml.replace("VLAN_ID", str(vlan))
Pierbbdf3782016-08-22 17:58:26 -07001301 config_nexthop_xml=config_nexthop_xml.replace("PHY_PORT", str(phy_port))
1302 config_nexthop_xml=config_nexthop_xml.replace("NEXT_HOP_ID", str(next_hop_id))
1303 config_nexthop_xml=config_nexthop_xml.replace("DST_MAC", str(dst_mac))
1304 config_nexthop_xml=config_nexthop_xml.replace("OPERATION", str(operation))
1305 return config_nexthop_xml
macauleyfddc4662015-07-27 17:40:30 +08001306
Pierbbdf3782016-08-22 17:58:26 -07001307def get_vni_config_xml(vni_id, mcast_ipv4, next_hop_id, operation='merge'):
macauleyfddc4662015-07-27 17:40:30 +08001308 #of-agent vni 10 multicast 224.1.1.1 nexthop 20
Pierbbdf3782016-08-22 17:58:26 -07001309 if mcast_ipv4!=None:
macauleyfddc4662015-07-27 17:40:30 +08001310 config_vni_xml="""
1311 <config>
1312 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1313 <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1314 <ofdpa10:id>VNID</ofdpa10:id>
1315 <ofdpa10:vni-multicast-group>MCAST_IP</ofdpa10:vni-multicast-group>
1316 <ofdpa10:multicast-group-nexthop-id>NEXT_HOP_ID</ofdpa10:multicast-group-nexthop-id>
1317 </ofdpa10:vni>
1318 </of11-config:capable-switch>
1319 </config>
Pierbbdf3782016-08-22 17:58:26 -07001320 """
1321 config_vni_xml=config_vni_xml.replace("NEXT_HOP_ID", str(next_hop_id))
1322 config_vni_xml=config_vni_xml.replace("MCAST_IP", str(mcast_ipv4))
macauleyfddc4662015-07-27 17:40:30 +08001323 else:
1324 config_vni_xml="""
1325 <config>
1326 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1327 <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1328 <ofdpa10:id>VNID</ofdpa10:id>
1329 </ofdpa10:vni>
1330 </of11-config:capable-switch>
1331 </config>
Pierbbdf3782016-08-22 17:58:26 -07001332 """
1333
1334 config_vni_xml=config_vni_xml.replace("VNID", str(vni_id))
1335 config_vni_xml=config_vni_xml.replace("OPERATION", str(operation))
macauleyfddc4662015-07-27 17:40:30 +08001336 return config_vni_xml
Pierbbdf3782016-08-22 17:58:26 -07001337
1338def get_featureReplay(self):
macauleyfddc4662015-07-27 17:40:30 +08001339 req = ofp.message.features_request()
1340 res, raw = self.controller.transact(req)
Pierbbdf3782016-08-22 17:58:26 -07001341 self.assertIsNotNone(res, "Did not receive a response from the DUT.")
macauleyfddc4662015-07-27 17:40:30 +08001342 self.assertEqual(res.type, ofp.OFPT_FEATURES_REPLY,
1343 ("Unexpected packet type %d received in response to "
1344 "OFPT_FEATURES_REQUEST") % res.type)
Pierbbdf3782016-08-22 17:58:26 -07001345 return res
1346
macauleyfddc4662015-07-27 17:40:30 +08001347def send_edit_config(switch_ip, xml, target='runing'):
1348 NETCONF_ACCOUNT="netconfuser"
1349 NETCONF_PASSWD="netconfuser"
1350 with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
1351 try:
Pierbbdf3782016-08-22 17:58:26 -07001352 m.edit_config(target='running',
1353 config=xml,
1354 default_operation='merge',
macauleyfddc4662015-07-27 17:40:30 +08001355 error_option='stop-on-error')
1356
1357 except Exception as e:
1358 logging.info("Fail to set xml %s", xml)
1359 return False
1360
1361 #return m.get_config(source='running').data_xml
1362 return True
1363
1364def send_delete_config(switch_ip, xml, target='runing'):
1365 NETCONF_ACCOUNT="netconfuser"
1366 NETCONF_PASSWD="netconfuser"
1367 with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
1368 try:
Pierbbdf3782016-08-22 17:58:26 -07001369 m.edit_config(target='running',
1370 config=xml,
1371 default_operation='delete',
macauleyfddc4662015-07-27 17:40:30 +08001372 error_option='stop-on-error')
1373
1374 except Exception as e:
1375 logging.info("Fail to set xml %s", xml)
1376 return False
1377
1378 #return m.get_config(source='running').data_xml
1379 return True
Pierbbdf3782016-08-22 17:58:26 -07001380
macauleyfddc4662015-07-27 17:40:30 +08001381def get_edit_config(switch_ip, target='runing'):
1382 NETCONF_ACCOUNT="netconfuser"
1383 NETCONF_PASSWD="netconfuser"
1384 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 +08001385 return m.get_config(source='running').data_xml
macauleydbff3272015-07-30 14:07:16 +08001386
macauley_cheng67da9262015-08-31 15:18:41 +08001387
1388"""
1389MPLS
1390"""
1391
1392OFDPA_MPLS_SUBTYPE_SHIFT=24
Pierbbdf3782016-08-22 17:58:26 -07001393OFDPA_MPLS_GROUP_SUBTYPE_L2_VPN_LABEL=1
macauley_cheng67da9262015-08-31 15:18:41 +08001394OFDPA_MPLS_GROUP_SUBTYPE_L3_VPN_LABEL=2
1395OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL1=3
1396OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL2=4
1397OFDPA_MPLS_GROUP_SUBTYPE_SWAP_LABEL=5
1398OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP=6
1399OFDPA_MPLS_GROUP_SUBTYPE_ECMP=8
1400OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG=10
1401
1402def encode_mpls_interface_group_id(subtype, index):
1403 index=index&0x00ffffff
1404 assert(subtype==0)
1405 return index + (9 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
1406
1407def encode_mpls_label_group_id(subtype, index):
1408 index=index&0x00ffffff
1409 assert(subtype <=5 or subtype==0)
1410 #1: l2 vpn label
1411 #2: l3 vpn label
1412 #3: mpls tunnel label 1
1413 #4: mpls tunnel lable 2
1414 #5: mpls swap label
Pierbbdf3782016-08-22 17:58:26 -07001415 return index + (9 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
macauley_cheng67da9262015-08-31 15:18:41 +08001416
1417def encode_mpls_forwarding_group_id(subtype, index):
1418 index=index&0x00ffffff
1419 assert(subtype==6 or subtype==8 or subtype==10)
Pierbbdf3782016-08-22 17:58:26 -07001420 return index + (10 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
macauley_cheng67da9262015-08-31 15:18:41 +08001421
1422
1423def add_mpls_intf_group(ctrl, ref_gid, dst_mac, src_mac, vid, index, subtype=0):
1424 action=[]
1425 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
1426 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
Pierbbdf3782016-08-22 17:58:26 -07001427 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vid)))
macauley_cheng67da9262015-08-31 15:18:41 +08001428 action.append(ofp.action.group(ref_gid))
Pierbbdf3782016-08-22 17:58:26 -07001429
macauley_cheng67da9262015-08-31 15:18:41 +08001430 buckets = [ofp.bucket(actions=action)]
1431
1432 mpls_group_id =encode_mpls_interface_group_id(subtype, index)
1433 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
1434 group_id=mpls_group_id,
1435 buckets=buckets
1436 )
1437 ctrl.message_send(request)
1438 return mpls_group_id, request
1439
Pierbbdf3782016-08-22 17:58:26 -07001440def add_mpls_label_group(ctrl, subtype, index, ref_gid,
macauley_cheng67da9262015-08-31 15:18:41 +08001441 lmep_id=-1,
1442 qos_index=-1,
1443 push_l2_header=False,
1444 push_vlan=False,
1445 push_mpls_header=False,
1446 push_cw=False,
1447 set_mpls_label=None,
1448 set_bos=None,
1449 set_tc=None,
1450 set_tc_from_table=False,
1451 cpy_tc_outward=False,
1452 set_ttl=None,
1453 cpy_ttl_outward=False,
1454 oam_lm_tx_count=False,
1455 set_pri_from_table=False
1456 ):
1457 """
1458 @ref_gid: only can be mpls intf group or mpls tunnel label 1/2 group
Pierbbdf3782016-08-22 17:58:26 -07001459 """
macauley_cheng67da9262015-08-31 15:18:41 +08001460 action=[]
1461
1462 if push_vlan== True:
1463 action.append(ofp.action.push_vlan(0x8100))
1464 if push_mpls_header== True:
1465 action.append(ofp.action.push_mpls(0x8847))
1466 if set_mpls_label != None:
1467 action.append(ofp.action.set_field(ofp.oxm.mpls_label(set_mpls_label)))
1468 if set_bos != None:
1469 action.append(ofp.action.set_field(ofp.oxm.mpls_bos(set_bos)))
1470 if set_tc != None:
1471 assert(set_tc_from_table==False)
1472 action.append(ofp.action.set_field(ofp.oxm.mpls_tc(set_tc)))
1473 if set_ttl != None:
Pierbbdf3782016-08-22 17:58:26 -07001474 action.append(ofp.action.set_mpls_ttl(set_ttl))
macauley_cheng67da9262015-08-31 15:18:41 +08001475 if cpy_ttl_outward == True:
Pierbbdf3782016-08-22 17:58:26 -07001476 action.append(ofp.action.copy_ttl_out())
macauley_cheng67da9262015-08-31 15:18:41 +08001477 """
1478 ofdpa experimenter
Pierbbdf3782016-08-22 17:58:26 -07001479 """
macauley_cheng67da9262015-08-31 15:18:41 +08001480 if push_l2_header== True:
Pierbbdf3782016-08-22 17:58:26 -07001481 action.append(ofp.action.ofdpa_push_l2_header())
macauley_cheng67da9262015-08-31 15:18:41 +08001482 if set_tc_from_table== True:
1483 assert(qos_index>=0)
1484 assert(set_tc == None)
Pierbbdf3782016-08-22 17:58:26 -07001485 action.append(ofp.action.ofdpa_set_tc_from_table(qos_index))
macauley_cheng67da9262015-08-31 15:18:41 +08001486 if cpy_tc_outward == True:
Pierbbdf3782016-08-22 17:58:26 -07001487 action.append(ofp.action.ofdpa_copy_tc_out())
macauley_cheng67da9262015-08-31 15:18:41 +08001488 if oam_lm_tx_count == True:
Pierbbdf3782016-08-22 17:58:26 -07001489 assert(qos_index>=0 and lmep_id>=0)
1490 action.append(ofp.action.ofdpa_oam_lm_tx_count(lmep_id, qos_index))
macauley_cheng67da9262015-08-31 15:18:41 +08001491 if set_pri_from_table == True:
Pierbbdf3782016-08-22 17:58:26 -07001492 assert(qos_index>=0)
1493 action.append(ofp.action.ofdpa_set_qos_from_table(qos_index))
macauley_cheng67da9262015-08-31 15:18:41 +08001494 if push_cw == True:
1495 action.append(ofp.action.ofdpa_push_cw())
Pierbbdf3782016-08-22 17:58:26 -07001496
1497 action.append(ofp.action.group(ref_gid))
macauley_cheng67da9262015-08-31 15:18:41 +08001498 buckets = [ofp.bucket(actions=action)]
Pierbbdf3782016-08-22 17:58:26 -07001499
macauley_cheng67da9262015-08-31 15:18:41 +08001500 mpls_group_id = encode_mpls_label_group_id(subtype, index)
1501 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
1502 group_id=mpls_group_id,
1503 buckets=buckets
1504 )
1505 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -07001506
1507 return mpls_group_id, request
1508
1509def add_mpls_forwarding_group(ctrl, subtype, index, ref_gids,
1510 watch_port=None,
1511 watch_group=ofp.OFPP_ANY,
macauley_cheng67da9262015-08-31 15:18:41 +08001512 push_vlan=None,
macauley_chengd17ce512015-08-31 17:45:51 +08001513 pop_vlan=None,
macauley_cheng67da9262015-08-31 15:18:41 +08001514 set_vid=None):
1515 assert(subtype == OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP
1516 or subtype == OFDPA_MPLS_GROUP_SUBTYPE_ECMP
1517 or subtype == OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG)
macauley_chengd17ce512015-08-31 17:45:51 +08001518
macauley_cheng67da9262015-08-31 15:18:41 +08001519 buckets=[]
1520 if subtype == OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP:
macauley_chengd17ce512015-08-31 17:45:51 +08001521 group_type = ofp.OFPGT_FF
macauley_cheng67da9262015-08-31 15:18:41 +08001522 for gid in ref_gids:
macauley_chengd17ce512015-08-31 17:45:51 +08001523 action=[]
Pierbbdf3782016-08-22 17:58:26 -07001524 action.append(ofp.action.group(gid))
macauley_chengd17ce512015-08-31 17:45:51 +08001525 buckets.append(ofp.bucket(watch_port=watch_port, watch_group=watch_group,actions=action))
1526
macauley_cheng67da9262015-08-31 15:18:41 +08001527 elif subtype == OFDPA_MPLS_GROUP_SUBTYPE_ECMP:
1528 group_type = ofp.OFPGT_SELECT
1529 for gid in ref_gids:
macauley_chengd17ce512015-08-31 17:45:51 +08001530 action=[]
Pierbbdf3782016-08-22 17:58:26 -07001531 action.append(ofp.action.group(gid))
macauley_cheng67da9262015-08-31 15:18:41 +08001532 buckets.append(ofp.bucket(actions=action))
macauley_chengd17ce512015-08-31 17:45:51 +08001533
macauley_cheng67da9262015-08-31 15:18:41 +08001534 elif subtype == OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG:
1535 group_type = ofp.OFPGT_INDIRECT
macauley_chengd17ce512015-08-31 17:45:51 +08001536 action=[]
macauley_cheng67da9262015-08-31 15:18:41 +08001537 if set_vid!=None:
Flavio Castro91d1a552016-05-17 16:59:44 -07001538 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+set_vid)))
macauley_cheng67da9262015-08-31 15:18:41 +08001539 if push_vlan!=None:
Pierbbdf3782016-08-22 17:58:26 -07001540 action.append(ofp.action.push_vlan(push_vlan))
macauley_cheng67da9262015-08-31 15:18:41 +08001541 if pop_vlan!=None:
Pierbbdf3782016-08-22 17:58:26 -07001542 action.append(ofp.action.pop_vlan())
1543 action.append(ofp.action.group(ref_gids[0]))
macauley_cheng67da9262015-08-31 15:18:41 +08001544 buckets.append(ofp.bucket(actions=action))
macauley_chengd17ce512015-08-31 17:45:51 +08001545
1546 mpls_group_id = encode_mpls_forwarding_group_id(subtype, index)
macauley_cheng67da9262015-08-31 15:18:41 +08001547 request = ofp.message.group_add(group_type=group_type,
macauley_cheng67da9262015-08-31 15:18:41 +08001548 group_id=mpls_group_id,
1549 buckets=buckets
1550 )
1551 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -07001552 return mpls_group_id, request
macauley_chengd17ce512015-08-31 17:45:51 +08001553
1554
macauley_cheng67da9262015-08-31 15:18:41 +08001555"""
1556dislay
Pierbbdf3782016-08-22 17:58:26 -07001557"""
macauleydbff3272015-07-30 14:07:16 +08001558def print_current_table_flow_stat(ctrl, table_id=0xff):
1559 stat_req=ofp.message.flow_stats_request()
1560 response, pkt = ctrl.transact(stat_req)
1561 if response == None:
1562 print "no response"
1563 return None
1564 print len(response.entries)
1565 for obj in response.entries:
1566 print "match ", obj.match
1567 print "cookie", obj.cookie
1568 print "priority", obj.priority
1569 print "idle_timeout", obj.idle_timeout
1570 print "hard_timeout", obj.hard_timeout
1571 #obj.actions
Flavio Castro167f5bd2015-12-02 19:33:53 -05001572 print "packet count: %lx"%obj.packet_count