Skip to content
207 changes: 167 additions & 40 deletions cfgmgr/coppmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,17 @@ void CoppMgr::setFeatureTrapIdsStatus(string feature, bool enable)

if (!enable)
{
m_coppDisabledTraps.insert(feature);
if (m_coppAlwaysEnabledTraps.find(feature) == m_coppAlwaysEnabledTraps.end())
{
m_coppDisabledTraps.insert(feature);
}
}
else
{
m_coppDisabledTraps.erase(feature);
if (m_coppDisabledTraps.find(feature) != m_coppDisabledTraps.end())
{
m_coppDisabledTraps.erase(feature);
}
}

/* Trap group moved to pending state when feature is disabled. Remove trap group
Expand Down Expand Up @@ -159,6 +165,7 @@ bool CoppMgr::isTrapIdDisabled(string trap_id)
}
return false;
}

void CoppMgr::mergeConfig(CoppCfg &init_cfg, CoppCfg &m_cfg, std::vector<std::string> &cfg_keys, Table &cfgTable)
{
/* Read the init configuration first. If the same key is present in
Expand Down Expand Up @@ -254,6 +261,7 @@ CoppMgr::CoppMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, c
{
std::vector<FieldValueTuple> feature_fvs;
m_cfgFeatureTable.get(i, feature_fvs);
m_featuresCfgTable.emplace(i, feature_fvs);

for (auto j: feature_fvs)
{
Expand All @@ -264,12 +272,37 @@ CoppMgr::CoppMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, c
}
}

/* If there is a trap that has always_enabled = true, remove it from the disabledTraps list */
for (auto trap: m_coppTrapInitCfg)
{
auto trap_name = trap.first;
auto trap_info = trap.second;
bool always_enabled = false;

if (std::find(trap_info.begin(), trap_info.end(), FieldValueTuple("always_enabled", "true")) != trap_info.end())
{
always_enabled = true;
m_coppAlwaysEnabledTraps.insert(trap_name);

if (std::find(m_coppDisabledTraps.begin(), m_coppDisabledTraps.end(), trap_name) != m_coppDisabledTraps.end())
{
m_coppDisabledTraps.erase(trap_name);
}
}
/* if trap has no feature entry and doesn't have the always_enabled:true field, add to disabledTraps list */
if (!(std::count(feature_keys.begin(), feature_keys.end(), trap_name)) && !always_enabled)
{
m_coppDisabledTraps.insert(trap_name);
}
}

mergeConfig(m_coppTrapInitCfg, trap_cfg, trap_cfg_keys, m_cfgCoppTrapTable);

for (auto i : trap_cfg)
{
string trap_group;
string trap_ids;
string is_always_enabled = "false";
std::vector<FieldValueTuple> trap_fvs = i.second;

for (auto j: trap_fvs)
Expand All @@ -282,13 +315,22 @@ CoppMgr::CoppMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, c
{
trap_group = fvValue(j);
}
else if (fvField(j) == COPP_ALWAYS_ENABLED_FIELD)
{
is_always_enabled = fvValue(j);
}
}

if (!trap_group.empty() && !trap_ids.empty())
{
addTrapIdsToTrapGroup(trap_group, trap_ids);
m_coppTrapConfMap[i.first].trap_group = trap_group;
m_coppTrapConfMap[i.first].trap_ids = trap_ids;
setCoppTrapStateOk(i.first);
m_coppTrapConfMap[i.first].is_always_enabled = is_always_enabled;
if (std::find(m_coppDisabledTraps.begin(), m_coppDisabledTraps.end(), i.first) == m_coppDisabledTraps.end())
{
setCoppTrapStateOk(i.first);
}
}
}

Expand All @@ -315,15 +357,18 @@ CoppMgr::CoppMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, c
trap_group_fvs.push_back(fv);
}

if (!trap_group_fvs.empty())
if (std::find(m_coppDisabledTraps.begin(), m_coppDisabledTraps.end(), i.first) == m_coppDisabledTraps.end())
{
m_appCoppTable.set(i.first, trap_group_fvs);
}
setCoppGroupStateOk(i.first);
auto g_cfg = std::find(group_cfg_keys.begin(), group_cfg_keys.end(), i.first);
if (g_cfg != group_cfg_keys.end())
{
g_copp_init_set.insert(i.first);
if (!trap_group_fvs.empty())
{
m_appCoppTable.set(i.first, trap_group_fvs);
}
setCoppGroupStateOk(i.first);
auto g_cfg = std::find(group_cfg_keys.begin(), group_cfg_keys.end(), i.first);
if (g_cfg != group_cfg_keys.end())
{
g_copp_init_set.insert(i.first);
}
}
}
}
Expand Down Expand Up @@ -406,6 +451,36 @@ void CoppMgr::getTrapGroupTrapIds(string trap_group, string &trap_ids)
}
}

void CoppMgr::removeTrap(std::string key)
{
std::string trap_ids;
std::vector<FieldValueTuple> fvs;
removeTrapIdsFromTrapGroup(m_coppTrapConfMap[key].trap_group, m_coppTrapConfMap[key].trap_ids);
getTrapGroupTrapIds(m_coppTrapConfMap[key].trap_group, trap_ids);
FieldValueTuple fv(COPP_TRAP_ID_LIST_FIELD, trap_ids);
fvs.push_back(fv);
if (!checkTrapGroupPending(m_coppTrapConfMap[key].trap_group))
{
m_appCoppTable.set(m_coppTrapConfMap[key].trap_group, fvs);
setCoppGroupStateOk(m_coppTrapConfMap[key].trap_group);
}
}

void CoppMgr::addTrap(std::string trap_ids, std::string trap_group)
{
string trap_group_trap_ids;
std::vector<FieldValueTuple> fvs;
addTrapIdsToTrapGroup(trap_group, trap_ids);
getTrapGroupTrapIds(trap_group, trap_group_trap_ids);
FieldValueTuple fv1(COPP_TRAP_ID_LIST_FIELD, trap_group_trap_ids);
fvs.push_back(fv1);
if (!checkTrapGroupPending(trap_group))
{
m_appCoppTable.set(trap_group, fvs);
setCoppGroupStateOk(trap_group);
}
}

void CoppMgr::doCoppTrapTask(Consumer &consumer)
{
auto it = consumer.m_toSync.begin();
Expand All @@ -418,12 +493,21 @@ void CoppMgr::doCoppTrapTask(Consumer &consumer)
vector<FieldValueTuple> fvs;
string trap_ids = "";
string trap_group = "";
string is_always_enabled = "";
bool conf_present = false;

if (m_coppTrapConfMap.find(key) != m_coppTrapConfMap.end())
{
trap_ids = m_coppTrapConfMap[key].trap_ids;
trap_group = m_coppTrapConfMap[key].trap_group;
if (m_coppTrapConfMap[key].is_always_enabled.empty())
{
is_always_enabled = "false";
}
else
{
is_always_enabled = m_coppTrapConfMap[key].is_always_enabled;
}
conf_present = true;
}

Expand All @@ -441,6 +525,10 @@ void CoppMgr::doCoppTrapTask(Consumer &consumer)
{
trap_ids = fvValue(i);
}
else if (fvField(i) == COPP_ALWAYS_ENABLED_FIELD)
{
is_always_enabled = fvValue(i);
}
else if (fvField(i) == "NULL")
{
null_cfg = true;
Expand All @@ -450,20 +538,8 @@ void CoppMgr::doCoppTrapTask(Consumer &consumer)
{
if (conf_present)
{
SWSS_LOG_DEBUG("Deleting trap key %s", key.c_str());
removeTrapIdsFromTrapGroup(m_coppTrapConfMap[key].trap_group,
m_coppTrapConfMap[key].trap_ids);
trap_ids.clear();
removeTrap(key);
setCoppTrapStateOk(key);
getTrapGroupTrapIds(m_coppTrapConfMap[key].trap_group, trap_ids);
fvs.clear();
FieldValueTuple fv(COPP_TRAP_ID_LIST_FIELD, trap_ids);
fvs.push_back(fv);
if (!checkTrapGroupPending(m_coppTrapConfMap[key].trap_group))
{
m_appCoppTable.set(m_coppTrapConfMap[key].trap_group, fvs);
setCoppGroupStateOk(m_coppTrapConfMap[key].trap_group);
}
m_coppTrapConfMap.erase(key);
}
it = consumer.m_toSync.erase(it);
Expand All @@ -472,11 +548,13 @@ void CoppMgr::doCoppTrapTask(Consumer &consumer)
/*Duplicate check*/
if (conf_present &&
(trap_group == m_coppTrapConfMap[key].trap_group) &&
(trap_ids == m_coppTrapConfMap[key].trap_ids))
(trap_ids == m_coppTrapConfMap[key].trap_ids) &&
(is_always_enabled == m_coppTrapConfMap[key].is_always_enabled))
{
it = consumer.m_toSync.erase(it);
continue;
}

/* Incomplete configuration. Do not process until both trap group
* and trap_ids are available
*/
Expand All @@ -485,33 +563,75 @@ void CoppMgr::doCoppTrapTask(Consumer &consumer)
it = consumer.m_toSync.erase(it);
continue;
}

/* if always_enabled field has been changed */
if (conf_present &&
(trap_group == m_coppTrapConfMap[key].trap_group) &&
(trap_ids == m_coppTrapConfMap[key].trap_ids))
{
std::vector<FieldValueTuple> feature_fvs;
if (is_always_enabled == "true")
{
/* if the value was changed from false to true,
if the trap is not installed, install it.
otherwise, do nothing. */

m_coppAlwaysEnabledTraps.insert(key);
if (m_coppTrapConfMap.find(key) == m_coppTrapConfMap.end())
{
addTrap(trap_ids, trap_group);
}
}
else
{
/* if the value was changed from true to false,
check if there is a feature enabled.
if no, remove the trap. is yes, do nothing. */
m_coppAlwaysEnabledTraps.erase(key);

if (m_featuresCfgTable.find(key) != m_featuresCfgTable.end())
{
bool isEnabled {false};
feature_fvs = m_featuresCfgTable[key];
for (auto i: feature_fvs)
{
if (fvField(i) == "state" && fvValue(i) == "enabled")
{
isEnabled = true;
it = consumer.m_toSync.erase(it);
continue;
}
}
if (isEnabled)
{
continue;
}
}

removeTrap(key);
delCoppTrapStateOk(key);
m_coppTrapConfMap.erase(key);
m_coppDisabledTraps.insert(key);
}
}

/* Remove the current trap IDs and add the new trap IDS to recompute the
* trap IDs for the trap group
* trap IDs for the trap group
*/
if (conf_present)
{
removeTrapIdsFromTrapGroup(m_coppTrapConfMap[key].trap_group,
m_coppTrapConfMap[key].trap_ids);
}
fvs.clear();
string trap_group_trap_ids;
addTrapIdsToTrapGroup(trap_group, trap_ids);
getTrapGroupTrapIds(trap_group, trap_group_trap_ids);
FieldValueTuple fv1(COPP_TRAP_ID_LIST_FIELD, trap_group_trap_ids);
fvs.push_back(fv1);
if (!checkTrapGroupPending(trap_group))
{
m_appCoppTable.set(trap_group, fvs);
setCoppGroupStateOk(trap_group);
}
addTrap(trap_ids, trap_group);

/* When the trap table's trap group is changed, the old trap group
* should also be reprogrammed as some of its associated traps got
* removed
*/
if (conf_present && (trap_group != m_coppTrapConfMap[key].trap_group))
{
trap_group_trap_ids.clear();
string trap_group_trap_ids;
fvs.clear();
getTrapGroupTrapIds(m_coppTrapConfMap[key].trap_group, trap_group_trap_ids);
FieldValueTuple fv2(COPP_TRAP_ID_LIST_FIELD, trap_group_trap_ids);
Expand All @@ -524,6 +644,7 @@ void CoppMgr::doCoppTrapTask(Consumer &consumer)
}
m_coppTrapConfMap[key].trap_group = trap_group;
m_coppTrapConfMap[key].trap_ids = trap_ids;
m_coppTrapConfMap[key].is_always_enabled = is_always_enabled;
setCoppTrapStateOk(key);
}
else if (op == DEL_COMMAND)
Expand All @@ -546,7 +667,7 @@ void CoppMgr::doCoppTrapTask(Consumer &consumer)
setCoppGroupStateOk(m_coppTrapConfMap[key].trap_group);
}
}
if (conf_present)
if (conf_present)
{
m_coppTrapConfMap.erase(key);
}
Expand All @@ -569,6 +690,10 @@ void CoppMgr::doCoppTrapTask(Consumer &consumer)
{
trap_ids = fvValue(i);
}
else if (fvField(i) == COPP_ALWAYS_ENABLED_FIELD)
{
is_always_enabled = fvValue(i);
}
}
vector<FieldValueTuple> g_fvs;
string trap_group_trap_ids;
Expand All @@ -583,6 +708,7 @@ void CoppMgr::doCoppTrapTask(Consumer &consumer)
}
m_coppTrapConfMap[key].trap_group = trap_group;
m_coppTrapConfMap[key].trap_ids = trap_ids;
m_coppTrapConfMap[key].is_always_enabled = is_always_enabled;
setCoppTrapStateOk(key);
}
}
Expand Down Expand Up @@ -706,6 +832,7 @@ void CoppMgr::doCoppGroupTask(Consumer &consumer)
}
}


void CoppMgr::doFeatureTask(Consumer &consumer)
{
auto it = consumer.m_toSync.begin();
Expand All @@ -715,11 +842,11 @@ void CoppMgr::doFeatureTask(Consumer &consumer)

string key = kfvKey(t);
string op = kfvOp(t);
vector<FieldValueTuple> fvs;
string trap_ids;

if (op == SET_COMMAND)
{
m_featuresCfgTable.emplace(key, kfvFieldsValues(t));
for (auto i : kfvFieldsValues(t))
{
if (fvField(i) == "state")
Expand Down
Loading