Skip to content

Commit da21172

Browse files
[aclorch] add generic AclOrch::updateAclRule() method (#1993)
- What I did I added generic AclOrch::updateAclRule() implementation. This implementation takes a newly constructed shared_ptr<AclRule> provided by the user, calculates a difference between priority, matches and actions and calls sai_acl_api->set_acl_entry_attribute() for those attributes that were changed. The derivatives of AclRule can customize the behaviour of AclRule::update(const AclRule& updatedRule) by polymorphic override, although in that case the derivative needs dynamic_cast the updatedRule to a concrete derivative type. Added unit test to cover update scenario. Currently this new API is not used by any clients nor handling ACL_RULE table updates. This API will be used by PBH ACL rule update flow. - Why I did it To support the scenario for updating PBH ACL rule in the future. - How I verified it Temporary changed the ACL_RULE table update to leverage this new API and tested updates through CONFIG_DB and unit test coverage. Signed-off-by: Stepan Blyshchak <[email protected]>
1 parent 4f6cb05 commit da21172

File tree

10 files changed

+783
-211
lines changed

10 files changed

+783
-211
lines changed

orchagent/Makefile.am

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ orchagent_SOURCES = \
6464
pbh/pbhrule.cpp \
6565
pbhorch.cpp \
6666
saihelper.cpp \
67+
saiattr.cpp \
6768
switchorch.cpp \
6869
pfcwdorch.cpp \
6970
pfcactionhandler.cpp \

orchagent/aclorch.cpp

+485-162
Large diffs are not rendered by default.

orchagent/aclorch.h

+41-17
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
#include "acltable.h"
2121

22+
#include "saiattr.h"
23+
2224
#define RULE_PRIORITY "PRIORITY"
2325
#define MATCH_IN_PORTS "IN_PORTS"
2426
#define MATCH_OUT_PORTS "OUT_PORTS"
@@ -93,6 +95,7 @@
9395
#define ACL_COUNTER_FLEX_COUNTER_GROUP "ACL_STAT_COUNTER"
9496

9597
typedef map<string, sai_acl_entry_attr_t> acl_rule_attr_lookup_t;
98+
typedef map<string, sai_acl_range_type_t> acl_range_type_lookup_t;
9699
typedef map<string, sai_acl_ip_type_t> acl_ip_type_lookup_t;
97100
typedef map<string, sai_acl_dtel_flow_op_t> acl_dtel_flow_op_type_lookup_t;
98101
typedef map<string, sai_packet_action_t> acl_packet_action_lookup_t;
@@ -102,6 +105,13 @@ typedef map<sai_acl_action_type_t, set<int32_t>> acl_action_enum_values_capabili
102105

103106
class AclOrch;
104107

108+
struct AclRangeConfig
109+
{
110+
sai_acl_range_type_t rangeType;
111+
uint32_t min;
112+
uint32_t max;
113+
};
114+
105115
class AclRange
106116
{
107117
public:
@@ -130,7 +140,7 @@ class AclRule
130140
AclRule(AclOrch *pAclOrch, string rule, string table, acl_table_type_t type, bool createCounter = true);
131141
virtual bool validateAddPriority(string attr_name, string attr_value);
132142
virtual bool validateAddMatch(string attr_name, string attr_value);
133-
virtual bool validateAddAction(string attr_name, string attr_value);
143+
virtual bool validateAddAction(string attr_name, string attr_value) = 0;
134144
virtual bool validate() = 0;
135145
bool processIpType(string type, sai_uint32_t &ip_type);
136146
inline static void setRulePriorities(sai_uint32_t min, sai_uint32_t max)
@@ -140,8 +150,9 @@ class AclRule
140150
}
141151

142152
virtual bool create();
153+
virtual bool update(const AclRule& updatedRule);
143154
virtual bool remove();
144-
virtual void update(SubjectType, void *) = 0;
155+
virtual void onUpdate(SubjectType, void *) = 0;
145156
virtual void updateInPorts();
146157

147158
virtual bool enableCounter();
@@ -167,16 +178,13 @@ class AclRule
167178
return m_counterOid;
168179
}
169180

181+
vector<sai_object_id_t> getInPorts() const;
182+
170183
bool hasCounter() const
171184
{
172185
return getCounterOid() != SAI_NULL_OBJECT_ID;
173186
}
174187

175-
vector<sai_object_id_t> getInPorts()
176-
{
177-
return m_inPorts;
178-
}
179-
180188
static shared_ptr<AclRule> makeShared(acl_table_type_t type, AclOrch *acl, MirrorOrch *mirror, DTelOrch *dtel, const string& rule, const string& table, const KeyOpFieldsValuesTuple&);
181189
virtual ~AclRule() {}
182190

@@ -187,6 +195,17 @@ class AclRule
187195
virtual bool removeRanges();
188196
virtual bool removeRule();
189197

198+
virtual bool updatePriority(const AclRule& updatedRule);
199+
virtual bool updateMatches(const AclRule& updatedRule);
200+
virtual bool updateActions(const AclRule& updatedRule);
201+
virtual bool updateCounter(const AclRule& updatedRule);
202+
203+
virtual bool setPriority(const sai_uint32_t &value);
204+
virtual bool setAction(sai_acl_entry_attr_t actionId, sai_acl_action_data_t actionData);
205+
virtual bool setMatch(sai_acl_entry_attr_t matchId, sai_acl_field_data_t matchData);
206+
207+
virtual bool setAttribute(sai_attribute_t attr);
208+
190209
void decreaseNextHopRefCount();
191210

192211
bool isActionSupported(sai_acl_entry_attr_t) const;
@@ -201,13 +220,13 @@ class AclRule
201220
sai_object_id_t m_ruleOid;
202221
sai_object_id_t m_counterOid;
203222
uint32_t m_priority;
204-
map <sai_acl_entry_attr_t, sai_attribute_value_t> m_matches;
205-
map <sai_acl_entry_attr_t, sai_attribute_value_t> m_actions;
223+
map <sai_acl_entry_attr_t, SaiAttrWrapper> m_actions;
224+
map <sai_acl_entry_attr_t, SaiAttrWrapper> m_matches;
206225
string m_redirect_target_next_hop;
207226
string m_redirect_target_next_hop_group;
208227

209-
vector<sai_object_id_t> m_inPorts;
210-
vector<sai_object_id_t> m_outPorts;
228+
vector<AclRangeConfig> m_rangeConfig;
229+
vector<AclRange*> m_ranges;
211230

212231
private:
213232
bool m_createCounter;
@@ -221,7 +240,8 @@ class AclRuleL3: public AclRule
221240
bool validateAddAction(string attr_name, string attr_value);
222241
bool validateAddMatch(string attr_name, string attr_value);
223242
bool validate();
224-
void update(SubjectType, void *);
243+
void onUpdate(SubjectType, void *) override;
244+
225245
protected:
226246
sai_object_id_t getRedirectObjectId(const string& redirect_param);
227247
};
@@ -256,11 +276,12 @@ class AclRuleMirror: public AclRule
256276
bool validate();
257277
bool createRule();
258278
bool removeRule();
259-
void update(SubjectType, void *);
279+
void onUpdate(SubjectType, void *) override;
260280

261281
bool activate();
262282
bool deactivate();
263283

284+
bool update(const AclRule& updatedRule) override;
264285
protected:
265286
bool m_state {false};
266287
string m_sessionName;
@@ -275,11 +296,12 @@ class AclRuleDTelFlowWatchListEntry: public AclRule
275296
bool validate();
276297
bool createRule();
277298
bool removeRule();
278-
void update(SubjectType, void *);
299+
void onUpdate(SubjectType, void *) override;
279300

280301
bool activate();
281302
bool deactivate();
282303

304+
bool update(const AclRule& updatedRule) override;
283305
protected:
284306
DTelOrch *m_pDTelOrch;
285307
string m_intSessionId;
@@ -293,8 +315,7 @@ class AclRuleDTelDropWatchListEntry: public AclRule
293315
AclRuleDTelDropWatchListEntry(AclOrch *m_pAclOrch, DTelOrch *m_pDTelOrch, string rule, string table, acl_table_type_t type);
294316
bool validateAddAction(string attr_name, string attr_value);
295317
bool validate();
296-
void update(SubjectType, void *);
297-
318+
void onUpdate(SubjectType, void *) override;
298319
protected:
299320
DTelOrch *m_pDTelOrch;
300321
};
@@ -342,12 +363,14 @@ class AclTable
342363
void unlink(sai_object_id_t portOid);
343364
// Add or overwrite a rule into the ACL table
344365
bool add(shared_ptr<AclRule> newRule);
366+
// Update existing ACL rule
367+
bool updateRule(shared_ptr<AclRule> updatedRule);
345368
// Remove a rule from the ACL table
346369
bool remove(string rule_id);
347370
// Remove all rules from the ACL table
348371
bool clear();
349372
// Update table subject to changes
350-
void update(SubjectType, void *);
373+
void onUpdate(SubjectType, void *);
351374

352375
public:
353376
string id;
@@ -403,6 +426,7 @@ class AclOrch : public Orch, public Observer
403426
bool updateAclTable(string table_id, AclTable &table);
404427
bool addAclRule(shared_ptr<AclRule> aclRule, string table_id);
405428
bool removeAclRule(string table_id, string rule_id);
429+
bool updateAclRule(shared_ptr<AclRule> updatedAclRule);
406430
bool updateAclRule(string table_id, string rule_id, string attr_name, void *data, bool oper);
407431
bool updateAclRule(string table_id, string rule_id, bool enableCounter);
408432
AclRule* getAclRule(string table_id, string rule_id);

orchagent/pbh/pbhrule.cpp

+9-22
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,7 @@ bool AclRulePbh::validateAddPriority(const sai_uint32_t &value)
1111
{
1212
SWSS_LOG_ENTER();
1313

14-
if ((value < m_minPriority) || (value > m_maxPriority))
15-
{
16-
SWSS_LOG_ERROR("Failed to validate priority: invalid value %d", value);
17-
return false;
18-
}
19-
20-
m_priority = value;
21-
22-
return true;
14+
return setPriority(value);
2315
}
2416

2517
bool AclRulePbh::validateAddMatch(const sai_attribute_t &attr)
@@ -52,9 +44,7 @@ bool AclRulePbh::validateAddMatch(const sai_attribute_t &attr)
5244
return false;
5345
}
5446

55-
m_matches[attrId] = attr.value;
56-
57-
return true;
47+
return setMatch(attrId, attr.value.aclfield);
5848
}
5949

6050
bool AclRulePbh::validateAddAction(const sai_attribute_t &attr)
@@ -83,15 +73,7 @@ bool AclRulePbh::validateAddAction(const sai_attribute_t &attr)
8373
return false;
8474
}
8575

86-
if (!AclRule::isActionSupported(attrId))
87-
{
88-
SWSS_LOG_ERROR("Action %s is not supported by ASIC", attrName.c_str());
89-
return false;
90-
}
91-
92-
m_actions[attrId] = attr.value;
93-
94-
return true;
76+
return setAction(attrId, attr.value.aclaction);
9577
}
9678

9779
bool AclRulePbh::validate()
@@ -107,7 +89,12 @@ bool AclRulePbh::validate()
10789
return true;
10890
}
10991

110-
void AclRulePbh::update(SubjectType, void *)
92+
void AclRulePbh::onUpdate(SubjectType, void *)
11193
{
11294
// Do nothing
11395
}
96+
97+
bool AclRulePbh::validateAddAction(string attr_name, string attr_value)
98+
{
99+
SWSS_LOG_THROW("This API should not be used on PbhRule");
100+
}

orchagent/pbh/pbhrule.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ class AclRulePbh: public AclRule
1111
bool validateAddMatch(const sai_attribute_t &attr);
1212
bool validateAddAction(const sai_attribute_t &attr);
1313
bool validate() override;
14-
void update(SubjectType, void *) override;
14+
void onUpdate(SubjectType, void *) override;
15+
bool validateAddAction(string attr_name, string attr_value) override;
1516
};

orchagent/saiattr.cpp

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#include "saiattr.h"
2+
3+
#include <swss/logger.h>
4+
#include <sai_serialize.h>
5+
6+
SaiAttrWrapper::SaiAttrWrapper(sai_object_type_t objectType, const sai_attribute_t& attr)
7+
{
8+
auto meta = sai_metadata_get_attr_metadata(objectType, attr.id);
9+
if (!meta)
10+
{
11+
SWSS_LOG_THROW("Failed to get attribute %d metadata", attr.id);
12+
}
13+
14+
init(objectType, *meta, attr);
15+
}
16+
17+
SaiAttrWrapper::~SaiAttrWrapper()
18+
{
19+
if (m_meta)
20+
{
21+
sai_deserialize_free_attribute_value(m_meta->attrvaluetype, m_attr);
22+
}
23+
}
24+
25+
SaiAttrWrapper::SaiAttrWrapper(const SaiAttrWrapper& other)
26+
{
27+
init(other.m_objectType, *other.m_meta, other.m_attr);
28+
}
29+
30+
SaiAttrWrapper& SaiAttrWrapper::operator=(const SaiAttrWrapper& other)
31+
{
32+
init(other.m_objectType, *other.m_meta, other.m_attr);
33+
return *this;
34+
}
35+
36+
SaiAttrWrapper::SaiAttrWrapper(SaiAttrWrapper&& other)
37+
{
38+
swap(std::move(other));
39+
}
40+
41+
SaiAttrWrapper& SaiAttrWrapper::operator=(SaiAttrWrapper&& other)
42+
{
43+
swap(std::move(other));
44+
return *this;
45+
}
46+
47+
bool SaiAttrWrapper::operator<(const SaiAttrWrapper& other) const
48+
{
49+
return m_serializedAttr < other.m_serializedAttr;
50+
}
51+
52+
const sai_attribute_t& SaiAttrWrapper::getSaiAttr() const
53+
{
54+
return m_attr;
55+
}
56+
57+
std::string SaiAttrWrapper::toString() const
58+
{
59+
return m_serializedAttr;
60+
}
61+
62+
sai_attr_id_t SaiAttrWrapper::getAttrId() const
63+
{
64+
return m_attr.id;
65+
}
66+
67+
void SaiAttrWrapper::swap(SaiAttrWrapper&& other)
68+
{
69+
m_objectType = other.m_objectType;
70+
m_meta = other.m_meta;
71+
m_attr = other.m_attr;
72+
m_serializedAttr = other.m_serializedAttr;
73+
other.m_attr = sai_attribute_t{};
74+
other.m_serializedAttr.clear();
75+
}
76+
77+
void SaiAttrWrapper::init(
78+
sai_object_type_t objectType,
79+
const sai_attr_metadata_t& meta,
80+
const sai_attribute_t& attr)
81+
{
82+
m_objectType = objectType;
83+
m_attr.id = attr.id;
84+
m_meta = &meta;
85+
86+
m_serializedAttr = sai_serialize_attr_value(*m_meta, attr);
87+
88+
// deserialize to actually preform a deep copy of attr
89+
// and attribute value's dynamically allocated lists.
90+
sai_deserialize_attr_value(m_serializedAttr, *m_meta, m_attr);
91+
}

orchagent/saiattr.h

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#pragma once
2+
3+
extern "C"
4+
{
5+
#include <sai.h>
6+
#include <saimetadata.h>
7+
}
8+
9+
#include <string>
10+
11+
class SaiAttrWrapper
12+
{
13+
public:
14+
SaiAttrWrapper() = default;
15+
16+
SaiAttrWrapper(sai_object_type_t objectType, const sai_attribute_t& attr);
17+
SaiAttrWrapper(const SaiAttrWrapper& other);
18+
SaiAttrWrapper(SaiAttrWrapper&& other);
19+
SaiAttrWrapper& operator=(const SaiAttrWrapper& other);
20+
SaiAttrWrapper& operator=(SaiAttrWrapper&& other);
21+
virtual ~SaiAttrWrapper();
22+
23+
bool operator<(const SaiAttrWrapper& other) const;
24+
25+
const sai_attribute_t& getSaiAttr() const;
26+
std::string toString() const;
27+
sai_attr_id_t getAttrId() const;
28+
29+
private:
30+
31+
void init(
32+
sai_object_type_t objectType,
33+
const sai_attr_metadata_t& meta,
34+
const sai_attribute_t& attr);
35+
void swap(SaiAttrWrapper&& other);
36+
37+
sai_object_type_t m_objectType {SAI_OBJECT_TYPE_NULL};
38+
const sai_attr_metadata_t* m_meta {nullptr};
39+
sai_attribute_t m_attr {};
40+
std::string m_serializedAttr;
41+
};

tests/mock_tests/Makefile.am

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ tests_SOURCES = aclorch_ut.cpp \
5959
$(top_srcdir)/orchagent/pbh/pbhrule.cpp \
6060
$(top_srcdir)/orchagent/pbhorch.cpp \
6161
$(top_srcdir)/orchagent/saihelper.cpp \
62+
$(top_srcdir)/orchagent/saiattr.cpp \
6263
$(top_srcdir)/orchagent/switchorch.cpp \
6364
$(top_srcdir)/orchagent/pfcwdorch.cpp \
6465
$(top_srcdir)/orchagent/pfcactionhandler.cpp \

0 commit comments

Comments
 (0)