From 580c7a562c4a01e371b6779cd4ca89e13ab62560 Mon Sep 17 00:00:00 2001 From: ArthiGovindaraj Date: Thu, 24 Nov 2022 04:07:06 -0600 Subject: [PATCH] sonic-utilities : support for addind/deleting rules in openconfig format using acl-loader * Support for adding rules using json file in dataplane acl using "config acl add rule * Support for deleting rule using table_name rule_name using "config acl delete rule " --- acl_loader/main.py | 55 ++++++++++++++++++++++++++++++++++++++++++++++ config/main.py | 32 +++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/acl_loader/main.py b/acl_loader/main.py index c50efec032..ae5df7a356 100644 --- a/acl_loader/main.py +++ b/acl_loader/main.py @@ -766,6 +766,50 @@ def incremental_update(self): for namespace_configdb in self.per_npu_configdb.values(): namespace_configdb.set_entry(self.ACL_RULE, key, self.rules_info[key]) + def add_rule(self): + """ + Perform update/addition of new rules only. Get existing rules from + Config DB. Compare with rules specified in file and perform corresponding + modifications. Do not delete the existing rules. Handles only dataplane rules + :return: + """ + + # TODO: Alternate command for adding rules in dataplane ACLs instead of removing + # all the rules and populating like in full/incremental. + new_rules = set(self.rules_info.keys()) + new_dataplane_rules = set() + current_rules = set(self.rules_db_info.keys()) + current_dataplane_rules = set() + + for key in new_rules: + table_name = key[0] + if self.tables_db_info[table_name]['type'].upper() != self.ACL_TABLE_TYPE_CTRLPLANE: + new_dataplane_rules.add(key) + + for key in current_rules: + table_name = key[0] + if self.tables_db_info[table_name]['type'].upper() != self.ACL_TABLE_TYPE_CTRLPLANE: + current_dataplane_rules.add(key) + + added_dataplane_rules = new_dataplane_rules.difference(current_dataplane_rules) + removed_dataplane_rules = current_dataplane_rules.difference(new_dataplane_rules) + existing_dataplane_rules = new_rules.intersection(current_dataplane_rules) + + for key in added_dataplane_rules: + self.configdb.mod_entry(self.ACL_RULE, key, self.rules_info[key]) + # Program for per-asic namespace corresponding to front asic also if present. + # For control plane ACL it's not needed but to keep all db in sync program everywhere + for namespace_configdb in self.per_npu_configdb.values(): + namespace_configdb.mod_entry(self.ACL_RULE, key, self.rules_info[key]) + + for key in existing_dataplane_rules: + if not operator.eq(self.rules_info[key], self.rules_db_info[key]): + self.configdb.set_entry(self.ACL_RULE, key, self.rules_info[key]) + # Program for per-asic namespace corresponding to front asic also if present. + # For control plane ACL it's not needed but to keep all db in sync program everywhere + for namespace_configdb in self.per_npu_configdb.values(): + namespace_configdb.set_entry(self.ACL_RULE, key, self.rules_info[key]) + def delete(self, table=None, rule=None): """ :param table: @@ -1068,6 +1112,17 @@ def incremental(ctx, filename, session_name, mirror_stage, max_priority): acl_loader.load_rules_from_file(filename) acl_loader.incremental_update() +@cli.command() +@click.argument('filename', type=click.Path(exists=True)) +@click.pass_context +def add(ctx, filename): + """ + Add ACL rules. + """ + acl_loader = ctx.obj["acl_loader"] + + acl_loader.load_rules_from_file(filename) + acl_loader.add_rule() @cli.command() @click.argument('table', required=False) diff --git a/config/main.py b/config/main.py index 004b40bdb4..bc80f3bfd5 100644 --- a/config/main.py +++ b/config/main.py @@ -5579,6 +5579,20 @@ def table(ctx, table_name, table_type, description, ports, stage): config_db.set_entry("ACL_TABLE", table_name, table_info) +# +# 'add' subcommand +# + +@add.command() +@click.argument('file_name', required=True) +def rule(file_name): + """ + Add ACL rule + """ + log.log_info("'config acl add rule {}' executing...".format(file_name)) + command = "acl-loader add {}".format(file_name) + clicommon.run_command(command) + # # 'remove' subgroup ('config acl remove ...') # @@ -5600,10 +5614,28 @@ def table(table_name): """ Remove ACL table """ + log.log_info("'config acl remove table {}' executing...".format(table_name)) + command = "acl-loader delete {}".format(table_name) + clicommon.run_command(command) + config_db = ConfigDBConnector() config_db.connect() config_db.set_entry("ACL_TABLE", table_name, None) +# +# 'delete' subcommand +# + +@remove.command() +@click.argument("table_name", required=True, metavar="") +@click.argument("rule_name", required=True, metavar="") +def rule(table_name, rule_name): + """ + Remove ACL rule + """ + log.log_info("'config acl remove rule {} {}' executing...".format(table_name, rule_name)) + command = "acl-loader delete {} {}".format(table_name, rule_name) + clicommon.run_command(command) # # 'acl update' group