1
+ extern " C" {
2
+ #include < saiobject.h>
3
+ #include < saistatus.h>
4
+ #include < saiswitch.h>
5
+ }
6
+
1
7
#include " sai.h"
2
8
#include " copporch.h"
3
9
#include " portsorch.h"
@@ -89,9 +95,55 @@ static map<string, sai_hostif_trap_type_t> trap_id_map = {
89
95
{" dest_nat_miss" , SAI_HOSTIF_TRAP_TYPE_DNAT_MISS},
90
96
{" ldp" , SAI_HOSTIF_TRAP_TYPE_LDP},
91
97
{" 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}
93
100
};
94
101
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
+ };
95
147
96
148
std::string get_trap_name_by_type (sai_hostif_trap_type_t trap_type)
97
149
{
@@ -104,7 +156,13 @@ std::string get_trap_name_by_type(sai_hostif_trap_type_t trap_type)
104
156
}
105
157
}
106
158
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 ;
108
166
}
109
167
110
168
static map<string, sai_packet_action_t > packet_action_map = {
@@ -122,27 +180,118 @@ const string default_trap_group = "default";
122
180
const vector<sai_hostif_trap_type_t > default_trap_ids = {
123
181
SAI_HOSTIF_TRAP_TYPE_TTL_ERROR
124
182
};
183
+
125
184
const uint HOSTIF_TRAP_COUNTER_POLLING_INTERVAL_MS = 10000 ;
126
185
127
186
CoppOrch::CoppOrch (DBConnector* db, string tableName) :
128
187
Orch(db, tableName),
129
188
m_counter_db(std::shared_ptr<DBConnector>(new DBConnector(" COUNTERS_DB" , 0 ))),
130
189
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 ))),
131
191
m_counter_table(std::unique_ptr<Table>(new Table(m_counter_db.get(), COUNTERS_TRAP_NAME_MAP))),
132
192
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)))
134
196
{
135
197
SWSS_LOG_ENTER ();
136
198
auto intervT = timespec { .tv_sec = FLEX_COUNTER_UPD_INTERVAL , .tv_nsec = 0 };
137
199
m_FlexCounterUpdTimer = new SelectableTimer (intervT);
138
200
auto executorT = new ExecutableTimer (m_FlexCounterUpdTimer, this , " FLEX_COUNTER_UPD_TIMER" );
139
201
Orch::addExecutor (executorT);
140
202
203
+ /* Query SAI for supported trap IDs and publish to STATE_DB */
204
+ publishTrapIdsCapability ();
205
+
141
206
initDefaultHostIntfTable ();
142
207
initDefaultTrapGroup ();
143
208
initDefaultTrapIds ();
209
+
144
210
};
145
211
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
+
146
295
void CoppOrch::initDefaultHostIntfTable ()
147
296
{
148
297
SWSS_LOG_ENTER ();
@@ -248,6 +397,14 @@ void CoppOrch::getTrapIdList(vector<string> &trap_id_name_list, vector<sai_hosti
248
397
SWSS_LOG_NOTICE (" Ignoring the trap_id: %s, as NAT is not supported" , trap_id_str.c_str ());
249
398
continue ;
250
399
}
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
+
251
408
trap_id_list.push_back (trap_id);
252
409
}
253
410
}
@@ -358,6 +515,8 @@ bool CoppOrch::applyAttributesToTrapIds(sai_object_id_t trap_group_id,
358
515
return parseHandleSaiStatusFailure (handle_status);
359
516
}
360
517
}
518
+
519
+ updateTrapOperStatus (trap_id, " installed" );
361
520
m_syncdTrapIds[trap_id].trap_group_obj = trap_group_id;
362
521
m_syncdTrapIds[trap_id].trap_obj = hostif_trap_id;
363
522
m_syncdTrapIds[trap_id].trap_type = trap_id;
@@ -803,6 +962,7 @@ void CoppOrch::getTrapAddandRemoveList(string trap_group_name,
803
962
{
804
963
805
964
vector<sai_hostif_trap_type_t > tmp_trap_ids = trap_ids;
965
+
806
966
if (m_trap_group_map.find (trap_group_name) == m_trap_group_map.end ())
807
967
{
808
968
add_trap_ids = trap_ids;
@@ -867,7 +1027,7 @@ bool CoppOrch::trapGroupProcessTrapIdChange (string trap_group_name,
867
1027
{
868
1028
if (m_syncdTrapIds.find (i)!= m_syncdTrapIds.end ())
869
1029
{
870
- if (!removeTrap (m_syncdTrapIds[i].trap_obj ))
1030
+ if (!removeTrap (m_syncdTrapIds[i].trap_obj , i ))
871
1031
{
872
1032
return false ;
873
1033
}
@@ -912,7 +1072,7 @@ bool CoppOrch::trapGroupProcessTrapIdChange (string trap_group_name,
912
1072
*/
913
1073
if (m_syncdTrapIds[i].trap_group_obj == m_trap_group_map[trap_group_name])
914
1074
{
915
- if (!removeTrap (m_syncdTrapIds[i].trap_obj ))
1075
+ if (!removeTrap (m_syncdTrapIds[i].trap_obj , i ))
916
1076
{
917
1077
return false ;
918
1078
}
@@ -956,7 +1116,7 @@ bool CoppOrch::processTrapGroupDel (string trap_group_name)
956
1116
if (it.second .trap_group_obj == m_trap_group_map[trap_group_name])
957
1117
{
958
1118
trap_ids_to_reset.push_back (it.first );
959
- if (!removeTrap (it.second .trap_obj ))
1119
+ if (!removeTrap (it.second .trap_obj , it. first ))
960
1120
{
961
1121
return false ;
962
1122
}
@@ -1227,7 +1387,7 @@ void CoppOrch::initTrapRatePlugin()
1227
1387
m_trap_rate_plugin_loaded = true ;
1228
1388
}
1229
1389
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 )
1231
1391
{
1232
1392
unbindTrapCounter (hostif_trap_id);
1233
1393
@@ -1242,6 +1402,8 @@ bool CoppOrch::removeTrap(sai_object_id_t hostif_trap_id)
1242
1402
return parseHandleSaiStatusFailure (handle_status);
1243
1403
}
1244
1404
}
1405
+
1406
+ updateTrapOperStatus (trap_type, " not-installed" );
1245
1407
1246
1408
return true ;
1247
1409
}
0 commit comments