Skip to content

Commit 28b64ec

Browse files
authored
[acl-loader]: do not add default deny rule for egress acl (#1531)
* [acl-loader]: do not add default deny rule for egress acl Signed-off-by: Guohan Lu <[email protected]>
1 parent 4d89510 commit 28b64ec

File tree

5 files changed

+180
-30
lines changed

5 files changed

+180
-30
lines changed

acl_loader/main.py

+29-21
Original file line numberDiff line numberDiff line change
@@ -132,27 +132,27 @@ def __init__(self):
132132
# Global namespace will be used for Control plane ACL which are via IPTables.
133133
# Per ASIC namespace will be used for Data and Everflow ACL's.
134134
# Global Configdb will have all ACL information for both Ctrl and Data/Evereflow ACL's
135-
# and will be used as souurce of truth for ACL modification to config DB which will be done to both Global DB and
135+
# and will be used as souurce of truth for ACL modification to config DB which will be done to both Global DB and
136136
# front asic namespace
137-
137+
138138
self.per_npu_configdb = {}
139139

140140
# State DB are used for to get mirror Session monitor port.
141141
# For multi-npu platforms each asic namespace can have different monitor port
142142
# dependinding on which route to session destination ip. So for multi-npu
143-
# platforms we get state db for all front asic namespace in addition to
144-
143+
# platforms we get state db for all front asic namespace in addition to
144+
145145
self.per_npu_statedb = {}
146146

147147
# Getting all front asic namespace and correspding config and state DB connector
148-
148+
149149
namespaces = device_info.get_all_namespaces()
150150
for front_asic_namespaces in namespaces['front_ns']:
151151
self.per_npu_configdb[front_asic_namespaces] = ConfigDBConnector(use_unix_socket_path=True, namespace=front_asic_namespaces)
152152
self.per_npu_configdb[front_asic_namespaces].connect()
153153
self.per_npu_statedb[front_asic_namespaces] = SonicV2Connector(use_unix_socket_path=True, namespace=front_asic_namespaces)
154154
self.per_npu_statedb[front_asic_namespaces].connect(self.per_npu_statedb[front_asic_namespaces].STATE_DB)
155-
155+
156156
self.read_tables_info()
157157
self.read_rules_info()
158158
self.read_sessions_info()
@@ -183,8 +183,8 @@ def read_policers_info(self):
183183
Read POLICER table from configuration database
184184
:return:
185185
"""
186-
187-
# For multi-npu platforms we will read from any one of front asic namespace
186+
187+
# For multi-npu platforms we will read from any one of front asic namespace
188188
# config db as the information should be same across all config db
189189
if self.per_npu_configdb:
190190
namespace_configdb = list(self.per_npu_configdb.values())[0]
@@ -201,7 +201,7 @@ def read_sessions_info(self):
201201
:return:
202202
"""
203203

204-
# For multi-npu platforms we will read from any one of front asic namespace
204+
# For multi-npu platforms we will read from any one of front asic namespace
205205
# config db as the information should be same across all config db
206206
if self.per_npu_configdb:
207207
namespace_configdb = list(self.per_npu_configdb.values())[0]
@@ -210,8 +210,8 @@ def read_sessions_info(self):
210210
self.sessions_db_info = self.configdb.get_table(self.CFG_MIRROR_SESSION_TABLE)
211211
for key in self.sessions_db_info:
212212
if self.per_npu_statedb:
213-
# For multi-npu platforms we will read from all front asic name space
214-
# statedb as the monitor port will be differnt for each asic
213+
# For multi-npu platforms we will read from all front asic name space
214+
# statedb as the monitor port will be differnt for each asic
215215
# and it's status also might be different (ideally should not happen)
216216
# We will store them as dict of 'asic' : value
217217
self.sessions_db_info[key]["status"] = {}
@@ -283,6 +283,14 @@ def set_max_priority(self, priority):
283283
def is_table_valid(self, tname):
284284
return self.tables_db_info.get(tname)
285285

286+
def is_table_egress(self, tname):
287+
"""
288+
Check if ACL table stage is egress
289+
:param tname: ACL table name
290+
:return: True if table type is Egress
291+
"""
292+
return self.tables_db_info[tname].get("stage", Stage.INGRESS).upper() == Stage.EGRESS
293+
286294
def is_table_mirror(self, tname):
287295
"""
288296
Check if ACL table type is ACL_TABLE_TYPE_MIRROR or ACL_TABLE_TYPE_MIRRORV6
@@ -377,12 +385,12 @@ def validate_actions(self, table_name, action_props):
377385
# check if per npu state db is there then read using first state db
378386
# else read from global statedb
379387
if self.per_npu_statedb:
380-
# For multi-npu we will read using anyone statedb connector for front asic namespace.
381-
# Same information should be there in all state DB's
388+
# For multi-npu we will read using anyone statedb connector for front asic namespace.
389+
# Same information should be there in all state DB's
382390
# as it is static information about switch capability
383391
namespace_statedb = list(self.per_npu_statedb.values())[0]
384392
capability = namespace_statedb.get_all(self.statedb.STATE_DB, "{}|switch".format(self.SWITCH_CAPABILITY_TABLE))
385-
else:
393+
else:
386394
capability = self.statedb.get_all(self.statedb.STATE_DB, "{}|switch".format(self.SWITCH_CAPABILITY_TABLE))
387395
for action_key in dict(action_props):
388396
key = "{}|{}".format(self.ACL_ACTIONS_CAPABILITY_FIELD, stage.upper())
@@ -636,7 +644,7 @@ def convert_rules(self):
636644
except AclLoaderException as ex:
637645
error("Error processing rule %s: %s. Skipped." % (acl_entry_name, ex))
638646

639-
if not self.is_table_mirror(table_name):
647+
if not self.is_table_mirror(table_name) and not self.is_table_egress(table_name):
640648
deep_update(self.rules_info, self.deny_rule(table_name))
641649

642650
def full_update(self):
@@ -705,7 +713,7 @@ def incremental_update(self):
705713
# Add all new dataplane rules
706714
for key in new_dataplane_rules:
707715
self.configdb.mod_entry(self.ACL_RULE, key, self.rules_info[key])
708-
# Program for per-asic namespace corresponding to front asic also if present.
716+
# Program for per-asic namespace corresponding to front asic also if present.
709717
for namespace_configdb in self.per_npu_configdb.values():
710718
namespace_configdb.mod_entry(self.ACL_RULE, key, self.rules_info[key])
711719

@@ -715,22 +723,22 @@ def incremental_update(self):
715723

716724
for key in added_controlplane_rules:
717725
self.configdb.mod_entry(self.ACL_RULE, key, self.rules_info[key])
718-
# Program for per-asic namespace corresponding to front asic also if present.
726+
# Program for per-asic namespace corresponding to front asic also if present.
719727
# For control plane ACL it's not needed but to keep all db in sync program everywhere
720728
for namespace_configdb in self.per_npu_configdb.values():
721729
namespace_configdb.mod_entry(self.ACL_RULE, key, self.rules_info[key])
722730

723731
for key in removed_controlplane_rules:
724732
self.configdb.mod_entry(self.ACL_RULE, key, None)
725-
# Program for per-asic namespace corresponding to front asic also if present.
733+
# Program for per-asic namespace corresponding to front asic also if present.
726734
# For control plane ACL it's not needed but to keep all db in sync program everywhere
727735
for namespace_configdb in self.per_npu_configdb.values():
728736
namespace_configdb.mod_entry(self.ACL_RULE, key, None)
729737

730738
for key in existing_controlplane_rules:
731739
if cmp(self.rules_info[key], self.rules_db_info[key]) != 0:
732740
self.configdb.set_entry(self.ACL_RULE, key, self.rules_info[key])
733-
# Program for per-asic namespace corresponding to front asic also if present.
741+
# Program for per-asic namespace corresponding to front asic also if present.
734742
# For control plane ACL it's not needed but to keep all db in sync program everywhere
735743
for namespace_configdb in self.per_npu_configdb.values():
736744
namespace_configdb.set_entry(self.ACL_RULE, key, self.rules_info[key])
@@ -745,10 +753,10 @@ def delete(self, table=None, rule=None):
745753
if not table or table == key[0]:
746754
if not rule or rule == key[1]:
747755
self.configdb.set_entry(self.ACL_RULE, key, None)
748-
# Program for per-asic namespace corresponding to front asic also if present.
756+
# Program for per-asic namespace corresponding to front asic also if present.
749757
for namespace_configdb in self.per_npu_configdb.values():
750758
namespace_configdb.set_entry(self.ACL_RULE, key, None)
751-
759+
752760
def show_table(self, table_name):
753761
"""
754762
Show ACL table configuration.

tests/acl_input/acl_egress.json

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
{
2+
"acl": {
3+
"acl-sets": {
4+
"acl-set": {
5+
"DATAACL_3": {
6+
"acl-entries": {
7+
"acl-entry": {
8+
"1": {
9+
"config": {
10+
"sequence-id": 1
11+
},
12+
"actions": {
13+
"config": {
14+
"forwarding-action": "ACCEPT"
15+
}
16+
},
17+
"ip": {
18+
"config": {
19+
"protocol": "IP_ICMP",
20+
"source-ip-address": "20.0.0.2/32",
21+
"destination-ip-address": "30.0.0.3/32"
22+
}
23+
},
24+
"icmp": {
25+
"config": {
26+
"type": "3",
27+
"code": "0"
28+
}
29+
}
30+
},
31+
"2": {
32+
"config": {
33+
"sequence-id": 2
34+
},
35+
"actions": {
36+
"config": {
37+
"forwarding-action": "ACCEPT"
38+
}
39+
},
40+
"l2": {
41+
"config": {
42+
"vlan-id": "369"
43+
}
44+
},
45+
"ip": {
46+
"config": {
47+
"protocol": "IP_TCP",
48+
"source-ip-address": "20.0.0.2/32",
49+
"destination-ip-address": "30.0.0.3/32"
50+
}
51+
}
52+
}
53+
}
54+
}
55+
},
56+
"DATAACL_4": {
57+
"acl-entries": {
58+
"acl-entry": {
59+
"1": {
60+
"config": {
61+
"sequence-id": 1
62+
},
63+
"actions": {
64+
"config": {
65+
"forwarding-action": "ACCEPT"
66+
}
67+
},
68+
"ip": {
69+
"config": {
70+
"protocol": "IP_ICMP",
71+
"source-ip-address": "::1/128",
72+
"destination-ip-address": "::1/128"
73+
}
74+
},
75+
"icmp": {
76+
"config": {
77+
"type": "1",
78+
"code": "0"
79+
}
80+
}
81+
},
82+
"2": {
83+
"config": {
84+
"sequence-id": 100
85+
},
86+
"actions": {
87+
"config": {
88+
"forwarding-action": "ACCEPT"
89+
}
90+
},
91+
"ip": {
92+
"config": {
93+
"protocol": "IP_ICMP",
94+
"source-ip-address": "::1/128",
95+
"destination-ip-address": "::1/128"
96+
}
97+
},
98+
"icmp": {
99+
"config": {
100+
"type": "128"
101+
}
102+
}
103+
}
104+
}
105+
}
106+
}
107+
}
108+
}
109+
}
110+
}

tests/acl_loader_test.py

+22
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,28 @@ def test_icmpv6_translation(self, acl_loader):
118118
"PRIORITY": "9900"
119119
}
120120

121+
def test_ingress_default_deny_rule(self, acl_loader):
122+
acl_loader.rules_info = {}
123+
acl_loader.load_rules_from_file(os.path.join(test_path, 'acl_input/acl1.json'))
124+
print(acl_loader.rules_info)
125+
assert acl_loader.rules_info[('DATAACL', 'DEFAULT_RULE')] == {
126+
'PRIORITY': '1',
127+
'PACKET_ACTION': 'DROP',
128+
'ETHER_TYPE': '2048'
129+
}
130+
assert acl_loader.rules_info[('DATAACL_2', 'DEFAULT_RULE')] == {
131+
'PRIORITY': '1',
132+
'PACKET_ACTION': 'DROP',
133+
'IP_TYPE': 'IPV6ANY'
134+
}
135+
136+
def test_egress_no_default_deny_rule(self, acl_loader):
137+
acl_loader.rules_info = {}
138+
acl_loader.load_rules_from_file(os.path.join(test_path, 'acl_input/acl_egress.json'))
139+
print(acl_loader.rules_info)
140+
assert ('DATAACL_3', 'DEFAULT_RULE') not in acl_loader.rules_info
141+
assert ('DATAACL_4', 'DEFAULT_RULE') not in acl_loader.rules_info
142+
121143
def test_icmp_type_lower_bound(self, acl_loader):
122144
with pytest.raises(ValueError):
123145
acl_loader.rules_info = {}

tests/aclshow_test.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@
7878
# Expected output for aclshow -r RULE_4,RULE_6 -vv
7979
rule4_rule6_verbose_output = '' + \
8080
"""Reading ACL info...
81-
Total number of ACL Tables: 6
81+
Total number of ACL Tables: 8
8282
Total number of ACL Rules: 11
8383
8484
RULE NAME TABLE NAME PRIO PACKETS COUNT BYTES COUNT

tests/mock_tables/config_db.json

+18-8
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,18 @@
405405
"ports@": "PortChannel0002,PortChannel0005,PortChannel0008,PortChannel0011,PortChannel0014,PortChannel0017,PortChannel0020,PortChannel0023,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124",
406406
"type": "L3V6"
407407
},
408+
"ACL_TABLE|DATAACL_3": {
409+
"policy_desc": "DATAACL_3",
410+
"ports@": "PortChannel0002,PortChannel0005,PortChannel0008,PortChannel0011,PortChannel0014,PortChannel0017,PortChannel0020,PortChannel0023,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124",
411+
"type": "L3",
412+
"stage": "egress"
413+
},
414+
"ACL_TABLE|DATAACL_4": {
415+
"policy_desc": "DATAACL_4",
416+
"ports@": "PortChannel0002,PortChannel0005,PortChannel0008,PortChannel0011,PortChannel0014,PortChannel0017,PortChannel0020,PortChannel0023,Ethernet64,Ethernet68,Ethernet72,Ethernet76,Ethernet80,Ethernet84,Ethernet88,Ethernet92,Ethernet96,Ethernet100,Ethernet104,Ethernet108,Ethernet112,Ethernet116,Ethernet120,Ethernet124",
417+
"type": "L3V6",
418+
"stage": "egress"
419+
},
408420
"ACL_TABLE|EVERFLOW": {
409421
"policy_desc": "EVERFLOW",
410422
"ports@": "PortChannel0002,PortChannel0005,PortChannel0008,PortChannel0011,PortChannel0014,PortChannel0017,PortChannel0020,PortChannel0023,Ethernet100,Ethernet104,Ethernet92,Ethernet96,Ethernet84,Ethernet88,Ethernet76,Ethernet80,Ethernet108,Ethernet112,Ethernet64,Ethernet120,Ethernet116,Ethernet124,Ethernet72,Ethernet68",
@@ -1489,21 +1501,19 @@
14891501
"name": "T2-Peer",
14901502
"local_addr": "20.1.1.1",
14911503
"nhopself": "0",
1492-
"admin_status": "up",
1493-
"holdtime": "10",
1494-
"asn": "65200",
1504+
"admin_status": "up",
1505+
"holdtime": "10",
1506+
"asn": "65200",
14951507
"keepalive": "3"
14961508
},
14971509
"BGP_NEIGHBOR|30.1.1.5": {
14981510
"rrclient": "0",
14991511
"name": "T0-Peer",
15001512
"local_addr": "30.1.1.1",
15011513
"nhopself": "0",
1502-
"admin_status": "up",
1503-
"holdtime": "10",
1504-
"asn": "65200",
1514+
"admin_status": "up",
1515+
"holdtime": "10",
1516+
"asn": "65200",
15051517
"keepalive": "3"
15061518
}
1507-
1508-
15091519
}

0 commit comments

Comments
 (0)