blob: c5cf95f2a1911fba4787a3a170de517382fc6039 [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
Pierbbdf3782016-08-22 17:58:26 -070017import Queue
Piercf76e802016-09-19 20:16:35 -070018import itertools
Pierbbdf3782016-08-22 17:58:26 -070019
20from oftest.testutils import *
21from accton_util import *
22
Piercf76e802016-09-19 20:16:35 -070023"""
24MISC
25"""
26
27def print_port_stats(test, port):
28 entries = get_port_stats(test, port)
29 for item in entries:
30 packet_rcv = item.rx_packets
31 packet_rcv_dropped = item.rx_dropped
32 packet_rcv_errors = item.rx_errors
33
34 packet_sent = item.tx_packets
35 packet_sent_dropped = item.tx_dropped
36 packet_sent_errors = item.tx_errors
37
Pier1e4e98e2016-10-26 14:36:05 -070038 print "\nPort %d stats count: tx %d rx %d - tx_dropped %d rx_dropped %d - tx_errors %d rx_errors %d" % (
Piercf76e802016-09-19 20:16:35 -070039 port, packet_sent, packet_rcv, packet_sent_dropped, packet_rcv_dropped, packet_sent_errors, packet_rcv_errors
40 )
41
42def filter_dhcp(controller):
43 match = ofp.match( )
44 match.oxm_list.append( ofp.oxm.eth_type( 0x0800 ) )
45 match.oxm_list.append( ofp.oxm.ip_proto( 17 ) )
46 match.oxm_list.append( ofp.oxm.udp_src( 68 ) )
47 match.oxm_list.append( ofp.oxm.udp_dst( 67 ))
48 request = ofp.message.flow_add(
49 table_id=60,
50 cookie=42,
51 match=match,
52 instructions=[ofp.instruction.clear_actions( )],
53 buffer_id=ofp.OFP_NO_BUFFER,
54 priority=1
55 )
56 controller.message_send( request )
57 do_barrier( controller )
58
59def filter_ipv6(controller):
60 match = ofp.match( )
61 match.oxm_list.append( ofp.oxm.eth_type( 0x86dd ) )
62 request = ofp.message.flow_add(
63 table_id=60,
64 cookie=42,
65 match=match,
66 instructions=[ofp.instruction.clear_actions( )],
67 buffer_id=ofp.OFP_NO_BUFFER,
68 priority=1
69 )
70 controller.message_send( request )
71 do_barrier( controller )
72
73def filter_igmp(controller):
74 match = ofp.match( )
75 match.oxm_list.append( ofp.oxm.eth_type( 0x0800 ) )
76 match.oxm_list.append( ofp.oxm.ip_proto( 2 ) )
77 request = ofp.message.flow_add(
78 table_id=60,
79 cookie=42,
80 match=match,
81 instructions=[ofp.instruction.clear_actions( )],
82 buffer_id=ofp.OFP_NO_BUFFER,
83 priority=1
84 )
85 controller.message_send( request )
86 do_barrier( controller )
87
Piercf76e802016-09-19 20:16:35 -070088"""
89MULTICAST Pipelines
90"""
91
Pier7b031af2016-08-25 15:00:22 -070092def fill_mcast_pipeline_L3toL2(
93 controller,
94 logging,
95 ports,
96 is_ingress_tagged,
97 is_egress_tagged,
98 is_vlan_translated,
99 is_max_vlan
100 ):
101 """
102 This method, according to the scenario, fills properly
103 the pipeline. The method generates using ports data the
104 necessary information to fill the multicast pipeline and
105 fills properly the pipeline which consists in this scenario:
106
107 i) to create l2 interface groups;
108 ii) to create l3 multicast groups;
109 iii) to add multicast flows;
110 iv) to add termination; flows;
111 v) to add vlan flows
112
113 Scenarios:
114 1) ingress untagged, egress untagged
115 2) ingress untagged, egress tagged
116 3) ingress tagged, egress untagged
117 4) ingress tagged, egress tagged, no translation
118 5) ingress tagged, egress tagged, translation
119 """
120
121 MAX_INTERNAL_VLAN = 4094
122 # Used for no translation
123 FIXED_VLAN = 300
124 Groups = Queue.LifoQueue( )
125 L2_Groups = []
126 port_to_in_vlan = {}
127 port_to_out_vlan = {}
128 port_to_src_mac = {}
129 port_to_src_mac_str = {}
130 port_to_dst_mac = {}
131 port_to_dst_mac_str = {}
132 port_to_src_ip = {}
133 port_to_src_ip_str = {}
134 src_ip_0 = 0xc0a80100
135 src_ip_0_str = "192.168.1.%s"
136 dst_ip = 0xe0000001
137 switch_mac = [ 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 ]
138
139 for port in ports:
140 in_vlan_id = port + 1
141 out_vlan_id = MAX_INTERNAL_VLAN - port
142 if is_max_vlan and not is_vlan_translated:
143 in_vlan_id = MAX_INTERNAL_VLAN
144 out_vlan_id = MAX_INTERNAL_VLAN
145 elif not is_max_vlan and not is_vlan_translated:
146 in_vlan_id = FIXED_VLAN
147 out_vlan_id = FIXED_VLAN
148 src_mac = [ 0x00, 0x11, 0x11, 0x11, 0x11, port ]
149 src_mac_str = ':'.join( [ '%02X' % x for x in src_mac ] )
150 dst_mac = [ 0x01, 0x00, 0x5e, 0x01, 0x01, port ]
151 dst_mac_str = ':'.join( [ '%02X' % x for x in dst_mac ] )
152 src_ip = src_ip_0 + port
153 src_ip_str = src_ip_0_str % port
154 port_to_in_vlan[port] = in_vlan_id
155 port_to_out_vlan[port] = out_vlan_id
156 port_to_src_mac[port] = src_mac
157 port_to_src_mac_str[port] = src_mac_str
158 port_to_dst_mac[port] = dst_mac
159 port_to_dst_mac_str[port] = dst_mac_str
160 port_to_src_ip[port] = src_ip
161 port_to_src_ip_str[port] = src_ip_str
162
163 for in_port in ports:
164
165 L2_Groups = []
166 # add vlan flows table
Pier265ad5f2017-02-28 17:46:28 +0100167 add_one_vlan_table_flow( controller, in_port, 1, port_to_in_vlan[in_port], flag=VLAN_TABLE_FLAG_ONLY_TAG )
Pier7b031af2016-08-25 15:00:22 -0700168 if not is_ingress_tagged:
Pier265ad5f2017-02-28 17:46:28 +0100169 add_one_vlan_table_flow( controller, in_port, 1, port_to_in_vlan[in_port], flag=VLAN_TABLE_FLAG_ONLY_UNTAG )
Pier7b031af2016-08-25 15:00:22 -0700170 elif is_vlan_translated:
171 add_one_vlan_table_flow_translation( controller, in_port, port_to_in_vlan[in_port], port_to_out_vlan[in_port], flag=VLAN_TABLE_FLAG_ONLY_TAG)
172 # add termination flow
173 if not is_vlan_translated:
174 add_termination_flow( controller, in_port, 0x0800, switch_mac, port_to_in_vlan[in_port] )
175 else:
176 add_termination_flow( controller, in_port, 0x0800, switch_mac, port_to_out_vlan[in_port] )
177
178 for out_port in ports:
179 if out_port == in_port:
180 continue
181 # add l2 interface group, vlan_id equals for each port and must coincide with mcast_group vlan_id
182 if not is_vlan_translated:
183 l2gid, msg = add_one_l2_interface_group( controller, out_port, vlan_id=port_to_in_vlan[in_port],
184 is_tagged=is_egress_tagged, send_barrier=True )
185 else:
186 l2gid, msg = add_one_l2_interface_group( controller, out_port, vlan_id=port_to_out_vlan[in_port],
187 is_tagged=is_egress_tagged, send_barrier=True )
188 Groups._put( l2gid )
189 L2_Groups.append( l2gid )
190
191 # add l3 mcast group
192 if not is_vlan_translated:
193 mcat_group_msg = add_l3_mcast_group( controller, port_to_in_vlan[in_port], in_port, L2_Groups )
194 else:
195 mcat_group_msg = add_l3_mcast_group( controller, port_to_out_vlan[in_port], in_port, L2_Groups )
196 Groups._put( mcat_group_msg.group_id )
197 # add mcast routing flow
198 if not is_vlan_translated:
199 add_mcast4_routing_flow( controller, port_to_in_vlan[in_port], port_to_src_ip[in_port], 0, dst_ip, mcat_group_msg.group_id )
200 else:
201 add_mcast4_routing_flow( controller, port_to_out_vlan[in_port], port_to_src_ip[in_port], 0, dst_ip, mcat_group_msg.group_id )
202
203 return (
204 port_to_in_vlan,
205 port_to_out_vlan,
206 port_to_src_mac_str,
207 port_to_dst_mac_str,
208 port_to_src_ip_str,
209 Groups
210 )
211
Pierbbdf3782016-08-22 17:58:26 -0700212def fill_mcast_pipeline_L3toL3(
213 controller,
214 logging,
215 ports,
216 is_ingress_tagged,
217 is_egress_tagged,
218 is_vlan_translated,
219 is_max_vlan
220 ):
221 """
222 This method, according to the scenario, fills properly
223 the pipeline. The method generates using ports data the
224 necessary information to fill the multicast pipeline and
225 fills properly the pipeline which consists in this scenario:
226
227 i) to create l2 interface groups;
228 ii)to create l3 interface groups;
229 iii) to create l3 multicast groups;
230 iv) to add multicast flows;
231 v) to add termination; flows;
232 vi) to add vlan flows
233
234 Scenarios:
235 1) ingress tagged, egress tagged, translation
236 """
237
238 Groups = Queue.LifoQueue( )
239 MAX_INTERNAL_VLAN = 4094
240 port_to_in_vlan = {}
241 port_to_out_vlan = {}
242 port_to_src_mac = {}
243 port_to_src_mac_str = {}
244 port_to_dst_mac = {}
245 port_to_dst_mac_str = {}
246 port_to_src_ip = {}
247 port_to_src_ip_str = {}
248 port_to_intf_src_mac = {}
249 port_to_intf_src_mac_str = {}
250 src_ip_0 = 0xc0a80100
251 src_ip_0_str = "192.168.1.%s"
252 dst_ip = 0xe0000001
253 switch_mac = [ 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 ]
254
255 for port in ports:
256 in_vlan_id = port + 1
257 out_vlan_id = MAX_INTERNAL_VLAN - port
258 src_mac = [ 0x00, 0x11, 0x11, 0x11, 0x11, port ]
259 src_mac_str = ':'.join( [ '%02X' % x for x in src_mac ] )
260 dst_mac = [ 0x01, 0x00, 0x5e, 0x01, 0x01, port ]
261 dst_mac_str = ':'.join( [ '%02X' % x for x in dst_mac ] )
262 src_ip = src_ip_0 + port
263 src_ip_str = src_ip_0_str % port
264 intf_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, port ]
265 intf_src_mac_str = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
266 port_to_in_vlan[port] = in_vlan_id
267 port_to_out_vlan[port] = out_vlan_id
268 port_to_src_mac[port] = src_mac
269 port_to_src_mac_str[port] = src_mac_str
270 port_to_dst_mac[port] = dst_mac
271 port_to_dst_mac_str[port] = dst_mac_str
272 port_to_src_ip[port] = src_ip
273 port_to_src_ip_str[port] = src_ip_str
274 port_to_intf_src_mac[port] = intf_src_mac
275 port_to_intf_src_mac_str[port] = intf_src_mac_str
276
277 for port in ports:
278 L3_Groups = []
279 for other_port in ports:
280 # add l2 interface group
281 l2gid, msg = add_one_l2_interface_group( controller, other_port, vlan_id=port_to_out_vlan[other_port],
282 is_tagged=True, send_barrier=False )
283 Groups._put( l2gid )
284 # add l3 interface group
285 l3group_ucast_msg = add_l3_interface_group( controller, other_port, port_to_out_vlan[other_port], port_to_in_vlan[other_port],
286 port_to_intf_src_mac[other_port] )
287 L3_Groups.append(l3group_ucast_msg.group_id)
288 Groups._put( l3group_ucast_msg.group_id )
289
290 # add mcast group
291 mcat_group_msg = add_l3_mcast_group( controller, port_to_in_vlan[port], port_to_in_vlan[port], L3_Groups )
292 Groups._put( mcat_group_msg.group_id )
293 # add mcast flow
294 add_mcast4_routing_flow( controller, port_to_in_vlan[port], port_to_src_ip[port], 0, dst_ip, mcat_group_msg.group_id )
295 # add termination flow
296 add_termination_flow( controller, port, 0x0800, switch_mac, port_to_in_vlan[port] )
297 # add vlan flow table
Pier265ad5f2017-02-28 17:46:28 +0100298 add_one_vlan_table_flow( controller, port, 1, port_to_in_vlan[port], flag=VLAN_TABLE_FLAG_ONLY_TAG )
Pierbbdf3782016-08-22 17:58:26 -0700299
300 return (
301 port_to_in_vlan,
302 port_to_out_vlan,
303 port_to_src_mac_str,
304 port_to_dst_mac_str,
305 port_to_src_ip_str,
306 port_to_intf_src_mac_str,
307 Groups
Piercf76e802016-09-19 20:16:35 -0700308 )
309
310"""
311VPWS Pipeline
312"""
313
314OF_DPA_MPLS_L2_VPN_Label = 1
315OF_DPA_MPLS_Tunnel_Label_1 = 3
316OF_DPA_MPLS_Tunnel_Label_2 = 4
317
318EGRESS_UNTAGGED = 1
319EGRESS_TAGGED = 2
320EGRESS_TAGGED_TRANS = 3
321
322
323def fill_pw_initiation_pipeline(
324 controller,
325 logging,
326 in_port,
327 out_port,
328 ingress_tags,
329 egress_tag,
330 mpls_labels
331 ):
332 """
333 This method, according to the scenario, fills properly
334 the pw pipeline. The method generates using ports data the
335 necessary information to fill the pw pipeline and
336 fills properly the pipeline which consists into:
337
338 """
339
340 Groups = Queue.LifoQueue( )
341 out_vlan = 4094
342 port_to_in_vlan_1 = {}
343 port_to_in_vlan_2 = {}
344 port_to_in_vlan_3 = {}
345 port_to_src_mac = {}
346 port_to_src_mac_str = {}
347 port_to_dst_mac = {}
348 port_to_dst_mac_str = {}
Piercf76e802016-09-19 20:16:35 -0700349 port_to_mpls_label_1 = {}
350 port_to_mpls_label_2 = {}
351 port_to_mpls_label_pw = {}
352 ports = [in_port, out_port]
353
354 for port in ports:
355 in_vlan_id_1 = port + 1
356 in_vlan_id_2 = port + 100
357 in_vlan_id_3 = port + 300
358 mpls_label_1 = port + 100
359 mpls_label_2 = port + 200
360 mpls_label_pw = port + 300
361 port_to_in_vlan_1[port] = in_vlan_id_1
362 port_to_in_vlan_2[port] = in_vlan_id_2
363 port_to_in_vlan_3[port] = in_vlan_id_3
364 src_mac = [ 0x00, 0x00, 0x00, 0x00, 0x11, port ]
365 src_mac_str = ':'.join( [ '%02X' % x for x in src_mac ] )
366 dst_mac = [ 0x00, 0x00, 0x00, 0x11, 0x11, port ]
367 dst_mac_str = ':'.join( [ '%02X' % x for x in dst_mac ] )
368 port_to_src_mac[port] = src_mac
369 port_to_src_mac_str[port] = src_mac_str
370 port_to_dst_mac[port] = dst_mac
371 port_to_dst_mac_str[port] = dst_mac_str
372 port_to_mpls_label_1[port] = mpls_label_1
373 port_to_mpls_label_2[port] = mpls_label_2
374 port_to_mpls_label_pw[port] = mpls_label_pw
375
376 # add l2 interface group, we have to pop the VLAN;
377 l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(
378 ctrl=controller,
379 port=out_port,
380 vlan_id=out_vlan,
381 is_tagged=False,
382 send_barrier=False
383 )
384 Groups._put( l2_intf_gid )
385 # add MPLS interface group
386 mpls_intf_gid, mpls_intf_msg = add_mpls_intf_group(
387 ctrl=controller,
388 ref_gid=l2_intf_gid,
389 dst_mac=port_to_dst_mac[in_port],
390 src_mac=port_to_src_mac[out_port],
391 vid=out_vlan,
392 index=in_port
393 )
394 Groups._put( mpls_intf_gid )
395 mpls_gid = mpls_intf_gid
396 # add MPLS tunnel label groups, the number depends on the labels
397 if mpls_labels == 2:
398 mpls_tunnel_gid, mpls_tunnel_msg = add_mpls_tunnel_label_group(
399 ctrl=controller,
400 ref_gid=mpls_intf_gid,
401 subtype=OF_DPA_MPLS_Tunnel_Label_2,
402 index=in_port,
403 label=port_to_mpls_label_2[in_port]
404 )
405 Groups._put( mpls_tunnel_gid )
406 mpls_tunnel_gid, mpls_tunnel_msg = add_mpls_tunnel_label_group(
407 ctrl=controller,
408 ref_gid=mpls_tunnel_gid,
409 subtype=OF_DPA_MPLS_Tunnel_Label_1,
410 index=in_port,
411 label=port_to_mpls_label_1[in_port]
412 )
413 Groups._put( mpls_tunnel_gid )
414 mpls_gid = mpls_tunnel_gid
415 elif mpls_labels == 1:
416 mpls_tunnel_gid, mpls_tunnel_msg = add_mpls_tunnel_label_group(
417 ctrl=controller,
418 ref_gid=mpls_intf_gid,
419 subtype=OF_DPA_MPLS_Tunnel_Label_1,
420 index=in_port,
421 label=port_to_mpls_label_1[in_port]
422 )
423 Groups._put( mpls_tunnel_gid )
424 mpls_gid = mpls_tunnel_gid
Piercf76e802016-09-19 20:16:35 -0700425 # add MPLS L2 VPN group
426 mpls_l2_vpn_gid, mpls_l2_vpn_msg = add_mpls_label_group(
427 ctrl=controller,
428 subtype=OF_DPA_MPLS_L2_VPN_Label,
429 index=in_port,
430 ref_gid=mpls_gid,
431 push_l2_header=True,
432 push_vlan=True,
433 push_mpls_header=True,
434 push_cw=True,
435 set_mpls_label=port_to_mpls_label_pw[in_port],
436 set_bos=1,
437 cpy_ttl_outward=True
438 )
Piercf76e802016-09-19 20:16:35 -0700439 Groups._put( mpls_l2_vpn_gid )
440 # add MPLS L2 port flow
441 add_mpls_l2_port_flow(
442 ctrl=controller,
443 of_port=in_port,
444 mpls_l2_port=in_port,
445 tunnel_index=1,
446 ref_gid=mpls_l2_vpn_gid
447 )
448 # add VLAN flows table
449 if ingress_tags == 2:
450 if egress_tag == EGRESS_TAGGED:
451 add_one_vlan_1_table_flow_pw(
452 ctrl=controller,
453 of_port=in_port,
454 tunnel_index=1,
455 new_outer_vlan_id=-1,
456 outer_vlan_id=port_to_in_vlan_2[in_port],
457 inner_vlan_id=port_to_in_vlan_1[in_port],
458 )
459 elif egress_tag == EGRESS_TAGGED_TRANS:
460 add_one_vlan_1_table_flow_pw(
461 ctrl=controller,
462 of_port=in_port,
463 tunnel_index=1,
464 new_outer_vlan_id=port_to_in_vlan_3[in_port],
465 outer_vlan_id=port_to_in_vlan_2[in_port],
466 inner_vlan_id=port_to_in_vlan_1[in_port],
467 )
468 add_one_vlan_table_flow(
469 ctrl=controller,
470 of_port=in_port,
471 vlan_id=port_to_in_vlan_2[in_port],
472 flag=VLAN_TABLE_FLAG_ONLY_STACKED,
473 )
474 elif ingress_tags == 1:
475 if egress_tag == EGRESS_TAGGED:
476 add_one_vlan_table_flow_pw(
477 ctrl=controller,
478 of_port=in_port,
479 tunnel_index=1,
480 vlan_id=port_to_in_vlan_1[in_port],
481 flag=VLAN_TABLE_FLAG_ONLY_TAG,
482 )
483 elif egress_tag == EGRESS_TAGGED_TRANS:
484 add_one_vlan_table_flow_pw(
485 ctrl=controller,
486 of_port=in_port,
487 tunnel_index=1,
488 vlan_id=port_to_in_vlan_1[in_port],
489 new_vlan_id=port_to_in_vlan_3[in_port],
490 flag=VLAN_TABLE_FLAG_ONLY_TAG,
491 )
492 elif ingress_tags == 0:
493 filter_dhcp(controller)
494 filter_ipv6(controller)
495 filter_igmp(controller)
496 if egress_tag == EGRESS_UNTAGGED:
497 add_one_vlan_table_flow_pw(
498 ctrl=controller,
499 of_port=in_port,
500 tunnel_index=1,
501 flag=VLAN_TABLE_FLAG_ONLY_UNTAG,
502 )
503 elif egress_tag == EGRESS_TAGGED:
504 add_one_vlan_table_flow_pw(
505 ctrl=controller,
506 of_port=in_port,
507 tunnel_index=1,
508 vlan_id=port_to_in_vlan_1[in_port],
509 flag=VLAN_TABLE_FLAG_ONLY_UNTAG,
510 )
511
512 return (
513 port_to_mpls_label_2,
514 port_to_mpls_label_1,
515 port_to_mpls_label_pw,
516 port_to_in_vlan_3,
517 port_to_in_vlan_2,
518 port_to_in_vlan_1,
519 port_to_src_mac_str,
520 port_to_dst_mac_str,
521 Groups
522 )
Pierb5da4c92016-09-21 11:23:35 -0700523
524MPLS_FLOW_TABLE_0 = 23
525OF_DPA_MPLS_SWAP_Label = 5
526
527def fill_pw_intermediate_transport_pipeline(
528 controller,
529 logging,
530 ports,
531 mpls_labels
532 ):
533 """
534 This method, according to the scenario, fills properly
535 the pw pipeline. The method generates using ports data the
536 necessary information to fill the pw pipeline and
537 fills properly the pipeline which consists into:
538
539 """
540
541 Groups = Queue.LifoQueue( )
542 out_vlan = 4094
543 port_to_src_mac = {}
544 port_to_src_mac_str = {}
545 port_to_dst_mac = {}
546 port_to_dst_mac_str = {}
547 port_to_mpls_label_2 = {}
548 port_to_mpls_label_1 = {}
549 port_to_mpls_label_pw = {}
550 port_to_switch_mac = {}
551 port_to_switch_mac_str = {}
552
553 for port in ports:
554 mpls_label_1 = port + 10
555 mpls_label_2 = port + 100
556 mpls_label_pw = port + 300
557 src_mac = [ 0x00, 0x00, 0x00, 0x00, 0x11, port ]
558 src_mac_str = ':'.join( [ '%02X' % x for x in src_mac ] )
559 dst_mac = [ 0x00, 0x00, 0x00, 0x11, 0x11, port ]
560 dst_mac_str = ':'.join( [ '%02X' % x for x in dst_mac ] )
561 switch_mac = [ 0x00, 0x00, 0x00, 0x00, 0x00, port ]
562 switch_mac_str = ':'.join( [ '%02X' % x for x in switch_mac ] )
563 port_to_src_mac[port] = src_mac
564 port_to_src_mac_str[port] = src_mac_str
565 port_to_dst_mac[port] = dst_mac
566 port_to_dst_mac_str[port] = dst_mac_str
567 port_to_mpls_label_1[port] = mpls_label_1
568 port_to_mpls_label_2[port] = mpls_label_2
569 port_to_mpls_label_pw[port] = mpls_label_pw
570 port_to_switch_mac[port] = switch_mac
571 port_to_switch_mac_str[port] = switch_mac_str
572
573 for pair in itertools.product(ports, ports):
574 in_port = pair[0]
575 out_port = pair[1]
576 if out_port == in_port:
577 continue
578 # add l2 interface group, we have to pop the VLAN;
579 l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(
580 ctrl=controller,
581 port=out_port,
582 vlan_id=out_vlan,
583 is_tagged=False,
584 send_barrier=False
585 )
586 Groups._put( l2_intf_gid )
587 # add MPLS interface group
588 mpls_intf_gid, mpls_intf_msg = add_mpls_intf_group(
589 ctrl=controller,
590 ref_gid=l2_intf_gid,
591 dst_mac=port_to_dst_mac[in_port],
592 src_mac=port_to_src_mac[out_port],
593 vid=out_vlan,
594 index=in_port
595 )
596 Groups._put( mpls_intf_gid )
597 # add MPLS flows
598 if mpls_labels >=2:
599 add_mpls_flow_pw(
600 ctrl=controller,
601 action_group_id=mpls_intf_gid,
602 label=port_to_mpls_label_2[in_port],
603 ethertype=0x8847,
604 tunnel_index=1,
605 bos=0
606 )
607 else:
608 mpls_tunnel_gid, mpls_tunnel_msg = add_mpls_tunnel_label_group(
609 ctrl=controller,
610 ref_gid=mpls_intf_gid,
611 subtype=OF_DPA_MPLS_Tunnel_Label_2,
612 index=in_port,
613 label=port_to_mpls_label_2[in_port]
614 )
615 Groups._put( mpls_tunnel_gid )
616 mpls_tunnel_gid, mpls_tunnel_msg = add_mpls_tunnel_label_group(
617 ctrl=controller,
618 ref_gid=mpls_tunnel_gid,
619 subtype=OF_DPA_MPLS_Tunnel_Label_1,
620 index=in_port,
621 label=port_to_mpls_label_1[in_port]
622 )
623 Groups._put( mpls_tunnel_gid )
624 mpls_swap_gid, mpls_tunnel_msg = add_mpls_swap_label_group(
625 ctrl=controller,
626 ref_gid=mpls_tunnel_gid,
627 subtype=OF_DPA_MPLS_SWAP_Label,
628 index=in_port,
629 label=port_to_mpls_label_pw[in_port]
630 )
631 Groups._put( mpls_swap_gid )
632 add_mpls_flow_pw(
633 ctrl=controller,
634 action_group_id=mpls_swap_gid,
635 label=port_to_mpls_label_pw[in_port],
636 ethertype=0x8847,
637 tunnel_index=1,
638 bos=1,
639 popMPLS=False,
640 popL2=False
641 )
642 # add Termination flow
643 add_termination_flow(
644 ctrl=controller,
645 in_port=in_port,
646 eth_type=0x8847,
647 dst_mac=port_to_switch_mac[in_port],
648 vlanid=out_vlan,
649 goto_table=MPLS_FLOW_TABLE_0)
650 # add VLAN flows
651 add_one_vlan_table_flow(
652 ctrl=controller,
653 of_port=in_port,
654 vlan_id=out_vlan,
655 flag=VLAN_TABLE_FLAG_ONLY_TAG,
Pierb5da4c92016-09-21 11:23:35 -0700656 )
657 add_one_vlan_table_flow(
658 ctrl=controller,
659 of_port=in_port,
660 vlan_id=out_vlan,
661 flag=VLAN_TABLE_FLAG_ONLY_UNTAG
662 )
663
664 return (
665 port_to_mpls_label_2,
666 port_to_mpls_label_1,
667 port_to_mpls_label_pw,
668 port_to_switch_mac_str,
669 port_to_src_mac_str,
670 port_to_dst_mac_str,
671 Groups
672 )
Pierf6f28162016-09-22 16:30:52 -0700673
674def fill_pw_termination_pipeline(
675 controller,
676 logging,
677 in_port,
678 out_port,
Pier23784aa2016-09-19 20:08:21 -0700679 egress_tags
Pierf6f28162016-09-22 16:30:52 -0700680 ):
681 """
682 This method, according to the scenario, fills properly
683 the pw pipeline. The method generates using ports data the
684 necessary information to fill the pw pipeline and
685 fills properly the pipeline which consists into:
686
687 """
688
689 Groups = Queue.LifoQueue( )
690 out_vlan = 4094
691 port_to_mpls_label_pw = {}
692 port_to_vlan_2 = {}
693 port_to_vlan_1 = {}
694 port_to_switch_mac = {}
695 port_to_switch_mac_str = {}
696 ports = [in_port, out_port]
697
698 for port in ports:
699 mpls_label_pw = port + 300
700 in_vlan_id_1 = port + 1
701 in_vlan_id_2 = port + 100
702 switch_mac = [ 0x00, 0x00, 0x00, 0x00, 0x11, port ]
703 switch_mac_str = ':'.join( [ '%02X' % x for x in switch_mac ] )
704 port_to_mpls_label_pw[port] = mpls_label_pw
705 port_to_vlan_2[port] = in_vlan_id_2
706 port_to_vlan_1[port] = in_vlan_id_1
707 port_to_switch_mac[port] = switch_mac
708 port_to_switch_mac_str[port] = switch_mac_str
709
710 # add l2 interface group;
711 if egress_tags == 2:
712 l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(
713 ctrl=controller,
714 port=out_port,
715 vlan_id=port_to_vlan_2[out_port],
716 is_tagged=True,
717 send_barrier=False
718 )
719 elif egress_tags == 1:
720 l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(
721 ctrl=controller,
722 port=out_port,
723 vlan_id=port_to_vlan_1[out_port],
724 is_tagged=True,
725 send_barrier=False
726 )
727 elif egress_tags == 0:
728 l2_intf_gid, l2_intf_msg = add_one_l2_interface_group(
729 ctrl=controller,
730 port=out_port,
731 vlan_id=port_to_vlan_1[out_port],
732 is_tagged=False,
733 send_barrier=False
734 )
Charles Chanc85f1562018-01-18 15:44:29 -0800735
Pierf6f28162016-09-22 16:30:52 -0700736 Groups._put( l2_intf_gid )
737 add_mpls_flow_pw(
738 ctrl=controller,
739 action_group_id=l2_intf_gid,
740 label=port_to_mpls_label_pw[out_port],
741 ethertype=0x6558,
742 bos=1,
743 tunnel_index=1,
744 popMPLS=True,
745 popL2=True,
746 of_port=in_port
747 )
748 # add Termination flow
749 add_termination_flow(
750 ctrl=controller,
751 in_port=in_port,
752 eth_type=0x8847,
753 dst_mac=port_to_switch_mac[in_port],
754 vlanid=out_vlan,
755 goto_table=MPLS_FLOW_TABLE_0)
756 # add VLAN flows
757 add_one_vlan_table_flow(
758 ctrl=controller,
759 of_port=in_port,
760 vlan_id=out_vlan,
761 flag=VLAN_TABLE_FLAG_ONLY_TAG,
Pierf6f28162016-09-22 16:30:52 -0700762 )
763 add_one_vlan_table_flow(
764 ctrl=controller,
765 of_port=in_port,
766 vlan_id=out_vlan,
767 flag=VLAN_TABLE_FLAG_ONLY_UNTAG
768 )
769
770 return (
771 port_to_mpls_label_pw,
772 port_to_vlan_2,
Pier23784aa2016-09-19 20:08:21 -0700773 port_to_vlan_1,
Pierf6f28162016-09-22 16:30:52 -0700774 port_to_switch_mac_str,
775 Groups
776 )