Skip to content

Commit b767ca2

Browse files
Sudharsan D.Gprsunny
Sudharsan D.G
authored andcommitted
Copp sflow changes (#1011)
* Copp sflow changes
1 parent 0917157 commit b767ca2

File tree

3 files changed

+257
-10
lines changed

3 files changed

+257
-10
lines changed

orchagent/copporch.cpp

+221-5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <inttypes.h>
88
#include <sstream>
99
#include <iostream>
10+
#include <algorithm>
1011

1112
using namespace swss;
1213
using namespace std;
@@ -90,14 +91,15 @@ const vector<sai_hostif_trap_type_t> default_trap_ids = {
9091
SAI_HOSTIF_TRAP_TYPE_TTL_ERROR
9192
};
9293

93-
CoppOrch::CoppOrch(DBConnector *db, string tableName) :
94-
Orch(db, tableName)
94+
CoppOrch::CoppOrch(vector<TableConnector> &tableConnectors) :
95+
Orch( tableConnectors)
9596
{
9697
SWSS_LOG_ENTER();
9798

9899
initDefaultHostIntfTable();
99100
initDefaultTrapGroup();
100101
initDefaultTrapIds();
102+
enable_sflow_trap = false;
101103
};
102104

103105
void CoppOrch::initDefaultHostIntfTable()
@@ -191,6 +193,60 @@ void CoppOrch::getTrapIdList(vector<string> &trap_id_name_list, vector<sai_hosti
191193
}
192194
}
193195

196+
bool CoppOrch::createGenetlinkHostIfTable(vector<string> &trap_id_name_list)
197+
{
198+
SWSS_LOG_ENTER();
199+
200+
vector<sai_hostif_trap_type_t> trap_id_list;
201+
202+
getTrapIdList(trap_id_name_list, trap_id_list);
203+
204+
for (auto trap_id : trap_id_list)
205+
{
206+
auto host_tbl_entry = m_trapid_hostif_table_map.find(trap_id);
207+
208+
if (host_tbl_entry == m_trapid_hostif_table_map.end())
209+
{
210+
sai_object_id_t trap_group_id = m_syncdTrapIds[trap_id].trap_group_obj;
211+
auto hostif_map = m_trap_group_hostif_map.find(trap_group_id);
212+
if (hostif_map != m_trap_group_hostif_map.end())
213+
{
214+
sai_object_id_t hostif_table_entry = SAI_NULL_OBJECT_ID;
215+
sai_attribute_t attr;
216+
vector<sai_attribute_t> sai_host_table_attr;
217+
218+
attr.id = SAI_HOSTIF_TABLE_ENTRY_ATTR_TYPE;
219+
attr.value.s32 = SAI_HOSTIF_TABLE_ENTRY_TYPE_TRAP_ID;
220+
sai_host_table_attr.push_back(attr);
221+
222+
attr.id = SAI_HOSTIF_TABLE_ENTRY_ATTR_TRAP_ID;
223+
attr.value.oid = m_syncdTrapIds[trap_id].trap_obj;
224+
sai_host_table_attr.push_back(attr);
225+
226+
attr.id = SAI_HOSTIF_TABLE_ENTRY_ATTR_CHANNEL_TYPE;
227+
attr.value.s32 = SAI_HOSTIF_TABLE_ENTRY_CHANNEL_TYPE_GENETLINK;
228+
sai_host_table_attr.push_back(attr);
229+
230+
attr.id = SAI_HOSTIF_TABLE_ENTRY_ATTR_HOST_IF;
231+
attr.value.oid = hostif_map->second;
232+
sai_host_table_attr.push_back(attr);
233+
234+
sai_status_t status = sai_hostif_api->create_hostif_table_entry(&hostif_table_entry,
235+
gSwitchId,
236+
(uint32_t)sai_host_table_attr.size(),
237+
sai_host_table_attr.data());
238+
if (status != SAI_STATUS_SUCCESS)
239+
{
240+
SWSS_LOG_ERROR("Failed to create hostif table entry failed, rv %d", status);
241+
return false;
242+
}
243+
m_trapid_hostif_table_map[trap_id] = hostif_table_entry;
244+
}
245+
}
246+
}
247+
return true;
248+
}
249+
194250
bool CoppOrch::applyAttributesToTrapIds(sai_object_id_t trap_group_id,
195251
const vector<sai_hostif_trap_type_t> &trap_id_list,
196252
vector<sai_attribute_t> &trap_id_attribs)
@@ -213,9 +269,9 @@ bool CoppOrch::applyAttributesToTrapIds(sai_object_id_t trap_group_id,
213269
SWSS_LOG_ERROR("Failed to create trap %d, rv:%d", trap_id, status);
214270
return false;
215271
}
216-
m_syncdTrapIds[trap_id] = trap_group_id;
272+
m_syncdTrapIds[trap_id].trap_group_obj = trap_group_id;
273+
m_syncdTrapIds[trap_id].trap_obj = hostif_trap_id;
217274
}
218-
219275
return true;
220276
}
221277

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

294+
238295
bool CoppOrch::removePolicer(string trap_group_name)
239296
{
240297
SWSS_LOG_ENTER();
@@ -321,6 +378,69 @@ bool CoppOrch::createPolicer(string trap_group_name, vector<sai_attribute_t> &po
321378
return true;
322379
}
323380

381+
bool CoppOrch::createGenetlinkHostIf(string trap_group_name, vector<sai_attribute_t> &genetlink_attribs)
382+
{
383+
SWSS_LOG_ENTER();
384+
385+
sai_object_id_t hostif_id;
386+
sai_status_t sai_status;
387+
388+
sai_status = sai_hostif_api->create_hostif(&hostif_id, gSwitchId,
389+
(uint32_t)genetlink_attribs.size(),
390+
genetlink_attribs.data());
391+
if (sai_status != SAI_STATUS_SUCCESS)
392+
{
393+
SWSS_LOG_ERROR("Failed to create genetlink hostif for trap group %s, rc=%d",
394+
trap_group_name.c_str(), sai_status);
395+
return false;
396+
}
397+
398+
m_trap_group_hostif_map[m_trap_group_map[trap_group_name]] = hostif_id;
399+
return true;
400+
}
401+
402+
bool CoppOrch::removeGenetlinkHostIf(string trap_group_name)
403+
{
404+
SWSS_LOG_ENTER();
405+
406+
sai_status_t sai_status;
407+
408+
for (auto it : m_syncdTrapIds)
409+
{
410+
if (it.second.trap_group_obj == m_trap_group_map[trap_group_name])
411+
{
412+
auto hostTableEntry = m_trapid_hostif_table_map.find(it.first);
413+
if (hostTableEntry != m_trapid_hostif_table_map.end())
414+
{
415+
sai_status = sai_hostif_api->remove_hostif_table_entry(hostTableEntry->second);
416+
if(sai_status != SAI_STATUS_SUCCESS)
417+
{
418+
SWSS_LOG_ERROR("Failed to delete hostif table entry %ld \
419+
on trap group %s. rc=%d", hostTableEntry->second,
420+
trap_group_name.c_str(), sai_status);
421+
return false;
422+
}
423+
m_trapid_hostif_table_map.erase(it.first);
424+
}
425+
}
426+
}
427+
428+
auto hostInfo = m_trap_group_hostif_map.find(m_trap_group_map[trap_group_name]);
429+
if(hostInfo != m_trap_group_hostif_map.end())
430+
{
431+
sai_status = sai_hostif_api->remove_hostif(hostInfo->second);
432+
if(sai_status != SAI_STATUS_SUCCESS)
433+
{
434+
SWSS_LOG_ERROR("Failed to delete host info %ld on trap group %s. rc=%d",
435+
hostInfo->second, trap_group_name.c_str(), sai_status);
436+
return false;
437+
}
438+
m_trap_group_hostif_map.erase(m_trap_group_map[trap_group_name]);
439+
}
440+
441+
return true;
442+
}
443+
324444
task_process_status CoppOrch::processCoppRule(Consumer& consumer)
325445
{
326446
SWSS_LOG_ENTER();
@@ -336,6 +456,7 @@ task_process_status CoppOrch::processCoppRule(Consumer& consumer)
336456
vector<sai_attribute_t> trap_gr_attribs;
337457
vector<sai_attribute_t> trap_id_attribs;
338458
vector<sai_attribute_t> policer_attribs;
459+
vector<sai_attribute_t> genetlink_attribs;
339460

340461
if (op == SET_COMMAND)
341462
{
@@ -346,6 +467,14 @@ task_process_status CoppOrch::processCoppRule(Consumer& consumer)
346467
if (fvField(*i) == copp_trap_id_list)
347468
{
348469
trap_id_list = tokenize(fvValue(*i), list_item_delimiter);
470+
auto it = std::find(trap_id_list.begin(), trap_id_list.end(), "sample_packet");
471+
if (it != trap_id_list.end())
472+
{
473+
if (!enable_sflow_trap)
474+
{
475+
return task_process_status::task_need_retry;
476+
}
477+
}
349478
}
350479
else if (fvField(*i) == copp_queue_field)
351480
{
@@ -443,6 +572,25 @@ task_process_status CoppOrch::processCoppRule(Consumer& consumer)
443572
attr.value.s32 = policer_action;
444573
policer_attribs.push_back(attr);
445574
}
575+
else if (fvField(*i) == copp_genetlink_name)
576+
{
577+
attr.id = SAI_HOSTIF_ATTR_TYPE;
578+
attr.value.s32 = SAI_HOSTIF_TYPE_GENETLINK;
579+
genetlink_attribs.push_back(attr);
580+
581+
attr.id = SAI_HOSTIF_ATTR_NAME;
582+
strncpy(attr.value.chardata, fvValue(*i).c_str(),
583+
sizeof(attr.value.chardata));
584+
genetlink_attribs.push_back(attr);
585+
586+
}
587+
else if (fvField(*i) == copp_genetlink_mcgrp_name)
588+
{
589+
attr.id = SAI_HOSTIF_ATTR_GENETLINK_MCGRP_NAME;
590+
strncpy(attr.value.chardata, fvValue(*i).c_str(),
591+
sizeof(attr.value.chardata));
592+
genetlink_attribs.push_back(attr);
593+
}
446594
else
447595
{
448596
SWSS_LOG_ERROR("Unknown copp field specified:%s\n", fvField(*i).c_str());
@@ -519,13 +667,29 @@ task_process_status CoppOrch::processCoppRule(Consumer& consumer)
519667
return task_process_status::task_failed;
520668
}
521669
}
670+
671+
if (!genetlink_attribs.empty())
672+
{
673+
if (!createGenetlinkHostIf(trap_group_name, genetlink_attribs))
674+
{
675+
return task_process_status::task_failed;
676+
}
677+
}
522678
}
523679

524680
/* Apply traps to trap group */
525681
if (!applyTrapIds(m_trap_group_map[trap_group_name], trap_id_list, trap_id_attribs))
526682
{
527683
return task_process_status::task_failed;
528684
}
685+
686+
if (!genetlink_attribs.empty())
687+
{
688+
if (!createGenetlinkHostIfTable(trap_id_list))
689+
{
690+
return task_process_status::task_failed;
691+
}
692+
}
529693
}
530694
else if (op == DEL_COMMAND)
531695
{
@@ -536,6 +700,12 @@ task_process_status CoppOrch::processCoppRule(Consumer& consumer)
536700
return task_process_status::task_failed;
537701
}
538702

703+
if (!removeGenetlinkHostIf(trap_group_name))
704+
{
705+
SWSS_LOG_ERROR("Failed to remove hostif from trap group %s", trap_group_name.c_str());
706+
return task_process_status::task_failed;
707+
}
708+
539709
/* Do not remove default trap group */
540710
if (trap_group_name == default_trap_group)
541711
{
@@ -547,10 +717,16 @@ task_process_status CoppOrch::processCoppRule(Consumer& consumer)
547717
vector<sai_hostif_trap_type_t> trap_ids_to_reset;
548718
for (auto it : m_syncdTrapIds)
549719
{
550-
if (it.second == m_trap_group_map[trap_group_name])
720+
if (it.second.trap_group_obj == m_trap_group_map[trap_group_name])
551721
{
552722
trap_ids_to_reset.push_back(it.first);
553723
}
724+
sai_status = sai_hostif_api->remove_hostif_trap(it.second.trap_obj);
725+
if (sai_status != SAI_STATUS_SUCCESS)
726+
{
727+
SWSS_LOG_ERROR("Failed to remove trap object %ld", it.second.trap_obj);
728+
return task_process_status::task_failed;
729+
}
554730
}
555731

556732
sai_attribute_t attr;
@@ -588,9 +764,49 @@ task_process_status CoppOrch::processCoppRule(Consumer& consumer)
588764
return task_process_status::task_success;
589765
}
590766

767+
/* Program Sflow trap once we get sflow enable command */
768+
void CoppOrch::coppProcessSflow(Consumer &consumer)
769+
{
770+
auto it = consumer.m_toSync.begin();
771+
772+
while (it != consumer.m_toSync.end())
773+
{
774+
auto tuple = it->second;
775+
string op = kfvOp(tuple);
776+
777+
/*
778+
* Need to handled just 'config sflow enable' command to install the sflow trap group
779+
* for the first time to ensure support of genetlink attributes. Rest of the fields or
780+
* disable value or DEL command are not required to be handled
781+
*
782+
*/
783+
if (op == SET_COMMAND)
784+
{
785+
for (auto i : kfvFieldsValues(tuple))
786+
{
787+
if (fvField(i) == "admin_state")
788+
{
789+
if (fvValue(i) == "up")
790+
{
791+
enable_sflow_trap = true;
792+
}
793+
}
794+
}
795+
}
796+
it = consumer.m_toSync.erase(it);
797+
}
798+
}
799+
591800
void CoppOrch::doTask(Consumer &consumer)
592801
{
593802
SWSS_LOG_ENTER();
803+
string table_name = consumer.getTableName();
804+
805+
if (table_name == CFG_SFLOW_TABLE_NAME)
806+
{
807+
coppProcessSflow(consumer);
808+
return;
809+
}
594810

595811
if (!gPortsOrch->allPortsReady())
596812
{

orchagent/copporch.h

+27-4
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,38 @@ const std::string copp_policer_action_green_field = "green_action";
2424
const std::string copp_policer_action_red_field = "red_action";
2525
const std::string copp_policer_action_yellow_field = "yellow_action";
2626

27+
// genetlink fields
28+
const std::string copp_genetlink_name = "genetlink_name";
29+
const std::string copp_genetlink_mcgrp_name = "genetlink_mcgrp_name";
30+
31+
struct copp_trap_objects
32+
{
33+
sai_object_id_t trap_obj;
34+
sai_object_id_t trap_group_obj;
35+
};
36+
2737
/* TrapGroupPolicerTable: trap group ID, policer ID */
2838
typedef std::map<sai_object_id_t, sai_object_id_t> TrapGroupPolicerTable;
29-
/* TrapIdTrapGroupTable: trap ID, trap group ID */
30-
typedef std::map<sai_hostif_trap_type_t, sai_object_id_t> TrapIdTrapGroupTable;
39+
/* TrapIdTrapObjectsTable: trap ID, copp trap objects */
40+
typedef std::map<sai_hostif_trap_type_t, copp_trap_objects> TrapIdTrapObjectsTable;
41+
/* TrapGroupHostIfMap: trap group ID, host interface ID */
42+
typedef std::map<sai_object_id_t, sai_object_id_t> TrapGroupHostIfMap;
43+
/* TrapIdHostIfTableMap: trap type, host table entry ID*/
44+
typedef std::map<sai_hostif_trap_type_t, sai_object_id_t> TrapIdHostIfTableMap;
3145

3246
class CoppOrch : public Orch
3347
{
3448
public:
35-
CoppOrch(swss::DBConnector *db, std::string tableName);
49+
CoppOrch(std::vector<TableConnector> &tableConnectors);
3650
protected:
3751
object_map m_trap_group_map;
52+
bool enable_sflow_trap;
3853

3954
TrapGroupPolicerTable m_trap_group_policer_map;
40-
TrapIdTrapGroupTable m_syncdTrapIds;
55+
TrapIdTrapObjectsTable m_syncdTrapIds;
56+
57+
TrapGroupHostIfMap m_trap_group_hostif_map;
58+
TrapIdHostIfTableMap m_trapid_hostif_table_map;
4159

4260
void initDefaultHostIntfTable();
4361
void initDefaultTrapGroup();
@@ -54,6 +72,11 @@ class CoppOrch : public Orch
5472

5573
sai_object_id_t getPolicer(std::string trap_group_name);
5674

75+
bool createGenetlinkHostIf(std::string trap_group_name, std::vector<sai_attribute_t> &hostif_attribs);
76+
bool removeGenetlinkHostIf(std::string trap_group_name);
77+
bool createGenetlinkHostIfTable(std::vector<std::string> &trap_id_name_list);
78+
void coppProcessSflow(Consumer& consumer);
79+
5780
virtual void doTask(Consumer& consumer);
5881
};
5982
#endif /* SWSS_COPPORCH_H */

0 commit comments

Comments
 (0)