Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated PFCWD to use single ACL table for PFCWD and MUX #1620

Merged
merged 6 commits into from
Feb 23, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 99 additions & 12 deletions orchagent/aclorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ static acl_table_type_lookup_t aclTableTypeLookUp =
{ TABLE_TYPE_CTRLPLANE, ACL_TABLE_CTRLPLANE },
{ TABLE_TYPE_DTEL_FLOW_WATCHLIST, ACL_TABLE_DTEL_FLOW_WATCHLIST },
{ TABLE_TYPE_DTEL_DROP_WATCHLIST, ACL_TABLE_DTEL_DROP_WATCHLIST },
{ TABLE_TYPE_MCLAG, ACL_TABLE_MCLAG }
{ TABLE_TYPE_MCLAG, ACL_TABLE_MCLAG },
{ TABLE_TYPE_DROP, ACL_TABLE_DROP }
};

static acl_stage_type_lookup_t aclStageLookUp =
Expand Down Expand Up @@ -620,6 +621,26 @@ bool AclRule::remove()
return res;
}

void AclRule::update_in_ports(void *data)
{
SWSS_LOG_ENTER();
sai_attribute_t attr;
sai_status_t status;

if (data != NULL)
{
attr.id = *(sai_acl_entry_attr_t *)data;
attr.value = m_matches[*(sai_acl_entry_attr_t *)data];
attr.value.aclfield.enable = true;

status = sai_acl_api->set_acl_entry_attribute(m_ruleOid, &attr);
if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to update ACL rule %s, rv:%d", m_id.c_str(), status);
}
}
}

AclRuleCounters AclRule::getCounters()
{
SWSS_LOG_ENTER();
Expand Down Expand Up @@ -675,7 +696,8 @@ shared_ptr<AclRule> AclRule::makeShared(acl_table_type_t type, AclOrch *acl, Mir
type != ACL_TABLE_MIRROR_DSCP &&
type != ACL_TABLE_DTEL_FLOW_WATCHLIST &&
type != ACL_TABLE_DTEL_DROP_WATCHLIST &&
type != ACL_TABLE_MCLAG)
type != ACL_TABLE_MCLAG &&
type != ACL_TABLE_DROP)
{
throw runtime_error("Unknown table type");
}
Expand Down Expand Up @@ -723,6 +745,10 @@ shared_ptr<AclRule> AclRule::makeShared(acl_table_type_t type, AclOrch *acl, Mir
{
return make_shared<AclRuleMclag>(acl, rule, table, type);
}
else if (type == ACL_TABLE_DROP)
{
return make_shared<AclRulePfcwd>(acl, rule, table, type);
}

throw runtime_error("Wrong combination of table type and action in rule " + rule);
}
Expand Down Expand Up @@ -998,20 +1024,13 @@ void AclRuleL3::update(SubjectType, void *)
// Do nothing
}


AclRulePfcwd::AclRulePfcwd(AclOrch *aclOrch, string rule, string table, acl_table_type_t type, bool createCounter) :
AclRuleL3(aclOrch, rule, table, type, createCounter)
{
}

bool AclRulePfcwd::validateAddMatch(string attr_name, string attr_value)
{
if (attr_name != MATCH_TC)
{
SWSS_LOG_ERROR("%s is not supported for the tables of type Pfcwd", attr_name.c_str());
return false;
}

return AclRule::validateAddMatch(attr_name, attr_value);
}

Expand Down Expand Up @@ -1326,7 +1345,7 @@ bool AclTable::create()
vector<int32_t> bpoint_list;

// PFC watch dog ACLs are only applied to port
if (type == ACL_TABLE_PFCWD)
if ((type == ACL_TABLE_PFCWD) || (type == ACL_TABLE_DROP))
{
bpoint_list = { SAI_ACL_BIND_POINT_TYPE_PORT };
}
Expand All @@ -1340,7 +1359,7 @@ bool AclTable::create()
attr.value.s32list.list = bpoint_list.data();
table_attrs.push_back(attr);

if (type == ACL_TABLE_PFCWD)
if ((type == ACL_TABLE_PFCWD) || (type == ACL_TABLE_DROP))
{
attr.id = SAI_ACL_TABLE_ATTR_FIELD_TC;
attr.value.booldata = true;
Expand All @@ -1349,7 +1368,14 @@ bool AclTable::create()
attr.id = SAI_ACL_TABLE_ATTR_ACL_STAGE;
attr.value.s32 = (stage == ACL_STAGE_INGRESS) ? SAI_ACL_STAGE_INGRESS : SAI_ACL_STAGE_EGRESS;
table_attrs.push_back(attr);


if (stage == ACL_STAGE_INGRESS)
{
attr.id = SAI_ACL_TABLE_ATTR_FIELD_IN_PORTS;
attr.value.booldata = true;
table_attrs.push_back(attr);
}

sai_status_t status = sai_acl_api->create_acl_table(&m_oid, gSwitchId, (uint32_t)table_attrs.size(), table_attrs.data());

if (status == SAI_STATUS_SUCCESS)
Expand Down Expand Up @@ -1519,6 +1545,10 @@ bool AclTable::create()
attr.id = SAI_ACL_TABLE_ATTR_FIELD_IP_PROTOCOL;
attr.value.booldata = true;
table_attrs.push_back(attr);

attr.id = SAI_ACL_TABLE_ATTR_FIELD_IN_PORTS;
attr.value.booldata = true;
table_attrs.push_back(attr);
}

attr.id = SAI_ACL_TABLE_ATTR_FIELD_L4_SRC_PORT;
Expand Down Expand Up @@ -2919,6 +2949,63 @@ bool AclOrch::removeAclRule(string table_id, string rule_id)
return m_AclTables[table_oid].remove(rule_id);
}

bool AclOrch::updateAclRule(shared_ptr<AclRule> rule, string table_id, string attr_name, void *data, bool oper)
{
SWSS_LOG_ENTER();

sai_object_id_t table_oid = getTableById(table_id);
string attr_value;

if (table_oid == SAI_NULL_OBJECT_ID)
{
SWSS_LOG_ERROR("Failed to update ACL rule in ACL table %s. Table doesn't exist", table_id.c_str());
return false;
}

switch (aclMatchLookup[attr_name])
{
case SAI_ACL_ENTRY_ATTR_FIELD_IN_PORTS:
{
sai_object_id_t port_oid = *(sai_object_id_t *)data;
vector<sai_object_id_t> in_ports = rule->getInPorts();

if (oper == RULE_OPER_ADD)
{
in_ports.push_back(port_oid);
}
else
{
for (auto port_iter = in_ports.begin(); port_iter != in_ports.end(); port_iter++)
{
if (*port_iter == port_oid)
{
in_ports.erase(port_iter);
break;
}
}
}

for (const auto& port_iter: in_ports)
{
Port p;
gPortsOrch->getPort(port_iter, p);
attr_value += p.m_alias;
attr_value += ',';
}
attr_value.pop_back();

rule->validateAddMatch(MATCH_IN_PORTS, attr_value);
m_AclTables[table_oid].rules[rule->getId()]->update_in_ports(&aclMatchLookup[attr_name]);
}
break;

default:
break;
}

return true;
}

bool AclOrch::isCombinedMirrorV6Table()
{
return m_isCombinedMirrorV6Table;
Expand Down
19 changes: 17 additions & 2 deletions orchagent/aclorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#define TABLE_TYPE_DTEL_DROP_WATCHLIST "DTEL_DROP_WATCHLIST"
#define TABLE_TYPE_MCLAG "MCLAG"
#define TABLE_TYPE_MUX "MUX"
#define TABLE_TYPE_DROP "DROP"

#define RULE_PRIORITY "PRIORITY"
#define MATCH_IN_PORTS "IN_PORTS"
Expand Down Expand Up @@ -103,6 +104,9 @@
#define IP_TYPE_ARP_REPLY "ARP_REPLY"

#define MLNX_MAX_RANGES_COUNT 16
#define INGRESS_TABLE_DROP "IngressTableDrop"
#define RULE_OPER_ADD 0
#define RULE_OPER_DELETE 1

typedef enum
{
Expand All @@ -117,7 +121,8 @@ typedef enum
ACL_TABLE_DTEL_FLOW_WATCHLIST,
ACL_TABLE_DTEL_DROP_WATCHLIST,
ACL_TABLE_MCLAG,
ACL_TABLE_MUX
ACL_TABLE_MUX,
ACL_TABLE_DROP
} acl_table_type_t;

typedef map<string, acl_table_type_t> acl_table_type_lookup_t;
Expand Down Expand Up @@ -196,6 +201,7 @@ class AclRule
virtual bool create();
virtual bool remove();
virtual void update(SubjectType, void *) = 0;
virtual void update_in_ports(void *);
virtual AclRuleCounters getCounters();

string getId()
Expand All @@ -213,6 +219,11 @@ class AclRule
return m_counterOid;
}

vector<sai_object_id_t> getInPorts()
{
return m_inPorts;
}

static shared_ptr<AclRule> makeShared(acl_table_type_t type, AclOrch *acl, MirrorOrch *mirror, DTelOrch *dtel, const string& rule, const string& table, const KeyOpFieldsValuesTuple&);
virtual ~AclRule() {}

Expand Down Expand Up @@ -417,7 +428,6 @@ class AclOrch : public Orch, public Observer
return m_countersTable;
}


// FIXME: Add getters for them? I'd better to add a common directory of orch objects and use it everywhere
MirrorOrch *m_mirrorOrch;
NeighOrch *m_neighOrch;
Expand All @@ -429,6 +439,7 @@ class AclOrch : public Orch, public Observer
bool updateAclTable(AclTable &currentTable, AclTable &newTable);
bool addAclRule(shared_ptr<AclRule> aclRule, string table_id);
bool removeAclRule(string table_id, string rule_id);
bool updateAclRule(shared_ptr<AclRule> aclRule, string table_id, string attr_name, void *data, bool oper);

bool isCombinedMirrorV6Table();
bool isAclActionSupported(acl_stage_type_t stage, sai_acl_action_type_t action) const;
Expand All @@ -443,6 +454,10 @@ class AclOrch : public Orch, public Observer
static bool getAclBindPortId(Port& port, sai_object_id_t& port_id);

using Orch::doTask; // Allow access to the basic doTask
map<sai_object_id_t, AclTable> getAclTables()
{
return m_AclTables;
}

private:
SwitchOrch *m_switchOrch;
Expand Down
Loading