blob: ac729a45d57609d2fbf67613ed076f55f6d1438f [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
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
54
55def convertIP4toStr(ip_addr):
56 a=(ip_addr&0xff000000)>>24
57 b=(ip_addr&0x00ff0000)>>16
58 c=(ip_addr&0x0000ff00)>>8
59 d=(ip_addr&0x000000ff)
60 return str(a)+"."+str(b)+"."+str(c)+"."+str(d)
61
62def convertMACtoStr(mac):
63 if not isinstance(mac, list):
64 assert(0)
65
66 return ':'.join(['%02X' % x for x in mac])
67
macauley7f89d962015-08-06 18:13:48 +080068def getSwitchCpuMACFromDPID(dpid):
69 str_datapath_id_f= "{:016x}".format(dpid)
70 str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
71 switch_cpu_mac_str=str_datapath_id[6:]
72 switch_cpu_mac = switch_cpu_mac_str.split(":")
73 switch_cpu_mac=[int(switch_cpu_mac[i],16) for i in range(0, len(switch_cpu_mac))]
74
75 return switch_cpu_mac_str, switch_cpu_mac
Pierbbdf3782016-08-22 17:58:26 -070076
macauley_cheng67da9262015-08-31 15:18:41 +080077def DumpGroup(stats, verify_group_stats, always_show=True):
78 if(len(stats) > len(verify_group_stats)):
79 min_len = len(verify_group_stats)
80 print "Stats Len is not the same, stats>verify_group_stats"
81 if(len(stats)< len(verify_group_stats)):
Pierbbdf3782016-08-22 17:58:26 -070082 min_len = len(stats)
macauley_cheng67da9262015-08-31 15:18:41 +080083 print "Stats Len is not the same, stats<verify_group_stats"
Pierbbdf3782016-08-22 17:58:26 -070084 else:
macauley_cheng67da9262015-08-31 15:18:41 +080085 min_len = len(stats)
macauleye8b140e2015-08-03 13:35:45 +080086
macauley_cheng67da9262015-08-31 15:18:41 +080087 print "\r\n"
88 for i in range(min_len):
89 gs = stats[i]
Pierbbdf3782016-08-22 17:58:26 -070090 gv = verify_group_stats[i]
macauley_cheng67da9262015-08-31 15:18:41 +080091 print "FromSwtich:(GID=%lx, TYPE=%lx)\r\nVerify :(GID=%lx, TYPE=%lx)"%(gs.group_id, gs.group_type, gv.group_id, gv.group_type)
92 if(len(gs.buckets) != len(gv.buckets)):
93 print "buckets len is not the same gs %lx, gv %lx",(len(gs.buckets), len(gv.buckets))
94
95 for j in range(len(gs.buckets)):
96 b1=gs.buckets[j]
Pierbbdf3782016-08-22 17:58:26 -070097 b2=gv.buckets[j]
macauley_cheng67da9262015-08-31 15:18:41 +080098 if(len(b1.actions) != len(b2.actions)):
99 print "action len is not the same"
100
101 for k in range(len(b1.actions)):
102 a1=b1.actions[k]
103 a2=b2.actions[k]
104 if(always_show == True):
105 print "a1:"+a1.show()
Pierbbdf3782016-08-22 17:58:26 -0700106 print "a2:"+a2.show()
macauley_cheng67da9262015-08-31 15:18:41 +0800107
108def AssertGroup(self, stats, verify_group_stats):
109 self.assertTrue(len(stats) ==len(verify_group_stats), "stats len is not the same")
110
111 for i in range(len(stats)):
112 gs = stats[i]
Pierbbdf3782016-08-22 17:58:26 -0700113 gv = verify_group_stats[i]
macauley_cheng67da9262015-08-31 15:18:41 +0800114 self.assertTrue(len(gs.buckets) == len(gv.buckets), "buckets len is not the same")
115
116 for j in range(len(gs.buckets)):
117 b1=gs.buckets[j]
Pierbbdf3782016-08-22 17:58:26 -0700118 b2=gv.buckets[j]
macauley_cheng67da9262015-08-31 15:18:41 +0800119 self.assertTrue(len(b1.actions) == len(b2.actions), "action len is not the same")
120
121 for k in range(len(b1.actions)):
122 a1=b1.actions[k]
123 a2=b2.actions[k]
124 self.assertEquals(a1, a2, "action is not the same")
Pierbbdf3782016-08-22 17:58:26 -0700125
macauley97557232015-07-16 17:28:07 +0800126def encode_l2_interface_group_id(vlan, id):
127 return id + (vlan << OFDPA_VLAN_ID_SHIFT)
128
129def encode_l2_rewrite_group_id(id):
130 return id + (1 << OFDPA_GROUP_TYPE_SHIFT)
131
132def encode_l3_unicast_group_id(id):
133 return id + (2 << OFDPA_GROUP_TYPE_SHIFT)
134
135def encode_l2_mcast_group_id(vlan, id):
136 return id + (vlan << OFDPA_VLAN_ID_SHIFT) + (3 << OFDPA_GROUP_TYPE_SHIFT)
137
138def encode_l2_flood_group_id(vlan, id):
139 return id + (vlan << OFDPA_VLAN_ID_SHIFT) + (4 << OFDPA_GROUP_TYPE_SHIFT)
Pierbbdf3782016-08-22 17:58:26 -0700140
macauley97557232015-07-16 17:28:07 +0800141def encode_l3_interface_group_id(id):
142 return id + (5 << OFDPA_GROUP_TYPE_SHIFT)
143
144def encode_l3_mcast_group_id(vlan, id):
145 return id + (vlan << OFDPA_VLAN_ID_SHIFT)+(6 << OFDPA_GROUP_TYPE_SHIFT)
146
147def encode_l3_ecmp_group_id(id):
148 return id + (7 << OFDPA_GROUP_TYPE_SHIFT)
149
Flavio Castro91d1a552016-05-17 16:59:44 -0700150def encode_l2_unfiltered_group_id(id):
151 return id + (11 << OFDPA_GROUP_TYPE_SHIFT)
152
macauleyfddc4662015-07-27 17:40:30 +0800153def encode_l2_overlay_group_id(tunnel_id, subtype, index):
154 tunnel_id=tunnel_id&0xffff #16 bits
155 subtype = subtype&3 #2 bits
156 index = index & 0x3f #10 bits
157 return index + (tunnel_id << OFDPA_TUNNEL_ID_SHIFT)+ (subtype<<OFDPA_TUNNEL_SUBTYPE_SHIFT)+(8 << OFDPA_GROUP_TYPE_SHIFT)
macauley97557232015-07-16 17:28:07 +0800158
Flavio Castro91d1a552016-05-17 16:59:44 -0700159def add_l2_unfiltered_group(ctrl, ports, send_barrier=False):
160 # group table
161 # set up untag groups for each port
162 group_id_list=[]
163 msgs=[]
164 for of_port in ports:
165 # do stuff
166 group_id = encode_l2_unfiltered_group_id(of_port)
167 group_id_list.append(group_id)
168 actions = [ofp.action.output(of_port)]
169 actions.append(ofp.action.set_field(ofp.oxm.exp1ByteValue(exp_type=24, value=1)))
170
171 buckets = [ofp.bucket(actions=actions)]
172 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
173 group_id=group_id,
174 buckets=buckets
175 )
176 ctrl.message_send(request)
177 msgs.append(request)
178
179 if send_barrier:
180 do_barrier(ctrl)
181
182 return group_id_list, msgs
183
Pierf6f28162016-09-22 16:30:52 -0700184def add_one_l2_unfiltered_group(ctrl, of_port, send_barrier=False):
185 # group table
186 # set up untag groups for each port
187 group_id = encode_l2_unfiltered_group_id(of_port)
188 actions = [ofp.action.output(of_port)]
189 actions.append(ofp.action.set_field(ofp.oxm.exp1ByteValue(exp_type=24, value=1)))
190
191 buckets = [ofp.bucket(actions=actions)]
192 request = ofp.message.group_add(
193 group_type=ofp.OFPGT_INDIRECT,
194 group_id=group_id,
195 buckets=buckets
196 )
197 ctrl.message_send(request)
198
199 if send_barrier:
200 do_barrier(ctrl)
201
202 return group_id, request
203
Flavio Castrod4c44d12015-12-08 14:44:18 -0500204def add_l2_interface_group(ctrl, ports, vlan_id=1, is_tagged=False, send_barrier=False):
macauley97557232015-07-16 17:28:07 +0800205 # group table
206 # set up untag groups for each port
macauley41904ed2015-07-16 17:38:35 +0800207 group_id_list=[]
macauley15909e72015-07-17 15:58:57 +0800208 msgs=[]
macauley97557232015-07-16 17:28:07 +0800209 for of_port in ports:
210 # do stuff
211 group_id = encode_l2_interface_group_id(vlan_id, of_port)
macauley41904ed2015-07-16 17:38:35 +0800212 group_id_list.append(group_id)
macauley97557232015-07-16 17:28:07 +0800213 if is_tagged:
214 actions = [
215 ofp.action.output(of_port),
Pierbbdf3782016-08-22 17:58:26 -0700216 ]
macauley97557232015-07-16 17:28:07 +0800217 else:
218 actions = [
219 ofp.action.pop_vlan(),
220 ofp.action.output(of_port),
221 ]
222
223 buckets = [
224 ofp.bucket(actions=actions),
225 ]
226
227 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
228 group_id=group_id,
229 buckets=buckets
230 )
231 ctrl.message_send(request)
macauley15909e72015-07-17 15:58:57 +0800232 msgs.append(request)
macauley97557232015-07-16 17:28:07 +0800233
234 if send_barrier:
235 do_barrier(ctrl)
Pierbbdf3782016-08-22 17:58:26 -0700236
macauley15909e72015-07-17 15:58:57 +0800237 return group_id_list, msgs
macauley97557232015-07-16 17:28:07 +0800238
Flavio Castrod4c44d12015-12-08 14:44:18 -0500239def add_one_l2_interface_group(ctrl, port, vlan_id=1, is_tagged=False, send_barrier=False):
macauley0f91a3e2015-07-17 18:09:59 +0800240 # group table
241 # set up untag groups for each port
242 group_id = encode_l2_interface_group_id(vlan_id, port)
243
244 if is_tagged:
245 actions = [
246 ofp.action.output(port),
Pierbbdf3782016-08-22 17:58:26 -0700247 ]
macauley0f91a3e2015-07-17 18:09:59 +0800248 else:
249 actions = [
250 ofp.action.pop_vlan(),
251 ofp.action.output(port),
252 ]
253
254 buckets = [
255 ofp.bucket(actions=actions),
256 ]
257
258 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
259 group_id=group_id,
260 buckets=buckets
261 )
262 ctrl.message_send(request)
263
264 if send_barrier:
265 do_barrier(ctrl)
Pierbbdf3782016-08-22 17:58:26 -0700266
macauley0f91a3e2015-07-17 18:09:59 +0800267 return group_id, request
Pierbbdf3782016-08-22 17:58:26 -0700268
macauley97557232015-07-16 17:28:07 +0800269def add_l2_mcast_group(ctrl, ports, vlanid, mcast_grp_index):
270 buckets=[]
271 for of_port in ports:
272 group_id = encode_l2_interface_group_id(vlanid, of_port)
273 action=[ofp.action.group(group_id)]
274 buckets.append(ofp.bucket(actions=action))
275
276 group_id =encode_l2_mcast_group_id(vlanid, mcast_grp_index)
277 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
278 group_id=group_id,
279 buckets=buckets
280 )
281 ctrl.message_send(request)
macauley15909e72015-07-17 15:58:57 +0800282 return request
macauley97557232015-07-16 17:28:07 +0800283
macauley15909e72015-07-17 15:58:57 +0800284def add_l2_flood_group(ctrl, ports, vlanid, id):
285 buckets=[]
286 for of_port in ports:
287 group_id = encode_l2_interface_group_id(vlanid, of_port)
288 action=[ofp.action.group(group_id)]
289 buckets.append(ofp.bucket(actions=action))
macauley97557232015-07-16 17:28:07 +0800290
macauley15909e72015-07-17 15:58:57 +0800291 group_id =encode_l2_flood_group_id(vlanid, id)
292 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
293 group_id=group_id,
294 buckets=buckets
295 )
296 ctrl.message_send(request)
297 return request
298
Flavio Castroa7162bb2016-07-25 17:30:30 -0700299def mod_l2_flood_group(ctrl, ports, vlanid, id):
300 buckets=[]
301 for of_port in ports:
302 group_id = encode_l2_interface_group_id(vlanid, of_port)
303 action=[ofp.action.group(group_id)]
304 buckets.append(ofp.bucket(actions=action))
305
306 group_id =encode_l2_flood_group_id(vlanid, id)
307 request = ofp.message.group_modify(group_type=ofp.OFPGT_ALL,
308 group_id=group_id,
309 buckets=buckets
310 )
311 ctrl.message_send(request)
312 return request
313
314
macauley15909e72015-07-17 15:58:57 +0800315def add_l2_rewrite_group(ctrl, port, vlanid, id, src_mac, dst_mac):
316 group_id = encode_l2_interface_group_id(vlanid, port)
317
318 action=[]
319 if src_mac is not None:
320 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
321
322 if dst_mac is not None:
323 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
324
Flavio Castro91d1a552016-05-17 16:59:44 -0700325 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlanid)))
Pierbbdf3782016-08-22 17:58:26 -0700326
macauley15909e72015-07-17 15:58:57 +0800327 action.append(ofp.action.group(group_id))
Pierbbdf3782016-08-22 17:58:26 -0700328
macauley15909e72015-07-17 15:58:57 +0800329 buckets = [ofp.bucket(actions=action)]
330
331 group_id =encode_l2_rewrite_group_id(id)
332 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
333 group_id=group_id,
334 buckets=buckets
335 )
336 ctrl.message_send(request)
337 return request
Pierbbdf3782016-08-22 17:58:26 -0700338
Pier1e4e98e2016-10-26 14:36:05 -0700339def add_l3_unicast_group(ctrl, port, vlanid, id, src_mac, dst_mac, send_barrier=False):
macauley15909e72015-07-17 15:58:57 +0800340 group_id = encode_l2_interface_group_id(vlanid, port)
341
342 action=[]
343 if src_mac is not None:
344 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
345
346 if dst_mac is not None:
347 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
348
Flavio Castroaf2b4502016-02-02 17:41:32 -0500349 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlanid)))
Pierbbdf3782016-08-22 17:58:26 -0700350
macauley15909e72015-07-17 15:58:57 +0800351 action.append(ofp.action.group(group_id))
Pierbbdf3782016-08-22 17:58:26 -0700352
macauley15909e72015-07-17 15:58:57 +0800353 buckets = [ofp.bucket(actions=action)]
354
355 group_id =encode_l3_unicast_group_id(id)
356 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
357 group_id=group_id,
358 buckets=buckets
359 )
360 ctrl.message_send(request)
Pier1e4e98e2016-10-26 14:36:05 -0700361
362 if send_barrier:
363 do_barrier(ctrl)
364
macauley15909e72015-07-17 15:58:57 +0800365 return request
Pierbbdf3782016-08-22 17:58:26 -0700366
macauley15909e72015-07-17 15:58:57 +0800367def add_l3_interface_group(ctrl, port, vlanid, id, src_mac):
368 group_id = encode_l2_interface_group_id(vlanid, port)
369
370 action=[]
371 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
Pierbbdf3782016-08-22 17:58:26 -0700372 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlanid)))
macauley15909e72015-07-17 15:58:57 +0800373 action.append(ofp.action.group(group_id))
Pierbbdf3782016-08-22 17:58:26 -0700374
macauley15909e72015-07-17 15:58:57 +0800375 buckets = [ofp.bucket(actions=action)]
376
377 group_id =encode_l3_interface_group_id(id)
378 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
379 group_id=group_id,
380 buckets=buckets
381 )
382 ctrl.message_send(request)
383 return request
384
Pier1e4e98e2016-10-26 14:36:05 -0700385def add_l3_ecmp_group(ctrl, id, l3_ucast_groups, send_barrier=False):
macauley15909e72015-07-17 15:58:57 +0800386 buckets=[]
387 for group in l3_ucast_groups:
388 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
389
390 group_id =encode_l3_ecmp_group_id(id)
391 request = ofp.message.group_add(group_type=ofp.OFPGT_SELECT,
392 group_id=group_id,
393 buckets=buckets
394 )
395 ctrl.message_send(request)
Pier1e4e98e2016-10-26 14:36:05 -0700396
397 if send_barrier:
398 do_barrier(ctrl)
399
macauley15909e72015-07-17 15:58:57 +0800400 return request
Flavio Castroa7162bb2016-07-25 17:30:30 -0700401
402def mod_l3_ecmp_group(ctrl, id, l3_ucast_groups):
403 buckets=[]
404 for group in l3_ucast_groups:
405 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
406
407 group_id =encode_l3_ecmp_group_id(id)
408 request = ofp.message.group_modify(group_type=ofp.OFPGT_SELECT,
409 group_id=group_id,
410 buckets=buckets
411 )
412 ctrl.message_send(request)
413 return request
414
macauley15909e72015-07-17 15:58:57 +0800415def add_l3_mcast_group(ctrl, vid, mcast_group_id, groups_on_buckets):
416 buckets=[]
417 for group in groups_on_buckets:
418 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
Pierbbdf3782016-08-22 17:58:26 -0700419
macauley15909e72015-07-17 15:58:57 +0800420 group_id =encode_l3_mcast_group_id(vid, mcast_group_id)
421 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
422 group_id=group_id,
423 buckets=buckets
424 )
425 ctrl.message_send(request)
426 return request
macauleyfddc4662015-07-27 17:40:30 +0800427
428def add_l2_overlay_flood_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
429 buckets=[]
430 for port in ports:
431 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
432
433 group_id=encode_l2_overlay_group_id(tunnel_id, 0, index)
434 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
435 group_id=group_id,
436 buckets=buckets
437 )
438 ctrl.message_send(request)
439 return request
440
441def add_l2_overlay_flood_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
442 buckets=[]
443 for port in ports:
444 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
445
446 group_id=encode_l2_overlay_group_id(tunnel_id, 1, index)
447 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
448 group_id=group_id,
449 buckets=buckets
450 )
451 ctrl.message_send(request)
452 return request
453
454def add_l2_overlay_mcast_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
455 buckets=[]
456 for port in ports:
457 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
458
459 group_id=encode_l2_overlay_group_id(tunnel_id, 2, index)
460 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
461 group_id=group_id,
462 buckets=buckets
463 )
464 ctrl.message_send(request)
465 return request
466
467def add_l2_overlay_mcast_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
468 buckets=[]
469 for port in ports:
470 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
471
472 group_id=encode_l2_overlay_group_id(tunnel_id, 3, index)
473 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
474 group_id=group_id,
475 buckets=buckets
476 )
477 ctrl.message_send(request)
478 return request
Pierbbdf3782016-08-22 17:58:26 -0700479
macauleyfddc4662015-07-27 17:40:30 +0800480def add_port_table_flow(ctrl, is_overlay=True):
481 match = ofp.match()
482
483 if is_overlay == True:
484 match.oxm_list.append(ofp.oxm.in_port(0x10000))
macauleydbff3272015-07-30 14:07:16 +0800485 NEXT_TABLE=50
macauleyfddc4662015-07-27 17:40:30 +0800486 else:
487 match.oxm_list.append(ofp.oxm.in_port(0))
Pierbbdf3782016-08-22 17:58:26 -0700488 NEXT_TABLE=10
macauleyfddc4662015-07-27 17:40:30 +0800489
490 request = ofp.message.flow_add(
Pier265ad5f2017-02-28 17:46:28 +0100491 table_id=0,
492 cookie=42,
493 match=match,
494 instructions=[
495 ofp.instruction.goto_table(NEXT_TABLE)
496 ],
497 priority=0)
macauleyfddc4662015-07-27 17:40:30 +0800498 logging.info("Add port table, match port %lx" % 0x10000)
499 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -0700500
Flavio Castrod8f8af22015-12-02 18:19:26 -0500501def pop_vlan_flow(ctrl, ports, vlan_id=1):
502 # table 10: vlan
503 # goto to table 20
504 msgs=[]
505 for of_port in ports:
506 match = ofp.match()
507 match.oxm_list.append(ofp.oxm.in_port(of_port))
508 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
509 request = ofp.message.flow_add(
510 table_id=10,
511 cookie=42,
512 match=match,
513 instructions=[
514 ofp.instruction.apply_actions(
515 actions=[
516 ofp.action.pop_vlan()
517 ]
518 ),
519 ofp.instruction.goto_table(20)
520 ],
521 priority=0)
522 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
523 ctrl.message_send(request)
524
525
526 return msgs
macauleyfddc4662015-07-27 17:40:30 +0800527
macauley97557232015-07-16 17:28:07 +0800528def add_vlan_table_flow(ctrl, ports, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
529 # table 10: vlan
530 # goto to table 20
macauley15909e72015-07-17 15:58:57 +0800531 msgs=[]
macauley97557232015-07-16 17:28:07 +0800532 for of_port in ports:
Flavio Castro932014b2016-01-05 18:29:15 -0500533 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
macauley97557232015-07-16 17:28:07 +0800534 match = ofp.match()
535 match.oxm_list.append(ofp.oxm.in_port(of_port))
536 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
537 request = ofp.message.flow_add(
538 table_id=10,
539 cookie=42,
540 match=match,
541 instructions=[
Flavio Castrod8f8af22015-12-02 18:19:26 -0500542 ofp.instruction.apply_actions(
543 actions=[
544 ofp.action.pop_vlan()
545 ]
546 ),
macauley97557232015-07-16 17:28:07 +0800547 ofp.instruction.goto_table(20)
548 ],
549 priority=0)
550 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
551 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -0700552
macauley97557232015-07-16 17:28:07 +0800553 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
554 match = ofp.match()
555 match.oxm_list.append(ofp.oxm.in_port(of_port))
Flavio Castro12296312015-12-15 17:48:26 -0500556 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0x1fff))
macauley97557232015-07-16 17:28:07 +0800557 request = ofp.message.flow_add(
558 table_id=10,
559 cookie=42,
560 match=match,
561 instructions=[
562 ofp.instruction.apply_actions(
563 actions=[
Flavio Castroaf2b4502016-02-02 17:41:32 -0500564 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id))
macauley97557232015-07-16 17:28:07 +0800565 ]
566 ),
567 ofp.instruction.goto_table(20)
568 ],
569 priority=0)
570 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
571 ctrl.message_send(request)
macauley15909e72015-07-17 15:58:57 +0800572 msgs.append(request)
macauley97557232015-07-16 17:28:07 +0800573
Flavio Castro932014b2016-01-05 18:29:15 -0500574 if (flag == 4) :
575 match = ofp.match()
576 match.oxm_list.append(ofp.oxm.in_port(of_port))
577 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1fff))
578 request = ofp.message.flow_add(
579 table_id=10,
580 cookie=42,
581 match=match,
582 instructions=[
583 ofp.instruction.apply_actions(
584 actions=[
Flavio Castroaf2b4502016-02-02 17:41:32 -0500585 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id))
Flavio Castro932014b2016-01-05 18:29:15 -0500586 ]
587 ),
588 ofp.instruction.goto_table(20)
589 ],
590 priority=0)
591 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
592 ctrl.message_send(request)
593 msgs.append(request)
594
macauley97557232015-07-16 17:28:07 +0800595 if send_barrier:
596 do_barrier(ctrl)
597
macauley15909e72015-07-17 15:58:57 +0800598 return msgs
Pierbbdf3782016-08-22 17:58:26 -0700599
macauley_cheng6e6a6122015-11-16 14:19:18 +0800600def del_vlan_table_flow(ctrl, ports, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
601 # table 10: vlan
602 # goto to table 20
603 msgs=[]
604 for of_port in ports:
605 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
606 match = ofp.match()
607 match.oxm_list.append(ofp.oxm.in_port(of_port))
608 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
609 request = ofp.message.flow_delete(
610 table_id=10,
611 cookie=42,
612 match=match,
613 priority=0)
614 logging.info("Del vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
615 ctrl.message_send(request)
macauley0f91a3e2015-07-17 18:09:59 +0800616
macauley_cheng6e6a6122015-11-16 14:19:18 +0800617 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) 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_masked(0, 0xfff))
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 untagged packets on port %d and go to table 20" % (vlan_id, of_port))
627 ctrl.message_send(request)
628 msgs.append(request)
629
630 if send_barrier:
631 do_barrier(ctrl)
632
633 return msgs
Pierbbdf3782016-08-22 17:58:26 -0700634
macauley_cheng6b311612015-09-04 11:32:27 +0800635def add_vlan_table_flow_pvid(ctrl, in_port, match_vid=None, pvid=1, send_barrier=False):
636 """it will tag pack as untagged packet wether it has tagg or not"""
637 match = ofp.match()
638 match.oxm_list.append(ofp.oxm.in_port(in_port))
639 actions=[]
640 if match_vid == None:
Pierbbdf3782016-08-22 17:58:26 -0700641 match.oxm_list.append(ofp.oxm.vlan_vid(0))
macauley_cheng6b311612015-09-04 11:32:27 +0800642 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+pvid)))
643 goto_table=20
644 else:
645 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+match_vid, 0x1fff))
646 actions.append(ofp.action.push_vlan(0x8100))
Pierbbdf3782016-08-22 17:58:26 -0700647 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+pvid)))
macauley_cheng6b311612015-09-04 11:32:27 +0800648 goto_table=20
Pierbbdf3782016-08-22 17:58:26 -0700649
macauley_cheng6b311612015-09-04 11:32:27 +0800650 request = ofp.message.flow_add(
651 table_id=10,
652 cookie=42,
653 match=match,
654 instructions=[
655 ofp.instruction.apply_actions(actions=actions)
656 ,ofp.instruction.goto_table(goto_table)
657 ],
658 priority=0)
659 logging.info("Add PVID %d on port %d and go to table %ld" %( pvid, in_port, goto_table))
Pierbbdf3782016-08-22 17:58:26 -0700660 ctrl.message_send(request)
661
macauley_cheng6b311612015-09-04 11:32:27 +0800662 if send_barrier:
663 do_barrier(ctrl)
664
665def add_vlan_table_flow_allow_all_vlan(ctrl, in_port, send_barrier=False):
666 """it st flow allow all vlan tag on this port"""
667 match = ofp.match()
668 match.oxm_list.append(ofp.oxm.in_port(in_port))
669 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1000))
670 request = ofp.message.flow_add(
671 table_id=10,
672 cookie=42,
673 match=match,
674 instructions=[
Pierbbdf3782016-08-22 17:58:26 -0700675 ofp.instruction.goto_table(20)
macauley_cheng6b311612015-09-04 11:32:27 +0800676 ],
677 priority=0)
678 logging.info("Add allow all vlan on port %d " %(in_port))
Pierbbdf3782016-08-22 17:58:26 -0700679 ctrl.message_send(request)
macauley_cheng6b311612015-09-04 11:32:27 +0800680
Pier7b031af2016-08-25 15:00:22 -0700681def 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):
682 # Install a flow for VLAN translation
683 # in VLAN table.
684 # table 10: vlan
685 # goto to table 20
686 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
687 match = ofp.match()
688 match.oxm_list.append(ofp.oxm.in_port(of_port))
689 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id,0x1fff))
690
691 actions=[]
692 if vrf!=0:
693 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
694 if new_vlan_id != -1:
695 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_vlan_id)))
696
697 request = ofp.message.flow_add(
698 table_id=10,
699 cookie=42,
700 match=match,
701 instructions=[
702 ofp.instruction.apply_actions(
703 actions=actions
704 ),
705 ofp.instruction.goto_table(20)
706 ],
707 priority=0)
708 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
709 ctrl.message_send(request)
710
Piere1308762016-09-12 15:29:56 -0700711def add_one_vlan_table_flow(ctrl, of_port, out_vlan_id=1, vlan_id=1, vrf=0, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
macauley0f91a3e2015-07-17 18:09:59 +0800712 # table 10: vlan
713 # goto to table 20
Flavio Castro932014b2016-01-05 18:29:15 -0500714 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
macauley0f91a3e2015-07-17 18:09:59 +0800715 match = ofp.match()
716 match.oxm_list.append(ofp.oxm.in_port(of_port))
Flavio Castro12296312015-12-15 17:48:26 -0500717 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id,0x1fff))
macauley7f89d962015-08-06 18:13:48 +0800718
719 actions=[]
Alex Yashchuk9f449462017-12-09 18:27:19 +0200720 if config["switch_type"] != 'xpliant' and vrf != 0:
721 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
Pierbbdf3782016-08-22 17:58:26 -0700722
Flavio Castro6d498522015-12-15 14:05:04 -0500723 #actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(value=vlan_id)))
macauley7f89d962015-08-06 18:13:48 +0800724
macauley0f91a3e2015-07-17 18:09:59 +0800725 request = ofp.message.flow_add(
726 table_id=10,
727 cookie=42,
728 match=match,
729 instructions=[
macauley53d90fe2015-08-04 17:34:22 +0800730 ofp.instruction.apply_actions(
macauley7f89d962015-08-06 18:13:48 +0800731 actions=actions
macauley53d90fe2015-08-04 17:34:22 +0800732 ),
733 ofp.instruction.goto_table(20)
macauley0f91a3e2015-07-17 18:09:59 +0800734 ],
735 priority=0)
736 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
737 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -0700738
macauley0f91a3e2015-07-17 18:09:59 +0800739 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
740 match = ofp.match()
741 match.oxm_list.append(ofp.oxm.in_port(of_port))
Flavio Castro12296312015-12-15 17:48:26 -0500742 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0x1fff))
Pierbbdf3782016-08-22 17:58:26 -0700743
macauley7f89d962015-08-06 18:13:48 +0800744 actions=[]
745 if vrf!=0:
746 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
Pierbbdf3782016-08-22 17:58:26 -0700747
Flavio Castro91d1a552016-05-17 16:59:44 -0700748 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
Pierbbdf3782016-08-22 17:58:26 -0700749
macauley0f91a3e2015-07-17 18:09:59 +0800750 request = ofp.message.flow_add(
751 table_id=10,
752 cookie=42,
753 match=match,
754 instructions=[
755 ofp.instruction.apply_actions(
macauley7f89d962015-08-06 18:13:48 +0800756 actions=actions
macauley0f91a3e2015-07-17 18:09:59 +0800757 ),
758 ofp.instruction.goto_table(20)
759 ],
760 priority=0)
761 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
762 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -0700763
Flavio Castro932014b2016-01-05 18:29:15 -0500764 if (flag == 4) :
765 match = ofp.match()
766 match.oxm_list.append(ofp.oxm.in_port(of_port))
767 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000,0x1fff))
768
769 actions=[]
770 if vrf!=0:
771 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
772
Flavio Castro91d1a552016-05-17 16:59:44 -0700773 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
Flavio Castro932014b2016-01-05 18:29:15 -0500774
775 request = ofp.message.flow_add(
776 table_id=10,
777 cookie=42,
778 match=match,
779 instructions=[
780 ofp.instruction.apply_actions(
781 actions=actions
782 ),
783 ofp.instruction.goto_table(20)
784 ],
785 priority=0)
786 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
787 ctrl.message_send(request)
macauley0f91a3e2015-07-17 18:09:59 +0800788
Piere1308762016-09-12 15:29:56 -0700789 if (flag == VLAN_TABLE_FLAG_ONLY_STACKED):
790 # This flag is meant to managed stacked vlan packtes
791 # Matches on outer VLAN_ID, set OVID with outer VLAN.
792 # Finally expose inner VLAN_ID with a pop action and
793 # goto VLAN_1_FLOW_TABLE
794 match = ofp.match()
795 match.oxm_list.append(ofp.oxm.in_port(of_port))
796 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id,0x1fff))
797
798 actions=[]
799 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_OVID, value=0x1000+vlan_id)))
800 actions.append(ofp.action.pop_vlan())
801
802 request = ofp.message.flow_add(
803 table_id=10,
804 cookie=42,
805 match=match,
806 instructions=[
807 ofp.instruction.apply_actions(
808 actions=actions
809 ),
810 ofp.instruction.goto_table(VLAN_1_FLOW_TABLE)
811 ],
812 priority=0)
813 logging.info("Add vlan %d tagged packets on port %d and go to table %d" %( vlan_id, of_port, VLAN_1_FLOW_TABLE))
814 ctrl.message_send(request)
815
816 if (flag == VLAN_TABLE_FLAG_PRIORITY) :
817 match = ofp.match()
818 match.oxm_list.append(ofp.oxm.in_port(of_port))
819 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1fff))
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=[
827 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)),
828 ofp.action.push_vlan(0x8100),
829 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+out_vlan_id)),
830 ]
831 ),
832 ofp.instruction.goto_table(20)
833 ],
834 priority=0)
835 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
836 ctrl.message_send(request)
837
838 if send_barrier:
839 do_barrier(ctrl)
840
841 return request
842
Piercf76e802016-09-19 20:16:35 -0700843def 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):
844 # table 10: vlan
845 # goto to table 13
846 if flag == VLAN_TABLE_FLAG_ONLY_TAG:
847 match = ofp.match()
848 match.oxm_list.append(ofp.oxm.in_port(of_port))
849 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id, 0x1fff))
850
851 actions=[]
852 if vlan_id == -1:
853 actions.append(ofp.action.pop_vlan())
854 if new_vlan_id > 1:
855 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_vlan_id)))
856 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
857 actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
858 # 0x0000nnnn is for UNI interfaces
859 actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port)))
860
861 request = ofp.message.flow_add(
862 table_id=10,
863 cookie=42,
864 match=match,
865 instructions=[
866 ofp.instruction.apply_actions(
867 actions=actions
868 ),
869 ofp.instruction.goto_table(MPLS_L2_PORT_FLOW_TABLE)
870 ],
871 priority=0)
872 logging.info("Add vlan %d tagged packets on port %d and go to table %d" % (vlan_id, of_port, MPLS_L2_PORT_FLOW_TABLE))
873 ctrl.message_send(request)
874
875 if flag == VLAN_TABLE_FLAG_ONLY_UNTAG:
876 match = ofp.match()
877 match.oxm_list.append(ofp.oxm.in_port(of_port))
878 match.oxm_list.append(ofp.oxm.vlan_vid(0))
879
880 actions=[]
881 if vlan_id > 1:
Charles Chanc85f1562018-01-18 15:44:29 -0800882 # actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
883 # actions.append(ofp.action.set_field(ofp.action.push_vlan(0x8100)))
Piercf76e802016-09-19 20:16:35 -0700884 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
Charles Chanc85f1562018-01-18 15:44:29 -0800885
Piercf76e802016-09-19 20:16:35 -0700886 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
887 actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
888 # 0x0000nnnn is for UNI interfaces
889 actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port)))
890
891 request = ofp.message.flow_add(
892 table_id=10,
893 cookie=42,
894 match=match,
895 instructions=[
896 ofp.instruction.apply_actions(
897 actions=actions
898 ),
899 ofp.instruction.goto_table(MPLS_L2_PORT_FLOW_TABLE)
900 ],
901 priority=0)
902 logging.info("Add vlan %d untagged packets on port %d and go to table %d" % (vlan_id, of_port, MPLS_L2_PORT_FLOW_TABLE))
903 ctrl.message_send(request)
904
905 if send_barrier:
906 do_barrier(ctrl)
907
908 return request
909
Piere1308762016-09-12 15:29:56 -0700910def 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):
911 # table 11: vlan 1 table
912 # goto to table 20
913 if flag == VLAN_TABLE_FLAG_ONLY_TAG:
914 match = ofp.match()
915 match.oxm_list.append(ofp.oxm.in_port(of_port))
916 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
917 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
918
919 actions=[]
920 actions.append(ofp.action.push_vlan(0x8100))
921 if new_outer_vlan_id != -1:
922 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_outer_vlan_id)))
923 else:
924 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+outer_vlan_id)))
925
926 request = ofp.message.flow_add(
927 table_id=11,
928 cookie=42,
929 match=match,
930 instructions=[
931 ofp.instruction.apply_actions(
932 actions=actions
933 ),
934 ofp.instruction.goto_table(TERMINATION_FLOW_TABLE)
935 ],
936 priority=0)
937 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))
938 ctrl.message_send(request)
939
940 if flag == VLAN_TABLE_FLAG_ONLY_UNTAG:
941 match = ofp.match()
942 match.oxm_list.append(ofp.oxm.in_port(of_port))
943 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
944 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
945
946 actions=[]
947 request = ofp.message.flow_add(
948 table_id=11,
949 cookie=42,
950 match=match,
951 instructions=[
952 ofp.instruction.apply_actions(
953 actions=actions
954 ),
955 ofp.instruction.goto_table(TERMINATION_FLOW_TABLE)
956 ],
957 priority=0)
958 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))
959 ctrl.message_send(request)
960
macauley0f91a3e2015-07-17 18:09:59 +0800961 if send_barrier:
962 do_barrier(ctrl)
963
964 return request
Pierbbdf3782016-08-22 17:58:26 -0700965
Piercf76e802016-09-19 20:16:35 -0700966def 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 -0800967
Piercf76e802016-09-19 20:16:35 -0700968 # table 11: vlan 1 table
969 # goto to table 13
970 match = ofp.match()
971 match.oxm_list.append(ofp.oxm.in_port(of_port))
972 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
973 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
974
975 actions=[]
976 actions.append(ofp.action.push_vlan(0x8100))
977 if new_outer_vlan_id != -1:
Charles Chanc85f1562018-01-18 15:44:29 -0800978 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_outer_vlan_id)))
Piercf76e802016-09-19 20:16:35 -0700979 else:
Charles Chanc85f1562018-01-18 15:44:29 -0800980 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+outer_vlan_id)))
Piercf76e802016-09-19 20:16:35 -0700981
982 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
983 actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
984 # 0x0000nnnn is for UNI interfaces
985 actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port)))
986
987 request = ofp.message.flow_add(
Charles Chanc85f1562018-01-18 15:44:29 -0800988 table_id=11,
989 cookie=42,
990 match=match,
991 instructions=[
992 ofp.instruction.apply_actions(
993 actions=actions
994 ),
995 ofp.instruction.goto_table(MPLS_L2_PORT_FLOW_TABLE)
996 ],
997 priority=0)
Piercf76e802016-09-19 20:16:35 -0700998 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))
999 ctrl.message_send(request)
Piercf76e802016-09-19 20:16:35 -07001000 if send_barrier:
1001 do_barrier(ctrl)
1002
1003 return request
1004
macauley97557232015-07-16 17:28:07 +08001005def add_bridge_flow(ctrl, dst_mac, vlanid, group_id, send_barrier=False):
1006 match = ofp.match()
castroflavio21894482015-12-08 15:29:55 -05001007 priority=500
macauleyfddc4662015-07-27 17:40:30 +08001008 if dst_mac!=None:
castroflavio21894482015-12-08 15:29:55 -05001009 priority=1000
macauleyfddc4662015-07-27 17:40:30 +08001010 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
1011
macauley97557232015-07-16 17:28:07 +08001012 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
macauleyfddc4662015-07-27 17:40:30 +08001013
macauley97557232015-07-16 17:28:07 +08001014 request = ofp.message.flow_add(
1015 table_id=50,
1016 cookie=42,
1017 match=match,
1018 instructions=[
1019 ofp.instruction.write_actions(
1020 actions=[
1021 ofp.action.group(group_id)]),
1022 ofp.instruction.goto_table(60)
1023 ],
1024 buffer_id=ofp.OFP_NO_BUFFER,
castroflavio21894482015-12-08 15:29:55 -05001025 priority=priority)
macauley97557232015-07-16 17:28:07 +08001026
1027 logging.info("Inserting Brdige flow vlan %d, mac %s", vlanid, dst_mac)
1028 ctrl.message_send(request)
1029
1030 if send_barrier:
Pierbbdf3782016-08-22 17:58:26 -07001031 do_barrier(ctrl)
macauley15909e72015-07-17 15:58:57 +08001032
Pierbbdf3782016-08-22 17:58:26 -07001033 return request
macauleyfddc4662015-07-27 17:40:30 +08001034
1035def add_overlay_bridge_flow(ctrl, dst_mac, vnid, group_id, is_group=True, send_barrier=False):
1036 match = ofp.match()
1037 if dst_mac!=None:
1038 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
1039
1040 match.oxm_list.append(ofp.oxm.tunnel_id(vnid))
1041 if is_group == True:
1042 actions=[ofp.action.group(group_id)]
1043 else:
1044 actions=[ofp.action.output(group_id)]
1045
1046 request = ofp.message.flow_add(
1047 table_id=50,
1048 cookie=42,
1049 match=match,
1050 instructions=[
1051 ofp.instruction.write_actions(
1052 actions=actions),
1053 ofp.instruction.goto_table(60)
1054 ],
1055 buffer_id=ofp.OFP_NO_BUFFER,
Pierbbdf3782016-08-22 17:58:26 -07001056 priority=1000)
macauleyfddc4662015-07-27 17:40:30 +08001057
1058 logging.info("Inserting Brdige flow vnid %d, mac %s", vnid, dst_mac)
1059 ctrl.message_send(request)
1060
1061 if send_barrier:
Pierbbdf3782016-08-22 17:58:26 -07001062 do_barrier(ctrl)
macauleyfddc4662015-07-27 17:40:30 +08001063
Pierbbdf3782016-08-22 17:58:26 -07001064 return request
1065
macauley_cheng6b133662015-11-09 13:52:39 +08001066def add_termination_flow(ctrl, in_port, eth_type, dst_mac, vlanid, goto_table=None, send_barrier=False):
macauley0f91a3e2015-07-17 18:09:59 +08001067 match = ofp.match()
macauley0f91a3e2015-07-17 18:09:59 +08001068 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
macauleyfddc4662015-07-27 17:40:30 +08001069 if dst_mac[0]&0x01 == 0x01:
1070 match.oxm_list.append(ofp.oxm.eth_dst_masked(dst_mac, [0xff, 0xff, 0xff, 0x80, 0x00, 0x00]))
1071 goto_table=40
1072 else:
macauley53d90fe2015-08-04 17:34:22 +08001073 if in_port!=0:
1074 match.oxm_list.append(ofp.oxm.in_port(in_port))
macauleyfddc4662015-07-27 17:40:30 +08001075 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
1076 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
macauley_cheng6b133662015-11-09 13:52:39 +08001077 if goto_table == None:
1078 goto_table=30
macauley0f91a3e2015-07-17 18:09:59 +08001079
1080 request = ofp.message.flow_add(
1081 table_id=20,
1082 cookie=42,
1083 match=match,
1084 instructions=[
1085 ofp.instruction.goto_table(goto_table)
1086 ],
1087 buffer_id=ofp.OFP_NO_BUFFER,
Pierbbdf3782016-08-22 17:58:26 -07001088 priority=1)
macauley0f91a3e2015-07-17 18:09:59 +08001089
1090 logging.info("Inserting termination flow inport %d, eth_type %lx, vlan %d, mac %s", in_port, eth_type, vlanid, dst_mac)
1091 ctrl.message_send(request)
macauley0f91a3e2015-07-17 18:09:59 +08001092 if send_barrier:
Pierbbdf3782016-08-22 17:58:26 -07001093 do_barrier(ctrl)
macauley0f91a3e2015-07-17 18:09:59 +08001094
Pierbbdf3782016-08-22 17:58:26 -07001095 return request
1096
Alex Yashchuk9f449462017-12-09 18:27:19 +02001097def 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 +08001098 match = ofp.match()
1099 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
Alex Yashchuk9f449462017-12-09 18:27:19 +02001100 if config["switch_type"] != 'xpliant' and vrf != 0:
macauley53d90fe2015-08-04 17:34:22 +08001101 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_VRF, vrf))
macauley0f91a3e2015-07-17 18:09:59 +08001102
Flavio Castroaf2b4502016-02-02 17:41:32 -05001103 match.oxm_list.append(ofp.oxm.ipv4_dst_masked(dst_ip, mask))
1104
1105 instructions = []
1106 instructions.append(ofp.instruction.goto_table(60))
1107 if send_ctrl:
Pier265ad5f2017-02-28 17:46:28 +01001108 instructions.append(ofp.instruction.write_actions(
Flavio Castroaf2b4502016-02-02 17:41:32 -05001109 actions=[ofp.action.output( port=ofp.OFPP_CONTROLLER,
1110 max_len=ofp.OFPCML_NO_BUFFER)]))
Pierbbdf3782016-08-22 17:58:26 -07001111 else:
Flavio Castroaf2b4502016-02-02 17:41:32 -05001112 instructions.append(ofp.instruction.write_actions(
1113 actions=[ofp.action.group(action_group_id)]))
macauley53d90fe2015-08-04 17:34:22 +08001114
macauley0f91a3e2015-07-17 18:09:59 +08001115 request = ofp.message.flow_add(
1116 table_id=30,
1117 cookie=42,
1118 match=match,
Flavio Castroaf2b4502016-02-02 17:41:32 -05001119 instructions=instructions,
macauley0f91a3e2015-07-17 18:09:59 +08001120 buffer_id=ofp.OFP_NO_BUFFER,
Alex Yashchuk9f449462017-12-09 18:27:19 +02001121 priority=priority)
macauley0f91a3e2015-07-17 18:09:59 +08001122
1123 logging.info("Inserting unicast routing flow eth_type %lx, dip %ld",eth_type, dst_ip)
1124 ctrl.message_send(request)
1125
1126 if send_barrier:
Pierbbdf3782016-08-22 17:58:26 -07001127 do_barrier(ctrl)
macauley0f91a3e2015-07-17 18:09:59 +08001128
Flavio Castro9debaaa2016-07-26 19:37:50 -07001129 return request
Flavio Castrod8f8af22015-12-02 18:19:26 -05001130
Pier1e4e98e2016-10-26 14:36:05 -07001131def add_unicast_v6_routing_flow(ctrl, eth_type, dst_ip, mask, action_group_id, vrf=0, send_ctrl=False, send_barrier=False):
1132 match = ofp.match()
1133 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
1134 if vrf != 0:
1135 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_VRF, vrf))
1136
1137 match.oxm_list.append(ofp.oxm.ipv6_dst_masked(parse_ipv6(dst_ip), parse_ipv6(mask)))
1138
1139 instructions = []
1140 instructions.append(ofp.instruction.goto_table(60))
1141 if send_ctrl:
Pier265ad5f2017-02-28 17:46:28 +01001142 instructions.append(ofp.instruction.write_actions(
Pier1e4e98e2016-10-26 14:36:05 -07001143 actions=[ofp.action.output( port=ofp.OFPP_CONTROLLER,
1144 max_len=ofp.OFPCML_NO_BUFFER)]))
1145 else:
1146 instructions.append(ofp.instruction.write_actions(
1147 actions=[ofp.action.group(action_group_id)]))
1148
1149 request = ofp.message.flow_add(
1150 table_id=30,
1151 cookie=42,
1152 match=match,
1153 instructions=instructions,
1154 buffer_id=ofp.OFP_NO_BUFFER,
1155 priority=1)
1156
1157 logging.info("Inserting unicast routing flow eth_type %lx, dip %s",eth_type, dst_ip)
1158 ctrl.message_send(request)
1159
1160 if send_barrier:
1161 do_barrier(ctrl)
1162
1163 return request
1164
Andreas Pantelopoulos6c76b942018-01-22 10:03:02 -08001165def 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 -04001166 match = ofp.match()
1167 match.oxm_list.append(ofp.oxm.eth_type(0x8847))
1168 match.oxm_list.append(ofp.oxm.mpls_label(label))
1169 match.oxm_list.append(ofp.oxm.mpls_bos(bos))
Pier265ad5f2017-02-28 17:46:28 +01001170 write_actions = []
1171 write_actions.append(ofp.action.group(action_group_id))
1172 apply_actions = []
1173 apply_actions = [ofp.action.dec_mpls_ttl(),
Flavio Castro8ca52542016-04-11 11:24:49 -04001174 ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf))]
Pier265ad5f2017-02-28 17:46:28 +01001175 if (goto_table != 29):
1176 apply_actions.append(ofp.action.set_field(
Flavio Castrod80fbc32016-07-25 15:54:26 -07001177 ofp.oxm.exp2ByteValue(exp_type=23, value=32)))
Pier265ad5f2017-02-28 17:46:28 +01001178 apply_actions.append(ofp.action.copy_ttl_in())
Flavio Castro9debaaa2016-07-26 19:37:50 -07001179
Flavio Castrob702a2f2016-04-10 22:01:48 -04001180 request = ofp.message.flow_add(
1181 table_id=24,
1182 cookie=43,
1183 match=match,
1184 instructions=[
Pier265ad5f2017-02-28 17:46:28 +01001185 ofp.instruction.apply_actions(actions=apply_actions),
1186 ofp.instruction.write_actions(actions=write_actions),
Flavio Castro8ca52542016-04-11 11:24:49 -04001187 ofp.instruction.goto_table(goto_table)
Flavio Castrob702a2f2016-04-10 22:01:48 -04001188 ],
1189 buffer_id=ofp.OFP_NO_BUFFER,
1190 priority=1)
Flavio Castrob702a2f2016-04-10 22:01:48 -04001191 logging.info("Inserting MPLS flow , label %ld", label)
1192 ctrl.message_send(request)
1193
1194 if send_barrier:
1195 do_barrier(ctrl)
1196
1197 return request
1198
Alex Yashchuk9f449462017-12-09 18:27:19 +02001199def xpliant_add_mpls_flow(ctrl, action_group_id=0x0, label=100 ,ethertype=0x0800, bos=1, vrf=1, goto_table=27, send_barrier=False):
1200 match = ofp.match()
1201 match.oxm_list.append(ofp.oxm.eth_type(0x8847))
1202 match.oxm_list.append(ofp.oxm.mpls_label(label))
1203
1204 apply_actions = []
1205 apply_actions.append(ofp.action.group(action_group_id))
1206 apply_actions.append(ofp.action.dec_mpls_ttl())
1207 if (goto_table != 29):
1208 apply_actions.append(ofp.action.pop_mpls(ethertype))
1209
1210 request = ofp.message.flow_add(
1211 table_id=24,
1212 cookie=43,
1213 match=match,
1214 instructions=[
1215 ofp.instruction.apply_actions(actions=apply_actions),
1216 ],
1217 buffer_id=ofp.OFP_NO_BUFFER,
1218 priority=1)
1219 logging.info("Inserting MPLS flow , label %ld", label)
1220 ctrl.message_send(request)
1221
1222 if send_barrier:
1223 do_barrier(ctrl)
1224
1225 return request
1226
Andreas Pantelopoulos6c76b942018-01-22 10:03:02 -08001227def add_mpls_flow_swap(ctrl, action_group_id, label, ethertype, bos, goto_table=MPLS_TYPE_FLOW_TABLE, of_port=0, send_barrier=False):
1228 match = ofp.match()
1229 match.oxm_list.append(ofp.oxm.eth_type(0x8847))
1230 match.oxm_list.append(ofp.oxm.mpls_label(label))
1231 match.oxm_list.append(ofp.oxm.mpls_bos(1))
1232
1233 apply_actions = []
1234 write_actions = []
1235 apply_actions.append(ofp.action.dec_mpls_ttl())
1236 write_actions.append(ofp.action.group(action_group_id))
1237
1238 request = ofp.message.flow_add(
1239 table_id=24,
1240 cookie=43,
1241 match=match,
1242 instructions=[
1243 ofp.instruction.apply_actions(actions=apply_actions),
1244 ofp.instruction.write_actions(actions=write_actions),
1245 ofp.instruction.goto_table(goto_table)
1246 ],
1247 buffer_id=ofp.OFP_NO_BUFFER,
1248 priority=1)
1249
1250 logging.info("Inserting MPLS flow , label %ld", label)
1251 ctrl.message_send(request)
1252
1253 if send_barrier:
1254 do_barrier(ctrl)
1255
1256 return request
1257
1258
Pierf6f28162016-09-22 16:30:52 -07001259def 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 -07001260 match = ofp.match()
1261 match.oxm_list.append(ofp.oxm.eth_type(0x8847))
1262 match.oxm_list.append(ofp.oxm.mpls_label(label))
1263 match.oxm_list.append(ofp.oxm.mpls_bos(bos))
1264
Pier265ad5f2017-02-28 17:46:28 +01001265 apply_actions = []
1266 write_actions = []
1267 apply_actions.append(ofp.action.dec_mpls_ttl())
Pierf6f28162016-09-22 16:30:52 -07001268 if popMPLS == True:
Pier265ad5f2017-02-28 17:46:28 +01001269 apply_actions.append(ofp.action.copy_ttl_in())
1270 apply_actions.append(ofp.action.pop_mpls(ethertype))
Pierf6f28162016-09-22 16:30:52 -07001271 if bos==1 and popL2 == True:
Pier265ad5f2017-02-28 17:46:28 +01001272 apply_actions.append(ofp.action.ofdpa_pop_l2_header())
1273 apply_actions.append(ofp.action.ofdpa_pop_cw())
1274 apply_actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
Pierf6f28162016-09-22 16:30:52 -07001275 # 0x0002nnnn is for UNI interfaces
Pier265ad5f2017-02-28 17:46:28 +01001276 apply_actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00020000 + of_port)))
1277 apply_actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
1278 write_actions.append(ofp.action.group(action_group_id))
Pierb5da4c92016-09-21 11:23:35 -07001279
1280 request = ofp.message.flow_add(
Pier265ad5f2017-02-28 17:46:28 +01001281 table_id=24,
1282 cookie=43,
1283 match=match,
1284 instructions=[
1285 ofp.instruction.apply_actions(actions=apply_actions),
1286 ofp.instruction.write_actions(actions=write_actions),
1287 ofp.instruction.goto_table(goto_table)
1288 ],
1289 buffer_id=ofp.OFP_NO_BUFFER,
1290 priority=1)
Pierb5da4c92016-09-21 11:23:35 -07001291 logging.info("Inserting MPLS flow , label %ld", label)
1292 ctrl.message_send(request)
1293
1294 if send_barrier:
1295 do_barrier(ctrl)
1296
1297 return request
1298
macauleyfddc4662015-07-27 17:40:30 +08001299def add_mcast4_routing_flow(ctrl, vlan_id, src_ip, src_ip_mask, dst_ip, action_group_id, send_barrier=False):
1300 match = ofp.match()
1301 match.oxm_list.append(ofp.oxm.eth_type(0x0800))
Alex Yashchuk9f449462017-12-09 18:27:19 +02001302 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000 + vlan_id))
macauleyfddc4662015-07-27 17:40:30 +08001303 if src_ip_mask!=0:
1304 match.oxm_list.append(ofp.oxm.ipv4_src_masked(src_ip, src_ip_mask))
1305 else:
1306 match.oxm_list.append(ofp.oxm.ipv4_src(src_ip))
Pierbbdf3782016-08-22 17:58:26 -07001307
macauleyfddc4662015-07-27 17:40:30 +08001308 match.oxm_list.append(ofp.oxm.ipv4_dst(dst_ip))
Pierbbdf3782016-08-22 17:58:26 -07001309
macauleyfddc4662015-07-27 17:40:30 +08001310 request = ofp.message.flow_add(
1311 table_id=40,
1312 cookie=42,
1313 match=match,
1314 instructions=[
1315 ofp.instruction.write_actions(
1316 actions=[ofp.action.group(action_group_id)]),
1317 ofp.instruction.goto_table(60)
1318 ],
1319 buffer_id=ofp.OFP_NO_BUFFER,
Pierbbdf3782016-08-22 17:58:26 -07001320 priority=1)
macauleyfddc4662015-07-27 17:40:30 +08001321
1322 logging.info("Inserting mcast routing flow eth_type %lx, dip %lx, sip %lx, sip_mask %lx",0x0800, dst_ip, src_ip, src_ip_mask)
1323 ctrl.message_send(request)
1324
1325 if send_barrier:
Pierbbdf3782016-08-22 17:58:26 -07001326 do_barrier(ctrl)
macauleyfddc4662015-07-27 17:40:30 +08001327
Pierbbdf3782016-08-22 17:58:26 -07001328 return request
macauley_cheng6b133662015-11-09 13:52:39 +08001329
Pier1e4e98e2016-10-26 14:36:05 -07001330def add_acl_rule(ctrl, eth_type=None, ip_proto=None, send_barrier=False):
1331 match = ofp.match()
1332 if eth_type != None:
1333 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
1334 if ip_proto != None:
1335 match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
1336
1337 request = ofp.message.flow_add(
1338 table_id=60,
1339 cookie=42,
1340 match=match,
1341 instructions=[
1342 ofp.instruction.apply_actions(
1343 actions=[ofp.action.output(port=ofp.OFPP_CONTROLLER, max_len=ofp.OFPCML_NO_BUFFER)]
1344 ),
1345 ],
1346 buffer_id=ofp.OFP_NO_BUFFER,
1347 priority=1
1348 )
1349
1350 logging.info("Inserting ACL flow eth_type %lx, ip_proto %ld", eth_type, ip_proto)
1351 ctrl.message_send(request)
1352
1353 if send_barrier:
1354 do_barrier(ctrl)
1355
1356 return request
1357
macauley_cheng6b133662015-11-09 13:52:39 +08001358#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 +08001359def 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 +08001360 match = ofp.match()
1361 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
1362 match.oxm_list.append(ofp.oxm.ipv4_dst(ip_dst))
1363 match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
1364 match.oxm_list.append(ofp.oxm.tcp_dst(tcp_dst))
Pierbbdf3782016-08-22 17:58:26 -07001365
macauley_cheng6b133662015-11-09 13:52:39 +08001366 request = ofp.message.flow_add(
1367 table_id=28,
1368 cookie=42,
1369 match=match,
1370 instructions=[
1371 ofp.instruction.write_actions(
1372 actions=[ofp.action.set_field(ofp.oxm.ipv4_dst(set_ip_dst)),
1373 ofp.action.set_field(ofp.oxm.tcp_dst(set_tcp_dst)),
1374 ofp.action.group(action_group_id)]),
1375 ofp.instruction.goto_table(60)
1376 ],
1377 buffer_id=ofp.OFP_NO_BUFFER,
Pierbbdf3782016-08-22 17:58:26 -07001378 priority=1)
macauley_cheng6b133662015-11-09 13:52:39 +08001379 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)
1380 ctrl.message_send(request)
1381 return request
macauley_chengeffc20a2015-11-09 16:14:56 +08001382
1383#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
1384def add_snat_flow(ctrl, eth_type, ip_src, ip_proto, tcp_src, set_ip_src, set_tcp_src):
1385 match = ofp.match()
1386 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
1387 match.oxm_list.append(ofp.oxm.ipv4_src(ip_src))
1388 match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
1389 match.oxm_list.append(ofp.oxm.tcp_src(tcp_src))
Pierbbdf3782016-08-22 17:58:26 -07001390
macauley_chengeffc20a2015-11-09 16:14:56 +08001391 request = ofp.message.flow_add(
1392 table_id=29,
1393 cookie=42,
1394 match=match,
1395 instructions=[
1396 ofp.instruction.write_actions(
1397 actions=[ofp.action.set_field(ofp.oxm.ipv4_src(set_ip_src)),
1398 ofp.action.set_field(ofp.oxm.tcp_src(set_tcp_src))]),
1399 ofp.instruction.goto_table(30)
1400 ],
1401 buffer_id=ofp.OFP_NO_BUFFER,
Pierbbdf3782016-08-22 17:58:26 -07001402 priority=1)
macauley_chengeffc20a2015-11-09 16:14:56 +08001403 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)
1404 ctrl.message_send(request)
1405 return request
Pierbbdf3782016-08-22 17:58:26 -07001406
1407def get_vtap_lport_config_xml(dp_id, lport, phy_port, vlan, vnid, operation='merge'):
macauleyfddc4662015-07-27 17:40:30 +08001408 """
1409 Command Example:
1410 of-agent vtap 10001 ethernet 1/1 vid 1
1411 of-agent vtp 10001 vni 10
1412 """
1413 if vlan != 0:
1414 config_vtap_xml="""
1415 <config>
1416 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1417 <id>capable-switch-1</id>
1418 <resources>
1419 <port xc:operation="OPERATION">
Pierbbdf3782016-08-22 17:58:26 -07001420 <resource-id >LPORT</resource-id>
macauleyfddc4662015-07-27 17:40:30 +08001421 <features>
1422 <current>
1423 <rate>10Gb</rate>
1424 <medium>fiber</medium>
Pierbbdf3782016-08-22 17:58:26 -07001425 <pause>symmetric</pause>
macauleyfddc4662015-07-27 17:40:30 +08001426 </current>
1427 <advertised>
1428 <rate>10Gb</rate>
1429 <rate>100Gb</rate>
1430 <medium>fiber</medium>
1431 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001432 </advertised>
macauleyfddc4662015-07-27 17:40:30 +08001433 <supported>
1434 <rate>10Gb</rate>
1435 <rate>100Gb</rate>
1436 <medium>fiber</medium>
1437 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001438 </supported>
macauleyfddc4662015-07-27 17:40:30 +08001439 <advertised-peer>
1440 <rate>10Gb</rate>
1441 <rate>100Gb</rate>
1442 <medium>fiber</medium>
1443 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001444 </advertised-peer>
macauleyfddc4662015-07-27 17:40:30 +08001445 </features>
1446 <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1447 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
1448 <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
1449 <ofdpa10:vni>VNID</ofdpa10:vni>
1450 </ofdpa10:vtap>
Pierbbdf3782016-08-22 17:58:26 -07001451 </port>
macauleyfddc4662015-07-27 17:40:30 +08001452 </resources>
1453 <logical-switches>
1454 <switch>
1455 <id>DATAPATH_ID</id>
1456 <datapath-id>DATAPATH_ID</datapath-id>
1457 <resources>
1458 <port xc:operation="OPERATION">LPORT</port>
1459 </resources>
1460 </switch>
1461 </logical-switches>
1462 </capable-switch>
1463 </config>
Pierbbdf3782016-08-22 17:58:26 -07001464 """
macauleyfddc4662015-07-27 17:40:30 +08001465 else:
1466 config_vtap_xml="""
1467 <config>
1468 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1469 <id>capable-switch-1</id>
1470 <resources>
1471 <port xc:operation="OPERATION">
Pierbbdf3782016-08-22 17:58:26 -07001472 <resource-id >LPORT</resource-id>
macauleyfddc4662015-07-27 17:40:30 +08001473 <features>
1474 <current>
1475 <rate>10Gb</rate>
1476 <medium>fiber</medium>
Pierbbdf3782016-08-22 17:58:26 -07001477 <pause>symmetric</pause>
macauleyfddc4662015-07-27 17:40:30 +08001478 </current>
1479 <advertised>
1480 <rate>10Gb</rate>
1481 <rate>100Gb</rate>
1482 <medium>fiber</medium>
1483 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001484 </advertised>
macauleyfddc4662015-07-27 17:40:30 +08001485 <supported>
1486 <rate>10Gb</rate>
1487 <rate>100Gb</rate>
1488 <medium>fiber</medium>
1489 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001490 </supported>
macauleyfddc4662015-07-27 17:40:30 +08001491 <advertised-peer>
1492 <rate>10Gb</rate>
1493 <rate>100Gb</rate>
1494 <medium>fiber</medium>
1495 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001496 </advertised-peer>
macauleyfddc4662015-07-27 17:40:30 +08001497 </features>
1498 <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1499 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
1500 <ofdpa10:vni>VNID</ofdpa10:vni>
1501 </ofdpa10:vtap>
Pierbbdf3782016-08-22 17:58:26 -07001502 </port>
macauleyfddc4662015-07-27 17:40:30 +08001503 </resources>
1504 <logical-switches>
1505 <switch>
1506 <id>DATAPATH_ID</id>
1507 <datapath-id>DATAPATH_ID</datapath-id>
1508 <resources>
1509 <port xc:operation="OPERATION">LPORT</port>
1510 </resources>
1511 </switch>
1512 </logical-switches>
1513 </capable-switch>
1514 </config>
Pierbbdf3782016-08-22 17:58:26 -07001515 """
1516 str_datapath_id_f= "{:016x}".format(dp_id)
1517 str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
1518 config_vtap_xml=config_vtap_xml.replace("DATAPATH_ID", str_datapath_id)
1519 config_vtap_xml=config_vtap_xml.replace("LPORT", str(int(lport)))
1520 config_vtap_xml=config_vtap_xml.replace("PHY_PORT", str(phy_port))
1521 config_vtap_xml=config_vtap_xml.replace("VLAN_ID", str(vlan))
macauleyfddc4662015-07-27 17:40:30 +08001522 config_vtap_xml=config_vtap_xml.replace("VNID", str(vnid))
1523 config_vtap_xml=config_vtap_xml.replace("OPERATION", str(operation))
1524 return config_vtap_xml
Pierbbdf3782016-08-22 17:58:26 -07001525
1526def 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 +08001527 """
1528 Command Example:
1529 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 -07001530 of-agent vtp 10001 vni 10
macauleyfddc4662015-07-27 17:40:30 +08001531 """
1532
1533 config_vtep_xml="""
1534 <config>
1535 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1536 <id>capable-switch-1</id>
1537 <resources>
1538 <port xc:operation="OPERATION">
Pierbbdf3782016-08-22 17:58:26 -07001539 <resource-id>LPORT</resource-id>
macauleyfddc4662015-07-27 17:40:30 +08001540 <features>
1541 <current>
1542 <rate>10Gb</rate>
1543 <medium>fiber</medium>
Pierbbdf3782016-08-22 17:58:26 -07001544 <pause>symmetric</pause>
macauleyfddc4662015-07-27 17:40:30 +08001545 </current>
1546 <advertised>
1547 <rate>10Gb</rate>
1548 <rate>100Gb</rate>
1549 <medium>fiber</medium>
1550 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001551 </advertised>
macauleyfddc4662015-07-27 17:40:30 +08001552 <supported>
1553 <rate>10Gb</rate>
1554 <rate>100Gb</rate>
1555 <medium>fiber</medium>
1556 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001557 </supported>
macauleyfddc4662015-07-27 17:40:30 +08001558 <advertised-peer>
1559 <rate>10Gb</rate>
1560 <rate>100Gb</rate>
1561 <medium>fiber</medium>
1562 <pause>symmetric</pause>
Pierbbdf3782016-08-22 17:58:26 -07001563 </advertised-peer>
macauleyfddc4662015-07-27 17:40:30 +08001564 </features>
Pier265ad5f2017-02-28 17:46:28 +01001565 <ofdpa10:vtep xmlns:ofdpa10="urn:bcm:ofdpa10:accton01">
1566 <ofdpa10:src-ip>SRC_IP</ofdpa10:src-ip>
1567 <ofdpa10:dest-ip>DST_IP</ofdpa10:dest-ip>
1568 <ofdpa10:udp-src-port>UDP_SRC_PORT</ofdpa10:udp-src-port>
1569 <ofdpa10:vni xc:operation="OPERATION">
macauley25999cf2015-08-07 17:03:24 +08001570 <ofdpa10:id>VNID</ofdpa10:id>
1571 </ofdpa10:vni>
Pier265ad5f2017-02-28 17:46:28 +01001572 <ofdpa10:nexthop-id>NEXT_HOP_ID</ofdpa10:nexthop-id>
1573 <ofdpa10:ttl>TTL</ofdpa10:ttl>
1574 </ofdpa10:vtep>
Pierbbdf3782016-08-22 17:58:26 -07001575 </port>
macauleyfddc4662015-07-27 17:40:30 +08001576 </resources>
1577 <logical-switches>
1578 <switch>
1579 <id>DATAPATH_ID</id>
1580 <datapath-id>DATAPATH_ID</datapath-id>
1581 <resources>
1582 <port xc:operation="OPERATION">LPORT</port>
1583 </resources>
1584 </switch>
1585 </logical-switches>
1586 </capable-switch>
Pierbbdf3782016-08-22 17:58:26 -07001587 </config>
macauleyfddc4662015-07-27 17:40:30 +08001588 """
Pierbbdf3782016-08-22 17:58:26 -07001589 str_datapath_id_f= "{:016x}".format(dp_id)
1590 str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
1591 config_vtep_xml=config_vtep_xml.replace("DATAPATH_ID", str_datapath_id)
macauley25999cf2015-08-07 17:03:24 +08001592 config_vtep_xml=config_vtep_xml.replace("LPORT", str(int(lport)))
Pierbbdf3782016-08-22 17:58:26 -07001593 config_vtep_xml=config_vtep_xml.replace("SRC_IP", str(src_ip))
1594 config_vtep_xml=config_vtep_xml.replace("DST_IP", str(dst_ip))
1595 config_vtep_xml=config_vtep_xml.replace("UDP_SRC_PORT", str(udp_src_port))
1596 config_vtep_xml=config_vtep_xml.replace("NEXT_HOP_ID", str(next_hop_id))
1597 config_vtep_xml=config_vtep_xml.replace("TTL", str(ttl))
macauleyfddc4662015-07-27 17:40:30 +08001598 config_vtep_xml=config_vtep_xml.replace("VNID", str(vnid))
Pierbbdf3782016-08-22 17:58:26 -07001599 config_vtep_xml=config_vtep_xml.replace("OPERATION", str(operation))
macauleyfddc4662015-07-27 17:40:30 +08001600
Pierbbdf3782016-08-22 17:58:26 -07001601 return config_vtep_xml
1602
1603def get_next_hop_config_xml(next_hop_id, dst_mac, phy_port, vlan, operation='merge'):
macauleyfddc4662015-07-27 17:40:30 +08001604 #of-agent nexthop 2 destination user-input-dst-mac ethernet 1/2 vid 2
1605 config_nexthop_xml="""
1606 <config>
1607 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1608 <ofdpa10:next-hop xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1609 <ofdpa10:id>NEXT_HOP_ID</ofdpa10:id>
1610 <ofdpa10:dest-mac>DST_MAC</ofdpa10:dest-mac>
1611 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
1612 <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
1613 </ofdpa10:next-hop>
1614 </of11-config:capable-switch>
1615 </config>
1616 """
1617 config_nexthop_xml=config_nexthop_xml.replace("VLAN_ID", str(vlan))
Pierbbdf3782016-08-22 17:58:26 -07001618 config_nexthop_xml=config_nexthop_xml.replace("PHY_PORT", str(phy_port))
1619 config_nexthop_xml=config_nexthop_xml.replace("NEXT_HOP_ID", str(next_hop_id))
1620 config_nexthop_xml=config_nexthop_xml.replace("DST_MAC", str(dst_mac))
1621 config_nexthop_xml=config_nexthop_xml.replace("OPERATION", str(operation))
1622 return config_nexthop_xml
macauleyfddc4662015-07-27 17:40:30 +08001623
Pierbbdf3782016-08-22 17:58:26 -07001624def get_vni_config_xml(vni_id, mcast_ipv4, next_hop_id, operation='merge'):
macauleyfddc4662015-07-27 17:40:30 +08001625 #of-agent vni 10 multicast 224.1.1.1 nexthop 20
Pierbbdf3782016-08-22 17:58:26 -07001626 if mcast_ipv4!=None:
macauleyfddc4662015-07-27 17:40:30 +08001627 config_vni_xml="""
1628 <config>
1629 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1630 <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1631 <ofdpa10:id>VNID</ofdpa10:id>
1632 <ofdpa10:vni-multicast-group>MCAST_IP</ofdpa10:vni-multicast-group>
1633 <ofdpa10:multicast-group-nexthop-id>NEXT_HOP_ID</ofdpa10:multicast-group-nexthop-id>
1634 </ofdpa10:vni>
1635 </of11-config:capable-switch>
1636 </config>
Pierbbdf3782016-08-22 17:58:26 -07001637 """
1638 config_vni_xml=config_vni_xml.replace("NEXT_HOP_ID", str(next_hop_id))
1639 config_vni_xml=config_vni_xml.replace("MCAST_IP", str(mcast_ipv4))
macauleyfddc4662015-07-27 17:40:30 +08001640 else:
1641 config_vni_xml="""
1642 <config>
1643 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1644 <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1645 <ofdpa10:id>VNID</ofdpa10:id>
1646 </ofdpa10:vni>
1647 </of11-config:capable-switch>
1648 </config>
Pierbbdf3782016-08-22 17:58:26 -07001649 """
1650
1651 config_vni_xml=config_vni_xml.replace("VNID", str(vni_id))
1652 config_vni_xml=config_vni_xml.replace("OPERATION", str(operation))
macauleyfddc4662015-07-27 17:40:30 +08001653 return config_vni_xml
Pierbbdf3782016-08-22 17:58:26 -07001654
1655def get_featureReplay(self):
macauleyfddc4662015-07-27 17:40:30 +08001656 req = ofp.message.features_request()
1657 res, raw = self.controller.transact(req)
Pierbbdf3782016-08-22 17:58:26 -07001658 self.assertIsNotNone(res, "Did not receive a response from the DUT.")
macauleyfddc4662015-07-27 17:40:30 +08001659 self.assertEqual(res.type, ofp.OFPT_FEATURES_REPLY,
1660 ("Unexpected packet type %d received in response to "
1661 "OFPT_FEATURES_REQUEST") % res.type)
Pierbbdf3782016-08-22 17:58:26 -07001662 return res
1663
macauleyfddc4662015-07-27 17:40:30 +08001664def send_edit_config(switch_ip, xml, target='runing'):
1665 NETCONF_ACCOUNT="netconfuser"
1666 NETCONF_PASSWD="netconfuser"
1667 with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
1668 try:
Pierbbdf3782016-08-22 17:58:26 -07001669 m.edit_config(target='running',
1670 config=xml,
1671 default_operation='merge',
macauleyfddc4662015-07-27 17:40:30 +08001672 error_option='stop-on-error')
1673
1674 except Exception as e:
1675 logging.info("Fail to set xml %s", xml)
1676 return False
1677
Pier265ad5f2017-02-28 17:46:28 +01001678 #return m.get_config(source='running').data_xml
macauleyfddc4662015-07-27 17:40:30 +08001679 return True
1680
1681def send_delete_config(switch_ip, xml, target='runing'):
1682 NETCONF_ACCOUNT="netconfuser"
1683 NETCONF_PASSWD="netconfuser"
1684 with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
1685 try:
Pierbbdf3782016-08-22 17:58:26 -07001686 m.edit_config(target='running',
1687 config=xml,
1688 default_operation='delete',
macauleyfddc4662015-07-27 17:40:30 +08001689 error_option='stop-on-error')
1690
1691 except Exception as e:
1692 logging.info("Fail to set xml %s", xml)
1693 return False
1694
Pier265ad5f2017-02-28 17:46:28 +01001695 #return m.get_config(source='running').data_xml
macauleyfddc4662015-07-27 17:40:30 +08001696 return True
Pierbbdf3782016-08-22 17:58:26 -07001697
macauleyfddc4662015-07-27 17:40:30 +08001698def get_edit_config(switch_ip, target='runing'):
1699 NETCONF_ACCOUNT="netconfuser"
1700 NETCONF_PASSWD="netconfuser"
1701 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 +01001702 return m.get_config(source='running').data_xml
macauleydbff3272015-07-30 14:07:16 +08001703
macauley_cheng67da9262015-08-31 15:18:41 +08001704
1705"""
1706MPLS
1707"""
1708
1709OFDPA_MPLS_SUBTYPE_SHIFT=24
Pierbbdf3782016-08-22 17:58:26 -07001710OFDPA_MPLS_GROUP_SUBTYPE_L2_VPN_LABEL=1
macauley_cheng67da9262015-08-31 15:18:41 +08001711OFDPA_MPLS_GROUP_SUBTYPE_L3_VPN_LABEL=2
1712OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL1=3
1713OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL2=4
1714OFDPA_MPLS_GROUP_SUBTYPE_SWAP_LABEL=5
1715OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP=6
1716OFDPA_MPLS_GROUP_SUBTYPE_ECMP=8
1717OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG=10
1718
Piercf76e802016-09-19 20:16:35 -07001719
1720
1721
macauley_cheng67da9262015-08-31 15:18:41 +08001722def encode_mpls_interface_group_id(subtype, index):
1723 index=index&0x00ffffff
1724 assert(subtype==0)
1725 return index + (9 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
1726
1727def encode_mpls_label_group_id(subtype, index):
1728 index=index&0x00ffffff
1729 assert(subtype <=5 or subtype==0)
1730 #1: l2 vpn label
1731 #2: l3 vpn label
1732 #3: mpls tunnel label 1
1733 #4: mpls tunnel lable 2
1734 #5: mpls swap label
Pierbbdf3782016-08-22 17:58:26 -07001735 return index + (9 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
macauley_cheng67da9262015-08-31 15:18:41 +08001736
1737def encode_mpls_forwarding_group_id(subtype, index):
1738 index=index&0x00ffffff
1739 assert(subtype==6 or subtype==8 or subtype==10)
Pierbbdf3782016-08-22 17:58:26 -07001740 return index + (10 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
macauley_cheng67da9262015-08-31 15:18:41 +08001741
1742
Pier1e4e98e2016-10-26 14:36:05 -07001743def 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 +08001744 action=[]
1745 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
1746 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
Pier265ad5f2017-02-28 17:46:28 +01001747 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vid)))
macauley_cheng67da9262015-08-31 15:18:41 +08001748 action.append(ofp.action.group(ref_gid))
Pierbbdf3782016-08-22 17:58:26 -07001749
macauley_cheng67da9262015-08-31 15:18:41 +08001750 buckets = [ofp.bucket(actions=action)]
1751
1752 mpls_group_id =encode_mpls_interface_group_id(subtype, index)
1753 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
1754 group_id=mpls_group_id,
1755 buckets=buckets
1756 )
Andreas Pantelopoulos6c76b942018-01-22 10:03:02 -08001757
1758 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 +08001759 ctrl.message_send(request)
Pier1e4e98e2016-10-26 14:36:05 -07001760
1761 if send_barrier:
1762 do_barrier(ctrl)
macauley_cheng67da9262015-08-31 15:18:41 +08001763 return mpls_group_id, request
1764
Piercf76e802016-09-19 20:16:35 -07001765def add_mpls_tunnel_label_group(
1766 ctrl,
1767 ref_gid,
1768 subtype,
1769 index,
1770 label,
1771 ):
1772
1773 action=[]
1774 action.append(ofp.action.push_mpls(0x8847))
1775 action.append(ofp.action.set_field(ofp.oxm.mpls_label(label)))
1776 action.append(ofp.action.group(ref_gid))
1777 buckets = [ofp.bucket(actions=action)]
1778
1779 mpls_group_id = encode_mpls_label_group_id(subtype, index)
1780 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
1781 group_id=mpls_group_id,
1782 buckets=buckets
1783 )
1784 ctrl.message_send(request)
1785
1786 return mpls_group_id, request
1787
Pierb5da4c92016-09-21 11:23:35 -07001788def add_mpls_swap_label_group(
1789 ctrl,
1790 ref_gid,
1791 subtype,
1792 index,
1793 label,
1794 ):
1795
1796 action=[]
1797 action.append(ofp.action.set_field(ofp.oxm.mpls_label(label)))
1798 action.append(ofp.action.group(ref_gid))
1799 buckets = [ofp.bucket(actions=action)]
1800
1801 mpls_group_id = encode_mpls_label_group_id(subtype, index)
1802 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
1803 group_id=mpls_group_id,
1804 buckets=buckets
1805 )
Andreas Pantelopoulos6c76b942018-01-22 10:03:02 -08001806 logging.debug("Adding MPLS Swap group %02x, label %d", mpls_group_id, label)
Pierb5da4c92016-09-21 11:23:35 -07001807 ctrl.message_send(request)
1808
1809 return mpls_group_id, request
1810
Pierbbdf3782016-08-22 17:58:26 -07001811def add_mpls_label_group(ctrl, subtype, index, ref_gid,
macauley_cheng67da9262015-08-31 15:18:41 +08001812 lmep_id=-1,
1813 qos_index=-1,
1814 push_l2_header=False,
1815 push_vlan=False,
1816 push_mpls_header=False,
1817 push_cw=False,
1818 set_mpls_label=None,
1819 set_bos=None,
1820 set_tc=None,
1821 set_tc_from_table=False,
1822 cpy_tc_outward=False,
1823 set_ttl=None,
1824 cpy_ttl_outward=False,
1825 oam_lm_tx_count=False,
Pier1e4e98e2016-10-26 14:36:05 -07001826 set_pri_from_table=False,
1827 send_barrier=False
macauley_cheng67da9262015-08-31 15:18:41 +08001828 ):
1829 """
1830 @ref_gid: only can be mpls intf group or mpls tunnel label 1/2 group
Pierbbdf3782016-08-22 17:58:26 -07001831 """
macauley_cheng67da9262015-08-31 15:18:41 +08001832 action=[]
1833
1834 if push_vlan== True:
1835 action.append(ofp.action.push_vlan(0x8100))
1836 if push_mpls_header== True:
1837 action.append(ofp.action.push_mpls(0x8847))
1838 if set_mpls_label != None:
1839 action.append(ofp.action.set_field(ofp.oxm.mpls_label(set_mpls_label)))
1840 if set_bos != None:
1841 action.append(ofp.action.set_field(ofp.oxm.mpls_bos(set_bos)))
1842 if set_tc != None:
1843 assert(set_tc_from_table==False)
1844 action.append(ofp.action.set_field(ofp.oxm.mpls_tc(set_tc)))
1845 if set_ttl != None:
Pierbbdf3782016-08-22 17:58:26 -07001846 action.append(ofp.action.set_mpls_ttl(set_ttl))
macauley_cheng67da9262015-08-31 15:18:41 +08001847 if cpy_ttl_outward == True:
Pierbbdf3782016-08-22 17:58:26 -07001848 action.append(ofp.action.copy_ttl_out())
macauley_cheng67da9262015-08-31 15:18:41 +08001849 """
1850 ofdpa experimenter
Pierbbdf3782016-08-22 17:58:26 -07001851 """
macauley_cheng67da9262015-08-31 15:18:41 +08001852 if push_l2_header== True:
Pierbbdf3782016-08-22 17:58:26 -07001853 action.append(ofp.action.ofdpa_push_l2_header())
macauley_cheng67da9262015-08-31 15:18:41 +08001854 if set_tc_from_table== True:
1855 assert(qos_index>=0)
1856 assert(set_tc == None)
Pierbbdf3782016-08-22 17:58:26 -07001857 action.append(ofp.action.ofdpa_set_tc_from_table(qos_index))
macauley_cheng67da9262015-08-31 15:18:41 +08001858 if cpy_tc_outward == True:
Pierbbdf3782016-08-22 17:58:26 -07001859 action.append(ofp.action.ofdpa_copy_tc_out())
macauley_cheng67da9262015-08-31 15:18:41 +08001860 if oam_lm_tx_count == True:
Pierbbdf3782016-08-22 17:58:26 -07001861 assert(qos_index>=0 and lmep_id>=0)
1862 action.append(ofp.action.ofdpa_oam_lm_tx_count(lmep_id, qos_index))
macauley_cheng67da9262015-08-31 15:18:41 +08001863 if set_pri_from_table == True:
Pierbbdf3782016-08-22 17:58:26 -07001864 assert(qos_index>=0)
1865 action.append(ofp.action.ofdpa_set_qos_from_table(qos_index))
macauley_cheng67da9262015-08-31 15:18:41 +08001866 if push_cw == True:
1867 action.append(ofp.action.ofdpa_push_cw())
Pierbbdf3782016-08-22 17:58:26 -07001868
1869 action.append(ofp.action.group(ref_gid))
macauley_cheng67da9262015-08-31 15:18:41 +08001870 buckets = [ofp.bucket(actions=action)]
Pierbbdf3782016-08-22 17:58:26 -07001871
macauley_cheng67da9262015-08-31 15:18:41 +08001872 mpls_group_id = encode_mpls_label_group_id(subtype, index)
1873 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
1874 group_id=mpls_group_id,
1875 buckets=buckets
1876 )
1877 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -07001878
Pier1e4e98e2016-10-26 14:36:05 -07001879 if send_barrier:
1880 do_barrier(ctrl)
1881
Pierbbdf3782016-08-22 17:58:26 -07001882 return mpls_group_id, request
1883
Piercf76e802016-09-19 20:16:35 -07001884def add_mpls_l2_port_flow(ctrl, of_port, mpls_l2_port, tunnel_index, ref_gid, qos_index=0):
1885 """
1886 Only action is Group, which must indicate one of:
1887 MPLS L2 VPN Label or Fast Failover Protection Group.
1888 ref_gid contains this information
1889 """
1890 tunnel_id = tunnel_index + ofp.oxm.TUNNEL_ID_BASE
1891
1892 match = ofp.match()
1893 match.oxm_list.append(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port))
1894 match.oxm_list.append(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE))
1895
Pier23784aa2016-09-19 20:08:21 -07001896
Pier265ad5f2017-02-28 17:46:28 +01001897 write_actions = []
1898 write_actions.append(ofp.action.group(ref_gid))
1899 apply_actions = []
Piercf76e802016-09-19 20:16:35 -07001900 assert(qos_index>=0)
Pier265ad5f2017-02-28 17:46:28 +01001901 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 -07001902
1903 request = ofp.message.flow_add(
1904 table_id=MPLS_L2_PORT_FLOW_TABLE,
1905 cookie=42,
1906 match=match,
1907 instructions=[
Pier265ad5f2017-02-28 17:46:28 +01001908 ofp.instruction.apply_actions(actions=apply_actions),
1909 ofp.instruction.write_actions(actions=write_actions),
1910 ofp.instruction.goto_table(MPLS_L2_PORT_PCP_TRUST_FLOW_TABLE)
1911 ],
Piercf76e802016-09-19 20:16:35 -07001912 buffer_id=ofp.OFP_NO_BUFFER,
1913 priority=1)
1914 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)
1915 ctrl.message_send(request)
1916 return request
1917
1918 return
1919
Pierbbdf3782016-08-22 17:58:26 -07001920def add_mpls_forwarding_group(ctrl, subtype, index, ref_gids,
1921 watch_port=None,
Pier265ad5f2017-02-28 17:46:28 +01001922 watch_group=ofp.OFPP_ANY,
1923 push_vlan=None,
macauley_chengd17ce512015-08-31 17:45:51 +08001924 pop_vlan=None,
macauley_cheng67da9262015-08-31 15:18:41 +08001925 set_vid=None):
1926 assert(subtype == OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP
Pier265ad5f2017-02-28 17:46:28 +01001927 or subtype == OFDPA_MPLS_GROUP_SUBTYPE_ECMP
1928 or subtype == OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG)
macauley_chengd17ce512015-08-31 17:45:51 +08001929
macauley_cheng67da9262015-08-31 15:18:41 +08001930 buckets=[]
1931 if subtype == OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP:
macauley_chengd17ce512015-08-31 17:45:51 +08001932 group_type = ofp.OFPGT_FF
macauley_cheng67da9262015-08-31 15:18:41 +08001933 for gid in ref_gids:
macauley_chengd17ce512015-08-31 17:45:51 +08001934 action=[]
Pierbbdf3782016-08-22 17:58:26 -07001935 action.append(ofp.action.group(gid))
macauley_chengd17ce512015-08-31 17:45:51 +08001936 buckets.append(ofp.bucket(watch_port=watch_port, watch_group=watch_group,actions=action))
1937
macauley_cheng67da9262015-08-31 15:18:41 +08001938 elif subtype == OFDPA_MPLS_GROUP_SUBTYPE_ECMP:
1939 group_type = ofp.OFPGT_SELECT
1940 for gid in ref_gids:
macauley_chengd17ce512015-08-31 17:45:51 +08001941 action=[]
Pierbbdf3782016-08-22 17:58:26 -07001942 action.append(ofp.action.group(gid))
macauley_cheng67da9262015-08-31 15:18:41 +08001943 buckets.append(ofp.bucket(actions=action))
macauley_chengd17ce512015-08-31 17:45:51 +08001944
macauley_cheng67da9262015-08-31 15:18:41 +08001945 elif subtype == OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG:
1946 group_type = ofp.OFPGT_INDIRECT
macauley_chengd17ce512015-08-31 17:45:51 +08001947 action=[]
macauley_cheng67da9262015-08-31 15:18:41 +08001948 if set_vid!=None:
Flavio Castro91d1a552016-05-17 16:59:44 -07001949 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+set_vid)))
macauley_cheng67da9262015-08-31 15:18:41 +08001950 if push_vlan!=None:
Pierbbdf3782016-08-22 17:58:26 -07001951 action.append(ofp.action.push_vlan(push_vlan))
macauley_cheng67da9262015-08-31 15:18:41 +08001952 if pop_vlan!=None:
Pierbbdf3782016-08-22 17:58:26 -07001953 action.append(ofp.action.pop_vlan())
1954 action.append(ofp.action.group(ref_gids[0]))
macauley_cheng67da9262015-08-31 15:18:41 +08001955 buckets.append(ofp.bucket(actions=action))
macauley_chengd17ce512015-08-31 17:45:51 +08001956
1957 mpls_group_id = encode_mpls_forwarding_group_id(subtype, index)
macauley_cheng67da9262015-08-31 15:18:41 +08001958 request = ofp.message.group_add(group_type=group_type,
macauley_cheng67da9262015-08-31 15:18:41 +08001959 group_id=mpls_group_id,
1960 buckets=buckets
1961 )
1962 ctrl.message_send(request)
Pierbbdf3782016-08-22 17:58:26 -07001963 return mpls_group_id, request
macauley_chengd17ce512015-08-31 17:45:51 +08001964
1965
macauley_cheng67da9262015-08-31 15:18:41 +08001966"""
Piercf76e802016-09-19 20:16:35 -07001967display
Pierbbdf3782016-08-22 17:58:26 -07001968"""
macauleydbff3272015-07-30 14:07:16 +08001969def print_current_table_flow_stat(ctrl, table_id=0xff):
1970 stat_req=ofp.message.flow_stats_request()
1971 response, pkt = ctrl.transact(stat_req)
1972 if response == None:
1973 print "no response"
1974 return None
1975 print len(response.entries)
1976 for obj in response.entries:
1977 print "match ", obj.match
1978 print "cookie", obj.cookie
1979 print "priority", obj.priority
1980 print "idle_timeout", obj.idle_timeout
1981 print "hard_timeout", obj.hard_timeout
1982 #obj.actions
Flavio Castro167f5bd2015-12-02 19:33:53 -05001983 print "packet count: %lx"%obj.packet_count