Skip to content

Commit 756471a

Browse files
authored
[ACL] Match TCP protocol while matching TCP_FLAG (sonic-net#1854)
* Match TCP protocol while matching TCP_FLAG Signed-off-by: bingwang <[email protected]>
1 parent ed867b1 commit 756471a

File tree

2 files changed

+82
-26
lines changed

2 files changed

+82
-26
lines changed

orchagent/aclorch.cpp

+47-13
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ extern CrmOrch *gCrmOrch;
3535
#define MIN_VLAN_ID 1 // 0 is a reserved VLAN ID
3636
#define MAX_VLAN_ID 4095 // 4096 is a reserved VLAN ID
3737

38+
const int TCP_PROTOCOL_NUM = 6; // TCP protocol number
39+
3840
acl_rule_attr_lookup_t aclMatchLookup =
3941
{
4042
{ MATCH_IN_PORTS, SAI_ACL_ENTRY_ATTR_FIELD_IN_PORTS },
@@ -645,7 +647,7 @@ void AclRule::updateInPorts()
645647
attr.id = SAI_ACL_ENTRY_ATTR_FIELD_IN_PORTS;
646648
attr.value = m_matches[SAI_ACL_ENTRY_ATTR_FIELD_IN_PORTS];
647649
attr.value.aclfield.enable = true;
648-
650+
649651
status = sai_acl_api->set_acl_entry_attribute(m_ruleOid, &attr);
650652
if (status != SAI_STATUS_SUCCESS)
651653
{
@@ -1378,14 +1380,14 @@ bool AclTable::create()
13781380
attr.id = SAI_ACL_TABLE_ATTR_ACL_STAGE;
13791381
attr.value.s32 = (stage == ACL_STAGE_INGRESS) ? SAI_ACL_STAGE_INGRESS : SAI_ACL_STAGE_EGRESS;
13801382
table_attrs.push_back(attr);
1381-
1383+
13821384
if (stage == ACL_STAGE_INGRESS)
13831385
{
13841386
attr.id = SAI_ACL_TABLE_ATTR_FIELD_IN_PORTS;
13851387
attr.value.booldata = true;
13861388
table_attrs.push_back(attr);
13871389
}
1388-
1390+
13891391
sai_status_t status = sai_acl_api->create_acl_table(&m_oid, gSwitchId, (uint32_t)table_attrs.size(), table_attrs.data());
13901392

13911393
if (status == SAI_STATUS_SUCCESS)
@@ -2985,11 +2987,11 @@ AclRule* AclOrch::getAclRule(string table_id, string rule_id)
29852987
bool AclOrch::updateAclRule(string table_id, string rule_id, string attr_name, void *data, bool oper)
29862988
{
29872989
SWSS_LOG_ENTER();
2988-
2990+
29892991
sai_object_id_t table_oid = getTableById(table_id);
29902992
string attr_value;
29912993

2992-
if (table_oid == SAI_NULL_OBJECT_ID)
2994+
if (table_oid == SAI_NULL_OBJECT_ID)
29932995
{
29942996
SWSS_LOG_ERROR("Failed to update ACL rule in ACL table %s. Table doesn't exist", table_id.c_str());
29952997
return false;
@@ -3002,29 +3004,29 @@ bool AclOrch::updateAclRule(string table_id, string rule_id, string attr_name, v
30023004
return false;
30033005
}
30043006

3005-
switch (aclMatchLookup[attr_name])
3007+
switch (aclMatchLookup[attr_name])
30063008
{
30073009
case SAI_ACL_ENTRY_ATTR_FIELD_IN_PORTS:
30083010
{
30093011
sai_object_id_t port_oid = *(sai_object_id_t *)data;
30103012
vector<sai_object_id_t> in_ports = rule_it->second->getInPorts();
30113013

3012-
if (oper == RULE_OPER_ADD)
3014+
if (oper == RULE_OPER_ADD)
30133015
{
30143016
in_ports.push_back(port_oid);
3015-
}
3016-
else
3017+
}
3018+
else
30173019
{
30183020
for (auto port_iter = in_ports.begin(); port_iter != in_ports.end(); port_iter++)
30193021
{
3020-
if (*port_iter == port_oid)
3022+
if (*port_iter == port_oid)
30213023
{
30223024
in_ports.erase(port_iter);
30233025
break;
30243026
}
30253027
}
30263028
}
3027-
3029+
30283030
for (const auto& port_iter: in_ports)
30293031
{
30303032
Port p;
@@ -3277,14 +3279,22 @@ void AclOrch::doAclRuleTask(Consumer &consumer)
32773279
it = consumer.m_toSync.erase(it);
32783280
return;
32793281
}
3280-
3282+
bool bHasTCPFlag = false;
3283+
bool bHasIPProtocol = false;
32813284
for (const auto& itr : kfvFieldsValues(t))
32823285
{
32833286
string attr_name = to_upper(fvField(itr));
32843287
string attr_value = fvValue(itr);
32853288

32863289
SWSS_LOG_INFO("ATTRIBUTE: %s %s", attr_name.c_str(), attr_value.c_str());
3287-
3290+
if (attr_name == MATCH_TCP_FLAGS)
3291+
{
3292+
bHasTCPFlag = true;
3293+
}
3294+
if (attr_name == MATCH_IP_PROTOCOL || attr_name == MATCH_NEXT_HEADER)
3295+
{
3296+
bHasIPProtocol = true;
3297+
}
32883298
if (newRule->validateAddPriority(attr_name, attr_value))
32893299
{
32903300
SWSS_LOG_INFO("Added priority attribute");
@@ -3304,6 +3314,30 @@ void AclOrch::doAclRuleTask(Consumer &consumer)
33043314
break;
33053315
}
33063316
}
3317+
// If acl rule is to match TCP_FLAGS, and IP_PROTOCOL(NEXT_HEADER) is not set
3318+
// we set IP_PROTOCOL(NEXT_HEADER) to 6 to match TCP explicitly
3319+
if (bHasTCPFlag && !bHasIPProtocol)
3320+
{
3321+
string attr_name;
3322+
if (type == ACL_TABLE_MIRRORV6 || type == ACL_TABLE_L3V6)
3323+
{
3324+
attr_name = MATCH_NEXT_HEADER;
3325+
}
3326+
else
3327+
{
3328+
attr_name = MATCH_IP_PROTOCOL;
3329+
3330+
}
3331+
string attr_value = std::to_string(TCP_PROTOCOL_NUM);
3332+
if (newRule->validateAddMatch(attr_name, attr_value))
3333+
{
3334+
SWSS_LOG_INFO("Automatically added match attribute '%s : %s'", attr_name.c_str(), attr_value.c_str());
3335+
}
3336+
else
3337+
{
3338+
SWSS_LOG_ERROR("Failed to add attribute '%s : %s'", attr_name.c_str(), attr_value.c_str());
3339+
}
3340+
}
33073341

33083342
// validate and create ACL rule
33093343
if (bAllAttributesOk && newRule->validate())

tests/test_acl.py

+35-13
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,23 @@ def test_AclRuleIpProtocol(self, dvs_acl, l3_acl_table):
8888
dvs_acl.remove_acl_rule(L3_TABLE_NAME, L3_RULE_NAME)
8989
dvs_acl.verify_no_acl_rules()
9090

91+
def test_AclRuleTCPProtocolAppendedForTCPFlags(self, dvs_acl, l3_acl_table):
92+
"""
93+
Verify TCP Protocol number (6) will be appended for ACL rules matching TCP_FLAGS
94+
"""
95+
config_qualifiers = {"TCP_FLAGS": "0x07/0x3f"}
96+
expected_sai_qualifiers = {
97+
"SAI_ACL_ENTRY_ATTR_FIELD_TCP_FLAGS":
98+
dvs_acl.get_simple_qualifier_comparator("7&mask:0x3f"),
99+
"SAI_ACL_ENTRY_ATTR_FIELD_IP_PROTOCOL":
100+
dvs_acl.get_simple_qualifier_comparator("6&mask:0xff")
101+
}
102+
dvs_acl.create_acl_rule(L3_TABLE_NAME, L3_RULE_NAME, config_qualifiers)
103+
dvs_acl.verify_acl_rule(expected_sai_qualifiers)
104+
105+
dvs_acl.remove_acl_rule(L3_TABLE_NAME, L3_RULE_NAME)
106+
dvs_acl.verify_no_acl_rules()
107+
91108
def test_AclRuleNextHeader(self, dvs_acl, l3_acl_table):
92109
config_qualifiers = {"NEXT_HEADER": "6"}
93110

@@ -98,6 +115,24 @@ def test_AclRuleNextHeader(self, dvs_acl, l3_acl_table):
98115
dvs_acl.remove_acl_rule(L3_TABLE_NAME, L3_RULE_NAME)
99116
dvs_acl.verify_no_acl_rules()
100117

118+
def test_V6AclRuleNextHeaderAppendedForTCPFlags(self, dvs_acl, l3v6_acl_table):
119+
"""
120+
Verify next heder (6) will be appended for IPv6 ACL rules matching TCP_FLAGS
121+
"""
122+
config_qualifiers = {"TCP_FLAGS": "0x07/0x3f"}
123+
expected_sai_qualifiers = {
124+
"SAI_ACL_ENTRY_ATTR_FIELD_TCP_FLAGS":
125+
dvs_acl.get_simple_qualifier_comparator("7&mask:0x3f"),
126+
"SAI_ACL_ENTRY_ATTR_FIELD_IPV6_NEXT_HEADER":
127+
dvs_acl.get_simple_qualifier_comparator("6&mask:0xff")
128+
}
129+
130+
dvs_acl.create_acl_rule(L3V6_TABLE_NAME, L3V6_RULE_NAME, config_qualifiers)
131+
dvs_acl.verify_acl_rule(expected_sai_qualifiers)
132+
133+
dvs_acl.remove_acl_rule(L3V6_TABLE_NAME, L3V6_RULE_NAME)
134+
dvs_acl.verify_no_acl_rules()
135+
101136
def test_AclRuleInOutPorts(self, dvs_acl, l3_acl_table):
102137
config_qualifiers = {
103138
"IN_PORTS": "Ethernet0,Ethernet4",
@@ -263,19 +298,6 @@ def test_V6AclRuleL4DstPort(self, dvs_acl, l3v6_acl_table):
263298
dvs_acl.remove_acl_rule(L3V6_TABLE_NAME, L3V6_RULE_NAME)
264299
dvs_acl.verify_no_acl_rules()
265300

266-
def test_V6AclRuleTCPFlags(self, dvs_acl, l3v6_acl_table):
267-
config_qualifiers = {"TCP_FLAGS": "0x07/0x3f"}
268-
expected_sai_qualifiers = {
269-
"SAI_ACL_ENTRY_ATTR_FIELD_TCP_FLAGS":
270-
dvs_acl.get_simple_qualifier_comparator("7&mask:0x3f")
271-
}
272-
273-
dvs_acl.create_acl_rule(L3V6_TABLE_NAME, L3V6_RULE_NAME, config_qualifiers)
274-
dvs_acl.verify_acl_rule(expected_sai_qualifiers)
275-
276-
dvs_acl.remove_acl_rule(L3V6_TABLE_NAME, L3V6_RULE_NAME)
277-
dvs_acl.verify_no_acl_rules()
278-
279301
def test_V6AclRuleL4SrcPortRange(self, dvs_acl, l3v6_acl_table):
280302
config_qualifiers = {"L4_SRC_PORT_RANGE": "1-100"}
281303
expected_sai_qualifiers = {

0 commit comments

Comments
 (0)