Skip to content

Commit bc55d4a

Browse files
daalllguohan
authored andcommitted
[debugcounterorch] Add checks for supported counter types and drop reasons (sonic-net#1173)
- Refactor drop reason capability query to trim SAI prefixes - Store device capabilities in orchagent to perform safety checks Fixes sonic-net#1136 - Rather than depending on each ASIC vendor to follow the same error handling doctrine, this PR validates HW support in orchagent, which should be more reliable. Related to sonic-net/sonic-utilities#785 - In order to validate user input, we need to remove the SAI prefixes before we store the results. This removes the need for the CLI to perform these checks. Signed-off-by: Danny Allen <[email protected]>
1 parent 4edcc4d commit bc55d4a

File tree

4 files changed

+61
-25
lines changed

4 files changed

+61
-25
lines changed

orchagent/debug_counter/drop_counter.cpp

+12-5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include "logger.h"
44
#include "sai_serialize.h"
55

6+
#include <vector>
7+
68
using std::runtime_error;
79
using std::string;
810
using std::unordered_map;
@@ -12,6 +14,9 @@ using std::vector;
1214
extern sai_object_id_t gSwitchId;
1315
extern sai_debug_counter_api_t *sai_debug_counter_api;
1416

17+
#define INGRESS_DROP_REASON_PREFIX_LENGTH 19 // "SAI_IN_DROP_REASON_"
18+
#define EGRESS_DROP_REASON_PREFIX_LENGTH 20 // "SAI_OUT_DROP_REASON_"
19+
1520
const unordered_map<string, sai_in_drop_reason_t> DropCounter::ingress_drop_reason_lookup =
1621
{
1722
{ L2_ANY, SAI_IN_DROP_REASON_L2_ANY },
@@ -290,7 +295,7 @@ void DropCounter::updateDropReasonsInSAI()
290295
//
291296
// If the device does not support querying drop reasons, this method will
292297
// return an empty list.
293-
vector<string> DropCounter::getSupportedDropReasons(sai_debug_counter_attr_t drop_reason_type)
298+
unordered_set<string> DropCounter::getSupportedDropReasons(sai_debug_counter_attr_t drop_reason_type)
294299
{
295300
sai_s32_list_t drop_reason_list;
296301
int32_t supported_reasons[maxDropReasons];
@@ -306,20 +311,22 @@ vector<string> DropCounter::getSupportedDropReasons(sai_debug_counter_attr_t dro
306311
return {};
307312
}
308313

309-
vector<string> supported_drop_reasons;
314+
unordered_set<string> supported_drop_reasons;
310315
for (uint32_t i = 0; i < drop_reason_list.count; i++)
311316
{
312317
string drop_reason;
313318
if (drop_reason_type == SAI_DEBUG_COUNTER_ATTR_IN_DROP_REASON_LIST)
314319
{
315320
drop_reason = sai_serialize_ingress_drop_reason(static_cast<sai_in_drop_reason_t>(drop_reason_list.list[i]));
321+
drop_reason = drop_reason.substr(INGRESS_DROP_REASON_PREFIX_LENGTH);
316322
}
317323
else
318324
{
319325
drop_reason = sai_serialize_egress_drop_reason(static_cast<sai_out_drop_reason_t>(drop_reason_list.list[i]));
326+
drop_reason = drop_reason.substr(EGRESS_DROP_REASON_PREFIX_LENGTH);
320327
}
321328

322-
supported_drop_reasons.push_back(drop_reason);
329+
supported_drop_reasons.emplace(drop_reason);
323330
}
324331

325332
return supported_drop_reasons;
@@ -330,15 +337,15 @@ vector<string> DropCounter::getSupportedDropReasons(sai_debug_counter_attr_t dro
330337
//
331338
// e.g. { "SMAC_EQUALS_DMAC", "INGRESS_VLAN_FILTER" } -> "["SMAC_EQUALS_DMAC","INGRESS_VLAN_FILTER"]"
332339
// e.g. { } -> "[]"
333-
string DropCounter::serializeSupportedDropReasons(vector<string> drop_reasons)
340+
string DropCounter::serializeSupportedDropReasons(unordered_set<string> drop_reasons)
334341
{
335342
if (drop_reasons.size() == 0)
336343
{
337344
return "[]";
338345
}
339346

340347
string supported_drop_reasons;
341-
for (auto const &drop_reason : drop_reasons)
348+
for (auto const& drop_reason : drop_reasons)
342349
{
343350
supported_drop_reasons += ',';
344351
supported_drop_reasons += drop_reason;

orchagent/debug_counter/drop_counter.h

+2-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
#define SWSS_UTIL_DROP_COUNTER_H_
33

44
#include <string>
5-
#include <vector>
65
#include <unordered_set>
76
#include <unordered_map>
87
#include "debug_counter.h"
@@ -33,8 +32,8 @@ class DropCounter : public DebugCounter
3332
static bool isIngressDropReasonValid(const std::string& drop_reason);
3433
static bool isEgressDropReasonValid(const std::string& drop_reason);
3534

36-
static std::vector<std::string> getSupportedDropReasons(sai_debug_counter_attr_t drop_reason_type);
37-
static std::string serializeSupportedDropReasons(std::vector<std::string> drop_reasons);
35+
static std::unordered_set<std::string> getSupportedDropReasons(sai_debug_counter_attr_t drop_reason_type);
36+
static std::string serializeSupportedDropReasons(std::unordered_set<std::string> drop_reasons);
3837
static uint64_t getSupportedDebugCounterAmounts(sai_debug_counter_type_t counter_type);
3938

4039
private:

orchagent/debugcounterorch.cpp

+43-17
Original file line numberDiff line numberDiff line change
@@ -182,35 +182,46 @@ void DebugCounterOrch::doTask(Consumer& consumer)
182182
// DROP_COUNTER_CAPABILITIES table in STATE_DB.
183183
void DebugCounterOrch::publishDropCounterCapabilities()
184184
{
185-
string supported_ingress_drop_reasons = DropCounter::serializeSupportedDropReasons(
186-
DropCounter::getSupportedDropReasons(SAI_DEBUG_COUNTER_ATTR_IN_DROP_REASON_LIST));
187-
string supported_egress_drop_reasons = DropCounter::serializeSupportedDropReasons(
188-
DropCounter::getSupportedDropReasons(SAI_DEBUG_COUNTER_ATTR_OUT_DROP_REASON_LIST));
185+
supported_ingress_drop_reasons = DropCounter::getSupportedDropReasons(SAI_DEBUG_COUNTER_ATTR_IN_DROP_REASON_LIST);
186+
supported_egress_drop_reasons = DropCounter::getSupportedDropReasons(SAI_DEBUG_COUNTER_ATTR_OUT_DROP_REASON_LIST);
187+
188+
string ingress_drop_reason_str = DropCounter::serializeSupportedDropReasons(supported_ingress_drop_reasons);
189+
string egress_drop_reason_str = DropCounter::serializeSupportedDropReasons(supported_egress_drop_reasons);
189190

190191
for (auto const &counter_type : DebugCounter::getDebugCounterTypeLookup())
191192
{
192-
string num_counters = std::to_string(DropCounter::getSupportedDebugCounterAmounts(counter_type.second));
193-
194193
string drop_reasons;
195194
if (counter_type.first == PORT_INGRESS_DROPS || counter_type.first == SWITCH_INGRESS_DROPS)
196195
{
197-
drop_reasons = supported_ingress_drop_reasons;
196+
drop_reasons = ingress_drop_reason_str;
198197
}
199198
else
200199
{
201-
drop_reasons = supported_egress_drop_reasons;
200+
drop_reasons = egress_drop_reason_str;
202201
}
203202

204-
// Only include available capabilities in State DB
205-
if (num_counters != "0" && !drop_reasons.empty())
203+
// Don't bother publishing counters that have no drop reasons
204+
if (drop_reasons.empty())
206205
{
207-
vector<FieldValueTuple> fieldValues;
208-
fieldValues.push_back(FieldValueTuple("count", num_counters));
209-
fieldValues.push_back(FieldValueTuple("reasons", drop_reasons));
206+
continue;
207+
}
210208

211-
SWSS_LOG_DEBUG("Setting '%s' capabilities to count='%s', reasons='%s'", counter_type.first.c_str(), num_counters.c_str(), drop_reasons.c_str());
212-
m_debugCapabilitiesTable->set(counter_type.first, fieldValues);
209+
string num_counters = std::to_string(DropCounter::getSupportedDebugCounterAmounts(counter_type.second));
210+
211+
// Don't bother publishing counters that aren't available.
212+
if (num_counters == "0")
213+
{
214+
continue;
213215
}
216+
217+
supported_counter_types.emplace(counter_type.first);
218+
219+
vector<FieldValueTuple> fieldValues;
220+
fieldValues.push_back(FieldValueTuple("count", num_counters));
221+
fieldValues.push_back(FieldValueTuple("reasons", drop_reasons));
222+
223+
SWSS_LOG_DEBUG("Setting '%s' capabilities to count='%s', reasons='%s'", counter_type.first.c_str(), num_counters.c_str(), drop_reasons.c_str());
224+
m_debugCapabilitiesTable->set(counter_type.first, fieldValues);
214225
}
215226
}
216227

@@ -229,12 +240,19 @@ task_process_status DebugCounterOrch::installDebugCounter(const string& counter_
229240
return task_process_status::task_success;
230241
}
231242

232-
// Note: this method currently assumes that all counters are drop counters.
243+
// NOTE: this method currently assumes that all counters are drop counters.
233244
// If you are adding support for a non-drop counter than it may make sense
234245
// to either: a) dispatch to different handlers in doTask or b) dispatch to
235246
// different helper methods in this method.
236247

237248
string counter_type = getDebugCounterType(attributes);
249+
250+
if (supported_counter_types.find(counter_type) == supported_counter_types.end())
251+
{
252+
SWSS_LOG_ERROR("Specified counter type '%s' is not supported.", counter_type.c_str());
253+
return task_process_status::task_failed;
254+
}
255+
238256
addFreeCounter(counter_name, counter_type);
239257
reconcileFreeDropCounters(counter_name);
240258

@@ -287,7 +305,15 @@ task_process_status DebugCounterOrch::addDropReason(const string& counter_name,
287305

288306
if (!isDropReasonValid(drop_reason))
289307
{
290-
return task_failed;
308+
SWSS_LOG_ERROR("Specified drop reason '%s' is invalid.", drop_reason.c_str());
309+
return task_process_status::task_failed;
310+
}
311+
312+
if (supported_ingress_drop_reasons.find(drop_reason) == supported_ingress_drop_reasons.end() &&
313+
supported_egress_drop_reasons.find(drop_reason) == supported_egress_drop_reasons.end())
314+
{
315+
SWSS_LOG_ERROR("Specified drop reason '%s' is not supported.", drop_reason.c_str());
316+
return task_process_status::task_failed;
291317
}
292318

293319
auto it = debug_counters.find(counter_name);

orchagent/debugcounterorch.h

+4
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ class DebugCounterOrch: public Orch
7777
std::shared_ptr<swss::Table> m_counterNameToPortStatMap = nullptr;
7878
std::shared_ptr<swss::Table> m_counterNameToSwitchStatMap = nullptr;
7979

80+
std::unordered_set<std::string> supported_counter_types;
81+
std::unordered_set<std::string> supported_ingress_drop_reasons;
82+
std::unordered_set<std::string> supported_egress_drop_reasons;
83+
8084
FlexCounterStatManager flex_counter_manager;
8185

8286
std::unordered_map<std::string, std::unique_ptr<DebugCounter>> debug_counters;

0 commit comments

Comments
 (0)