Skip to content

Commit

Permalink
Copp sflow changes (sonic-net#1011)
Browse files Browse the repository at this point in the history
* Copp sflow changes
  • Loading branch information
Sudharsan D.G authored and prsunny committed Oct 28, 2019
1 parent 0917157 commit b767ca2
Show file tree
Hide file tree
Showing 3 changed files with 257 additions and 10 deletions.
226 changes: 221 additions & 5 deletions orchagent/copporch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <inttypes.h>
#include <sstream>
#include <iostream>
#include <algorithm>

using namespace swss;
using namespace std;
Expand Down Expand Up @@ -90,14 +91,15 @@ const vector<sai_hostif_trap_type_t> default_trap_ids = {
SAI_HOSTIF_TRAP_TYPE_TTL_ERROR
};

CoppOrch::CoppOrch(DBConnector *db, string tableName) :
Orch(db, tableName)
CoppOrch::CoppOrch(vector<TableConnector> &tableConnectors) :
Orch( tableConnectors)
{
SWSS_LOG_ENTER();

initDefaultHostIntfTable();
initDefaultTrapGroup();
initDefaultTrapIds();
enable_sflow_trap = false;
};

void CoppOrch::initDefaultHostIntfTable()
Expand Down Expand Up @@ -191,6 +193,60 @@ void CoppOrch::getTrapIdList(vector<string> &trap_id_name_list, vector<sai_hosti
}
}

bool CoppOrch::createGenetlinkHostIfTable(vector<string> &trap_id_name_list)
{
SWSS_LOG_ENTER();

vector<sai_hostif_trap_type_t> trap_id_list;

getTrapIdList(trap_id_name_list, trap_id_list);

for (auto trap_id : trap_id_list)
{
auto host_tbl_entry = m_trapid_hostif_table_map.find(trap_id);

if (host_tbl_entry == m_trapid_hostif_table_map.end())
{
sai_object_id_t trap_group_id = m_syncdTrapIds[trap_id].trap_group_obj;
auto hostif_map = m_trap_group_hostif_map.find(trap_group_id);
if (hostif_map != m_trap_group_hostif_map.end())
{
sai_object_id_t hostif_table_entry = SAI_NULL_OBJECT_ID;
sai_attribute_t attr;
vector<sai_attribute_t> sai_host_table_attr;

attr.id = SAI_HOSTIF_TABLE_ENTRY_ATTR_TYPE;
attr.value.s32 = SAI_HOSTIF_TABLE_ENTRY_TYPE_TRAP_ID;
sai_host_table_attr.push_back(attr);

attr.id = SAI_HOSTIF_TABLE_ENTRY_ATTR_TRAP_ID;
attr.value.oid = m_syncdTrapIds[trap_id].trap_obj;
sai_host_table_attr.push_back(attr);

attr.id = SAI_HOSTIF_TABLE_ENTRY_ATTR_CHANNEL_TYPE;
attr.value.s32 = SAI_HOSTIF_TABLE_ENTRY_CHANNEL_TYPE_GENETLINK;
sai_host_table_attr.push_back(attr);

attr.id = SAI_HOSTIF_TABLE_ENTRY_ATTR_HOST_IF;
attr.value.oid = hostif_map->second;
sai_host_table_attr.push_back(attr);

sai_status_t status = sai_hostif_api->create_hostif_table_entry(&hostif_table_entry,
gSwitchId,
(uint32_t)sai_host_table_attr.size(),
sai_host_table_attr.data());
if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to create hostif table entry failed, rv %d", status);
return false;
}
m_trapid_hostif_table_map[trap_id] = hostif_table_entry;
}
}
}
return true;
}

bool CoppOrch::applyAttributesToTrapIds(sai_object_id_t trap_group_id,
const vector<sai_hostif_trap_type_t> &trap_id_list,
vector<sai_attribute_t> &trap_id_attribs)
Expand All @@ -213,9 +269,9 @@ bool CoppOrch::applyAttributesToTrapIds(sai_object_id_t trap_group_id,
SWSS_LOG_ERROR("Failed to create trap %d, rv:%d", trap_id, status);
return false;
}
m_syncdTrapIds[trap_id] = trap_group_id;
m_syncdTrapIds[trap_id].trap_group_obj = trap_group_id;
m_syncdTrapIds[trap_id].trap_obj = hostif_trap_id;
}

return true;
}

Expand All @@ -235,6 +291,7 @@ bool CoppOrch::applyTrapIds(sai_object_id_t trap_group, vector<string> &trap_id_
return applyAttributesToTrapIds(trap_group, trap_id_list, trap_id_attribs);
}


bool CoppOrch::removePolicer(string trap_group_name)
{
SWSS_LOG_ENTER();
Expand Down Expand Up @@ -321,6 +378,69 @@ bool CoppOrch::createPolicer(string trap_group_name, vector<sai_attribute_t> &po
return true;
}

bool CoppOrch::createGenetlinkHostIf(string trap_group_name, vector<sai_attribute_t> &genetlink_attribs)
{
SWSS_LOG_ENTER();

sai_object_id_t hostif_id;
sai_status_t sai_status;

sai_status = sai_hostif_api->create_hostif(&hostif_id, gSwitchId,
(uint32_t)genetlink_attribs.size(),
genetlink_attribs.data());
if (sai_status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to create genetlink hostif for trap group %s, rc=%d",
trap_group_name.c_str(), sai_status);
return false;
}

m_trap_group_hostif_map[m_trap_group_map[trap_group_name]] = hostif_id;
return true;
}

bool CoppOrch::removeGenetlinkHostIf(string trap_group_name)
{
SWSS_LOG_ENTER();

sai_status_t sai_status;

for (auto it : m_syncdTrapIds)
{
if (it.second.trap_group_obj == m_trap_group_map[trap_group_name])
{
auto hostTableEntry = m_trapid_hostif_table_map.find(it.first);
if (hostTableEntry != m_trapid_hostif_table_map.end())
{
sai_status = sai_hostif_api->remove_hostif_table_entry(hostTableEntry->second);
if(sai_status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to delete hostif table entry %ld \
on trap group %s. rc=%d", hostTableEntry->second,
trap_group_name.c_str(), sai_status);
return false;
}
m_trapid_hostif_table_map.erase(it.first);
}
}
}

auto hostInfo = m_trap_group_hostif_map.find(m_trap_group_map[trap_group_name]);
if(hostInfo != m_trap_group_hostif_map.end())
{
sai_status = sai_hostif_api->remove_hostif(hostInfo->second);
if(sai_status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to delete host info %ld on trap group %s. rc=%d",
hostInfo->second, trap_group_name.c_str(), sai_status);
return false;
}
m_trap_group_hostif_map.erase(m_trap_group_map[trap_group_name]);
}

return true;
}

task_process_status CoppOrch::processCoppRule(Consumer& consumer)
{
SWSS_LOG_ENTER();
Expand All @@ -336,6 +456,7 @@ task_process_status CoppOrch::processCoppRule(Consumer& consumer)
vector<sai_attribute_t> trap_gr_attribs;
vector<sai_attribute_t> trap_id_attribs;
vector<sai_attribute_t> policer_attribs;
vector<sai_attribute_t> genetlink_attribs;

if (op == SET_COMMAND)
{
Expand All @@ -346,6 +467,14 @@ task_process_status CoppOrch::processCoppRule(Consumer& consumer)
if (fvField(*i) == copp_trap_id_list)
{
trap_id_list = tokenize(fvValue(*i), list_item_delimiter);
auto it = std::find(trap_id_list.begin(), trap_id_list.end(), "sample_packet");
if (it != trap_id_list.end())
{
if (!enable_sflow_trap)
{
return task_process_status::task_need_retry;
}
}
}
else if (fvField(*i) == copp_queue_field)
{
Expand Down Expand Up @@ -443,6 +572,25 @@ task_process_status CoppOrch::processCoppRule(Consumer& consumer)
attr.value.s32 = policer_action;
policer_attribs.push_back(attr);
}
else if (fvField(*i) == copp_genetlink_name)
{
attr.id = SAI_HOSTIF_ATTR_TYPE;
attr.value.s32 = SAI_HOSTIF_TYPE_GENETLINK;
genetlink_attribs.push_back(attr);

attr.id = SAI_HOSTIF_ATTR_NAME;
strncpy(attr.value.chardata, fvValue(*i).c_str(),
sizeof(attr.value.chardata));
genetlink_attribs.push_back(attr);

}
else if (fvField(*i) == copp_genetlink_mcgrp_name)
{
attr.id = SAI_HOSTIF_ATTR_GENETLINK_MCGRP_NAME;
strncpy(attr.value.chardata, fvValue(*i).c_str(),
sizeof(attr.value.chardata));
genetlink_attribs.push_back(attr);
}
else
{
SWSS_LOG_ERROR("Unknown copp field specified:%s\n", fvField(*i).c_str());
Expand Down Expand Up @@ -519,13 +667,29 @@ task_process_status CoppOrch::processCoppRule(Consumer& consumer)
return task_process_status::task_failed;
}
}

if (!genetlink_attribs.empty())
{
if (!createGenetlinkHostIf(trap_group_name, genetlink_attribs))
{
return task_process_status::task_failed;
}
}
}

/* Apply traps to trap group */
if (!applyTrapIds(m_trap_group_map[trap_group_name], trap_id_list, trap_id_attribs))
{
return task_process_status::task_failed;
}

if (!genetlink_attribs.empty())
{
if (!createGenetlinkHostIfTable(trap_id_list))
{
return task_process_status::task_failed;
}
}
}
else if (op == DEL_COMMAND)
{
Expand All @@ -536,6 +700,12 @@ task_process_status CoppOrch::processCoppRule(Consumer& consumer)
return task_process_status::task_failed;
}

if (!removeGenetlinkHostIf(trap_group_name))
{
SWSS_LOG_ERROR("Failed to remove hostif from trap group %s", trap_group_name.c_str());
return task_process_status::task_failed;
}

/* Do not remove default trap group */
if (trap_group_name == default_trap_group)
{
Expand All @@ -547,10 +717,16 @@ task_process_status CoppOrch::processCoppRule(Consumer& consumer)
vector<sai_hostif_trap_type_t> trap_ids_to_reset;
for (auto it : m_syncdTrapIds)
{
if (it.second == m_trap_group_map[trap_group_name])
if (it.second.trap_group_obj == m_trap_group_map[trap_group_name])
{
trap_ids_to_reset.push_back(it.first);
}
sai_status = sai_hostif_api->remove_hostif_trap(it.second.trap_obj);
if (sai_status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to remove trap object %ld", it.second.trap_obj);
return task_process_status::task_failed;
}
}

sai_attribute_t attr;
Expand Down Expand Up @@ -588,9 +764,49 @@ task_process_status CoppOrch::processCoppRule(Consumer& consumer)
return task_process_status::task_success;
}

/* Program Sflow trap once we get sflow enable command */
void CoppOrch::coppProcessSflow(Consumer &consumer)
{
auto it = consumer.m_toSync.begin();

while (it != consumer.m_toSync.end())
{
auto tuple = it->second;
string op = kfvOp(tuple);

/*
* Need to handled just 'config sflow enable' command to install the sflow trap group
* for the first time to ensure support of genetlink attributes. Rest of the fields or
* disable value or DEL command are not required to be handled
*
*/
if (op == SET_COMMAND)
{
for (auto i : kfvFieldsValues(tuple))
{
if (fvField(i) == "admin_state")
{
if (fvValue(i) == "up")
{
enable_sflow_trap = true;
}
}
}
}
it = consumer.m_toSync.erase(it);
}
}

void CoppOrch::doTask(Consumer &consumer)
{
SWSS_LOG_ENTER();
string table_name = consumer.getTableName();

if (table_name == CFG_SFLOW_TABLE_NAME)
{
coppProcessSflow(consumer);
return;
}

if (!gPortsOrch->allPortsReady())
{
Expand Down
31 changes: 27 additions & 4 deletions orchagent/copporch.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,38 @@ const std::string copp_policer_action_green_field = "green_action";
const std::string copp_policer_action_red_field = "red_action";
const std::string copp_policer_action_yellow_field = "yellow_action";

// genetlink fields
const std::string copp_genetlink_name = "genetlink_name";
const std::string copp_genetlink_mcgrp_name = "genetlink_mcgrp_name";

struct copp_trap_objects
{
sai_object_id_t trap_obj;
sai_object_id_t trap_group_obj;
};

/* TrapGroupPolicerTable: trap group ID, policer ID */
typedef std::map<sai_object_id_t, sai_object_id_t> TrapGroupPolicerTable;
/* TrapIdTrapGroupTable: trap ID, trap group ID */
typedef std::map<sai_hostif_trap_type_t, sai_object_id_t> TrapIdTrapGroupTable;
/* TrapIdTrapObjectsTable: trap ID, copp trap objects */
typedef std::map<sai_hostif_trap_type_t, copp_trap_objects> TrapIdTrapObjectsTable;
/* TrapGroupHostIfMap: trap group ID, host interface ID */
typedef std::map<sai_object_id_t, sai_object_id_t> TrapGroupHostIfMap;
/* TrapIdHostIfTableMap: trap type, host table entry ID*/
typedef std::map<sai_hostif_trap_type_t, sai_object_id_t> TrapIdHostIfTableMap;

class CoppOrch : public Orch
{
public:
CoppOrch(swss::DBConnector *db, std::string tableName);
CoppOrch(std::vector<TableConnector> &tableConnectors);
protected:
object_map m_trap_group_map;
bool enable_sflow_trap;

TrapGroupPolicerTable m_trap_group_policer_map;
TrapIdTrapGroupTable m_syncdTrapIds;
TrapIdTrapObjectsTable m_syncdTrapIds;

TrapGroupHostIfMap m_trap_group_hostif_map;
TrapIdHostIfTableMap m_trapid_hostif_table_map;

void initDefaultHostIntfTable();
void initDefaultTrapGroup();
Expand All @@ -54,6 +72,11 @@ class CoppOrch : public Orch

sai_object_id_t getPolicer(std::string trap_group_name);

bool createGenetlinkHostIf(std::string trap_group_name, std::vector<sai_attribute_t> &hostif_attribs);
bool removeGenetlinkHostIf(std::string trap_group_name);
bool createGenetlinkHostIfTable(std::vector<std::string> &trap_id_name_list);
void coppProcessSflow(Consumer& consumer);

virtual void doTask(Consumer& consumer);
};
#endif /* SWSS_COPPORCH_H */
Expand Down
Loading

0 comments on commit b767ca2

Please sign in to comment.