Skip to content

Commit 752c3d4

Browse files
authored
[ACL] Display rule and table info written to APP DB (sonic-net#3713)
* [Acl] Display rule and table info written to APP DB Signed-off-by: Vivek Reddy <[email protected]>
1 parent fbd0c3b commit 752c3d4

File tree

9 files changed

+232
-55
lines changed

9 files changed

+232
-55
lines changed

acl_loader/main.py

+48-15
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,10 @@ class AclLoader(object):
7373
ACL_TABLE = "ACL_TABLE"
7474
ACL_RULE = "ACL_RULE"
7575
CFG_ACL_TABLE = "ACL_TABLE"
76+
APPL_ACL_TABLE = "ACL_TABLE_TABLE"
7677
STATE_ACL_TABLE = "ACL_TABLE_TABLE"
7778
CFG_ACL_RULE = "ACL_RULE"
79+
APPL_ACL_RULE = "ACL_RULE_TABLE"
7880
STATE_ACL_RULE = "ACL_RULE_TABLE"
7981
ACL_TABLE_TYPE_MIRROR = "MIRROR"
8082
ACL_TABLE_TYPE_CTRLPLANE = "CTRLPLANE"
@@ -135,6 +137,8 @@ def __init__(self):
135137
self.configdb.connect()
136138
self.statedb = SonicV2Connector(host="127.0.0.1")
137139
self.statedb.connect(self.statedb.STATE_DB)
140+
self.appldb = SonicV2Connector(host="127.0.0.1")
141+
self.appldb.connect(self.statedb.APPL_DB)
138142

139143
# For multi-npu architecture we will have both global and per front asic namespace.
140144
# Global namespace will be used for Control plane ACL which are via IPTables.
@@ -165,8 +169,8 @@ def __init__(self):
165169
self.read_rules_info()
166170
self.read_sessions_info()
167171
self.read_policers_info()
168-
self.acl_table_status = self.read_acl_object_status_info(self.CFG_ACL_TABLE, self.STATE_ACL_TABLE)
169-
self.acl_rule_status = self.read_acl_object_status_info(self.CFG_ACL_RULE, self.STATE_ACL_RULE)
172+
self.acl_table_status = self.read_acl_object_status_info(self.tables_db_info.keys(), self.STATE_ACL_TABLE)
173+
self.acl_rule_status = self.read_acl_object_status_info(self.rules_db_info.keys(), self.STATE_ACL_RULE)
170174

171175
def read_tables_info(self):
172176
"""
@@ -199,16 +203,51 @@ def read_tables_info(self):
199203
self.tables_db_info[table]['ports'] += entry.get(
200204
'ports', [])
201205

206+
if self.per_npu_configdb:
207+
# Note: Ability to read table information from APPL_DB is not yet supported for masic devices
208+
return
209+
210+
appl_db_keys = self.appldb.keys(self.appldb.APPL_DB, "{}:*".format(self.APPL_ACL_TABLE))
211+
if not appl_db_keys:
212+
return
213+
214+
for app_acl_tbl in appl_db_keys:
215+
key = app_acl_tbl.split(":")[-1]
216+
if key in self.tables_db_info:
217+
# Shouldn't be hit, table is either programmed to APPL or CONFIG DB
218+
continue
219+
self.tables_db_info[key] = dict()
220+
for f, v in self.appldb.get_all(self.appldb.APPL_DB, app_acl_tbl).items():
221+
if f.lower() == "ports":
222+
v = v.split(",")
223+
self.tables_db_info[key][f.lower()] = v
224+
202225
def get_tables_db_info(self):
203226
return self.tables_db_info
204227

205228
def read_rules_info(self):
206229
"""
207-
Read ACL_RULE table from configuration database
230+
Read ACL_RULE table from CFG_DB and APPL_DB database
208231
:return:
209232
"""
210233
self.rules_db_info = self.configdb.get_table(self.ACL_RULE)
211234

235+
if self.per_npu_configdb:
236+
# Note: Ability to read table information from APPL_DB is not yet supported for masic devices
237+
return
238+
239+
# Read rule information from APPL_DB
240+
appl_db_keys = self.appldb.keys(self.appldb.APPL_DB, "{}:*".format(self.APPL_ACL_RULE))
241+
if not appl_db_keys:
242+
return
243+
244+
for app_acl_rule in appl_db_keys:
245+
_, tid, rid = app_acl_rule.split(":")
246+
if (tid, rid) in self.rules_db_info:
247+
# Shouldn't be hit, table is either programmed to APPL or CONFIG DB
248+
continue
249+
self.rules_db_info[(tid, rid)] = self.appldb.get_all(self.appldb.APPL_DB, app_acl_rule)
250+
212251
def get_rules_db_info(self):
213252
return self.rules_db_info
214253

@@ -259,16 +298,10 @@ def read_sessions_info(self):
259298
self.sessions_db_info[key]["status"] = state_db_info.get("status", "inactive") if state_db_info else "error"
260299
self.sessions_db_info[key]["monitor_port"] = state_db_info.get("monitor_port", "") if state_db_info else ""
261300

262-
def read_acl_object_status_info(self, cfg_db_table_name, state_db_table_name):
301+
def read_acl_object_status_info(self, keys, state_db_table_name):
263302
"""
264303
Read ACL_TABLE status or ACL_RULE status from STATE_DB
265304
"""
266-
if self.per_npu_configdb:
267-
namespace_configdb = list(self.per_npu_configdb.values())[0]
268-
keys = namespace_configdb.get_table(cfg_db_table_name).keys()
269-
else:
270-
keys = self.configdb.get_table(cfg_db_table_name).keys()
271-
272305
status = {}
273306
for key in keys:
274307
# For ACL_RULE, the key is (acl_table_name, acl_rule_name)
@@ -922,19 +955,19 @@ def show_table(self, table_name):
922955
status = self.acl_table_status[key]['status']
923956
else:
924957
status = 'N/A'
925-
if val["type"] == AclLoader.ACL_TABLE_TYPE_CTRLPLANE:
958+
if val.get("type", "N/A") == AclLoader.ACL_TABLE_TYPE_CTRLPLANE:
926959
services = natsorted(val["services"])
927-
data.append([key, val["type"], services[0], val["policy_desc"], stage, status])
960+
data.append([key, val.get("type", "N/A"), services[0], val.get("policy_desc", ""), stage, status])
928961

929962
if len(services) > 1:
930963
for service in services[1:]:
931964
data.append(["", "", service, "", "", ""])
932965
else:
933-
if not val["ports"]:
934-
data.append([key, val["type"], "", val["policy_desc"], stage, status])
966+
if not val.get("ports", []):
967+
data.append([key, val["type"], "", val.get("policy_desc", ""), stage, status])
935968
else:
936969
ports = natsorted(val["ports"])
937-
data.append([key, val["type"], ports[0], val["policy_desc"], stage, status])
970+
data.append([key, val["type"], ports[0], val.get("policy_desc", ""), stage, status])
938971

939972
if len(ports) > 1:
940973
for port in ports[1:]:

dump/plugins/acl_rule.py

+25-6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
CFG_DB_SEPARATOR = SonicDBConfig.getSeparator("CONFIG_DB")
1010
ASIC_DB_SEPARATOR = SonicDBConfig.getSeparator("ASIC_DB")
11+
APP_DB_SEPARATOR = SonicDBConfig.getSeparator("APPL_DB")
12+
APP_RULE_NAME = "ACL_RULE_TABLE"
1113

1214

1315
class Acl_Rule(Executor):
@@ -22,27 +24,44 @@ def __init__(self, match_engine=None):
2224
def get_all_args(self, ns=""):
2325
req = MatchRequest(db="CONFIG_DB", table="ACL_RULE", key_pattern="*", ns=ns)
2426
ret = self.match_engine.fetch(req)
25-
acl_rules = ret["keys"]
26-
return [key.split(CFG_DB_SEPARATOR, 1)[-1] for key in acl_rules]
27+
req_app = MatchRequest(db="APPL_DB", table=APP_RULE_NAME, key_pattern="*", ns=ns)
28+
ret_app = self.match_engine.fetch(req_app)
29+
return [f"{CFG_DB_SEPARATOR}".join(key.split(CFG_DB_SEPARATOR)[1:]) for key in ret.get("keys")] + \
30+
[f"{APP_DB_SEPARATOR}".join(key.split(APP_DB_SEPARATOR)[1:]) for key in ret_app.get("keys")]
2731

2832
def execute(self, params):
29-
self.ret_temp = create_template_dict(dbs=["CONFIG_DB", "ASIC_DB"])
30-
33+
self.ret_temp = create_template_dict(dbs=["CONFIG_DB", "APPL_DB", "ASIC_DB"])
34+
invalid = False
3135
try:
3236
acl_table_name, acl_rule_name = params[self.ARG_NAME].split(CFG_DB_SEPARATOR, 1)
3337
except ValueError:
34-
raise ValueError(f"Invalid rule name passed {params[self.ARG_NAME]}")
38+
invalid = True
39+
40+
if invalid:
41+
try:
42+
acl_table_name, acl_rule_name = params[self.ARG_NAME].split(APP_DB_SEPARATOR, 1)
43+
except ValueError:
44+
raise ValueError(f"Invalid rule name passed {params[self.ARG_NAME]}")
3545

3646
self.ns = params["namespace"]
3747
self.init_acl_rule_config_info(acl_table_name, acl_rule_name)
48+
self.init_acl_rule_appl_info(acl_table_name, acl_rule_name)
3849
self.init_acl_rule_asic_info(acl_table_name, acl_rule_name)
3950
return self.ret_temp
4051

4152
def init_acl_rule_config_info(self, acl_table_name, acl_rule_name):
4253
req = MatchRequest(db="CONFIG_DB", table="ACL_RULE",
4354
key_pattern=CFG_DB_SEPARATOR.join([acl_table_name, acl_rule_name]), ns=self.ns)
4455
ret = self.match_engine.fetch(req)
45-
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])
56+
if ret["keys"]:
57+
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])
58+
59+
def init_acl_rule_appl_info(self, acl_table_name, acl_rule_name):
60+
req = MatchRequest(db="APPL_DB", table=APP_RULE_NAME,
61+
key_pattern=APP_DB_SEPARATOR.join([acl_table_name, acl_rule_name]), ns=self.ns)
62+
ret = self.match_engine.fetch(req)
63+
if ret["keys"]:
64+
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])
4665

4766
def init_acl_rule_asic_info(self, acl_table_name, acl_rule_name):
4867
counter_oid = fetch_acl_counter_oid(self.match_engine, acl_table_name, acl_rule_name, self.ns)

dump/plugins/acl_table.py

+43-7
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88

99
CFG_DB_SEPARATOR = SonicDBConfig.getSeparator("CONFIG_DB")
1010
ASIC_DB_SEPARATOR = SonicDBConfig.getSeparator("ASIC_DB")
11+
APP_DB_SEPARATOR = SonicDBConfig.getSeparator("APPL_DB")
12+
APP_TABLE_TYPE_NAME = "ACL_TABLE_TYPE_TABLE"
13+
APP_TABLE_NAME = "ACL_TABLE_TABLE"
14+
APP_RULE_NAME = "ACL_RULE_TABLE"
1115

1216

1317
class Acl_Table(Executor):
@@ -22,21 +26,25 @@ def __init__(self, match_engine=None):
2226
def get_all_args(self, ns=""):
2327
req = MatchRequest(db="CONFIG_DB", table="ACL_TABLE", key_pattern="*", ns=ns)
2428
ret = self.match_engine.fetch(req)
25-
acl_tables = ret["keys"]
26-
return [key.split(CFG_DB_SEPARATOR)[-1] for key in acl_tables]
29+
req_app = MatchRequest(db="APPL_DB", table=APP_TABLE_NAME, key_pattern="*", ns=ns)
30+
ret_app = self.match_engine.fetch(req_app)
31+
return [key.split(CFG_DB_SEPARATOR)[-1] for key in ret.get("keys")] + \
32+
[key.split(APP_DB_SEPARATOR)[-1] for key in ret_app.get("keys")]
2733

2834
def execute(self, params):
29-
self.ret_temp = create_template_dict(dbs=["CONFIG_DB", "ASIC_DB"])
35+
self.ret_temp = create_template_dict(dbs=["CONFIG_DB", "APPL_DB", "ASIC_DB"])
3036
acl_table_name = params[self.ARG_NAME]
3137
self.ns = params["namespace"]
3238
self.init_acl_table_config_info(acl_table_name)
39+
self.init_acl_table_appl_info(acl_table_name)
3340
self.init_acl_table_asic_info(acl_table_name)
3441
return self.ret_temp
3542

3643
def init_acl_table_config_info(self, acl_table_name):
3744
req = MatchRequest(db="CONFIG_DB", table="ACL_TABLE", key_pattern=acl_table_name, return_fields=["type"], ns=self.ns)
3845
ret = self.match_engine.fetch(req)
39-
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])
46+
if ret["keys"]:
47+
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])
4048

4149
# Find corresponding ACL table type in CONFIG DB
4250
return_values = ret["return_values"]
@@ -47,13 +55,41 @@ def init_acl_table_config_info(self, acl_table_name):
4755
if ret["keys"]:
4856
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])
4957

50-
def init_acl_table_asic_info(self, acl_table_name):
58+
def init_acl_table_appl_info(self, acl_table_name):
59+
req = MatchRequest(db="APPL_DB", table=APP_TABLE_NAME, key_pattern=acl_table_name,
60+
return_fields=["type"], ns=self.ns)
61+
ret = self.match_engine.fetch(req)
62+
if ret["keys"]:
63+
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])
64+
65+
# Find corresponding ACL table type in CONFIG DB
66+
return_values = ret["return_values"]
67+
acl_table_type_name = return_values.get(APP_DB_SEPARATOR.join([APP_TABLE_NAME, acl_table_name]), {}).get("type")
68+
req = MatchRequest(db="APPL_DB", table=APP_TABLE_TYPE_NAME, key_pattern=acl_table_type_name, ns=self.ns)
69+
ret = self.match_engine.fetch(req)
70+
# If not found don't add it to the table, it might be a default table type
71+
if ret["keys"]:
72+
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])
73+
74+
def find_any_rule(self, acl_table_name):
5175
req = MatchRequest(db="CONFIG_DB", table="ACL_RULE", key_pattern=CFG_DB_SEPARATOR.join([acl_table_name, "*"]), ns=self.ns)
5276
ret = self.match_engine.fetch(req)
5377
acl_rules = ret["keys"]
54-
if not acl_rules:
78+
if acl_rules:
79+
return acl_rules[0].split(CFG_DB_SEPARATOR)[-1]
80+
81+
# Check in APPL_DB
82+
req = MatchRequest(db="APPL_DB", table=APP_RULE_NAME,
83+
key_pattern=APP_DB_SEPARATOR.join([acl_table_name, "*"]), ns=self.ns)
84+
ret = self.match_engine.fetch(req)
85+
acl_rules = ret["keys"]
86+
if acl_rules:
87+
return acl_rules[0].split(APP_DB_SEPARATOR)[-1]
88+
89+
def init_acl_table_asic_info(self, acl_table_name):
90+
acl_rule_name = self.find_any_rule(acl_table_name)
91+
if not acl_rule_name:
5592
return
56-
acl_rule_name = acl_rules[0].split(CFG_DB_SEPARATOR)[-1]
5793

5894
counter_oid = fetch_acl_counter_oid(self.match_engine, acl_table_name, acl_rule_name, self.ns)
5995
if not counter_oid:

tests/dump_input/acl/appl_db.json

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"ACL_TABLE_TYPE_TABLE:MY_TYPE": {
3+
"matches": "ETHER_TYPE,L4_DST_PORT_RANGE,L4_SRC_PORT_RANGE ",
4+
"bind_point_types": "port"
5+
},
6+
"ACL_TABLE_TABLE:DATAACL2": {
7+
"policy_desc": "Some ACL table",
8+
"ports": "Ethernet0,Ethernet4",
9+
"stage": "ingress",
10+
"type": "MY_TYPE"
11+
},
12+
"ACL_RULE_TABLE:DATAACL2:R0": {
13+
"L4_SRC_PORT_RANGE ": "90-95",
14+
"L4_DST_PORT_RANGE ": "90-95",
15+
"PACKET_ACTION": "FORWARD",
16+
"PRIORITY": "999"
17+
}
18+
}

tests/dump_input/acl/config_db.json

-16
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@
77
"stage": "ingress",
88
"type": "CTRLPLANE"
99
},
10-
"ACL_TABLE_TYPE|MY_TYPE": {
11-
"matches": "ETHER_TYPE,L4_DST_PORT_RANGE,L4_SRC_PORT_RANGE ",
12-
"bind_point_types": "port"
13-
},
1410
"ACL_TABLE|DATAACL": {
1511
"policy_desc": "Some ACL table",
1612
"ports": "Ethernet0,Ethernet4",
@@ -23,21 +19,9 @@
2319
"stage": "ingress",
2420
"type": "L3"
2521
},
26-
"ACL_TABLE|DATAACL2": {
27-
"policy_desc": "Some ACL table",
28-
"ports": "Ethernet0,Ethernet4",
29-
"stage": "ingress",
30-
"type": "MY_TYPE"
31-
},
3222
"ACL_RULE|DATAACL|R0": {
3323
"ETHER_TYPE": "2048",
3424
"PACKET_ACTION": "FORWARD",
3525
"PRIORITY": "999"
36-
},
37-
"ACL_RULE|DATAACL2|R0": {
38-
"L4_SRC_PORT_RANGE ": "90-95",
39-
"L4_DST_PORT_RANGE ": "90-95",
40-
"PACKET_ACTION": "FORWARD",
41-
"PRIORITY": "999"
4226
}
4327
}

0 commit comments

Comments
 (0)