Skip to content

Commit

Permalink
[Pfcwd]: Add pfcAclHandler to drop ingress packets by acl rules (soni…
Browse files Browse the repository at this point in the history
…c-net#361)

* [Pfcwd]: Add pfcAclHandler to drop ingress packets by acl rules

Signed-off-by: Sihui Han <sihan@microsoft.com>

* Simple refactoring

Signed-off-by: Qi Luo <qiluo-msft@users.noreply.github.com>

* Refactor AclTable

Signed-off-by: Qi Luo <qiluo-msft@users.noreply.github.com>

* Refactor AclRule, PfcWdAclHandler will bind/unbind ACL tables

Signed-off-by: Qi Luo <qiluo-msft@users.noreply.github.com>

* Fix ACL table/rule names, fix port oids in bind/unbind

Signed-off-by: Qi Luo <qiluo-msft@users.noreply.github.com>

* Add function entries logs

Signed-off-by: Qi Luo <qiluo-msft@users.noreply.github.com>
  • Loading branch information
qiluo-msft committed Oct 30, 2017
1 parent 98fc24b commit d460103
Show file tree
Hide file tree
Showing 8 changed files with 414 additions and 195 deletions.
426 changes: 256 additions & 170 deletions orchagent/aclorch.cpp

Large diffs are not rendered by default.

45 changes: 36 additions & 9 deletions orchagent/aclorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ typedef enum
typedef map<string, acl_table_type_t> acl_table_type_lookup_t;
typedef map<string, sai_acl_entry_attr_t> acl_rule_attr_lookup_t;
typedef map<string, sai_acl_ip_type_t> acl_ip_type_lookup_t;
typedef vector<sai_object_id_t> ports_list_t;
typedef tuple<sai_acl_range_type_t, int, int> acl_range_properties_t;

class AclOrch;
Expand Down Expand Up @@ -214,14 +213,43 @@ class AclRuleMirror: public AclRule
MirrorOrch *m_pMirrorOrch;
};

struct AclTable {
class AclTable {
sai_object_id_t m_oid;
public:
string id;
string description;
acl_table_type_t type;
ports_list_t ports;
// Map port oid to group member oid
std::map<sai_object_id_t, sai_object_id_t> ports;
// Map rule name to rule data
map<string, shared_ptr<AclRule>> rules;
AclTable(): type(ACL_TABLE_UNKNOWN) {}

AclTable()
: type(ACL_TABLE_UNKNOWN)
, m_oid(SAI_NULL_OBJECT_ID)
{}

sai_object_id_t getOid() { return m_oid; }
string getId() { return id; }
bool validate();
bool create();

// Bind the ACL table to a port which is alread linked
bool bind(sai_object_id_t portOid);
// Unbind the ACL table to a port which is alread linked
bool unbind(sai_object_id_t portOid);
// Bind the ACL table to all ports linked
bool bind();
// Unbind the ACL table to all ports linked
bool unbind();
// Link the ACL table with a port, for future bind or unbind
void link(sai_object_id_t portOid);
// Add or overwrite a rule into the ACL table
bool add(shared_ptr<AclRule> newRule);
// Remove a rule from the ACL table
bool remove(string rule_id);
// Remove all rules from the ACL table
bool clear();
};

template <class Iterable>
Expand Down Expand Up @@ -259,7 +287,7 @@ class AclOrch : public Orch, public Observer

bool addAclTable(AclTable &aclTable, string table_id);
bool removeAclTable(string table_id);
bool addAclRule(shared_ptr<AclRule> aclRule, string table_id, string rule_id);
bool addAclRule(shared_ptr<AclRule> aclRule, string table_id);
bool removeAclRule(string table_id, string rule_id);

private:
Expand All @@ -269,18 +297,17 @@ class AclOrch : public Orch, public Observer

static void collectCountersThread(AclOrch *pAclOrch);

sai_status_t createBindAclTable(AclTable &aclTable, sai_object_id_t &table_oid);
bool createBindAclTable(AclTable &aclTable, sai_object_id_t &table_oid);
sai_status_t bindAclTable(sai_object_id_t table_oid, AclTable &aclTable, bool bind = true);
sai_status_t deleteUnbindAclTable(sai_object_id_t table_oid);

bool processAclTableType(string type, acl_table_type_t &table_type);
bool processPorts(string portsList, ports_list_t& out);

bool processPorts(string portsList, std::function<void (sai_object_id_t)> inserter);
bool validateAclTable(AclTable &aclTable);

//vector <AclTable> m_AclTables;
map <sai_object_id_t, AclTable> m_AclTables;
// ACL table OID to multiple ACL table group member
multimap <sai_object_id_t, sai_object_id_t> m_AclTableGroupMembers;

static mutex m_countersMutex;
static condition_variable m_sleepGuard;
Expand Down
6 changes: 4 additions & 2 deletions orchagent/orchdaemon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ extern sai_object_id_t gSwitchId;
PortsOrch *gPortsOrch;
/* Global variable gFdbOrch declared */
FdbOrch *gFdbOrch;
/*Global variable gAclOrch declared*/
AclOrch *gAclOrch;

OrchDaemon::OrchDaemon(DBConnector *applDb, DBConnector *configDb) :
m_applDb(applDb),
Expand Down Expand Up @@ -93,9 +95,9 @@ bool OrchDaemon::init()
CFG_ACL_TABLE_NAME,
CFG_ACL_RULE_TABLE_NAME
};
AclOrch *acl_orch = new AclOrch(m_configDb, acl_tables, gPortsOrch, mirror_orch, neigh_orch, route_orch);
gAclOrch = new AclOrch(m_configDb, acl_tables, gPortsOrch, mirror_orch, neigh_orch, route_orch);

m_orchList = { switch_orch, gPortsOrch, intfs_orch, neigh_orch, route_orch, copp_orch, tunnel_decap_orch, qos_orch, buffer_orch, mirror_orch, acl_orch, gFdbOrch};
m_orchList = { switch_orch, gPortsOrch, intfs_orch, neigh_orch, route_orch, copp_orch, tunnel_decap_orch, qos_orch, buffer_orch, mirror_orch, gAclOrch, gFdbOrch};
m_select = new Select();

vector<string> pfc_wd_tables = {
Expand Down
90 changes: 88 additions & 2 deletions orchagent/pfcactionhandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#include "logger.h"
#include "saiserialize.h"
#include "portsorch.h"

#include <vector>

#define PFC_WD_QUEUE_STATUS "PFC_WD_STATUS"
Expand All @@ -17,6 +16,7 @@

extern sai_object_id_t gSwitchId;
extern PortsOrch *gPortsOrch;
extern AclOrch * gAclOrch;
extern sai_port_api_t *sai_port_api;
extern sai_queue_api_t *sai_queue_api;
extern sai_buffer_api_t *sai_buffer_api;
Expand All @@ -34,7 +34,7 @@ PfcWdActionHandler::PfcWdActionHandler(sai_object_id_t port, sai_object_id_t que
"PFC Watchdog detected PFC storm on queue 0x%lx port 0x%lx",
m_queue,
m_port);

m_stats = getQueueStats(m_countersTable, sai_serialize_object_id(m_queue));
m_stats.detectCount++;
m_stats.operational = false;
Expand Down Expand Up @@ -133,6 +133,92 @@ void PfcWdActionHandler::updateWdCounters(const string& queueIdStr, const PfcWdQ
m_countersTable->set(queueIdStr, resultFvValues);
}

PfcWdAclHandler::PfcWdAclHandler(sai_object_id_t port, sai_object_id_t queue,
uint8_t queueId, shared_ptr<Table> countersTable):
PfcWdActionHandler(port, queue, queueId, countersTable)
{
SWSS_LOG_ENTER();

acl_table_type_t table_type = ACL_TABLE_L3;

// There is one handler instance per queue ID
string queuestr = to_string(queueId);
m_strTable = "Table_PfcWdAclHandler_" + queuestr;
m_strRule = "Rule_PfcWdAclHandler_" + queuestr;

auto found = m_aclTables.find(m_strTable);
if (found == m_aclTables.end())
{
// First time of handling PFC for this queue, create ACL table, and bind
createPfcAclTable(port);
shared_ptr<AclRuleL3> newRule = make_shared<AclRuleL3>(gAclOrch, m_strRule, m_strTable, table_type);
createPfcAclRule(newRule, queueId);
}
else
{
// Otherwise just bind ACL table with the port
found->second.bind(port);
}
}

PfcWdAclHandler::~PfcWdAclHandler(void)
{
SWSS_LOG_ENTER();

auto found = m_aclTables.find(m_strTable);
found->second.unbind(getPort());
}

void PfcWdAclHandler::clear()
{
SWSS_LOG_ENTER();

for (auto& tablepair: m_aclTables)
{
auto& table = tablepair.second;
gAclOrch->removeAclTable(table.getId());
}
}

void PfcWdAclHandler::createPfcAclTable(sai_object_id_t port)
{
SWSS_LOG_ENTER();

auto inserted = m_aclTables.emplace(piecewise_construct,
std::forward_as_tuple(m_strTable),
std::forward_as_tuple());

assert(inserted.second);
AclTable& aclTable = inserted.first->second;
aclTable.type = ACL_TABLE_L3;
aclTable.link(port);
aclTable.id = m_strTable;
gAclOrch->addAclTable(aclTable, m_strTable);
}

void PfcWdAclHandler::createPfcAclRule(shared_ptr<AclRuleL3> rule, uint8_t queueId)
{
SWSS_LOG_ENTER();

string attr_name, attr_value;

attr_name = "RULE_PRIORITY";
attr_value = "999";
rule->validateAddPriority(attr_name, attr_value);

attr_name = "MATCH_TC";
attr_value = to_string(queueId);
rule->validateAddMatch(attr_name, attr_value);

attr_name = ACTION_PACKET_ACTION;
attr_value = PACKET_ACTION_DROP;
rule->validateAddAction(attr_name, attr_value);

gAclOrch->addAclRule(rule, m_strTable);
}

std::map<std::string, AclTable> PfcWdAclHandler::m_aclTables;

PfcWdLossyHandler::PfcWdLossyHandler(sai_object_id_t port, sai_object_id_t queue,
uint8_t queueId, shared_ptr<Table> countersTable):
PfcWdActionHandler(port, queue, queueId, countersTable)
Expand Down
21 changes: 20 additions & 1 deletion orchagent/pfcactionhandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#include <vector>
#include <memory>

#include "aclorch.h"
#include "table.h"

extern "C" {
Expand Down Expand Up @@ -60,6 +60,25 @@ class PfcWdActionHandler
PfcWdQueueStats m_stats;
};

class PfcWdAclHandler: public PfcWdActionHandler
{
public:
PfcWdAclHandler(sai_object_id_t port, sai_object_id_t queue,
uint8_t queueId, shared_ptr<Table> countersTable);
virtual ~PfcWdAclHandler(void);

// class shared cleanup
static void clear();
private:
// class shared dict: ACL table name -> ACL table
static std::map<std::string, AclTable> m_aclTables;

string m_strTable;
string m_strRule;
void createPfcAclTable(sai_object_id_t port);
void createPfcAclRule(shared_ptr<AclRuleL3> rule, uint8_t queueId);
};

// Pfc queue that implements forward action by disabling PFC on queue
class PfcWdLossyHandler: public PfcWdActionHandler
{
Expand Down
11 changes: 5 additions & 6 deletions orchagent/pfcwdorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ void PfcWdOrch<DropHandler, ForwardHandler>::createEntry(const string& key,
SWSS_LOG_ERROR("%s missing", PFC_WD_DETECTION_TIME);
return;
}

if (restorationTime == 0)
{
SWSS_LOG_ERROR("%s missing", PFC_WD_RESTORATION_TIME);
Expand Down Expand Up @@ -341,11 +341,10 @@ template <typename DropHandler, typename ForwardHandler>
PfcWdSwOrch<DropHandler, ForwardHandler>::PfcWdSwOrch(
DBConnector *db,
vector<string> &tableNames,
vector<sai_port_stat_t> portStatIds,
vector<sai_queue_stat_t> queueStatIds,
vector<sai_queue_attr_t> queueAttrIds):
PfcWdOrch<DropHandler,
ForwardHandler>(db, tableNames),
const vector<sai_port_stat_t> &portStatIds,
const vector<sai_queue_stat_t> &queueStatIds,
const vector<sai_queue_attr_t> &queueAttrIds):
PfcWdOrch<DropHandler, ForwardHandler>(db, tableNames),
m_pfcWdDb(new DBConnector(PFC_WD_DB, DBConnector::DEFAULT_UNIXSOCKET, 0)),
m_pfcWdTable(new ProducerStateTable(m_pfcWdDb.get(), PFC_WD_STATE_TABLE)),
c_portStatIds(portStatIds),
Expand Down
6 changes: 3 additions & 3 deletions orchagent/pfcwdorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ class PfcWdSwOrch: public PfcWdOrch<DropHandler, ForwardHandler>
PfcWdSwOrch(
DBConnector *db,
vector<string> &tableNames,
vector<sai_port_stat_t> portStatIds,
vector<sai_queue_stat_t> queueStatIds,
vector<sai_queue_attr_t> queueAttrIds);
const vector<sai_port_stat_t> &portStatIds,
const vector<sai_queue_stat_t> &queueStatIds,
const vector<sai_queue_attr_t> &queueAttrIds);
virtual ~PfcWdSwOrch(void);

virtual bool startWdOnPort(const Port& port,
Expand Down
4 changes: 2 additions & 2 deletions orchagent/port.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ sai_status_t Port::bindAclTable(sai_object_id_t& group_member_oid, sai_object_id
status = sai_port_api->set_port_attribute(m_port_id, &port_attr);
if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to bind port %s to ACL table group %lx, rv:%d",
m_alias.c_str(), groupOid, status);
SWSS_LOG_ERROR("Failed to bind port %lx(%s) to ACL table group %lx, rv:%d",
m_port_id, m_alias.c_str(), groupOid, status);
return status;
}

Expand Down

0 comments on commit d460103

Please sign in to comment.