blob: 5cdfad3a4bf5d811fc344ea6606885a46c78b226 [file] [log] [blame]
Matteo Scandoloa229eca2017-08-08 13:05:28 -07001# Copyright 2017-present Open Networking Foundation
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15
macauley97557232015-07-16 17:28:07 +080016import logging
17
18from oftest import config
19import oftest.base_tests as base_tests
20import ofp
21import time
22from oftest.testutils import *
Pier1e4e98e2016-10-26 14:36:05 -070023from oftest.parse import parse_ipv6
macauley97557232015-07-16 17:28:07 +080024
macauleyfddc4662015-07-27 17:40:30 +080025from ncclient import manager
26import ncclient
27
macauley97557232015-07-16 17:28:07 +080028OFDPA_GROUP_TYPE_SHIFT=28
29OFDPA_VLAN_ID_SHIFT =16
macauleyfddc4662015-07-27 17:40:30 +080030OFDPA_TUNNEL_ID_SHIFT =12
31OFDPA_TUNNEL_SUBTYPE_SHIFT=10
macauley97557232015-07-16 17:28:07 +080032
33#VLAN_TABLE_FLAGS
34VLAN_TABLE_FLAG_ONLY_UNTAG=1
35VLAN_TABLE_FLAG_ONLY_TAG =2
36VLAN_TABLE_FLAG_ONLY_BOTH =3
Piere1308762016-09-12 15:29:56 -070037VLAN_TABLE_FLAG_ONLY_STACKED=5
38VLAN_TABLE_FLAG_PRIORITY=6
39VLAN_TABLE_FLAG_ONLY_UNTAG_PRIORITY=7
Andreas Pantelopoulosf83e0212018-03-18 20:44:05 -070040VLAN_TABLE_FLAG_ONLY_POP_VLAN=8
macauley97557232015-07-16 17:28:07 +080041
macauleye8b140e2015-08-03 13:35:45 +080042PORT_FLOW_TABLE=0
43VLAN_FLOW_TABLE=10
Piere1308762016-09-12 15:29:56 -070044VLAN_1_FLOW_TABLE=11
Piercf76e802016-09-19 20:16:35 -070045MPLS_L2_PORT_FLOW_TABLE=13
46MPLS_L2_PORT_DSCP_TRUST_FLOW_TABLE=15
47MPLS_L2_PORT_PCP_TRUST_FLOW_TABLE=16
macauleye8b140e2015-08-03 13:35:45 +080048TERMINATION_FLOW_TABLE=20
Piercf76e802016-09-19 20:16:35 -070049MPLS_TYPE_FLOW_TABLE=29
macauleye8b140e2015-08-03 13:35:45 +080050UCAST_ROUTING_FLOW_TABLE=30
51MCAST_ROUTING_FLOW_TABLE=40
52BRIDGE_FLOW_TABLE=50
53ACL_FLOW_TABLE=60
Jonghwan Hyunff0dfd52018-03-20 15:04:35 -070054EGRESS_TPID_FLOW_TABLE = 235
55
56ONF_EXPERIMENTER_ID = 0x4F4E4600
macauleye8b140e2015-08-03 13:35:45 +080057
Andreas Pantelopoulosf83e0212018-03-18 20:44:05 -070058EGRESS_VLAN_FLOW_TABLE=210
59EGRESS_VLAN_1_FLOW_TABLE=211
60EGRESS_MAINTENANCE_POINT_FLOW_TABLE=226
61EGRESS_DSCP_TABLE=230
62EGRESS_TPID_TABLE=235
63EGRESS_SOURCE_MAC_LEARNING_TABLE=254
64
macauleye8b140e2015-08-03 13:35:45 +080065def convertIP4toStr(ip_addr):
66 a=(ip_addr&0xff000000)>>24
67 b=(ip_addr&0x00ff0000)>>16
68 c=(ip_addr&0x0000ff00)>>8
69 d=(ip_addr&0x000000ff)
70 return str(a)+"."+str(b)+"."+str(c)+"."+str(d)
71
72def convertMACtoStr(mac):
73 if not isinstance(mac, list):
74 assert(0)
75
76 return ':'.join(['%02X' % x for x in mac])
77
macauley7f89d962015-08-06 18:13:48 +080078def getSwitchCpuMACFromDPID(dpid):
79 str_datapath_id_f= "{:016x}".format(dpid)
80 str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
81 switch_cpu_mac_str=str_datapath_id[6:]
82 switch_cpu_mac = switch_cpu_mac_str.split(":")
83 switch_cpu_mac=[int(switch_cpu_mac[i],16) for i in range(0, len(switch_cpu_mac))]
84
85 return switch_cpu_mac_str, switch_cpu_mac
Pierbbdf3782016-08-22 17:58:26 -070086
macauley_cheng67da9262015-08-31 15:18:41 +080087def DumpGroup(stats, verify_group_stats, always_show=True):
88 if(len(stats) > len(verify_group_stats)):
89 min_len = len(verify_group_stats)
90 print "Stats Len is not the same, stats>verify_group_stats"
91 if(len(stats)< len(verify_group_stats)):
Pierbbdf3782016-08-22 17:58:26 -070092 min_len = len(stats)
macauley_cheng67da9262015-08-31 15:18:41 +080093 print "Stats Len is not the same, stats<verify_group_stats"
Pierbbdf3782016-08-22 17:58:26 -070094 else:
macauley_cheng67da9262015-08-31 15:18:41 +080095 min_len = len(stats)
macauleye8b140e2015-08-03 13:35:45 +080096
macauley_cheng67da9262015-08-31 15:18:41 +080097 print "\r\n"
98 for i in range(min_len):
99 gs = stats[i]
Pierbbdf3782016-08-22 17:58:26 -0700100 gv = verify_group_stats[i]
macauley_cheng67da9262015-08-31 15:18:41 +0800101 print "FromSwtich:(GID=%lx, TYPE=%lx)\r\nVerify :(GID=%lx, TYPE=%lx)"%(gs.group_id, gs.group_type, gv.group_id, gv.group_type)
102 if(len(gs.buckets) != len(gv.buckets)):
103 print "buckets len is not the same gs %lx, gv %lx",(len(gs.buckets), len(gv.buckets))
104
105 for j in range(len(gs.buckets)):
106 b1=gs.buckets[j]
Pierbbdf3782016-08-22 17:58:26 -0700107 b2=gv.buckets[j]
macauley_cheng67da9262015-08-31 15:18:41 +0800108 if(len(b1.actions) != len(b2.actions)):
109 print "action len is not the same"
110
111 for k in range(len(b1.actions)):
112 a1=b1.actions[k]
113 a2=b2.actions[k]
114 if(always_show == True):
115 print "a1:"+a1.show()
Pierbbdf3782016-08-22 17:58:26 -0700116 print "a2:"+a2.show()
macauley_cheng67da9262015-08-31 15:18:41 +0800117
118def AssertGroup(self, stats, verify_group_stats):
119 self.assertTrue(len(stats) ==len(verify_group_stats), "stats len is not the same")
120
121 for i in range(len(stats)):
122 gs = stats[i]
Pierbbdf3782016-08-22 17:58:26 -0700123 gv = verify_group_stats[i]
macauley_cheng67da9262015-08-31 15:18:41 +0800124 self.assertTrue(len(gs.buckets) == len(gv.buckets), "buckets len is not the same")
125
126 for j in range(len(gs.buckets)):
127 b1=gs.buckets[j]
Pierbbdf3782016-08-22 17:58:26 -0700128 b2=gv.buckets[j]
macauley_cheng67da9262015-08-31 15:18:41 +0800129 self.assertTrue(len(b1.actions) == len(b2.actions), "action len is not the same")
130
131 for k in range(len(b1.actions)):
132 a1=b1.actions[k]
133 a2=b2.actions[k]
134 self.assertEquals(a1, a2, "action is not the same")
Pierbbdf3782016-08-22 17:58:26 -0700135
macauley97557232015-07-16 17:28:07 +0800136def encode_l2_interface_group_id(vlan, id):
137 return id + (vlan << OFDPA_VLAN_ID_SHIFT)
138
139def encode_l2_rewrite_group_id(id):
140 return id + (1 << OFDPA_GROUP_TYPE_SHIFT)
141
142def encode_l3_unicast_group_id(id):
143 return id + (2 << OFDPA_GROUP_TYPE_SHIFT)
144
145def encode_l2_mcast_group_id(vlan, id):
146 return id + (vlan << OFDPA_VLAN_ID_SHIFT) + (3 << OFDPA_GROUP_TYPE_SHIFT)
147
148def encode_l2_flood_group_id(vlan, id):
149 return id + (vlan << OFDPA_VLAN_ID_SHIFT) + (4 << OFDPA_GROUP_TYPE_SHIFT)
Pierbbdf3782016-08-22 17:58:26 -0700150
macauley97557232015-07-16 17:28:07 +0800151def encode_l3_interface_group_id(id):
152 return id + (5 << OFDPA_GROUP_TYPE_SHIFT)
153
154def encode_l3_mcast_group_id(vlan, id):
155 return id + (vlan << OFDPA_VLAN_ID_SHIFT)+(6 << OFDPA_GROUP_TYPE_SHIFT)
156
157def encode_l3_ecmp_group_id(id):
158 return id + (7 << OFDPA_GROUP_TYPE_SHIFT)
159
Flavio Castro91d1a552016-05-17 16:59:44 -0700160def encode_l2_unfiltered_group_id(id):
161 return id + (11 << OFDPA_GROUP_TYPE_SHIFT)
162
macauleyfddc4662015-07-27 17:40:30 +0800163def encode_l2_overlay_group_id(tunnel_id, subtype, index):
164 tunnel_id=tunnel_id&0xffff #16 bits
165 subtype = subtype&3 #2 bits
166 index = index & 0x3f #10 bits
167 return index + (tunnel_id << OFDPA_TUNNEL_ID_SHIFT)+ (subtype<<OFDPA_TUNNEL_SUBTYPE_SHIFT)+(8 << OFDPA_GROUP_TYPE_SHIFT)
macauley97557232015-07-16 17:28:07 +0800168
Flavio Castro91d1a552016-05-17 16:59:44 -0700169def add_l2_unfiltered_group(ctrl, ports, send_barrier=False):
170 # group table
171 # set up untag groups for each port
172 group_id_list=[]
173 msgs=[]
174 for of_port in ports:
175 # do stuff
176 group_id = encode_l2_unfiltered_group_id(of_port)
177 group_id_list.append(group_id)
178 actions = [ofp.action.output(of_port)]
179 actions.append(ofp.action.set_field(ofp.oxm.exp1ByteValue(exp_type=24, value=1)))
180
181 buckets = [ofp.bucket(actions=actions)]
182 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
183 group_id=group_id,
184 buckets=buckets
185 )
186 ctrl.message_send(request)
187 msgs.append(request)
188
189 if send_barrier:
190 do_barrier(ctrl)
191
192 return group_id_list, msgs
193
Pierf6f28162016-09-22 16:30:52 -0700194def add_one_l2_unfiltered_group(ctrl, of_port, send_barrier=False):
195 # group table
196 # set up untag groups for each port
197 group_id = encode_l2_unfiltered_group_id(of_port)
198 actions = [ofp.action.output(of_port)]
199 actions.append(ofp.action.set_field(ofp.oxm.exp1ByteValue(exp_type=24, value=1)))
200
201 buckets = [ofp.bucket(actions=actions)]
202 request = ofp.message.group_add(
203 group_type=ofp.OFPGT_INDIRECT,
204 group_id=group_id,
205 buckets=buckets
206 )
207 ctrl.message_send(request)
208
209 if send_barrier:
210 do_barrier(ctrl)
211
212 return group_id, request
213
Flavio Castrod4c44d12015-12-08 14:44:18 -0500214def add_l2_interface_group(ctrl, ports, vlan_id=1, is_tagged=False, send_barrier=False):
macauley97557232015-07-16 17:28:07 +0800215 # group table
216 # set up untag groups for each port
macauley41904ed2015-07-16 17:38:35 +0800217 group_id_list=[]
macauley15909e72015-07-17 15:58:57 +0800218 msgs=[]
macauley97557232015-07-16 17:28:07 +0800219 for of_port in ports:
220 # do stuff
221 group_id = encode_l2_interface_group_id(vlan_id, of_port)
macauley41904ed2015-07-16 17:38:35 +0800222 group_id_list.append(group_id)
macauley97557232015-07-16 17:28:07 +0800223 if is_tagged:
224 actions = [
225 ofp.action.output(of_port),
Pierbbdf3782016-08-22 17:58:26 -0700226 ]
macauley97557232015-07-16 17:28:07 +0800227 else:
228 actions = [
229 ofp.action.pop_vlan(),
230 ofp.action.output(of_port),
231 ]
232
233 buckets = [
234 ofp.bucket(actions=actions),
235 ]
236
237 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
238 group_id=group_id,
239 buckets=buckets
240 )
241 ctrl.message_send(request)
macauley15909e72015-07-17 15:58:57 +0800242 msgs.append(request)
macauley97557232015-07-16 17:28:07 +0800243
244 if send_barrier:
245 do_barrier(ctrl)
Pierbbdf3782016-08-22 17:58:26 -0700246
macauley15909e72015-07-17 15:58:57 +0800247 return group_id_list, msgs
macauley97557232015-07-16 17:28:07 +0800248
Flavio Castrod4c44d12015-12-08 14:44:18 -0500249def add_one_l2_interface_group(ctrl, port, vlan_id=1, is_tagged=False, send_barrier=False):
macauley0f91a3e2015-07-17 18:09:59 +0800250 # group table
251 # set up untag groups for each port
252 group_id = encode_l2_interface_group_id(vlan_id, port)
253
254 if is_tagged:
255 actions = [
256 ofp.action.output(port),
Pierbbdf3782016-08-22 17:58:26 -0700257 ]
macauley0f91a3e2015-07-17 18:09:59 +0800258 else:
259 actions = [
260 ofp.action.pop_vlan(),
261 ofp.action.output(port),
262 ]
263
264 buckets = [
265 ofp.bucket(actions=actions),
266 ]
267
268 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
269 group_id=group_id,
270 buckets=buckets
271 )
272 ctrl.message_send(request)
273
274 if send_barrier:
275 do_barrier(ctrl)
Pierbbdf3782016-08-22 17:58:26 -0700276
macauley0f91a3e2015-07-17 18:09:59 +0800277 return group_id, request
Pierbbdf3782016-08-22 17:58:26 -0700278
macauley97557232015-07-16 17:28:07 +0800279def add_l2_mcast_group(ctrl, ports, vlanid, mcast_grp_index):
280 buckets=[]
281 for of_port in ports:
282 group_id = encode_l2_interface_group_id(vlanid, of_port)
283 action=[ofp.action.group(group_id)]
284 buckets.append(ofp.bucket(actions=action))
285
286 group_id =encode_l2_mcast_group_id(vlanid, mcast_grp_index)
287 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
288 group_id=group_id,
289 buckets=buckets
290 )
291 ctrl.message_send(request)
macauley15909e72015-07-17 15:58:57 +0800292 return request
macauley97557232015-07-16 17:28:07 +0800293
macauley15909e72015-07-17 15:58:57 +0800294def add_l2_flood_group(ctrl, ports, vlanid, id):
295 buckets=[]
296 for of_port in ports:
297 group_id = encode_l2_interface_group_id(vlanid, of_port)
298 action=[ofp.action.group(group_id)]
299 buckets.append(ofp.bucket(actions=action))
macauley97557232015-07-16 17:28:07 +0800300
macauley15909e72015-07-17 15:58:57 +0800301 group_id =encode_l2_flood_group_id(vlanid, id)
302 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
303 group_id=group_id,
304 buckets=buckets
305 )
306 ctrl.message_send(request)
307 return request
308
Flavio Castroa7162bb2016-07-25 17:30:30 -0700309def mod_l2_flood_group(ctrl, ports, vlanid, id):
310 buckets=[]
311 for of_port in ports:
312 group_id = encode_l2_interface_group_id(vlanid, of_port)
313 action=[ofp.action.group(group_id)]
314 buckets.append(ofp.bucket(actions=action))
315
316 group_id =encode_l2_flood_group_id(vlanid, id)
317 request = ofp.message.group_modify(group_type=ofp.OFPGT_ALL,
318 group_id=group_id,
319 buckets=buckets
320 )
321 ctrl.message_send(request)
322 return request
323
324
macauley15909e72015-07-17 15:58:57 +0800325def add_l2_rewrite_group(ctrl, port, vlanid, id, src_mac, dst_mac):
326 group_id = encode_l2_interface_group_id(vlanid, port)
327
328 action=[]
329 if src_mac is not None:
330 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
331
332 if dst_mac is not None:
333 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
334
Flavio Castro91d1a552016-05-17 16:59:44 -0700335 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlanid)))
Pierbbdf3782016-08-22 17:58:26 -0700336
macauley15909e72015-07-17 15:58:57 +0800337 action.append(ofp.action.group(group_id))
Pierbbdf3782016-08-22 17:58:26 -0700338
macauley15909e72015-07-17 15:58:57 +0800339 buckets = [ofp.bucket(actions=action)]
340
341 group_id =encode_l2_rewrite_group_id(id)
342 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
343 group_id=group_id,
344 buckets=buckets
345 )
346 ctrl.message_send(request)
347 return request
Pierbbdf3782016-08-22 17:58:26 -0700348
Andreas Pantelopoulosf83e0212018-03-18 20:44:05 -0700349def add_l3_unicast_group(ctrl, port, vlanid, id, src_mac, dst_mac, send_barrier=False, gid=None):
350
351 if (not gid):
352 group_id = encode_l2_interface_group_id(vlanid, port)
353 else:
354 group_id = gid
macauley15909e72015-07-17 15:58:57 +0800355
356 action=[]
357 if src_mac is not None:
358 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
359
360 if dst_mac is not None:
361 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
362
Flavio Castroaf2b4502016-02-02 17:41:32 -0500363 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlanid)))
Pierbbdf3782016-08-22 17:58:26 -0700364
macauley15909e72015-07-17 15:58:57 +0800365 action.append(ofp.action.group(group_id))
Pierbbdf3782016-08-22 17:58:26 -0700366
macauley15909e72015-07-17 15:58:57 +0800367 buckets = [ofp.bucket(actions=action)]
368
369 group_id =encode_l3_unicast_group_id(id)
370 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
371 group_id=group_id,
372 buckets=buckets
373 )
374 ctrl.message_send(request)
Pier1e4e98e2016-10-26 14:36:05 -0700375
376 if send_barrier:
377 do_barrier(ctrl)
378
macauley15909e72015-07-17 15:58:57 +0800379 return request
Pierbbdf3782016-08-22 17:58:26 -0700380
macauley15909e72015-07-17 15:58:57 +0800381def add_l3_interface_group(ctrl, port, vlanid, id, src_mac):
382 group_id = encode_l2_interface_group_id(vlanid, port)
383
384 action=[]
385 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
Pierbbdf3782016-08-22 17:58:26 -0700386 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlanid)))
macauley15909e72015-07-17 15:58:57 +0800387 action.append(ofp.action.group(group_id))
Pierbbdf3782016-08-22 17:58:26 -0700388
macauley15909e72015-07-17 15:58:57 +0800389 buckets = [ofp.bucket(actions=action)]
390
391 group_id =encode_l3_interface_group_id(id)
392 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
393 group_id=group_id,
394 buckets=buckets
395 )
396 ctrl.message_send(request)
397 return request
398
Pier1e4e98e2016-10-26 14:36:05 -0700399def add_l3_ecmp_group(ctrl, id, l3_ucast_groups, send_barrier=False):
macauley15909e72015-07-17 15:58:57 +0800400 buckets=[]
401 for group in l3_ucast_groups:
402 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
403
404 group_id =encode_l3_ecmp_group_id(id)
405 request = ofp.message.group_add(group_type=ofp.OFPGT_SELECT,
406 group_id=group_id,
407 buckets=buckets
408 )
409 ctrl.message_send(request)
Pier1e4e98e2016-10-26 14:36:05 -0700410
411 if send_barrier:
412 do_barrier(ctrl)
413
macauley15909e72015-07-17 15:58:57 +0800414 return request
Flavio Castroa7162bb2016-07-25 17:30:30 -0700415
416def mod_l3_ecmp_group(ctrl, id, l3_ucast_groups):
417 buckets=[]
418 for group in l3_ucast_groups:
419 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
420
421 group_id =encode_l3_ecmp_group_id(id)
422 request = ofp.message.group_modify(group_type=ofp.OFPGT_SELECT,
423 group_id=group_id,
424 buckets=buckets
425 )
426 ctrl.message_send(request)
427 return request
428
macauley15909e72015-07-17 15:58:57 +0800429def add_l3_mcast_group(ctrl, vid, mcast_group_id, groups_on_buckets):
430 buckets=[]
431 for group in groups_on_buckets:
432 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
Pierbbdf3782016-08-22 17:58:26 -0700433
macauley15909e72015-07-17 15:58:57 +0800434 group_id =encode_l3_mcast_group_id(vid, mcast_group_id)
435 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
436 group_id=group_id,
437 buckets=buckets
438 )
439 ctrl.message_send(request)
440 return request
macauleyfddc4662015-07-27 17:40:30 +0800441
442def add_l2_overlay_flood_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
443 buckets=[]
444 for port in ports:
445 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
446
447 group_id=encode_l2_overlay_group_id(tunnel_id, 0, index)
448 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
449 group_id=group_id,
450 buckets=buckets
451 )
452 ctrl.message_send(request)
453 return request
454
455def add_l2_overlay_flood_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
456 buckets=[]
457 for port in ports:
458 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
459
460 group_id=encode_l2_overlay_group_id(tunnel_id, 1, index)
461 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
462 group_id=group_id,
463 buckets=buckets
464 )
465 ctrl.message_send(request)
466 return request
467
468def add_l2_overlay_mcast_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
469 buckets=[]
470 for port in ports:
471 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
472
473 group_id=encode_l2_overlay_group_id(tunnel_id, 2, index)
474 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
475 group_id=group_id,
476 buckets=buckets
477 )
478 ctrl.message_send(request)
479 return request
480
481def add_l2_overlay_mcast_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
482 buckets=[]
483 for port in ports:
484 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
485
486 group_id=encode_l2_overlay_group_id(tunnel_id, 3, index)
487 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
488 group_id=group_id,
489 buckets=buckets
490 )
491 ctrl.message_send(request)
492 return request
Pierbbdf3782016-08-22 17:58:26 -0700493
macauleyfddc4662015-07-27 17:40:30 +0800494def add_port_table_flow(ctrl, is_overlay=True):
495 match = ofp.match()
496
497 if is_overlay == True:
498 match.oxm_list.append(ofp.oxm.in_port(0x10000))
macauleydbff3272015-07-30 14:07:16 +0800499 NEXT_TABLE=50
macauleyfddc4662015-07-27 17:40:30 +0800500 else:
501 match.oxm_list.append(ofp.oxm.in_port(0))
Pierbbdf3782016-08-22 17:58:26 -0700502 NEXT_TABLE=10
macauleyfddc4662015-07-27 17:40:30 +0800503
504 request = ofp.message.flow_add(
Pier265ad5f2017-02-28 17:46:28 +0100505 table_id=0,
506 cookie=42,
507 match=match,
508 instructions=[
509 ofp.instruction.goto_table(NEXT_TABLE)
510 ],
511 priority=0)
macauleyfddc4662015-07-27 17:40:30 +0800512 logging.info("Add port table, match port %lx" % 0x10000)
513 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -0700514
Flavio Castrod8f8af22015-12-02 18:19:26 -0500515def pop_vlan_flow(ctrl, ports, vlan_id=1):
516 # table 10: vlan
517 # goto to table 20
518 msgs=[]
519 for of_port in ports:
520 match = ofp.match()
521 match.oxm_list.append(ofp.oxm.in_port(of_port))
522 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
523 request = ofp.message.flow_add(
524 table_id=10,
525 cookie=42,
526 match=match,
527 instructions=[
528 ofp.instruction.apply_actions(
529 actions=[
530 ofp.action.pop_vlan()
531 ]
532 ),
533 ofp.instruction.goto_table(20)
534 ],
535 priority=0)
536 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
537 ctrl.message_send(request)
538
539
540 return msgs
macauleyfddc4662015-07-27 17:40:30 +0800541
macauley97557232015-07-16 17:28:07 +0800542def add_vlan_table_flow(ctrl, ports, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
543 # table 10: vlan
544 # goto to table 20
macauley15909e72015-07-17 15:58:57 +0800545 msgs=[]
macauley97557232015-07-16 17:28:07 +0800546 for of_port in ports:
Flavio Castro932014b2016-01-05 18:29:15 -0500547 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
macauley97557232015-07-16 17:28:07 +0800548 match = ofp.match()
549 match.oxm_list.append(ofp.oxm.in_port(of_port))
550 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
551 request = ofp.message.flow_add(
552 table_id=10,
553 cookie=42,
554 match=match,
555 instructions=[
Flavio Castrod8f8af22015-12-02 18:19:26 -0500556 ofp.instruction.apply_actions(
557 actions=[
558 ofp.action.pop_vlan()
559 ]
560 ),
macauley97557232015-07-16 17:28:07 +0800561 ofp.instruction.goto_table(20)
562 ],
563 priority=0)
564 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
565 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -0700566
macauley97557232015-07-16 17:28:07 +0800567 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
568 match = ofp.match()
569 match.oxm_list.append(ofp.oxm.in_port(of_port))
Flavio Castro12296312015-12-15 17:48:26 -0500570 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0x1fff))
macauley97557232015-07-16 17:28:07 +0800571 request = ofp.message.flow_add(
572 table_id=10,
573 cookie=42,
574 match=match,
575 instructions=[
576 ofp.instruction.apply_actions(
577 actions=[
Flavio Castroaf2b4502016-02-02 17:41:32 -0500578 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id))
macauley97557232015-07-16 17:28:07 +0800579 ]
580 ),
581 ofp.instruction.goto_table(20)
582 ],
583 priority=0)
584 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
585 ctrl.message_send(request)
macauley15909e72015-07-17 15:58:57 +0800586 msgs.append(request)
macauley97557232015-07-16 17:28:07 +0800587
Flavio Castro932014b2016-01-05 18:29:15 -0500588 if (flag == 4) :
589 match = ofp.match()
590 match.oxm_list.append(ofp.oxm.in_port(of_port))
591 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1fff))
592 request = ofp.message.flow_add(
593 table_id=10,
594 cookie=42,
595 match=match,
596 instructions=[
597 ofp.instruction.apply_actions(
598 actions=[
Flavio Castroaf2b4502016-02-02 17:41:32 -0500599 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id))
Flavio Castro932014b2016-01-05 18:29:15 -0500600 ]
601 ),
602 ofp.instruction.goto_table(20)
603 ],
604 priority=0)
605 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
606 ctrl.message_send(request)
607 msgs.append(request)
608
macauley97557232015-07-16 17:28:07 +0800609 if send_barrier:
610 do_barrier(ctrl)
611
macauley15909e72015-07-17 15:58:57 +0800612 return msgs
Pierbbdf3782016-08-22 17:58:26 -0700613
macauley_cheng6e6a6122015-11-16 14:19:18 +0800614def del_vlan_table_flow(ctrl, ports, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
615 # table 10: vlan
616 # goto to table 20
617 msgs=[]
618 for of_port in ports:
619 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
620 match = ofp.match()
621 match.oxm_list.append(ofp.oxm.in_port(of_port))
622 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
623 request = ofp.message.flow_delete(
624 table_id=10,
625 cookie=42,
626 match=match,
627 priority=0)
628 logging.info("Del vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
629 ctrl.message_send(request)
macauley0f91a3e2015-07-17 18:09:59 +0800630
macauley_cheng6e6a6122015-11-16 14:19:18 +0800631 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
632 match = ofp.match()
633 match.oxm_list.append(ofp.oxm.in_port(of_port))
634 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0xfff))
635 request = ofp.message.flow_delete(
636 table_id=10,
637 cookie=42,
638 match=match,
639 priority=0)
640 logging.info("Del vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
641 ctrl.message_send(request)
642 msgs.append(request)
643
644 if send_barrier:
645 do_barrier(ctrl)
646
647 return msgs
Pierbbdf3782016-08-22 17:58:26 -0700648
macauley_cheng6b311612015-09-04 11:32:27 +0800649def add_vlan_table_flow_pvid(ctrl, in_port, match_vid=None, pvid=1, send_barrier=False):
650 """it will tag pack as untagged packet wether it has tagg or not"""
651 match = ofp.match()
652 match.oxm_list.append(ofp.oxm.in_port(in_port))
653 actions=[]
654 if match_vid == None:
Pierbbdf3782016-08-22 17:58:26 -0700655 match.oxm_list.append(ofp.oxm.vlan_vid(0))
macauley_cheng6b311612015-09-04 11:32:27 +0800656 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+pvid)))
657 goto_table=20
658 else:
659 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+match_vid, 0x1fff))
660 actions.append(ofp.action.push_vlan(0x8100))
Pierbbdf3782016-08-22 17:58:26 -0700661 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+pvid)))
macauley_cheng6b311612015-09-04 11:32:27 +0800662 goto_table=20
Pierbbdf3782016-08-22 17:58:26 -0700663
macauley_cheng6b311612015-09-04 11:32:27 +0800664 request = ofp.message.flow_add(
665 table_id=10,
666 cookie=42,
667 match=match,
668 instructions=[
669 ofp.instruction.apply_actions(actions=actions)
670 ,ofp.instruction.goto_table(goto_table)
671 ],
672 priority=0)
673 logging.info("Add PVID %d on port %d and go to table %ld" %( pvid, in_port, goto_table))
Pierbbdf3782016-08-22 17:58:26 -0700674 ctrl.message_send(request)
675
macauley_cheng6b311612015-09-04 11:32:27 +0800676 if send_barrier:
677 do_barrier(ctrl)
678
679def add_vlan_table_flow_allow_all_vlan(ctrl, in_port, send_barrier=False):
680 """it st flow allow all vlan tag on this port"""
681 match = ofp.match()
682 match.oxm_list.append(ofp.oxm.in_port(in_port))
683 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1000))
684 request = ofp.message.flow_add(
685 table_id=10,
686 cookie=42,
687 match=match,
688 instructions=[
Pierbbdf3782016-08-22 17:58:26 -0700689 ofp.instruction.goto_table(20)
macauley_cheng6b311612015-09-04 11:32:27 +0800690 ],
691 priority=0)
692 logging.info("Add allow all vlan on port %d " %(in_port))
Pierbbdf3782016-08-22 17:58:26 -0700693 ctrl.message_send(request)
macauley_cheng6b311612015-09-04 11:32:27 +0800694
Pier7b031af2016-08-25 15:00:22 -0700695def 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):
696 # Install a flow for VLAN translation
697 # in VLAN table.
698 # table 10: vlan
699 # goto to table 20
700 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
701 match = ofp.match()
702 match.oxm_list.append(ofp.oxm.in_port(of_port))
703 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id,0x1fff))
704
705 actions=[]
706 if vrf!=0:
707 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
708 if new_vlan_id != -1:
709 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_vlan_id)))
710
711 request = ofp.message.flow_add(
712 table_id=10,
713 cookie=42,
714 match=match,
715 instructions=[
716 ofp.instruction.apply_actions(
717 actions=actions
718 ),
719 ofp.instruction.goto_table(20)
720 ],
721 priority=0)
722 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
723 ctrl.message_send(request)
724
Andreas Pantelopoulosf83e0212018-03-18 20:44:05 -0700725
726def add_one_egress_vlan_table_flow(ctrl, of_port, match_vlan, inner_vlan, outer_vlan):
727
728 # used for translating single to double tagged packets only
729
730 match = ofp.match()
731 match.oxm_list.append(ofp.oxm.exp4ByteValue(ofp.oxm.OFDPA_EXP_TYPE_ACTSET_OUTPUT, of_port))
732 match.oxm_list.append(ofp.oxm.exp1ByteValue(ofp.oxm.OFDPA_EXP_TYPE_ALLOW_VLAN_TRANSLATION, 1))
733 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+match_vlan,0x1fff))
734
735 actions=[]
736 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+inner_vlan)))
737 actions.append(ofp.action.push_vlan(0x8100))
738 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+outer_vlan)))
739
740 request = ofp.message.flow_add(
741 table_id=EGRESS_VLAN_FLOW_TABLE,
742 cookie=42,
743 match=match,
744 instructions=[
745 ofp.instruction.apply_actions(
746 actions=actions
747 ),
748 ofp.instruction.goto_table(EGRESS_DSCP_TABLE)
749 ],
750 priority=0)
751
752 ctrl.message_send(request)
753
754 return
755
Piere1308762016-09-12 15:29:56 -0700756def 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 -0700757
macauley0f91a3e2015-07-17 18:09:59 +0800758 # goto to table 20
Flavio Castro932014b2016-01-05 18:29:15 -0500759 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
macauley0f91a3e2015-07-17 18:09:59 +0800760 match = ofp.match()
761 match.oxm_list.append(ofp.oxm.in_port(of_port))
Flavio Castro12296312015-12-15 17:48:26 -0500762 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id,0x1fff))
macauley7f89d962015-08-06 18:13:48 +0800763
764 actions=[]
Alex Yashchuk9f449462017-12-09 18:27:19 +0200765 if config["switch_type"] != 'xpliant' and vrf != 0:
766 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
Pierbbdf3782016-08-22 17:58:26 -0700767
Flavio Castro6d498522015-12-15 14:05:04 -0500768 #actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(value=vlan_id)))
macauley7f89d962015-08-06 18:13:48 +0800769
macauley0f91a3e2015-07-17 18:09:59 +0800770 request = ofp.message.flow_add(
771 table_id=10,
772 cookie=42,
773 match=match,
774 instructions=[
macauley53d90fe2015-08-04 17:34:22 +0800775 ofp.instruction.apply_actions(
macauley7f89d962015-08-06 18:13:48 +0800776 actions=actions
macauley53d90fe2015-08-04 17:34:22 +0800777 ),
778 ofp.instruction.goto_table(20)
macauley0f91a3e2015-07-17 18:09:59 +0800779 ],
780 priority=0)
781 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
782 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -0700783
macauley0f91a3e2015-07-17 18:09:59 +0800784 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
Andreas Pantelopoulosf83e0212018-03-18 20:44:05 -0700785
macauley0f91a3e2015-07-17 18:09:59 +0800786 match = ofp.match()
787 match.oxm_list.append(ofp.oxm.in_port(of_port))
Flavio Castro12296312015-12-15 17:48:26 -0500788 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0x1fff))
Pierbbdf3782016-08-22 17:58:26 -0700789
macauley7f89d962015-08-06 18:13:48 +0800790 actions=[]
791 if vrf!=0:
792 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
Pierbbdf3782016-08-22 17:58:26 -0700793
Andreas Pantelopoulosf83e0212018-03-18 20:44:05 -0700794 # actions.append(ofp.action.push_vlan(0x8100))
Flavio Castro91d1a552016-05-17 16:59:44 -0700795 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
Pierbbdf3782016-08-22 17:58:26 -0700796
macauley0f91a3e2015-07-17 18:09:59 +0800797 request = ofp.message.flow_add(
798 table_id=10,
799 cookie=42,
800 match=match,
801 instructions=[
802 ofp.instruction.apply_actions(
macauley7f89d962015-08-06 18:13:48 +0800803 actions=actions
macauley0f91a3e2015-07-17 18:09:59 +0800804 ),
805 ofp.instruction.goto_table(20)
806 ],
807 priority=0)
808 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
809 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -0700810
Flavio Castro932014b2016-01-05 18:29:15 -0500811 if (flag == 4) :
812 match = ofp.match()
813 match.oxm_list.append(ofp.oxm.in_port(of_port))
814 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000,0x1fff))
815
816 actions=[]
817 if vrf!=0:
818 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
819
Flavio Castro91d1a552016-05-17 16:59:44 -0700820 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
Flavio Castro932014b2016-01-05 18:29:15 -0500821
822 request = ofp.message.flow_add(
823 table_id=10,
824 cookie=42,
825 match=match,
826 instructions=[
827 ofp.instruction.apply_actions(
828 actions=actions
829 ),
830 ofp.instruction.goto_table(20)
831 ],
832 priority=0)
833 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
834 ctrl.message_send(request)
macauley0f91a3e2015-07-17 18:09:59 +0800835
Piere1308762016-09-12 15:29:56 -0700836 if (flag == VLAN_TABLE_FLAG_ONLY_STACKED):
837 # This flag is meant to managed stacked vlan packtes
838 # Matches on outer VLAN_ID, set OVID with outer VLAN.
839 # Finally expose inner VLAN_ID with a pop action and
840 # goto VLAN_1_FLOW_TABLE
841 match = ofp.match()
842 match.oxm_list.append(ofp.oxm.in_port(of_port))
843 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id,0x1fff))
844
845 actions=[]
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 actions.append(ofp.action.pop_vlan())
Andreas Pantelopoulosf83e0212018-03-18 20:44:05 -0700848 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 -0700849
850 request = ofp.message.flow_add(
851 table_id=10,
852 cookie=42,
853 match=match,
854 instructions=[
855 ofp.instruction.apply_actions(
856 actions=actions
857 ),
858 ofp.instruction.goto_table(VLAN_1_FLOW_TABLE)
859 ],
860 priority=0)
861 logging.info("Add vlan %d tagged packets on port %d and go to table %d" %( vlan_id, of_port, VLAN_1_FLOW_TABLE))
862 ctrl.message_send(request)
863
864 if (flag == VLAN_TABLE_FLAG_PRIORITY) :
865 match = ofp.match()
866 match.oxm_list.append(ofp.oxm.in_port(of_port))
867 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1fff))
868 request = ofp.message.flow_add(
869 table_id=10,
870 cookie=42,
871 match=match,
872 instructions=[
873 ofp.instruction.apply_actions(
874 actions=[
875 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)),
876 ofp.action.push_vlan(0x8100),
877 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+out_vlan_id)),
878 ]
879 ),
880 ofp.instruction.goto_table(20)
881 ],
882 priority=0)
883 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
884 ctrl.message_send(request)
885
886 if send_barrier:
887 do_barrier(ctrl)
888
889 return request
890
Piercf76e802016-09-19 20:16:35 -0700891def 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):
892 # table 10: vlan
893 # goto to table 13
894 if flag == VLAN_TABLE_FLAG_ONLY_TAG:
895 match = ofp.match()
896 match.oxm_list.append(ofp.oxm.in_port(of_port))
897 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id, 0x1fff))
898
899 actions=[]
900 if vlan_id == -1:
901 actions.append(ofp.action.pop_vlan())
902 if new_vlan_id > 1:
903 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_vlan_id)))
904 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
905 actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
906 # 0x0000nnnn is for UNI interfaces
907 actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port)))
908
909 request = ofp.message.flow_add(
910 table_id=10,
911 cookie=42,
912 match=match,
913 instructions=[
914 ofp.instruction.apply_actions(
915 actions=actions
916 ),
917 ofp.instruction.goto_table(MPLS_L2_PORT_FLOW_TABLE)
918 ],
919 priority=0)
920 logging.info("Add vlan %d tagged packets on port %d and go to table %d" % (vlan_id, of_port, MPLS_L2_PORT_FLOW_TABLE))
921 ctrl.message_send(request)
922
923 if flag == VLAN_TABLE_FLAG_ONLY_UNTAG:
924 match = ofp.match()
925 match.oxm_list.append(ofp.oxm.in_port(of_port))
926 match.oxm_list.append(ofp.oxm.vlan_vid(0))
927
928 actions=[]
929 if vlan_id > 1:
Charles Chanc85f1562018-01-18 15:44:29 -0800930 # actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
931 # actions.append(ofp.action.set_field(ofp.action.push_vlan(0x8100)))
Piercf76e802016-09-19 20:16:35 -0700932 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
Charles Chanc85f1562018-01-18 15:44:29 -0800933
Piercf76e802016-09-19 20:16:35 -0700934 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
935 actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
936 # 0x0000nnnn is for UNI interfaces
937 actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port)))
938
939 request = ofp.message.flow_add(
940 table_id=10,
941 cookie=42,
942 match=match,
943 instructions=[
944 ofp.instruction.apply_actions(
945 actions=actions
946 ),
947 ofp.instruction.goto_table(MPLS_L2_PORT_FLOW_TABLE)
948 ],
949 priority=0)
950 logging.info("Add vlan %d untagged packets on port %d and go to table %d" % (vlan_id, of_port, MPLS_L2_PORT_FLOW_TABLE))
951 ctrl.message_send(request)
952
953 if send_barrier:
954 do_barrier(ctrl)
955
956 return request
957
Piere1308762016-09-12 15:29:56 -0700958def 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 -0700959
Piere1308762016-09-12 15:29:56 -0700960 # table 11: vlan 1 table
961 # goto to table 20
962 if flag == VLAN_TABLE_FLAG_ONLY_TAG:
963 match = ofp.match()
964 match.oxm_list.append(ofp.oxm.in_port(of_port))
965 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
966 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
967
968 actions=[]
969 actions.append(ofp.action.push_vlan(0x8100))
970 if new_outer_vlan_id != -1:
971 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_outer_vlan_id)))
972 else:
973 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+outer_vlan_id)))
974
975 request = ofp.message.flow_add(
976 table_id=11,
977 cookie=42,
978 match=match,
979 instructions=[
980 ofp.instruction.apply_actions(
981 actions=actions
982 ),
983 ofp.instruction.goto_table(TERMINATION_FLOW_TABLE)
984 ],
985 priority=0)
986 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))
987 ctrl.message_send(request)
988
989 if flag == VLAN_TABLE_FLAG_ONLY_UNTAG:
Andreas Pantelopoulosf83e0212018-03-18 20:44:05 -0700990
Piere1308762016-09-12 15:29:56 -0700991 match = ofp.match()
992 match.oxm_list.append(ofp.oxm.in_port(of_port))
993 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
994 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
995
996 actions=[]
997 request = ofp.message.flow_add(
998 table_id=11,
999 cookie=42,
1000 match=match,
1001 instructions=[
1002 ofp.instruction.apply_actions(
1003 actions=actions
1004 ),
1005 ofp.instruction.goto_table(TERMINATION_FLOW_TABLE)
1006 ],
1007 priority=0)
1008 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))
1009 ctrl.message_send(request)
1010
Andreas Pantelopoulosf83e0212018-03-18 20:44:05 -07001011 if flag == VLAN_TABLE_FLAG_ONLY_POP_VLAN:
1012
1013 print("INSTALLIN IN TABLE 11!")
1014
1015 match = ofp.match()
1016 match.oxm_list.append(ofp.oxm.in_port(of_port))
1017 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
1018 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
1019
1020 actions=[]
1021 actions.append(ofp.action.pop_vlan())
1022
1023 request = ofp.message.flow_add(
1024 table_id=11,
1025 cookie=42,
1026 match=match,
1027 instructions=[
1028 ofp.instruction.apply_actions(
1029 actions=actions
1030 ),
1031 ofp.instruction.goto_table(TERMINATION_FLOW_TABLE)
1032 ],
1033 priority=0)
1034 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))
1035 ctrl.message_send(request)
1036
1037
macauley0f91a3e2015-07-17 18:09:59 +08001038 if send_barrier:
1039 do_barrier(ctrl)
1040
1041 return request
Pierbbdf3782016-08-22 17:58:26 -07001042
Piercf76e802016-09-19 20:16:35 -07001043def 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 -08001044
Piercf76e802016-09-19 20:16:35 -07001045 # table 11: vlan 1 table
1046 # goto to table 13
1047 match = ofp.match()
1048 match.oxm_list.append(ofp.oxm.in_port(of_port))
1049 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
1050 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
1051
1052 actions=[]
1053 actions.append(ofp.action.push_vlan(0x8100))
1054 if new_outer_vlan_id != -1:
Charles Chanc85f1562018-01-18 15:44:29 -08001055 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_outer_vlan_id)))
Piercf76e802016-09-19 20:16:35 -07001056 else:
Charles Chanc85f1562018-01-18 15:44:29 -08001057 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+outer_vlan_id)))
Piercf76e802016-09-19 20:16:35 -07001058
1059 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
1060 actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
1061 # 0x0000nnnn is for UNI interfaces
1062 actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port)))
1063
1064 request = ofp.message.flow_add(
Charles Chanc85f1562018-01-18 15:44:29 -08001065 table_id=11,
1066 cookie=42,
1067 match=match,
1068 instructions=[
1069 ofp.instruction.apply_actions(
1070 actions=actions
1071 ),
1072 ofp.instruction.goto_table(MPLS_L2_PORT_FLOW_TABLE)
1073 ],
1074 priority=0)
Piercf76e802016-09-19 20:16:35 -07001075 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))
1076 ctrl.message_send(request)
Piercf76e802016-09-19 20:16:35 -07001077 if send_barrier:
1078 do_barrier(ctrl)
1079
1080 return request
1081
macauley97557232015-07-16 17:28:07 +08001082def add_bridge_flow(ctrl, dst_mac, vlanid, group_id, send_barrier=False):
1083 match = ofp.match()
castroflavio21894482015-12-08 15:29:55 -05001084 priority=500
macauleyfddc4662015-07-27 17:40:30 +08001085 if dst_mac!=None:
castroflavio21894482015-12-08 15:29:55 -05001086 priority=1000
macauleyfddc4662015-07-27 17:40:30 +08001087 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
1088
macauley97557232015-07-16 17:28:07 +08001089 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
macauleyfddc4662015-07-27 17:40:30 +08001090
macauley97557232015-07-16 17:28:07 +08001091 request = ofp.message.flow_add(
1092 table_id=50,
1093 cookie=42,
1094 match=match,
1095 instructions=[
1096 ofp.instruction.write_actions(
1097 actions=[
1098 ofp.action.group(group_id)]),
1099 ofp.instruction.goto_table(60)
1100 ],
1101 buffer_id=ofp.OFP_NO_BUFFER,
castroflavio21894482015-12-08 15:29:55 -05001102 priority=priority)
macauley97557232015-07-16 17:28:07 +08001103
1104 logging.info("Inserting Brdige flow vlan %d, mac %s", vlanid, dst_mac)
1105 ctrl.message_send(request)
1106
1107 if send_barrier:
Pierbbdf3782016-08-22 17:58:26 -07001108 do_barrier(ctrl)
macauley15909e72015-07-17 15:58:57 +08001109
Pierbbdf3782016-08-22 17:58:26 -07001110 return request
macauleyfddc4662015-07-27 17:40:30 +08001111
1112def add_overlay_bridge_flow(ctrl, dst_mac, vnid, group_id, is_group=True, send_barrier=False):
1113 match = ofp.match()
1114 if dst_mac!=None:
1115 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
1116
1117 match.oxm_list.append(ofp.oxm.tunnel_id(vnid))
1118 if is_group == True:
1119 actions=[ofp.action.group(group_id)]
1120 else:
1121 actions=[ofp.action.output(group_id)]
1122
1123 request = ofp.message.flow_add(
1124 table_id=50,
1125 cookie=42,
1126 match=match,
1127 instructions=[
1128 ofp.instruction.write_actions(
1129 actions=actions),
1130 ofp.instruction.goto_table(60)
1131 ],
1132 buffer_id=ofp.OFP_NO_BUFFER,
Pierbbdf3782016-08-22 17:58:26 -07001133 priority=1000)
macauleyfddc4662015-07-27 17:40:30 +08001134
1135 logging.info("Inserting Brdige flow vnid %d, mac %s", vnid, dst_mac)
1136 ctrl.message_send(request)
1137
1138 if send_barrier:
Pierbbdf3782016-08-22 17:58:26 -07001139 do_barrier(ctrl)
macauleyfddc4662015-07-27 17:40:30 +08001140
Pierbbdf3782016-08-22 17:58:26 -07001141 return request
1142
macauley_cheng6b133662015-11-09 13:52:39 +08001143def add_termination_flow(ctrl, in_port, eth_type, dst_mac, vlanid, goto_table=None, send_barrier=False):
macauley0f91a3e2015-07-17 18:09:59 +08001144 match = ofp.match()
macauley0f91a3e2015-07-17 18:09:59 +08001145 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
macauleyfddc4662015-07-27 17:40:30 +08001146 if dst_mac[0]&0x01 == 0x01:
1147 match.oxm_list.append(ofp.oxm.eth_dst_masked(dst_mac, [0xff, 0xff, 0xff, 0x80, 0x00, 0x00]))
1148 goto_table=40
1149 else:
macauley53d90fe2015-08-04 17:34:22 +08001150 if in_port!=0:
1151 match.oxm_list.append(ofp.oxm.in_port(in_port))
macauleyfddc4662015-07-27 17:40:30 +08001152 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
1153 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
macauley_cheng6b133662015-11-09 13:52:39 +08001154 if goto_table == None:
1155 goto_table=30
macauley0f91a3e2015-07-17 18:09:59 +08001156
1157 request = ofp.message.flow_add(
1158 table_id=20,
1159 cookie=42,
1160 match=match,
1161 instructions=[
1162 ofp.instruction.goto_table(goto_table)
1163 ],
1164 buffer_id=ofp.OFP_NO_BUFFER,
Pierbbdf3782016-08-22 17:58:26 -07001165 priority=1)
macauley0f91a3e2015-07-17 18:09:59 +08001166
1167 logging.info("Inserting termination flow inport %d, eth_type %lx, vlan %d, mac %s", in_port, eth_type, vlanid, dst_mac)
1168 ctrl.message_send(request)
macauley0f91a3e2015-07-17 18:09:59 +08001169 if send_barrier:
Pierbbdf3782016-08-22 17:58:26 -07001170 do_barrier(ctrl)
macauley0f91a3e2015-07-17 18:09:59 +08001171
Pierbbdf3782016-08-22 17:58:26 -07001172 return request
1173
Alex Yashchuk9f449462017-12-09 18:27:19 +02001174def 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 +08001175 match = ofp.match()
1176 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
Alex Yashchuk9f449462017-12-09 18:27:19 +02001177 if config["switch_type"] != 'xpliant' and vrf != 0:
macauley53d90fe2015-08-04 17:34:22 +08001178 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_VRF, vrf))
macauley0f91a3e2015-07-17 18:09:59 +08001179
Flavio Castroaf2b4502016-02-02 17:41:32 -05001180 match.oxm_list.append(ofp.oxm.ipv4_dst_masked(dst_ip, mask))
1181
1182 instructions = []
1183 instructions.append(ofp.instruction.goto_table(60))
1184 if send_ctrl:
Pier265ad5f2017-02-28 17:46:28 +01001185 instructions.append(ofp.instruction.write_actions(
Flavio Castroaf2b4502016-02-02 17:41:32 -05001186 actions=[ofp.action.output( port=ofp.OFPP_CONTROLLER,
1187 max_len=ofp.OFPCML_NO_BUFFER)]))
Pierbbdf3782016-08-22 17:58:26 -07001188 else:
Flavio Castroaf2b4502016-02-02 17:41:32 -05001189 instructions.append(ofp.instruction.write_actions(
1190 actions=[ofp.action.group(action_group_id)]))
macauley53d90fe2015-08-04 17:34:22 +08001191
macauley0f91a3e2015-07-17 18:09:59 +08001192 request = ofp.message.flow_add(
1193 table_id=30,
1194 cookie=42,
1195 match=match,
Flavio Castroaf2b4502016-02-02 17:41:32 -05001196 instructions=instructions,
macauley0f91a3e2015-07-17 18:09:59 +08001197 buffer_id=ofp.OFP_NO_BUFFER,
Alex Yashchuk9f449462017-12-09 18:27:19 +02001198 priority=priority)
macauley0f91a3e2015-07-17 18:09:59 +08001199
1200 logging.info("Inserting unicast routing flow eth_type %lx, dip %ld",eth_type, dst_ip)
1201 ctrl.message_send(request)
1202
1203 if send_barrier:
Pierbbdf3782016-08-22 17:58:26 -07001204 do_barrier(ctrl)
macauley0f91a3e2015-07-17 18:09:59 +08001205
Flavio Castro9debaaa2016-07-26 19:37:50 -07001206 return request
Flavio Castrod8f8af22015-12-02 18:19:26 -05001207
Pier1e4e98e2016-10-26 14:36:05 -07001208def add_unicast_v6_routing_flow(ctrl, eth_type, dst_ip, mask, action_group_id, vrf=0, send_ctrl=False, send_barrier=False):
1209 match = ofp.match()
1210 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
1211 if vrf != 0:
1212 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_VRF, vrf))
1213
1214 match.oxm_list.append(ofp.oxm.ipv6_dst_masked(parse_ipv6(dst_ip), parse_ipv6(mask)))
1215
1216 instructions = []
1217 instructions.append(ofp.instruction.goto_table(60))
1218 if send_ctrl:
Pier265ad5f2017-02-28 17:46:28 +01001219 instructions.append(ofp.instruction.write_actions(
Pier1e4e98e2016-10-26 14:36:05 -07001220 actions=[ofp.action.output( port=ofp.OFPP_CONTROLLER,
1221 max_len=ofp.OFPCML_NO_BUFFER)]))
1222 else:
1223 instructions.append(ofp.instruction.write_actions(
1224 actions=[ofp.action.group(action_group_id)]))
1225
1226 request = ofp.message.flow_add(
1227 table_id=30,
1228 cookie=42,
1229 match=match,
1230 instructions=instructions,
1231 buffer_id=ofp.OFP_NO_BUFFER,
1232 priority=1)
1233
1234 logging.info("Inserting unicast routing flow eth_type %lx, dip %s",eth_type, dst_ip)
1235 ctrl.message_send(request)
1236
1237 if send_barrier:
1238 do_barrier(ctrl)
1239
1240 return request
1241
Andreas Pantelopoulos6c76b942018-01-22 10:03:02 -08001242def 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 -04001243 match = ofp.match()
1244 match.oxm_list.append(ofp.oxm.eth_type(0x8847))
1245 match.oxm_list.append(ofp.oxm.mpls_label(label))
1246 match.oxm_list.append(ofp.oxm.mpls_bos(bos))
Pier265ad5f2017-02-28 17:46:28 +01001247 write_actions = []
1248 write_actions.append(ofp.action.group(action_group_id))
1249 apply_actions = []
1250 apply_actions = [ofp.action.dec_mpls_ttl(),
Flavio Castro8ca52542016-04-11 11:24:49 -04001251 ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf))]
Pier265ad5f2017-02-28 17:46:28 +01001252 if (goto_table != 29):
1253 apply_actions.append(ofp.action.set_field(
Flavio Castrod80fbc32016-07-25 15:54:26 -07001254 ofp.oxm.exp2ByteValue(exp_type=23, value=32)))
Pier265ad5f2017-02-28 17:46:28 +01001255 apply_actions.append(ofp.action.copy_ttl_in())
Flavio Castro9debaaa2016-07-26 19:37:50 -07001256
Flavio Castrob702a2f2016-04-10 22:01:48 -04001257 request = ofp.message.flow_add(
1258 table_id=24,
1259 cookie=43,
1260 match=match,
1261 instructions=[
Pier265ad5f2017-02-28 17:46:28 +01001262 ofp.instruction.apply_actions(actions=apply_actions),
1263 ofp.instruction.write_actions(actions=write_actions),
Flavio Castro8ca52542016-04-11 11:24:49 -04001264 ofp.instruction.goto_table(goto_table)
Flavio Castrob702a2f2016-04-10 22:01:48 -04001265 ],
1266 buffer_id=ofp.OFP_NO_BUFFER,
1267 priority=1)
Flavio Castrob702a2f2016-04-10 22:01:48 -04001268 logging.info("Inserting MPLS flow , label %ld", label)
1269 ctrl.message_send(request)
1270
1271 if send_barrier:
1272 do_barrier(ctrl)
1273
1274 return request
1275
Alex Yashchuk9f449462017-12-09 18:27:19 +02001276def xpliant_add_mpls_flow(ctrl, action_group_id=0x0, label=100 ,ethertype=0x0800, bos=1, vrf=1, goto_table=27, send_barrier=False):
1277 match = ofp.match()
1278 match.oxm_list.append(ofp.oxm.eth_type(0x8847))
1279 match.oxm_list.append(ofp.oxm.mpls_label(label))
1280
1281 apply_actions = []
1282 apply_actions.append(ofp.action.group(action_group_id))
1283 apply_actions.append(ofp.action.dec_mpls_ttl())
1284 if (goto_table != 29):
1285 apply_actions.append(ofp.action.pop_mpls(ethertype))
1286
1287 request = ofp.message.flow_add(
1288 table_id=24,
1289 cookie=43,
1290 match=match,
1291 instructions=[
1292 ofp.instruction.apply_actions(actions=apply_actions),
1293 ],
1294 buffer_id=ofp.OFP_NO_BUFFER,
1295 priority=1)
1296 logging.info("Inserting MPLS flow , label %ld", label)
1297 ctrl.message_send(request)
1298
1299 if send_barrier:
1300 do_barrier(ctrl)
1301
1302 return request
1303
Andreas Pantelopoulos6c76b942018-01-22 10:03:02 -08001304def add_mpls_flow_swap(ctrl, action_group_id, label, ethertype, bos, goto_table=MPLS_TYPE_FLOW_TABLE, of_port=0, send_barrier=False):
1305 match = ofp.match()
1306 match.oxm_list.append(ofp.oxm.eth_type(0x8847))
1307 match.oxm_list.append(ofp.oxm.mpls_label(label))
1308 match.oxm_list.append(ofp.oxm.mpls_bos(1))
1309
1310 apply_actions = []
1311 write_actions = []
1312 apply_actions.append(ofp.action.dec_mpls_ttl())
1313 write_actions.append(ofp.action.group(action_group_id))
1314
1315 request = ofp.message.flow_add(
1316 table_id=24,
1317 cookie=43,
1318 match=match,
1319 instructions=[
1320 ofp.instruction.apply_actions(actions=apply_actions),
1321 ofp.instruction.write_actions(actions=write_actions),
1322 ofp.instruction.goto_table(goto_table)
1323 ],
1324 buffer_id=ofp.OFP_NO_BUFFER,
1325 priority=1)
1326
1327 logging.info("Inserting MPLS flow , label %ld", label)
1328 ctrl.message_send(request)
1329
1330 if send_barrier:
1331 do_barrier(ctrl)
1332
1333 return request
1334
1335
Pierf6f28162016-09-22 16:30:52 -07001336def 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 -07001337 match = ofp.match()
1338 match.oxm_list.append(ofp.oxm.eth_type(0x8847))
1339 match.oxm_list.append(ofp.oxm.mpls_label(label))
1340 match.oxm_list.append(ofp.oxm.mpls_bos(bos))
1341
Pier265ad5f2017-02-28 17:46:28 +01001342 apply_actions = []
1343 write_actions = []
1344 apply_actions.append(ofp.action.dec_mpls_ttl())
Pierf6f28162016-09-22 16:30:52 -07001345 if popMPLS == True:
Pier265ad5f2017-02-28 17:46:28 +01001346 apply_actions.append(ofp.action.copy_ttl_in())
1347 apply_actions.append(ofp.action.pop_mpls(ethertype))
Pierf6f28162016-09-22 16:30:52 -07001348 if bos==1 and popL2 == True:
Pier265ad5f2017-02-28 17:46:28 +01001349 apply_actions.append(ofp.action.ofdpa_pop_l2_header())
1350 apply_actions.append(ofp.action.ofdpa_pop_cw())
1351 apply_actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
Pierf6f28162016-09-22 16:30:52 -07001352 # 0x0002nnnn is for UNI interfaces
Pier265ad5f2017-02-28 17:46:28 +01001353 apply_actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00020000 + of_port)))
1354 apply_actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
1355 write_actions.append(ofp.action.group(action_group_id))
Pierb5da4c92016-09-21 11:23:35 -07001356
1357 request = ofp.message.flow_add(
Pier265ad5f2017-02-28 17:46:28 +01001358 table_id=24,
1359 cookie=43,
1360 match=match,
1361 instructions=[
1362 ofp.instruction.apply_actions(actions=apply_actions),
1363 ofp.instruction.write_actions(actions=write_actions),
1364 ofp.instruction.goto_table(goto_table)
1365 ],
1366 buffer_id=ofp.OFP_NO_BUFFER,
1367 priority=1)
Pierb5da4c92016-09-21 11:23:35 -07001368 logging.info("Inserting MPLS flow , label %ld", label)
1369 ctrl.message_send(request)
1370
1371 if send_barrier:
1372 do_barrier(ctrl)
1373
1374 return request
1375
macauleyfddc4662015-07-27 17:40:30 +08001376def add_mcast4_routing_flow(ctrl, vlan_id, src_ip, src_ip_mask, dst_ip, action_group_id, send_barrier=False):
1377 match = ofp.match()
1378 match.oxm_list.append(ofp.oxm.eth_type(0x0800))
Alex Yashchuk9f449462017-12-09 18:27:19 +02001379 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000 + vlan_id))
macauleyfddc4662015-07-27 17:40:30 +08001380 if src_ip_mask!=0:
1381 match.oxm_list.append(ofp.oxm.ipv4_src_masked(src_ip, src_ip_mask))
1382 else:
1383 match.oxm_list.append(ofp.oxm.ipv4_src(src_ip))
Pierbbdf3782016-08-22 17:58:26 -07001384
macauleyfddc4662015-07-27 17:40:30 +08001385 match.oxm_list.append(ofp.oxm.ipv4_dst(dst_ip))
Pierbbdf3782016-08-22 17:58:26 -07001386
macauleyfddc4662015-07-27 17:40:30 +08001387 request = ofp.message.flow_add(
1388 table_id=40,
1389 cookie=42,
1390 match=match,
1391 instructions=[
1392 ofp.instruction.write_actions(
1393 actions=[ofp.action.group(action_group_id)]),
1394 ofp.instruction.goto_table(60)
1395 ],
1396 buffer_id=ofp.OFP_NO_BUFFER,
Pierbbdf3782016-08-22 17:58:26 -07001397 priority=1)
macauleyfddc4662015-07-27 17:40:30 +08001398
1399 logging.info("Inserting mcast routing flow eth_type %lx, dip %lx, sip %lx, sip_mask %lx",0x0800, dst_ip, src_ip, src_ip_mask)
1400 ctrl.message_send(request)
1401
1402 if send_barrier:
Pierbbdf3782016-08-22 17:58:26 -07001403 do_barrier(ctrl)
macauleyfddc4662015-07-27 17:40:30 +08001404
Pierbbdf3782016-08-22 17:58:26 -07001405 return request
macauley_cheng6b133662015-11-09 13:52:39 +08001406
Pier1e4e98e2016-10-26 14:36:05 -07001407def add_acl_rule(ctrl, eth_type=None, ip_proto=None, send_barrier=False):
1408 match = ofp.match()
1409 if eth_type != None:
1410 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
1411 if ip_proto != None:
1412 match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
1413
1414 request = ofp.message.flow_add(
1415 table_id=60,
1416 cookie=42,
1417 match=match,
1418 instructions=[
1419 ofp.instruction.apply_actions(
1420 actions=[ofp.action.output(port=ofp.OFPP_CONTROLLER, max_len=ofp.OFPCML_NO_BUFFER)]
1421 ),
1422 ],
1423 buffer_id=ofp.OFP_NO_BUFFER,
1424 priority=1
1425 )
1426
1427 logging.info("Inserting ACL flow eth_type %lx, ip_proto %ld", eth_type, ip_proto)
1428 ctrl.message_send(request)
1429
1430 if send_barrier:
1431 do_barrier(ctrl)
1432
1433 return request
1434
macauley_cheng6b133662015-11-09 13:52:39 +08001435#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 +08001436def 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 +08001437 match = ofp.match()
1438 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
1439 match.oxm_list.append(ofp.oxm.ipv4_dst(ip_dst))
1440 match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
1441 match.oxm_list.append(ofp.oxm.tcp_dst(tcp_dst))
Pierbbdf3782016-08-22 17:58:26 -07001442
macauley_cheng6b133662015-11-09 13:52:39 +08001443 request = ofp.message.flow_add(
1444 table_id=28,
1445 cookie=42,
1446 match=match,
1447 instructions=[
1448 ofp.instruction.write_actions(
1449 actions=[ofp.action.set_field(ofp.oxm.ipv4_dst(set_ip_dst)),
1450 ofp.action.set_field(ofp.oxm.tcp_dst(set_tcp_dst)),
1451 ofp.action.group(action_group_id)]),
1452 ofp.instruction.goto_table(60)
1453 ],
1454 buffer_id=ofp.OFP_NO_BUFFER,
Pierbbdf3782016-08-22 17:58:26 -07001455 priority=1)
macauley_cheng6b133662015-11-09 13:52:39 +08001456 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)
1457 ctrl.message_send(request)
1458 return request
macauley_chengeffc20a2015-11-09 16:14:56 +08001459
1460#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
1461def add_snat_flow(ctrl, eth_type, ip_src, ip_proto, tcp_src, set_ip_src, set_tcp_src):
1462 match = ofp.match()
1463 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
1464 match.oxm_list.append(ofp.oxm.ipv4_src(ip_src))
1465 match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
1466 match.oxm_list.append(ofp.oxm.tcp_src(tcp_src))
Pierbbdf3782016-08-22 17:58:26 -07001467
macauley_chengeffc20a2015-11-09 16:14:56 +08001468 request = ofp.message.flow_add(
1469 table_id=29,
1470 cookie=42,
1471 match=match,
1472 instructions=[
1473 ofp.instruction.write_actions(
1474 actions=[ofp.action.set_field(ofp.oxm.ipv4_src(set_ip_src)),
1475 ofp.action.set_field(ofp.oxm.tcp_src(set_tcp_src))]),
1476 ofp.instruction.goto_table(30)
1477 ],
1478 buffer_id=ofp.OFP_NO_BUFFER,
Pierbbdf3782016-08-22 17:58:26 -07001479 priority=1)
macauley_chengeffc20a2015-11-09 16:14:56 +08001480 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)
1481 ctrl.message_send(request)
1482 return request
Pierbbdf3782016-08-22 17:58:26 -07001483
1484def get_vtap_lport_config_xml(dp_id, lport, phy_port, vlan, vnid, operation='merge'):
macauleyfddc4662015-07-27 17:40:30 +08001485 """
1486 Command Example:
1487 of-agent vtap 10001 ethernet 1/1 vid 1
1488 of-agent vtp 10001 vni 10
1489 """
1490 if vlan != 0:
1491 config_vtap_xml="""
1492 <config>
1493 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1494 <id>capable-switch-1</id>
1495 <resources>
1496 <port xc:operation="OPERATION">
Pierbbdf3782016-08-22 17:58:26 -07001497 <resource-id >LPORT</resource-id>
macauleyfddc4662015-07-27 17:40:30 +08001498 <features>
1499 <current>
1500 <rate>10Gb</rate>
1501 <medium>fiber</medium>
Pierbbdf3782016-08-22 17:58:26 -07001502 <pause>symmetric</pause>
macauleyfddc4662015-07-27 17:40:30 +08001503 </current>
1504 <advertised>
1505 <rate>10Gb</rate>
1506 <rate>100Gb</rate>
1507 <medium>fiber</medium>
1508 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001509 </advertised>
macauleyfddc4662015-07-27 17:40:30 +08001510 <supported>
1511 <rate>10Gb</rate>
1512 <rate>100Gb</rate>
1513 <medium>fiber</medium>
1514 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001515 </supported>
macauleyfddc4662015-07-27 17:40:30 +08001516 <advertised-peer>
1517 <rate>10Gb</rate>
1518 <rate>100Gb</rate>
1519 <medium>fiber</medium>
1520 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001521 </advertised-peer>
macauleyfddc4662015-07-27 17:40:30 +08001522 </features>
1523 <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1524 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
1525 <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
1526 <ofdpa10:vni>VNID</ofdpa10:vni>
1527 </ofdpa10:vtap>
Pierbbdf3782016-08-22 17:58:26 -07001528 </port>
macauleyfddc4662015-07-27 17:40:30 +08001529 </resources>
1530 <logical-switches>
1531 <switch>
1532 <id>DATAPATH_ID</id>
1533 <datapath-id>DATAPATH_ID</datapath-id>
1534 <resources>
1535 <port xc:operation="OPERATION">LPORT</port>
1536 </resources>
1537 </switch>
1538 </logical-switches>
1539 </capable-switch>
1540 </config>
Pierbbdf3782016-08-22 17:58:26 -07001541 """
macauleyfddc4662015-07-27 17:40:30 +08001542 else:
1543 config_vtap_xml="""
1544 <config>
1545 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1546 <id>capable-switch-1</id>
1547 <resources>
1548 <port xc:operation="OPERATION">
Pierbbdf3782016-08-22 17:58:26 -07001549 <resource-id >LPORT</resource-id>
macauleyfddc4662015-07-27 17:40:30 +08001550 <features>
1551 <current>
1552 <rate>10Gb</rate>
1553 <medium>fiber</medium>
Pierbbdf3782016-08-22 17:58:26 -07001554 <pause>symmetric</pause>
macauleyfddc4662015-07-27 17:40:30 +08001555 </current>
1556 <advertised>
1557 <rate>10Gb</rate>
1558 <rate>100Gb</rate>
1559 <medium>fiber</medium>
1560 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001561 </advertised>
macauleyfddc4662015-07-27 17:40:30 +08001562 <supported>
1563 <rate>10Gb</rate>
1564 <rate>100Gb</rate>
1565 <medium>fiber</medium>
1566 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001567 </supported>
macauleyfddc4662015-07-27 17:40:30 +08001568 <advertised-peer>
1569 <rate>10Gb</rate>
1570 <rate>100Gb</rate>
1571 <medium>fiber</medium>
1572 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001573 </advertised-peer>
macauleyfddc4662015-07-27 17:40:30 +08001574 </features>
1575 <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1576 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
1577 <ofdpa10:vni>VNID</ofdpa10:vni>
1578 </ofdpa10:vtap>
Pierbbdf3782016-08-22 17:58:26 -07001579 </port>
macauleyfddc4662015-07-27 17:40:30 +08001580 </resources>
1581 <logical-switches>
1582 <switch>
1583 <id>DATAPATH_ID</id>
1584 <datapath-id>DATAPATH_ID</datapath-id>
1585 <resources>
1586 <port xc:operation="OPERATION">LPORT</port>
1587 </resources>
1588 </switch>
1589 </logical-switches>
1590 </capable-switch>
1591 </config>
Pierbbdf3782016-08-22 17:58:26 -07001592 """
1593 str_datapath_id_f= "{:016x}".format(dp_id)
1594 str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
1595 config_vtap_xml=config_vtap_xml.replace("DATAPATH_ID", str_datapath_id)
1596 config_vtap_xml=config_vtap_xml.replace("LPORT", str(int(lport)))
1597 config_vtap_xml=config_vtap_xml.replace("PHY_PORT", str(phy_port))
1598 config_vtap_xml=config_vtap_xml.replace("VLAN_ID", str(vlan))
macauleyfddc4662015-07-27 17:40:30 +08001599 config_vtap_xml=config_vtap_xml.replace("VNID", str(vnid))
1600 config_vtap_xml=config_vtap_xml.replace("OPERATION", str(operation))
1601 return config_vtap_xml
Pierbbdf3782016-08-22 17:58:26 -07001602
1603def 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 +08001604 """
1605 Command Example:
1606 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 -07001607 of-agent vtp 10001 vni 10
macauleyfddc4662015-07-27 17:40:30 +08001608 """
1609
1610 config_vtep_xml="""
1611 <config>
1612 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1613 <id>capable-switch-1</id>
1614 <resources>
1615 <port xc:operation="OPERATION">
Pierbbdf3782016-08-22 17:58:26 -07001616 <resource-id>LPORT</resource-id>
macauleyfddc4662015-07-27 17:40:30 +08001617 <features>
1618 <current>
1619 <rate>10Gb</rate>
1620 <medium>fiber</medium>
Pierbbdf3782016-08-22 17:58:26 -07001621 <pause>symmetric</pause>
macauleyfddc4662015-07-27 17:40:30 +08001622 </current>
1623 <advertised>
1624 <rate>10Gb</rate>
1625 <rate>100Gb</rate>
1626 <medium>fiber</medium>
1627 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001628 </advertised>
macauleyfddc4662015-07-27 17:40:30 +08001629 <supported>
1630 <rate>10Gb</rate>
1631 <rate>100Gb</rate>
1632 <medium>fiber</medium>
1633 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001634 </supported>
macauleyfddc4662015-07-27 17:40:30 +08001635 <advertised-peer>
1636 <rate>10Gb</rate>
1637 <rate>100Gb</rate>
1638 <medium>fiber</medium>
1639 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001640 </advertised-peer>
macauleyfddc4662015-07-27 17:40:30 +08001641 </features>
Pier265ad5f2017-02-28 17:46:28 +01001642 <ofdpa10:vtep xmlns:ofdpa10="urn:bcm:ofdpa10:accton01">
1643 <ofdpa10:src-ip>SRC_IP</ofdpa10:src-ip>
1644 <ofdpa10:dest-ip>DST_IP</ofdpa10:dest-ip>
1645 <ofdpa10:udp-src-port>UDP_SRC_PORT</ofdpa10:udp-src-port>
1646 <ofdpa10:vni xc:operation="OPERATION">
macauley25999cf2015-08-07 17:03:24 +08001647 <ofdpa10:id>VNID</ofdpa10:id>
1648 </ofdpa10:vni>
Pier265ad5f2017-02-28 17:46:28 +01001649 <ofdpa10:nexthop-id>NEXT_HOP_ID</ofdpa10:nexthop-id>
1650 <ofdpa10:ttl>TTL</ofdpa10:ttl>
1651 </ofdpa10:vtep>
Pierbbdf3782016-08-22 17:58:26 -07001652 </port>
macauleyfddc4662015-07-27 17:40:30 +08001653 </resources>
1654 <logical-switches>
1655 <switch>
1656 <id>DATAPATH_ID</id>
1657 <datapath-id>DATAPATH_ID</datapath-id>
1658 <resources>
1659 <port xc:operation="OPERATION">LPORT</port>
1660 </resources>
1661 </switch>
1662 </logical-switches>
1663 </capable-switch>
Pierbbdf3782016-08-22 17:58:26 -07001664 </config>
macauleyfddc4662015-07-27 17:40:30 +08001665 """
Pierbbdf3782016-08-22 17:58:26 -07001666 str_datapath_id_f= "{:016x}".format(dp_id)
1667 str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
1668 config_vtep_xml=config_vtep_xml.replace("DATAPATH_ID", str_datapath_id)
macauley25999cf2015-08-07 17:03:24 +08001669 config_vtep_xml=config_vtep_xml.replace("LPORT", str(int(lport)))
Pierbbdf3782016-08-22 17:58:26 -07001670 config_vtep_xml=config_vtep_xml.replace("SRC_IP", str(src_ip))
1671 config_vtep_xml=config_vtep_xml.replace("DST_IP", str(dst_ip))
1672 config_vtep_xml=config_vtep_xml.replace("UDP_SRC_PORT", str(udp_src_port))
1673 config_vtep_xml=config_vtep_xml.replace("NEXT_HOP_ID", str(next_hop_id))
1674 config_vtep_xml=config_vtep_xml.replace("TTL", str(ttl))
macauleyfddc4662015-07-27 17:40:30 +08001675 config_vtep_xml=config_vtep_xml.replace("VNID", str(vnid))
Pierbbdf3782016-08-22 17:58:26 -07001676 config_vtep_xml=config_vtep_xml.replace("OPERATION", str(operation))
macauleyfddc4662015-07-27 17:40:30 +08001677
Pierbbdf3782016-08-22 17:58:26 -07001678 return config_vtep_xml
1679
1680def get_next_hop_config_xml(next_hop_id, dst_mac, phy_port, vlan, operation='merge'):
macauleyfddc4662015-07-27 17:40:30 +08001681 #of-agent nexthop 2 destination user-input-dst-mac ethernet 1/2 vid 2
1682 config_nexthop_xml="""
1683 <config>
1684 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1685 <ofdpa10:next-hop xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1686 <ofdpa10:id>NEXT_HOP_ID</ofdpa10:id>
1687 <ofdpa10:dest-mac>DST_MAC</ofdpa10:dest-mac>
1688 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
1689 <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
1690 </ofdpa10:next-hop>
1691 </of11-config:capable-switch>
1692 </config>
1693 """
1694 config_nexthop_xml=config_nexthop_xml.replace("VLAN_ID", str(vlan))
Pierbbdf3782016-08-22 17:58:26 -07001695 config_nexthop_xml=config_nexthop_xml.replace("PHY_PORT", str(phy_port))
1696 config_nexthop_xml=config_nexthop_xml.replace("NEXT_HOP_ID", str(next_hop_id))
1697 config_nexthop_xml=config_nexthop_xml.replace("DST_MAC", str(dst_mac))
1698 config_nexthop_xml=config_nexthop_xml.replace("OPERATION", str(operation))
1699 return config_nexthop_xml
macauleyfddc4662015-07-27 17:40:30 +08001700
Pierbbdf3782016-08-22 17:58:26 -07001701def get_vni_config_xml(vni_id, mcast_ipv4, next_hop_id, operation='merge'):
macauleyfddc4662015-07-27 17:40:30 +08001702 #of-agent vni 10 multicast 224.1.1.1 nexthop 20
Pierbbdf3782016-08-22 17:58:26 -07001703 if mcast_ipv4!=None:
macauleyfddc4662015-07-27 17:40:30 +08001704 config_vni_xml="""
1705 <config>
1706 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1707 <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1708 <ofdpa10:id>VNID</ofdpa10:id>
1709 <ofdpa10:vni-multicast-group>MCAST_IP</ofdpa10:vni-multicast-group>
1710 <ofdpa10:multicast-group-nexthop-id>NEXT_HOP_ID</ofdpa10:multicast-group-nexthop-id>
1711 </ofdpa10:vni>
1712 </of11-config:capable-switch>
1713 </config>
Pierbbdf3782016-08-22 17:58:26 -07001714 """
1715 config_vni_xml=config_vni_xml.replace("NEXT_HOP_ID", str(next_hop_id))
1716 config_vni_xml=config_vni_xml.replace("MCAST_IP", str(mcast_ipv4))
macauleyfddc4662015-07-27 17:40:30 +08001717 else:
1718 config_vni_xml="""
1719 <config>
1720 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1721 <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1722 <ofdpa10:id>VNID</ofdpa10:id>
1723 </ofdpa10:vni>
1724 </of11-config:capable-switch>
1725 </config>
Pierbbdf3782016-08-22 17:58:26 -07001726 """
1727
1728 config_vni_xml=config_vni_xml.replace("VNID", str(vni_id))
1729 config_vni_xml=config_vni_xml.replace("OPERATION", str(operation))
macauleyfddc4662015-07-27 17:40:30 +08001730 return config_vni_xml
Pierbbdf3782016-08-22 17:58:26 -07001731
1732def get_featureReplay(self):
macauleyfddc4662015-07-27 17:40:30 +08001733 req = ofp.message.features_request()
1734 res, raw = self.controller.transact(req)
Pierbbdf3782016-08-22 17:58:26 -07001735 self.assertIsNotNone(res, "Did not receive a response from the DUT.")
macauleyfddc4662015-07-27 17:40:30 +08001736 self.assertEqual(res.type, ofp.OFPT_FEATURES_REPLY,
1737 ("Unexpected packet type %d received in response to "
1738 "OFPT_FEATURES_REQUEST") % res.type)
Pierbbdf3782016-08-22 17:58:26 -07001739 return res
1740
macauleyfddc4662015-07-27 17:40:30 +08001741def send_edit_config(switch_ip, xml, target='runing'):
1742 NETCONF_ACCOUNT="netconfuser"
1743 NETCONF_PASSWD="netconfuser"
1744 with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
1745 try:
Pierbbdf3782016-08-22 17:58:26 -07001746 m.edit_config(target='running',
1747 config=xml,
1748 default_operation='merge',
macauleyfddc4662015-07-27 17:40:30 +08001749 error_option='stop-on-error')
1750
1751 except Exception as e:
1752 logging.info("Fail to set xml %s", xml)
1753 return False
1754
Pier265ad5f2017-02-28 17:46:28 +01001755 #return m.get_config(source='running').data_xml
macauleyfddc4662015-07-27 17:40:30 +08001756 return True
1757
1758def send_delete_config(switch_ip, xml, target='runing'):
1759 NETCONF_ACCOUNT="netconfuser"
1760 NETCONF_PASSWD="netconfuser"
1761 with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
1762 try:
Pierbbdf3782016-08-22 17:58:26 -07001763 m.edit_config(target='running',
1764 config=xml,
1765 default_operation='delete',
macauleyfddc4662015-07-27 17:40:30 +08001766 error_option='stop-on-error')
1767
1768 except Exception as e:
1769 logging.info("Fail to set xml %s", xml)
1770 return False
1771
Pier265ad5f2017-02-28 17:46:28 +01001772 #return m.get_config(source='running').data_xml
macauleyfddc4662015-07-27 17:40:30 +08001773 return True
Pierbbdf3782016-08-22 17:58:26 -07001774
macauleyfddc4662015-07-27 17:40:30 +08001775def get_edit_config(switch_ip, target='runing'):
1776 NETCONF_ACCOUNT="netconfuser"
1777 NETCONF_PASSWD="netconfuser"
1778 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 +01001779 return m.get_config(source='running').data_xml
macauleydbff3272015-07-30 14:07:16 +08001780
macauley_cheng67da9262015-08-31 15:18:41 +08001781
1782"""
1783MPLS
1784"""
1785
1786OFDPA_MPLS_SUBTYPE_SHIFT=24
Pierbbdf3782016-08-22 17:58:26 -07001787OFDPA_MPLS_GROUP_SUBTYPE_L2_VPN_LABEL=1
macauley_cheng67da9262015-08-31 15:18:41 +08001788OFDPA_MPLS_GROUP_SUBTYPE_L3_VPN_LABEL=2
1789OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL1=3
1790OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL2=4
1791OFDPA_MPLS_GROUP_SUBTYPE_SWAP_LABEL=5
1792OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP=6
1793OFDPA_MPLS_GROUP_SUBTYPE_ECMP=8
1794OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG=10
1795
Piercf76e802016-09-19 20:16:35 -07001796
1797
1798
macauley_cheng67da9262015-08-31 15:18:41 +08001799def encode_mpls_interface_group_id(subtype, index):
1800 index=index&0x00ffffff
1801 assert(subtype==0)
1802 return index + (9 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
1803
1804def encode_mpls_label_group_id(subtype, index):
1805 index=index&0x00ffffff
1806 assert(subtype <=5 or subtype==0)
1807 #1: l2 vpn label
1808 #2: l3 vpn label
1809 #3: mpls tunnel label 1
1810 #4: mpls tunnel lable 2
1811 #5: mpls swap label
Pierbbdf3782016-08-22 17:58:26 -07001812 return index + (9 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
macauley_cheng67da9262015-08-31 15:18:41 +08001813
1814def encode_mpls_forwarding_group_id(subtype, index):
1815 index=index&0x00ffffff
1816 assert(subtype==6 or subtype==8 or subtype==10)
Pierbbdf3782016-08-22 17:58:26 -07001817 return index + (10 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
macauley_cheng67da9262015-08-31 15:18:41 +08001818
1819
Pier1e4e98e2016-10-26 14:36:05 -07001820def 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 +08001821 action=[]
1822 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
1823 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
Pier265ad5f2017-02-28 17:46:28 +01001824 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vid)))
macauley_cheng67da9262015-08-31 15:18:41 +08001825 action.append(ofp.action.group(ref_gid))
Pierbbdf3782016-08-22 17:58:26 -07001826
macauley_cheng67da9262015-08-31 15:18:41 +08001827 buckets = [ofp.bucket(actions=action)]
1828
1829 mpls_group_id =encode_mpls_interface_group_id(subtype, index)
1830 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
1831 group_id=mpls_group_id,
1832 buckets=buckets
1833 )
Andreas Pantelopoulos6c76b942018-01-22 10:03:02 -08001834
1835 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 +08001836 ctrl.message_send(request)
Pier1e4e98e2016-10-26 14:36:05 -07001837
1838 if send_barrier:
1839 do_barrier(ctrl)
macauley_cheng67da9262015-08-31 15:18:41 +08001840 return mpls_group_id, request
1841
Piercf76e802016-09-19 20:16:35 -07001842def add_mpls_tunnel_label_group(
1843 ctrl,
1844 ref_gid,
1845 subtype,
1846 index,
1847 label,
1848 ):
1849
1850 action=[]
1851 action.append(ofp.action.push_mpls(0x8847))
1852 action.append(ofp.action.set_field(ofp.oxm.mpls_label(label)))
1853 action.append(ofp.action.group(ref_gid))
1854 buckets = [ofp.bucket(actions=action)]
1855
1856 mpls_group_id = encode_mpls_label_group_id(subtype, index)
1857 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
1858 group_id=mpls_group_id,
1859 buckets=buckets
1860 )
1861 ctrl.message_send(request)
1862
1863 return mpls_group_id, request
1864
Pierb5da4c92016-09-21 11:23:35 -07001865def add_mpls_swap_label_group(
1866 ctrl,
1867 ref_gid,
1868 subtype,
1869 index,
1870 label,
1871 ):
1872
1873 action=[]
1874 action.append(ofp.action.set_field(ofp.oxm.mpls_label(label)))
1875 action.append(ofp.action.group(ref_gid))
1876 buckets = [ofp.bucket(actions=action)]
1877
1878 mpls_group_id = encode_mpls_label_group_id(subtype, index)
1879 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
1880 group_id=mpls_group_id,
1881 buckets=buckets
1882 )
Andreas Pantelopoulos6c76b942018-01-22 10:03:02 -08001883 logging.debug("Adding MPLS Swap group %02x, label %d", mpls_group_id, label)
Pierb5da4c92016-09-21 11:23:35 -07001884 ctrl.message_send(request)
1885
1886 return mpls_group_id, request
1887
Pierbbdf3782016-08-22 17:58:26 -07001888def add_mpls_label_group(ctrl, subtype, index, ref_gid,
macauley_cheng67da9262015-08-31 15:18:41 +08001889 lmep_id=-1,
1890 qos_index=-1,
1891 push_l2_header=False,
1892 push_vlan=False,
1893 push_mpls_header=False,
1894 push_cw=False,
1895 set_mpls_label=None,
1896 set_bos=None,
1897 set_tc=None,
1898 set_tc_from_table=False,
1899 cpy_tc_outward=False,
1900 set_ttl=None,
1901 cpy_ttl_outward=False,
1902 oam_lm_tx_count=False,
Pier1e4e98e2016-10-26 14:36:05 -07001903 set_pri_from_table=False,
1904 send_barrier=False
macauley_cheng67da9262015-08-31 15:18:41 +08001905 ):
1906 """
1907 @ref_gid: only can be mpls intf group or mpls tunnel label 1/2 group
Pierbbdf3782016-08-22 17:58:26 -07001908 """
macauley_cheng67da9262015-08-31 15:18:41 +08001909 action=[]
1910
1911 if push_vlan== True:
1912 action.append(ofp.action.push_vlan(0x8100))
1913 if push_mpls_header== True:
1914 action.append(ofp.action.push_mpls(0x8847))
1915 if set_mpls_label != None:
1916 action.append(ofp.action.set_field(ofp.oxm.mpls_label(set_mpls_label)))
1917 if set_bos != None:
1918 action.append(ofp.action.set_field(ofp.oxm.mpls_bos(set_bos)))
1919 if set_tc != None:
1920 assert(set_tc_from_table==False)
1921 action.append(ofp.action.set_field(ofp.oxm.mpls_tc(set_tc)))
1922 if set_ttl != None:
Pierbbdf3782016-08-22 17:58:26 -07001923 action.append(ofp.action.set_mpls_ttl(set_ttl))
macauley_cheng67da9262015-08-31 15:18:41 +08001924 if cpy_ttl_outward == True:
Pierbbdf3782016-08-22 17:58:26 -07001925 action.append(ofp.action.copy_ttl_out())
macauley_cheng67da9262015-08-31 15:18:41 +08001926 """
1927 ofdpa experimenter
Pierbbdf3782016-08-22 17:58:26 -07001928 """
macauley_cheng67da9262015-08-31 15:18:41 +08001929 if push_l2_header== True:
Pierbbdf3782016-08-22 17:58:26 -07001930 action.append(ofp.action.ofdpa_push_l2_header())
macauley_cheng67da9262015-08-31 15:18:41 +08001931 if set_tc_from_table== True:
1932 assert(qos_index>=0)
1933 assert(set_tc == None)
Pierbbdf3782016-08-22 17:58:26 -07001934 action.append(ofp.action.ofdpa_set_tc_from_table(qos_index))
macauley_cheng67da9262015-08-31 15:18:41 +08001935 if cpy_tc_outward == True:
Pierbbdf3782016-08-22 17:58:26 -07001936 action.append(ofp.action.ofdpa_copy_tc_out())
macauley_cheng67da9262015-08-31 15:18:41 +08001937 if oam_lm_tx_count == True:
Pierbbdf3782016-08-22 17:58:26 -07001938 assert(qos_index>=0 and lmep_id>=0)
1939 action.append(ofp.action.ofdpa_oam_lm_tx_count(lmep_id, qos_index))
macauley_cheng67da9262015-08-31 15:18:41 +08001940 if set_pri_from_table == True:
Pierbbdf3782016-08-22 17:58:26 -07001941 assert(qos_index>=0)
1942 action.append(ofp.action.ofdpa_set_qos_from_table(qos_index))
macauley_cheng67da9262015-08-31 15:18:41 +08001943 if push_cw == True:
1944 action.append(ofp.action.ofdpa_push_cw())
Pierbbdf3782016-08-22 17:58:26 -07001945
1946 action.append(ofp.action.group(ref_gid))
macauley_cheng67da9262015-08-31 15:18:41 +08001947 buckets = [ofp.bucket(actions=action)]
Pierbbdf3782016-08-22 17:58:26 -07001948
macauley_cheng67da9262015-08-31 15:18:41 +08001949 mpls_group_id = encode_mpls_label_group_id(subtype, index)
1950 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
1951 group_id=mpls_group_id,
1952 buckets=buckets
1953 )
1954 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -07001955
Pier1e4e98e2016-10-26 14:36:05 -07001956 if send_barrier:
1957 do_barrier(ctrl)
1958
Pierbbdf3782016-08-22 17:58:26 -07001959 return mpls_group_id, request
1960
Piercf76e802016-09-19 20:16:35 -07001961def add_mpls_l2_port_flow(ctrl, of_port, mpls_l2_port, tunnel_index, ref_gid, qos_index=0):
1962 """
1963 Only action is Group, which must indicate one of:
1964 MPLS L2 VPN Label or Fast Failover Protection Group.
1965 ref_gid contains this information
1966 """
1967 tunnel_id = tunnel_index + ofp.oxm.TUNNEL_ID_BASE
1968
1969 match = ofp.match()
1970 match.oxm_list.append(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port))
1971 match.oxm_list.append(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE))
1972
Pier23784aa2016-09-19 20:08:21 -07001973
Pier265ad5f2017-02-28 17:46:28 +01001974 write_actions = []
1975 write_actions.append(ofp.action.group(ref_gid))
1976 apply_actions = []
Piercf76e802016-09-19 20:16:35 -07001977 assert(qos_index>=0)
Pier265ad5f2017-02-28 17:46:28 +01001978 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 -07001979
1980 request = ofp.message.flow_add(
1981 table_id=MPLS_L2_PORT_FLOW_TABLE,
1982 cookie=42,
1983 match=match,
1984 instructions=[
Pier265ad5f2017-02-28 17:46:28 +01001985 ofp.instruction.apply_actions(actions=apply_actions),
1986 ofp.instruction.write_actions(actions=write_actions),
1987 ofp.instruction.goto_table(MPLS_L2_PORT_PCP_TRUST_FLOW_TABLE)
1988 ],
Piercf76e802016-09-19 20:16:35 -07001989 buffer_id=ofp.OFP_NO_BUFFER,
1990 priority=1)
1991 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)
1992 ctrl.message_send(request)
1993 return request
1994
1995 return
1996
Pierbbdf3782016-08-22 17:58:26 -07001997def add_mpls_forwarding_group(ctrl, subtype, index, ref_gids,
1998 watch_port=None,
Pier265ad5f2017-02-28 17:46:28 +01001999 watch_group=ofp.OFPP_ANY,
2000 push_vlan=None,
macauley_chengd17ce512015-08-31 17:45:51 +08002001 pop_vlan=None,
macauley_cheng67da9262015-08-31 15:18:41 +08002002 set_vid=None):
2003 assert(subtype == OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP
Pier265ad5f2017-02-28 17:46:28 +01002004 or subtype == OFDPA_MPLS_GROUP_SUBTYPE_ECMP
2005 or subtype == OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG)
macauley_chengd17ce512015-08-31 17:45:51 +08002006
macauley_cheng67da9262015-08-31 15:18:41 +08002007 buckets=[]
2008 if subtype == OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP:
macauley_chengd17ce512015-08-31 17:45:51 +08002009 group_type = ofp.OFPGT_FF
macauley_cheng67da9262015-08-31 15:18:41 +08002010 for gid in ref_gids:
macauley_chengd17ce512015-08-31 17:45:51 +08002011 action=[]
Pierbbdf3782016-08-22 17:58:26 -07002012 action.append(ofp.action.group(gid))
macauley_chengd17ce512015-08-31 17:45:51 +08002013 buckets.append(ofp.bucket(watch_port=watch_port, watch_group=watch_group,actions=action))
2014
macauley_cheng67da9262015-08-31 15:18:41 +08002015 elif subtype == OFDPA_MPLS_GROUP_SUBTYPE_ECMP:
2016 group_type = ofp.OFPGT_SELECT
2017 for gid in ref_gids:
macauley_chengd17ce512015-08-31 17:45:51 +08002018 action=[]
Pierbbdf3782016-08-22 17:58:26 -07002019 action.append(ofp.action.group(gid))
macauley_cheng67da9262015-08-31 15:18:41 +08002020 buckets.append(ofp.bucket(actions=action))
macauley_chengd17ce512015-08-31 17:45:51 +08002021
macauley_cheng67da9262015-08-31 15:18:41 +08002022 elif subtype == OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG:
2023 group_type = ofp.OFPGT_INDIRECT
macauley_chengd17ce512015-08-31 17:45:51 +08002024 action=[]
macauley_cheng67da9262015-08-31 15:18:41 +08002025 if set_vid!=None:
Flavio Castro91d1a552016-05-17 16:59:44 -07002026 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+set_vid)))
macauley_cheng67da9262015-08-31 15:18:41 +08002027 if push_vlan!=None:
Pierbbdf3782016-08-22 17:58:26 -07002028 action.append(ofp.action.push_vlan(push_vlan))
macauley_cheng67da9262015-08-31 15:18:41 +08002029 if pop_vlan!=None:
Pierbbdf3782016-08-22 17:58:26 -07002030 action.append(ofp.action.pop_vlan())
2031 action.append(ofp.action.group(ref_gids[0]))
macauley_cheng67da9262015-08-31 15:18:41 +08002032 buckets.append(ofp.bucket(actions=action))
macauley_chengd17ce512015-08-31 17:45:51 +08002033
2034 mpls_group_id = encode_mpls_forwarding_group_id(subtype, index)
macauley_cheng67da9262015-08-31 15:18:41 +08002035 request = ofp.message.group_add(group_type=group_type,
macauley_cheng67da9262015-08-31 15:18:41 +08002036 group_id=mpls_group_id,
2037 buckets=buckets
2038 )
2039 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -07002040 return mpls_group_id, request
macauley_chengd17ce512015-08-31 17:45:51 +08002041
Jonghwan Hyunff0dfd52018-03-20 15:04:35 -07002042def add_one_egress_vlan_tpid_table_flow(ctrl, of_port):
2043 # Used for changing ethertype of outer vlan header to 0x88a8
2044
2045 match = ofp.match()
2046 match.oxm_list.append(ofp.oxm.exp4ByteValue(ofp.oxm.OFDPA_EXP_TYPE_ACTSET_OUTPUT, of_port, ONF_EXPERIMENTER_ID))
2047 match.oxm_list.append(ofp.oxm.vlan_vid_masked(ofp.OFPVID_PRESENT, ofp.OFPVID_PRESENT))
2048
2049 actions = []
2050 actions.append(ofp.action.copy_field(
2051 12, 0, 0, ['\x80\x00\x0c\x02', ofp.oxm.exp4ByteReg(oxm_field = 1).pack()])) # VLAN_VID, PACKET_REG(1)
2052 actions.append(ofp.action.pop_vlan())
2053 actions.append(ofp.action.push_vlan(0x88a8))
2054 actions.append(ofp.action.copy_field(
2055 12, 0, 0, [ofp.oxm.exp4ByteReg(oxm_field = 1).pack(), '\x80\x00\x0c\x02'])) # PACKET_REG(1), VLAN_VID
2056
2057 request = ofp.message.flow_add(
2058 table_id=EGRESS_TPID_FLOW_TABLE,
2059 cookie=42,
2060 match=match,
2061 instructions=[
2062 ofp.instruction.apply_actions(
2063 actions=actions
2064 ),
2065 ],
2066 priority=0)
2067
2068 ctrl.message_send(request)
2069
2070 return
macauley_chengd17ce512015-08-31 17:45:51 +08002071
macauley_cheng67da9262015-08-31 15:18:41 +08002072"""
Piercf76e802016-09-19 20:16:35 -07002073display
Pierbbdf3782016-08-22 17:58:26 -07002074"""
macauleydbff3272015-07-30 14:07:16 +08002075def print_current_table_flow_stat(ctrl, table_id=0xff):
2076 stat_req=ofp.message.flow_stats_request()
2077 response, pkt = ctrl.transact(stat_req)
2078 if response == None:
2079 print "no response"
2080 return None
2081 print len(response.entries)
2082 for obj in response.entries:
2083 print "match ", obj.match
2084 print "cookie", obj.cookie
2085 print "priority", obj.priority
2086 print "idle_timeout", obj.idle_timeout
2087 print "hard_timeout", obj.hard_timeout
2088 #obj.actions
Flavio Castro167f5bd2015-12-02 19:33:53 -05002089 print "packet count: %lx"%obj.packet_count