Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions orchagent/flex_counter/flex_counter_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ const unordered_map<CounterType, string> FlexCounterManager::counter_id_field_lo
{ CounterType::SRV6, SRV6_COUNTER_ID_LIST },
{ CounterType::SWITCH, SWITCH_COUNTER_ID_LIST },
{ CounterType::HA_SET, HA_SET_COUNTER_ID_LIST },
{ CounterType::OFFLOAD_SESSION, FLOW_COUNTER_ID_LIST },
{ CounterType::ICMP_ECHO_SESSION, ICMP_ECHO_SESSION_COUNTER_ID_LIST },
};

FlexManagerDirectory g_FlexManagerDirectory;
Expand Down
2 changes: 2 additions & 0 deletions orchagent/flex_counter/flex_counter_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ enum class CounterType
SRV6,
SWITCH,
HA_SET,
OFFLOAD_SESSION,
ICMP_ECHO_SESSION,
};

extern bool gTraditionalFlexCounter;
Expand Down
8 changes: 8 additions & 0 deletions orchagent/flexcounterorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "pfcwdorch.h"
#include "routeorch.h"
#include "srv6orch.h"
#include "icmporch.h"
#include "switchorch.h"
#include "debugcounterorch.h"
#include "fabricportsorch.h"
Expand All @@ -37,6 +38,7 @@ extern Directory<Orch*> gDirectory;
extern CoppOrch *gCoppOrch;
extern FlowCounterRouteOrch *gFlowCounterRouteOrch;
extern Srv6Orch *gSrv6Orch;
extern IcmpOrch *gIcmpOrch;
extern SwitchOrch *gSwitchOrch;
extern sai_object_id_t gSwitchId;
extern string gMySwitchType;
Expand All @@ -62,6 +64,7 @@ extern string gMySwitchType;
#define WRED_QUEUE_KEY "WRED_ECN_QUEUE"
#define WRED_PORT_KEY "WRED_ECN_PORT"
#define SRV6_KEY "SRV6"
#define ICMP_SESSION_KEY "ICMP_SESSION"
#define SWITCH_KEY "SWITCH"
#define HA_SET_KEY "HA_SET"

Expand Down Expand Up @@ -94,6 +97,7 @@ unordered_map<string, string> flexCounterGroupMap =
{"WRED_ECN_PORT", WRED_PORT_STAT_COUNTER_FLEX_COUNTER_GROUP},
{"WRED_ECN_QUEUE", WRED_QUEUE_STAT_COUNTER_FLEX_COUNTER_GROUP},
{SRV6_KEY, SRV6_STAT_COUNTER_FLEX_COUNTER_GROUP},
{ICMP_SESSION_KEY, ICMP_SESSION_STAT_COUNTER_FLEX_COUNTER_GROUP},
{SWITCH_KEY, SWITCH_STAT_COUNTER_FLEX_COUNTER_GROUP},
{HA_SET_KEY, HA_SET_STAT_COUNTER_FLEX_COUNTER_GROUP}
};
Expand Down Expand Up @@ -338,6 +342,10 @@ void FlexCounterOrch::doTask(Consumer &consumer)
{
gSrv6Orch->setCountersState((value == "enable"));
}
if (gIcmpOrch && (key == ICMP_SESSION_KEY))
{
gIcmpOrch->setCountersState((value == "enable"));
}
if (gPortsOrch && (key == PORT_PHY_ATTR_KEY))
{
if(value == "enable")
Expand Down
140 changes: 88 additions & 52 deletions orchagent/icmporch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,6 @@ IcmpOrch::IcmpOrch(DBConnector *db, string tableName, TableConnector stateDbIcmp
return;
}

if (!resolve_stats_count_mode())
{
SWSS_LOG_WARN("ICMP stats count mode resolution failed, will try to create ICMP session without explicit stats count mode");
}

DBConnector *notificationsDb = new DBConnector("ASIC_DB", 0);
m_icmpStateNotificationConsumer = new swss::NotificationConsumer(notificationsDb, "NOTIFICATIONS");

Expand All @@ -71,64 +66,71 @@ IcmpOrch::IcmpOrch(DBConnector *db, string tableName, TableConnector stateDbIcmp

auto icmpStateNotifier = new Notifier(m_icmpStateNotificationConsumer, this, "ICMP_STATE_NOTIFICATIONS");
Orch::addExecutor(icmpStateNotifier);

initializeCounters();
}

IcmpOrch::~IcmpOrch(void)
void IcmpOrch::initializeCounters()
{
// do nothing, just log
SWSS_LOG_ENTER();

m_stats_handler = std::make_unique<SaiOffloadStatsHandler<IcmpSaiSessionHandler, sai_icmp_echo_api_t>>(
ICMP_SESSION_STAT_COUNTER_FLEX_COUNTER_GROUP,
COUNTERS_ICMP_ECHO_SESSION_NAME_MAP,
ICMP_SESSION_STAT_COUNTER_POLLING_INTERVAL_MS,
ICMP_SESSION_FLEX_COUNTER_UPDATE_TIMER_SEC);

if (!m_stats_handler->initialize())
{
return;
}

// Modern mode registers counters at create time; only traditional
// mode needs the retry timer for VID->RID resolution.
if (gTraditionalFlexCounter)
{
auto timer = m_stats_handler->createUpdateTimer();
auto et = new ExecutableTimer(timer, this, "ICMP_SESSION_FLEX_COUNTER_UPDATE_TIMER");
Orch::addExecutor(et);
}
}

bool IcmpOrch::resolve_stats_count_mode()
std::map<std::string, sai_object_id_t> IcmpOrch::get_existing_session_map() const
{
m_stats_count_mode_initialized = false;

const auto *meta = sai_metadata_get_attr_metadata(
SAI_OBJECT_TYPE_ICMP_ECHO_SESSION,
SAI_ICMP_ECHO_SESSION_ATTR_STATS_COUNT_MODE);
if (!meta || !meta->isenum)
std::map<std::string, sai_object_id_t> existing;
for (const auto& kv : m_icmp_session_map)
{
SWSS_LOG_WARN("sai_metadata_get_attr_metadata for SAI_ICMP_ECHO_SESSION_ATTR_STATS_COUNT_MODE failed");
return false;
existing[kv.first] = kv.second.session_id;
}
return existing;
}

std::vector<int32_t> values_list(meta->enummetadata->valuescount);
sai_s32_list_t values;
values.count = static_cast<uint32_t>(values_list.size());
values.list = values_list.data();
void IcmpOrch::setCountersState(bool enable)
{
SWSS_LOG_ENTER();

auto status = sai_query_attribute_enum_values_capability(
gSwitchId,
SAI_OBJECT_TYPE_ICMP_ECHO_SESSION,
SAI_ICMP_ECHO_SESSION_ATTR_STATS_COUNT_MODE,
&values);
if (status != SAI_STATUS_SUCCESS)
if (!m_stats_handler)
{
SWSS_LOG_WARN("sai_query_attribute_enum_values_capability for SAI_ICMP_ECHO_SESSION_ATTR_STATS_COUNT_MODE failed");
return false;
return;
}

auto *end = values.list + values.count;
m_stats_handler->setState(enable, get_existing_session_map(), sai_icmp_echo_api);
}

static const sai_stats_count_mode_t preferred_modes[] = {
SAI_STATS_COUNT_MODE_PACKET_AND_BYTE,
SAI_STATS_COUNT_MODE_PACKET,
SAI_STATS_COUNT_MODE_BYTE,
SAI_STATS_COUNT_MODE_NONE,
};
void IcmpOrch::doTask(swss::SelectableTimer &timer)
{
SWSS_LOG_ENTER();

for (auto mode : preferred_modes)
if (m_stats_handler)
{
if (std::find(values.list, end, static_cast<int32_t>(mode)) != end)
{
m_stats_count_mode = mode;
m_stats_count_mode_initialized = true;
return true;
}
m_stats_handler->processPending();
}
}

SWSS_LOG_WARN("No supported stats count mode found");
return false;
IcmpOrch::~IcmpOrch(void)
{
// do nothing, just log
SWSS_LOG_ENTER();
}

void IcmpOrch::doTask(Consumer &consumer)
Expand Down Expand Up @@ -288,6 +290,11 @@ bool IcmpOrch::create_icmp_session(const string& key, const vector<FieldValueTup

m_num_sessions++;

if (m_stats_handler && m_stats_handler->isEnabled())
{
m_stats_handler->addSession(key, session_id, sai_icmp_echo_api);
}

SWSS_LOG_NOTICE("Created ICMP offload session key(%s)", key.c_str());
return true;
}
Expand Down Expand Up @@ -351,6 +358,13 @@ bool IcmpOrch::remove_icmp_session(const string& key)
}

sai_object_id_t icmp_session_id = m_icmp_session_map[key].session_id;

// Detach counters before removing the session.
if (m_stats_handler)
{
m_stats_handler->removeSession(key, icmp_session_id, sai_icmp_echo_api);
}

auto remove_status = sai_session_handler.remove(icmp_session_id);
if ( remove_status != SaiOffloadHandlerStatus::SUCCESS_VALID_ENTRY)
{
Expand All @@ -374,6 +388,34 @@ bool IcmpOrch::remove_icmp_session(const string& key)

const std::string IcmpSaiSessionHandler::m_name = "IcmpOffload";

const std::vector<SelectiveCounterVariant>
IcmpSaiSessionHandler::m_selective_counter_variants = {
{ "IN", { SAI_ICMP_ECHO_SESSION_STAT_IN_PACKETS } },
{ "OUT", { SAI_ICMP_ECHO_SESSION_STAT_OUT_PACKETS } },
};

CounterType IcmpSaiSessionHandler::native_counter_type()
{
return CounterType::ICMP_ECHO_SESSION;
}

std::unordered_set<std::string> IcmpSaiSessionHandler::native_counter_stats()
{
// Must match the serializer registered in sairedis for
// COUNTER_TYPE_ICMP_ECHO_SESSION (FlexCounter::createCounterContext).
return {
sai_serialize_icmp_echo_session_stat(SAI_ICMP_ECHO_SESSION_STAT_IN_PACKETS),
sai_serialize_icmp_echo_session_stat(SAI_ICMP_ECHO_SESSION_STAT_OUT_PACKETS),
};
}

sai_status_t IcmpSaiSessionHandler::set_session_attribute(sai_icmp_echo_api_t* api,
sai_object_id_t session_id,
const sai_attribute_t* attr)
{
return api->set_icmp_echo_session_attribute(session_id, attr);
}

const std::string IcmpSaiSessionHandler::m_tx_interval_fname = "tx_interval";
const std::string IcmpSaiSessionHandler::m_rx_interval_fname = "rx_interval";
const std::string IcmpSaiSessionHandler::m_src_ip_fname = "src_ip";
Expand Down Expand Up @@ -617,15 +659,9 @@ SaiOffloadHandlerStatus IcmpSaiSessionHandler::do_create()
m_fv_map[m_tx_interval_fname] = "0";
}

if (m_orch.m_stats_count_mode_initialized)
{
sai_attribute_value_t statsCountModeAttr{};
statsCountModeAttr.s32 = m_orch.m_stats_count_mode;
m_attr_val_map[SAI_ICMP_ECHO_SESSION_ATTR_STATS_COUNT_MODE] = statsCountModeAttr;
}
else
if (m_orch.m_stats_handler)
{
SWSS_LOG_WARN("%s, Stats count mode capability unresolved", m_name.c_str());
m_orch.m_stats_handler->applyStatsCountMode(m_attr_val_map);
}

// update the hw_lookup parameter in fv_vector
Expand Down
Loading
Loading