Skip to content

Commit db7d939

Browse files
Remove cache for high volume DASH objects (#3534)
What I did Remove caching for DASH routes, VNET maps, and ACL rules in orchagent Behavior implemented in this PR: Deletion of individual routes is supported as long as route group is unbound. When a route group is not bound, all routes must be deleted from a route group before deleting the group itself (until SAI/syncd are updated to perform implicit deletion). The goal is for SAI to support implicit deletion so that when a route group is deleted, all member routes are also deleted. Deletion of individual VNET maps is supported. All VNET maps must be deleted before parent VNET can be deleted. Deletion of individual ACL rules is NOT supported. Once SAI supports implicit deletion, ACL rules can be deleted by deleting the parent ACL group. Until support is added, there is no way to delete ACL rules. Remove functions to modify/delete individual DASH ACL rules In the future we plan to allow deleting of route groups/acl groups without deleting any member routes/acl rules. However this behavior is currently not possible as syncd tracks reference counts for each SAI object and rejects deletion of any object still being referenced. A change to syncd is needed to bypass refcount tracking for route groups/vnets/acl groups. Until this change is made in syncd, routes/maps/rules must be deleted before their parent route group/vnet/acl group can be delete.
1 parent 80294d5 commit db7d939

19 files changed

+372
-736
lines changed

orchagent/dash/dashaclgroupmgr.cpp

Lines changed: 7 additions & 243 deletions
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,6 @@ void DashAclGroupMgr::init(DashAclGroup& group)
152152
SWSS_LOG_ENTER();
153153
group.m_dash_acl_group_id = SAI_NULL_OBJECT_ID;
154154

155-
for (auto& rule: group.m_dash_acl_rule_table)
156-
{
157-
rule.second.m_dash_acl_rule_id = SAI_NULL_OBJECT_ID;
158-
}
159155
}
160156

161157
void DashAclGroupMgr::create(DashAclGroup& group)
@@ -216,6 +212,7 @@ void DashAclGroupMgr::remove(DashAclGroup& group)
216212

217213
CrmResourceType crm_rtype = (group.m_ip_version == SAI_IP_ADDR_FAMILY_IPV4) ?
218214
CrmResourceType::CRM_DASH_IPV4_ACL_GROUP : CrmResourceType::CRM_DASH_IPV6_ACL_GROUP;
215+
// Will also delete/zero out ACL rule count for this group, no need to do so separately
219216
gCrmOrch->decCrmDashAclUsedCounter(crm_rtype, group.m_dash_acl_group_id);
220217

221218
group.m_dash_acl_group_id = SAI_NULL_OBJECT_ID;
@@ -234,12 +231,6 @@ task_process_status DashAclGroupMgr::remove(const string& group_id)
234231

235232
auto& group = group_it->second;
236233

237-
if (!group.m_dash_acl_rule_table.empty())
238-
{
239-
SWSS_LOG_ERROR("ACL group %s still has %zu rules", group_id.c_str(), group.m_dash_acl_rule_table.size());
240-
return task_need_retry;
241-
}
242-
243234
if (isBound(group))
244235
{
245236
SWSS_LOG_ERROR("ACL group %s still has %zu references", group_id.c_str(), group.m_in_tables.size() + group.m_out_tables.size());
@@ -249,6 +240,7 @@ task_process_status DashAclGroupMgr::remove(const string& group_id)
249240
remove(group);
250241

251242
m_groups_table.erase(group_id);
243+
detachTags(group_id, group.m_tags);
252244
SWSS_LOG_INFO("Removed ACL group %s", group_id.c_str());
253245

254246
return task_success;
@@ -261,121 +253,6 @@ bool DashAclGroupMgr::exists(const string& group_id) const
261253
return m_groups_table.find(group_id) != m_groups_table.end();
262254
}
263255

264-
task_process_status DashAclGroupMgr::onUpdate(const string& group_id, const string& tag_id, const DashTag& tag)
265-
{
266-
SWSS_LOG_ENTER();
267-
268-
auto group_it = m_groups_table.find(group_id);
269-
if (group_it == m_groups_table.end())
270-
{
271-
return task_success;
272-
}
273-
274-
auto& group = group_it->second;
275-
if (isBound(group))
276-
{
277-
// If the group is bound to at least one ENI refresh the full group to update the affected rules.
278-
// When the group is bound to the ENI we need to make sure that the update of the affected rules will be atomic.
279-
SWSS_LOG_INFO("Update full ACL group %s", group_id.c_str());
280-
281-
return refreshAclGroupFull(group_id);
282-
}
283-
284-
// If the group is not bound to ENI update the rule immediately.
285-
SWSS_LOG_INFO("Update ACL group %s", group_id.c_str());
286-
for (auto& rule_it: group.m_dash_acl_rule_table)
287-
{
288-
auto& rule_id = rule_it.first;
289-
auto& rule_info = rule_it.second;
290-
if (rule_info.isTagUsed(tag_id))
291-
{
292-
DashAclRule rule;
293-
bool found = fetchRule(group_id, rule_id, rule);
294-
if (!found)
295-
{
296-
SWSS_LOG_ERROR("Failed to fetch group %s rule %s", group_id.c_str(), rule_id.c_str());
297-
return task_failed;
298-
}
299-
removeRule(group, rule_info);
300-
rule_info = createRule(group, rule);
301-
}
302-
}
303-
304-
return task_success;
305-
}
306-
307-
task_process_status DashAclGroupMgr::refreshAclGroupFull(const string &group_id)
308-
{
309-
SWSS_LOG_ENTER();
310-
311-
auto& group = m_groups_table[group_id];
312-
313-
DashAclGroup new_group = group;
314-
init(new_group);
315-
create(new_group);
316-
317-
for (auto& rule_it: new_group.m_dash_acl_rule_table)
318-
{
319-
auto& rule_id = rule_it.first;
320-
auto& rule_info = rule_it.second;
321-
DashAclRule rule;
322-
bool found = fetchRule(group_id, rule_id, rule);
323-
if (!found)
324-
{
325-
SWSS_LOG_ERROR("Failed to fetch group %s rule %s", group_id.c_str(), rule_id.c_str());
326-
return task_failed;
327-
}
328-
329-
rule_info = createRule(new_group, rule);
330-
}
331-
332-
for (const auto& table: new_group.m_in_tables)
333-
{
334-
const auto& eni_id = table.first;
335-
const auto& stages = table.second;
336-
337-
const auto eni = m_dash_orch->getEni(eni_id);
338-
ABORT_IF_NOT(eni != nullptr, "Failed to get ENI %s", eni_id.c_str());
339-
340-
for (const auto& stage: stages)
341-
{
342-
bind(new_group, *eni, DashAclDirection::IN, stage);
343-
}
344-
}
345-
346-
for (const auto& table: new_group.m_out_tables)
347-
{
348-
const auto& eni_id = table.first;
349-
const auto& stages = table.second;
350-
351-
const auto eni = m_dash_orch->getEni(eni_id);
352-
ABORT_IF_NOT(eni != nullptr, "Failed to get ENI %s", eni_id.c_str());
353-
354-
for (const auto& stage: stages)
355-
{
356-
bind(new_group, *eni, DashAclDirection::OUT, stage);
357-
}
358-
}
359-
360-
removeAclGroupFull(group);
361-
362-
group = new_group;
363-
364-
return task_success;
365-
}
366-
367-
void DashAclGroupMgr::removeAclGroupFull(DashAclGroup& group)
368-
{
369-
SWSS_LOG_ENTER();
370-
371-
for (auto& rule: group.m_dash_acl_rule_table)
372-
{
373-
removeRule(group, rule.second);
374-
}
375-
376-
remove(group);
377-
}
378-
379256
DashAclRuleInfo DashAclGroupMgr::createRule(DashAclGroup& group, DashAclRule& rule)
380257
{
381258
SWSS_LOG_ENTER();
@@ -439,9 +316,9 @@ DashAclRuleInfo DashAclGroupMgr::createRule(DashAclGroup& group, DashAclRule& ru
439316
for (const auto &tag : rule.m_src_tags)
440317
{
441318
const auto& prefixes = m_dash_acl_orch->getDashAclTagMgr().getPrefixes(tag);
442-
443319
src_prefixes.insert(src_prefixes.end(),
444320
prefixes.begin(), prefixes.end());
321+
group.m_tags.insert(tag);
445322
}
446323

447324
for (const auto &tag : rule.m_dst_tags)
@@ -450,6 +327,7 @@ DashAclRuleInfo DashAclGroupMgr::createRule(DashAclGroup& group, DashAclRule& ru
450327

451328
dst_prefixes.insert(dst_prefixes.end(),
452329
prefixes.begin(), prefixes.end());
330+
group.m_tags.insert(tag);
453331
}
454332

455333
if (src_prefixes.empty())
@@ -512,9 +390,6 @@ task_process_status DashAclGroupMgr::createRule(const string& group_id, const st
512390
}
513391
auto& group = group_it->second;
514392

515-
auto acl_rule_it = group.m_dash_acl_rule_table.find(rule_id);
516-
ABORT_IF_NOT(acl_rule_it == group.m_dash_acl_rule_table.end(), "Failed to create ACL rule %s. Rule already exist in ACL group %s", rule_id.c_str(), group_id.c_str());
517-
518393
for (const auto& tag_id : rule.m_src_tags)
519394
{
520395
if (!m_dash_acl_orch->getDashAclTagMgr().exists(tag_id))
@@ -535,112 +410,14 @@ task_process_status DashAclGroupMgr::createRule(const string& group_id, const st
535410

536411
auto rule_info = createRule(group, rule);
537412

538-
group.m_dash_acl_rule_table.emplace(rule_id, rule_info);
539-
attachTags(group_id, rule.m_src_tags);
540-
attachTags(group_id, rule.m_dst_tags);
413+
group.m_rule_count++;
414+
attachTags(group_id, group.m_tags);
541415

542416
SWSS_LOG_INFO("Created ACL rule %s:%s", group_id.c_str(), rule_id.c_str());
543417

544418
return task_success;
545419
}
546420

547-
task_process_status DashAclGroupMgr::updateRule(const string& group_id, const string& rule_id, DashAclRule& rule)
548-
{
549-
SWSS_LOG_ENTER();
550-
551-
if (ruleExists(group_id, rule_id))
552-
{
553-
removeRule(group_id, rule_id);
554-
}
555-
556-
createRule(group_id, rule_id, rule);
557-
558-
return task_success;
559-
}
560-
561-
void DashAclGroupMgr::removeRule(DashAclGroup& group, DashAclRuleInfo& rule)
562-
{
563-
SWSS_LOG_ENTER();
564-
565-
if (rule.m_dash_acl_rule_id == SAI_NULL_OBJECT_ID)
566-
{
567-
return;
568-
}
569-
570-
// Remove the ACL group
571-
auto status = sai_dash_acl_api->remove_dash_acl_rule(rule.m_dash_acl_rule_id);
572-
if (status != SAI_STATUS_SUCCESS)
573-
{
574-
SWSS_LOG_ERROR("Failed to remove ACL rule: %d, %s", status, sai_serialize_status(status).c_str());
575-
handleSaiRemoveStatus((sai_api_t)SAI_API_DASH_ACL, status);
576-
}
577-
578-
CrmResourceType crm_resource = (group.m_ip_version == SAI_IP_ADDR_FAMILY_IPV4) ?
579-
CrmResourceType::CRM_DASH_IPV4_ACL_RULE : CrmResourceType::CRM_DASH_IPV6_ACL_RULE;
580-
gCrmOrch->decCrmDashAclUsedCounter(crm_resource, group.m_dash_acl_group_id);
581-
582-
rule.m_dash_acl_rule_id = SAI_NULL_OBJECT_ID;
583-
}
584-
585-
task_process_status DashAclGroupMgr::removeRule(const string& group_id, const string& rule_id)
586-
{
587-
SWSS_LOG_ENTER();
588-
589-
if (!ruleExists(group_id, rule_id))
590-
{
591-
SWSS_LOG_INFO("ACL rule %s:%s does not exists", group_id.c_str(), rule_id.c_str());
592-
return task_success;
593-
}
594-
595-
auto& group = m_groups_table[group_id];
596-
if (isBound(group))
597-
{
598-
SWSS_LOG_INFO("Failed to remove dash ACL rule %s:%s, ACL group is bound to the ENI", group_id.c_str(), rule_id.c_str());
599-
return task_need_retry;
600-
}
601-
602-
auto& rule = group.m_dash_acl_rule_table[rule_id];
603-
604-
removeRule(group, rule);
605-
606-
detachTags(group_id, rule.m_src_tags);
607-
detachTags(group_id, rule.m_dst_tags);
608-
609-
group.m_dash_acl_rule_table.erase(rule_id);
610-
611-
SWSS_LOG_INFO("Removed ACL rule %s:%s", group_id.c_str(), rule_id.c_str());
612-
613-
return task_success;
614-
}
615-
616-
bool DashAclGroupMgr::fetchRule(const std::string &group_id, const std::string &rule_id, DashAclRule &rule)
617-
{
618-
auto key = group_id + ":" + rule_id;
619-
vector<FieldValueTuple> tuples;
620-
621-
bool exists = m_dash_acl_rules_table->get(key, tuples);
622-
if (!exists)
623-
{
624-
SWSS_LOG_ERROR("Failed to fetch DASH ACL Rule %s", key.c_str());
625-
return false;
626-
}
627-
628-
AclRule pb_rule;
629-
if (!parsePbMessage(tuples, pb_rule))
630-
{
631-
SWSS_LOG_ERROR("Failed to parse PB message for DASH ACL rule");
632-
return false;
633-
}
634-
635-
if (!from_pb(pb_rule, rule))
636-
{
637-
SWSS_LOG_ERROR("Failed to convert PB DASH ACL Rule");
638-
return false;
639-
}
640-
641-
return true;
642-
}
643-
644421
void DashAclGroupMgr::bind(const DashAclGroup& group, const EniEntry& eni, DashAclDirection direction, DashAclStage stage)
645422
{
646423
SWSS_LOG_ENTER();
@@ -658,19 +435,6 @@ void DashAclGroupMgr::bind(const DashAclGroup& group, const EniEntry& eni, DashA
658435
}
659436
}
660437

661-
bool DashAclGroupMgr::ruleExists(const string& group_id, const string& rule_id) const
662-
{
663-
SWSS_LOG_ENTER();
664-
665-
auto group_it = m_groups_table.find(group_id);
666-
if (group_it == m_groups_table.end())
667-
{
668-
return false;
669-
}
670-
671-
return group_it->second.m_dash_acl_rule_table.find(rule_id) != group_it->second.m_dash_acl_rule_table.end();
672-
}
673-
674438
task_process_status DashAclGroupMgr::bind(const string& group_id, const string& eni_id, DashAclDirection direction, DashAclStage stage)
675439
{
676440
SWSS_LOG_ENTER();
@@ -684,7 +448,7 @@ task_process_status DashAclGroupMgr::bind(const string& group_id, const string&
684448

685449
auto& group = group_it->second;
686450

687-
if (group.m_dash_acl_rule_table.empty())
451+
if (group.m_rule_count == 0)
688452
{
689453
SWSS_LOG_INFO("Failed to bind ACL group %s to ENI %s. ACL group has no rules attached.", group_id.c_str(), eni_id.c_str());
690454
return task_failed;

orchagent/dash/dashaclgroupmgr.h

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,11 @@ struct DashAclRuleInfo
6767
struct DashAclGroup
6868
{
6969
using EniTable = std::unordered_map<std::string, std::unordered_set<DashAclStage>>;
70-
using RuleTable = std::unordered_map<std::string, DashAclRuleInfo>;
71-
using RuleKeys = std::unordered_set<std::string>;
7270
sai_object_id_t m_dash_acl_group_id = SAI_NULL_OBJECT_ID;
71+
std::unordered_set<std::string> m_tags;
72+
int m_rule_count = 0;
7373

74-
std::string m_guid;
7574
sai_ip_addr_family_t m_ip_version;
76-
RuleTable m_dash_acl_rule_table;
7775

7876
EniTable m_in_tables;
7977
EniTable m_out_tables;
@@ -109,12 +107,7 @@ class DashAclGroupMgr
109107
bool exists(const std::string& group_id) const;
110108
bool isBound(const std::string& group_id);
111109

112-
task_process_status onUpdate(const std::string& group_id, const std::string& tag_id,const DashTag& tag);
113-
114110
task_process_status createRule(const std::string& group_id, const std::string& rule_id, DashAclRule& rule);
115-
task_process_status updateRule(const std::string& group_id, const std::string& rule_id, DashAclRule& rule);
116-
task_process_status removeRule(const std::string& group_id, const std::string& rule_id);
117-
bool ruleExists(const std::string& group_id, const std::string& rule_id) const;
118111

119112
task_process_status bind(const std::string& group_id, const std::string& eni_id, DashAclDirection direction, DashAclStage stage);
120113
task_process_status unbind(const std::string& group_id, const std::string& eni_id, DashAclDirection direction, DashAclStage stage);
@@ -125,15 +118,10 @@ class DashAclGroupMgr
125118
void remove(DashAclGroup& group);
126119

127120
DashAclRuleInfo createRule(DashAclGroup& group, DashAclRule& rule);
128-
void removeRule(DashAclGroup& group, DashAclRuleInfo& rule);
129-
bool fetchRule(const std::string &group_id, const std::string &rule_id, DashAclRule &rule);
130121

131122
void bind(const DashAclGroup& group, const EniEntry& eni, DashAclDirection direction, DashAclStage stage);
132123
void unbind(const DashAclGroup& group, const EniEntry& eni, DashAclDirection direction, DashAclStage stage);
133124
bool isBound(const DashAclGroup& group);
134125
void attachTags(const std::string &group_id, const std::unordered_set<std::string>& tags);
135126
void detachTags(const std::string &group_id, const std::unordered_set<std::string>& tags);
136-
137-
task_process_status refreshAclGroupFull(const std::string &group_id);
138-
void removeAclGroupFull(DashAclGroup& group);
139127
};

0 commit comments

Comments
 (0)