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

[CoPP] Add always_enabled field to coppmgr logic #2034

Merged
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