Skip to content

Commit 5779c1a

Browse files
keboliuliat-grozovik
authored andcommitted
[aclorch] Remove L4 port range support limitation on egress ACL table and add new SWSS virtual test. (sonic-net#741)
* fix bug for egress acl support and add vs test cases
1 parent 36e85eb commit 5779c1a

File tree

2 files changed

+344
-8
lines changed

2 files changed

+344
-8
lines changed

orchagent/aclorch.cpp

+5-8
Original file line numberDiff line numberDiff line change
@@ -1151,14 +1151,11 @@ bool AclTable::create()
11511151
attr.value.booldata = true;
11521152
table_attrs.push_back(attr);
11531153

1154-
if (stage == ACL_STAGE_INGRESS)
1155-
{
1156-
int32_t range_types_list[] = { SAI_ACL_RANGE_TYPE_L4_DST_PORT_RANGE, SAI_ACL_RANGE_TYPE_L4_SRC_PORT_RANGE };
1157-
attr.id = SAI_ACL_TABLE_ATTR_FIELD_ACL_RANGE_TYPE;
1158-
attr.value.s32list.count = (uint32_t)(sizeof(range_types_list) / sizeof(range_types_list[0]));
1159-
attr.value.s32list.list = range_types_list;
1160-
table_attrs.push_back(attr);
1161-
}
1154+
int32_t range_types_list[] = { SAI_ACL_RANGE_TYPE_L4_DST_PORT_RANGE, SAI_ACL_RANGE_TYPE_L4_SRC_PORT_RANGE };
1155+
attr.id = SAI_ACL_TABLE_ATTR_FIELD_ACL_RANGE_TYPE;
1156+
attr.value.s32list.count = (uint32_t)(sizeof(range_types_list) / sizeof(range_types_list[0]));
1157+
attr.value.s32list.list = range_types_list;
1158+
table_attrs.push_back(attr);
11621159

11631160
attr.id = SAI_ACL_TABLE_ATTR_ACL_STAGE;
11641161
attr.value.s32 = stage == ACL_STAGE_INGRESS ? SAI_ACL_STAGE_INGRESS : SAI_ACL_STAGE_EGRESS;

tests/test_acl_egress_table.py

+339
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,339 @@
1+
from swsscommon import swsscommon
2+
3+
import time
4+
5+
class TestEgressAclTable(object):
6+
def setup_db(self, dvs):
7+
self.pdb = swsscommon.DBConnector(0, dvs.redis_sock, 0)
8+
self.adb = swsscommon.DBConnector(1, dvs.redis_sock, 0)
9+
self.cdb = swsscommon.DBConnector(4, dvs.redis_sock, 0)
10+
11+
def create_egress_acl_table(self, table_name, ports):
12+
tbl = swsscommon.Table(self.cdb, "ACL_TABLE")
13+
14+
fvs = swsscommon.FieldValuePairs([("POLICY_DESC", "EGRESS_ACL_TEST"),
15+
("TYPE", "L3"),
16+
("PORTS", ports),
17+
("stage", "EGRESS")])
18+
tbl.set(table_name, fvs)
19+
time.sleep(1)
20+
21+
def create_acl_rule(self, fv_pairs, rule_name):
22+
rule_tbl = swsscommon.Table(self.cdb, "ACL_RULE")
23+
fvs = swsscommon.FieldValuePairs(fv_pairs)
24+
rule_tbl.set("egress_acl_table|" + rule_name, fvs)
25+
time.sleep(1)
26+
27+
def remove_acl_table(self, table_name):
28+
tbl = swsscommon.Table(self.cdb, "ACL_TABLE")
29+
tbl._del(table_name)
30+
time.sleep(1)
31+
32+
def get_acl_table_id(self, dvs):
33+
atbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE")
34+
keys = atbl.getKeys()
35+
for k in dvs.asicdb.default_acl_tables:
36+
assert k in keys
37+
acl_tables = [k for k in keys if k not in dvs.asicdb.default_acl_tables]
38+
39+
assert len(acl_tables) == 1
40+
41+
return acl_tables[0]
42+
43+
def remove_acl_rule(self, table_name, rule_name):
44+
tbl = swsscommon.Table(self.cdb, "ACL_RULE")
45+
tbl._del(table_name + "|" + rule_name)
46+
time.sleep(1)
47+
48+
def verify_acl_asic_table(self, dvs, bind_ports):
49+
tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE_GROUP")
50+
acl_table_groups = tbl.getKeys()
51+
assert len(acl_table_groups) == len(bind_ports)
52+
53+
tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_PORT")
54+
port_groups = []
55+
for p in [dvs.asicdb.portnamemap[portname] for portname in bind_ports]:
56+
(status, fvs) = tbl.get(p)
57+
for fv in fvs:
58+
if fv[0] == "SAI_PORT_ATTR_EGRESS_ACL":
59+
assert fv[1] in acl_table_groups
60+
port_groups.append(fv[1])
61+
62+
assert len(port_groups) == len(bind_ports)
63+
assert set(port_groups) == set(acl_table_groups)
64+
65+
tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE_GROUP")
66+
(status, fvs) = tbl.get(port_groups[0])
67+
assert status == True
68+
assert len(fvs) == 3
69+
for fv in fvs:
70+
if fv[0] == "SAI_ACL_TABLE_GROUP_ATTR_ACL_STAGE":
71+
assert fv[1] == "SAI_ACL_STAGE_EGRESS"
72+
elif fv[0] == "SAI_ACL_TABLE_GROUP_ATTR_ACL_BIND_POINT_TYPE_LIST":
73+
assert fv[1] == "1:SAI_ACL_BIND_POINT_TYPE_PORT"
74+
elif fv[0] == "SAI_ACL_TABLE_GROUP_ATTR_TYPE":
75+
assert fv[1] == "SAI_ACL_TABLE_GROUP_TYPE_PARALLEL"
76+
else:
77+
assert False
78+
79+
tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE_GROUP_MEMBER")
80+
member = tbl.getKeys()[0]
81+
(status, fvs) = tbl.get(member)
82+
assert status == True
83+
assert len(fvs) == 3
84+
for fv in fvs:
85+
if fv[0] == "SAI_ACL_TABLE_GROUP_MEMBER_ATTR_ACL_TABLE_GROUP_ID":
86+
assert port_groups[0] == fv[1]
87+
elif fv[0] == "SAI_ACL_TABLE_GROUP_MEMBER_ATTR_ACL_TABLE_ID":
88+
table_id = fv[1]
89+
elif fv[0] == "SAI_ACL_TABLE_GROUP_MEMBER_ATTR_PRIORITY":
90+
assert fv[1] == "100"
91+
else:
92+
assert False
93+
94+
tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE")
95+
(status, fvs) = tbl.get(table_id)
96+
assert status == True
97+
98+
def verify_acl_rule_asic_fvs(self, dvs, fv_tuple):
99+
# Verify Acl entry in ASIC DB
100+
test_acl_table_id = self.get_acl_table_id(dvs)
101+
acl_tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_ENTRY")
102+
keys = acl_tbl.getKeys()
103+
104+
acl_entry = [k for k in keys if k not in dvs.asicdb.default_acl_entries]
105+
assert len(acl_entry) == 1
106+
107+
(status, fvs) = acl_tbl.get(acl_entry[0])
108+
assert status == True
109+
assert len(fvs) == 6
110+
for fv in fvs:
111+
if fv[0] == "SAI_ACL_ENTRY_ATTR_TABLE_ID":
112+
assert fv[1] == test_acl_table_id
113+
elif fv[0] == "SAI_ACL_ENTRY_ATTR_ADMIN_STATE":
114+
assert fv[1] == "true"
115+
elif fv[0] == "SAI_ACL_ENTRY_ATTR_PRIORITY":
116+
assert fv[1] == "1000"
117+
elif fv[0] == "SAI_ACL_ENTRY_ATTR_ACTION_COUNTER":
118+
assert True
119+
elif fv[0] == fv_tuple[0]:
120+
assert fv[1] == fv_tuple[1]
121+
elif fv[0] == "SAI_ACL_ENTRY_ATTR_ACTION_PACKET_ACTION":
122+
assert fv[1] == "SAI_PACKET_ACTION_DROP"
123+
else:
124+
assert False
125+
126+
def verify_acl_rule_with_L4PortRange_asic_fvs(self, dvs, fv_tuple):
127+
# Verify Acl entry in ASIC DB
128+
test_acl_table_id = self.get_acl_table_id(dvs)
129+
acl_tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_ENTRY")
130+
keys = acl_tbl.getKeys()
131+
132+
acl_entry = [k for k in keys if k not in dvs.asicdb.default_acl_entries]
133+
assert len(acl_entry) == 1
134+
135+
(status, fvs) = acl_tbl.get(acl_entry[0])
136+
assert status == True
137+
assert len(fvs) == 6
138+
for fv in fvs:
139+
if fv[0] == "SAI_ACL_ENTRY_ATTR_TABLE_ID":
140+
assert fv[1] == test_acl_table_id
141+
elif fv[0] == "SAI_ACL_ENTRY_ATTR_ADMIN_STATE":
142+
assert fv[1] == "true"
143+
elif fv[0] == "SAI_ACL_ENTRY_ATTR_PRIORITY":
144+
assert fv[1] == "999"
145+
elif fv[0] == "SAI_ACL_ENTRY_ATTR_ACTION_COUNTER":
146+
assert True
147+
elif fv[0] == "SAI_ACL_ENTRY_ATTR_FIELD_ACL_RANGE_TYPE":
148+
aclrange = fv[1]
149+
elif fv[0] == "SAI_ACL_ENTRY_ATTR_ACTION_PACKET_ACTION":
150+
assert fv[1] == "SAI_PACKET_ACTION_FORWARD"
151+
else:
152+
assert False
153+
154+
# Verify Acl range in ASIC DB
155+
acl_tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_RANGE")
156+
aclrange_obj = aclrange.split(":", 1)[1]
157+
158+
(status, fvs) = acl_tbl.get(aclrange_obj)
159+
assert status == True
160+
assert len(fvs) == 2
161+
for fv in fvs:
162+
if fv[0] == "SAI_ACL_RANGE_ATTR_TYPE":
163+
assert fv[1] == fv_tuple[0]
164+
elif fv[0] == "SAI_ACL_RANGE_ATTR_LIMIT":
165+
assert fv[1] == fv_tuple[1]
166+
else:
167+
assert False
168+
169+
def check_asic_table_absent(self, dvs):
170+
tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_TABLE")
171+
acl_tables = tbl.getKeys()
172+
for key in dvs.asicdb.default_acl_tables:
173+
assert key in acl_tables
174+
acl_tables = [k for k in acl_tables if k not in dvs.asicdb.default_acl_tables]
175+
176+
assert len(acl_tables) == 0
177+
178+
def check_asic_rule_absent(self, dvs):
179+
tbl = swsscommon.Table(self.adb, "ASIC_STATE:SAI_OBJECT_TYPE_ACL_ENTRY")
180+
acl_entries = tbl.getKeys()
181+
for key in dvs.asicdb.default_acl_entries:
182+
assert key in acl_entries
183+
acl_entries = [k for k in acl_entries if k not in dvs.asicdb.default_acl_entries]
184+
185+
assert len(acl_entries) == 0
186+
187+
def test_EgressAclTableCreation(self, dvs):
188+
self.setup_db(dvs)
189+
190+
# Create ACL_TABLE in config db
191+
bind_ports = ["Ethernet0", "Ethernet4"]
192+
self.create_egress_acl_table("egress_acl_table", ",".join(bind_ports))
193+
194+
time.sleep(1)
195+
196+
# Check acl table in asic db
197+
self.verify_acl_asic_table(dvs, bind_ports)
198+
199+
def test_EgressAclRuleL4SrcPortRange(self, dvs):
200+
self.setup_db(dvs)
201+
202+
# Create L4 SrcPortRange Acl rule
203+
fvPairs = [("priority", "999"), ("PACKET_ACTION", "FORWARD"), ("L4_SRC_PORT_RANGE", "0-1001")]
204+
self.create_acl_rule(fvPairs, "L4SrcPortRange_rule")
205+
206+
# Verify Acl rule in ASIC DB
207+
fv_tuple = ("SAI_ACL_RANGE_TYPE_L4_SRC_PORT_RANGE", "0,1001")
208+
self.verify_acl_rule_with_L4PortRange_asic_fvs(dvs, fv_tuple)
209+
210+
# Remove Acl rule
211+
self.remove_acl_rule("egress_acl_table", "L4SrcPortRange_rule")
212+
self.check_asic_rule_absent(dvs)
213+
214+
def test_EgressAclRuleL4DstPortRange(self, dvs):
215+
self.setup_db(dvs)
216+
217+
# Create L4 DstPortRange Acl rule
218+
fvPairs = [("priority", "999"), ("PACKET_ACTION", "FORWARD"), ("L4_DST_PORT_RANGE", "1003-6666")]
219+
self.create_acl_rule(fvPairs, "L4DstPortRange_rule")
220+
221+
# Verify Acl rule in ASIC DB
222+
fv_tuple = ("SAI_ACL_RANGE_TYPE_L4_DST_PORT_RANGE", "1003,6666")
223+
self.verify_acl_rule_with_L4PortRange_asic_fvs(dvs, fv_tuple)
224+
225+
# Remove Acl rule
226+
self.remove_acl_rule("egress_acl_table", "L4DstPortRange_rule")
227+
self.check_asic_rule_absent(dvs)
228+
229+
def test_EgressAclRuleL2EthType(self, dvs):
230+
self.setup_db(dvs)
231+
232+
# Create L4 L2EthType Acl rule
233+
fvPairs = [("priority", "1000"), ("PACKET_ACTION", "DROP"), ("ETHER_TYPE", "8000")]
234+
self.create_acl_rule(fvPairs, "L2EthType_rule")
235+
236+
# Verify Acl rule in ASIC DB
237+
fv_tuple = ("SAI_ACL_ENTRY_ATTR_FIELD_ETHER_TYPE", "8000&mask:0xffff")
238+
self.verify_acl_rule_asic_fvs( dvs, fv_tuple)
239+
240+
# Remove Acl rule
241+
self.remove_acl_rule("egress_acl_table", "L2EthType_rule")
242+
self.check_asic_rule_absent(dvs)
243+
244+
def test_EgressAclRuleTunnelVNI(self, dvs):
245+
self.setup_db(dvs)
246+
247+
# Create Tunnel VNI Acl rule
248+
fvPairs = [("priority", "1000"), ("PACKET_ACTION", "DROP"), ("TUNNEL_VNI", "5000")]
249+
self.create_acl_rule(fvPairs, "TunnelVNI_rule")
250+
251+
# Verify Acl rule in ASIC DB
252+
fv_tuple = ("SAI_ACL_ENTRY_ATTR_FIELD_TUNNEL_VNI", "5000&mask:0xffffffff")
253+
self.verify_acl_rule_asic_fvs(dvs, fv_tuple)
254+
255+
# Remove Acl rule
256+
self.remove_acl_rule("egress_acl_table", "TunnelVNI_rule")
257+
self.check_asic_rule_absent(dvs)
258+
259+
def test_EgressAclRuleTC(self, dvs):
260+
self.setup_db(dvs)
261+
262+
# Create TC Acl rule
263+
fvPairs = [("priority", "1000"), ("PACKET_ACTION", "DROP"), ("TC", "1")]
264+
self.create_acl_rule(fvPairs, "TC_rule")
265+
266+
# Verify Acl rule in ASIC DB
267+
fv_tuple = ("SAI_ACL_ENTRY_ATTR_FIELD_TC", "1&mask:0xff")
268+
self.verify_acl_rule_asic_fvs(dvs, fv_tuple)
269+
270+
# Remove Acl rule
271+
self.remove_acl_rule("egress_acl_table", "TC_rule")
272+
self.check_asic_rule_absent(dvs)
273+
274+
def test_EgressAclInnerIPProtocol(self, dvs):
275+
self.setup_db(dvs)
276+
277+
# Create InnerIPProtocol Acl rule
278+
fvPairs = [("priority", "1000"), ("PACKET_ACTION", "DROP"), ("INNER_IP_PROTOCOL", "8")]
279+
self.create_acl_rule(fvPairs, "InnerIPProtocol_rule")
280+
281+
# Verify Acl rule in ASIC DB
282+
fv_tuple = ("SAI_ACL_ENTRY_ATTR_FIELD_INNER_IP_PROTOCOL", "8&mask:0xff")
283+
self.verify_acl_rule_asic_fvs(dvs, fv_tuple)
284+
285+
# Remove Acl rule
286+
self.remove_acl_rule("egress_acl_table", "InnerIPProtocol_rule")
287+
self.check_asic_rule_absent(dvs)
288+
289+
def test_EgressAclInnerEthType(self, dvs):
290+
self.setup_db(dvs)
291+
292+
# Create InnerEthernetType Acl rule
293+
fvPairs = [("priority", "1000"), ("PACKET_ACTION", "DROP"), ("INNER_ETHER_TYPE", "8000")]
294+
self.create_acl_rule(fvPairs, "InnerEthType_rule")
295+
296+
# Verify Acl rule in ASIC DB
297+
fv_tuple = ("SAI_ACL_ENTRY_ATTR_FIELD_INNER_ETHER_TYPE", "8000&mask:0xffff")
298+
self.verify_acl_rule_asic_fvs(dvs, fv_tuple)
299+
300+
# Remove Acl rule
301+
self.remove_acl_rule("egress_acl_table", "InnerEthType_rule")
302+
self.check_asic_rule_absent(dvs)
303+
304+
def test_EgressAclInnerL4SrcPort(self, dvs):
305+
self.setup_db(dvs)
306+
307+
# Create InnerL4SrcPort Acl rule
308+
fvPairs = [("priority", "1000"), ("PACKET_ACTION", "DROP"), ("INNER_L4_SRC_PORT", "999")]
309+
self.create_acl_rule(fvPairs, "InnerL4SrcPort_rule")
310+
311+
# Verify Acl rule in ASIC DB
312+
fv_tuple = ("SAI_ACL_ENTRY_ATTR_FIELD_INNER_L4_SRC_PORT", "999&mask:0xffff")
313+
self.verify_acl_rule_asic_fvs(dvs, fv_tuple)
314+
315+
# Remove Acl rule
316+
self.remove_acl_rule("egress_acl_table", "InnerL4SrcPort_rule")
317+
self.check_asic_rule_absent(dvs)
318+
319+
def test_EgressAclInnerL4DstPort(self, dvs):
320+
self.setup_db(dvs)
321+
322+
# Create InnerL4DstPort Acl rule
323+
fvPairs = [("priority", "1000"), ("PACKET_ACTION", "DROP"), ("INNER_L4_DST_PORT", "999")]
324+
self.create_acl_rule(fvPairs, "InnerL4DstPort_rule")
325+
326+
# Verify Acl rule in ASIC DB
327+
fv_tuple = ("SAI_ACL_ENTRY_ATTR_FIELD_INNER_L4_DST_PORT", "999&mask:0xffff")
328+
self.verify_acl_rule_asic_fvs(dvs, fv_tuple)
329+
330+
# Remove Acl rule
331+
self.remove_acl_rule("egress_acl_table", "InnerL4DstPort_rule")
332+
self.check_asic_rule_absent(dvs)
333+
334+
def test_EgressAclTableDeletion(self, dvs):
335+
self.setup_db(dvs)
336+
337+
# Remove Acl table
338+
self.remove_acl_table("egress_acl_table")
339+
self.check_asic_table_absent(dvs)

0 commit comments

Comments
 (0)