From 2f095f5145ede78e93de9b09c4737621dc43ab14 Mon Sep 17 00:00:00 2001 From: keboliu Date: Mon, 24 Dec 2018 07:50:15 +0200 Subject: [PATCH 1/2] fix bug for egress acl support and add vs test cases --- orchagent/aclorch.cpp | 36 ++-- orchagent/aclorch.h | 5 +- tests/test_acl_egress_table.py | 339 +++++++++++++++++++++++++++++++++ tests/test_mirror.py | 97 +++++++++- 4 files changed, 454 insertions(+), 23 deletions(-) create mode 100644 tests/test_acl_egress_table.py diff --git a/orchagent/aclorch.cpp b/orchagent/aclorch.cpp index dd138d16f81..fa2c169bba4 100644 --- a/orchagent/aclorch.cpp +++ b/orchagent/aclorch.cpp @@ -550,7 +550,7 @@ AclRuleCounters AclRule::getCounters() return AclRuleCounters(counter_attr[0].value.u64, counter_attr[1].value.u64); } -shared_ptr AclRule::makeShared(acl_table_type_t type, AclOrch *acl, MirrorOrch *mirror, DTelOrch *dtel, const string& rule, const string& table, const KeyOpFieldsValuesTuple& data) +shared_ptr AclRule::makeShared(acl_table_type_t type, acl_stage_type_t stage, AclOrch *acl, MirrorOrch *mirror, DTelOrch *dtel, const string& rule, const string& table, const KeyOpFieldsValuesTuple& data) { string action; bool action_found = false; @@ -585,7 +585,7 @@ shared_ptr AclRule::makeShared(acl_table_type_t type, AclOrch *acl, Mir /* Mirror rules can exist in both tables*/ if (action == ACTION_MIRROR_ACTION) { - return make_shared(acl, mirror, rule, table, type); + return make_shared(acl, stage, mirror, rule, table, type); } /* L3 rules can exist only in L3 table */ else if (type == ACL_TABLE_L3) @@ -901,9 +901,10 @@ bool AclRuleL3V6::validateAddMatch(string attr_name, string attr_value) } -AclRuleMirror::AclRuleMirror(AclOrch *aclOrch, MirrorOrch *mirror, string rule, string table, acl_table_type_t type) : +AclRuleMirror::AclRuleMirror(AclOrch *aclOrch, acl_stage_type_t stage, MirrorOrch *mirror, string rule, string table, acl_table_type_t type) : AclRule(aclOrch, rule, table, type), m_state(false), + m_tableStage(stage), m_pMirrorOrch(mirror) { } @@ -986,7 +987,19 @@ bool AclRuleMirror::create() value.aclaction.parameter.objlist.count = 1; m_actions.clear(); - m_actions[SAI_ACL_ENTRY_ATTR_ACTION_MIRROR_INGRESS] = value; + if (m_tableStage == ACL_STAGE_INGRESS) + { + m_actions[SAI_ACL_ENTRY_ATTR_ACTION_MIRROR_INGRESS] = value; + } + else if (m_tableStage == ACL_STAGE_EGRESS) + { + m_actions[SAI_ACL_ENTRY_ATTR_ACTION_MIRROR_EGRESS] = value; + } + else + { + SWSS_LOG_ERROR("Unknown ACL table stage: %d", m_tableStage); + return false; + } if (!AclRule::create()) { @@ -1151,14 +1164,11 @@ bool AclTable::create() attr.value.booldata = true; table_attrs.push_back(attr); - if (stage == ACL_STAGE_INGRESS) - { - int32_t range_types_list[] = { SAI_ACL_RANGE_TYPE_L4_DST_PORT_RANGE, SAI_ACL_RANGE_TYPE_L4_SRC_PORT_RANGE }; - attr.id = SAI_ACL_TABLE_ATTR_FIELD_ACL_RANGE_TYPE; - attr.value.s32list.count = (uint32_t)(sizeof(range_types_list) / sizeof(range_types_list[0])); - attr.value.s32list.list = range_types_list; - table_attrs.push_back(attr); - } + int32_t range_types_list[] = { SAI_ACL_RANGE_TYPE_L4_DST_PORT_RANGE, SAI_ACL_RANGE_TYPE_L4_SRC_PORT_RANGE }; + attr.id = SAI_ACL_TABLE_ATTR_FIELD_ACL_RANGE_TYPE; + attr.value.s32list.count = (uint32_t)(sizeof(range_types_list) / sizeof(range_types_list[0])); + attr.value.s32list.list = range_types_list; + table_attrs.push_back(attr); attr.id = SAI_ACL_TABLE_ATTR_ACL_STAGE; attr.value.s32 = stage == ACL_STAGE_INGRESS ? SAI_ACL_STAGE_INGRESS : SAI_ACL_STAGE_EGRESS; @@ -2141,7 +2151,7 @@ void AclOrch::doAclRuleTask(Consumer &consumer) continue; } - newRule = AclRule::makeShared(m_AclTables[table_oid].type, this, m_mirrorOrch, m_dTelOrch, rule_id, table_id, t); + newRule = AclRule::makeShared(m_AclTables[table_oid].type, m_AclTables[table_oid].stage, this, m_mirrorOrch, m_dTelOrch, rule_id, table_id, t); for (const auto& itr : kfvFieldsValues(t)) { diff --git a/orchagent/aclorch.h b/orchagent/aclorch.h index 5d609dac4e6..66411fecc41 100644 --- a/orchagent/aclorch.h +++ b/orchagent/aclorch.h @@ -191,7 +191,7 @@ class AclRule return m_counterOid; } - static shared_ptr makeShared(acl_table_type_t type, AclOrch *acl, MirrorOrch *mirror, DTelOrch *dtel, const string& rule, const string& table, const KeyOpFieldsValuesTuple&); + static shared_ptr makeShared(acl_table_type_t type, acl_stage_type_t stage, AclOrch *acl, MirrorOrch *mirror, DTelOrch *dtel, const string& rule, const string& table, const KeyOpFieldsValuesTuple&); virtual ~AclRule() {} protected: @@ -251,7 +251,7 @@ class AclRulePfcwd: public AclRuleL3 class AclRuleMirror: public AclRule { public: - AclRuleMirror(AclOrch *m_pAclOrch, MirrorOrch *m_pMirrorOrch, string rule, string table, acl_table_type_t type); + AclRuleMirror(AclOrch *m_pAclOrch, acl_stage_type_t stage, MirrorOrch *m_pMirrorOrch, string rule, string table, acl_table_type_t type); bool validateAddAction(string attr_name, string attr_value); bool validateAddMatch(string attr_name, string attr_value); bool validate(); @@ -263,6 +263,7 @@ class AclRuleMirror: public AclRule protected: bool m_state; string m_sessionName; + acl_stage_type_t m_tableStage; AclRuleCounters counters; MirrorOrch *m_pMirrorOrch; }; diff --git a/tests/test_acl_egress_table.py b/tests/test_acl_egress_table.py new file mode 100644 index 00000000000..f0a0870e1d4 --- /dev/null +++ b/tests/test_acl_egress_table.py @@ -0,0 +1,339 @@ +from swsscommon import swsscommon + +import time + +class TestEgressAclTable(object): + def setup_db(self, dvs): + self.pdb = swsscommon.DBConnector(0, dvs.redis_sock, 0) + self.adb = swsscommon.DBConnector(1, dvs.redis_sock, 0) + self.cdb = swsscommon.DBConnector(4, dvs.redis_sock, 0) + + def create_egress_acl_table(self, table_name, ports): + tbl = swsscommon.Table(self.cdb, "ACL_TABLE") + + fvs = swsscommon.FieldValuePairs([("POLICY_DESC", "EGRESS_ACL_TEST"), + ("TYPE", "L3"), + ("PORTS", ports), + ("stage", "EGRESS")]) + tbl.set(table_name, fvs) + time.sleep(1) + + def create_acl_rule(self, fv_pairs, rule_name): + rule_tbl = swsscommon.Table(self.cdb, "ACL_RULE") + fvs = swsscommon.FieldValuePairs(fv_pairs) + rule_tbl.set("egress_acl_table|" + rule_name, fvs) + time.sleep(1) + + def remove_acl_table(self, table_name): + tbl = swsscommon.Table(self.cdb, "ACL_TABLE") + tbl._del(table_name) + time.sleep(1) + + def get_acl_table_id(self, dvs): + atbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE") + keys = atbl.getKeys() + for k in dvs.asicdb.default_acl_tables: + assert k in keys + acl_tables = [k for k in keys if k not in dvs.asicdb.default_acl_tables] + + assert len(acl_tables) == 1 + + return acl_tables[0] + + def remove_acl_rule(self, table_name, rule_name): + tbl = swsscommon.Table(self.cdb, "ACL_RULE") + tbl._del(table_name + "|" + rule_name) + time.sleep(1) + + def verify_acl_asic_table(self, dvs, bind_ports): + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE_GROUP") + acl_table_groups = tbl.getKeys() + assert len(acl_table_groups) == len(bind_ports) + + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_PORT") + port_groups = [] + for p in [dvs.asicdb.portnamemap[portname] for portname in bind_ports]: + (status, fvs) = tbl.get(p) + for fv in fvs: + if fv[0] == "SAI_PORT_ATTR_EGRESS_ACL": + assert fv[1] in acl_table_groups + port_groups.append(fv[1]) + + assert len(port_groups) == len(bind_ports) + assert set(port_groups) == set(acl_table_groups) + + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE_GROUP") + (status, fvs) = tbl.get(port_groups[0]) + assert status == True + assert len(fvs) == 3 + for fv in fvs: + if fv[0] == "SAI_ACL_TABLE_GROUP_ATTR_ACL_STAGE": + assert fv[1] == "SAI_ACL_STAGE_EGRESS" + elif fv[0] == "SAI_ACL_TABLE_GROUP_ATTR_ACL_BIND_POINT_TYPE_LIST": + assert fv[1] == "1:SAI_ACL_BIND_POINT_TYPE_PORT" + elif fv[0] == "SAI_ACL_TABLE_GROUP_ATTR_TYPE": + assert fv[1] == "SAI_ACL_TABLE_GROUP_TYPE_PARALLEL" + else: + assert False + + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE_GROUP_MEMBER") + member = tbl.getKeys()[0] + (status, fvs) = tbl.get(member) + assert status == True + assert len(fvs) == 3 + for fv in fvs: + if fv[0] == "SAI_ACL_TABLE_GROUP_MEMBER_ATTR_ACL_TABLE_GROUP_ID": + assert port_groups[0] == fv[1] + elif fv[0] == "SAI_ACL_TABLE_GROUP_MEMBER_ATTR_ACL_TABLE_ID": + table_id = fv[1] + elif fv[0] == "SAI_ACL_TABLE_GROUP_MEMBER_ATTR_PRIORITY": + assert fv[1] == "100" + else: + assert False + + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE") + (status, fvs) = tbl.get(table_id) + assert status == True + + def verify_acl_rule_asic_fvs(self, dvs, fv_tuple): + # Verify Acl entry in ASIC DB + test_acl_table_id = self.get_acl_table_id(dvs) + acl_tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_ENTRY") + keys = acl_tbl.getKeys() + + acl_entry = [k for k in keys if k not in dvs.asicdb.default_acl_entries] + assert len(acl_entry) == 1 + + (status, fvs) = acl_tbl.get(acl_entry[0]) + assert status == True + assert len(fvs) == 6 + for fv in fvs: + if fv[0] == "SAI_ACL_ENTRY_ATTR_TABLE_ID": + assert fv[1] == test_acl_table_id + elif fv[0] == "SAI_ACL_ENTRY_ATTR_ADMIN_STATE": + assert fv[1] == "true" + elif fv[0] == "SAI_ACL_ENTRY_ATTR_PRIORITY": + assert fv[1] == "1000" + elif fv[0] == "SAI_ACL_ENTRY_ATTR_ACTION_COUNTER": + assert True + elif fv[0] == fv_tuple[0]: + assert fv[1] == fv_tuple[1] + elif fv[0] == "SAI_ACL_ENTRY_ATTR_ACTION_PACKET_ACTION": + assert fv[1] == "SAI_PACKET_ACTION_DROP" + else: + assert False + + def verify_acl_rule_with_L4PortRange_asic_fvs(self, dvs, fv_tuple): + # Verify Acl entry in ASIC DB + test_acl_table_id = self.get_acl_table_id(dvs) + acl_tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_ENTRY") + keys = acl_tbl.getKeys() + + acl_entry = [k for k in keys if k not in dvs.asicdb.default_acl_entries] + assert len(acl_entry) == 1 + + (status, fvs) = acl_tbl.get(acl_entry[0]) + assert status == True + assert len(fvs) == 6 + for fv in fvs: + if fv[0] == "SAI_ACL_ENTRY_ATTR_TABLE_ID": + assert fv[1] == test_acl_table_id + elif fv[0] == "SAI_ACL_ENTRY_ATTR_ADMIN_STATE": + assert fv[1] == "true" + elif fv[0] == "SAI_ACL_ENTRY_ATTR_PRIORITY": + assert fv[1] == "999" + elif fv[0] == "SAI_ACL_ENTRY_ATTR_ACTION_COUNTER": + assert True + elif fv[0] == "SAI_ACL_ENTRY_ATTR_FIELD_ACL_RANGE_TYPE": + aclrange = fv[1] + elif fv[0] == "SAI_ACL_ENTRY_ATTR_ACTION_PACKET_ACTION": + assert fv[1] == "SAI_PACKET_ACTION_FORWARD" + else: + assert False + + # Verify Acl range in ASIC DB + acl_tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_RANGE") + aclrange_obj = aclrange.split(":", 1)[1] + + (status, fvs) = acl_tbl.get(aclrange_obj) + assert status == True + assert len(fvs) == 2 + for fv in fvs: + if fv[0] == "SAI_ACL_RANGE_ATTR_TYPE": + assert fv[1] == fv_tuple[0] + elif fv[0] == "SAI_ACL_RANGE_ATTR_LIMIT": + assert fv[1] == fv_tuple[1] + else: + assert False + + def check_asic_table_absent(self, dvs): + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE") + acl_tables = tbl.getKeys() + for key in dvs.asicdb.default_acl_tables: + assert key in acl_tables + acl_tables = [k for k in acl_tables if k not in dvs.asicdb.default_acl_tables] + + assert len(acl_tables) == 0 + + def check_asic_rule_absent(self, dvs): + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_ENTRY") + acl_entries = tbl.getKeys() + for key in dvs.asicdb.default_acl_entries: + assert key in acl_entries + acl_entries = [k for k in acl_entries if k not in dvs.asicdb.default_acl_entries] + + assert len(acl_entries) == 0 + + def test_EgressAclTableCreation(self, dvs): + self.setup_db(dvs) + + # Create ACL_TABLE in config db + bind_ports = ["Ethernet0", "Ethernet4"] + self.create_egress_acl_table("egress_acl_table", ",".join(bind_ports)) + + time.sleep(1) + + # Check acl table in asic db + self.verify_acl_asic_table(dvs, bind_ports) + + def test_EgressAclRuleL4SrcPortRange(self, dvs): + self.setup_db(dvs) + + # Create L4 SrcPortRange Acl rule + fvPairs = [("priority", "999"), ("PACKET_ACTION", "FORWARD"), ("L4_SRC_PORT_RANGE", "0-1001")] + self.create_acl_rule(fvPairs, "L4SrcPortRange_rule") + + # Verify Acl rule in ASIC DB + fv_tuple = ("SAI_ACL_RANGE_TYPE_L4_SRC_PORT_RANGE", "0,1001") + self.verify_acl_rule_with_L4PortRange_asic_fvs(dvs, fv_tuple) + + # Remove Acl rule + self.remove_acl_rule("egress_acl_table", "L4SrcPortRange_rule") + self.check_asic_rule_absent(dvs) + + def test_EgressAclRuleL4DstPortRange(self, dvs): + self.setup_db(dvs) + + # Create L4 DstPortRange Acl rule + fvPairs = [("priority", "999"), ("PACKET_ACTION", "FORWARD"), ("L4_DST_PORT_RANGE", "1003-6666")] + self.create_acl_rule(fvPairs, "L4DstPortRange_rule") + + # Verify Acl rule in ASIC DB + fv_tuple = ("SAI_ACL_RANGE_TYPE_L4_DST_PORT_RANGE", "1003,6666") + self.verify_acl_rule_with_L4PortRange_asic_fvs(dvs, fv_tuple) + + # Remove Acl rule + self.remove_acl_rule("egress_acl_table", "L4DstPortRange_rule") + self.check_asic_rule_absent(dvs) + + def test_EgressAclRuleL2EthType(self, dvs): + self.setup_db(dvs) + + # Create L4 L2EthType Acl rule + fvPairs = [("priority", "1000"), ("PACKET_ACTION", "DROP"), ("ETHER_TYPE", "8000")] + self.create_acl_rule(fvPairs, "L2EthType_rule") + + # Verify Acl rule in ASIC DB + fv_tuple = ("SAI_ACL_ENTRY_ATTR_FIELD_ETHER_TYPE", "8000&mask:0xffff") + self.verify_acl_rule_asic_fvs( dvs, fv_tuple) + + # Remove Acl rule + self.remove_acl_rule("egress_acl_table", "L2EthType_rule") + self.check_asic_rule_absent(dvs) + + def test_EgressAclRuleTunnelVNI(self, dvs): + self.setup_db(dvs) + + # Create Tunnel VNI Acl rule + fvPairs = [("priority", "1000"), ("PACKET_ACTION", "DROP"), ("TUNNEL_VNI", "5000")] + self.create_acl_rule(fvPairs, "TunnelVNI_rule") + + # Verify Acl rule in ASIC DB + fv_tuple = ("SAI_ACL_ENTRY_ATTR_FIELD_TUNNEL_VNI", "5000&mask:0xffffffff") + self.verify_acl_rule_asic_fvs(dvs, fv_tuple) + + # Remove Acl rule + self.remove_acl_rule("egress_acl_table", "TunnelVNI_rule") + self.check_asic_rule_absent(dvs) + + def test_EgressAclRuleTC(self, dvs): + self.setup_db(dvs) + + # Create TC Acl rule + fvPairs = [("priority", "1000"), ("PACKET_ACTION", "DROP"), ("TC", "1")] + self.create_acl_rule(fvPairs, "TC_rule") + + # Verify Acl rule in ASIC DB + fv_tuple = ("SAI_ACL_ENTRY_ATTR_FIELD_TC", "1&mask:0xff") + self.verify_acl_rule_asic_fvs(dvs, fv_tuple) + + # Remove Acl rule + self.remove_acl_rule("egress_acl_table", "TC_rule") + self.check_asic_rule_absent(dvs) + + def test_EgressAclInnerIPProtocol(self, dvs): + self.setup_db(dvs) + + # Create InnerIPProtocol Acl rule + fvPairs = [("priority", "1000"), ("PACKET_ACTION", "DROP"), ("INNER_IP_PROTOCOL", "8")] + self.create_acl_rule(fvPairs, "InnerIPProtocol_rule") + + # Verify Acl rule in ASIC DB + fv_tuple = ("SAI_ACL_ENTRY_ATTR_FIELD_INNER_IP_PROTOCOL", "8&mask:0xff") + self.verify_acl_rule_asic_fvs(dvs, fv_tuple) + + # Remove Acl rule + self.remove_acl_rule("egress_acl_table", "InnerIPProtocol_rule") + self.check_asic_rule_absent(dvs) + + def test_EgressAclInnerEthType(self, dvs): + self.setup_db(dvs) + + # Create InnerEthernetType Acl rule + fvPairs = [("priority", "1000"), ("PACKET_ACTION", "DROP"), ("INNER_ETHER_TYPE", "8000")] + self.create_acl_rule(fvPairs, "InnerEthType_rule") + + # Verify Acl rule in ASIC DB + fv_tuple = ("SAI_ACL_ENTRY_ATTR_FIELD_INNER_ETHER_TYPE", "8000&mask:0xffff") + self.verify_acl_rule_asic_fvs(dvs, fv_tuple) + + # Remove Acl rule + self.remove_acl_rule("egress_acl_table", "InnerEthType_rule") + self.check_asic_rule_absent(dvs) + + def test_EgressAclInnerL4SrcPort(self, dvs): + self.setup_db(dvs) + + # Create InnerL4SrcPort Acl rule + fvPairs = [("priority", "1000"), ("PACKET_ACTION", "DROP"), ("INNER_L4_SRC_PORT", "999")] + self.create_acl_rule(fvPairs, "InnerL4SrcPort_rule") + + # Verify Acl rule in ASIC DB + fv_tuple = ("SAI_ACL_ENTRY_ATTR_FIELD_INNER_L4_SRC_PORT", "999&mask:0xffff") + self.verify_acl_rule_asic_fvs(dvs, fv_tuple) + + # Remove Acl rule + self.remove_acl_rule("egress_acl_table", "InnerL4SrcPort_rule") + self.check_asic_rule_absent(dvs) + + def test_EgressAclInnerL4DstPort(self, dvs): + self.setup_db(dvs) + + # Create InnerL4DstPort Acl rule + fvPairs = [("priority", "1000"), ("PACKET_ACTION", "DROP"), ("INNER_L4_DST_PORT", "999")] + self.create_acl_rule(fvPairs, "InnerL4DstPort_rule") + + # Verify Acl rule in ASIC DB + fv_tuple = ("SAI_ACL_ENTRY_ATTR_FIELD_INNER_L4_DST_PORT", "999&mask:0xffff") + self.verify_acl_rule_asic_fvs(dvs, fv_tuple) + + # Remove Acl rule + self.remove_acl_rule("egress_acl_table", "InnerL4DstPort_rule") + self.check_asic_rule_absent(dvs) + + def test_EgressAclTableDeletion(self, dvs): + self.setup_db(dvs) + + # Remove Acl table + self.remove_acl_table("egress_acl_table") + self.check_asic_table_absent(dvs) diff --git a/tests/test_mirror.py b/tests/test_mirror.py index d1a29840406..b8f440ec801 100644 --- a/tests/test_mirror.py +++ b/tests/test_mirror.py @@ -23,7 +23,7 @@ def set_interface_status(self, interface, admin_status): else: tbl_name = "PORT" tbl = swsscommon.Table(self.cdb, tbl_name) - fvs = swsscommon.FieldValuePairs([("admin_status", "up")]) + fvs = swsscommon.FieldValuePairs([("admin_status", admin_status)]) tbl.set(interface, fvs) time.sleep(1) @@ -680,11 +680,12 @@ def test_MirrorDestMoveLag(self, dvs, testlog): self.remove_mirror_session(session) - def create_acl_table(self, table, interfaces): + def create_acl_table(self, table, interfaces, stage = "INGRESS"): tbl = swsscommon.Table(self.cdb, "ACL_TABLE") fvs = swsscommon.FieldValuePairs([("policy_desc", "mirror_test"), - ("type", "mirror"), - ("ports", ",".join(interfaces))]) + ("type", "mirror"), + ("ports", ",".join(interfaces)), + ("stage", stage)]) tbl.set(table, fvs) time.sleep(1) @@ -696,12 +697,20 @@ def remove_acl_table(self, table): def create_mirror_acl_dscp_rule(self, table, rule, dscp, session): tbl = swsscommon.Table(self.cdb, "ACL_RULE") fvs = swsscommon.FieldValuePairs([("priority", "1000"), - ("mirror_action", session), + ("MIRROR_ACTION", session), ("DSCP", dscp)]) tbl.set(table + "|" + rule, fvs) time.sleep(1) - def remove_mirror_acl_dscp_rule(self, table, rule): + def create_mirror_acl_tcp_flag_rule(self, table, rule, tcp_flag, session): + tbl = swsscommon.Table(self.cdb, "ACL_RULE") + fvs = swsscommon.FieldValuePairs([("priority", "1000"), + ("MIRROR_ACTION", session), + ("TCP_FLAGS", tcp_flag)]) + tbl.set(table + "|" + rule, fvs) + time.sleep(1) + + def remove_mirror_acl_rule(self, table, rule): tbl = swsscommon.Table(self.cdb, "ACL_RULE") tbl._del(table + "|" + rule) time.sleep(1) @@ -753,7 +762,7 @@ def test_AclBindMirror(self, dvs, testlog): assert fv[1] == "1:" + mirror_session_oid # remove acl rule - self.remove_mirror_acl_dscp_rule(acl_table, acl_rule) + self.remove_mirror_acl_rule(acl_table, acl_rule) # create acl rule with dscp value 16/16 self.create_mirror_acl_dscp_rule(acl_table, acl_rule, "16/16", session) @@ -772,7 +781,7 @@ def test_AclBindMirror(self, dvs, testlog): assert fv[1] == "1:" + mirror_session_oid # remove acl rule - self.remove_mirror_acl_dscp_rule(acl_table, acl_rule) + self.remove_mirror_acl_rule(acl_table, acl_rule) # remove acl table self.remove_acl_table(acl_table) @@ -789,3 +798,75 @@ def test_AclBindMirror(self, dvs, testlog): self.remove_neighbor("Ethernet32", "20.0.0.1") self.remove_ip_address("Ethernet32", "20.0.0.0/31") self.set_interface_status("Ethernet32", "down") + + def test_EgressAclBindMirror(self, dvs, testlog): + """ + This test tests Egress ACL associated with mirror session with TCP flag value/mask + """ + self.setup_db(dvs) + + session = "MIRROR_SESSION" + acl_table = "EGRESS_MIRROR_TABLE" + acl_rule = "MIRROR_RULE" + + # create port channel; create port channel member; bring up + self.create_port_channel(dvs, "080") + self.create_port_channel_member("080", "Ethernet32") + self.set_interface_status("PortChannel080", "up") + self.set_interface_status("Ethernet32", "up") + + # add ip address to port channel 080; create neighbor to port channel 080 + self.add_ip_address("PortChannel080", "200.0.0.0/31") + self.add_neighbor("PortChannel080", "200.0.0.1", "12:10:08:06:04:02") + + # add route + self.add_route(dvs, "2.2.2.2", "200.0.0.1") + + # create mirror session + self.create_mirror_session(session, "1.1.1.1", "2.2.2.2", "0x6558", "8", "100", "0") + assert self.get_mirror_session_state(session)["status"] == "active" + + # assert mirror session in asic database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_MIRROR_SESSION") + assert len(tbl.getKeys()) == 1 + mirror_session_oid = tbl.getKeys()[0] + + # create acl table + self.create_acl_table(acl_table, ["Ethernet0", "Ethernet4"], "EGRESS") + + # create acl rule with TCP flag value/mask 48 + self.create_mirror_acl_tcp_flag_rule(acl_table, acl_rule, "0x07/0x3f", session) + + # assert acl rule is created + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_ENTRY") + rule_entries = [k for k in tbl.getKeys() if k not in dvs.asicdb.default_acl_entries] + assert len(rule_entries) == 1 + + (status, fvs) = tbl.get(rule_entries[0]) + assert status == True + for fv in fvs: + if fv[0] == "SAI_ACL_ENTRY_ATTR_FIELD_TCP_FLAGS": + assert fv[1] == "7&mask:0x3f" + if fv[0] == "SAI_ACL_ENTRY_ATTR_ACTION_MIRROR_EGRESS": + assert fv[1] == "1:" + mirror_session_oid + + # remove acl rule + self.remove_mirror_acl_rule(acl_table, acl_rule) + + # remove acl table + self.remove_acl_table(acl_table) + + # remove mirror session + self.remove_mirror_session(session) + + # assert no mirror session in asic database + tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_MIRROR_SESSION") + assert len(tbl.getKeys()) == 0 + + # remove route; remove neighbor; remove ip; bring down port + self.remove_route(dvs, "2.2.2.2") + self.remove_neighbor("PortChannel080", "200.0.0.1") + self.remove_ip_address("PortChannel080", "200.0.0.0/31") + self.set_interface_status("PortChannel080", "down") + self.set_interface_status("Ethernet32", "down") + From ff55ef179ac00b803395c1a68b133071eae3a20f Mon Sep 17 00:00:00 2001 From: keboliu Date: Fri, 25 Jan 2019 05:29:15 +0200 Subject: [PATCH 2/2] remove change for egress mirror --- orchagent/aclorch.cpp | 23 +++------- orchagent/aclorch.h | 5 +-- tests/test_mirror.py | 97 ++++--------------------------------------- 3 files changed, 15 insertions(+), 110 deletions(-) diff --git a/orchagent/aclorch.cpp b/orchagent/aclorch.cpp index fa2c169bba4..888cf45a9bc 100644 --- a/orchagent/aclorch.cpp +++ b/orchagent/aclorch.cpp @@ -550,7 +550,7 @@ AclRuleCounters AclRule::getCounters() return AclRuleCounters(counter_attr[0].value.u64, counter_attr[1].value.u64); } -shared_ptr AclRule::makeShared(acl_table_type_t type, acl_stage_type_t stage, AclOrch *acl, MirrorOrch *mirror, DTelOrch *dtel, const string& rule, const string& table, const KeyOpFieldsValuesTuple& data) +shared_ptr AclRule::makeShared(acl_table_type_t type, AclOrch *acl, MirrorOrch *mirror, DTelOrch *dtel, const string& rule, const string& table, const KeyOpFieldsValuesTuple& data) { string action; bool action_found = false; @@ -585,7 +585,7 @@ shared_ptr AclRule::makeShared(acl_table_type_t type, acl_stage_type_t /* Mirror rules can exist in both tables*/ if (action == ACTION_MIRROR_ACTION) { - return make_shared(acl, stage, mirror, rule, table, type); + return make_shared(acl, mirror, rule, table, type); } /* L3 rules can exist only in L3 table */ else if (type == ACL_TABLE_L3) @@ -901,10 +901,9 @@ bool AclRuleL3V6::validateAddMatch(string attr_name, string attr_value) } -AclRuleMirror::AclRuleMirror(AclOrch *aclOrch, acl_stage_type_t stage, MirrorOrch *mirror, string rule, string table, acl_table_type_t type) : +AclRuleMirror::AclRuleMirror(AclOrch *aclOrch, MirrorOrch *mirror, string rule, string table, acl_table_type_t type) : AclRule(aclOrch, rule, table, type), m_state(false), - m_tableStage(stage), m_pMirrorOrch(mirror) { } @@ -987,19 +986,7 @@ bool AclRuleMirror::create() value.aclaction.parameter.objlist.count = 1; m_actions.clear(); - if (m_tableStage == ACL_STAGE_INGRESS) - { - m_actions[SAI_ACL_ENTRY_ATTR_ACTION_MIRROR_INGRESS] = value; - } - else if (m_tableStage == ACL_STAGE_EGRESS) - { - m_actions[SAI_ACL_ENTRY_ATTR_ACTION_MIRROR_EGRESS] = value; - } - else - { - SWSS_LOG_ERROR("Unknown ACL table stage: %d", m_tableStage); - return false; - } + m_actions[SAI_ACL_ENTRY_ATTR_ACTION_MIRROR_INGRESS] = value; if (!AclRule::create()) { @@ -2151,7 +2138,7 @@ void AclOrch::doAclRuleTask(Consumer &consumer) continue; } - newRule = AclRule::makeShared(m_AclTables[table_oid].type, m_AclTables[table_oid].stage, this, m_mirrorOrch, m_dTelOrch, rule_id, table_id, t); + newRule = AclRule::makeShared(m_AclTables[table_oid].type, this, m_mirrorOrch, m_dTelOrch, rule_id, table_id, t); for (const auto& itr : kfvFieldsValues(t)) { diff --git a/orchagent/aclorch.h b/orchagent/aclorch.h index 66411fecc41..5d609dac4e6 100644 --- a/orchagent/aclorch.h +++ b/orchagent/aclorch.h @@ -191,7 +191,7 @@ class AclRule return m_counterOid; } - static shared_ptr makeShared(acl_table_type_t type, acl_stage_type_t stage, AclOrch *acl, MirrorOrch *mirror, DTelOrch *dtel, const string& rule, const string& table, const KeyOpFieldsValuesTuple&); + static shared_ptr makeShared(acl_table_type_t type, AclOrch *acl, MirrorOrch *mirror, DTelOrch *dtel, const string& rule, const string& table, const KeyOpFieldsValuesTuple&); virtual ~AclRule() {} protected: @@ -251,7 +251,7 @@ class AclRulePfcwd: public AclRuleL3 class AclRuleMirror: public AclRule { public: - AclRuleMirror(AclOrch *m_pAclOrch, acl_stage_type_t stage, MirrorOrch *m_pMirrorOrch, string rule, string table, acl_table_type_t type); + AclRuleMirror(AclOrch *m_pAclOrch, MirrorOrch *m_pMirrorOrch, string rule, string table, acl_table_type_t type); bool validateAddAction(string attr_name, string attr_value); bool validateAddMatch(string attr_name, string attr_value); bool validate(); @@ -263,7 +263,6 @@ class AclRuleMirror: public AclRule protected: bool m_state; string m_sessionName; - acl_stage_type_t m_tableStage; AclRuleCounters counters; MirrorOrch *m_pMirrorOrch; }; diff --git a/tests/test_mirror.py b/tests/test_mirror.py index b8f440ec801..d1a29840406 100644 --- a/tests/test_mirror.py +++ b/tests/test_mirror.py @@ -23,7 +23,7 @@ def set_interface_status(self, interface, admin_status): else: tbl_name = "PORT" tbl = swsscommon.Table(self.cdb, tbl_name) - fvs = swsscommon.FieldValuePairs([("admin_status", admin_status)]) + fvs = swsscommon.FieldValuePairs([("admin_status", "up")]) tbl.set(interface, fvs) time.sleep(1) @@ -680,12 +680,11 @@ def test_MirrorDestMoveLag(self, dvs, testlog): self.remove_mirror_session(session) - def create_acl_table(self, table, interfaces, stage = "INGRESS"): + def create_acl_table(self, table, interfaces): tbl = swsscommon.Table(self.cdb, "ACL_TABLE") fvs = swsscommon.FieldValuePairs([("policy_desc", "mirror_test"), - ("type", "mirror"), - ("ports", ",".join(interfaces)), - ("stage", stage)]) + ("type", "mirror"), + ("ports", ",".join(interfaces))]) tbl.set(table, fvs) time.sleep(1) @@ -697,20 +696,12 @@ def remove_acl_table(self, table): def create_mirror_acl_dscp_rule(self, table, rule, dscp, session): tbl = swsscommon.Table(self.cdb, "ACL_RULE") fvs = swsscommon.FieldValuePairs([("priority", "1000"), - ("MIRROR_ACTION", session), + ("mirror_action", session), ("DSCP", dscp)]) tbl.set(table + "|" + rule, fvs) time.sleep(1) - def create_mirror_acl_tcp_flag_rule(self, table, rule, tcp_flag, session): - tbl = swsscommon.Table(self.cdb, "ACL_RULE") - fvs = swsscommon.FieldValuePairs([("priority", "1000"), - ("MIRROR_ACTION", session), - ("TCP_FLAGS", tcp_flag)]) - tbl.set(table + "|" + rule, fvs) - time.sleep(1) - - def remove_mirror_acl_rule(self, table, rule): + def remove_mirror_acl_dscp_rule(self, table, rule): tbl = swsscommon.Table(self.cdb, "ACL_RULE") tbl._del(table + "|" + rule) time.sleep(1) @@ -762,7 +753,7 @@ def test_AclBindMirror(self, dvs, testlog): assert fv[1] == "1:" + mirror_session_oid # remove acl rule - self.remove_mirror_acl_rule(acl_table, acl_rule) + self.remove_mirror_acl_dscp_rule(acl_table, acl_rule) # create acl rule with dscp value 16/16 self.create_mirror_acl_dscp_rule(acl_table, acl_rule, "16/16", session) @@ -781,7 +772,7 @@ def test_AclBindMirror(self, dvs, testlog): assert fv[1] == "1:" + mirror_session_oid # remove acl rule - self.remove_mirror_acl_rule(acl_table, acl_rule) + self.remove_mirror_acl_dscp_rule(acl_table, acl_rule) # remove acl table self.remove_acl_table(acl_table) @@ -798,75 +789,3 @@ def test_AclBindMirror(self, dvs, testlog): self.remove_neighbor("Ethernet32", "20.0.0.1") self.remove_ip_address("Ethernet32", "20.0.0.0/31") self.set_interface_status("Ethernet32", "down") - - def test_EgressAclBindMirror(self, dvs, testlog): - """ - This test tests Egress ACL associated with mirror session with TCP flag value/mask - """ - self.setup_db(dvs) - - session = "MIRROR_SESSION" - acl_table = "EGRESS_MIRROR_TABLE" - acl_rule = "MIRROR_RULE" - - # create port channel; create port channel member; bring up - self.create_port_channel(dvs, "080") - self.create_port_channel_member("080", "Ethernet32") - self.set_interface_status("PortChannel080", "up") - self.set_interface_status("Ethernet32", "up") - - # add ip address to port channel 080; create neighbor to port channel 080 - self.add_ip_address("PortChannel080", "200.0.0.0/31") - self.add_neighbor("PortChannel080", "200.0.0.1", "12:10:08:06:04:02") - - # add route - self.add_route(dvs, "2.2.2.2", "200.0.0.1") - - # create mirror session - self.create_mirror_session(session, "1.1.1.1", "2.2.2.2", "0x6558", "8", "100", "0") - assert self.get_mirror_session_state(session)["status"] == "active" - - # assert mirror session in asic database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_MIRROR_SESSION") - assert len(tbl.getKeys()) == 1 - mirror_session_oid = tbl.getKeys()[0] - - # create acl table - self.create_acl_table(acl_table, ["Ethernet0", "Ethernet4"], "EGRESS") - - # create acl rule with TCP flag value/mask 48 - self.create_mirror_acl_tcp_flag_rule(acl_table, acl_rule, "0x07/0x3f", session) - - # assert acl rule is created - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_ENTRY") - rule_entries = [k for k in tbl.getKeys() if k not in dvs.asicdb.default_acl_entries] - assert len(rule_entries) == 1 - - (status, fvs) = tbl.get(rule_entries[0]) - assert status == True - for fv in fvs: - if fv[0] == "SAI_ACL_ENTRY_ATTR_FIELD_TCP_FLAGS": - assert fv[1] == "7&mask:0x3f" - if fv[0] == "SAI_ACL_ENTRY_ATTR_ACTION_MIRROR_EGRESS": - assert fv[1] == "1:" + mirror_session_oid - - # remove acl rule - self.remove_mirror_acl_rule(acl_table, acl_rule) - - # remove acl table - self.remove_acl_table(acl_table) - - # remove mirror session - self.remove_mirror_session(session) - - # assert no mirror session in asic database - tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_MIRROR_SESSION") - assert len(tbl.getKeys()) == 0 - - # remove route; remove neighbor; remove ip; bring down port - self.remove_route(dvs, "2.2.2.2") - self.remove_neighbor("PortChannel080", "200.0.0.1") - self.remove_ip_address("PortChannel080", "200.0.0.0/31") - self.set_interface_status("PortChannel080", "down") - self.set_interface_status("Ethernet32", "down") -