@@ -103,6 +103,7 @@ class AclLoader(object):
103
103
"IP_RSVP" : 46 ,
104
104
"IP_GRE" : 47 ,
105
105
"IP_AUTH" : 51 ,
106
+ "IP_ICMPV6" : 58 ,
106
107
"IP_L2TP" : 115
107
108
}
108
109
@@ -290,6 +291,14 @@ def is_table_mirror(self, tname):
290
291
"""
291
292
return self .tables_db_info [tname ]['type' ].upper ().startswith (self .ACL_TABLE_TYPE_MIRROR )
292
293
294
+ def is_table_ipv6 (self , tname ):
295
+ """
296
+ Check if ACL table type is IPv6 (L3V6 or MIRRORV6)
297
+ :param tname: ACL table name
298
+ :return: True if table type is IPv6 else False
299
+ """
300
+ return self .tables_db_info [tname ]["type" ].upper () in ("L3V6" , "MIRRORV6" )
301
+
293
302
def is_table_control_plane (self , tname ):
294
303
"""
295
304
Check if ACL table type is ACL_TABLE_TYPE_CTRLPLANE
@@ -409,9 +418,18 @@ def convert_l2(self, table_name, rule_idx, rule):
409
418
else :
410
419
try :
411
420
rule_props ["ETHER_TYPE" ] = int (rule .l2 .config .ethertype )
412
- except :
413
- raise AclLoaderException ("Failed to convert ethertype %s table %s rule %s" % (
414
- rule .l2 .config .ethertype , table_name , rule_idx ))
421
+ except Exception as e :
422
+ raise AclLoaderException (
423
+ "Failed to convert ethertype %s; table %s rule %s; exception=%s" %
424
+ (rule .l2 .config .ethertype , table_name , rule_idx , str (e )))
425
+
426
+ if rule .l2 .config .vlan_id != "" and rule .l2 .config .vlan_id != "null" :
427
+ vlan_id = rule .l2 .config .vlan_id
428
+
429
+ if vlan_id <= 0 or vlan_id >= 4096 :
430
+ raise AclLoaderException ("VLAN ID %d is out of bounds (0, 4096)" % (vlan_id ))
431
+
432
+ rule_props ["VLAN_ID" ] = vlan_id
415
433
416
434
return rule_props
417
435
@@ -422,7 +440,12 @@ def convert_ip(self, table_name, rule_idx, rule):
422
440
# so there isn't currently a good way to check if the user defined proto=0 or not.
423
441
if rule .ip .config .protocol :
424
442
if rule .ip .config .protocol in self .ip_protocol_map :
425
- rule_props ["IP_PROTOCOL" ] = self .ip_protocol_map [rule .ip .config .protocol ]
443
+ # Special case: ICMP has different protocol numbers for IPv4 and IPv6, so if we receive
444
+ # "IP_ICMP" we need to pick the correct protocol number for the IP version
445
+ if rule .ip .config .protocol == "IP_ICMP" and self .is_table_ipv6 (table_name ):
446
+ rule_props ["IP_PROTOCOL" ] = self .ip_protocol_map ["IP_ICMPV6" ]
447
+ else :
448
+ rule_props ["IP_PROTOCOL" ] = self .ip_protocol_map [rule .ip .config .protocol ]
426
449
else :
427
450
try :
428
451
int (rule .ip .config .protocol )
@@ -453,6 +476,31 @@ def convert_ip(self, table_name, rule_idx, rule):
453
476
454
477
return rule_props
455
478
479
+ def convert_icmp (self , table_name , rule_idx , rule ):
480
+ rule_props = {}
481
+
482
+ is_table_v6 = self .is_table_ipv6 (table_name )
483
+ type_key = "ICMPV6_TYPE" if is_table_v6 else "ICMP_TYPE"
484
+ code_key = "ICMPV6_CODE" if is_table_v6 else "ICMP_CODE"
485
+
486
+ if rule .icmp .config .type != "" and rule .icmp .config .type != "null" :
487
+ icmp_type = rule .icmp .config .type
488
+
489
+ if icmp_type < 0 or icmp_type > 255 :
490
+ raise AclLoaderException ("ICMP type %d is out of bounds [0, 255]" % (icmp_type ))
491
+
492
+ rule_props [type_key ] = icmp_type
493
+
494
+ if rule .icmp .config .code != "" and rule .icmp .config .code != "null" :
495
+ icmp_code = rule .icmp .config .code
496
+
497
+ if icmp_code < 0 or icmp_code > 255 :
498
+ raise AclLoaderException ("ICMP code %d is out of bounds [0, 255]" % (icmp_code ))
499
+
500
+ rule_props [code_key ] = icmp_code
501
+
502
+ return rule_props
503
+
456
504
def convert_port (self , port ):
457
505
"""
458
506
Convert port field format from openconfig ACL to Config DB schema
@@ -527,6 +575,7 @@ def convert_rule_to_db_schema(self, table_name, rule):
527
575
deep_update (rule_props , self .convert_action (table_name , rule_idx , rule ))
528
576
deep_update (rule_props , self .convert_l2 (table_name , rule_idx , rule ))
529
577
deep_update (rule_props , self .convert_ip (table_name , rule_idx , rule ))
578
+ deep_update (rule_props , self .convert_icmp (table_name , rule_idx , rule ))
530
579
deep_update (rule_props , self .convert_transport (table_name , rule_idx , rule ))
531
580
deep_update (rule_props , self .convert_input_interface (table_name , rule_idx , rule ))
532
581
0 commit comments