Skip to content

Commit 36c5182

Browse files
committed
CoPP neighbor miss trap and enhancements
What I did * Added neighbor_miss trap type support * enum capability query for hostif trap type * Added trap hw_status field to state_db HLD: sonic-net/SONiC#1943 Signed-off-by: Ravi Minnikanti <[email protected]>
1 parent da11599 commit 36c5182

File tree

4 files changed

+235
-11
lines changed

4 files changed

+235
-11
lines changed

orchagent/copporch.cpp

+169-7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
extern "C" {
2+
#include <saiobject.h>
3+
#include <saistatus.h>
4+
#include <saiswitch.h>
5+
}
6+
17
#include "sai.h"
28
#include "copporch.h"
39
#include "portsorch.h"
@@ -89,9 +95,55 @@ static map<string, sai_hostif_trap_type_t> trap_id_map = {
8995
{"dest_nat_miss", SAI_HOSTIF_TRAP_TYPE_DNAT_MISS},
9096
{"ldp", SAI_HOSTIF_TRAP_TYPE_LDP},
9197
{"bfd_micro", SAI_HOSTIF_TRAP_TYPE_BFD_MICRO},
92-
{"bfdv6_micro", SAI_HOSTIF_TRAP_TYPE_BFDV6_MICRO}
98+
{"bfdv6_micro", SAI_HOSTIF_TRAP_TYPE_BFDV6_MICRO},
99+
{"neighbor_miss", SAI_HOSTIF_TRAP_TYPE_NEIGHBOR_MISS}
93100
};
94101

102+
const vector<sai_hostif_trap_type_t> default_supported_trap_ids = {
103+
SAI_HOSTIF_TRAP_TYPE_STP,
104+
SAI_HOSTIF_TRAP_TYPE_LACP,
105+
SAI_HOSTIF_TRAP_TYPE_EAPOL,
106+
SAI_HOSTIF_TRAP_TYPE_LLDP,
107+
SAI_HOSTIF_TRAP_TYPE_PVRST,
108+
SAI_HOSTIF_TRAP_TYPE_IGMP_TYPE_QUERY,
109+
SAI_HOSTIF_TRAP_TYPE_IGMP_TYPE_LEAVE,
110+
SAI_HOSTIF_TRAP_TYPE_IGMP_TYPE_V1_REPORT,
111+
SAI_HOSTIF_TRAP_TYPE_IGMP_TYPE_V2_REPORT,
112+
SAI_HOSTIF_TRAP_TYPE_IGMP_TYPE_V3_REPORT,
113+
SAI_HOSTIF_TRAP_TYPE_SAMPLEPACKET,
114+
SAI_HOSTIF_TRAP_TYPE_SWITCH_CUSTOM_RANGE_BASE,
115+
SAI_HOSTIF_TRAP_TYPE_ARP_REQUEST,
116+
SAI_HOSTIF_TRAP_TYPE_ARP_RESPONSE,
117+
SAI_HOSTIF_TRAP_TYPE_DHCP,
118+
SAI_HOSTIF_TRAP_TYPE_OSPF,
119+
SAI_HOSTIF_TRAP_TYPE_PIM,
120+
SAI_HOSTIF_TRAP_TYPE_VRRP,
121+
SAI_HOSTIF_TRAP_TYPE_BGP,
122+
SAI_HOSTIF_TRAP_TYPE_DHCPV6,
123+
SAI_HOSTIF_TRAP_TYPE_OSPFV6,
124+
SAI_HOSTIF_TRAP_TYPE_ISIS,
125+
SAI_HOSTIF_TRAP_TYPE_VRRPV6,
126+
SAI_HOSTIF_TRAP_TYPE_BGPV6,
127+
SAI_HOSTIF_TRAP_TYPE_IPV6_NEIGHBOR_DISCOVERY,
128+
SAI_HOSTIF_TRAP_TYPE_IPV6_MLD_V1_V2,
129+
SAI_HOSTIF_TRAP_TYPE_IPV6_MLD_V1_REPORT,
130+
SAI_HOSTIF_TRAP_TYPE_IPV6_MLD_V1_DONE,
131+
SAI_HOSTIF_TRAP_TYPE_MLD_V2_REPORT,
132+
SAI_HOSTIF_TRAP_TYPE_IP2ME,
133+
SAI_HOSTIF_TRAP_TYPE_SSH,
134+
SAI_HOSTIF_TRAP_TYPE_SNMP,
135+
SAI_HOSTIF_TRAP_TYPE_ROUTER_CUSTOM_RANGE_BASE,
136+
SAI_HOSTIF_TRAP_TYPE_L3_MTU_ERROR,
137+
SAI_HOSTIF_TRAP_TYPE_TTL_ERROR,
138+
SAI_HOSTIF_TRAP_TYPE_UDLD,
139+
SAI_HOSTIF_TRAP_TYPE_BFD,
140+
SAI_HOSTIF_TRAP_TYPE_BFDV6,
141+
SAI_HOSTIF_TRAP_TYPE_SNAT_MISS,
142+
SAI_HOSTIF_TRAP_TYPE_DNAT_MISS,
143+
SAI_HOSTIF_TRAP_TYPE_LDP,
144+
SAI_HOSTIF_TRAP_TYPE_BFD_MICRO,
145+
SAI_HOSTIF_TRAP_TYPE_BFDV6_MICRO
146+
};
95147

96148
std::string get_trap_name_by_type(sai_hostif_trap_type_t trap_type)
97149
{
@@ -104,7 +156,13 @@ std::string get_trap_name_by_type(sai_hostif_trap_type_t trap_type)
104156
}
105157
}
106158

107-
return trap_name_to_id_map.at(trap_type);
159+
auto it = trap_name_to_id_map.find(trap_type);
160+
if (it == trap_name_to_id_map.end())
161+
{
162+
return "";
163+
}
164+
165+
return it->second;
108166
}
109167

110168
static map<string, sai_packet_action_t> packet_action_map = {
@@ -122,27 +180,118 @@ const string default_trap_group = "default";
122180
const vector<sai_hostif_trap_type_t> default_trap_ids = {
123181
SAI_HOSTIF_TRAP_TYPE_TTL_ERROR
124182
};
183+
125184
const uint HOSTIF_TRAP_COUNTER_POLLING_INTERVAL_MS = 10000;
126185

127186
CoppOrch::CoppOrch(DBConnector* db, string tableName) :
128187
Orch(db, tableName),
129188
m_counter_db(std::shared_ptr<DBConnector>(new DBConnector("COUNTERS_DB", 0))),
130189
m_asic_db(std::shared_ptr<DBConnector>(new DBConnector("ASIC_DB", 0))),
190+
m_state_db(std::shared_ptr<DBConnector>(new DBConnector("STATE_DB", 0))),
131191
m_counter_table(std::unique_ptr<Table>(new Table(m_counter_db.get(), COUNTERS_TRAP_NAME_MAP))),
132192
m_vidToRidTable(std::unique_ptr<Table>(new Table(m_asic_db.get(), "VIDTORID"))),
133-
m_trap_counter_manager(HOSTIF_TRAP_COUNTER_FLEX_COUNTER_GROUP, StatsMode::READ, HOSTIF_TRAP_COUNTER_POLLING_INTERVAL_MS, false)
193+
m_trap_counter_manager(HOSTIF_TRAP_COUNTER_FLEX_COUNTER_GROUP, StatsMode::READ, HOSTIF_TRAP_COUNTER_POLLING_INTERVAL_MS, false),
194+
m_trapCapabilityTable(std::unique_ptr<Table>(new Table(m_state_db.get(), STATE_COPP_TRAP_CAPABILITY_TABLE_NAME))),
195+
m_trapTable(std::unique_ptr<Table>(new Table(m_state_db.get(), STATE_COPP_TRAP_TABLE_NAME)))
134196
{
135197
SWSS_LOG_ENTER();
136198
auto intervT = timespec { .tv_sec = FLEX_COUNTER_UPD_INTERVAL , .tv_nsec = 0 };
137199
m_FlexCounterUpdTimer = new SelectableTimer(intervT);
138200
auto executorT = new ExecutableTimer(m_FlexCounterUpdTimer, this, "FLEX_COUNTER_UPD_TIMER");
139201
Orch::addExecutor(executorT);
140202

203+
/* Query SAI for supported trap IDs and publish to STATE_DB */
204+
publishTrapIdsCapability();
205+
141206
initDefaultHostIntfTable();
142207
initDefaultTrapGroup();
143208
initDefaultTrapIds();
209+
144210
};
145211

212+
bool CoppOrch::isTrapIdSupported(sai_hostif_trap_type_t trap_id) const
213+
{
214+
return supported_trap_ids.find(trap_id) != supported_trap_ids.end();
215+
}
216+
217+
void CoppOrch::updateTrapOperStatus(sai_hostif_trap_type_t trap_type, const string& hw_status)
218+
{
219+
SWSS_LOG_ENTER();
220+
221+
string trap_name = get_trap_name_by_type(trap_type);
222+
if (trap_name.empty())
223+
{
224+
SWSS_LOG_ERROR("Failed to get trap name for type %d", trap_type);
225+
return;
226+
}
227+
228+
// Update or add the hw_status field in the table
229+
vector<FieldValueTuple> hwStatusFvs;
230+
hwStatusFvs.emplace_back("hw_status", hw_status);
231+
m_trapTable->set(trap_name, hwStatusFvs);
232+
}
233+
234+
// Query SAI for trap IDs capability and publish to the COPP_TRAP_CAPABILITY_TABLE
235+
void CoppOrch::publishTrapIdsCapability()
236+
{
237+
SWSS_LOG_ENTER();
238+
239+
sai_s32_list_t enum_values_capability;
240+
241+
supported_trap_ids.clear();
242+
243+
const auto* meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_HOSTIF_TRAP, SAI_HOSTIF_TRAP_ATTR_TRAP_TYPE);
244+
if (!meta || !meta->isenum)
245+
{
246+
SWSS_LOG_THROW("sai_metadata_get_attr_metadata for SAI_HOSTIF_TRAP_ATTR_TRAP_TYPE Failed");
247+
return;
248+
}
249+
250+
vector<int32_t> values_list(meta->enummetadata->valuescount);
251+
enum_values_capability.count = static_cast<uint32_t>(values_list.size());
252+
enum_values_capability.list = values_list.data();
253+
254+
sai_status_t status = sai_query_attribute_enum_values_capability(gSwitchId,
255+
SAI_OBJECT_TYPE_HOSTIF_TRAP,
256+
SAI_HOSTIF_TRAP_ATTR_TRAP_TYPE,
257+
&enum_values_capability);
258+
if (status != SAI_STATUS_SUCCESS)
259+
{
260+
SWSS_LOG_WARN("Failed to query trap id enum values capability"
261+
" from SAI_HOSTIF_TRAP_ATTR_TRAP_TYPE assuming set of pre-defined trap IDs as supported");
262+
// Populate enum_values_capability with default_supported_trap_ids
263+
enum_values_capability.count = static_cast<uint32_t>(default_supported_trap_ids.size());
264+
values_list.assign(default_supported_trap_ids.begin(), default_supported_trap_ids.end());
265+
enum_values_capability.list = values_list.data();
266+
}
267+
268+
string trap_id_list_str;
269+
270+
for (uint32_t i = 0; i < enum_values_capability.count; i++)
271+
{
272+
273+
auto trap_str = get_trap_name_by_type(static_cast<sai_hostif_trap_type_t>(enum_values_capability.list[i]));
274+
if (trap_str.empty())
275+
{
276+
SWSS_LOG_NOTICE("Unknown trap id enum value: %d", enum_values_capability.list[i]);
277+
continue;
278+
}
279+
280+
supported_trap_ids.insert(static_cast<sai_hostif_trap_type_t>(enum_values_capability.list[i]));
281+
282+
if (!trap_id_list_str.empty())
283+
{
284+
trap_id_list_str += ",";
285+
}
286+
trap_id_list_str += trap_str;
287+
}
288+
289+
SWSS_LOG_INFO("Publishing supported trap IDs to STATE_DB");
290+
vector<FieldValueTuple> trapCapabilityFvs;
291+
trapCapabilityFvs.push_back(FieldValueTuple("trap_ids", trap_id_list_str));
292+
m_trapCapabilityTable->set("traps", trapCapabilityFvs);
293+
}
294+
146295
void CoppOrch::initDefaultHostIntfTable()
147296
{
148297
SWSS_LOG_ENTER();
@@ -248,6 +397,14 @@ void CoppOrch::getTrapIdList(vector<string> &trap_id_name_list, vector<sai_hosti
248397
SWSS_LOG_NOTICE("Ignoring the trap_id: %s, as NAT is not supported", trap_id_str.c_str());
249398
continue;
250399
}
400+
401+
if (!isTrapIdSupported(trap_id))
402+
{
403+
/* If the trap_id is not in supported_trap_ids, ignore it */
404+
SWSS_LOG_NOTICE("Ignoring the trap_id: %s, since not supported by vendor SAI", trap_id_str.c_str());
405+
continue;
406+
}
407+
251408
trap_id_list.push_back(trap_id);
252409
}
253410
}
@@ -358,6 +515,8 @@ bool CoppOrch::applyAttributesToTrapIds(sai_object_id_t trap_group_id,
358515
return parseHandleSaiStatusFailure(handle_status);
359516
}
360517
}
518+
519+
updateTrapOperStatus(trap_id, "installed");
361520
m_syncdTrapIds[trap_id].trap_group_obj = trap_group_id;
362521
m_syncdTrapIds[trap_id].trap_obj = hostif_trap_id;
363522
m_syncdTrapIds[trap_id].trap_type = trap_id;
@@ -803,6 +962,7 @@ void CoppOrch::getTrapAddandRemoveList(string trap_group_name,
803962
{
804963

805964
vector<sai_hostif_trap_type_t> tmp_trap_ids = trap_ids;
965+
806966
if(m_trap_group_map.find(trap_group_name) == m_trap_group_map.end())
807967
{
808968
add_trap_ids = trap_ids;
@@ -867,7 +1027,7 @@ bool CoppOrch::trapGroupProcessTrapIdChange (string trap_group_name,
8671027
{
8681028
if (m_syncdTrapIds.find(i)!= m_syncdTrapIds.end())
8691029
{
870-
if (!removeTrap(m_syncdTrapIds[i].trap_obj))
1030+
if (!removeTrap(m_syncdTrapIds[i].trap_obj, i))
8711031
{
8721032
return false;
8731033
}
@@ -912,7 +1072,7 @@ bool CoppOrch::trapGroupProcessTrapIdChange (string trap_group_name,
9121072
*/
9131073
if (m_syncdTrapIds[i].trap_group_obj == m_trap_group_map[trap_group_name])
9141074
{
915-
if (!removeTrap(m_syncdTrapIds[i].trap_obj))
1075+
if (!removeTrap(m_syncdTrapIds[i].trap_obj, i))
9161076
{
9171077
return false;
9181078
}
@@ -956,7 +1116,7 @@ bool CoppOrch::processTrapGroupDel (string trap_group_name)
9561116
if (it.second.trap_group_obj == m_trap_group_map[trap_group_name])
9571117
{
9581118
trap_ids_to_reset.push_back(it.first);
959-
if (!removeTrap(it.second.trap_obj))
1119+
if (!removeTrap(it.second.trap_obj, it.first))
9601120
{
9611121
return false;
9621122
}
@@ -1227,7 +1387,7 @@ void CoppOrch::initTrapRatePlugin()
12271387
m_trap_rate_plugin_loaded = true;
12281388
}
12291389

1230-
bool CoppOrch::removeTrap(sai_object_id_t hostif_trap_id)
1390+
bool CoppOrch::removeTrap(sai_object_id_t hostif_trap_id, sai_hostif_trap_type_t trap_type)
12311391
{
12321392
unbindTrapCounter(hostif_trap_id);
12331393

@@ -1242,6 +1402,8 @@ bool CoppOrch::removeTrap(sai_object_id_t hostif_trap_id)
12421402
return parseHandleSaiStatusFailure(handle_status);
12431403
}
12441404
}
1405+
1406+
updateTrapOperStatus(trap_type, "not-installed");
12451407

12461408
return true;
12471409
}

orchagent/copporch.h

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
#ifndef SWSS_COPPORCH_H
22
#define SWSS_COPPORCH_H
33

4+
extern "C" {
5+
#include <saiobject.h>
6+
#include <saistatus.h>
7+
#include <saiswitch.h>
8+
}
9+
410
#include <map>
511
#include <set>
612
#include <memory>
13+
#include <unordered_set>
714
#include "dbconnector.h"
815
#include "orch.h"
916
#include "flex_counter_manager.h"
@@ -99,8 +106,13 @@ class CoppOrch : public Orch
99106

100107
std::shared_ptr<DBConnector> m_counter_db;
101108
std::shared_ptr<DBConnector> m_asic_db;
109+
std::shared_ptr<DBConnector> m_state_db;
102110
std::unique_ptr<Table> m_counter_table;
103111
std::unique_ptr<Table> m_vidToRidTable;
112+
std::unique_ptr<Table> m_trapCapabilityTable;
113+
std::unique_ptr<Table> m_trapTable;
114+
115+
std::unordered_set<sai_hostif_trap_type_t> supported_trap_ids;
104116

105117
FlexCounterManager m_trap_counter_manager;
106118

@@ -112,6 +124,9 @@ class CoppOrch : public Orch
112124
void initDefaultTrapGroup();
113125
void initDefaultTrapIds();
114126
void initTrapRatePlugin();
127+
bool isTrapIdSupported(sai_hostif_trap_type_t trap_id) const;
128+
void updateTrapOperStatus(sai_hostif_trap_type_t trap_type, const std::string& hw_status);
129+
void publishTrapIdsCapability();
115130

116131
task_process_status processCoppRule(Consumer& consumer);
117132
bool isValidList(std::vector<std::string> &trap_id_list, std::vector<std::string> &all_items) const;
@@ -148,7 +163,7 @@ class CoppOrch : public Orch
148163

149164
bool trapGroupUpdatePolicer (std::string trap_group_name, std::vector<sai_attribute_t> &policer_attribs);
150165

151-
bool removeTrap(sai_object_id_t hostif_trap_id);
166+
bool removeTrap(sai_object_id_t hostif_trap_id, sai_hostif_trap_type_t trap_type);
152167

153168
bool bindTrapCounter(sai_object_id_t hostif_trap_id, sai_hostif_trap_type_t trap_type);
154169
void unbindTrapCounter(sai_object_id_t hostif_trap_id);

orchagent/debugcounterorch.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ void DebugCounterOrch::doTask(Consumer& consumer)
227227

228228
// publishDropCounterCapabilities queries the SAI for available drop counter
229229
// capabilities on this device and publishes the information to the
230-
// DROP_COUNTER_CAPABILITIES table in STATE_DB.
230+
// DEBUG_COUNTER_CAPABILITIES table in STATE_DB.
231231
void DebugCounterOrch::publishDropCounterCapabilities()
232232
{
233233
supported_ingress_drop_reasons = DropCounter::getSupportedDropReasons(SAI_DEBUG_COUNTER_ATTR_IN_DROP_REASON_LIST);

0 commit comments

Comments
 (0)