blob: 592265e5bb64feef309eff82c54978c9b69d84b3 [file] [log] [blame]
Sreeju Sreedhare3fefd92019-04-02 15:57:15 -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
16import logging
17
18from oftest import config
19import oftest.base_tests as base_tests
20import ofp
21import time
22from oftest.testutils import *
23from oftest.parse import parse_ipv6
Roman Bubyr8c385572019-04-25 11:45:13 +030024import pexpect
25import os
26import json
27import sys
Sreeju Sreedhare3fefd92019-04-02 15:57:15 -070028
29from ncclient import manager
30import ncclient
31
32OFDPA_GROUP_TYPE_SHIFT=28
33OFDPA_VLAN_ID_SHIFT =16
34OFDPA_TUNNEL_ID_SHIFT =12
35OFDPA_TUNNEL_SUBTYPE_SHIFT=10
36
37#VLAN_TABLE_FLAGS
38VLAN_TABLE_FLAG_ONLY_UNTAG=1
39VLAN_TABLE_FLAG_ONLY_TAG =2
40VLAN_TABLE_FLAG_ONLY_BOTH =3
41VLAN_TABLE_FLAG_ONLY_STACKED=5
42VLAN_TABLE_FLAG_PRIORITY=6
43VLAN_TABLE_FLAG_ONLY_UNTAG_PRIORITY=7
44VLAN_TABLE_FLAG_ONLY_POP_VLAN=8
45
46PORT_FLOW_TABLE=0
47VLAN_FLOW_TABLE=10
48VLAN_1_FLOW_TABLE=11
49MPLS_L2_PORT_FLOW_TABLE=13
50MPLS_L2_PORT_DSCP_TRUST_FLOW_TABLE=15
51MPLS_L2_PORT_PCP_TRUST_FLOW_TABLE=16
52TERMINATION_FLOW_TABLE=20
53MPLS_TYPE_FLOW_TABLE=29
54UCAST_ROUTING_FLOW_TABLE=30
55MCAST_ROUTING_FLOW_TABLE=40
56BRIDGE_FLOW_TABLE=50
57ACL_FLOW_TABLE=60
58EGRESS_TPID_FLOW_TABLE = 235
59
60ONF_EXPERIMENTER_ID = 0x4F4E4600
61
62EGRESS_VLAN_FLOW_TABLE=210
63EGRESS_VLAN_1_FLOW_TABLE=211
64EGRESS_MAINTENANCE_POINT_FLOW_TABLE=226
65EGRESS_DSCP_TABLE=230
66EGRESS_TPID_TABLE=235
67EGRESS_SOURCE_MAC_LEARNING_TABLE=254
68
69def convertIP4toStr(ip_addr):
70 a=(ip_addr&0xff000000)>>24
71 b=(ip_addr&0x00ff0000)>>16
72 c=(ip_addr&0x0000ff00)>>8
73 d=(ip_addr&0x000000ff)
74 return str(a)+"."+str(b)+"."+str(c)+"."+str(d)
75
76def convertMACtoStr(mac):
77 if not isinstance(mac, list):
78 assert(0)
79
80 return ':'.join(['%02X' % x for x in mac])
81
82def getSwitchCpuMACFromDPID(dpid):
83 str_datapath_id_f= "{:016x}".format(dpid)
84 str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
85 switch_cpu_mac_str=str_datapath_id[6:]
86 switch_cpu_mac = switch_cpu_mac_str.split(":")
87 switch_cpu_mac=[int(switch_cpu_mac[i],16) for i in range(0, len(switch_cpu_mac))]
88
89 return switch_cpu_mac_str, switch_cpu_mac
90
Roman Bubyr8c385572019-04-25 11:45:13 +030091
Sreeju Sreedhare3fefd92019-04-02 15:57:15 -070092def DumpGroup(stats, verify_group_stats, always_show=True):
93 if(len(stats) > len(verify_group_stats)):
94 min_len = len(verify_group_stats)
95 print "Stats Len is not the same, stats>verify_group_stats"
96 if(len(stats)< len(verify_group_stats)):
97 min_len = len(stats)
98 print "Stats Len is not the same, stats<verify_group_stats"
99 else:
100 min_len = len(stats)
101
102 print "\r\n"
103 for i in range(min_len):
104 gs = stats[i]
105 gv = verify_group_stats[i]
106 print "FromSwtich:(GID=%lx, TYPE=%lx)\r\nVerify :(GID=%lx, TYPE=%lx)"%(gs.group_id, gs.group_type, gv.group_id, gv.group_type)
107 if(len(gs.buckets) != len(gv.buckets)):
108 print "buckets len is not the same gs %lx, gv %lx",(len(gs.buckets), len(gv.buckets))
109
110 for j in range(len(gs.buckets)):
111 b1=gs.buckets[j]
112 b2=gv.buckets[j]
113 if(len(b1.actions) != len(b2.actions)):
114 print "action len is not the same"
115
116 for k in range(len(b1.actions)):
117 a1=b1.actions[k]
118 a2=b2.actions[k]
119 if(always_show == True):
120 print "a1:"+a1.show()
121 print "a2:"+a2.show()
122
123def AssertGroup(self, stats, verify_group_stats):
124 self.assertTrue(len(stats) ==len(verify_group_stats), "stats len is not the same")
125
126 for i in range(len(stats)):
127 gs = stats[i]
128 gv = verify_group_stats[i]
129 self.assertTrue(len(gs.buckets) == len(gv.buckets), "buckets len is not the same")
130
131 for j in range(len(gs.buckets)):
132 b1=gs.buckets[j]
133 b2=gv.buckets[j]
134 self.assertTrue(len(b1.actions) == len(b2.actions), "action len is not the same")
135
136 for k in range(len(b1.actions)):
137 a1=b1.actions[k]
138 a2=b2.actions[k]
139 self.assertEquals(a1, a2, "action is not the same")
140
141def encode_l2_interface_group_id(vlan, id):
142 return id + (vlan << OFDPA_VLAN_ID_SHIFT)
143
144def encode_l2_rewrite_group_id(id):
145 return id + (1 << OFDPA_GROUP_TYPE_SHIFT)
146
147def encode_l3_unicast_group_id(id):
148 return id + (2 << OFDPA_GROUP_TYPE_SHIFT)
149
150def encode_l2_mcast_group_id(vlan, id):
151 return id + (vlan << OFDPA_VLAN_ID_SHIFT) + (3 << OFDPA_GROUP_TYPE_SHIFT)
152
153def encode_l2_flood_group_id(vlan, id):
154 return id + (vlan << OFDPA_VLAN_ID_SHIFT) + (4 << OFDPA_GROUP_TYPE_SHIFT)
155
156def encode_l3_interface_group_id(id):
157 return id + (5 << OFDPA_GROUP_TYPE_SHIFT)
158
159def encode_l3_mcast_group_id(vlan, id):
160 return id + (vlan << OFDPA_VLAN_ID_SHIFT)+(6 << OFDPA_GROUP_TYPE_SHIFT)
161
162def encode_l3_ecmp_group_id(id):
163 return id + (7 << OFDPA_GROUP_TYPE_SHIFT)
164
165def encode_l2_unfiltered_group_id(id):
166 return id + (11 << OFDPA_GROUP_TYPE_SHIFT)
167
168def encode_l2_loadbal_group_id(id):
169 return id + (12 << OFDPA_GROUP_TYPE_SHIFT)
170
171def encode_l2_overlay_group_id(tunnel_id, subtype, index):
172 tunnel_id=tunnel_id&0xffff #16 bits
173 subtype = subtype&3 #2 bits
174 index = index & 0x3f #10 bits
175 return index + (tunnel_id << OFDPA_TUNNEL_ID_SHIFT)+ (subtype<<OFDPA_TUNNEL_SUBTYPE_SHIFT)+(8 << OFDPA_GROUP_TYPE_SHIFT)
176
177def add_l2_unfiltered_group(ctrl, ports, send_barrier=False, allow_vlan_translation=1):
178 # group table
179 # set up untag groups for each port
180 group_id_list=[]
181 msgs=[]
182 for of_port in ports:
183 # do stuff
184 group_id = encode_l2_unfiltered_group_id(of_port)
185 group_id_list.append(group_id)
186 actions = [ofp.action.output(of_port)]
187
188 actions.append(ofp.action.set_field(ofp.oxm.exp1ByteValue(exp_type=24, value=allow_vlan_translation)))
189 buckets = [ofp.bucket(actions=actions)]
190 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
191 group_id=group_id,
192 buckets=buckets
193 )
194 ctrl.message_send(request)
195 msgs.append(request)
196
197 if send_barrier:
198 do_barrier(ctrl)
199
200 return group_id_list, msgs
201
202def add_one_l2_unfiltered_group(ctrl, of_port, send_barrier=False):
203 # group table
204 # set up untag groups for each port
205 group_id = encode_l2_unfiltered_group_id(of_port)
206 actions = [ofp.action.output(of_port)]
207 actions.append(ofp.action.set_field(ofp.oxm.exp1ByteValue(exp_type=24, value=1)))
208
209 buckets = [ofp.bucket(actions=actions)]
210 request = ofp.message.group_add(
211 group_type=ofp.OFPGT_INDIRECT,
212 group_id=group_id,
213 buckets=buckets
214 )
215 ctrl.message_send(request)
216
217 if send_barrier:
218 do_barrier(ctrl)
219
220 return group_id, request
221
222def add_l2_interface_group(ctrl, ports, vlan_id=1, is_tagged=False, send_barrier=False):
223 # group table
224 # set up untag groups for each port
225 group_id_list=[]
226 msgs=[]
227 for of_port in ports:
228 # do stuff
229 group_id = encode_l2_interface_group_id(vlan_id, of_port)
230 group_id_list.append(group_id)
231 if is_tagged:
232 actions = [
233 ofp.action.output(of_port),
234 ]
235 else:
236 actions = [
237 ofp.action.pop_vlan(),
238 ofp.action.output(of_port),
239 ]
240
241 buckets = [
242 ofp.bucket(actions=actions),
243 ]
244
245 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
246 group_id=group_id,
247 buckets=buckets
248 )
249 ctrl.message_send(request)
250 msgs.append(request)
251
252 if send_barrier:
253 do_barrier(ctrl)
254
255 return group_id_list, msgs
256
257def add_one_l2_interface_group(ctrl, port, vlan_id=1, is_tagged=False, send_barrier=False):
258 # group table
259 # set up untag groups for each port
260 group_id = encode_l2_interface_group_id(vlan_id, port)
261
262 if is_tagged:
263 actions = [
264 ofp.action.output(port),
265 ]
266 else:
267 actions = [
268 ofp.action.pop_vlan(),
269 ofp.action.output(port),
270 ]
271
272 buckets = [
273 ofp.bucket(actions=actions),
274 ]
275
276 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
277 group_id=group_id,
278 buckets=buckets
279 )
280 ctrl.message_send(request)
281
282 if send_barrier:
283 do_barrier(ctrl)
284
285 return group_id, request
286
287def add_l2_mcast_group(ctrl, ports, vlanid, mcast_grp_index):
288 buckets=[]
289 for of_port in ports:
290 group_id = encode_l2_interface_group_id(vlanid, of_port)
291 action=[ofp.action.group(group_id)]
292 buckets.append(ofp.bucket(actions=action))
293
294 group_id =encode_l2_mcast_group_id(vlanid, mcast_grp_index)
295 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
296 group_id=group_id,
297 buckets=buckets
298 )
299 ctrl.message_send(request)
300 return request
301
302def add_l2_flood_group(ctrl, ports, vlanid, id):
303 buckets=[]
304 for of_port in ports:
305 group_id = encode_l2_interface_group_id(vlanid, of_port)
306 action=[ofp.action.group(group_id)]
307 buckets.append(ofp.bucket(actions=action))
308
309 group_id =encode_l2_flood_group_id(vlanid, id)
310 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
311 group_id=group_id,
312 buckets=buckets
313 )
314 ctrl.message_send(request)
315 return request
316
317def add_l2_flood_group_with_gids(ctrl, gids, vlanid, id, send_barrier=False):
318 buckets=[]
319 for gid in gids:
320 action=[ofp.action.group(gid)]
321 buckets.append(ofp.bucket(actions=action))
322
323 group_id =encode_l2_flood_group_id(vlanid, id)
324 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
325 group_id=group_id,
326 buckets=buckets
327 )
328 ctrl.message_send(request)
329
330 if send_barrier:
331 do_barrier(ctrl)
332
333 return request
334
335def mod_l2_flood_group(ctrl, ports, vlanid, id):
336 buckets=[]
337 for of_port in ports:
338 group_id = encode_l2_interface_group_id(vlanid, of_port)
339 action=[ofp.action.group(group_id)]
340 buckets.append(ofp.bucket(actions=action))
341
342 group_id =encode_l2_flood_group_id(vlanid, id)
343 request = ofp.message.group_modify(group_type=ofp.OFPGT_ALL,
344 group_id=group_id,
345 buckets=buckets
346 )
347 ctrl.message_send(request)
348 return request
349
350
351def add_l2_rewrite_group(ctrl, port, vlanid, id, src_mac, dst_mac):
352 group_id = encode_l2_interface_group_id(vlanid, port)
353
354 action=[]
355 if src_mac is not None:
356 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
357
358 if dst_mac is not None:
359 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
360
361 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlanid)))
362
363 action.append(ofp.action.group(group_id))
364
365 buckets = [ofp.bucket(actions=action)]
366
367 group_id =encode_l2_rewrite_group_id(id)
368 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
369 group_id=group_id,
370 buckets=buckets
371 )
372 ctrl.message_send(request)
373 return request
374
375def add_l3_unicast_group(ctrl, port, vlanid, id, src_mac, dst_mac, send_barrier=False, gid=None):
376
377 if (not gid):
378 group_id = encode_l2_interface_group_id(vlanid, port)
379 else:
380 group_id = gid
381
382 action=[]
383 if src_mac is not None:
384 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
385
386 if dst_mac is not None:
387 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
388
389 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlanid)))
390
391 action.append(ofp.action.group(group_id))
392
393 buckets = [ofp.bucket(actions=action)]
394
395 group_id =encode_l3_unicast_group_id(id)
396 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
397 group_id=group_id,
398 buckets=buckets
399 )
400 ctrl.message_send(request)
401
402 if send_barrier:
403 do_barrier(ctrl)
404
405 return request
406
407def add_l3_interface_group(ctrl, port, vlanid, id, src_mac):
408 group_id = encode_l2_interface_group_id(vlanid, port)
409
410 action=[]
411 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
412 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlanid)))
413 action.append(ofp.action.group(group_id))
414
415 buckets = [ofp.bucket(actions=action)]
416
417 group_id =encode_l3_interface_group_id(id)
418 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
419 group_id=group_id,
420 buckets=buckets
421 )
422 ctrl.message_send(request)
423 return request
424
425
426def add_l2_loadbal_group(ctrl, id, l2_unfil_intf_groups, send_barrier=False):
427 buckets=[]
428 for group in l2_unfil_intf_groups:
429 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
430
431 group_id=encode_l2_loadbal_group_id(id)
432 request = ofp.message.group_add(group_type=ofp.OFPGT_SELECT,
433 group_id=group_id,
434 buckets=buckets
435 )
436 ctrl.message_send(request)
437 if send_barrier:
438 do_barrier(ctrl)
439
440 return group_id, request
441
442def mod_l2_loadbal_group(ctrl, id, l2_unfil_intf_groups, send_barrier=False):
443 buckets=[]
444 for group in l2_unfil_intf_groups:
445 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
446
447 group_id =encode_l2_loadbal_group_id(id)
448 request = ofp.message.group_modify(group_type=ofp.OFPGT_SELECT,
449 group_id=group_id,
450 buckets=buckets
451 )
452 ctrl.message_send(request)
453 return request
454
455
456def add_l3_ecmp_group(ctrl, id, l3_ucast_groups, send_barrier=False):
457 buckets=[]
458 for group in l3_ucast_groups:
459 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
460
461 group_id =encode_l3_ecmp_group_id(id)
462 request = ofp.message.group_add(group_type=ofp.OFPGT_SELECT,
463 group_id=group_id,
464 buckets=buckets
465 )
466 ctrl.message_send(request)
467
468 if send_barrier:
469 do_barrier(ctrl)
470
471 return request
472
473def mod_l3_ecmp_group(ctrl, id, l3_ucast_groups):
474 buckets=[]
475 for group in l3_ucast_groups:
476 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
477
478 group_id =encode_l3_ecmp_group_id(id)
479 request = ofp.message.group_modify(group_type=ofp.OFPGT_SELECT,
480 group_id=group_id,
481 buckets=buckets
482 )
483 ctrl.message_send(request)
484 return request
485
486def add_l3_mcast_group(ctrl, vid, mcast_group_id, groups_on_buckets):
487 buckets=[]
488 for group in groups_on_buckets:
489 buckets.append(ofp.bucket(actions=[ofp.action.group(group)]))
490
491 group_id =encode_l3_mcast_group_id(vid, mcast_group_id)
492 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
493 group_id=group_id,
494 buckets=buckets
495 )
496 ctrl.message_send(request)
497 return request
498
499def add_l2_overlay_flood_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
500 buckets=[]
501 for port in ports:
502 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
503
504 group_id=encode_l2_overlay_group_id(tunnel_id, 0, index)
505 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
506 group_id=group_id,
507 buckets=buckets
508 )
509 ctrl.message_send(request)
510 return request
511
512def add_l2_overlay_flood_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
513 buckets=[]
514 for port in ports:
515 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
516
517 group_id=encode_l2_overlay_group_id(tunnel_id, 1, index)
518 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
519 group_id=group_id,
520 buckets=buckets
521 )
522 ctrl.message_send(request)
523 return request
524
525def add_l2_overlay_mcast_over_unicast_tunnel_group(ctrl, tunnel_id, ports, index):
526 buckets=[]
527 for port in ports:
528 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
529
530 group_id=encode_l2_overlay_group_id(tunnel_id, 2, index)
531 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
532 group_id=group_id,
533 buckets=buckets
534 )
535 ctrl.message_send(request)
536 return request
537
538def add_l2_overlay_mcast_over_mcast_tunnel_group(ctrl, tunnel_id, ports, index):
539 buckets=[]
540 for port in ports:
541 buckets.append(ofp.bucket(actions=[ofp.action.output(port)]))
542
543 group_id=encode_l2_overlay_group_id(tunnel_id, 3, index)
544 request = ofp.message.group_add(group_type=ofp.OFPGT_ALL,
545 group_id=group_id,
546 buckets=buckets
547 )
548 ctrl.message_send(request)
549 return request
550
551def add_port_table_flow(ctrl, is_overlay=True):
552 match = ofp.match()
553
554 if is_overlay == True:
555 match.oxm_list.append(ofp.oxm.in_port(0x10000))
556 NEXT_TABLE=50
557 else:
558 match.oxm_list.append(ofp.oxm.in_port(0))
559 NEXT_TABLE=10
560
561 request = ofp.message.flow_add(
562 table_id=0,
563 cookie=42,
564 match=match,
565 instructions=[
566 ofp.instruction.goto_table(NEXT_TABLE)
567 ],
568 priority=0)
569 logging.info("Add port table, match port %lx" % 0x10000)
570 ctrl.message_send(request)
571
572def pop_vlan_flow(ctrl, ports, vlan_id=1):
573 # table 10: vlan
574 # goto to table 20
575 msgs=[]
576 for of_port in ports:
577 match = ofp.match()
578 match.oxm_list.append(ofp.oxm.in_port(of_port))
579 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
580 request = ofp.message.flow_add(
581 table_id=10,
582 cookie=42,
583 match=match,
584 instructions=[
585 ofp.instruction.apply_actions(
586 actions=[
587 ofp.action.pop_vlan()
588 ]
589 ),
590 ofp.instruction.goto_table(20)
591 ],
592 priority=0)
593 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
594 ctrl.message_send(request)
595
596
597 return msgs
598
599def add_vlan_table_flow(ctrl, ports, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
600 # table 10: vlan
601 # goto to table 20
602 msgs=[]
603 for of_port in ports:
604 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
605 match = ofp.match()
606 match.oxm_list.append(ofp.oxm.in_port(of_port))
607 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
608 request = ofp.message.flow_add(
609 table_id=10,
610 cookie=42,
611 match=match,
612 instructions=[
613 ofp.instruction.apply_actions(
614 actions=[
615 ofp.action.pop_vlan()
616 ]
617 ),
618 ofp.instruction.goto_table(20)
619 ],
620 priority=0)
621 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
622 ctrl.message_send(request)
623
624 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
625 match = ofp.match()
626 match.oxm_list.append(ofp.oxm.in_port(of_port))
627 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0x1fff))
628 request = ofp.message.flow_add(
629 table_id=10,
630 cookie=42,
631 match=match,
632 instructions=[
633 ofp.instruction.apply_actions(
634 actions=[
635 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id))
636 ]
637 ),
638 ofp.instruction.goto_table(20)
639 ],
640 priority=0)
641 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
642 ctrl.message_send(request)
643 msgs.append(request)
644
645 if (flag == 4) :
646 match = ofp.match()
647 match.oxm_list.append(ofp.oxm.in_port(of_port))
648 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1fff))
649 request = ofp.message.flow_add(
650 table_id=10,
651 cookie=42,
652 match=match,
653 instructions=[
654 ofp.instruction.apply_actions(
655 actions=[
656 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id))
657 ]
658 ),
659 ofp.instruction.goto_table(20)
660 ],
661 priority=0)
662 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
663 ctrl.message_send(request)
664 msgs.append(request)
665
666 if send_barrier:
667 do_barrier(ctrl)
668
669 return msgs
670
671def del_vlan_table_flow(ctrl, ports, vlan_id=1, flag=VLAN_TABLE_FLAG_ONLY_BOTH, send_barrier=False):
672 # table 10: vlan
673 # goto to table 20
674 msgs=[]
675 for of_port in ports:
676 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
677 match = ofp.match()
678 match.oxm_list.append(ofp.oxm.in_port(of_port))
679 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlan_id))
680 request = ofp.message.flow_delete(
681 table_id=10,
682 cookie=42,
683 match=match,
684 priority=0)
685 logging.info("Del vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
686 ctrl.message_send(request)
687
688 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
689 match = ofp.match()
690 match.oxm_list.append(ofp.oxm.in_port(of_port))
691 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0xfff))
692 request = ofp.message.flow_delete(
693 table_id=10,
694 cookie=42,
695 match=match,
696 priority=0)
697 logging.info("Del vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
698 ctrl.message_send(request)
699 msgs.append(request)
700
701 if send_barrier:
702 do_barrier(ctrl)
703
704 return msgs
705
706def add_vlan_table_flow_pvid(ctrl, in_port, match_vid=None, pvid=1, send_barrier=False):
707 """it will tag pack as untagged packet wether it has tagg or not"""
708 match = ofp.match()
709 match.oxm_list.append(ofp.oxm.in_port(in_port))
710 actions=[]
711 if match_vid == None:
712 match.oxm_list.append(ofp.oxm.vlan_vid(0))
713 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+pvid)))
714 goto_table=20
715 else:
716 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+match_vid, 0x1fff))
717 actions.append(ofp.action.push_vlan(0x8100))
718 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+pvid)))
719 goto_table=20
720
721 request = ofp.message.flow_add(
722 table_id=10,
723 cookie=42,
724 match=match,
725 instructions=[
726 ofp.instruction.apply_actions(actions=actions)
727 ,ofp.instruction.goto_table(goto_table)
728 ],
729 priority=0)
730 logging.info("Add PVID %d on port %d and go to table %ld" %( pvid, in_port, goto_table))
731 ctrl.message_send(request)
732
733 if send_barrier:
734 do_barrier(ctrl)
735
736def add_vlan_table_flow_allow_all_vlan(ctrl, in_port, send_barrier=False):
737 """it st flow allow all vlan tag on this port"""
738 match = ofp.match()
739 match.oxm_list.append(ofp.oxm.in_port(in_port))
740 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1000))
741 request = ofp.message.flow_add(
742 table_id=10,
743 cookie=42,
744 match=match,
745 instructions=[
746 ofp.instruction.goto_table(20)
747 ],
748 priority=0)
749 logging.info("Add allow all vlan on port %d " %(in_port))
750 ctrl.message_send(request)
751
752def 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):
753 # Install a flow for VLAN translation
754 # in VLAN table.
755 # table 10: vlan
756 # goto to table 20
757 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
758 match = ofp.match()
759 match.oxm_list.append(ofp.oxm.in_port(of_port))
760 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id,0x1fff))
761
762 actions=[]
763 if vrf!=0:
764 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
765 if new_vlan_id != -1:
766 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_vlan_id)))
767
768 request = ofp.message.flow_add(
769 table_id=10,
770 cookie=42,
771 match=match,
772 instructions=[
773 ofp.instruction.apply_actions(
774 actions=actions
775 ),
776 ofp.instruction.goto_table(20)
777 ],
778 priority=0)
779 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
780 ctrl.message_send(request)
781
782
783def add_one_egress_vlan_table_flow(ctrl, of_port, match_vlan, inner_vlan, outer_vlan):
784
785 # used for translating single to double tagged packets only
786
787 match = ofp.match()
788 match.oxm_list.append(ofp.oxm.exp4ByteValue(ofp.oxm.OFDPA_EXP_TYPE_ACTSET_OUTPUT, of_port))
789 match.oxm_list.append(ofp.oxm.exp1ByteValue(ofp.oxm.OFDPA_EXP_TYPE_ALLOW_VLAN_TRANSLATION, 1))
790 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+match_vlan,0x1fff))
791
792 actions=[]
793 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+inner_vlan)))
794 actions.append(ofp.action.push_vlan(0x8100))
795 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+outer_vlan)))
796
797 request = ofp.message.flow_add(
798 table_id=EGRESS_VLAN_FLOW_TABLE,
799 cookie=42,
800 match=match,
801 instructions=[
802 ofp.instruction.apply_actions(
803 actions=actions
804 ),
805 ofp.instruction.goto_table(EGRESS_DSCP_TABLE)
806 ],
807 priority=0)
808
809 ctrl.message_send(request)
810
811 return
812
813def 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):
814
815 # goto to table 20
816 if (flag == VLAN_TABLE_FLAG_ONLY_TAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH) or (flag == 4):
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+vlan_id,0x1fff))
820
821 actions=[]
822 if config["switch_type"] != 'xpliant' and vrf != 0:
823 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
824
825 #actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(value=vlan_id)))
826
827 request = ofp.message.flow_add(
828 table_id=10,
829 cookie=42,
830 match=match,
831 instructions=[
832 ofp.instruction.apply_actions(
833 actions=actions
834 ),
835 ofp.instruction.goto_table(20)
836 ],
837 priority=0)
838 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
839 ctrl.message_send(request)
840
841 if (flag == VLAN_TABLE_FLAG_ONLY_UNTAG) or (flag == VLAN_TABLE_FLAG_ONLY_BOTH):
842
843 match = ofp.match()
844 match.oxm_list.append(ofp.oxm.in_port(of_port))
845 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0, 0x1fff))
846
847 actions=[]
848 if vrf!=0:
849 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
850
851 # actions.append(ofp.action.push_vlan(0x8100))
852 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
853
854 request = ofp.message.flow_add(
855 table_id=10,
856 cookie=42,
857 match=match,
858 instructions=[
859 ofp.instruction.apply_actions(
860 actions=actions
861 ),
862 ofp.instruction.goto_table(20)
863 ],
864 priority=0)
865 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
866 ctrl.message_send(request)
867
868 if (flag == 4) :
869 match = ofp.match()
870 match.oxm_list.append(ofp.oxm.in_port(of_port))
871 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000,0x1fff))
872
873 actions=[]
874 if vrf!=0:
875 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf)))
876
877 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
878
879 request = ofp.message.flow_add(
880 table_id=10,
881 cookie=42,
882 match=match,
883 instructions=[
884 ofp.instruction.apply_actions(
885 actions=actions
886 ),
887 ofp.instruction.goto_table(20)
888 ],
889 priority=0)
890 logging.info("Add vlan %d tagged packets on port %d and go to table 20" %( vlan_id, of_port))
891 ctrl.message_send(request)
892
893 if (flag == VLAN_TABLE_FLAG_ONLY_STACKED):
894 # This flag is meant to managed stacked vlan packtes
895 # Matches on outer VLAN_ID, set OVID with outer VLAN.
896 # Finally expose inner VLAN_ID with a pop action and
897 # goto VLAN_1_FLOW_TABLE
898 match = ofp.match()
899 match.oxm_list.append(ofp.oxm.in_port(of_port))
900 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id,0x1fff))
901
902 actions=[]
903 # actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_OVID, value=0x1000+vlan_id)))
904 actions.append(ofp.action.pop_vlan())
905 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_OVID, value=0x1000+vlan_id)))
906
907 request = ofp.message.flow_add(
908 table_id=10,
909 cookie=42,
910 match=match,
911 instructions=[
912 ofp.instruction.apply_actions(
913 actions=actions
914 ),
915 ofp.instruction.goto_table(VLAN_1_FLOW_TABLE)
916 ],
917 priority=0)
918 logging.info("Add vlan %d tagged packets on port %d and go to table %d" %( vlan_id, of_port, VLAN_1_FLOW_TABLE))
919 ctrl.message_send(request)
920
921 if (flag == VLAN_TABLE_FLAG_PRIORITY) :
922 match = ofp.match()
923 match.oxm_list.append(ofp.oxm.in_port(of_port))
924 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000, 0x1fff))
925 request = ofp.message.flow_add(
926 table_id=10,
927 cookie=42,
928 match=match,
929 instructions=[
930 ofp.instruction.apply_actions(
931 actions=[
932 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)),
933 ofp.action.push_vlan(0x8100),
934 ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+out_vlan_id)),
935 ]
936 ),
937 ofp.instruction.goto_table(20)
938 ],
939 priority=0)
940 logging.info("Add vlan %d untagged packets on port %d and go to table 20" % (vlan_id, of_port))
941 ctrl.message_send(request)
942
943 if send_barrier:
944 do_barrier(ctrl)
945
946 return request
947
948def 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):
949 # table 10: vlan
950 # goto to table 13
951 if flag == VLAN_TABLE_FLAG_ONLY_TAG:
952 match = ofp.match()
953 match.oxm_list.append(ofp.oxm.in_port(of_port))
954 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+vlan_id, 0x1fff))
955
956 actions=[]
957 if vlan_id == -1:
958 actions.append(ofp.action.pop_vlan())
959 if new_vlan_id > 1:
960 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_vlan_id)))
961 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
962 actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
963 # 0x0000nnnn is for UNI interfaces
964 actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port)))
965
966 request = ofp.message.flow_add(
967 table_id=10,
968 cookie=42,
969 match=match,
970 instructions=[
971 ofp.instruction.apply_actions(
972 actions=actions
973 ),
974 ofp.instruction.goto_table(MPLS_L2_PORT_FLOW_TABLE)
975 ],
976 priority=0)
977 logging.info("Add vlan %d tagged packets on port %d and go to table %d" % (vlan_id, of_port, MPLS_L2_PORT_FLOW_TABLE))
978 ctrl.message_send(request)
979
980 if flag == VLAN_TABLE_FLAG_ONLY_UNTAG:
981 match = ofp.match()
982 match.oxm_list.append(ofp.oxm.in_port(of_port))
983 match.oxm_list.append(ofp.oxm.vlan_vid(0))
984
985 actions=[]
986 if vlan_id > 1:
987 # actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
988 # actions.append(ofp.action.set_field(ofp.action.push_vlan(0x8100)))
989 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vlan_id)))
990
991 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
992 actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
993 # 0x0000nnnn is for UNI interfaces
994 actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port)))
995
996 request = ofp.message.flow_add(
997 table_id=10,
998 cookie=42,
999 match=match,
1000 instructions=[
1001 ofp.instruction.apply_actions(
1002 actions=actions
1003 ),
1004 ofp.instruction.goto_table(MPLS_L2_PORT_FLOW_TABLE)
1005 ],
1006 priority=0)
1007 logging.info("Add vlan %d untagged packets on port %d and go to table %d" % (vlan_id, of_port, MPLS_L2_PORT_FLOW_TABLE))
1008 ctrl.message_send(request)
1009
1010 if send_barrier:
1011 do_barrier(ctrl)
1012
1013 return request
1014
1015def 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):
1016
1017 # table 11: vlan 1 table
1018 # goto to table 20
1019 if flag == VLAN_TABLE_FLAG_ONLY_TAG:
1020 match = ofp.match()
1021 match.oxm_list.append(ofp.oxm.in_port(of_port))
1022 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
1023 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
1024
1025 actions=[]
1026 actions.append(ofp.action.push_vlan(0x8100))
1027 if new_outer_vlan_id != -1:
1028 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_outer_vlan_id)))
1029 else:
1030 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+outer_vlan_id)))
1031
1032 request = ofp.message.flow_add(
1033 table_id=11,
1034 cookie=42,
1035 match=match,
1036 instructions=[
1037 ofp.instruction.apply_actions(
1038 actions=actions
1039 ),
1040 ofp.instruction.goto_table(TERMINATION_FLOW_TABLE)
1041 ],
1042 priority=0)
1043 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))
1044 ctrl.message_send(request)
1045
1046 if flag == VLAN_TABLE_FLAG_ONLY_UNTAG:
1047
1048 match = ofp.match()
1049 match.oxm_list.append(ofp.oxm.in_port(of_port))
1050 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
1051 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
1052
1053 actions=[]
1054 request = ofp.message.flow_add(
1055 table_id=11,
1056 cookie=42,
1057 match=match,
1058 instructions=[
1059 ofp.instruction.apply_actions(
1060 actions=actions
1061 ),
1062 ofp.instruction.goto_table(TERMINATION_FLOW_TABLE)
1063 ],
1064 priority=0)
1065 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))
1066 ctrl.message_send(request)
1067
1068 if flag == VLAN_TABLE_FLAG_ONLY_POP_VLAN:
1069
1070 print("INSTALLIN IN TABLE 11!")
1071
1072 match = ofp.match()
1073 match.oxm_list.append(ofp.oxm.in_port(of_port))
1074 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
1075 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
1076
1077 actions=[]
1078 actions.append(ofp.action.pop_vlan())
1079
1080 request = ofp.message.flow_add(
1081 table_id=11,
1082 cookie=42,
1083 match=match,
1084 instructions=[
1085 ofp.instruction.apply_actions(
1086 actions=actions
1087 ),
1088 ofp.instruction.goto_table(TERMINATION_FLOW_TABLE)
1089 ],
1090 priority=0)
1091 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))
1092 ctrl.message_send(request)
1093
1094
1095 if send_barrier:
1096 do_barrier(ctrl)
1097
1098 return request
1099
1100def 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, cross_connect=False, send_barrier=False):
1101
1102 # table 11: vlan 1 table
1103 # goto to table 13
1104 match = ofp.match()
1105 match.oxm_list.append(ofp.oxm.in_port(of_port))
1106 match.oxm_list.append(ofp.oxm.vlan_vid_masked(0x1000+inner_vlan_id,0x1fff))
1107 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_OVID, 0x1000+outer_vlan_id))
1108
1109 actions=[]
1110
1111 if cross_connect:
1112 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+inner_vlan_id)))
1113 actions.append(ofp.action.push_vlan(0x8100))
1114 if new_outer_vlan_id != -1:
1115 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+new_outer_vlan_id)))
1116 else:
1117 actions.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+outer_vlan_id)))
1118
1119 if not cross_connect:
1120 actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
1121 actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
1122 else:
1123 actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE_CROSS_CONNECT)))
1124
1125 # 0x0000nnnn is for UNI interfaces
1126 actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port)))
1127
1128 request = ofp.message.flow_add(
1129 table_id=11,
1130 cookie=42,
1131 match=match,
1132 instructions=[
1133 ofp.instruction.apply_actions(
1134 actions=actions
1135 ),
1136 ofp.instruction.goto_table(MPLS_L2_PORT_FLOW_TABLE)
1137 ],
1138 priority=0)
1139 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))
1140 ctrl.message_send(request)
1141 if send_barrier:
1142 do_barrier(ctrl)
1143
1144 return request
1145
1146def add_bridge_flow(ctrl, dst_mac, vlanid, group_id, send_barrier=False):
1147 match = ofp.match()
1148 priority=500
1149 if dst_mac!=None:
1150 priority=1000
1151 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
1152
1153 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
1154
1155 request = ofp.message.flow_add(
1156 table_id=50,
1157 cookie=42,
1158 match=match,
1159 instructions=[
1160 ofp.instruction.write_actions(
1161 actions=[
1162 ofp.action.group(group_id)]),
1163 ofp.instruction.goto_table(60)
1164 ],
1165 buffer_id=ofp.OFP_NO_BUFFER,
1166 priority=priority)
1167
1168 logging.info("Inserting Brdige flow vlan %d, mac %s", vlanid, dst_mac)
1169 ctrl.message_send(request)
1170
1171 if send_barrier:
1172 do_barrier(ctrl)
1173
1174 return request
1175
1176def add_overlay_bridge_flow(ctrl, dst_mac, vnid, group_id, is_group=True, send_barrier=False):
1177 match = ofp.match()
1178 if dst_mac!=None:
1179 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
1180
1181 match.oxm_list.append(ofp.oxm.tunnel_id(vnid))
1182 if is_group == True:
1183 actions=[ofp.action.group(group_id)]
1184 else:
1185 actions=[ofp.action.output(group_id)]
1186
1187 request = ofp.message.flow_add(
1188 table_id=50,
1189 cookie=42,
1190 match=match,
1191 instructions=[
1192 ofp.instruction.write_actions(
1193 actions=actions),
1194 ofp.instruction.goto_table(60)
1195 ],
1196 buffer_id=ofp.OFP_NO_BUFFER,
1197 priority=1000)
1198
1199 logging.info("Inserting Brdige flow vnid %d, mac %s", vnid, dst_mac)
1200 ctrl.message_send(request)
1201
1202 if send_barrier:
1203 do_barrier(ctrl)
1204
1205 return request
1206
1207def add_termination_flow(ctrl, in_port, eth_type, dst_mac, vlanid, goto_table=None, send_barrier=False):
1208 match = ofp.match()
1209 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
1210 if dst_mac[0]&0x01 == 0x01:
1211 match.oxm_list.append(ofp.oxm.eth_dst_masked(dst_mac, [0xff, 0xff, 0xff, 0x80, 0x00, 0x00]))
1212 goto_table=40
1213 else:
1214 if in_port!=0:
1215 match.oxm_list.append(ofp.oxm.in_port(in_port))
1216 match.oxm_list.append(ofp.oxm.eth_dst(dst_mac))
1217 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000+vlanid))
1218 if goto_table == None:
1219 goto_table=30
1220
1221 request = ofp.message.flow_add(
1222 table_id=20,
1223 cookie=42,
1224 match=match,
1225 instructions=[
1226 ofp.instruction.goto_table(goto_table)
1227 ],
1228 buffer_id=ofp.OFP_NO_BUFFER,
1229 priority=1)
1230
1231 logging.info("Inserting termination flow inport %d, eth_type %lx, vlan %d, mac %s", in_port, eth_type, vlanid, dst_mac)
1232 ctrl.message_send(request)
1233 if send_barrier:
1234 do_barrier(ctrl)
1235
1236 return request
1237
1238def add_unicast_routing_flow(ctrl, eth_type, dst_ip, mask, action_group_id, vrf=0, send_ctrl=False, send_barrier=False, priority = 1):
1239 match = ofp.match()
1240 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
1241 if config["switch_type"] != 'xpliant' and vrf != 0:
1242 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_VRF, vrf))
1243
1244 match.oxm_list.append(ofp.oxm.ipv4_dst_masked(dst_ip, mask))
1245
1246 instructions = []
1247 instructions.append(ofp.instruction.goto_table(60))
1248 if send_ctrl:
1249 instructions.append(ofp.instruction.write_actions(
1250 actions=[ofp.action.output( port=ofp.OFPP_CONTROLLER,
1251 max_len=ofp.OFPCML_NO_BUFFER)]))
1252 else:
1253 instructions.append(ofp.instruction.write_actions(
1254 actions=[ofp.action.group(action_group_id)]))
1255
1256 request = ofp.message.flow_add(
1257 table_id=30,
1258 cookie=42,
1259 match=match,
1260 instructions=instructions,
1261 buffer_id=ofp.OFP_NO_BUFFER,
1262 priority=priority)
1263
1264 logging.info("Inserting unicast routing flow eth_type %lx, dip %ld",eth_type, dst_ip)
1265 ctrl.message_send(request)
1266
1267 if send_barrier:
1268 do_barrier(ctrl)
1269
1270 return request
1271
1272def add_unicast_blackhole_flow(ctrl, eth_type, dst_ip, mask, vrf=0, send_ctrl=False, send_barrier=False, priority = 1):
1273 match = ofp.match()
1274 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
1275 if config["switch_type"] != 'xpliant' and vrf != 0:
1276 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_VRF, vrf))
1277
1278 match.oxm_list.append(ofp.oxm.ipv4_dst_masked(dst_ip, mask))
1279
1280 instructions = []
1281 instructions.append(ofp.instruction.goto_table(60))
1282 instructions.append(ofp.instruction.clear_actions( ))
1283
1284 request = ofp.message.flow_add(
1285 table_id=30,
1286 cookie=42,
1287 match=match,
1288 instructions=instructions,
1289 buffer_id=ofp.OFP_NO_BUFFER,
1290 priority=priority)
1291
1292 logging.info("Inserting unicast blackhole routing flow eth_type %lx, dip %ld",eth_type, dst_ip)
1293 ctrl.message_send(request)
1294
1295 if send_barrier:
1296 do_barrier(ctrl)
1297
1298 return request
1299
1300def add_unicast_v6_routing_flow(ctrl, eth_type, dst_ip, mask, action_group_id, vrf=0, send_ctrl=False, send_barrier=False):
1301 match = ofp.match()
1302 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
1303 if vrf != 0:
1304 match.oxm_list.append(ofp.oxm.exp2ByteValue(ofp.oxm.OFDPA_EXP_TYPE_VRF, vrf))
1305
1306 match.oxm_list.append(ofp.oxm.ipv6_dst_masked(parse_ipv6(dst_ip), parse_ipv6(mask)))
1307
1308 instructions = []
1309 instructions.append(ofp.instruction.goto_table(60))
1310 if send_ctrl:
1311 instructions.append(ofp.instruction.write_actions(
1312 actions=[ofp.action.output( port=ofp.OFPP_CONTROLLER,
1313 max_len=ofp.OFPCML_NO_BUFFER)]))
1314 else:
1315 instructions.append(ofp.instruction.write_actions(
1316 actions=[ofp.action.group(action_group_id)]))
1317
1318 request = ofp.message.flow_add(
1319 table_id=30,
1320 cookie=42,
1321 match=match,
1322 instructions=instructions,
1323 buffer_id=ofp.OFP_NO_BUFFER,
1324 priority=1)
1325
1326 logging.info("Inserting unicast routing flow eth_type %lx, dip %s",eth_type, dst_ip)
1327 ctrl.message_send(request)
1328
1329 if send_barrier:
1330 do_barrier(ctrl)
1331
1332 return request
1333
1334def 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):
1335 match = ofp.match()
1336 match.oxm_list.append(ofp.oxm.eth_type(0x8847))
1337 match.oxm_list.append(ofp.oxm.mpls_label(label))
1338 match.oxm_list.append(ofp.oxm.mpls_bos(bos))
1339 write_actions = []
1340 write_actions.append(ofp.action.group(action_group_id))
1341 apply_actions = []
1342 apply_actions = [ofp.action.dec_mpls_ttl(),
1343 ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=1, value=vrf))]
1344 if (goto_table != 29):
1345 apply_actions.append(ofp.action.set_field(
1346 ofp.oxm.exp2ByteValue(exp_type=23, value=32)))
1347 apply_actions.append(ofp.action.copy_ttl_in())
1348
1349 request = ofp.message.flow_add(
1350 table_id=24,
1351 cookie=43,
1352 match=match,
1353 instructions=[
1354 ofp.instruction.apply_actions(actions=apply_actions),
1355 ofp.instruction.write_actions(actions=write_actions),
1356 ofp.instruction.goto_table(goto_table)
1357 ],
1358 buffer_id=ofp.OFP_NO_BUFFER,
1359 priority=1)
1360 ctrl.message_send(request)
1361
1362 if send_barrier:
1363 do_barrier(ctrl)
1364
1365 return request
1366
1367def xpliant_add_mpls_flow(ctrl, action_group_id=0x0, label=100 ,ethertype=0x0800, bos=1, vrf=1, goto_table=27, send_barrier=False):
1368 match = ofp.match()
1369 match.oxm_list.append(ofp.oxm.eth_type(0x8847))
1370 match.oxm_list.append(ofp.oxm.mpls_label(label))
1371
1372 apply_actions = []
1373 apply_actions.append(ofp.action.group(action_group_id))
1374 apply_actions.append(ofp.action.dec_mpls_ttl())
1375 if (goto_table != 29):
1376 apply_actions.append(ofp.action.pop_mpls(ethertype))
1377
1378 request = ofp.message.flow_add(
1379 table_id=24,
1380 cookie=43,
1381 match=match,
1382 instructions=[
1383 ofp.instruction.apply_actions(actions=apply_actions),
1384 ],
1385 buffer_id=ofp.OFP_NO_BUFFER,
1386 priority=1)
1387 logging.info("Inserting MPLS flow , label %ld", label)
1388 ctrl.message_send(request)
1389
1390 if send_barrier:
1391 do_barrier(ctrl)
1392
1393 return request
1394
1395def add_mpls_flow_swap(ctrl, action_group_id, label, ethertype, bos, goto_table=MPLS_TYPE_FLOW_TABLE, of_port=0, send_barrier=False):
1396 match = ofp.match()
1397 match.oxm_list.append(ofp.oxm.eth_type(0x8847))
1398 match.oxm_list.append(ofp.oxm.mpls_label(label))
1399 match.oxm_list.append(ofp.oxm.mpls_bos(1))
1400
1401 apply_actions = []
1402 write_actions = []
1403 apply_actions.append(ofp.action.dec_mpls_ttl())
1404 write_actions.append(ofp.action.group(action_group_id))
1405
1406 request = ofp.message.flow_add(
1407 table_id=24,
1408 cookie=43,
1409 match=match,
1410 instructions=[
1411 ofp.instruction.apply_actions(actions=apply_actions),
1412 ofp.instruction.write_actions(actions=write_actions),
1413 ofp.instruction.goto_table(goto_table)
1414 ],
1415 buffer_id=ofp.OFP_NO_BUFFER,
1416 priority=1)
1417
1418 logging.info("Inserting MPLS flow , label %ld", label)
1419 ctrl.message_send(request)
1420
1421 if send_barrier:
1422 do_barrier(ctrl)
1423
1424 return request
1425
1426
1427def 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):
1428 match = ofp.match()
1429 match.oxm_list.append(ofp.oxm.eth_type(0x8847))
1430 match.oxm_list.append(ofp.oxm.mpls_label(label))
1431 match.oxm_list.append(ofp.oxm.mpls_bos(bos))
1432
1433 apply_actions = []
1434 write_actions = []
1435 apply_actions.append(ofp.action.dec_mpls_ttl())
1436 if popMPLS == True:
1437 apply_actions.append(ofp.action.copy_ttl_in())
1438 apply_actions.append(ofp.action.pop_mpls(ethertype))
1439 if bos==1 and popL2 == True:
1440 apply_actions.append(ofp.action.ofdpa_pop_l2_header())
1441 apply_actions.append(ofp.action.ofdpa_pop_cw())
1442 apply_actions.append(ofp.action.set_field(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE)))
1443 # 0x0002nnnn is for UNI interfaces
1444 apply_actions.append(ofp.action.set_field(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00020000 + of_port)))
1445 apply_actions.append(ofp.action.set_field(ofp.oxm.exp2ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_TYPE, value=ofp.oxm.VPWS)))
1446
1447 write_actions.append(ofp.action.group(action_group_id))
1448
1449 request = ofp.message.flow_add(
1450 table_id=24,
1451 cookie=43,
1452 match=match,
1453 instructions=[
1454 ofp.instruction.apply_actions(actions=apply_actions),
1455 ofp.instruction.write_actions(actions=write_actions),
1456 ofp.instruction.goto_table(goto_table)
1457 ],
1458 buffer_id=ofp.OFP_NO_BUFFER,
1459 priority=1)
1460 logging.info("Inserting MPLS flow , label %ld", label)
1461 ctrl.message_send(request)
1462
1463 if send_barrier:
1464 do_barrier(ctrl)
1465
1466 return request
1467
1468def add_mcast4_routing_flow(ctrl, vlan_id, src_ip, src_ip_mask, dst_ip, action_group_id, send_barrier=False):
1469 match = ofp.match()
1470 match.oxm_list.append(ofp.oxm.eth_type(0x0800))
1471 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000 + vlan_id))
1472 if src_ip_mask!=0:
1473 match.oxm_list.append(ofp.oxm.ipv4_src_masked(src_ip, src_ip_mask))
1474 else:
1475 match.oxm_list.append(ofp.oxm.ipv4_src(src_ip))
1476
1477 match.oxm_list.append(ofp.oxm.ipv4_dst(dst_ip))
1478
1479 request = ofp.message.flow_add(
1480 table_id=40,
1481 cookie=42,
1482 match=match,
1483 instructions=[
1484 ofp.instruction.write_actions(
1485 actions=[ofp.action.group(action_group_id)]),
1486 ofp.instruction.goto_table(60)
1487 ],
1488 buffer_id=ofp.OFP_NO_BUFFER,
1489 priority=1)
1490
1491 logging.info("Inserting mcast routing flow eth_type %lx, dip %lx, sip %lx, sip_mask %lx",0x0800, dst_ip, src_ip, src_ip_mask)
1492 ctrl.message_send(request)
1493
1494 if send_barrier:
1495 do_barrier(ctrl)
1496
1497 return request
1498
1499def add_acl_rule(ctrl, eth_type=None, ip_proto=None, vlan_id=None, send_barrier=False):
1500 match = ofp.match()
1501 if eth_type:
1502 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
1503 if ip_proto:
1504 match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
1505 if vlan_id:
1506 match.oxm_list.append(ofp.oxm.vlan_vid(0x1000 + vlan_id))
1507 request = ofp.message.flow_add(
1508 table_id=60,
1509 cookie=42,
1510 match=match,
1511 instructions=[
1512 ofp.instruction.apply_actions(
1513 actions=[ofp.action.output(port=ofp.OFPP_CONTROLLER, max_len=ofp.OFPCML_NO_BUFFER)]
1514 ),
1515 ],
1516 buffer_id=ofp.OFP_NO_BUFFER,
1517 priority=1
1518 )
1519 output = "Inserting ACL flow: "
1520 if eth_type:
1521 output += "eth_type {}, ".format(eth_type)
1522 if ip_proto:
1523 output += "ip_proto {}, ".format(ip_proto)
1524 if vlan_id:
1525 output += "vlan_id {}".format(vlan_id)
1526 logging.info(output)
1527
1528 ctrl.message_send(request)
1529
1530 if send_barrier:
1531 do_barrier(ctrl)
1532
1533 return request
1534
1535#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
1536def add_dnat_flow(ctrl, eth_type, ip_dst, ip_proto, tcp_dst, set_ip_dst, set_tcp_dst, action_group_id):
1537 match = ofp.match()
1538 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
1539 match.oxm_list.append(ofp.oxm.ipv4_dst(ip_dst))
1540 match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
1541 match.oxm_list.append(ofp.oxm.tcp_dst(tcp_dst))
1542
1543 request = ofp.message.flow_add(
1544 table_id=28,
1545 cookie=42,
1546 match=match,
1547 instructions=[
1548 ofp.instruction.write_actions(
1549 actions=[ofp.action.set_field(ofp.oxm.ipv4_dst(set_ip_dst)),
1550 ofp.action.set_field(ofp.oxm.tcp_dst(set_tcp_dst)),
1551 ofp.action.group(action_group_id)]),
1552 ofp.instruction.goto_table(60)
1553 ],
1554 buffer_id=ofp.OFP_NO_BUFFER,
1555 priority=1)
1556 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)
1557 ctrl.message_send(request)
1558 return request
1559
1560#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
1561def add_snat_flow(ctrl, eth_type, ip_src, ip_proto, tcp_src, set_ip_src, set_tcp_src):
1562 match = ofp.match()
1563 match.oxm_list.append(ofp.oxm.eth_type(eth_type))
1564 match.oxm_list.append(ofp.oxm.ipv4_src(ip_src))
1565 match.oxm_list.append(ofp.oxm.ip_proto(ip_proto))
1566 match.oxm_list.append(ofp.oxm.tcp_src(tcp_src))
1567
1568 request = ofp.message.flow_add(
1569 table_id=29,
1570 cookie=42,
1571 match=match,
1572 instructions=[
1573 ofp.instruction.write_actions(
1574 actions=[ofp.action.set_field(ofp.oxm.ipv4_src(set_ip_src)),
1575 ofp.action.set_field(ofp.oxm.tcp_src(set_tcp_src))]),
1576 ofp.instruction.goto_table(30)
1577 ],
1578 buffer_id=ofp.OFP_NO_BUFFER,
1579 priority=1)
1580 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)
1581 ctrl.message_send(request)
1582 return request
1583
1584def get_vtap_lport_config_xml(dp_id, lport, phy_port, vlan, vnid, operation='merge'):
1585 """
1586 Command Example:
1587 of-agent vtap 10001 ethernet 1/1 vid 1
1588 of-agent vtp 10001 vni 10
1589 """
1590 if vlan != 0:
1591 config_vtap_xml="""
1592 <config>
1593 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1594 <id>capable-switch-1</id>
1595 <resources>
1596 <port xc:operation="OPERATION">
1597 <resource-id >LPORT</resource-id>
1598 <features>
1599 <current>
1600 <rate>10Gb</rate>
1601 <medium>fiber</medium>
1602 <pause>symmetric</pause>
1603 </current>
1604 <advertised>
1605 <rate>10Gb</rate>
1606 <rate>100Gb</rate>
1607 <medium>fiber</medium>
1608 <pause>symmetric</pause>
1609 </advertised>
1610 <supported>
1611 <rate>10Gb</rate>
1612 <rate>100Gb</rate>
1613 <medium>fiber</medium>
1614 <pause>symmetric</pause>
1615 </supported>
1616 <advertised-peer>
1617 <rate>10Gb</rate>
1618 <rate>100Gb</rate>
1619 <medium>fiber</medium>
1620 <pause>symmetric</pause>
1621 </advertised-peer>
1622 </features>
1623 <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1624 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
1625 <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
1626 <ofdpa10:vni>VNID</ofdpa10:vni>
1627 </ofdpa10:vtap>
1628 </port>
1629 </resources>
1630 <logical-switches>
1631 <switch>
1632 <id>DATAPATH_ID</id>
1633 <datapath-id>DATAPATH_ID</datapath-id>
1634 <resources>
1635 <port xc:operation="OPERATION">LPORT</port>
1636 </resources>
1637 </switch>
1638 </logical-switches>
1639 </capable-switch>
1640 </config>
1641 """
1642 else:
1643 config_vtap_xml="""
1644 <config>
1645 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1646 <id>capable-switch-1</id>
1647 <resources>
1648 <port xc:operation="OPERATION">
1649 <resource-id >LPORT</resource-id>
1650 <features>
1651 <current>
1652 <rate>10Gb</rate>
1653 <medium>fiber</medium>
1654 <pause>symmetric</pause>
1655 </current>
1656 <advertised>
1657 <rate>10Gb</rate>
1658 <rate>100Gb</rate>
1659 <medium>fiber</medium>
1660 <pause>symmetric</pause>
1661 </advertised>
1662 <supported>
1663 <rate>10Gb</rate>
1664 <rate>100Gb</rate>
1665 <medium>fiber</medium>
1666 <pause>symmetric</pause>
1667 </supported>
1668 <advertised-peer>
1669 <rate>10Gb</rate>
1670 <rate>100Gb</rate>
1671 <medium>fiber</medium>
1672 <pause>symmetric</pause>
1673 </advertised-peer>
1674 </features>
1675 <ofdpa10:vtap xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1676 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
1677 <ofdpa10:vni>VNID</ofdpa10:vni>
1678 </ofdpa10:vtap>
1679 </port>
1680 </resources>
1681 <logical-switches>
1682 <switch>
1683 <id>DATAPATH_ID</id>
1684 <datapath-id>DATAPATH_ID</datapath-id>
1685 <resources>
1686 <port xc:operation="OPERATION">LPORT</port>
1687 </resources>
1688 </switch>
1689 </logical-switches>
1690 </capable-switch>
1691 </config>
1692 """
1693 str_datapath_id_f= "{:016x}".format(dp_id)
1694 str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
1695 config_vtap_xml=config_vtap_xml.replace("DATAPATH_ID", str_datapath_id)
1696 config_vtap_xml=config_vtap_xml.replace("LPORT", str(int(lport)))
1697 config_vtap_xml=config_vtap_xml.replace("PHY_PORT", str(phy_port))
1698 config_vtap_xml=config_vtap_xml.replace("VLAN_ID", str(vlan))
1699 config_vtap_xml=config_vtap_xml.replace("VNID", str(vnid))
1700 config_vtap_xml=config_vtap_xml.replace("OPERATION", str(operation))
1701 return config_vtap_xml
1702
1703def get_vtep_lport_config_xml(dp_id, lport, src_ip, dst_ip, next_hop_id, vnid, udp_src_port=6633, ttl=25, operation='merge'):
1704 """
1705 Command Example:
1706 of-agent vtep 10002 source user-input-src-ip destination user-input-dst-ip udp-source-port 6633 nexthop 2 ttl 25
1707 of-agent vtp 10001 vni 10
1708 """
1709
1710 config_vtep_xml="""
1711 <config>
1712 <capable-switch xmlns="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1713 <id>capable-switch-1</id>
1714 <resources>
1715 <port xc:operation="OPERATION">
1716 <resource-id>LPORT</resource-id>
1717 <features>
1718 <current>
1719 <rate>10Gb</rate>
1720 <medium>fiber</medium>
1721 <pause>symmetric</pause>
1722 </current>
1723 <advertised>
1724 <rate>10Gb</rate>
1725 <rate>100Gb</rate>
1726 <medium>fiber</medium>
1727 <pause>symmetric</pause>
1728 </advertised>
1729 <supported>
1730 <rate>10Gb</rate>
1731 <rate>100Gb</rate>
1732 <medium>fiber</medium>
1733 <pause>symmetric</pause>
1734 </supported>
1735 <advertised-peer>
1736 <rate>10Gb</rate>
1737 <rate>100Gb</rate>
1738 <medium>fiber</medium>
1739 <pause>symmetric</pause>
1740 </advertised-peer>
1741 </features>
1742 <ofdpa10:vtep xmlns:ofdpa10="urn:bcm:ofdpa10:accton01">
1743 <ofdpa10:src-ip>SRC_IP</ofdpa10:src-ip>
1744 <ofdpa10:dest-ip>DST_IP</ofdpa10:dest-ip>
1745 <ofdpa10:udp-src-port>UDP_SRC_PORT</ofdpa10:udp-src-port>
1746 <ofdpa10:vni xc:operation="OPERATION">
1747 <ofdpa10:id>VNID</ofdpa10:id>
1748 </ofdpa10:vni>
1749 <ofdpa10:nexthop-id>NEXT_HOP_ID</ofdpa10:nexthop-id>
1750 <ofdpa10:ttl>TTL</ofdpa10:ttl>
1751 </ofdpa10:vtep>
1752 </port>
1753 </resources>
1754 <logical-switches>
1755 <switch>
1756 <id>DATAPATH_ID</id>
1757 <datapath-id>DATAPATH_ID</datapath-id>
1758 <resources>
1759 <port xc:operation="OPERATION">LPORT</port>
1760 </resources>
1761 </switch>
1762 </logical-switches>
1763 </capable-switch>
1764 </config>
1765 """
1766 str_datapath_id_f= "{:016x}".format(dp_id)
1767 str_datapath_id=':'.join([str_datapath_id_f[i:i+2] for i in range(0, len(str_datapath_id_f), 2)])
1768 config_vtep_xml=config_vtep_xml.replace("DATAPATH_ID", str_datapath_id)
1769 config_vtep_xml=config_vtep_xml.replace("LPORT", str(int(lport)))
1770 config_vtep_xml=config_vtep_xml.replace("SRC_IP", str(src_ip))
1771 config_vtep_xml=config_vtep_xml.replace("DST_IP", str(dst_ip))
1772 config_vtep_xml=config_vtep_xml.replace("UDP_SRC_PORT", str(udp_src_port))
1773 config_vtep_xml=config_vtep_xml.replace("NEXT_HOP_ID", str(next_hop_id))
1774 config_vtep_xml=config_vtep_xml.replace("TTL", str(ttl))
1775 config_vtep_xml=config_vtep_xml.replace("VNID", str(vnid))
1776 config_vtep_xml=config_vtep_xml.replace("OPERATION", str(operation))
1777
1778 return config_vtep_xml
1779
1780def get_next_hop_config_xml(next_hop_id, dst_mac, phy_port, vlan, operation='merge'):
1781 #of-agent nexthop 2 destination user-input-dst-mac ethernet 1/2 vid 2
1782 config_nexthop_xml="""
1783 <config>
1784 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1785 <ofdpa10:next-hop xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1786 <ofdpa10:id>NEXT_HOP_ID</ofdpa10:id>
1787 <ofdpa10:dest-mac>DST_MAC</ofdpa10:dest-mac>
1788 <ofdpa10:phy-port>PHY_PORT</ofdpa10:phy-port>
1789 <ofdpa10:vid>VLAN_ID</ofdpa10:vid>
1790 </ofdpa10:next-hop>
1791 </of11-config:capable-switch>
1792 </config>
1793 """
1794 config_nexthop_xml=config_nexthop_xml.replace("VLAN_ID", str(vlan))
1795 config_nexthop_xml=config_nexthop_xml.replace("PHY_PORT", str(phy_port))
1796 config_nexthop_xml=config_nexthop_xml.replace("NEXT_HOP_ID", str(next_hop_id))
1797 config_nexthop_xml=config_nexthop_xml.replace("DST_MAC", str(dst_mac))
1798 config_nexthop_xml=config_nexthop_xml.replace("OPERATION", str(operation))
1799 return config_nexthop_xml
1800
1801def get_vni_config_xml(vni_id, mcast_ipv4, next_hop_id, operation='merge'):
1802 #of-agent vni 10 multicast 224.1.1.1 nexthop 20
1803 if mcast_ipv4!=None:
1804 config_vni_xml="""
1805 <config>
1806 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1807 <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1808 <ofdpa10:id>VNID</ofdpa10:id>
1809 <ofdpa10:vni-multicast-group>MCAST_IP</ofdpa10:vni-multicast-group>
1810 <ofdpa10:multicast-group-nexthop-id>NEXT_HOP_ID</ofdpa10:multicast-group-nexthop-id>
1811 </ofdpa10:vni>
1812 </of11-config:capable-switch>
1813 </config>
1814 """
1815 config_vni_xml=config_vni_xml.replace("NEXT_HOP_ID", str(next_hop_id))
1816 config_vni_xml=config_vni_xml.replace("MCAST_IP", str(mcast_ipv4))
1817 else:
1818 config_vni_xml="""
1819 <config>
1820 <of11-config:capable-switch xmlns:of11-config="urn:onf:of111:config:yang" xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
1821 <ofdpa10:vni xmlns:ofdpa10="urn:bcm:ofdpa10:accton01" xc:operation="OPERATION">
1822 <ofdpa10:id>VNID</ofdpa10:id>
1823 </ofdpa10:vni>
1824 </of11-config:capable-switch>
1825 </config>
1826 """
1827
1828 config_vni_xml=config_vni_xml.replace("VNID", str(vni_id))
1829 config_vni_xml=config_vni_xml.replace("OPERATION", str(operation))
1830 return config_vni_xml
1831
1832def get_featureReplay(self):
1833 req = ofp.message.features_request()
1834 res, raw = self.controller.transact(req)
1835 self.assertIsNotNone(res, "Did not receive a response from the DUT.")
1836 self.assertEqual(res.type, ofp.OFPT_FEATURES_REPLY,
1837 ("Unexpected packet type %d received in response to "
1838 "OFPT_FEATURES_REQUEST") % res.type)
1839 return res
1840
1841def send_edit_config(switch_ip, xml, target='runing'):
1842 NETCONF_ACCOUNT="netconfuser"
1843 NETCONF_PASSWD="netconfuser"
1844 with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
1845 try:
1846 m.edit_config(target='running',
1847 config=xml,
1848 default_operation='merge',
1849 error_option='stop-on-error')
1850
1851 except Exception as e:
1852 logging.info("Fail to set xml %s", xml)
1853 return False
1854
1855 #return m.get_config(source='running').data_xml
1856 return True
1857
1858def send_delete_config(switch_ip, xml, target='runing'):
1859 NETCONF_ACCOUNT="netconfuser"
1860 NETCONF_PASSWD="netconfuser"
1861 with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
1862 try:
1863 m.edit_config(target='running',
1864 config=xml,
1865 default_operation='delete',
1866 error_option='stop-on-error')
1867
1868 except Exception as e:
1869 logging.info("Fail to set xml %s", xml)
1870 return False
1871
1872 #return m.get_config(source='running').data_xml
1873 return True
1874
1875def get_edit_config(switch_ip, target='runing'):
1876 NETCONF_ACCOUNT="netconfuser"
1877 NETCONF_PASSWD="netconfuser"
1878 with manager.connect_ssh(host=switch_ip, port=830, username=NETCONF_ACCOUNT, password=NETCONF_PASSWD, hostkey_verify=False ) as m:
1879 return m.get_config(source='running').data_xml
1880
1881
Roman Bubyr8c385572019-04-25 11:45:13 +03001882def ofagent_restart(self):
Roman Bubyr8c385572019-04-25 11:45:13 +03001883 regexp = 'Setting up OFDPA running environment'
Roman Bubyr8c385572019-04-25 11:45:13 +03001884 cmd = "service ofagentd restart"
Roman Bubyrd4b87412019-08-05 12:52:40 +03001885 logging.info(cmd)
Roman Bubyr8c385572019-04-25 11:45:13 +03001886 child = pexpect.spawn('ssh -p 22 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no ' + self.switch_user +'@%s' % self.switch_ip)
1887 child.expect('[pP]assword:')
1888 child.sendline(self.switch_passwd)
Roman Bubyr8c385572019-04-25 11:45:13 +03001889 child.expect('root@localhost:~#')
1890 child.sendline(cmd)
1891 if regexp:
1892 child.expect(regexp)
1893
Roman Bubyr8c385572019-04-25 11:45:13 +03001894 child.close()
1895
1896
1897def switch_restart(self):
Roman Bubyr8c385572019-04-25 11:45:13 +03001898 regexp = 'The system is going down for reboot NOW!'
Roman Bubyr8c385572019-04-25 11:45:13 +03001899 cmd = "reboot"
Roman Bubyrd4b87412019-08-05 12:52:40 +03001900 logging.info(cmd)
Roman Bubyr8c385572019-04-25 11:45:13 +03001901 child = pexpect.spawn('ssh -p 22 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no ' + self.switch_user +'@%s' % self.switch_ip)
1902 child.expect('[pP]assword:')
1903 child.sendline(self.switch_passwd)
Roman Bubyr8c385572019-04-25 11:45:13 +03001904 child.expect('root@localhost:~#')
1905 child.sendline(cmd)
1906 if regexp:
1907 child.expect(regexp)
1908
Roman Bubyr8c385572019-04-25 11:45:13 +03001909 child.close()
1910
1911
1912def switch_port_enable(self, port, state):
1913 # @parameters:
1914 # port - port number on the switch to admin state Enable or Disable
1915 # state - admin state "False" - Down or "True" - Up for switch's port
Roman Bubyr8c385572019-04-25 11:45:13 +03001916 regexp = 'Returned from ofdpaBcmCommand rpc with rc = 0.'
Roman Bubyr8c385572019-04-25 11:45:13 +03001917 if state == False:
1918 cmd = "client_drivshell port xe{} enable=false".format(port - 1)
1919 elif state == True:
1920 cmd = "client_drivshell port xe{} enable=true".format(port - 1)
1921 else:
1922 assert False, "Incorrect port state parameter is given!"
1923
Roman Bubyrd4b87412019-08-05 12:52:40 +03001924 logging.info(cmd)
Roman Bubyr8c385572019-04-25 11:45:13 +03001925 child = pexpect.spawn('ssh -p 22 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no ' + self.switch_user +'@%s' % self.switch_ip)
1926 child.expect('[pP]assword:')
1927 child.sendline(self.switch_passwd)
Roman Bubyr8c385572019-04-25 11:45:13 +03001928 child.expect('root@localhost:~#')
1929 child.sendline(cmd)
1930 if regexp:
1931 child.expect(regexp)
1932
Roman Bubyr8c385572019-04-25 11:45:13 +03001933 child.close()
1934
1935
1936def switch_port_set_mtu(self, port, mtu):
1937 # @parameters:
1938 # port - port number on the switch to admin state Enable or Disable
1939 # mtu - size of MTU for switch's port in bytes
Roman Bubyr8c385572019-04-25 11:45:13 +03001940 regexp = 'Returned from ofdpaBcmCommand rpc with rc = 0.'
Roman Bubyr8c385572019-04-25 11:45:13 +03001941 cmd = ("client_drivshell port xe{} FrameMax=" + str(mtu)).format(port - 1)
Roman Bubyrd4b87412019-08-05 12:52:40 +03001942 logging.info(cmd)
Roman Bubyr8c385572019-04-25 11:45:13 +03001943 child = pexpect.spawn('ssh -p 22 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no ' + self.switch_user +'@%s' % self.switch_ip)
1944 child.expect('[pP]assword:')
1945 child.sendline(self.switch_passwd)
Roman Bubyr8c385572019-04-25 11:45:13 +03001946 child.expect('root@localhost:~#')
1947 child.sendline(cmd)
1948 if regexp:
1949 child.expect(regexp)
1950
Roman Bubyr8c385572019-04-25 11:45:13 +03001951 child.close()
1952
1953
1954def send_command_to_switch_cli(log_file, cmd, switch_ip, switch_user, switch_passwd, regexp=None):
1955 log_path = (config["log_dir"])
Roman Bubyrd4b87412019-08-05 12:52:40 +03001956 output = open(log_path + '/' + log_file, 'a+')
1957 logging.info(cmd)
Roman Bubyr8c385572019-04-25 11:45:13 +03001958 child = pexpect.spawn('ssh -p 22 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no ' + switch_user +'@%s' % switch_ip)
1959 child.expect('[pP]assword:')
1960 child.sendline(switch_passwd)
1961 child.logfile = output
1962 child.expect('root@localhost:~#')
1963 child.sendline(cmd)
1964 if regexp:
1965 child.expect(regexp)
1966
1967 output.close()
1968 child.close()
1969
1970
1971def send_command_to_onos_cli(log_file, cmd, onos_server, onos_user, onos_passwd, regexp=None):
1972 log_path = (config["log_dir"])
Roman Bubyrd4b87412019-08-05 12:52:40 +03001973 output = open(log_path + '/' + log_file, 'a+')
1974 logging.info(cmd)
Roman Bubyr8c385572019-04-25 11:45:13 +03001975 child = pexpect.spawn('ssh -p 30115 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no ' + onos_user + '@%s' % onos_server)
1976 child.expect('[pP]assword:')
1977 child.sendline(onos_passwd)
1978 child.logfile = output
1979 child.expect('onos>')
1980 child.sendline(cmd)
1981 if regexp:
1982 child.expect(regexp)
1983
1984 output.close()
1985 child.close()
1986
1987
Roman Bubyrd4b87412019-08-05 12:52:40 +03001988def add_onos_xconnect(self, datapathid, vid, port1, port2):
Roman Bubyr8c385572019-04-25 11:45:13 +03001989 cmd = "sr-xconnect-add of:" + datapathid + " " + str(vid) + " " + str(port1) + " " + str(port2)
1990 regexp = 'onos>'
Roman Bubyrd4b87412019-08-05 12:52:40 +03001991 logging.info(cmd)
Roman Bubyr8c385572019-04-25 11:45:13 +03001992 child = pexpect.spawn(
1993 'ssh -p 30115 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no ' + self.onos_user + '@%s' % self.onos_server_ip)
1994 child.expect('[pP]assword:')
1995 child.sendline(self.onos_passwd)
Roman Bubyr8c385572019-04-25 11:45:13 +03001996 child.expect('onos>')
1997 child.sendline(cmd)
1998 if regexp:
1999 child.expect(regexp)
2000
Roman Bubyr8c385572019-04-25 11:45:13 +03002001 child.close()
2002
2003def remove_onos_xconnect(self,datapathid, vid):
Roman Bubyr8c385572019-04-25 11:45:13 +03002004 cmd = "sr-xconnect-remove of:" + datapathid + " " + str(vid)
2005 regexp = 'onos>'
Roman Bubyrd4b87412019-08-05 12:52:40 +03002006 logging.info(cmd)
Roman Bubyr8c385572019-04-25 11:45:13 +03002007 child = pexpect.spawn(
2008 'ssh -p 30115 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no ' + self.onos_user + '@%s' % self.onos_server_ip)
2009 child.expect('[pP]assword:')
2010 child.sendline(self.onos_passwd)
Roman Bubyr8c385572019-04-25 11:45:13 +03002011 child.expect('onos>')
2012 child.sendline(cmd)
2013 if regexp:
2014 child.expect(regexp)
2015
Roman Bubyr8c385572019-04-25 11:45:13 +03002016 child.close()
2017
2018
2019def ofagent_reconfig(self, arg):
2020 # @parameters:
2021 # arg - configure switch with both OFTest and ONOS (arg = yes) or only OFTest is required (arg = no)
Roman Bubyr8c385572019-04-25 11:45:13 +03002022 if arg == "yes":
2023 logging.info("Reconfigure OFAGENT to use both ONOS and OFTEST")
2024 comd = "sed -i '/^OPT_ARGS=/c\OPT_ARGS=\"-d 2 -c 2 -c 4 -t " + self.controller_ip + ":" + self.controller_port + " -t " + self.onos_server_ip + ":" + self.onos_port + " -i $DPID\"' /etc/ofagent/ofagent.conf"
2025 send_command_to_switch_cli("test_ofagent_reconfigure_yes", comd, self.switch_ip, self.switch_user, self.switch_passwd, regexp='root@localhost:~#')
2026 time.sleep(1)
2027 elif arg == "no":
2028 logging.info("Reconfigure OFAGENT to use OFTEST only")
2029 comd = "sed -i '/^OPT_ARGS=/c\OPT_ARGS=\"-d 2 -c 2 -c 4 -t " + self.controller_ip + ":" + self.controller_port + " -i $DPID\"' /etc/ofagent/ofagent.conf"
2030 send_command_to_switch_cli("test_ofagent_reconfigure_no", comd, self.switch_ip, self.switch_user, self.switch_passwd, regexp='root@localhost:~#')
2031 time.sleep(1)
2032
Sreeju Sreedhare3fefd92019-04-02 15:57:15 -07002033"""
2034MPLS
2035"""
2036
2037OFDPA_MPLS_SUBTYPE_SHIFT=24
2038OFDPA_MPLS_GROUP_SUBTYPE_L2_VPN_LABEL=1
2039OFDPA_MPLS_GROUP_SUBTYPE_L3_VPN_LABEL=2
2040OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL1=3
2041OFDPA_MPLS_GROUP_SUBTYPE_TUNNEL_LABEL2=4
2042OFDPA_MPLS_GROUP_SUBTYPE_SWAP_LABEL=5
2043OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP=6
2044OFDPA_MPLS_GROUP_SUBTYPE_ECMP=8
2045OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG=10
2046
2047
2048
2049
2050def encode_mpls_interface_group_id(subtype, index):
2051 index=index&0x00ffffff
2052 assert(subtype==0)
2053 return index + (9 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
2054
2055def encode_mpls_label_group_id(subtype, index):
2056 index=index&0x00ffffff
2057 assert(subtype <=5 or subtype==0)
2058 #1: l2 vpn label
2059 #2: l3 vpn label
2060 #3: mpls tunnel label 1
2061 #4: mpls tunnel lable 2
2062 #5: mpls swap label
2063 return index + (9 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
2064
2065def encode_mpls_forwarding_group_id(subtype, index):
2066 index=index&0x00ffffff
2067 assert(subtype==6 or subtype==8 or subtype==10)
2068 return index + (10 << OFDPA_GROUP_TYPE_SHIFT)+(subtype<<OFDPA_MPLS_SUBTYPE_SHIFT)
2069
2070
2071def add_mpls_intf_group(ctrl, ref_gid, dst_mac, src_mac, vid, index, subtype=0, send_barrier=False, add=True):
2072 action=[]
2073 action.append(ofp.action.set_field(ofp.oxm.eth_src(src_mac)))
2074 action.append(ofp.action.set_field(ofp.oxm.eth_dst(dst_mac)))
2075 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+vid)))
2076 action.append(ofp.action.group(ref_gid))
2077
2078 buckets = [ofp.bucket(actions=action)]
2079
2080 mpls_group_id =encode_mpls_interface_group_id(subtype, index)
2081 if add:
2082 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
2083 group_id=mpls_group_id,
2084 buckets=buckets
2085 )
2086 else:
2087 request = ofp.message.group_modify(group_type=ofp.OFPGT_INDIRECT,
2088 group_id=mpls_group_id,
2089 buckets=buckets
2090 )
2091
2092
2093 logging.debug("Adding MPLS interface group %02x, src_mac %s , dst_mac %s , vid %d", mpls_group_id, src_mac, dst_mac, vid)
2094 ctrl.message_send(request)
2095
2096 if send_barrier:
2097 do_barrier(ctrl)
2098 return mpls_group_id, request
2099
2100def add_mpls_tunnel_label_group(
2101 ctrl,
2102 ref_gid,
2103 subtype,
2104 index,
2105 label,
2106 ):
2107
2108 action=[]
2109 action.append(ofp.action.push_mpls(0x8847))
2110 action.append(ofp.action.set_field(ofp.oxm.mpls_label(label)))
2111 action.append(ofp.action.group(ref_gid))
2112 buckets = [ofp.bucket(actions=action)]
2113
2114 mpls_group_id = encode_mpls_label_group_id(subtype, index)
2115 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
2116 group_id=mpls_group_id,
2117 buckets=buckets
2118 )
2119 ctrl.message_send(request)
2120
2121 return mpls_group_id, request
2122
2123def add_mpls_swap_label_group(
2124 ctrl,
2125 ref_gid,
2126 subtype,
2127 index,
2128 label,
2129 ):
2130
2131 action=[]
2132 action.append(ofp.action.set_field(ofp.oxm.mpls_label(label)))
2133 action.append(ofp.action.group(ref_gid))
2134 buckets = [ofp.bucket(actions=action)]
2135
2136 mpls_group_id = encode_mpls_label_group_id(subtype, index)
2137 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
2138 group_id=mpls_group_id,
2139 buckets=buckets
2140 )
2141 logging.debug("Adding MPLS Swap group %02x, label %d", mpls_group_id, label)
2142 ctrl.message_send(request)
2143
2144 return mpls_group_id, request
2145
2146def add_mpls_label_group(ctrl, subtype, index, ref_gid,
2147 lmep_id=-1,
2148 qos_index=-1,
2149 push_l2_header=False,
2150 push_vlan=False,
2151 push_mpls_header=False,
2152 push_cw=False,
2153 set_mpls_label=None,
2154 set_bos=None,
2155 set_tc=None,
2156 set_tc_from_table=False,
2157 cpy_tc_outward=False,
2158 set_ttl=None,
2159 cpy_ttl_outward=False,
2160 oam_lm_tx_count=False,
2161 set_pri_from_table=False,
2162 send_barrier=False
2163 ):
2164 """
2165 @ref_gid: only can be mpls intf group or mpls tunnel label 1/2 group
2166 """
2167 action=[]
2168
2169 if push_vlan== True:
2170 action.append(ofp.action.push_vlan(0x8100))
2171 if push_mpls_header== True:
2172 action.append(ofp.action.push_mpls(0x8847))
2173 if set_mpls_label != None:
2174 action.append(ofp.action.set_field(ofp.oxm.mpls_label(set_mpls_label)))
2175 if set_bos != None:
2176 action.append(ofp.action.set_field(ofp.oxm.mpls_bos(set_bos)))
2177 if set_tc != None:
2178 assert(set_tc_from_table==False)
2179 action.append(ofp.action.set_field(ofp.oxm.mpls_tc(set_tc)))
2180 if set_ttl != None:
2181 action.append(ofp.action.set_mpls_ttl(set_ttl))
2182 if cpy_ttl_outward == True:
2183 action.append(ofp.action.copy_ttl_out())
2184 """
2185 ofdpa experimenter
2186 """
2187 if push_l2_header== True:
2188 action.append(ofp.action.ofdpa_push_l2_header())
2189 if set_tc_from_table== True:
2190 assert(qos_index>=0)
2191 assert(set_tc == None)
2192 action.append(ofp.action.ofdpa_set_tc_from_table(qos_index))
2193 if cpy_tc_outward == True:
2194 action.append(ofp.action.ofdpa_copy_tc_out())
2195 if oam_lm_tx_count == True:
2196 assert(qos_index>=0 and lmep_id>=0)
2197 action.append(ofp.action.ofdpa_oam_lm_tx_count(lmep_id, qos_index))
2198 if set_pri_from_table == True:
2199 assert(qos_index>=0)
2200 action.append(ofp.action.ofdpa_set_qos_from_table(qos_index))
2201 if push_cw == True:
2202 action.append(ofp.action.ofdpa_push_cw())
2203
2204 action.append(ofp.action.group(ref_gid))
2205 buckets = [ofp.bucket(actions=action)]
2206
2207 mpls_group_id = encode_mpls_label_group_id(subtype, index)
2208 request = ofp.message.group_add(group_type=ofp.OFPGT_INDIRECT,
2209 group_id=mpls_group_id,
2210 buckets=buckets
2211 )
2212 ctrl.message_send(request)
2213
2214 if send_barrier:
2215 do_barrier(ctrl)
2216
2217 return mpls_group_id, request
2218
2219def add_mpls_l2_port_flow(ctrl, of_port, mpls_l2_port, tunnel_index, ref_gid, qos_index=0, goto=MPLS_L2_PORT_PCP_TRUST_FLOW_TABLE):
2220 """
2221 Only action is Group, which must indicate one of:
2222 MPLS L2 VPN Label or Fast Failover Protection Group.
2223 ref_gid contains this information
2224 """
2225
2226 match = ofp.match()
2227
2228 write_actions = []
2229 write_actions.append(ofp.action.group(ref_gid))
2230 apply_actions = []
2231
2232 if goto==MPLS_L2_PORT_PCP_TRUST_FLOW_TABLE:
2233 tunnel_id = tunnel_index + ofp.oxm.TUNNEL_ID_BASE
2234 match.oxm_list.append(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port))
2235 match.oxm_list.append(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE))
2236 assert(qos_index>=0)
2237 apply_actions.append(ofp.action.set_field(ofp.oxm.exp1ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_QOS_INDEX, value=qos_index)))
2238
2239 request = ofp.message.flow_add(
2240 table_id=MPLS_L2_PORT_FLOW_TABLE,
2241 cookie=42,
2242 match=match,
2243 instructions=[
2244 ofp.instruction.apply_actions(actions=apply_actions),
2245 ofp.instruction.write_actions(actions=write_actions),
2246 ofp.instruction.goto_table(goto)
2247 ],
2248 buffer_id=ofp.OFP_NO_BUFFER,
2249 priority=1)
2250 logging.info("Inserting flow for Pseudowire Initiation %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)
2251 ctrl.message_send(request)
2252
2253 if goto==ACL_FLOW_TABLE:
2254 tunnel_id = tunnel_index + ofp.oxm.TUNNEL_ID_BASE
2255 match.oxm_list.append(ofp.oxm.exp4ByteValue(exp_type=ofp.oxm.OFDPA_EXP_TYPE_MPLS_L2_PORT, value=0x00000000 + of_port))
2256 match.oxm_list.append(ofp.oxm.tunnel_id(tunnel_index + ofp.oxm.TUNNEL_ID_BASE_CROSS_CONNECT))
2257 request = ofp.message.flow_add(
2258 table_id=MPLS_L2_PORT_FLOW_TABLE,
2259 cookie=42,
2260 match=match,
2261 instructions=[
2262 ofp.instruction.apply_actions(actions=apply_actions),
2263 ofp.instruction.write_actions(actions=write_actions),
2264 ofp.instruction.goto_table(goto)
2265 ],
2266 buffer_id=ofp.OFP_NO_BUFFER,
2267 priority=1)
2268 logging.info("Inserting flow for VLAN Cross Connect %d mpls_l2_port, %d tunnel_id, action %x group and go to table %d", mpls_l2_port, tunnel_id, ref_gid, ACL_FLOW_TABLE)
2269 ctrl.message_send(request)
2270
2271 return request
2272
2273def add_mpls_forwarding_group(ctrl, subtype, index, ref_gids,
2274 watch_port=None,
2275 watch_group=ofp.OFPP_ANY,
2276 push_vlan=None,
2277 pop_vlan=None,
2278 set_vid=None):
2279 assert(subtype == OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP
2280 or subtype == OFDPA_MPLS_GROUP_SUBTYPE_ECMP
2281 or subtype == OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG)
2282
2283 buckets=[]
2284 if subtype == OFDPA_MPLS_GROUP_SUBTYPE_FAST_FAILOVER_GROUP:
2285 group_type = ofp.OFPGT_FF
2286 for gid in ref_gids:
2287 action=[]
2288 action.append(ofp.action.group(gid))
2289 buckets.append(ofp.bucket(watch_port=watch_port, watch_group=watch_group,actions=action))
2290
2291 elif subtype == OFDPA_MPLS_GROUP_SUBTYPE_ECMP:
2292 group_type = ofp.OFPGT_SELECT
2293 for gid in ref_gids:
2294 action=[]
2295 action.append(ofp.action.group(gid))
2296 buckets.append(ofp.bucket(actions=action))
2297
2298 elif subtype == OFDPA_MPLS_GROUP_SUBTYPE_L2_TAG:
2299 group_type = ofp.OFPGT_INDIRECT
2300 action=[]
2301 if set_vid!=None:
2302 action.append(ofp.action.set_field(ofp.oxm.vlan_vid(0x1000+set_vid)))
2303 if push_vlan!=None:
2304 action.append(ofp.action.push_vlan(push_vlan))
2305 if pop_vlan!=None:
2306 action.append(ofp.action.pop_vlan())
2307 action.append(ofp.action.group(ref_gids[0]))
2308 buckets.append(ofp.bucket(actions=action))
2309
2310 mpls_group_id = encode_mpls_forwarding_group_id(subtype, index)
2311 request = ofp.message.group_add(group_type=group_type,
2312 group_id=mpls_group_id,
2313 buckets=buckets
2314 )
2315 ctrl.message_send(request)
2316 return mpls_group_id, request
2317
2318def add_one_egress_vlan_tpid_table_flow(ctrl, of_port):
2319 # Used for changing ethertype of outer vlan header to 0x88a8
2320
2321 match = ofp.match()
2322 match.oxm_list.append(ofp.oxm.exp4ByteValue(ofp.oxm.OFDPA_EXP_TYPE_ACTSET_OUTPUT, of_port, ONF_EXPERIMENTER_ID))
2323 match.oxm_list.append(ofp.oxm.vlan_vid_masked(ofp.OFPVID_PRESENT, ofp.OFPVID_PRESENT))
2324
2325 actions = []
2326 actions.append(ofp.action.copy_field(
2327 12, 0, 0, ['\x80\x00\x0c\x02', ofp.oxm.exp4ByteReg(oxm_field = 1).pack()])) # VLAN_VID, PACKET_REG(1)
2328 actions.append(ofp.action.pop_vlan())
2329 actions.append(ofp.action.push_vlan(0x88a8))
2330 actions.append(ofp.action.copy_field(
2331 12, 0, 0, [ofp.oxm.exp4ByteReg(oxm_field = 1).pack(), '\x80\x00\x0c\x02'])) # PACKET_REG(1), VLAN_VID
2332
2333 request = ofp.message.flow_add(
2334 table_id=EGRESS_TPID_FLOW_TABLE,
2335 cookie=42,
2336 match=match,
2337 instructions=[
2338 ofp.instruction.apply_actions(
2339 actions=actions
2340 ),
2341 ],
2342 priority=0)
2343
2344 ctrl.message_send(request)
2345
2346 return
2347
2348"""
2349display
2350"""
2351def print_current_table_flow_stat(ctrl, table_id=0xff):
2352 stat_req=ofp.message.flow_stats_request()
2353 response, pkt = ctrl.transact(stat_req)
2354 if response == None:
2355 print "no response"
2356 return None
2357 print len(response.entries)
2358 for obj in response.entries:
2359 print "match ", obj.match
2360 print "cookie", obj.cookie
2361 print "priority", obj.priority
2362 print "idle_timeout", obj.idle_timeout
2363 print "hard_timeout", obj.hard_timeout
2364 #obj.actions
2365 print "packet count: %lx"%obj.packet_count
2366