blob: 29cb64d9d8ab87589d6d3195dd2a4eecb350b04d [file] [log] [blame]
Matteo Scandoloa229eca2017-08-08 13:05:28 -07001
2# Copyright 2017-present Open Networking Foundation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16
macauley97557232015-07-16 17:28:07 +080017import logging
18
19from oftest import config
20import oftest.base_tests as base_tests
21import ofp
22import time
23from oftest.testutils import *
Pier1e4e98e2016-10-26 14:36:05 -070024from oftest.parse import parse_ipv6
macauley97557232015-07-16 17:28:07 +080025
macauleyfddc4662015-07-27 17:40:30 +080026from ncclient import manager
27import ncclient
28
macauley97557232015-07-16 17:28:07 +080029OFDPA_GROUP_TYPE_SHIFT=28
30OFDPA_VLAN_ID_SHIFT =16
macauleyfddc4662015-07-27 17:40:30 +080031OFDPA_TUNNEL_ID_SHIFT =12
32OFDPA_TUNNEL_SUBTYPE_SHIFT=10
macauley97557232015-07-16 17:28:07 +080033
34#VLAN_TABLE_FLAGS
35VLAN_TABLE_FLAG_ONLY_UNTAG=1
36VLAN_TABLE_FLAG_ONLY_TAG =2
37VLAN_TABLE_FLAG_ONLY_BOTH =3
Piere1308762016-09-12 15:29:56 -070038VLAN_TABLE_FLAG_ONLY_STACKED=5
39VLAN_TABLE_FLAG_PRIORITY=6
40VLAN_TABLE_FLAG_ONLY_UNTAG_PRIORITY=7
Andreas Pantelopoulosf83e0212018-03-18 20:44:05 -070041VLAN_TABLE_FLAG_ONLY_POP_VLAN=8
macauley97557232015-07-16 17:28:07 +080042
macauleye8b140e2015-08-03 13:35:45 +080043PORT_FLOW_TABLE=0
44VLAN_FLOW_TABLE=10
Piere1308762016-09-12 15:29:56 -070045VLAN_1_FLOW_TABLE=11
Piercf76e802016-09-19 20:16:35 -070046MPLS_L2_PORT_FLOW_TABLE=13
47MPLS_L2_PORT_DSCP_TRUST_FLOW_TABLE=15
48MPLS_L2_PORT_PCP_TRUST_FLOW_TABLE=16
macauleye8b140e2015-08-03 13:35:45 +080049TERMINATION_FLOW_TABLE=20
Piercf76e802016-09-19 20:16:35 -070050MPLS_TYPE_FLOW_TABLE=29
macauleye8b140e2015-08-03 13:35:45 +080051UCAST_ROUTING_FLOW_TABLE=30
52MCAST_ROUTING_FLOW_TABLE=40
53BRIDGE_FLOW_TABLE=50
54ACL_FLOW_TABLE=60
55
Andreas Pantelopoulosf83e0212018-03-18 20:44:05 -070056EGRESS_VLAN_FLOW_TABLE=210
57EGRESS_VLAN_1_FLOW_TABLE=211
58EGRESS_MAINTENANCE_POINT_FLOW_TABLE=226
59EGRESS_DSCP_TABLE=230
60EGRESS_TPID_TABLE=235
61EGRESS_SOURCE_MAC_LEARNING_TABLE=254
62
macauleye8b140e2015-08-03 13:35:45 +080063def convertIP4toStr(ip_addr):
64 a=(ip_addr&0xff000000)>>24
65 b=(ip_addr&0x00ff0000)>>16
66 c=(ip_addr&0x0000ff00)>>8
67 d=(ip_addr&0x000000ff)
68 return str(a)+"."+str(b)+"."+str(c)+"."+str(d)
69
70def convertMACtoStr(mac):
71 if not isinstance(mac, list):
72 assert(0)
73
74 return ':'.join(['%02X' % x for x in mac])
75
macauley7f89d962015-08-06 18:13:48 +080076def getSwitchCpuMACFromDPID(dpid):
77 str_datapath_id_f= "{:016x}".format(dpid)
78 str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
79 switch_cpu_mac_str=str_datapath_id[6:]
80 switch_cpu_mac = switch_cpu_mac_str.split(":")
81 switch_cpu_mac=[int(switch_cpu_mac[i],16) for i in range(0, len(switch_cpu_mac))]
82
83 return switch_cpu_mac_str, switch_cpu_mac
Pierbbdf3782016-08-22 17:58:26 -070084
macauley_cheng67da9262015-08-31 15:18:41 +080085def DumpGroup(stats, verify_group_stats, always_show=True):
86 if(len(stats) > len(verify_group_stats)):
87 min_len = len(verify_group_stats)
88 print "Stats Len is not the same, stats>verify_group_stats"
89 if(len(stats)< len(verify_group_stats)):
Pierbbdf3782016-08-22 17:58:26 -070090 min_len = len(stats)
macauley_cheng67da9262015-08-31 15:18:41 +080091 print "Stats Len is not the same, stats<verify_group_stats"
Pierbbdf3782016-08-22 17:58:26 -070092 else:
macauley_cheng67da9262015-08-31 15:18:41 +080093 min_len = len(stats)
macauleye8b140e2015-08-03 13:35:45 +080094
macauley_cheng67da9262015-08-31 15:18:41 +080095 print "\r\n"
96 for i in range(min_len):
97 gs = stats[i]
Pierbbdf3782016-08-22 17:58:26 -070098 gv = verify_group_stats[i]
macauley_cheng67da9262015-08-31 15:18:41 +080099 print "FromSwtich:(GID=%lx, TYPE=%lx)\r\nVerify :(GID=%lx, TYPE=%lx)"%(gs.group_id, gs.group_type, gv.group_id, gv.group_type)
100 if(len(gs.buckets) != len(gv.buckets)):
101 print "buckets len is not the same gs %lx, gv %lx",(len(gs.buckets), len(gv.buckets))
102
103 for j in range(len(gs.buckets)):
104 b1=gs.buckets[j]
Pierbbdf3782016-08-22 17:58:26 -0700105 b2=gv.buckets[j]
macauley_cheng67da9262015-08-31 15:18:41 +0800106 if(len(b1.actions) != len(b2.actions)):
107 print "action len is not the same"
108
109 for k in range(len(b1.actions)):
110 a1=b1.actions[k]
111 a2=b2.actions[k]
112 if(always_show == True):
113 print "a1:"+a1.show()
Pierbbdf3782016-08-22 17:58:26 -0700114 print "a2:"+a2.show()
macauley_cheng67da9262015-08-31 15:18:41 +0800115
116def AssertGroup(self, stats, verify_group_stats):
117 self.assertTrue(len(stats) ==len(verify_group_stats), "stats len is not the same")
118
119 for i in range(len(stats)):
120 gs = stats[i]
Pierbbdf3782016-08-22 17:58:26 -0700121 gv = verify_group_stats[i]
macauley_cheng67da9262015-08-31 15:18:41 +0800122 self.assertTrue(len(gs.buckets) == len(gv.buckets), "buckets len is not the same")
123
124 for j in range(len(gs.buckets)):
125 b1=gs.buckets[j]
Pierbbdf3782016-08-22 17:58:26 -0700126 b2=gv.buckets[j]
macauley_cheng67da9262015-08-31 15:18:41 +0800127 self.assertTrue(len(b1.actions) == len(b2.actions), "action len is not the same")
128
129 for k in range(len(b1.actions)):
130 a1=b1.actions[k]
131 a2=b2.actions[k]
132 self.assertEquals(a1, a2, "action is not the same")
Pierbbdf3782016-08-22 17:58:26 -0700133
macauley97557232015-07-16 17:28:07 +0800134def encode_l2_interface_group_id(vlan, id):
135 return id + (vlan << OFDPA_VLAN_ID_SHIFT)
136
137def encode_l2_rewrite_group_id(id):
138 return id + (1 << OFDPA_GROUP_TYPE_SHIFT)
139
140def encode_l3_unicast_group_id(id):
141 return id + (2 << OFDPA_GROUP_TYPE_SHIFT)
142
143def encode_l2_mcast_group_id(vlan, id):
144 return id + (vlan << OFDPA_VLAN_ID_SHIFT) + (3 << OFDPA_GROUP_TYPE_SHIFT)
145
146def encode_l2_flood_group_id(vlan, id):
147 return id + (vlan << OFDPA_VLAN_ID_SHIFT) + (4 << OFDPA_GROUP_TYPE_SHIFT)
Pierbbdf3782016-08-22 17:58:26 -0700148
macauley97557232015-07-16 17:28:07 +0800149def encode_l3_interface_group_id(id):
150 return id + (5 << OFDPA_GROUP_TYPE_SHIFT)
151
152def encode_l3_mcast_group_id(vlan, id):
153 return id + (vlan << OFDPA_VLAN_ID_SHIFT)+(6 << OFDPA_GROUP_TYPE_SHIFT)
154
155def encode_l3_ecmp_group_id(id):
156 return id + (7 << OFDPA_GROUP_TYPE_SHIFT)
157
Flavio Castro91d1a552016-05-17 16:59:44 -0700158def encode_l2_unfiltered_group_id(id):
159 return id + (11 << OFDPA_GROUP_TYPE_SHIFT)
160
macauleyfddc4662015-07-27 17:40:30 +0800161def encode_l2_overlay_group_id(tunnel_id, subtype, index):
162 tunnel_id=tunnel_id&0xffff #16 bits
163 subtype = subtype&3 #2 bits
164 index = index & 0x3f #10 bits
165 return index + (tunnel_id << OFDPA_TUNNEL_ID_SHIFT)+ (subtype<<OFDPA_TUNNEL_SUBTYPE_SHIFT)+(8 << OFDPA_GROUP_TYPE_SHIFT)
macauley97557232015-07-16 17:28:07 +0800166
Flavio Castro91d1a552016-05-17 16:59:44 -0700167def add_l2_unfiltered_group(ctrl, ports, send_barrier=False):
168 # group table
169 # set up untag groups for each port
170 group_id_list=[]
171 msgs=[]
172 for of_port in ports:
173 # do stuff
174 group_id = encode_l2_unfiltered_group_id(of_port)
175 group_id_list.append(group_id)
176 actions = [ofp.action.output(of_port)]
177 actions.append(ofp.action.set_field(ofp.oxm.exp1ByteValue(exp_type=24, value=1)))
178
179 buckets = [ofp.bucket(actions=actions)]
180 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
181 group_id=group_id,
182 buckets=buckets
183 )
184 ctrl.message_send(request)
185 msgs.append(request)
186
187 if send_barrier:
188 do_barrier(ctrl)
189
190 return group_id_list, msgs
191
Pierf6f28162016-09-22 16:30:52 -0700192def add_one_l2_unfiltered_group(ctrl, of_port, send_barrier=False):
193 # group table
194 # set up untag groups for each port
195 group_id = encode_l2_unfiltered_group_id(of_port)
196 actions = [ofp.action.output(of_port)]
197 actions.append(ofp.action.set_field(ofp.oxm.exp1ByteValue(exp_type=24, value=1)))
198
199 buckets = [ofp.bucket(actions=actions)]
200 request = ofp.message.group_add(
201 group_type=ofp.OFPGT_INDIRECT,
202 group_id=group_id,
203 buckets=buckets
204 )
205 ctrl.message_send(request)
206
207 if send_barrier:
208 do_barrier(ctrl)
209
210 return group_id, request
211
Flavio Castrod4c44d12015-12-08 14:44:18 -0500212def add_l2_interface_group(ctrl, ports, vlan_id=1, is_tagged=False, send_barrier=False):
macauley97557232015-07-16 17:28:07 +0800213 # group table
214 # set up untag groups for each port
macauley41904ed2015-07-16 17:38:35 +0800215 group_id_list=[]
macauley15909e72015-07-17 15:58:57 +0800216 msgs=[]
macauley97557232015-07-16 17:28:07 +0800217 for of_port in ports:
218 # do stuff
219 group_id = encode_l2_interface_group_id(vlan_id, of_port)
macauley41904ed2015-07-16 17:38:35 +0800220 group_id_list.append(group_id)
macauley97557232015-07-16 17:28:07 +0800221 if is_tagged:
222 actions = [
223 ofp.action.output(of_port),
Pierbbdf3782016-08-22 17:58:26 -0700224 ]
macauley97557232015-07-16 17:28:07 +0800225 else:
226 actions = [
227 ofp.action.pop_vlan(),
228 ofp.action.output(of_port),
229 ]
230
231 buckets = [
232 ofp.bucket(actions=actions),
233 ]
234
235 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
236 group_id=group_id,
237 buckets=buckets
238 )
239 ctrl.message_send(request)
macauley15909e72015-07-17 15:58:57 +0800240 msgs.append(request)
macauley97557232015-07-16 17:28:07 +0800241
242 if send_barrier:
243 do_barrier(ctrl)
Pierbbdf3782016-08-22 17:58:26 -0700244
macauley15909e72015-07-17 15:58:57 +0800245 return group_id_list, msgs
macauley97557232015-07-16 17:28:07 +0800246
Flavio Castrod4c44d12015-12-08 14:44:18 -0500247def add_one_l2_interface_group(ctrl, port, vlan_id=1, is_tagged=False, send_barrier=False):
macauley0f91a3e2015-07-17 18:09:59 +0800248 # group table
249 # set up untag groups for each port
250 group_id = encode_l2_interface_group_id(vlan_id, port)
251
252 if is_tagged:
253 actions = [
254 ofp.action.output(port),
Pierbbdf3782016-08-22 17:58:26 -0700255 ]
macauley0f91a3e2015-07-17 18:09:59 +0800256 else:
257 actions = [
258 ofp.action.pop_vlan(),
259 ofp.action.output(port),
260 ]
261
262 buckets = [
263 ofp.bucket(actions=actions),
264 ]
265
266 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
267 group_id=group_id,
268 buckets=buckets
269 )
270 ctrl.message_send(request)
271
272 if send_barrier:
273 do_barrier(ctrl)
Pierbbdf3782016-08-22 17:58:26 -0700274
macauley0f91a3e2015-07-17 18:09:59 +0800275 return group_id, request
Pierbbdf3782016-08-22 17:58:26 -0700276
macauley97557232015-07-16 17:28:07 +0800277def add_l2_mcast_group(ctrl, ports, vlanid, mcast_grp_index):
278 buckets=[]
279 for of_port in ports:
280 group_id = encode_l2_interface_group_id(vlanid, of_port)
281 action=[ofp.action.group(group_id)]
282 buckets.append(ofp.bucket(actions=action))
283
284 group_id =encode_l2_mcast_group_id(vlanid, mcast_grp_index)
285 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
286 group_id=group_id,
287 buckets=buckets
288 )
289 ctrl.message_send(request)
macauley15909e72015-07-17 15:58:57 +0800290 return request
macauley97557232015-07-16 17:28:07 +0800291
macauley15909e72015-07-17 15:58:57 +0800292def add_l2_flood_group(ctrl, ports, vlanid, id):
293 buckets=[]
294 for of_port in ports:
295 group_id = encode_l2_interface_group_id(vlanid, of_port)
296 action=[ofp.action.group(group_id)]
297 buckets.append(ofp.bucket(actions=action))
macauley97557232015-07-16 17:28:07 +0800298
macauley15909e72015-07-17 15:58:57 +0800299 group_id =encode_l2_flood_group_id(vlanid, id)
300 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
301 group_id=group_id,
302 buckets=buckets
303 )
304 ctrl.message_send(request)
305 return request
306
Flavio Castroa7162bb2016-07-25 17:30:30 -0700307def mod_l2_flood_group(ctrl, ports, vlanid, id):
308 buckets=[]
309 for of_port in ports:
310 group_id = encode_l2_interface_group_id(vlanid, of_port)
311 action=[ofp.action.group(group_id)]
312 buckets.append(ofp.bucket(actions=action))
313
314 group_id =encode_l2_flood_group_id(vlanid, id)
315 request = ofp.message.group_modify(group_type=ofp.OFPGT_ALL,
316 group_id=group_id,
317 buckets=buckets
318 )
319 ctrl.message_send(request)
320 return request
321
322
macauley15909e72015-07-17 15:58:57 +0800323def add_l2_rewrite_group(ctrl, port, vlanid, id, src_mac, dst_mac):
324 group_id = encode_l2_interface_group_id(vlanid, port)
325
326 action=[]
327 if src_mac is not None:
328 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
329
330 if dst_mac is not None:
331 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
332
Flavio Castro91d1a552016-05-17 16:59:44 -0700333 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlanid)))
Pierbbdf3782016-08-22 17:58:26 -0700334
macauley15909e72015-07-17 15:58:57 +0800335 action.append(ofp.action.group(group_id))
Pierbbdf3782016-08-22 17:58:26 -0700336
macauley15909e72015-07-17 15:58:57 +0800337 buckets = [ofp.bucket(actions=action)]
338
339 group_id =encode_l2_rewrite_group_id(id)
340 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
341 group_id=group_id,
342 buckets=buckets
343 )
344 ctrl.message_send(request)
345 return request
Pierbbdf3782016-08-22 17:58:26 -0700346
Andreas Pantelopoulosf83e0212018-03-18 20:44:05 -0700347def add_l3_unicast_group(ctrl, port, vlanid, id, src_mac, dst_mac, send_barrier=False, gid=None):
348
349 if (not gid):
350 group_id = encode_l2_interface_group_id(vlanid, port)
351 else:
352 group_id = gid
macauley15909e72015-07-17 15:58:57 +0800353
354 action=[]
355 if src_mac is not None:
356 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
357
358 if dst_mac is not None:
359 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
360
Flavio Castroaf2b4502016-02-02 17:41:32 -0500361 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlanid)))
Pierbbdf3782016-08-22 17:58:26 -0700362
macauley15909e72015-07-17 15:58:57 +0800363 action.append(ofp.action.group(group_id))
Pierbbdf3782016-08-22 17:58:26 -0700364
macauley15909e72015-07-17 15:58:57 +0800365 buckets = [ofp.bucket(actions=action)]
366
367 group_id =encode_l3_unicast_group_id(id)
368 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
369 group_id=group_id,
370 buckets=buckets
371 )
372 ctrl.message_send(request)
Pier1e4e98e2016-10-26 14:36:05 -0700373
374 if send_barrier:
375 do_barrier(ctrl)
376
macauley15909e72015-07-17 15:58:57 +0800377 return request
Pierbbdf3782016-08-22 17:58:26 -0700378
macauley15909e72015-07-17 15:58:57 +0800379def add_l3_interface_group(ctrl, port, vlanid, id, src_mac):
380 group_id = encode_l2_interface_group_id(vlanid, port)
381
382 action=[]
383 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
Pierbbdf3782016-08-22 17:58:26 -0700384 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlanid)))
macauley15909e72015-07-17 15:58:57 +0800385 action.append(ofp.action.group(group_id))
Pierbbdf3782016-08-22 17:58:26 -0700386
macauley15909e72015-07-17 15:58:57 +0800387 buckets = [ofp.bucket(actions=action)]
388
389 group_id =encode_l3_interface_group_id(id)
390 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
391 group_id=group_id,
392 buckets=buckets
393 )
394 ctrl.message_send(request)
395 return request
396
Pier1e4e98e2016-10-26 14:36:05 -0700397def add_l3_ecmp_group(ctrl, id, l3_ucast_groups, send_barrier=False):
macauley15909e72015-07-17 15:58:57 +0800398 buckets=[]
399 for group in l3_ucast_groups:
400 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
401
402 group_id =encode_l3_ecmp_group_id(id)
403 request = ofp.message.group_add(group_type=ofp.OFPGT_SELECT,
404 group_id=group_id,
405 buckets=buckets
406 )
407 ctrl.message_send(request)
Pier1e4e98e2016-10-26 14:36:05 -0700408
409 if send_barrier:
410 do_barrier(ctrl)
411
macauley15909e72015-07-17 15:58:57 +0800412 return request
Flavio Castroa7162bb2016-07-25 17:30:30 -0700413
414def mod_l3_ecmp_group(ctrl, id, l3_ucast_groups):
415 buckets=[]
416 for group in l3_ucast_groups:
417 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
418
419 group_id =encode_l3_ecmp_group_id(id)
420 request = ofp.message.group_modify(group_type=ofp.OFPGT_SELECT,
421 group_id=group_id,
422 buckets=buckets
423 )
424 ctrl.message_send(request)
425 return request
426
macauley15909e72015-07-17 15:58:57 +0800427def add_l3_mcast_group(ctrl, vid, mcast_group_id, groups_on_buckets):
428 buckets=[]
429 for group in groups_on_buckets:
430 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
Pierbbdf3782016-08-22 17:58:26 -0700431
macauley15909e72015-07-17 15:58:57 +0800432 group_id =encode_l3_mcast_group_id(vid, mcast_group_id)
433 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
434 group_id=group_id,
435 buckets=buckets
436 )
437 ctrl.message_send(request)
438 return request
macauleyfddc4662015-07-27 17:40:30 +0800439
440def add_l2_overlay_flood_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
441 buckets=[]
442 for port in ports:
443 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
444
445 group_id=encode_l2_overlay_group_id(tunnel_id, 0, index)
446 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
447 group_id=group_id,
448 buckets=buckets
449 )
450 ctrl.message_send(request)
451 return request
452
453def add_l2_overlay_flood_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
454 buckets=[]
455 for port in ports:
456 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
457
458 group_id=encode_l2_overlay_group_id(tunnel_id, 1, index)
459 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
460 group_id=group_id,
461 buckets=buckets
462 )
463 ctrl.message_send(request)
464 return request
465
466def add_l2_overlay_mcast_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
467 buckets=[]
468 for port in ports:
469 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
470
471 group_id=encode_l2_overlay_group_id(tunnel_id, 2, index)
472 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
473 group_id=group_id,
474 buckets=buckets
475 )
476 ctrl.message_send(request)
477 return request
478
479def add_l2_overlay_mcast_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
480 buckets=[]
481 for port in ports:
482 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
483
484 group_id=encode_l2_overlay_group_id(tunnel_id, 3, index)
485 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
486 group_id=group_id,
487 buckets=buckets
488 )
489 ctrl.message_send(request)
490 return request
Pierbbdf3782016-08-22 17:58:26 -0700491
macauleyfddc4662015-07-27 17:40:30 +0800492def add_port_table_flow(ctrl, is_overlay=True):
493 match = ofp.match()
494
495 if is_overlay == True:
496 match.oxm_list.append(ofp.oxm.in_port(0x10000))
macauleydbff3272015-07-30 14:07:16 +0800497 NEXT_TABLE=50
macauleyfddc4662015-07-27 17:40:30 +0800498 else:
499 match.oxm_list.append(ofp.oxm.in_port(0))
Pierbbdf3782016-08-22 17:58:26 -0700500 NEXT_TABLE=10
macauleyfddc4662015-07-27 17:40:30 +0800501
502 request = ofp.message.flow_add(
Pier265ad5f2017-02-28 17:46:28 +0100503 table_id=0,
504 cookie=42,
505 match=match,
506 instructions=[
507 ofp.instruction.goto_table(NEXT_TABLE)
508 ],
509 priority=0)
macauleyfddc4662015-07-27 17:40:30 +0800510 logging.info("Add port table, match port %lx" % 0x10000)
511 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -0700512
Flavio Castrod8f8af22015-12-02 18:19:26 -0500513def pop_vlan_flow(ctrl, ports, vlan_id=1):
514 # table 10: vlan
515 # goto to table 20
516 msgs=[]
517 for of_port in ports:
518 match = ofp.match()
519 match.oxm_list.append(ofp.oxm.in_port(of_port))
520 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
521 request = ofp.message.flow_add(
522 table_id=10,
523 cookie=42,
524 match=match,
525 instructions=[
526 ofp.instruction.apply_actions(
527 actions=[
528 ofp.action.pop_vlan()
529 ]
530 ),
531 ofp.instruction.goto_table(20)
532 ],
533 priority=0)
534 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
535 ctrl.message_send(request)
536
537
538 return msgs
macauleyfddc4662015-07-27 17:40:30 +0800539
macauley97557232015-07-16 17:28:07 +0800540def add_vlan_table_flow(ctrl, ports, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
541 # table 10: vlan
542 # goto to table 20
macauley15909e72015-07-17 15:58:57 +0800543 msgs=[]
macauley97557232015-07-16 17:28:07 +0800544 for of_port in ports:
Flavio Castro932014b2016-01-05 18:29:15 -0500545 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
macauley97557232015-07-16 17:28:07 +0800546 match = ofp.match()
547 match.oxm_list.append(ofp.oxm.in_port(of_port))
548 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
549 request = ofp.message.flow_add(
550 table_id=10,
551 cookie=42,
552 match=match,
553 instructions=[
Flavio Castrod8f8af22015-12-02 18:19:26 -0500554 ofp.instruction.apply_actions(
555 actions=[
556 ofp.action.pop_vlan()
557 ]
558 ),
macauley97557232015-07-16 17:28:07 +0800559 ofp.instruction.goto_table(20)
560 ],
561 priority=0)
562 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
563 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -0700564
macauley97557232015-07-16 17:28:07 +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))
Flavio Castro12296312015-12-15 17:48:26 -0500568 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0x1fff))
macauley97557232015-07-16 17:28:07 +0800569 request = ofp.message.flow_add(
570 table_id=10,
571 cookie=42,
572 match=match,
573 instructions=[
574 ofp.instruction.apply_actions(
575 actions=[
Flavio Castroaf2b4502016-02-02 17:41:32 -0500576 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id))
macauley97557232015-07-16 17:28:07 +0800577 ]
578 ),
579 ofp.instruction.goto_table(20)
580 ],
581 priority=0)
582 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
583 ctrl.message_send(request)
macauley15909e72015-07-17 15:58:57 +0800584 msgs.append(request)
macauley97557232015-07-16 17:28:07 +0800585
Flavio Castro932014b2016-01-05 18:29:15 -0500586 if (flag == 4) :
587 match = ofp.match()
588 match.oxm_list.append(ofp.oxm.in_port(of_port))
589 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1fff))
590 request = ofp.message.flow_add(
591 table_id=10,
592 cookie=42,
593 match=match,
594 instructions=[
595 ofp.instruction.apply_actions(
596 actions=[
Flavio Castroaf2b4502016-02-02 17:41:32 -0500597 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id))
Flavio Castro932014b2016-01-05 18:29:15 -0500598 ]
599 ),
600 ofp.instruction.goto_table(20)
601 ],
602 priority=0)
603 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
604 ctrl.message_send(request)
605 msgs.append(request)
606
macauley97557232015-07-16 17:28:07 +0800607 if send_barrier:
608 do_barrier(ctrl)
609
macauley15909e72015-07-17 15:58:57 +0800610 return msgs
Pierbbdf3782016-08-22 17:58:26 -0700611
macauley_cheng6e6a6122015-11-16 14:19:18 +0800612def del_vlan_table_flow(ctrl, ports, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
613 # table 10: vlan
614 # goto to table 20
615 msgs=[]
616 for of_port in ports:
617 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
618 match = ofp.match()
619 match.oxm_list.append(ofp.oxm.in_port(of_port))
620 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
621 request = ofp.message.flow_delete(
622 table_id=10,
623 cookie=42,
624 match=match,
625 priority=0)
626 logging.info("Del vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
627 ctrl.message_send(request)
macauley0f91a3e2015-07-17 18:09:59 +0800628
macauley_cheng6e6a6122015-11-16 14:19:18 +0800629 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
630 match = ofp.match()
631 match.oxm_list.append(ofp.oxm.in_port(of_port))
632 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0xfff))
633 request = ofp.message.flow_delete(
634 table_id=10,
635 cookie=42,
636 match=match,
637 priority=0)
638 logging.info("Del vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
639 ctrl.message_send(request)
640 msgs.append(request)
641
642 if send_barrier:
643 do_barrier(ctrl)
644
645 return msgs
Pierbbdf3782016-08-22 17:58:26 -0700646
macauley_cheng6b311612015-09-04 11:32:27 +0800647def add_vlan_table_flow_pvid(ctrl, in_port, match_vid=None, pvid=1, send_barrier=False):
648 """it will tag pack as untagged packet wether it has tagg or not"""
649 match = ofp.match()
650 match.oxm_list.append(ofp.oxm.in_port(in_port))
651 actions=[]
652 if match_vid == None:
Pierbbdf3782016-08-22 17:58:26 -0700653 match.oxm_list.append(ofp.oxm.vlan_vid(0))
macauley_cheng6b311612015-09-04 11:32:27 +0800654 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+pvid)))
655 goto_table=20
656 else:
657 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+match_vid, 0x1fff))
658 actions.append(ofp.action.push_vlan(0x8100))
Pierbbdf3782016-08-22 17:58:26 -0700659 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+pvid)))
macauley_cheng6b311612015-09-04 11:32:27 +0800660 goto_table=20
Pierbbdf3782016-08-22 17:58:26 -0700661
macauley_cheng6b311612015-09-04 11:32:27 +0800662 request = ofp.message.flow_add(
663 table_id=10,
664 cookie=42,
665 match=match,
666 instructions=[
667 ofp.instruction.apply_actions(actions=actions)
668 ,ofp.instruction.goto_table(goto_table)
669 ],
670 priority=0)
671 logging.info("Add PVID %d on port %d and go to table %ld" %( pvid, in_port, goto_table))
Pierbbdf3782016-08-22 17:58:26 -0700672 ctrl.message_send(request)
673
macauley_cheng6b311612015-09-04 11:32:27 +0800674 if send_barrier:
675 do_barrier(ctrl)
676
677def add_vlan_table_flow_allow_all_vlan(ctrl, in_port, send_barrier=False):
678 """it st flow allow all vlan tag on this port"""
679 match = ofp.match()
680 match.oxm_list.append(ofp.oxm.in_port(in_port))
681 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1000))
682 request = ofp.message.flow_add(
683 table_id=10,
684 cookie=42,
685 match=match,
686 instructions=[
Pierbbdf3782016-08-22 17:58:26 -0700687 ofp.instruction.goto_table(20)
macauley_cheng6b311612015-09-04 11:32:27 +0800688 ],
689 priority=0)
690 logging.info("Add allow all vlan on port %d " %(in_port))
Pierbbdf3782016-08-22 17:58:26 -0700691 ctrl.message_send(request)
macauley_cheng6b311612015-09-04 11:32:27 +0800692
Pier7b031af2016-08-25 15:00:22 -0700693def 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):
694 # Install a flow for VLAN translation
695 # in VLAN table.
696 # table 10: vlan
697 # goto to table 20
698 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
699 match = ofp.match()
700 match.oxm_list.append(ofp.oxm.in_port(of_port))
701 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id,0x1fff))
702
703 actions=[]
704 if vrf!=0:
705 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
706 if new_vlan_id != -1:
707 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_vlan_id)))
708
709 request = ofp.message.flow_add(
710 table_id=10,
711 cookie=42,
712 match=match,
713 instructions=[
714 ofp.instruction.apply_actions(
715 actions=actions
716 ),
717 ofp.instruction.goto_table(20)
718 ],
719 priority=0)
720 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
721 ctrl.message_send(request)
722
Andreas Pantelopoulosf83e0212018-03-18 20:44:05 -0700723
724def add_one_egress_vlan_table_flow(ctrl, of_port, match_vlan, inner_vlan, outer_vlan):
725
726 # used for translating single to double tagged packets only
727
728 match = ofp.match()
729 match.oxm_list.append(ofp.oxm.exp4ByteValue(ofp.oxm.OFDPA_EXP_TYPE_ACTSET_OUTPUT, of_port))
730 match.oxm_list.append(ofp.oxm.exp1ByteValue(ofp.oxm.OFDPA_EXP_TYPE_ALLOW_VLAN_TRANSLATION, 1))
731 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+match_vlan,0x1fff))
732
733 actions=[]
734 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+inner_vlan)))
735 actions.append(ofp.action.push_vlan(0x8100))
736 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+outer_vlan)))
737
738 request = ofp.message.flow_add(
739 table_id=EGRESS_VLAN_FLOW_TABLE,
740 cookie=42,
741 match=match,
742 instructions=[
743 ofp.instruction.apply_actions(
744 actions=actions
745 ),
746 ofp.instruction.goto_table(EGRESS_DSCP_TABLE)
747 ],
748 priority=0)
749
750 ctrl.message_send(request)
751
752 return
753
Piere1308762016-09-12 15:29:56 -0700754def 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):
Andreas Pantelopoulosf83e0212018-03-18 20:44:05 -0700755
macauley0f91a3e2015-07-17 18:09:59 +0800756 # goto to table 20
Flavio Castro932014b2016-01-05 18:29:15 -0500757 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
macauley0f91a3e2015-07-17 18:09:59 +0800758 match = ofp.match()
759 match.oxm_list.append(ofp.oxm.in_port(of_port))
Flavio Castro12296312015-12-15 17:48:26 -0500760 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id,0x1fff))
macauley7f89d962015-08-06 18:13:48 +0800761
762 actions=[]
Alex Yashchuk9f449462017-12-09 18:27:19 +0200763 if config["switch_type"] != 'xpliant' and vrf != 0:
764 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
Pierbbdf3782016-08-22 17:58:26 -0700765
Flavio Castro6d498522015-12-15 14:05:04 -0500766 #actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(value=vlan_id)))
macauley7f89d962015-08-06 18:13:48 +0800767
macauley0f91a3e2015-07-17 18:09:59 +0800768 request = ofp.message.flow_add(
769 table_id=10,
770 cookie=42,
771 match=match,
772 instructions=[
macauley53d90fe2015-08-04 17:34:22 +0800773 ofp.instruction.apply_actions(
macauley7f89d962015-08-06 18:13:48 +0800774 actions=actions
macauley53d90fe2015-08-04 17:34:22 +0800775 ),
776 ofp.instruction.goto_table(20)
macauley0f91a3e2015-07-17 18:09:59 +0800777 ],
778 priority=0)
779 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
780 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -0700781
macauley0f91a3e2015-07-17 18:09:59 +0800782 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
Andreas Pantelopoulosf83e0212018-03-18 20:44:05 -0700783
macauley0f91a3e2015-07-17 18:09:59 +0800784 match = ofp.match()
785 match.oxm_list.append(ofp.oxm.in_port(of_port))
Flavio Castro12296312015-12-15 17:48:26 -0500786 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0x1fff))
Pierbbdf3782016-08-22 17:58:26 -0700787
macauley7f89d962015-08-06 18:13:48 +0800788 actions=[]
789 if vrf!=0:
790 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
Pierbbdf3782016-08-22 17:58:26 -0700791
Andreas Pantelopoulosf83e0212018-03-18 20:44:05 -0700792 # actions.append(ofp.action.push_vlan(0x8100))
Flavio Castro91d1a552016-05-17 16:59:44 -0700793 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
Pierbbdf3782016-08-22 17:58:26 -0700794
macauley0f91a3e2015-07-17 18:09:59 +0800795 request = ofp.message.flow_add(
796 table_id=10,
797 cookie=42,
798 match=match,
799 instructions=[
800 ofp.instruction.apply_actions(
macauley7f89d962015-08-06 18:13:48 +0800801 actions=actions
macauley0f91a3e2015-07-17 18:09:59 +0800802 ),
803 ofp.instruction.goto_table(20)
804 ],
805 priority=0)
806 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
807 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -0700808
Flavio Castro932014b2016-01-05 18:29:15 -0500809 if (flag == 4) :
810 match = ofp.match()
811 match.oxm_list.append(ofp.oxm.in_port(of_port))
812 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000,0x1fff))
813
814 actions=[]
815 if vrf!=0:
816 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
817
Flavio Castro91d1a552016-05-17 16:59:44 -0700818 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
Flavio Castro932014b2016-01-05 18:29:15 -0500819
820 request = ofp.message.flow_add(
821 table_id=10,
822 cookie=42,
823 match=match,
824 instructions=[
825 ofp.instruction.apply_actions(
826 actions=actions
827 ),
828 ofp.instruction.goto_table(20)
829 ],
830 priority=0)
831 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
832 ctrl.message_send(request)
macauley0f91a3e2015-07-17 18:09:59 +0800833
Piere1308762016-09-12 15:29:56 -0700834 if (flag == VLAN_TABLE_FLAG_ONLY_STACKED):
835 # This flag is meant to managed stacked vlan packtes
836 # Matches on outer VLAN_ID, set OVID with outer VLAN.
837 # Finally expose inner VLAN_ID with a pop action and
838 # goto VLAN_1_FLOW_TABLE
839 match = ofp.match()
840 match.oxm_list.append(ofp.oxm.in_port(of_port))
841 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id,0x1fff))
842
843 actions=[]
Andreas Pantelopoulosf83e0212018-03-18 20:44:05 -0700844 # actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_OVID, value=0x1000+vlan_id)))
Piere1308762016-09-12 15:29:56 -0700845 actions.append(ofp.action.pop_vlan())
Andreas Pantelopoulosf83e0212018-03-18 20:44:05 -0700846 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_OVID, value=0x1000+vlan_id)))
Piere1308762016-09-12 15:29:56 -0700847
848 request = ofp.message.flow_add(
849 table_id=10,
850 cookie=42,
851 match=match,
852 instructions=[
853 ofp.instruction.apply_actions(
854 actions=actions
855 ),
856 ofp.instruction.goto_table(VLAN_1_FLOW_TABLE)
857 ],
858 priority=0)
859 logging.info("Add vlan %d tagged packets on port %d and go to table %d" %( vlan_id, of_port, VLAN_1_FLOW_TABLE))
860 ctrl.message_send(request)
861
862 if (flag == VLAN_TABLE_FLAG_PRIORITY) :
863 match = ofp.match()
864 match.oxm_list.append(ofp.oxm.in_port(of_port))
865 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1fff))
866 request = ofp.message.flow_add(
867 table_id=10,
868 cookie=42,
869 match=match,
870 instructions=[
871 ofp.instruction.apply_actions(
872 actions=[
873 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)),
874 ofp.action.push_vlan(0x8100),
875 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+out_vlan_id)),
876 ]
877 ),
878 ofp.instruction.goto_table(20)
879 ],
880 priority=0)
881 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
882 ctrl.message_send(request)
883
884 if send_barrier:
885 do_barrier(ctrl)
886
887 return request
888
Piercf76e802016-09-19 20:16:35 -0700889def add_one_vlan_table_flow_pw(ctrl, of_port, tunnel_index, new_vlan_id=1, vlan_id=1, vrf=0, flag=VLAN_TABLE_FLAG_ONLY_TAG, send_barrier=False):
890 # table 10: vlan
891 # goto to table 13
892 if flag == VLAN_TABLE_FLAG_ONLY_TAG:
893 match = ofp.match()
894 match.oxm_list.append(ofp.oxm.in_port(of_port))
895 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id, 0x1fff))
896
897 actions=[]
898 if vlan_id == -1:
899 actions.append(ofp.action.pop_vlan())
900 if new_vlan_id > 1:
901 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_vlan_id)))
902 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
903 actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
904 # 0x0000nnnn is for UNI interfaces
905 actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port)))
906
907 request = ofp.message.flow_add(
908 table_id=10,
909 cookie=42,
910 match=match,
911 instructions=[
912 ofp.instruction.apply_actions(
913 actions=actions
914 ),
915 ofp.instruction.goto_table(MPLS_L2_PORT_FLOW_TABLE)
916 ],
917 priority=0)
918 logging.info("Add vlan %d tagged packets on port %d and go to table %d" % (vlan_id, of_port, MPLS_L2_PORT_FLOW_TABLE))
919 ctrl.message_send(request)
920
921 if flag == VLAN_TABLE_FLAG_ONLY_UNTAG:
922 match = ofp.match()
923 match.oxm_list.append(ofp.oxm.in_port(of_port))
924 match.oxm_list.append(ofp.oxm.vlan_vid(0))
925
926 actions=[]
927 if vlan_id > 1:
Charles Chanc85f1562018-01-18 15:44:29 -0800928 # actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
929 # actions.append(ofp.action.set_field(ofp.action.push_vlan(0x8100)))
Piercf76e802016-09-19 20:16:35 -0700930 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
Charles Chanc85f1562018-01-18 15:44:29 -0800931
Piercf76e802016-09-19 20:16:35 -0700932 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
933 actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
934 # 0x0000nnnn is for UNI interfaces
935 actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port)))
936
937 request = ofp.message.flow_add(
938 table_id=10,
939 cookie=42,
940 match=match,
941 instructions=[
942 ofp.instruction.apply_actions(
943 actions=actions
944 ),
945 ofp.instruction.goto_table(MPLS_L2_PORT_FLOW_TABLE)
946 ],
947 priority=0)
948 logging.info("Add vlan %d untagged packets on port %d and go to table %d" % (vlan_id, of_port, MPLS_L2_PORT_FLOW_TABLE))
949 ctrl.message_send(request)
950
951 if send_barrier:
952 do_barrier(ctrl)
953
954 return request
955
Piere1308762016-09-12 15:29:56 -0700956def 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):
Andreas Pantelopoulosf83e0212018-03-18 20:44:05 -0700957
Piere1308762016-09-12 15:29:56 -0700958 # table 11: vlan 1 table
959 # goto to table 20
960 if flag == VLAN_TABLE_FLAG_ONLY_TAG:
961 match = ofp.match()
962 match.oxm_list.append(ofp.oxm.in_port(of_port))
963 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
964 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
965
966 actions=[]
967 actions.append(ofp.action.push_vlan(0x8100))
968 if new_outer_vlan_id != -1:
969 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_outer_vlan_id)))
970 else:
971 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+outer_vlan_id)))
972
973 request = ofp.message.flow_add(
974 table_id=11,
975 cookie=42,
976 match=match,
977 instructions=[
978 ofp.instruction.apply_actions(
979 actions=actions
980 ),
981 ofp.instruction.goto_table(TERMINATION_FLOW_TABLE)
982 ],
983 priority=0)
984 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))
985 ctrl.message_send(request)
986
987 if flag == VLAN_TABLE_FLAG_ONLY_UNTAG:
Andreas Pantelopoulosf83e0212018-03-18 20:44:05 -0700988
Piere1308762016-09-12 15:29:56 -0700989 match = ofp.match()
990 match.oxm_list.append(ofp.oxm.in_port(of_port))
991 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
992 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
993
994 actions=[]
995 request = ofp.message.flow_add(
996 table_id=11,
997 cookie=42,
998 match=match,
999 instructions=[
1000 ofp.instruction.apply_actions(
1001 actions=actions
1002 ),
1003 ofp.instruction.goto_table(TERMINATION_FLOW_TABLE)
1004 ],
1005 priority=0)
1006 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))
1007 ctrl.message_send(request)
1008
Andreas Pantelopoulosf83e0212018-03-18 20:44:05 -07001009 if flag == VLAN_TABLE_FLAG_ONLY_POP_VLAN:
1010
1011 print("INSTALLIN IN TABLE 11!")
1012
1013 match = ofp.match()
1014 match.oxm_list.append(ofp.oxm.in_port(of_port))
1015 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
1016 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
1017
1018 actions=[]
1019 actions.append(ofp.action.pop_vlan())
1020
1021 request = ofp.message.flow_add(
1022 table_id=11,
1023 cookie=42,
1024 match=match,
1025 instructions=[
1026 ofp.instruction.apply_actions(
1027 actions=actions
1028 ),
1029 ofp.instruction.goto_table(TERMINATION_FLOW_TABLE)
1030 ],
1031 priority=0)
1032 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))
1033 ctrl.message_send(request)
1034
1035
macauley0f91a3e2015-07-17 18:09:59 +08001036 if send_barrier:
1037 do_barrier(ctrl)
1038
1039 return request
Pierbbdf3782016-08-22 17:58:26 -07001040
Piercf76e802016-09-19 20:16:35 -07001041def add_one_vlan_1_table_flow_pw(ctrl, of_port, tunnel_index, new_outer_vlan_id=-1, outer_vlan_id=1, inner_vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_TAG, send_barrier=False):
Charles Chanc85f1562018-01-18 15:44:29 -08001042
Piercf76e802016-09-19 20:16:35 -07001043 # table 11: vlan 1 table
1044 # goto to table 13
1045 match = ofp.match()
1046 match.oxm_list.append(ofp.oxm.in_port(of_port))
1047 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
1048 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
1049
1050 actions=[]
1051 actions.append(ofp.action.push_vlan(0x8100))
1052 if new_outer_vlan_id != -1:
Charles Chanc85f1562018-01-18 15:44:29 -08001053 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_outer_vlan_id)))
Piercf76e802016-09-19 20:16:35 -07001054 else:
Charles Chanc85f1562018-01-18 15:44:29 -08001055 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+outer_vlan_id)))
Piercf76e802016-09-19 20:16:35 -07001056
1057 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
1058 actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
1059 # 0x0000nnnn is for UNI interfaces
1060 actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port)))
1061
1062 request = ofp.message.flow_add(
Charles Chanc85f1562018-01-18 15:44:29 -08001063 table_id=11,
1064 cookie=42,
1065 match=match,
1066 instructions=[
1067 ofp.instruction.apply_actions(
1068 actions=actions
1069 ),
1070 ofp.instruction.goto_table(MPLS_L2_PORT_FLOW_TABLE)
1071 ],
1072 priority=0)
Piercf76e802016-09-19 20:16:35 -07001073 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, MPLS_L2_PORT_FLOW_TABLE))
1074 ctrl.message_send(request)
Piercf76e802016-09-19 20:16:35 -07001075 if send_barrier:
1076 do_barrier(ctrl)
1077
1078 return request
1079
macauley97557232015-07-16 17:28:07 +08001080def add_bridge_flow(ctrl, dst_mac, vlanid, group_id, send_barrier=False):
1081 match = ofp.match()
castroflavio21894482015-12-08 15:29:55 -05001082 priority=500
macauleyfddc4662015-07-27 17:40:30 +08001083 if dst_mac!=None:
castroflavio21894482015-12-08 15:29:55 -05001084 priority=1000
macauleyfddc4662015-07-27 17:40:30 +08001085 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
1086
macauley97557232015-07-16 17:28:07 +08001087 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
macauleyfddc4662015-07-27 17:40:30 +08001088
macauley97557232015-07-16 17:28:07 +08001089 request = ofp.message.flow_add(
1090 table_id=50,
1091 cookie=42,
1092 match=match,
1093 instructions=[
1094 ofp.instruction.write_actions(
1095 actions=[
1096 ofp.action.group(group_id)]),
1097 ofp.instruction.goto_table(60)
1098 ],
1099 buffer_id=ofp.OFP_NO_BUFFER,
castroflavio21894482015-12-08 15:29:55 -05001100 priority=priority)
macauley97557232015-07-16 17:28:07 +08001101
1102 logging.info("Inserting Brdige flow vlan %d, mac %s", vlanid, dst_mac)
1103 ctrl.message_send(request)
1104
1105 if send_barrier:
Pierbbdf3782016-08-22 17:58:26 -07001106 do_barrier(ctrl)
macauley15909e72015-07-17 15:58:57 +08001107
Pierbbdf3782016-08-22 17:58:26 -07001108 return request
macauleyfddc4662015-07-27 17:40:30 +08001109
1110def add_overlay_bridge_flow(ctrl, dst_mac, vnid, group_id, is_group=True, send_barrier=False):
1111 match = ofp.match()
1112 if dst_mac!=None:
1113 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
1114
1115 match.oxm_list.append(ofp.oxm.tunnel_id(vnid))
1116 if is_group == True:
1117 actions=[ofp.action.group(group_id)]
1118 else:
1119 actions=[ofp.action.output(group_id)]
1120
1121 request = ofp.message.flow_add(
1122 table_id=50,
1123 cookie=42,
1124 match=match,
1125 instructions=[
1126 ofp.instruction.write_actions(
1127 actions=actions),
1128 ofp.instruction.goto_table(60)
1129 ],
1130 buffer_id=ofp.OFP_NO_BUFFER,
Pierbbdf3782016-08-22 17:58:26 -07001131 priority=1000)
macauleyfddc4662015-07-27 17:40:30 +08001132
1133 logging.info("Inserting Brdige flow vnid %d, mac %s", vnid, dst_mac)
1134 ctrl.message_send(request)
1135
1136 if send_barrier:
Pierbbdf3782016-08-22 17:58:26 -07001137 do_barrier(ctrl)
macauleyfddc4662015-07-27 17:40:30 +08001138
Pierbbdf3782016-08-22 17:58:26 -07001139 return request
1140
macauley_cheng6b133662015-11-09 13:52:39 +08001141def add_termination_flow(ctrl, in_port, eth_type, dst_mac, vlanid, goto_table=None, send_barrier=False):
macauley0f91a3e2015-07-17 18:09:59 +08001142 match = ofp.match()
macauley0f91a3e2015-07-17 18:09:59 +08001143 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
macauleyfddc4662015-07-27 17:40:30 +08001144 if dst_mac[0]&0x01 == 0x01:
1145 match.oxm_list.append(ofp.oxm.eth_dst_masked(dst_mac, [0xff, 0xff, 0xff, 0x80, 0x00, 0x00]))
1146 goto_table=40
1147 else:
macauley53d90fe2015-08-04 17:34:22 +08001148 if in_port!=0:
1149 match.oxm_list.append(ofp.oxm.in_port(in_port))
macauleyfddc4662015-07-27 17:40:30 +08001150 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
1151 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
macauley_cheng6b133662015-11-09 13:52:39 +08001152 if goto_table == None:
1153 goto_table=30
macauley0f91a3e2015-07-17 18:09:59 +08001154
1155 request = ofp.message.flow_add(
1156 table_id=20,
1157 cookie=42,
1158 match=match,
1159 instructions=[
1160 ofp.instruction.goto_table(goto_table)
1161 ],
1162 buffer_id=ofp.OFP_NO_BUFFER,
Pierbbdf3782016-08-22 17:58:26 -07001163 priority=1)
macauley0f91a3e2015-07-17 18:09:59 +08001164
1165 logging.info("Inserting termination flow inport %d, eth_type %lx, vlan %d, mac %s", in_port, eth_type, vlanid, dst_mac)
1166 ctrl.message_send(request)
macauley0f91a3e2015-07-17 18:09:59 +08001167 if send_barrier:
Pierbbdf3782016-08-22 17:58:26 -07001168 do_barrier(ctrl)
macauley0f91a3e2015-07-17 18:09:59 +08001169
Pierbbdf3782016-08-22 17:58:26 -07001170 return request
1171
Alex Yashchuk9f449462017-12-09 18:27:19 +02001172def add_unicast_routing_flow(ctrl, eth_type, dst_ip, mask, action_group_id, vrf=0, send_ctrl=False, send_barrier=False, priority = 1):
macauley0f91a3e2015-07-17 18:09:59 +08001173 match = ofp.match()
1174 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
Alex Yashchuk9f449462017-12-09 18:27:19 +02001175 if config["switch_type"] != 'xpliant' and vrf != 0:
macauley53d90fe2015-08-04 17:34:22 +08001176 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_VRF, vrf))
macauley0f91a3e2015-07-17 18:09:59 +08001177
Flavio Castroaf2b4502016-02-02 17:41:32 -05001178 match.oxm_list.append(ofp.oxm.ipv4_dst_masked(dst_ip, mask))
1179
1180 instructions = []
1181 instructions.append(ofp.instruction.goto_table(60))
1182 if send_ctrl:
Pier265ad5f2017-02-28 17:46:28 +01001183 instructions.append(ofp.instruction.write_actions(
Flavio Castroaf2b4502016-02-02 17:41:32 -05001184 actions=[ofp.action.output( port=ofp.OFPP_CONTROLLER,
1185 max_len=ofp.OFPCML_NO_BUFFER)]))
Pierbbdf3782016-08-22 17:58:26 -07001186 else:
Flavio Castroaf2b4502016-02-02 17:41:32 -05001187 instructions.append(ofp.instruction.write_actions(
1188 actions=[ofp.action.group(action_group_id)]))
macauley53d90fe2015-08-04 17:34:22 +08001189
macauley0f91a3e2015-07-17 18:09:59 +08001190 request = ofp.message.flow_add(
1191 table_id=30,
1192 cookie=42,
1193 match=match,
Flavio Castroaf2b4502016-02-02 17:41:32 -05001194 instructions=instructions,
macauley0f91a3e2015-07-17 18:09:59 +08001195 buffer_id=ofp.OFP_NO_BUFFER,
Alex Yashchuk9f449462017-12-09 18:27:19 +02001196 priority=priority)
macauley0f91a3e2015-07-17 18:09:59 +08001197
1198 logging.info("Inserting unicast routing flow eth_type %lx, dip %ld",eth_type, dst_ip)
1199 ctrl.message_send(request)
1200
1201 if send_barrier:
Pierbbdf3782016-08-22 17:58:26 -07001202 do_barrier(ctrl)
macauley0f91a3e2015-07-17 18:09:59 +08001203
Flavio Castro9debaaa2016-07-26 19:37:50 -07001204 return request
Flavio Castrod8f8af22015-12-02 18:19:26 -05001205
Pier1e4e98e2016-10-26 14:36:05 -07001206def add_unicast_v6_routing_flow(ctrl, eth_type, dst_ip, mask, action_group_id, vrf=0, send_ctrl=False, send_barrier=False):
1207 match = ofp.match()
1208 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
1209 if vrf != 0:
1210 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_VRF, vrf))
1211
1212 match.oxm_list.append(ofp.oxm.ipv6_dst_masked(parse_ipv6(dst_ip), parse_ipv6(mask)))
1213
1214 instructions = []
1215 instructions.append(ofp.instruction.goto_table(60))
1216 if send_ctrl:
Pier265ad5f2017-02-28 17:46:28 +01001217 instructions.append(ofp.instruction.write_actions(
Pier1e4e98e2016-10-26 14:36:05 -07001218 actions=[ofp.action.output( port=ofp.OFPP_CONTROLLER,
1219 max_len=ofp.OFPCML_NO_BUFFER)]))
1220 else:
1221 instructions.append(ofp.instruction.write_actions(
1222 actions=[ofp.action.group(action_group_id)]))
1223
1224 request = ofp.message.flow_add(
1225 table_id=30,
1226 cookie=42,
1227 match=match,
1228 instructions=instructions,
1229 buffer_id=ofp.OFP_NO_BUFFER,
1230 priority=1)
1231
1232 logging.info("Inserting unicast routing flow eth_type %lx, dip %s",eth_type, dst_ip)
1233 ctrl.message_send(request)
1234
1235 if send_barrier:
1236 do_barrier(ctrl)
1237
1238 return request
1239
Andreas Pantelopoulos6c76b942018-01-22 10:03:02 -08001240def add_mpls_flow(ctrl, action_group_id=0x0, label=100 ,ethertype=0x0800, bos=1, vrf=1, goto_table=27, dec_ttl=False, send_barrier=False):
Flavio Castrob702a2f2016-04-10 22:01:48 -04001241 match = ofp.match()
1242 match.oxm_list.append(ofp.oxm.eth_type(0x8847))
1243 match.oxm_list.append(ofp.oxm.mpls_label(label))
1244 match.oxm_list.append(ofp.oxm.mpls_bos(bos))
Pier265ad5f2017-02-28 17:46:28 +01001245 write_actions = []
1246 write_actions.append(ofp.action.group(action_group_id))
1247 apply_actions = []
1248 apply_actions = [ofp.action.dec_mpls_ttl(),
Flavio Castro8ca52542016-04-11 11:24:49 -04001249 ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf))]
Pier265ad5f2017-02-28 17:46:28 +01001250 if (goto_table != 29):
1251 apply_actions.append(ofp.action.set_field(
Flavio Castrod80fbc32016-07-25 15:54:26 -07001252 ofp.oxm.exp2ByteValue(exp_type=23, value=32)))
Pier265ad5f2017-02-28 17:46:28 +01001253 apply_actions.append(ofp.action.copy_ttl_in())
Flavio Castro9debaaa2016-07-26 19:37:50 -07001254
Flavio Castrob702a2f2016-04-10 22:01:48 -04001255 request = ofp.message.flow_add(
1256 table_id=24,
1257 cookie=43,
1258 match=match,
1259 instructions=[
Pier265ad5f2017-02-28 17:46:28 +01001260 ofp.instruction.apply_actions(actions=apply_actions),
1261 ofp.instruction.write_actions(actions=write_actions),
Flavio Castro8ca52542016-04-11 11:24:49 -04001262 ofp.instruction.goto_table(goto_table)
Flavio Castrob702a2f2016-04-10 22:01:48 -04001263 ],
1264 buffer_id=ofp.OFP_NO_BUFFER,
1265 priority=1)
Flavio Castrob702a2f2016-04-10 22:01:48 -04001266 logging.info("Inserting MPLS flow , label %ld", label)
1267 ctrl.message_send(request)
1268
1269 if send_barrier:
1270 do_barrier(ctrl)
1271
1272 return request
1273
Alex Yashchuk9f449462017-12-09 18:27:19 +02001274def xpliant_add_mpls_flow(ctrl, action_group_id=0x0, label=100 ,ethertype=0x0800, bos=1, vrf=1, goto_table=27, send_barrier=False):
1275 match = ofp.match()
1276 match.oxm_list.append(ofp.oxm.eth_type(0x8847))
1277 match.oxm_list.append(ofp.oxm.mpls_label(label))
1278
1279 apply_actions = []
1280 apply_actions.append(ofp.action.group(action_group_id))
1281 apply_actions.append(ofp.action.dec_mpls_ttl())
1282 if (goto_table != 29):
1283 apply_actions.append(ofp.action.pop_mpls(ethertype))
1284
1285 request = ofp.message.flow_add(
1286 table_id=24,
1287 cookie=43,
1288 match=match,
1289 instructions=[
1290 ofp.instruction.apply_actions(actions=apply_actions),
1291 ],
1292 buffer_id=ofp.OFP_NO_BUFFER,
1293 priority=1)
1294 logging.info("Inserting MPLS flow , label %ld", label)
1295 ctrl.message_send(request)
1296
1297 if send_barrier:
1298 do_barrier(ctrl)
1299
1300 return request
1301
Andreas Pantelopoulos6c76b942018-01-22 10:03:02 -08001302def add_mpls_flow_swap(ctrl, action_group_id, label, ethertype, bos, goto_table=MPLS_TYPE_FLOW_TABLE, of_port=0, send_barrier=False):
1303 match = ofp.match()
1304 match.oxm_list.append(ofp.oxm.eth_type(0x8847))
1305 match.oxm_list.append(ofp.oxm.mpls_label(label))
1306 match.oxm_list.append(ofp.oxm.mpls_bos(1))
1307
1308 apply_actions = []
1309 write_actions = []
1310 apply_actions.append(ofp.action.dec_mpls_ttl())
1311 write_actions.append(ofp.action.group(action_group_id))
1312
1313 request = ofp.message.flow_add(
1314 table_id=24,
1315 cookie=43,
1316 match=match,
1317 instructions=[
1318 ofp.instruction.apply_actions(actions=apply_actions),
1319 ofp.instruction.write_actions(actions=write_actions),
1320 ofp.instruction.goto_table(goto_table)
1321 ],
1322 buffer_id=ofp.OFP_NO_BUFFER,
1323 priority=1)
1324
1325 logging.info("Inserting MPLS flow , label %ld", label)
1326 ctrl.message_send(request)
1327
1328 if send_barrier:
1329 do_barrier(ctrl)
1330
1331 return request
1332
1333
Pierf6f28162016-09-22 16:30:52 -07001334def add_mpls_flow_pw(ctrl, action_group_id, label, ethertype, bos, tunnel_index, goto_table=MPLS_TYPE_FLOW_TABLE, popMPLS=True, popL2=False, of_port=0, send_barrier=False):
Pierb5da4c92016-09-21 11:23:35 -07001335 match = ofp.match()
1336 match.oxm_list.append(ofp.oxm.eth_type(0x8847))
1337 match.oxm_list.append(ofp.oxm.mpls_label(label))
1338 match.oxm_list.append(ofp.oxm.mpls_bos(bos))
1339
Pier265ad5f2017-02-28 17:46:28 +01001340 apply_actions = []
1341 write_actions = []
1342 apply_actions.append(ofp.action.dec_mpls_ttl())
Pierf6f28162016-09-22 16:30:52 -07001343 if popMPLS == True:
Pier265ad5f2017-02-28 17:46:28 +01001344 apply_actions.append(ofp.action.copy_ttl_in())
1345 apply_actions.append(ofp.action.pop_mpls(ethertype))
Pierf6f28162016-09-22 16:30:52 -07001346 if bos==1 and popL2 == True:
Pier265ad5f2017-02-28 17:46:28 +01001347 apply_actions.append(ofp.action.ofdpa_pop_l2_header())
1348 apply_actions.append(ofp.action.ofdpa_pop_cw())
1349 apply_actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
Pierf6f28162016-09-22 16:30:52 -07001350 # 0x0002nnnn is for UNI interfaces
Pier265ad5f2017-02-28 17:46:28 +01001351 apply_actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00020000 + of_port)))
1352 apply_actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
1353 write_actions.append(ofp.action.group(action_group_id))
Pierb5da4c92016-09-21 11:23:35 -07001354
1355 request = ofp.message.flow_add(
Pier265ad5f2017-02-28 17:46:28 +01001356 table_id=24,
1357 cookie=43,
1358 match=match,
1359 instructions=[
1360 ofp.instruction.apply_actions(actions=apply_actions),
1361 ofp.instruction.write_actions(actions=write_actions),
1362 ofp.instruction.goto_table(goto_table)
1363 ],
1364 buffer_id=ofp.OFP_NO_BUFFER,
1365 priority=1)
Pierb5da4c92016-09-21 11:23:35 -07001366 logging.info("Inserting MPLS flow , label %ld", label)
1367 ctrl.message_send(request)
1368
1369 if send_barrier:
1370 do_barrier(ctrl)
1371
1372 return request
1373
macauleyfddc4662015-07-27 17:40:30 +08001374def add_mcast4_routing_flow(ctrl, vlan_id, src_ip, src_ip_mask, dst_ip, action_group_id, send_barrier=False):
1375 match = ofp.match()
1376 match.oxm_list.append(ofp.oxm.eth_type(0x0800))
Alex Yashchuk9f449462017-12-09 18:27:19 +02001377 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000 + vlan_id))
macauleyfddc4662015-07-27 17:40:30 +08001378 if src_ip_mask!=0:
1379 match.oxm_list.append(ofp.oxm.ipv4_src_masked(src_ip, src_ip_mask))
1380 else:
1381 match.oxm_list.append(ofp.oxm.ipv4_src(src_ip))
Pierbbdf3782016-08-22 17:58:26 -07001382
macauleyfddc4662015-07-27 17:40:30 +08001383 match.oxm_list.append(ofp.oxm.ipv4_dst(dst_ip))
Pierbbdf3782016-08-22 17:58:26 -07001384
macauleyfddc4662015-07-27 17:40:30 +08001385 request = ofp.message.flow_add(
1386 table_id=40,
1387 cookie=42,
1388 match=match,
1389 instructions=[
1390 ofp.instruction.write_actions(
1391 actions=[ofp.action.group(action_group_id)]),
1392 ofp.instruction.goto_table(60)
1393 ],
1394 buffer_id=ofp.OFP_NO_BUFFER,
Pierbbdf3782016-08-22 17:58:26 -07001395 priority=1)
macauleyfddc4662015-07-27 17:40:30 +08001396
1397 logging.info("Inserting mcast routing flow eth_type %lx, dip %lx, sip %lx, sip_mask %lx",0x0800, dst_ip, src_ip, src_ip_mask)
1398 ctrl.message_send(request)
1399
1400 if send_barrier:
Pierbbdf3782016-08-22 17:58:26 -07001401 do_barrier(ctrl)
macauleyfddc4662015-07-27 17:40:30 +08001402
Pierbbdf3782016-08-22 17:58:26 -07001403 return request
macauley_cheng6b133662015-11-09 13:52:39 +08001404
Pier1e4e98e2016-10-26 14:36:05 -07001405def add_acl_rule(ctrl, eth_type=None, ip_proto=None, send_barrier=False):
1406 match = ofp.match()
1407 if eth_type != None:
1408 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
1409 if ip_proto != None:
1410 match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
1411
1412 request = ofp.message.flow_add(
1413 table_id=60,
1414 cookie=42,
1415 match=match,
1416 instructions=[
1417 ofp.instruction.apply_actions(
1418 actions=[ofp.action.output(port=ofp.OFPP_CONTROLLER, max_len=ofp.OFPCML_NO_BUFFER)]
1419 ),
1420 ],
1421 buffer_id=ofp.OFP_NO_BUFFER,
1422 priority=1
1423 )
1424
1425 logging.info("Inserting ACL flow eth_type %lx, ip_proto %ld", eth_type, ip_proto)
1426 ctrl.message_send(request)
1427
1428 if send_barrier:
1429 do_barrier(ctrl)
1430
1431 return request
1432
macauley_cheng6b133662015-11-09 13:52:39 +08001433#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 +08001434def 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 +08001435 match = ofp.match()
1436 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
1437 match.oxm_list.append(ofp.oxm.ipv4_dst(ip_dst))
1438 match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
1439 match.oxm_list.append(ofp.oxm.tcp_dst(tcp_dst))
Pierbbdf3782016-08-22 17:58:26 -07001440
macauley_cheng6b133662015-11-09 13:52:39 +08001441 request = ofp.message.flow_add(
1442 table_id=28,
1443 cookie=42,
1444 match=match,
1445 instructions=[
1446 ofp.instruction.write_actions(
1447 actions=[ofp.action.set_field(ofp.oxm.ipv4_dst(set_ip_dst)),
1448 ofp.action.set_field(ofp.oxm.tcp_dst(set_tcp_dst)),
1449 ofp.action.group(action_group_id)]),
1450 ofp.instruction.goto_table(60)
1451 ],
1452 buffer_id=ofp.OFP_NO_BUFFER,
Pierbbdf3782016-08-22 17:58:26 -07001453 priority=1)
macauley_cheng6b133662015-11-09 13:52:39 +08001454 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)
1455 ctrl.message_send(request)
1456 return request
macauley_chengeffc20a2015-11-09 16:14:56 +08001457
1458#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
1459def add_snat_flow(ctrl, eth_type, ip_src, ip_proto, tcp_src, set_ip_src, set_tcp_src):
1460 match = ofp.match()
1461 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
1462 match.oxm_list.append(ofp.oxm.ipv4_src(ip_src))
1463 match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
1464 match.oxm_list.append(ofp.oxm.tcp_src(tcp_src))
Pierbbdf3782016-08-22 17:58:26 -07001465
macauley_chengeffc20a2015-11-09 16:14:56 +08001466 request = ofp.message.flow_add(
1467 table_id=29,
1468 cookie=42,
1469 match=match,
1470 instructions=[
1471 ofp.instruction.write_actions(
1472 actions=[ofp.action.set_field(ofp.oxm.ipv4_src(set_ip_src)),
1473 ofp.action.set_field(ofp.oxm.tcp_src(set_tcp_src))]),
1474 ofp.instruction.goto_table(30)
1475 ],
1476 buffer_id=ofp.OFP_NO_BUFFER,
Pierbbdf3782016-08-22 17:58:26 -07001477 priority=1)
macauley_chengeffc20a2015-11-09 16:14:56 +08001478 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)
1479 ctrl.message_send(request)
1480 return request
Pierbbdf3782016-08-22 17:58:26 -07001481
1482def get_vtap_lport_config_xml(dp_id, lport, phy_port, vlan, vnid, operation='merge'):
macauleyfddc4662015-07-27 17:40:30 +08001483 """
1484 Command Example:
1485 of-agent vtap 10001 ethernet 1/1 vid 1
1486 of-agent vtp 10001 vni 10
1487 """
1488 if vlan != 0:
1489 config_vtap_xml="""
1490 <config>
1491 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1492 <id>capable-switch-1</id>
1493 <resources>
1494 <port xc:operation="OPERATION">
Pierbbdf3782016-08-22 17:58:26 -07001495 <resource-id >LPORT</resource-id>
macauleyfddc4662015-07-27 17:40:30 +08001496 <features>
1497 <current>
1498 <rate>10Gb</rate>
1499 <medium>fiber</medium>
Pierbbdf3782016-08-22 17:58:26 -07001500 <pause>symmetric</pause>
macauleyfddc4662015-07-27 17:40:30 +08001501 </current>
1502 <advertised>
1503 <rate>10Gb</rate>
1504 <rate>100Gb</rate>
1505 <medium>fiber</medium>
1506 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001507 </advertised>
macauleyfddc4662015-07-27 17:40:30 +08001508 <supported>
1509 <rate>10Gb</rate>
1510 <rate>100Gb</rate>
1511 <medium>fiber</medium>
1512 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001513 </supported>
macauleyfddc4662015-07-27 17:40:30 +08001514 <advertised-peer>
1515 <rate>10Gb</rate>
1516 <rate>100Gb</rate>
1517 <medium>fiber</medium>
1518 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001519 </advertised-peer>
macauleyfddc4662015-07-27 17:40:30 +08001520 </features>
1521 <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1522 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
1523 <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
1524 <ofdpa10:vni>VNID</ofdpa10:vni>
1525 </ofdpa10:vtap>
Pierbbdf3782016-08-22 17:58:26 -07001526 </port>
macauleyfddc4662015-07-27 17:40:30 +08001527 </resources>
1528 <logical-switches>
1529 <switch>
1530 <id>DATAPATH_ID</id>
1531 <datapath-id>DATAPATH_ID</datapath-id>
1532 <resources>
1533 <port xc:operation="OPERATION">LPORT</port>
1534 </resources>
1535 </switch>
1536 </logical-switches>
1537 </capable-switch>
1538 </config>
Pierbbdf3782016-08-22 17:58:26 -07001539 """
macauleyfddc4662015-07-27 17:40:30 +08001540 else:
1541 config_vtap_xml="""
1542 <config>
1543 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1544 <id>capable-switch-1</id>
1545 <resources>
1546 <port xc:operation="OPERATION">
Pierbbdf3782016-08-22 17:58:26 -07001547 <resource-id >LPORT</resource-id>
macauleyfddc4662015-07-27 17:40:30 +08001548 <features>
1549 <current>
1550 <rate>10Gb</rate>
1551 <medium>fiber</medium>
Pierbbdf3782016-08-22 17:58:26 -07001552 <pause>symmetric</pause>
macauleyfddc4662015-07-27 17:40:30 +08001553 </current>
1554 <advertised>
1555 <rate>10Gb</rate>
1556 <rate>100Gb</rate>
1557 <medium>fiber</medium>
1558 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001559 </advertised>
macauleyfddc4662015-07-27 17:40:30 +08001560 <supported>
1561 <rate>10Gb</rate>
1562 <rate>100Gb</rate>
1563 <medium>fiber</medium>
1564 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001565 </supported>
macauleyfddc4662015-07-27 17:40:30 +08001566 <advertised-peer>
1567 <rate>10Gb</rate>
1568 <rate>100Gb</rate>
1569 <medium>fiber</medium>
1570 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001571 </advertised-peer>
macauleyfddc4662015-07-27 17:40:30 +08001572 </features>
1573 <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1574 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
1575 <ofdpa10:vni>VNID</ofdpa10:vni>
1576 </ofdpa10:vtap>
Pierbbdf3782016-08-22 17:58:26 -07001577 </port>
macauleyfddc4662015-07-27 17:40:30 +08001578 </resources>
1579 <logical-switches>
1580 <switch>
1581 <id>DATAPATH_ID</id>
1582 <datapath-id>DATAPATH_ID</datapath-id>
1583 <resources>
1584 <port xc:operation="OPERATION">LPORT</port>
1585 </resources>
1586 </switch>
1587 </logical-switches>
1588 </capable-switch>
1589 </config>
Pierbbdf3782016-08-22 17:58:26 -07001590 """
1591 str_datapath_id_f= "{:016x}".format(dp_id)
1592 str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
1593 config_vtap_xml=config_vtap_xml.replace("DATAPATH_ID", str_datapath_id)
1594 config_vtap_xml=config_vtap_xml.replace("LPORT", str(int(lport)))
1595 config_vtap_xml=config_vtap_xml.replace("PHY_PORT", str(phy_port))
1596 config_vtap_xml=config_vtap_xml.replace("VLAN_ID", str(vlan))
macauleyfddc4662015-07-27 17:40:30 +08001597 config_vtap_xml=config_vtap_xml.replace("VNID", str(vnid))
1598 config_vtap_xml=config_vtap_xml.replace("OPERATION", str(operation))
1599 return config_vtap_xml
Pierbbdf3782016-08-22 17:58:26 -07001600
1601def 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 +08001602 """
1603 Command Example:
1604 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 -07001605 of-agent vtp 10001 vni 10
macauleyfddc4662015-07-27 17:40:30 +08001606 """
1607
1608 config_vtep_xml="""
1609 <config>
1610 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1611 <id>capable-switch-1</id>
1612 <resources>
1613 <port xc:operation="OPERATION">
Pierbbdf3782016-08-22 17:58:26 -07001614 <resource-id>LPORT</resource-id>
macauleyfddc4662015-07-27 17:40:30 +08001615 <features>
1616 <current>
1617 <rate>10Gb</rate>
1618 <medium>fiber</medium>
Pierbbdf3782016-08-22 17:58:26 -07001619 <pause>symmetric</pause>
macauleyfddc4662015-07-27 17:40:30 +08001620 </current>
1621 <advertised>
1622 <rate>10Gb</rate>
1623 <rate>100Gb</rate>
1624 <medium>fiber</medium>
1625 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001626 </advertised>
macauleyfddc4662015-07-27 17:40:30 +08001627 <supported>
1628 <rate>10Gb</rate>
1629 <rate>100Gb</rate>
1630 <medium>fiber</medium>
1631 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001632 </supported>
macauleyfddc4662015-07-27 17:40:30 +08001633 <advertised-peer>
1634 <rate>10Gb</rate>
1635 <rate>100Gb</rate>
1636 <medium>fiber</medium>
1637 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001638 </advertised-peer>
macauleyfddc4662015-07-27 17:40:30 +08001639 </features>
Pier265ad5f2017-02-28 17:46:28 +01001640 <ofdpa10:vtep xmlns:ofdpa10="urn:bcm:ofdpa10:accton01">
1641 <ofdpa10:src-ip>SRC_IP</ofdpa10:src-ip>
1642 <ofdpa10:dest-ip>DST_IP</ofdpa10:dest-ip>
1643 <ofdpa10:udp-src-port>UDP_SRC_PORT</ofdpa10:udp-src-port>
1644 <ofdpa10:vni xc:operation="OPERATION">
macauley25999cf2015-08-07 17:03:24 +08001645 <ofdpa10:id>VNID</ofdpa10:id>
1646 </ofdpa10:vni>
Pier265ad5f2017-02-28 17:46:28 +01001647 <ofdpa10:nexthop-id>NEXT_HOP_ID</ofdpa10:nexthop-id>
1648 <ofdpa10:ttl>TTL</ofdpa10:ttl>
1649 </ofdpa10:vtep>
Pierbbdf3782016-08-22 17:58:26 -07001650 </port>
macauleyfddc4662015-07-27 17:40:30 +08001651 </resources>
1652 <logical-switches>
1653 <switch>
1654 <id>DATAPATH_ID</id>
1655 <datapath-id>DATAPATH_ID</datapath-id>
1656 <resources>
1657 <port xc:operation="OPERATION">LPORT</port>
1658 </resources>
1659 </switch>
1660 </logical-switches>
1661 </capable-switch>
Pierbbdf3782016-08-22 17:58:26 -07001662 </config>
macauleyfddc4662015-07-27 17:40:30 +08001663 """
Pierbbdf3782016-08-22 17:58:26 -07001664 str_datapath_id_f= "{:016x}".format(dp_id)
1665 str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
1666 config_vtep_xml=config_vtep_xml.replace("DATAPATH_ID", str_datapath_id)
macauley25999cf2015-08-07 17:03:24 +08001667 config_vtep_xml=config_vtep_xml.replace("LPORT", str(int(lport)))
Pierbbdf3782016-08-22 17:58:26 -07001668 config_vtep_xml=config_vtep_xml.replace("SRC_IP", str(src_ip))
1669 config_vtep_xml=config_vtep_xml.replace("DST_IP", str(dst_ip))
1670 config_vtep_xml=config_vtep_xml.replace("UDP_SRC_PORT", str(udp_src_port))
1671 config_vtep_xml=config_vtep_xml.replace("NEXT_HOP_ID", str(next_hop_id))
1672 config_vtep_xml=config_vtep_xml.replace("TTL", str(ttl))
macauleyfddc4662015-07-27 17:40:30 +08001673 config_vtep_xml=config_vtep_xml.replace("VNID", str(vnid))
Pierbbdf3782016-08-22 17:58:26 -07001674 config_vtep_xml=config_vtep_xml.replace("OPERATION", str(operation))
macauleyfddc4662015-07-27 17:40:30 +08001675
Pierbbdf3782016-08-22 17:58:26 -07001676 return config_vtep_xml
1677
1678def get_next_hop_config_xml(next_hop_id, dst_mac, phy_port, vlan, operation='merge'):
macauleyfddc4662015-07-27 17:40:30 +08001679 #of-agent nexthop 2 destination user-input-dst-mac ethernet 1/2 vid 2
1680 config_nexthop_xml="""
1681 <config>
1682 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1683 <ofdpa10:next-hop xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1684 <ofdpa10:id>NEXT_HOP_ID</ofdpa10:id>
1685 <ofdpa10:dest-mac>DST_MAC</ofdpa10:dest-mac>
1686 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
1687 <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
1688 </ofdpa10:next-hop>
1689 </of11-config:capable-switch>
1690 </config>
1691 """
1692 config_nexthop_xml=config_nexthop_xml.replace("VLAN_ID", str(vlan))
Pierbbdf3782016-08-22 17:58:26 -07001693 config_nexthop_xml=config_nexthop_xml.replace("PHY_PORT", str(phy_port))
1694 config_nexthop_xml=config_nexthop_xml.replace("NEXT_HOP_ID", str(next_hop_id))
1695 config_nexthop_xml=config_nexthop_xml.replace("DST_MAC", str(dst_mac))
1696 config_nexthop_xml=config_nexthop_xml.replace("OPERATION", str(operation))
1697 return config_nexthop_xml
macauleyfddc4662015-07-27 17:40:30 +08001698
Pierbbdf3782016-08-22 17:58:26 -07001699def get_vni_config_xml(vni_id, mcast_ipv4, next_hop_id, operation='merge'):
macauleyfddc4662015-07-27 17:40:30 +08001700 #of-agent vni 10 multicast 224.1.1.1 nexthop 20
Pierbbdf3782016-08-22 17:58:26 -07001701 if mcast_ipv4!=None:
macauleyfddc4662015-07-27 17:40:30 +08001702 config_vni_xml="""
1703 <config>
1704 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1705 <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1706 <ofdpa10:id>VNID</ofdpa10:id>
1707 <ofdpa10:vni-multicast-group>MCAST_IP</ofdpa10:vni-multicast-group>
1708 <ofdpa10:multicast-group-nexthop-id>NEXT_HOP_ID</ofdpa10:multicast-group-nexthop-id>
1709 </ofdpa10:vni>
1710 </of11-config:capable-switch>
1711 </config>
Pierbbdf3782016-08-22 17:58:26 -07001712 """
1713 config_vni_xml=config_vni_xml.replace("NEXT_HOP_ID", str(next_hop_id))
1714 config_vni_xml=config_vni_xml.replace("MCAST_IP", str(mcast_ipv4))
macauleyfddc4662015-07-27 17:40:30 +08001715 else:
1716 config_vni_xml="""
1717 <config>
1718 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1719 <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1720 <ofdpa10:id>VNID</ofdpa10:id>
1721 </ofdpa10:vni>
1722 </of11-config:capable-switch>
1723 </config>
Pierbbdf3782016-08-22 17:58:26 -07001724 """
1725
1726 config_vni_xml=config_vni_xml.replace("VNID", str(vni_id))
1727 config_vni_xml=config_vni_xml.replace("OPERATION", str(operation))
macauleyfddc4662015-07-27 17:40:30 +08001728 return config_vni_xml
Pierbbdf3782016-08-22 17:58:26 -07001729
1730def get_featureReplay(self):
macauleyfddc4662015-07-27 17:40:30 +08001731 req = ofp.message.features_request()
1732 res, raw = self.controller.transact(req)
Pierbbdf3782016-08-22 17:58:26 -07001733 self.assertIsNotNone(res, "Did not receive a response from the DUT.")
macauleyfddc4662015-07-27 17:40:30 +08001734 self.assertEqual(res.type, ofp.OFPT_FEATURES_REPLY,
1735 ("Unexpected packet type %d received in response to "
1736 "OFPT_FEATURES_REQUEST") % res.type)
Pierbbdf3782016-08-22 17:58:26 -07001737 return res
1738
macauleyfddc4662015-07-27 17:40:30 +08001739def send_edit_config(switch_ip, xml, target='runing'):
1740 NETCONF_ACCOUNT="netconfuser"
1741 NETCONF_PASSWD="netconfuser"
1742 with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
1743 try:
Pierbbdf3782016-08-22 17:58:26 -07001744 m.edit_config(target='running',
1745 config=xml,
1746 default_operation='merge',
macauleyfddc4662015-07-27 17:40:30 +08001747 error_option='stop-on-error')
1748
1749 except Exception as e:
1750 logging.info("Fail to set xml %s", xml)
1751 return False
1752
Pier265ad5f2017-02-28 17:46:28 +01001753 #return m.get_config(source='running').data_xml
macauleyfddc4662015-07-27 17:40:30 +08001754 return True
1755
1756def send_delete_config(switch_ip, xml, target='runing'):
1757 NETCONF_ACCOUNT="netconfuser"
1758 NETCONF_PASSWD="netconfuser"
1759 with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
1760 try:
Pierbbdf3782016-08-22 17:58:26 -07001761 m.edit_config(target='running',
1762 config=xml,
1763 default_operation='delete',
macauleyfddc4662015-07-27 17:40:30 +08001764 error_option='stop-on-error')
1765
1766 except Exception as e:
1767 logging.info("Fail to set xml %s", xml)
1768 return False
1769
Pier265ad5f2017-02-28 17:46:28 +01001770 #return m.get_config(source='running').data_xml
macauleyfddc4662015-07-27 17:40:30 +08001771 return True
Pierbbdf3782016-08-22 17:58:26 -07001772
macauleyfddc4662015-07-27 17:40:30 +08001773def get_edit_config(switch_ip, target='runing'):
1774 NETCONF_ACCOUNT="netconfuser"
1775 NETCONF_PASSWD="netconfuser"
1776 with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
Pier265ad5f2017-02-28 17:46:28 +01001777 return m.get_config(source='running').data_xml
macauleydbff3272015-07-30 14:07:16 +08001778
macauley_cheng67da9262015-08-31 15:18:41 +08001779
1780"""
1781MPLS
1782"""
1783
1784OFDPA_MPLS_SUBTYPE_SHIFT=24
Pierbbdf3782016-08-22 17:58:26 -07001785OFDPA_MPLS_GROUP_SUBTYPE_L2_VPN_LABEL=1
macauley_cheng67da9262015-08-31 15:18:41 +08001786OFDPA_MPLS_GROUP_SUBTYPE_L3_VPN_LABEL=2
1787OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL1=3
1788OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL2=4
1789OFDPA_MPLS_GROUP_SUBTYPE_SWAP_LABEL=5
1790OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP=6
1791OFDPA_MPLS_GROUP_SUBTYPE_ECMP=8
1792OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG=10
1793
Piercf76e802016-09-19 20:16:35 -07001794
1795
1796
macauley_cheng67da9262015-08-31 15:18:41 +08001797def encode_mpls_interface_group_id(subtype, index):
1798 index=index&0x00ffffff
1799 assert(subtype==0)
1800 return index + (9 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
1801
1802def encode_mpls_label_group_id(subtype, index):
1803 index=index&0x00ffffff
1804 assert(subtype <=5 or subtype==0)
1805 #1: l2 vpn label
1806 #2: l3 vpn label
1807 #3: mpls tunnel label 1
1808 #4: mpls tunnel lable 2
1809 #5: mpls swap label
Pierbbdf3782016-08-22 17:58:26 -07001810 return index + (9 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
macauley_cheng67da9262015-08-31 15:18:41 +08001811
1812def encode_mpls_forwarding_group_id(subtype, index):
1813 index=index&0x00ffffff
1814 assert(subtype==6 or subtype==8 or subtype==10)
Pierbbdf3782016-08-22 17:58:26 -07001815 return index + (10 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
macauley_cheng67da9262015-08-31 15:18:41 +08001816
1817
Pier1e4e98e2016-10-26 14:36:05 -07001818def add_mpls_intf_group(ctrl, ref_gid, dst_mac, src_mac, vid, index, subtype=0, send_barrier=False):
macauley_cheng67da9262015-08-31 15:18:41 +08001819 action=[]
1820 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
1821 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
Pier265ad5f2017-02-28 17:46:28 +01001822 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vid)))
macauley_cheng67da9262015-08-31 15:18:41 +08001823 action.append(ofp.action.group(ref_gid))
Pierbbdf3782016-08-22 17:58:26 -07001824
macauley_cheng67da9262015-08-31 15:18:41 +08001825 buckets = [ofp.bucket(actions=action)]
1826
1827 mpls_group_id =encode_mpls_interface_group_id(subtype, index)
1828 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
1829 group_id=mpls_group_id,
1830 buckets=buckets
1831 )
Andreas Pantelopoulos6c76b942018-01-22 10:03:02 -08001832
1833 logging.debug("Adding MPLS interface group %02x, src_mac %s , dst_mac %s , vid %d", mpls_group_id, src_mac, dst_mac, vid)
macauley_cheng67da9262015-08-31 15:18:41 +08001834 ctrl.message_send(request)
Pier1e4e98e2016-10-26 14:36:05 -07001835
1836 if send_barrier:
1837 do_barrier(ctrl)
macauley_cheng67da9262015-08-31 15:18:41 +08001838 return mpls_group_id, request
1839
Piercf76e802016-09-19 20:16:35 -07001840def add_mpls_tunnel_label_group(
1841 ctrl,
1842 ref_gid,
1843 subtype,
1844 index,
1845 label,
1846 ):
1847
1848 action=[]
1849 action.append(ofp.action.push_mpls(0x8847))
1850 action.append(ofp.action.set_field(ofp.oxm.mpls_label(label)))
1851 action.append(ofp.action.group(ref_gid))
1852 buckets = [ofp.bucket(actions=action)]
1853
1854 mpls_group_id = encode_mpls_label_group_id(subtype, index)
1855 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
1856 group_id=mpls_group_id,
1857 buckets=buckets
1858 )
1859 ctrl.message_send(request)
1860
1861 return mpls_group_id, request
1862
Pierb5da4c92016-09-21 11:23:35 -07001863def add_mpls_swap_label_group(
1864 ctrl,
1865 ref_gid,
1866 subtype,
1867 index,
1868 label,
1869 ):
1870
1871 action=[]
1872 action.append(ofp.action.set_field(ofp.oxm.mpls_label(label)))
1873 action.append(ofp.action.group(ref_gid))
1874 buckets = [ofp.bucket(actions=action)]
1875
1876 mpls_group_id = encode_mpls_label_group_id(subtype, index)
1877 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
1878 group_id=mpls_group_id,
1879 buckets=buckets
1880 )
Andreas Pantelopoulos6c76b942018-01-22 10:03:02 -08001881 logging.debug("Adding MPLS Swap group %02x, label %d", mpls_group_id, label)
Pierb5da4c92016-09-21 11:23:35 -07001882 ctrl.message_send(request)
1883
1884 return mpls_group_id, request
1885
Pierbbdf3782016-08-22 17:58:26 -07001886def add_mpls_label_group(ctrl, subtype, index, ref_gid,
macauley_cheng67da9262015-08-31 15:18:41 +08001887 lmep_id=-1,
1888 qos_index=-1,
1889 push_l2_header=False,
1890 push_vlan=False,
1891 push_mpls_header=False,
1892 push_cw=False,
1893 set_mpls_label=None,
1894 set_bos=None,
1895 set_tc=None,
1896 set_tc_from_table=False,
1897 cpy_tc_outward=False,
1898 set_ttl=None,
1899 cpy_ttl_outward=False,
1900 oam_lm_tx_count=False,
Pier1e4e98e2016-10-26 14:36:05 -07001901 set_pri_from_table=False,
1902 send_barrier=False
macauley_cheng67da9262015-08-31 15:18:41 +08001903 ):
1904 """
1905 @ref_gid: only can be mpls intf group or mpls tunnel label 1/2 group
Pierbbdf3782016-08-22 17:58:26 -07001906 """
macauley_cheng67da9262015-08-31 15:18:41 +08001907 action=[]
1908
1909 if push_vlan== True:
1910 action.append(ofp.action.push_vlan(0x8100))
1911 if push_mpls_header== True:
1912 action.append(ofp.action.push_mpls(0x8847))
1913 if set_mpls_label != None:
1914 action.append(ofp.action.set_field(ofp.oxm.mpls_label(set_mpls_label)))
1915 if set_bos != None:
1916 action.append(ofp.action.set_field(ofp.oxm.mpls_bos(set_bos)))
1917 if set_tc != None:
1918 assert(set_tc_from_table==False)
1919 action.append(ofp.action.set_field(ofp.oxm.mpls_tc(set_tc)))
1920 if set_ttl != None:
Pierbbdf3782016-08-22 17:58:26 -07001921 action.append(ofp.action.set_mpls_ttl(set_ttl))
macauley_cheng67da9262015-08-31 15:18:41 +08001922 if cpy_ttl_outward == True:
Pierbbdf3782016-08-22 17:58:26 -07001923 action.append(ofp.action.copy_ttl_out())
macauley_cheng67da9262015-08-31 15:18:41 +08001924 """
1925 ofdpa experimenter
Pierbbdf3782016-08-22 17:58:26 -07001926 """
macauley_cheng67da9262015-08-31 15:18:41 +08001927 if push_l2_header== True:
Pierbbdf3782016-08-22 17:58:26 -07001928 action.append(ofp.action.ofdpa_push_l2_header())
macauley_cheng67da9262015-08-31 15:18:41 +08001929 if set_tc_from_table== True:
1930 assert(qos_index>=0)
1931 assert(set_tc == None)
Pierbbdf3782016-08-22 17:58:26 -07001932 action.append(ofp.action.ofdpa_set_tc_from_table(qos_index))
macauley_cheng67da9262015-08-31 15:18:41 +08001933 if cpy_tc_outward == True:
Pierbbdf3782016-08-22 17:58:26 -07001934 action.append(ofp.action.ofdpa_copy_tc_out())
macauley_cheng67da9262015-08-31 15:18:41 +08001935 if oam_lm_tx_count == True:
Pierbbdf3782016-08-22 17:58:26 -07001936 assert(qos_index>=0 and lmep_id>=0)
1937 action.append(ofp.action.ofdpa_oam_lm_tx_count(lmep_id, qos_index))
macauley_cheng67da9262015-08-31 15:18:41 +08001938 if set_pri_from_table == True:
Pierbbdf3782016-08-22 17:58:26 -07001939 assert(qos_index>=0)
1940 action.append(ofp.action.ofdpa_set_qos_from_table(qos_index))
macauley_cheng67da9262015-08-31 15:18:41 +08001941 if push_cw == True:
1942 action.append(ofp.action.ofdpa_push_cw())
Pierbbdf3782016-08-22 17:58:26 -07001943
1944 action.append(ofp.action.group(ref_gid))
macauley_cheng67da9262015-08-31 15:18:41 +08001945 buckets = [ofp.bucket(actions=action)]
Pierbbdf3782016-08-22 17:58:26 -07001946
macauley_cheng67da9262015-08-31 15:18:41 +08001947 mpls_group_id = encode_mpls_label_group_id(subtype, index)
1948 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
1949 group_id=mpls_group_id,
1950 buckets=buckets
1951 )
1952 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -07001953
Pier1e4e98e2016-10-26 14:36:05 -07001954 if send_barrier:
1955 do_barrier(ctrl)
1956
Pierbbdf3782016-08-22 17:58:26 -07001957 return mpls_group_id, request
1958
Piercf76e802016-09-19 20:16:35 -07001959def add_mpls_l2_port_flow(ctrl, of_port, mpls_l2_port, tunnel_index, ref_gid, qos_index=0):
1960 """
1961 Only action is Group, which must indicate one of:
1962 MPLS L2 VPN Label or Fast Failover Protection Group.
1963 ref_gid contains this information
1964 """
1965 tunnel_id = tunnel_index + ofp.oxm.TUNNEL_ID_BASE
1966
1967 match = ofp.match()
1968 match.oxm_list.append(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port))
1969 match.oxm_list.append(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE))
1970
Pier23784aa2016-09-19 20:08:21 -07001971
Pier265ad5f2017-02-28 17:46:28 +01001972 write_actions = []
1973 write_actions.append(ofp.action.group(ref_gid))
1974 apply_actions = []
Piercf76e802016-09-19 20:16:35 -07001975 assert(qos_index>=0)
Pier265ad5f2017-02-28 17:46:28 +01001976 apply_actions.append(ofp.action.set_field(ofp.oxm.exp1ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_QOS_INDEX, value=qos_index)))
Piercf76e802016-09-19 20:16:35 -07001977
1978 request = ofp.message.flow_add(
1979 table_id=MPLS_L2_PORT_FLOW_TABLE,
1980 cookie=42,
1981 match=match,
1982 instructions=[
Pier265ad5f2017-02-28 17:46:28 +01001983 ofp.instruction.apply_actions(actions=apply_actions),
1984 ofp.instruction.write_actions(actions=write_actions),
1985 ofp.instruction.goto_table(MPLS_L2_PORT_PCP_TRUST_FLOW_TABLE)
1986 ],
Piercf76e802016-09-19 20:16:35 -07001987 buffer_id=ofp.OFP_NO_BUFFER,
1988 priority=1)
1989 logging.info("Inserting flow %d mpls_l2_port, %d tunnel_id, action %x group and go to table %d", mpls_l2_port, tunnel_id, ref_gid, MPLS_L2_PORT_DSCP_TRUST_FLOW_TABLE)
1990 ctrl.message_send(request)
1991 return request
1992
1993 return
1994
Pierbbdf3782016-08-22 17:58:26 -07001995def add_mpls_forwarding_group(ctrl, subtype, index, ref_gids,
1996 watch_port=None,
Pier265ad5f2017-02-28 17:46:28 +01001997 watch_group=ofp.OFPP_ANY,
1998 push_vlan=None,
macauley_chengd17ce512015-08-31 17:45:51 +08001999 pop_vlan=None,
macauley_cheng67da9262015-08-31 15:18:41 +08002000 set_vid=None):
2001 assert(subtype == OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP
Pier265ad5f2017-02-28 17:46:28 +01002002 or subtype == OFDPA_MPLS_GROUP_SUBTYPE_ECMP
2003 or subtype == OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG)
macauley_chengd17ce512015-08-31 17:45:51 +08002004
macauley_cheng67da9262015-08-31 15:18:41 +08002005 buckets=[]
2006 if subtype == OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP:
macauley_chengd17ce512015-08-31 17:45:51 +08002007 group_type = ofp.OFPGT_FF
macauley_cheng67da9262015-08-31 15:18:41 +08002008 for gid in ref_gids:
macauley_chengd17ce512015-08-31 17:45:51 +08002009 action=[]
Pierbbdf3782016-08-22 17:58:26 -07002010 action.append(ofp.action.group(gid))
macauley_chengd17ce512015-08-31 17:45:51 +08002011 buckets.append(ofp.bucket(watch_port=watch_port, watch_group=watch_group,actions=action))
2012
macauley_cheng67da9262015-08-31 15:18:41 +08002013 elif subtype == OFDPA_MPLS_GROUP_SUBTYPE_ECMP:
2014 group_type = ofp.OFPGT_SELECT
2015 for gid in ref_gids:
macauley_chengd17ce512015-08-31 17:45:51 +08002016 action=[]
Pierbbdf3782016-08-22 17:58:26 -07002017 action.append(ofp.action.group(gid))
macauley_cheng67da9262015-08-31 15:18:41 +08002018 buckets.append(ofp.bucket(actions=action))
macauley_chengd17ce512015-08-31 17:45:51 +08002019
macauley_cheng67da9262015-08-31 15:18:41 +08002020 elif subtype == OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG:
2021 group_type = ofp.OFPGT_INDIRECT
macauley_chengd17ce512015-08-31 17:45:51 +08002022 action=[]
macauley_cheng67da9262015-08-31 15:18:41 +08002023 if set_vid!=None:
Flavio Castro91d1a552016-05-17 16:59:44 -07002024 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+set_vid)))
macauley_cheng67da9262015-08-31 15:18:41 +08002025 if push_vlan!=None:
Pierbbdf3782016-08-22 17:58:26 -07002026 action.append(ofp.action.push_vlan(push_vlan))
macauley_cheng67da9262015-08-31 15:18:41 +08002027 if pop_vlan!=None:
Pierbbdf3782016-08-22 17:58:26 -07002028 action.append(ofp.action.pop_vlan())
2029 action.append(ofp.action.group(ref_gids[0]))
macauley_cheng67da9262015-08-31 15:18:41 +08002030 buckets.append(ofp.bucket(actions=action))
macauley_chengd17ce512015-08-31 17:45:51 +08002031
2032 mpls_group_id = encode_mpls_forwarding_group_id(subtype, index)
macauley_cheng67da9262015-08-31 15:18:41 +08002033 request = ofp.message.group_add(group_type=group_type,
macauley_cheng67da9262015-08-31 15:18:41 +08002034 group_id=mpls_group_id,
2035 buckets=buckets
2036 )
2037 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -07002038 return mpls_group_id, request
macauley_chengd17ce512015-08-31 17:45:51 +08002039
2040
macauley_cheng67da9262015-08-31 15:18:41 +08002041"""
Piercf76e802016-09-19 20:16:35 -07002042display
Pierbbdf3782016-08-22 17:58:26 -07002043"""
macauleydbff3272015-07-30 14:07:16 +08002044def print_current_table_flow_stat(ctrl, table_id=0xff):
2045 stat_req=ofp.message.flow_stats_request()
2046 response, pkt = ctrl.transact(stat_req)
2047 if response == None:
2048 print "no response"
2049 return None
2050 print len(response.entries)
2051 for obj in response.entries:
2052 print "match ", obj.match
2053 print "cookie", obj.cookie
2054 print "priority", obj.priority
2055 print "idle_timeout", obj.idle_timeout
2056 print "hard_timeout", obj.hard_timeout
2057 #obj.actions
Flavio Castro167f5bd2015-12-02 19:33:53 -05002058 print "packet count: %lx"%obj.packet_count