From 4ba205fcc9e776c9e32eae53c7f7a248129c6a54 Mon Sep 17 00:00:00 2001 From: shaygol Date: Sun, 5 Jan 2025 21:30:19 +0200 Subject: [PATCH] Policy Base Metering - ACL_Loader Add functionality to bind policer to ACL --- acl_loader/main.py | 53 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/acl_loader/main.py b/acl_loader/main.py index f73f3eb039..7dcdf581ab 100644 --- a/acl_loader/main.py +++ b/acl_loader/main.py @@ -44,6 +44,7 @@ class AclAction: PACKET = "PACKET_ACTION" REDIRECT = "REDIRECT_ACTION" + POLICER = "POLICER_ACTION" MIRROR = "MIRROR_ACTION" MIRROR_INGRESS = "MIRROR_INGRESS_ACTION" MIRROR_EGRESS = "MIRROR_EGRESS_ACTION" @@ -116,6 +117,7 @@ class AclLoader(object): def __init__(self): self.yang_acl = None self.requested_session = None + self.requested_policer = None self.mirror_stage = None self.current_table = None self.tables_db_info = {} @@ -130,6 +132,7 @@ def __init__(self): self.sessions_db_info = {} self.acl_table_status = {} self.acl_rule_status = {} + self.policer_db_info = {} self.configdb = ConfigDBConnector() self.configdb.connect() @@ -229,6 +232,27 @@ def read_policers_info(self): def get_policers_db_info(self): return self.policers_db_info + def set_policer_to_acl_name(self, policer_name): + """ + Set policer object name to be used in ACL rule action + :param policer_name: policer object name + :return: + """ + if policer_name not in self.get_policers_db_info(): + raise AclLoaderException("Policer %s does not exist" % policer_name) + + self.requested_policer = policer_name + + def get_policer_to_acl_name(self): + """ + Get requested policer object name + :return: policer object name + """ + if self.requested_policer: + return self.requested_policer + + return None + def read_sessions_info(self): """ Read MIRROR_SESSION table from configuration database @@ -354,6 +378,14 @@ def is_table_egress(self, tname): """ return self.tables_db_info[tname].get("stage", Stage.INGRESS).upper() == Stage.EGRESS + def is_table_policer(self, tname): + """ + Check if ACL table type is ACL_TABLE_TYPE_POLICER + :param tname: ACL table name + :return: True if table type is POLICER + """ + return self.tables_db_info[tname]['type'].upper() == self.POLICER + def is_table_mirror(self, tname): """ Check if ACL table type is ACL_TABLE_TYPE_MIRROR or ACL_TABLE_TYPE_MIRRORV6 @@ -429,6 +461,13 @@ def convert_action(self, table_name, rule_idx, rule, skip_validation=False): if rule.actions.config.forwarding_action == "ACCEPT": if self.is_table_control_plane(table_name): rule_props[AclAction.PACKET] = PacketAction.ACCEPT + + elif self.is_table_policer(table_name): + policer_name = self.get_policer_to_acl_name() + if not policer_name: + raise AclLoaderException("Policer does not exist") + + rule_props[AclAction.POLICER] = policer_name elif self.is_table_mirror(table_name): session_name = self.get_session_name() if not session_name: @@ -1019,6 +1058,8 @@ def pop_action(val): action = val.pop(key) elif key == AclAction.REDIRECT: action = "REDIRECT: {}".format(val.pop(key)) + elif key == AclAction.POLICER: + action = "POLICER: {}".format(val.pop(key)) elif key in (AclAction.MIRROR, AclAction.MIRROR_INGRESS): action = "MIRROR INGRESS: {}".format(val.pop(key)) elif key == AclAction.MIRROR_EGRESS: @@ -1151,12 +1192,13 @@ def update(ctx): @update.command() @click.argument('filename', type=click.Path(exists=True)) @click.option('--table_name', type=click.STRING, required=False) +@click.option('--policer_name', type=click.STRING, required=False) @click.option('--session_name', type=click.STRING, required=False) @click.option('--mirror_stage', type=click.Choice(["ingress", "egress"]), default="ingress") @click.option('--max_priority', type=click.INT, required=False) @click.option('--skip_action_validation', is_flag=True, default=False, help="Skip action validation") @click.pass_context -def full(ctx, filename, table_name, session_name, mirror_stage, max_priority, skip_action_validation): +def full(ctx, filename, table_name, policer_name, session_name, mirror_stage, max_priority, skip_action_validation): """ Full update of ACL rules configuration. If a table_name is provided, the operation will be restricted in the specified table. @@ -1171,6 +1213,9 @@ def full(ctx, filename, table_name, session_name, mirror_stage, max_priority, sk acl_loader.set_mirror_stage(mirror_stage) + if policer_name: + acl_loader.set_policer_to_acl_name(policer_name) + if max_priority: acl_loader.set_max_priority(max_priority) @@ -1180,16 +1225,20 @@ def full(ctx, filename, table_name, session_name, mirror_stage, max_priority, sk @update.command() @click.argument('filename', type=click.Path(exists=True)) +@click.option('--policer_name', type=click.STRING, required=False) @click.option('--session_name', type=click.STRING, required=False) @click.option('--mirror_stage', type=click.Choice(["ingress", "egress"]), default="ingress") @click.option('--max_priority', type=click.INT, required=False) @click.pass_context -def incremental(ctx, filename, session_name, mirror_stage, max_priority): +def incremental(ctx, filename, policer_name, session_name, mirror_stage, max_priority): """ Incremental update of ACL rule configuration. """ acl_loader = ctx.obj["acl_loader"] + if policer_name: + acl_loader.set_policer_to_acl_name(policer_name) + if session_name: acl_loader.set_session_name(session_name)