@@ -173,7 +173,31 @@ def read_tables_info(self):
173
173
Read ACL_TABLE table from configuration database
174
174
:return:
175
175
"""
176
- self .tables_db_info = self .configdb .get_table (self .ACL_TABLE )
176
+ # get the acl table info from host config_db
177
+ host_acl_table = self .configdb .get_table (self .ACL_TABLE )
178
+ # For multi asic get only the control plane acls from the host config_db
179
+ if self .per_npu_configdb :
180
+ for table , entry in host_acl_table .items ():
181
+ if entry .get ('type' , None ) != self .ACL_TABLE_TYPE_CTRLPLANE :
182
+ continue
183
+
184
+ self .tables_db_info [table ] = entry
185
+ else :
186
+ self .tables_db_info .update (host_acl_table )
187
+
188
+ # for DATAACL, EVERFLOW acls.
189
+ # update the ports from all the namespaces
190
+ if self .per_npu_configdb :
191
+ for ns , config_db in self .per_npu_configdb .items ():
192
+ acl_table = config_db .get_table (self .ACL_TABLE )
193
+ for table , entry in acl_table .items ():
194
+ if entry .get ('type' , None ) == self .ACL_TABLE_TYPE_CTRLPLANE :
195
+ continue
196
+ if table not in self .tables_db_info :
197
+ self .tables_db_info [table ] = entry
198
+ else :
199
+ self .tables_db_info [table ]['ports' ] += entry .get (
200
+ 'ports' , [])
177
201
178
202
def get_tables_db_info (self ):
179
203
return self .tables_db_info
@@ -389,17 +413,17 @@ def parse_acl_json(filename):
389
413
raise AclLoaderException ("Invalid input file %s" % filename )
390
414
return yang_acl
391
415
392
- def load_rules_from_file (self , filename ):
416
+ def load_rules_from_file (self , filename , skip_action_validation = False ):
393
417
"""
394
418
Load file with ACL rules configuration in openconfig ACL format. Convert rules
395
419
to Config DB schema.
396
420
:param filename: File in openconfig ACL format
397
421
:return:
398
422
"""
399
423
self .yang_acl = AclLoader .parse_acl_json (filename )
400
- self .convert_rules ()
424
+ self .convert_rules (skip_action_validation )
401
425
402
- def convert_action (self , table_name , rule_idx , rule ):
426
+ def convert_action (self , table_name , rule_idx , rule , skip_validation = False ):
403
427
rule_props = {}
404
428
405
429
if rule .actions .config .forwarding_action == "ACCEPT" :
@@ -428,13 +452,13 @@ def convert_action(self, table_name, rule_idx, rule):
428
452
raise AclLoaderException ("Unknown rule action {} in table {}, rule {}" .format (
429
453
rule .actions .config .forwarding_action , table_name , rule_idx ))
430
454
431
- if not self .validate_actions (table_name , rule_props ):
455
+ if not self .validate_actions (table_name , rule_props , skip_validation ):
432
456
raise AclLoaderException ("Rule action {} is not supported in table {}, rule {}" .format (
433
457
rule .actions .config .forwarding_action , table_name , rule_idx ))
434
458
435
459
return rule_props
436
460
437
- def validate_actions (self , table_name , action_props ):
461
+ def validate_actions (self , table_name , action_props , skip_validation = False ):
438
462
if self .is_table_control_plane (table_name ):
439
463
return True
440
464
@@ -457,6 +481,11 @@ def validate_actions(self, table_name, action_props):
457
481
else :
458
482
aclcapability = self .statedb .get_all (self .statedb .STATE_DB , "{}|{}" .format (self .ACL_STAGE_CAPABILITY_TABLE , stage .upper ()))
459
483
switchcapability = self .statedb .get_all (self .statedb .STATE_DB , "{}|switch" .format (self .SWITCH_CAPABILITY_TABLE ))
484
+ # In the load_minigraph path, it's possible that the STATE_DB entry haven't pop up because orchagent is stopped
485
+ # before loading acl.json. So we skip the validation if any table is empty
486
+ if skip_validation and (not aclcapability or not switchcapability ):
487
+ warning ("Skipped action validation as capability table is not present in STATE_DB" )
488
+ return True
460
489
for action_key in dict (action_props ):
461
490
action_list_key = self .ACL_ACTIONS_CAPABILITY_FIELD
462
491
if action_list_key not in aclcapability :
@@ -574,6 +603,14 @@ def convert_icmp(self, table_name, rule_idx, rule):
574
603
is_rule_v6 = True
575
604
except Exception as e :
576
605
pass
606
+ else :
607
+ # get the IP version type using IP_PROTOCOL.
608
+ try :
609
+ ip_protocol = rule .ip .config .protocol
610
+ if ip_protocol == "IP_ICMPV6" or int (ip_protocol ) == self .ip_protocol_map ["IP_ICMPV6" ]:
611
+ is_rule_v6 = True
612
+ except Exception as e :
613
+ pass
577
614
578
615
type_key = "ICMPV6_TYPE" if is_rule_v6 else "ICMP_TYPE"
579
616
code_key = "ICMPV6_CODE" if is_rule_v6 else "ICMP_CODE"
@@ -667,7 +704,7 @@ def validate_rule_fields(self, rule_props):
667
704
if ("ICMPV6_TYPE" in rule_props or "ICMPV6_CODE" in rule_props ) and protocol != 58 :
668
705
raise AclLoaderException ("IP_PROTOCOL={} is not ICMPV6, but ICMPV6 fields were provided" .format (protocol ))
669
706
670
- def convert_rule_to_db_schema (self , table_name , rule ):
707
+ def convert_rule_to_db_schema (self , table_name , rule , skip_action_validation = False ):
671
708
"""
672
709
Convert rules format from openconfig ACL to Config DB schema
673
710
:param table_name: ACL table name to which rule belong
@@ -697,7 +734,7 @@ def convert_rule_to_db_schema(self, table_name, rule):
697
734
elif self .is_table_l3 (table_name ):
698
735
rule_props ["ETHER_TYPE" ] = str (self .ethertype_map ["ETHERTYPE_IPV4" ])
699
736
700
- deep_update (rule_props , self .convert_action (table_name , rule_idx , rule ))
737
+ deep_update (rule_props , self .convert_action (table_name , rule_idx , rule , skip_action_validation ))
701
738
deep_update (rule_props , self .convert_l2 (table_name , rule_idx , rule ))
702
739
deep_update (rule_props , self .convert_ip (table_name , rule_idx , rule ))
703
740
deep_update (rule_props , self .convert_icmp (table_name , rule_idx , rule ))
@@ -729,7 +766,7 @@ def deny_rule(self, table_name):
729
766
return {} # Don't add default deny rule if table is not [L3, L3V6]
730
767
return rule_data
731
768
732
- def convert_rules (self ):
769
+ def convert_rules (self , skip_aciton_validation = False ):
733
770
"""
734
771
Convert rules in openconfig ACL format to Config DB schema
735
772
:return:
@@ -748,7 +785,7 @@ def convert_rules(self):
748
785
for acl_entry_name in acl_set .acl_entries .acl_entry :
749
786
acl_entry = acl_set .acl_entries .acl_entry [acl_entry_name ]
750
787
try :
751
- rule = self .convert_rule_to_db_schema (table_name , acl_entry )
788
+ rule = self .convert_rule_to_db_schema (table_name , acl_entry , skip_aciton_validation )
752
789
deep_update (self .rules_info , rule )
753
790
except AclLoaderException as ex :
754
791
error ("Error processing rule %s: %s. Skipped." % (acl_entry_name , ex ))
@@ -1117,8 +1154,9 @@ def update(ctx):
1117
1154
@click .option ('--session_name' , type = click .STRING , required = False )
1118
1155
@click .option ('--mirror_stage' , type = click .Choice (["ingress" , "egress" ]), default = "ingress" )
1119
1156
@click .option ('--max_priority' , type = click .INT , required = False )
1157
+ @click .option ('--skip_action_validation' , is_flag = True , default = False , help = "Skip action validation" )
1120
1158
@click .pass_context
1121
- def full (ctx , filename , table_name , session_name , mirror_stage , max_priority ):
1159
+ def full (ctx , filename , table_name , session_name , mirror_stage , max_priority , skip_action_validation ):
1122
1160
"""
1123
1161
Full update of ACL rules configuration.
1124
1162
If a table_name is provided, the operation will be restricted in the specified table.
@@ -1136,7 +1174,7 @@ def full(ctx, filename, table_name, session_name, mirror_stage, max_priority):
1136
1174
if max_priority :
1137
1175
acl_loader .set_max_priority (max_priority )
1138
1176
1139
- acl_loader .load_rules_from_file (filename )
1177
+ acl_loader .load_rules_from_file (filename , skip_action_validation )
1140
1178
acl_loader .full_update ()
1141
1179
1142
1180
0 commit comments