From be4bfa58c4e197df1222f8fc4901743e8f507b90 Mon Sep 17 00:00:00 2001 From: Sudharsan Dhamal Gopalarathnam Date: Thu, 8 Jul 2021 23:40:00 +0000 Subject: [PATCH 01/15] Tunnel stat changes --- .../flex_counter/flex_counter_manager.cpp | 1 + orchagent/flex_counter/flex_counter_manager.h | 1 + orchagent/flexcounterorch.cpp | 7 +++ orchagent/vxlanorch.cpp | 52 +++++++++++++++++++ orchagent/vxlanorch.h | 11 +++- 5 files changed, 71 insertions(+), 1 deletion(-) diff --git a/orchagent/flex_counter/flex_counter_manager.cpp b/orchagent/flex_counter/flex_counter_manager.cpp index 299e238d37..c76e54d255 100644 --- a/orchagent/flex_counter/flex_counter_manager.cpp +++ b/orchagent/flex_counter/flex_counter_manager.cpp @@ -39,6 +39,7 @@ const unordered_map FlexCounterManager::counter_id_field_lo { CounterType::PORT, PORT_COUNTER_ID_LIST }, { CounterType::QUEUE, QUEUE_COUNTER_ID_LIST }, { CounterType::MACSEC_SA_ATTR, MACSEC_SA_ATTR_ID_LIST }, + { CounterType::TUNNEL, TUNNEL_ATTR_ID_LIST }, }; FlexCounterManager::FlexCounterManager( diff --git a/orchagent/flex_counter/flex_counter_manager.h b/orchagent/flex_counter/flex_counter_manager.h index 4df99c90bd..d091ddbb6f 100644 --- a/orchagent/flex_counter/flex_counter_manager.h +++ b/orchagent/flex_counter/flex_counter_manager.h @@ -24,6 +24,7 @@ enum class CounterType PORT_DEBUG, SWITCH_DEBUG, MACSEC_SA_ATTR, + TUNNEL, }; // FlexCounterManager allows users to manage a group of flex counters. diff --git a/orchagent/flexcounterorch.cpp b/orchagent/flexcounterorch.cpp index 41f024c639..2f765e55fb 100644 --- a/orchagent/flexcounterorch.cpp +++ b/orchagent/flexcounterorch.cpp @@ -23,6 +23,7 @@ extern BufferOrch *gBufferOrch; #define QUEUE_KEY "QUEUE" #define PG_WATERMARK_KEY "PG_WATERMARK" #define RIF_KEY "RIF" +#define TUNNEL_KEY "TUNNEL" unordered_map flexCounterGroupMap = { @@ -38,6 +39,7 @@ unordered_map flexCounterGroupMap = {"RIF", RIF_STAT_COUNTER_FLEX_COUNTER_GROUP}, {"RIF_RATES", RIF_RATE_COUNTER_FLEX_COUNTER_GROUP}, {"DEBUG_COUNTER", DEBUG_COUNTER_FLEX_COUNTER_GROUP}, + {"TUNNEL_COUNTER", TUNNEL_STAT_COUNTER_FLEX_COUNTER_GROUP}, }; @@ -58,6 +60,7 @@ void FlexCounterOrch::doTask(Consumer &consumer) { SWSS_LOG_ENTER(); + VxlanTunnelOrch* vxlan_tunnel_orch = gDirectory.get(); if (gPortsOrch && !gPortsOrch->allPortsReady()) { return; @@ -140,6 +143,10 @@ void FlexCounterOrch::doTask(Consumer &consumer) { gFabricPortsOrch->generateQueueStats(); } + if (vxlan_tunnel_orch && (key== TUNNEL_KEY) && (value == "enable")) + { + vxlan_tunnel_orch->generateTunnelStats(); + } vector fieldValues; fieldValues.emplace_back(FLEX_COUNTER_STATUS_FIELD, value); m_flexCounterGroupTable->set(flexCounterGroupMap[key], fieldValues); diff --git a/orchagent/vxlanorch.cpp b/orchagent/vxlanorch.cpp index 6e25454f13..d9cf381803 100644 --- a/orchagent/vxlanorch.cpp +++ b/orchagent/vxlanorch.cpp @@ -16,6 +16,7 @@ #include "warm_restart.h" #include "tokenize.h" + /* Global variables */ extern sai_object_id_t gSwitchId; extern sai_object_id_t gVirtualRouterId; @@ -57,6 +58,13 @@ const map> vxlanTunnelMapKeyVal = }, }; +const vector tunnel_stat_ids = +{ + SAI_TUNNEL_STAT_IN_OCTETS, + SAI_TUNNEL_STAT_IN_PACKETS, + SAI_TUNNEL_STAT_OUT_OCTETS, + SAI_TUNNEL_STAT_OUT_PACKETS +} /* * Manipulators for the above Map */ @@ -511,6 +519,13 @@ bool VxlanTunnel::createTunnel(MAP_T encap, MAP_T decap, uint8_t encap_ttl) ids_.tunnel_id = create_tunnel(&ids_, ip, NULL, gUnderlayIfId, false, encap_ttl); + if (ids_.tunnel_id != SAI_NULL_OBJECT_ID) + { + auto tunnel_stats = generateTunnelCounterStats(); + tunnel_stat_manager.setCounterIdList(ids_.tunnel_id, CounterType::TUNNEL, + tunnel_stats); + } + ip = nullptr; if (!dst_ip_.isZero()) { @@ -845,6 +860,7 @@ bool VxlanTunnel::deleteTunnelHw(uint8_t mapper_list, tunnel_map_use_t map_src, remove_tunnel_termination(ids_.tunnel_term_id); } + tunnel_stat_manager.clearCounterIdList(ids_.tunnel_id); remove_tunnel(ids_.tunnel_id); deleteMapperHw(mapper_list, map_src); } @@ -885,6 +901,13 @@ bool VxlanTunnel::createTunnelHw(uint8_t mapper_list, tunnel_map_use_t map_src, ids_.tunnel_id = create_tunnel(&ids_, &ips, ip, gUnderlayIfId, p2p); + if (ids_.tunnel_id != SAI_NULL_OBJECT_ID) + { + auto tunnel_stats = generateTunnelCounterStats(); + tunnel_stat_manager.setCounterIdList(ids_.tunnel_id, CounterType::TUNNEL, + tunnel_stats); + } + if (with_term) { ids_.tunnel_term_id = create_tunnel_termination(ids_.tunnel_id, ips, @@ -1156,6 +1179,34 @@ bool VxlanTunnel::deleteDynamicDIPTunnel(const std::string dip, tunnel_user_t us //------------------- VxlanTunnelOrch Implementation --------------------------// +std::unordered_set VxlanTunnelOrch::generateVxlanCounterStats() +{ + std::unordered_set counter_stats; + + for (const auto& it: tunnel_stat_ids) + { + counter_stats.emplace(sai_serialize_tunnel_stat(it)); + } + return counter_stats; +} + +void VxlanTunnelOrch::generateTunnelCounterMap() +{ + if (m_isTunnelCounterMapGenerated) + { + return; + } + + auto tunnel_counter_stats = generateTunnelCounterStats(); + for (const auto& it: vxlan_tunnel_table_) + { + tunnel_stat_manager.setCounterIdList(it.second.get()->getTunnelId(), CounterType::TUNNEL, tunnel_counter_stats); + } + + m_isTunnelCounterMapGenerated = true; +} + + sai_object_id_t VxlanTunnelOrch::createNextHopTunnel(string tunnelName, IpAddress& ipAddr, MacAddress macAddress, uint32_t vni) @@ -1334,6 +1385,7 @@ bool VxlanTunnelOrch::removeVxlanTunnelMap(string tunnelName, uint32_t vni) auto tunnel_id = vxlan_tunnel_table_[tunnelName].get()->getTunnelId(); try { + tunnel_stat_manager.clearCounterIdList(tunnel_id); remove_tunnel(tunnel_id); } catch(const std::runtime_error& error) diff --git a/orchagent/vxlanorch.h b/orchagent/vxlanorch.h index edc65d97fe..e7e03de7f4 100644 --- a/orchagent/vxlanorch.h +++ b/orchagent/vxlanorch.h @@ -35,6 +35,9 @@ typedef enum #define IS_TUNNELMAP_SET_VRF(x) ((x)& (1< generateVxlanCounterStats(); + void generateTunnelCounterMap(); uint32_t vlan_vrf_vni_count = 0; bool del_tnl_hw_pending = false; @@ -243,7 +248,9 @@ class VxlanTunnelOrch : public Orch2 public: VxlanTunnelOrch(DBConnector *statedb, DBConnector *db, const std::string& tableName) : Orch2(db, tableName, request_), - m_stateVxlanTable(statedb, STATE_VXLAN_TUNNEL_TABLE_NAME) + m_stateVxlanTable(statedb, STATE_VXLAN_TUNNEL_TABLE_NAME), + tunnel_stat_manager(TUNNEL_STAT_COUNTER_FLEX_COUNTER_GROUP, + StatsMode::READ, TUNNEL_STAT_FLEX_COUNTER_POLLING_INTERVAL_MS, false) {} @@ -349,6 +356,8 @@ class VxlanTunnelOrch : public Orch2 VxlanVniVlanMapTable vxlan_vni_vlan_map_table_; VTEPTable vtep_table_; Table m_stateVxlanTable; + FlexCounterManager vxlan_tunnel_stat_manager; + bool m_isTunnelCounterMapGenerated = false; }; const request_description_t vxlan_tunnel_map_request_description = { From fc132508fbfaf2c68aa488b5ae78f7eae106de7f Mon Sep 17 00:00:00 2001 From: Sudharsan Dhamal Gopalarathnam Date: Mon, 12 Jul 2021 22:22:26 +0000 Subject: [PATCH 02/15] Added flex manager directory and enabled tunnel counters --- .../flex_counter/flex_counter_manager.cpp | 35 +++++++ orchagent/flex_counter/flex_counter_manager.h | 32 +++++++ orchagent/flexcounterorch.cpp | 4 +- orchagent/vxlanorch.cpp | 91 +++++++++++++++---- orchagent/vxlanorch.h | 19 ++-- 5 files changed, 154 insertions(+), 27 deletions(-) diff --git a/orchagent/flex_counter/flex_counter_manager.cpp b/orchagent/flex_counter/flex_counter_manager.cpp index c76e54d255..89d896e708 100644 --- a/orchagent/flex_counter/flex_counter_manager.cpp +++ b/orchagent/flex_counter/flex_counter_manager.cpp @@ -42,6 +42,41 @@ const unordered_map FlexCounterManager::counter_id_field_lo { CounterType::TUNNEL, TUNNEL_ATTR_ID_LIST }, }; +FlexManagerDirectory g_FlexManagerDirectory; + +FlexCounterManager *FlexManagerDirectory::createFlexCounterManager(const string& group_name, + const StatsMode stats_mode, + const uint polling_interval, + const bool enabled) +{ + if (m_managers.find(group_name) != m_managers.end()) + { + if (stats_mode != m_managers[group_name]->getStatsMode()) + { + SWSS_LOG_ERROR("Stats mode mismatch with already created flex counter manager %s", + group_name.c_str()); + return NULL; + } + if (polling_interval != m_managers[group_name]->getPollingInterval()) + { + SWSS_LOG_ERROR("Polling interval mismatch with already created flex counter manager %s", + group_name.c_str()); + return NULL; + } + if (enabled != m_managers[group_name]->getEnabled()) + { + SWSS_LOG_ERROR("Enabled field mismatch with already created flex counter manager %s", + group_name.c_str()); + return NULL; + } + return m_managers[group_name]; + } + FlexCounterManager *fc_manager = new FlexCounterManager(group_name, stats_mode, polling_interval, + enabled); + m_managers[group_name] = fc_manager; + return fc_manager; +} + FlexCounterManager::FlexCounterManager( const string& group_name, const StatsMode stats_mode, diff --git a/orchagent/flex_counter/flex_counter_manager.h b/orchagent/flex_counter/flex_counter_manager.h index d091ddbb6f..a4d3078b70 100644 --- a/orchagent/flex_counter/flex_counter_manager.h +++ b/orchagent/flex_counter/flex_counter_manager.h @@ -41,6 +41,9 @@ class FlexCounterManager const uint polling_interval, const bool enabled); + FlexCounterManager() + {} + FlexCounterManager(const FlexCounterManager&) = delete; FlexCounterManager& operator=(const FlexCounterManager&) = delete; virtual ~FlexCounterManager(); @@ -55,6 +58,26 @@ class FlexCounterManager const std::unordered_set& counter_stats); void clearCounterIdList(const sai_object_id_t object_id); + std::string getGroupName() + { + return group_name; + } + + StatsMode getStatsMode() + { + return stats_mode; + } + + uint getPollingInterval() + { + return polling_interval; + } + + bool getEnabled() + { + return enabled; + } + protected: void applyGroupConfiguration(); @@ -80,4 +103,13 @@ class FlexCounterManager static const std::unordered_map counter_id_field_lookup; }; +class FlexManagerDirectory +{ + public: + FlexCounterManager* createFlexCounterManager(const std::string& group_name, const StatsMode stats_mode, + const uint polling_interval, const bool enabled); + private: + std::unordered_map m_managers; +}; + #endif // ORCHAGENT_FLEX_COUNTER_MANAGER_H diff --git a/orchagent/flexcounterorch.cpp b/orchagent/flexcounterorch.cpp index 2f765e55fb..51bd6c2c29 100644 --- a/orchagent/flexcounterorch.cpp +++ b/orchagent/flexcounterorch.cpp @@ -9,6 +9,7 @@ #include "bufferorch.h" #include "flexcounterorch.h" #include "debugcounterorch.h" +#include "directory.h" extern sai_port_api_t *sai_port_api; @@ -16,6 +17,7 @@ extern PortsOrch *gPortsOrch; extern FabricPortsOrch *gFabricPortsOrch; extern IntfsOrch *gIntfsOrch; extern BufferOrch *gBufferOrch; +extern Directory gDirectory; #define BUFFER_POOL_WATERMARK_KEY "BUFFER_POOL_WATERMARK" #define PORT_KEY "PORT" @@ -145,7 +147,7 @@ void FlexCounterOrch::doTask(Consumer &consumer) } if (vxlan_tunnel_orch && (key== TUNNEL_KEY) && (value == "enable")) { - vxlan_tunnel_orch->generateTunnelStats(); + vxlan_tunnel_orch->generateTunnelCounterMap(); } vector fieldValues; fieldValues.emplace_back(FLEX_COUNTER_STATUS_FIELD, value); diff --git a/orchagent/vxlanorch.cpp b/orchagent/vxlanorch.cpp index d9cf381803..1346476816 100644 --- a/orchagent/vxlanorch.cpp +++ b/orchagent/vxlanorch.cpp @@ -15,6 +15,8 @@ #include "swssnet.h" #include "warm_restart.h" #include "tokenize.h" +#include "sai_serialize.h" +#include "flex_counter_manager.h" /* Global variables */ @@ -25,6 +27,7 @@ extern sai_next_hop_api_t *sai_next_hop_api; extern Directory gDirectory; extern PortsOrch* gPortsOrch; extern sai_object_id_t gUnderlayIfId; +extern FlexManagerDirectory g_FlexManagerDirectory; const map vxlanTunnelMap = { @@ -58,13 +61,14 @@ const map> vxlanTunnelMapKeyVal = }, }; -const vector tunnel_stat_ids = +const vector tunnel_stat_ids = { SAI_TUNNEL_STAT_IN_OCTETS, SAI_TUNNEL_STAT_IN_PACKETS, SAI_TUNNEL_STAT_OUT_OCTETS, SAI_TUNNEL_STAT_OUT_PACKETS -} +}; + /* * Manipulators for the above Map */ @@ -490,6 +494,7 @@ bool VxlanTunnel::createTunnel(MAP_T encap, MAP_T decap, uint8_t encap_ttl) { try { + VxlanTunnelOrch* tunnel_orch = gDirectory.get(); sai_ip_address_t ips, ipd, *ip=nullptr; uint8_t mapper_list = 0; swss::copy(ips, src_ip_); @@ -519,12 +524,7 @@ bool VxlanTunnel::createTunnel(MAP_T encap, MAP_T decap, uint8_t encap_ttl) ids_.tunnel_id = create_tunnel(&ids_, ip, NULL, gUnderlayIfId, false, encap_ttl); - if (ids_.tunnel_id != SAI_NULL_OBJECT_ID) - { - auto tunnel_stats = generateTunnelCounterStats(); - tunnel_stat_manager.setCounterIdList(ids_.tunnel_id, CounterType::TUNNEL, - tunnel_stats); - } + tunnel_orch->addTunnelToFlexCounter(ids_.tunnel_id, tunnel_name_); ip = nullptr; if (!dst_ip_.isZero()) @@ -855,12 +855,14 @@ bool VxlanTunnel::deleteTunnelHw(uint8_t mapper_list, tunnel_map_use_t map_src, { try { + VxlanTunnelOrch* tunnel_orch = gDirectory.get(); + if (with_term) { remove_tunnel_termination(ids_.tunnel_term_id); } - tunnel_stat_manager.clearCounterIdList(ids_.tunnel_id); + tunnel_orch->removeTunnelFromFlexCounter(ids_.tunnel_id, tunnel_name_); remove_tunnel(ids_.tunnel_id); deleteMapperHw(mapper_list, map_src); } @@ -885,6 +887,7 @@ bool VxlanTunnel::createTunnelHw(uint8_t mapper_list, tunnel_map_use_t map_src, try { + VxlanTunnelOrch* tunnel_orch = gDirectory.get(); sai_ip_address_t ips, ipd, *ip=nullptr; swss::copy(ips, src_ip_); @@ -903,9 +906,7 @@ bool VxlanTunnel::createTunnelHw(uint8_t mapper_list, tunnel_map_use_t map_src, if (ids_.tunnel_id != SAI_NULL_OBJECT_ID) { - auto tunnel_stats = generateTunnelCounterStats(); - tunnel_stat_manager.setCounterIdList(ids_.tunnel_id, CounterType::TUNNEL, - tunnel_stats); + tunnel_orch->addTunnelToFlexCounter(ids_.tunnel_id, tunnel_name_); } if (with_term) @@ -1179,7 +1180,66 @@ bool VxlanTunnel::deleteDynamicDIPTunnel(const std::string dip, tunnel_user_t us //------------------- VxlanTunnelOrch Implementation --------------------------// -std::unordered_set VxlanTunnelOrch::generateVxlanCounterStats() +VxlanTunnelOrch::VxlanTunnelOrch(DBConnector *statedb, DBConnector *db, const std::string& tableName) : + Orch2(db, tableName, request_), + m_stateVxlanTable(statedb, STATE_VXLAN_TUNNEL_TABLE_NAME) +{ + tunnel_stat_manager = g_FlexManagerDirectory.createFlexCounterManager(TUNNEL_STAT_COUNTER_FLEX_COUNTER_GROUP, + StatsMode::READ, TUNNEL_STAT_FLEX_COUNTER_POLLING_INTERVAL_MS, false); + m_counter_db = shared_ptr(new DBConnector("COUNTERS_DB", 0)); + + m_tunnelNameTable = unique_ptr(new Table(m_counter_db.get(), COUNTERS_TUNNEL_NAME_MAP)); + m_tunnelTypeTable = unique_ptr
(new Table(m_counter_db.get(), COUNTERS_TUNNEL_TYPE_MAP)); + + +} + +void VxlanTunnelOrch::addTunnelToFlexCounter(sai_object_id_t oid, const string &name) +{ + SWSS_LOG_ENTER(); + string type = "SAI_TUNNEL_TYPE_VXLAN"; + + if (oid == SAI_NULL_OBJECT_ID) + { + SWSS_LOG_WARN("Not adding NULL OID to flex for tunnel %s", name.c_str()); + return; + } + + string sai_oid = sai_serialize_object_id(oid); + vector tunnelNameFvs; + vector tunnelTypeFvs; + + tunnelNameFvs.emplace_back(name, sai_oid); + tunnelTypeFvs.emplace_back(sai_oid, type); + + m_tunnelNameTable->set("", tunnelNameFvs); + m_tunnelTypeTable->set("", tunnelTypeFvs); + + auto tunnel_stats = generateTunnelCounterStats(); + tunnel_stat_manager->setCounterIdList(oid, CounterType::TUNNEL, + tunnel_stats); + SWSS_LOG_DEBUG("Registered tunnel %s to Flex counter", name.c_str()); +} + +void VxlanTunnelOrch::removeTunnelFromFlexCounter(sai_object_id_t oid, const string &name) +{ + SWSS_LOG_ENTER(); + + if (oid == SAI_NULL_OBJECT_ID) + { + SWSS_LOG_WARN("Not removing NULL OID to flex for tunnel %s", name.c_str()); + return; + } + + string sai_oid = sai_serialize_object_id(oid); + + m_tunnelNameTable->hdel("", name); + m_tunnelTypeTable->hdel("", sai_oid); + tunnel_stat_manager->clearCounterIdList(oid); + SWSS_LOG_DEBUG("Unregistered tunnel %s to Flex counter", name.c_str()); +} + +std::unordered_set VxlanTunnelOrch::generateTunnelCounterStats() { std::unordered_set counter_stats; @@ -1197,10 +1257,9 @@ void VxlanTunnelOrch::generateTunnelCounterMap() return; } - auto tunnel_counter_stats = generateTunnelCounterStats(); for (const auto& it: vxlan_tunnel_table_) { - tunnel_stat_manager.setCounterIdList(it.second.get()->getTunnelId(), CounterType::TUNNEL, tunnel_counter_stats); + addTunnelToFlexCounter(it.second.get()->getTunnelId(), it.second.get()->getTunnelName()); } m_isTunnelCounterMapGenerated = true; @@ -1385,7 +1444,7 @@ bool VxlanTunnelOrch::removeVxlanTunnelMap(string tunnelName, uint32_t vni) auto tunnel_id = vxlan_tunnel_table_[tunnelName].get()->getTunnelId(); try { - tunnel_stat_manager.clearCounterIdList(tunnel_id); + removeTunnelFromFlexCounter(tunnel_id, tunnelName); remove_tunnel(tunnel_id); } catch(const std::runtime_error& error) diff --git a/orchagent/vxlanorch.h b/orchagent/vxlanorch.h index e7e03de7f4..b7d9b4e24e 100644 --- a/orchagent/vxlanorch.h +++ b/orchagent/vxlanorch.h @@ -198,8 +198,6 @@ class VxlanTunnel int getDipTunnelCnt(); bool createDynamicDIPTunnel(const string dip, tunnel_user_t usr); bool deleteDynamicDIPTunnel(const string dip, tunnel_user_t usr, bool update_refcnt = true); - unordered_set generateVxlanCounterStats(); - void generateTunnelCounterMap(); uint32_t vlan_vrf_vni_count = 0; bool del_tnl_hw_pending = false; @@ -246,13 +244,7 @@ typedef std::map VTEPTable; class VxlanTunnelOrch : public Orch2 { public: - VxlanTunnelOrch(DBConnector *statedb, DBConnector *db, const std::string& tableName) : - Orch2(db, tableName, request_), - m_stateVxlanTable(statedb, STATE_VXLAN_TUNNEL_TABLE_NAME), - tunnel_stat_manager(TUNNEL_STAT_COUNTER_FLEX_COUNTER_GROUP, - StatsMode::READ, TUNNEL_STAT_FLEX_COUNTER_POLLING_INTERVAL_MS, false) - {} - + VxlanTunnelOrch(DBConnector *statedb, DBConnector *db, const std::string& tableName); bool isTunnelExists(const std::string& tunnelName) const { @@ -345,7 +337,10 @@ class VxlanTunnelOrch : public Orch2 vxlan_vni_vlan_map_table_.erase(vni); } - + unordered_set generateTunnelCounterStats(); + void generateTunnelCounterMap(); + void addTunnelToFlexCounter(sai_object_id_t oid, const std::string &name); + void removeTunnelFromFlexCounter(sai_object_id_t oid, const std::string &name); private: virtual bool addOperation(const Request& request); @@ -358,6 +353,10 @@ class VxlanTunnelOrch : public Orch2 Table m_stateVxlanTable; FlexCounterManager vxlan_tunnel_stat_manager; bool m_isTunnelCounterMapGenerated = false; + FlexCounterManager *tunnel_stat_manager; + unique_ptr
m_tunnelNameTable; + unique_ptr
m_tunnelTypeTable; + shared_ptr m_counter_db; }; const request_description_t vxlan_tunnel_map_request_description = { From 78766b4118916c35bfc5eadbbe3b77f0315a8edd Mon Sep 17 00:00:00 2001 From: Sudharsan Dhamal Gopalarathnam Date: Thu, 15 Jul 2021 21:58:59 +0000 Subject: [PATCH 03/15] Adding lua script --- .../flex_counter/flex_counter_manager.cpp | 14 +++- orchagent/flex_counter/flex_counter_manager.h | 9 +- orchagent/tunnel_rates.lua | 84 +++++++++++++++++++ orchagent/vxlanorch.cpp | 16 +++- 4 files changed, 117 insertions(+), 6 deletions(-) create mode 100644 orchagent/tunnel_rates.lua diff --git a/orchagent/flex_counter/flex_counter_manager.cpp b/orchagent/flex_counter/flex_counter_manager.cpp index 89d896e708..084bb466cc 100644 --- a/orchagent/flex_counter/flex_counter_manager.cpp +++ b/orchagent/flex_counter/flex_counter_manager.cpp @@ -47,7 +47,8 @@ FlexManagerDirectory g_FlexManagerDirectory; FlexCounterManager *FlexManagerDirectory::createFlexCounterManager(const string& group_name, const StatsMode stats_mode, const uint polling_interval, - const bool enabled) + const bool enabled, + FieldValueTuple fv_plugin) { if (m_managers.find(group_name) != m_managers.end()) { @@ -72,7 +73,7 @@ FlexCounterManager *FlexManagerDirectory::createFlexCounterManager(const string& return m_managers[group_name]; } FlexCounterManager *fc_manager = new FlexCounterManager(group_name, stats_mode, polling_interval, - enabled); + enabled, fv_plugin); m_managers[group_name] = fc_manager; return fc_manager; } @@ -81,11 +82,13 @@ FlexCounterManager::FlexCounterManager( const string& group_name, const StatsMode stats_mode, const uint polling_interval, - const bool enabled) : + const bool enabled, + FieldValueTuple fv_plugin) : group_name(group_name), stats_mode(stats_mode), polling_interval(polling_interval), enabled(enabled), + fv_plugin(fv_plugin), flex_counter_db(new DBConnector("FLEX_COUNTER_DB", 0)), flex_counter_group_table(new ProducerTable(flex_counter_db.get(), FLEX_COUNTER_GROUP_TABLE)), flex_counter_table(new ProducerTable(flex_counter_db.get(), FLEX_COUNTER_TABLE)) @@ -122,6 +125,11 @@ void FlexCounterManager::applyGroupConfiguration() FieldValueTuple(FLEX_COUNTER_STATUS_FIELD, status_lookup.at(enabled)) }; + if (!fvField(fv_plugin).empty()) + { + field_values.emplace_back(fv_plugin); + } + flex_counter_group_table->set(group_name, field_values); } diff --git a/orchagent/flex_counter/flex_counter_manager.h b/orchagent/flex_counter/flex_counter_manager.h index a4d3078b70..d63579631f 100644 --- a/orchagent/flex_counter/flex_counter_manager.h +++ b/orchagent/flex_counter/flex_counter_manager.h @@ -4,8 +4,10 @@ #include #include #include +#include #include "dbconnector.h" #include "producertable.h" +#include "table.h" #include extern "C" { @@ -39,7 +41,8 @@ class FlexCounterManager const std::string& group_name, const StatsMode stats_mode, const uint polling_interval, - const bool enabled); + const bool enabled, + swss::FieldValueTuple fv_plugin = std::make_pair("","")); FlexCounterManager() {} @@ -92,6 +95,7 @@ class FlexCounterManager StatsMode stats_mode; uint polling_interval; bool enabled; + swss::FieldValueTuple fv_plugin; std::unordered_set installed_counters; std::shared_ptr flex_counter_db = nullptr; @@ -107,7 +111,8 @@ class FlexManagerDirectory { public: FlexCounterManager* createFlexCounterManager(const std::string& group_name, const StatsMode stats_mode, - const uint polling_interval, const bool enabled); + const uint polling_interval, const bool enabled, + swss::FieldValueTuple fv_plugin = std::make_pair("","")); private: std::unordered_map m_managers; }; diff --git a/orchagent/tunnel_rates.lua b/orchagent/tunnel_rates.lua new file mode 100644 index 0000000000..5fe88b0663 --- /dev/null +++ b/orchagent/tunnel_rates.lua @@ -0,0 +1,84 @@ +-- KEYS - rif IDs +-- ARGV[1] - counters db index +-- ARGV[2] - counters table name +-- ARGV[3] - poll time interval +-- return log + +local logtable = {} + +local function logit(msg) + logtable[#logtable+1] = tostring(msg) +end + +local counters_db = ARGV[1] +local counters_table_name = ARGV[2] +local rates_table_name = "RATES" + +-- Get configuration +redis.call('SELECT', counters_db) +local smooth_interval = redis.call('HGET', rates_table_name .. ':' .. 'TUNNEL', 'TUNNEL_SMOOTH_INTERVAL') +local alpha = redis.call('HGET', rates_table_name .. ':' .. 'TUNNEL', 'TUNNEL_ALPHA') +if not alpha then + logit("Alpha is not defined") + return logtable +end +local one_minus_alpha = 1.0 - alpha +local delta = tonumber(ARGV[3]) + +local n = table.getn(KEYS) +for i = 1, n do + local state_table = rates_table_name .. ':' .. KEYS[i] .. ':' .. 'TUNNEL' + local initialized = redis.call('HGET', state_table, 'INIT_DONE') + logit(initialized) + + -- Get new COUNTERS values + local in_octets = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_IN_OCTETS') + local in_pkts = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_IN_PACKETS') + local out_octets = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_OUT_OCTETS') + local out_pkts = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_OUT_PACKETS') + + if initialized == "DONE" or initialized == "COUNTERS_LAST" then + -- Get old COUNTERS values + local in_octets_last = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_IN_OCTETS_last') + local in_pkts_last = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_IN_PACKETS_last') + local out_octets_last = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_OUT_OCTETS_last') + local out_pkts_last = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_OUT_PACKETS_last') + + -- Calculate new rates values + local rx_bps_new = (in_octets - in_octets_last)/delta + local tx_bps_new = (out_octets - out_octets_last)/delta + local rx_pps_new = (in_pkts - in_pkts_last)/delta + local tx_pps_new = (out_pkts - out_pkts_last)/delta + + if initialized == "DONE" then + -- Get old rates values + local rx_bps_old = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'RX_BPS') + local rx_pps_old = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'RX_PPS') + local tx_bps_old = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'TX_BPS') + local tx_pps_old = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'TX_PPS') + + -- Smooth the rates values and store them in DB + redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'RX_BPS', alpha*rx_bps_new + one_minus_alpha*rx_bps_old) + redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'RX_PPS', alpha*rx_pps_new + one_minus_alpha*rx_pps_old) + redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'TX_BPS', alpha*tx_bps_new + one_minus_alpha*tx_bps_old) + redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'TX_PPS', alpha*tx_pps_new + one_minus_alpha*tx_pps_old) + else + -- Store unsmoothed initial rates values in DB + redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'RX_BPS', rx_bps_new) + redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'RX_PPS', rx_pps_new) + redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'TX_BPS', tx_bps_new) + redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'TX_PPS', tx_pps_new) + redis.call('HSET', state_table, 'INIT_DONE', 'DONE') + end + else + redis.call('HSET', state_table, 'INIT_DONE', 'COUNTERS_LAST') + end + + -- Set old COUNTERS values + redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_IN_OCTETS_last', in_octets) + redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_IN_PACKETS_last', in_pkts) + redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_OUT_OCTETS_last', out_octets) + redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_OUT_PACKETS_last', out_pkts) +end + +return logtable diff --git a/orchagent/vxlanorch.cpp b/orchagent/vxlanorch.cpp index 1346476816..01c5eb28e9 100644 --- a/orchagent/vxlanorch.cpp +++ b/orchagent/vxlanorch.cpp @@ -1184,8 +1184,22 @@ VxlanTunnelOrch::VxlanTunnelOrch(DBConnector *statedb, DBConnector *db, const st Orch2(db, tableName, request_), m_stateVxlanTable(statedb, STATE_VXLAN_TUNNEL_TABLE_NAME) { + FieldValueTuple fv; + string tunnel_rate_plugin = "tunnel_rates.lua"; + try + { + string tunnel_rate_script = swss::loadLuaScript(tunnel_rate_plugin); + string tunnel_rate_sha = swss::loadRedisScript(m_counter_db.get(), tunnel_rate_script); + + fv = make_pair(TUNNEL_PLUGIN_FIELD, tunnel_rate_sha); + } + catch (const runtime_error &e) + { + SWSS_LOG_WARN("Tunnel flex counter group plugins was not set successfully: %s", e.what()); + } + tunnel_stat_manager = g_FlexManagerDirectory.createFlexCounterManager(TUNNEL_STAT_COUNTER_FLEX_COUNTER_GROUP, - StatsMode::READ, TUNNEL_STAT_FLEX_COUNTER_POLLING_INTERVAL_MS, false); + StatsMode::READ, TUNNEL_STAT_FLEX_COUNTER_POLLING_INTERVAL_MS, false, fv); m_counter_db = shared_ptr(new DBConnector("COUNTERS_DB", 0)); m_tunnelNameTable = unique_ptr
(new Table(m_counter_db.get(), COUNTERS_TUNNEL_NAME_MAP)); From 6e0954d714ff4642303958149ff160c81283b5d1 Mon Sep 17 00:00:00 2001 From: Sudharsan Dhamal Gopalarathnam Date: Sat, 17 Jul 2021 03:08:07 +0000 Subject: [PATCH 04/15] Adding UT and fixes --- orchagent/flexcounterorch.cpp | 2 +- orchagent/vxlanorch.cpp | 17 ++++++++------- tests/test_flex_counters.py | 39 ++++++++++++++++++++++++++++++++++- 3 files changed, 48 insertions(+), 10 deletions(-) diff --git a/orchagent/flexcounterorch.cpp b/orchagent/flexcounterorch.cpp index 51bd6c2c29..d47b82078f 100644 --- a/orchagent/flexcounterorch.cpp +++ b/orchagent/flexcounterorch.cpp @@ -41,7 +41,7 @@ unordered_map flexCounterGroupMap = {"RIF", RIF_STAT_COUNTER_FLEX_COUNTER_GROUP}, {"RIF_RATES", RIF_RATE_COUNTER_FLEX_COUNTER_GROUP}, {"DEBUG_COUNTER", DEBUG_COUNTER_FLEX_COUNTER_GROUP}, - {"TUNNEL_COUNTER", TUNNEL_STAT_COUNTER_FLEX_COUNTER_GROUP}, + {"TUNNEL", TUNNEL_STAT_COUNTER_FLEX_COUNTER_GROUP}, }; diff --git a/orchagent/vxlanorch.cpp b/orchagent/vxlanorch.cpp index 01c5eb28e9..bb2e164bb9 100644 --- a/orchagent/vxlanorch.cpp +++ b/orchagent/vxlanorch.cpp @@ -524,7 +524,10 @@ bool VxlanTunnel::createTunnel(MAP_T encap, MAP_T decap, uint8_t encap_ttl) ids_.tunnel_id = create_tunnel(&ids_, ip, NULL, gUnderlayIfId, false, encap_ttl); - tunnel_orch->addTunnelToFlexCounter(ids_.tunnel_id, tunnel_name_); + if (ids_.tunnel_id != SAI_NULL_OBJECT_ID) + { + tunnel_orch->addTunnelToFlexCounter(ids_.tunnel_id, tunnel_name_); + } ip = nullptr; if (!dst_ip_.isZero()) @@ -1213,12 +1216,6 @@ void VxlanTunnelOrch::addTunnelToFlexCounter(sai_object_id_t oid, const string & SWSS_LOG_ENTER(); string type = "SAI_TUNNEL_TYPE_VXLAN"; - if (oid == SAI_NULL_OBJECT_ID) - { - SWSS_LOG_WARN("Not adding NULL OID to flex for tunnel %s", name.c_str()); - return; - } - string sai_oid = sai_serialize_object_id(oid); vector tunnelNameFvs; vector tunnelTypeFvs; @@ -1273,7 +1270,11 @@ void VxlanTunnelOrch::generateTunnelCounterMap() for (const auto& it: vxlan_tunnel_table_) { - addTunnelToFlexCounter(it.second.get()->getTunnelId(), it.second.get()->getTunnelName()); + auto tunnel_id = it.second.get()->getTunnelId(); + if (tunnel_id != SAI_NULL_OBJECT_ID) + { + addTunnelToFlexCounter(it.second.get()->getTunnelId(), it.second.get()->getTunnelName()); + } } m_isTunnelCounterMapGenerated = true; diff --git a/tests/test_flex_counters.py b/tests/test_flex_counters.py index ecdc844572..b38a5594c4 100644 --- a/tests/test_flex_counters.py +++ b/tests/test_flex_counters.py @@ -8,6 +8,7 @@ BUFFER_POOL_WATERMARK_KEY = "BUFFER_POOL_WATERMARK" PORT_BUFFER_DROP_KEY = "PORT_BUFFER_DROP" PG_WATERMARK_KEY = "PG_WATERMARK" +TUNNEL_KEY = "TUNNEL" # Counter stats on FlexCountersDB PORT_STAT = "PORT_STAT_COUNTER" @@ -16,6 +17,7 @@ BUFFER_POOL_WATERMARK_STAT = "BUFFER_POOL_WATERMARK_STAT_COUNTER" PORT_BUFFER_DROP_STAT = "PORT_BUFFER_DROP_STAT" PG_WATERMARK_STAT = "PG_WATERMARK_STAT_COUNTER" +TUNNEL_STAT = "TUNNEL_STAT_COUNTER" # Counter maps on CountersDB PORT_MAP = "COUNTERS_PORT_NAME_MAP" @@ -24,7 +26,9 @@ BUFFER_POOL_WATERMARK_MAP = "COUNTERS_BUFFER_POOL_NAME_MAP" PORT_BUFFER_DROP_MAP = "COUNTERS_PORT_NAME_MAP" PG_WATERMARK_MAP = "COUNTERS_PG_NAME_MAP" +TUNNEL_MAP = "COUNTERS_TUNNEL_NAME_MAP" +TUNNEL_TYPE_MAP = "COUNTERS_TUNNEL_TYPE_MAP" NUMBER_OF_RETRIES = 10 CPU_PORT_OID = "0x0" @@ -33,7 +37,9 @@ "rif_counter":[RIF_KEY, RIF_STAT, RIF_MAP], "buffer_pool_watermark_counter":[BUFFER_POOL_WATERMARK_KEY, BUFFER_POOL_WATERMARK_STAT, BUFFER_POOL_WATERMARK_MAP], "port_buffer_drop_counter":[PORT_BUFFER_DROP_KEY, PORT_BUFFER_DROP_STAT, PORT_BUFFER_DROP_MAP], - "pg_watermark_counter":[PG_WATERMARK_KEY, PG_WATERMARK_STAT, PG_WATERMARK_MAP]} + "pg_watermark_counter":[PG_WATERMARK_KEY, PG_WATERMARK_STAT, PG_WATERMARK_MAP], + "vxlan_tunnel_counter":[TUNNEL_KEY, TUNNEL_STAT, TUNNEL_MAP]} + class TestFlexCounters(object): @@ -66,6 +72,15 @@ def verify_no_flex_counters_tables(self, counter_stat): counters_stat_keys = self.flex_db.get_keys("FLEX_COUNTER_TABLE:" + counter_stat) assert len(counters_stat_keys) == 0, "FLEX_COUNTER_TABLE:" + str(counter_stat) + " tables exist before enabling the flex counter group" + def verify_no_flex_counters_tables_after_delete(self, counter_stat): + for retry in range(NUMBER_OF_RETRIES): + counters_stat_keys = self.flex_db.get_keys("FLEX_COUNTER_TABLE:" + counter_stat + ":") + if len(counters_stat_keys) == 0: + return + else: + time.sleep(1) + assert False, "FLEX_COUNTER_TABLE:" + str(counter_stat) + " tables exist after removing the entries" + def verify_flex_counters_populated(self, map, stat): counters_keys = self.counters_db.db_connection.hgetall(map) for counter_entry in counters_keys.items(): @@ -73,6 +88,15 @@ def verify_flex_counters_populated(self, map, stat): oid = counter_entry[1] self.wait_for_id_list(stat, name, oid) + def verify_tunnel_type_vxlan(self, name_map, type_map): + counters_keys = self.counters_db.db_connection.hgetall(name_map) + for counter_entry in counters_keys.items(): + name = counter_entry[0] + oid = counter_entry[1] + fvs = self.counters_db.get_entry(type_map, "") + assert fvs != {} + assert fvs.get(oid) == "SAI_TUNNEL_TYPE_VXLAN" + def verify_only_phy_ports_created(self): port_counters_keys = self.counters_db.db_connection.hgetall(PORT_MAP) port_counters_stat_keys = self.flex_db.get_keys("FLEX_COUNTER_TABLE:" + PORT_STAT) @@ -102,6 +126,12 @@ def test_flex_counters(self, dvs, counter_type): self.config_db.db_connection.hset('INTERFACE|Ethernet0', "NULL", "NULL") self.config_db.db_connection.hset('INTERFACE|Ethernet0|192.168.0.1/24', "NULL", "NULL") + if counter_type == "vxlan_tunnel_counter": + self.config_db.db_connection.hset("VLAN|Vlan10", "vlanid", "10") + self.config_db.db_connection.hset("VXLAN_TUNNEL|vtep1", "src_ip", "1.1.1.1") + self.config_db.db_connection.hset("VXLAN_TUNNEL_MAP|vtep1|map_100_Vlan10", "vlan", "Vlan10") + self.config_db.db_connection.hset("VXLAN_TUNNEL_MAP|vtep1|map_100_Vlan10", "vni", "100") + self.enable_flex_counter_group(counter_key, counter_map) self.verify_flex_counters_populated(counter_map, counter_stat) @@ -110,3 +140,10 @@ def test_flex_counters(self, dvs, counter_type): if counter_type == "rif_counter": self.config_db.db_connection.hdel('INTERFACE|Ethernet0|192.168.0.1/24', "NULL") + + if counter_type == "vxlan_tunnel_counter": + self.verify_tunnel_type_vxlan(counter_map, TUNNEL_TYPE_MAP) + self.config_db.delete_entry("VLAN","Vlan10") + self.config_db.delete_entry("VLAN_TUNNEL","vtep1") + self.config_db.delete_entry("VLAN_TUNNEL_MAP","vtep1|map_100_Vlan10") + self.verify_no_flex_counters_tables_after_delete(counter_stat) From 92a5a7b8898ac89e07bd4da6bb1c7efd2a3c9464 Mon Sep 17 00:00:00 2001 From: Sudharsan Dhamal Gopalarathnam Date: Sat, 17 Jul 2021 03:30:47 +0000 Subject: [PATCH 05/15] Makefile changes to add lua script --- orchagent/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/orchagent/Makefile.am b/orchagent/Makefile.am index 05abdfbcec..2a544c6abb 100644 --- a/orchagent/Makefile.am +++ b/orchagent/Makefile.am @@ -16,7 +16,8 @@ dist_swss_DATA = \ watermark_queue.lua \ watermark_pg.lua \ watermark_bufferpool.lua \ - lagids.lua + lagids.lua \ + tunnel_rates.lua bin_PROGRAMS = orchagent routeresync orchagent_restart_check From a652ed1f2467508d2c9d535af182b845da88c542 Mon Sep 17 00:00:00 2001 From: Sudharsan Dhamal Gopalarathnam Date: Sat, 17 Jul 2021 03:44:21 +0000 Subject: [PATCH 06/15] adding rate table handling --- orchagent/flexcounterorch.cpp | 1 + orchagent/vxlanorch.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/orchagent/flexcounterorch.cpp b/orchagent/flexcounterorch.cpp index d47b82078f..bf65fe3645 100644 --- a/orchagent/flexcounterorch.cpp +++ b/orchagent/flexcounterorch.cpp @@ -42,6 +42,7 @@ unordered_map flexCounterGroupMap = {"RIF_RATES", RIF_RATE_COUNTER_FLEX_COUNTER_GROUP}, {"DEBUG_COUNTER", DEBUG_COUNTER_FLEX_COUNTER_GROUP}, {"TUNNEL", TUNNEL_STAT_COUNTER_FLEX_COUNTER_GROUP}, + {"TUNNEL_RATES", TUNNEL_RATE_COUNTER_FLEX_COUNTER_GROUP}, }; diff --git a/orchagent/vxlanorch.h b/orchagent/vxlanorch.h index b7d9b4e24e..8f1d6fcf40 100644 --- a/orchagent/vxlanorch.h +++ b/orchagent/vxlanorch.h @@ -36,7 +36,8 @@ typedef enum #define IS_TUNNELMAP_SET_BRIDGE(x) ((x)& (1< Date: Sat, 17 Jul 2021 03:50:23 +0000 Subject: [PATCH 07/15] Clean up of unused macros --- orchagent/flexcounterorch.cpp | 1 - orchagent/vxlanorch.h | 1 - 2 files changed, 2 deletions(-) diff --git a/orchagent/flexcounterorch.cpp b/orchagent/flexcounterorch.cpp index bf65fe3645..d47b82078f 100644 --- a/orchagent/flexcounterorch.cpp +++ b/orchagent/flexcounterorch.cpp @@ -42,7 +42,6 @@ unordered_map flexCounterGroupMap = {"RIF_RATES", RIF_RATE_COUNTER_FLEX_COUNTER_GROUP}, {"DEBUG_COUNTER", DEBUG_COUNTER_FLEX_COUNTER_GROUP}, {"TUNNEL", TUNNEL_STAT_COUNTER_FLEX_COUNTER_GROUP}, - {"TUNNEL_RATES", TUNNEL_RATE_COUNTER_FLEX_COUNTER_GROUP}, }; diff --git a/orchagent/vxlanorch.h b/orchagent/vxlanorch.h index 8f1d6fcf40..54e3c11567 100644 --- a/orchagent/vxlanorch.h +++ b/orchagent/vxlanorch.h @@ -36,7 +36,6 @@ typedef enum #define IS_TUNNELMAP_SET_BRIDGE(x) ((x)& (1< Date: Sat, 17 Jul 2021 05:06:26 +0000 Subject: [PATCH 08/15] UT fixes --- orchagent/vxlanorch.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/orchagent/vxlanorch.cpp b/orchagent/vxlanorch.cpp index bb2e164bb9..5723f9dc71 100644 --- a/orchagent/vxlanorch.cpp +++ b/orchagent/vxlanorch.cpp @@ -1189,12 +1189,12 @@ VxlanTunnelOrch::VxlanTunnelOrch(DBConnector *statedb, DBConnector *db, const st { FieldValueTuple fv; string tunnel_rate_plugin = "tunnel_rates.lua"; + m_counter_db = shared_ptr(new DBConnector("COUNTERS_DB", 0)); try { string tunnel_rate_script = swss::loadLuaScript(tunnel_rate_plugin); string tunnel_rate_sha = swss::loadRedisScript(m_counter_db.get(), tunnel_rate_script); - - fv = make_pair(TUNNEL_PLUGIN_FIELD, tunnel_rate_sha); + fv = FieldValueTuple(TUNNEL_PLUGIN_FIELD, tunnel_rate_sha); } catch (const runtime_error &e) { @@ -1203,7 +1203,6 @@ VxlanTunnelOrch::VxlanTunnelOrch(DBConnector *statedb, DBConnector *db, const st tunnel_stat_manager = g_FlexManagerDirectory.createFlexCounterManager(TUNNEL_STAT_COUNTER_FLEX_COUNTER_GROUP, StatsMode::READ, TUNNEL_STAT_FLEX_COUNTER_POLLING_INTERVAL_MS, false, fv); - m_counter_db = shared_ptr(new DBConnector("COUNTERS_DB", 0)); m_tunnelNameTable = unique_ptr
(new Table(m_counter_db.get(), COUNTERS_TUNNEL_NAME_MAP)); m_tunnelTypeTable = unique_ptr
(new Table(m_counter_db.get(), COUNTERS_TUNNEL_TYPE_MAP)); From 9213fe07fd11f1cc54b1a9aaf1b99d82762b35d5 Mon Sep 17 00:00:00 2001 From: Sudharsan Dhamal Gopalarathnam Date: Thu, 29 Jul 2021 05:33:43 +0000 Subject: [PATCH 09/15] Addressing code review comments --- orchagent/flex_counter/flex_counter_manager.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/orchagent/flex_counter/flex_counter_manager.h b/orchagent/flex_counter/flex_counter_manager.h index d63579631f..2d531d5084 100644 --- a/orchagent/flex_counter/flex_counter_manager.h +++ b/orchagent/flex_counter/flex_counter_manager.h @@ -61,22 +61,22 @@ class FlexCounterManager const std::unordered_set& counter_stats); void clearCounterIdList(const sai_object_id_t object_id); - std::string getGroupName() + const std::string& getGroupName() const { return group_name; } - StatsMode getStatsMode() + const StatsMode& getStatsMode() const { return stats_mode; } - uint getPollingInterval() + const uint& getPollingInterval() const { return polling_interval; } - bool getEnabled() + const bool& getEnabled() const { return enabled; } From 601c2c02b2d2aefee5b697109203b1fd382b3872 Mon Sep 17 00:00:00 2001 From: Sudharsan Dhamal Gopalarathnam Date: Sat, 7 Aug 2021 05:08:29 +0000 Subject: [PATCH 10/15] Modifying rates calculation considering delta to be ms instead of seconds --- orchagent/tunnel_rates.lua | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/orchagent/tunnel_rates.lua b/orchagent/tunnel_rates.lua index 5fe88b0663..ef3816210f 100644 --- a/orchagent/tunnel_rates.lua +++ b/orchagent/tunnel_rates.lua @@ -13,6 +13,7 @@ end local counters_db = ARGV[1] local counters_table_name = ARGV[2] local rates_table_name = "RATES" +local sec_to_ms = 1000 -- Get configuration redis.call('SELECT', counters_db) @@ -45,10 +46,10 @@ for i = 1, n do local out_pkts_last = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_OUT_PACKETS_last') -- Calculate new rates values - local rx_bps_new = (in_octets - in_octets_last)/delta - local tx_bps_new = (out_octets - out_octets_last)/delta - local rx_pps_new = (in_pkts - in_pkts_last)/delta - local tx_pps_new = (out_pkts - out_pkts_last)/delta + local rx_bps_new = (in_octets - in_octets_last)*sec_to_ms/delta + local tx_bps_new = (out_octets - out_octets_last)*sec_to_ms/delta + local rx_pps_new = (in_pkts - in_pkts_last)*sec_to_ms/delta + local tx_pps_new = (out_pkts - out_pkts_last)*sec_to_ms/delta if initialized == "DONE" then -- Get old rates values From c2d9d3ff5165a7343a6c9ad5f6584b1de2d98c1f Mon Sep 17 00:00:00 2001 From: Sudharsan Dhamal Gopalarathnam Date: Sat, 7 Aug 2021 17:29:53 +0000 Subject: [PATCH 11/15] Fixing lgtm --- tests/test_flex_counters.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_flex_counters.py b/tests/test_flex_counters.py index b38a5594c4..6fe3e67500 100644 --- a/tests/test_flex_counters.py +++ b/tests/test_flex_counters.py @@ -91,7 +91,6 @@ def verify_flex_counters_populated(self, map, stat): def verify_tunnel_type_vxlan(self, name_map, type_map): counters_keys = self.counters_db.db_connection.hgetall(name_map) for counter_entry in counters_keys.items(): - name = counter_entry[0] oid = counter_entry[1] fvs = self.counters_db.get_entry(type_map, "") assert fvs != {} From fbf577d7c067cb814cce32540f2a0178fe9e6cda Mon Sep 17 00:00:00 2001 From: Sudharsan Dhamal Gopalarathnam Date: Fri, 10 Sep 2021 06:10:02 +0000 Subject: [PATCH 12/15] UT fixes --- .../flex_counter/flex_counter_manager.cpp | 2 +- orchagent/tunnel_rates.lua | 33 +++++++++++++------ 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/orchagent/flex_counter/flex_counter_manager.cpp b/orchagent/flex_counter/flex_counter_manager.cpp index 084bb466cc..c924b269e8 100644 --- a/orchagent/flex_counter/flex_counter_manager.cpp +++ b/orchagent/flex_counter/flex_counter_manager.cpp @@ -39,7 +39,7 @@ const unordered_map FlexCounterManager::counter_id_field_lo { CounterType::PORT, PORT_COUNTER_ID_LIST }, { CounterType::QUEUE, QUEUE_COUNTER_ID_LIST }, { CounterType::MACSEC_SA_ATTR, MACSEC_SA_ATTR_ID_LIST }, - { CounterType::TUNNEL, TUNNEL_ATTR_ID_LIST }, + { CounterType::TUNNEL, TUNNEL_COUNTER_ID_LIST }, }; FlexManagerDirectory g_FlexManagerDirectory; diff --git a/orchagent/tunnel_rates.lua b/orchagent/tunnel_rates.lua index ef3816210f..3b536c29ac 100644 --- a/orchagent/tunnel_rates.lua +++ b/orchagent/tunnel_rates.lua @@ -33,23 +33,36 @@ for i = 1, n do logit(initialized) -- Get new COUNTERS values - local in_octets = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_IN_OCTETS') - local in_pkts = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_IN_PACKETS') - local out_octets = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_OUT_OCTETS') - local out_pkts = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_OUT_PACKETS') + local in_octets = 0 + local in_packets = 0 + local out_octets = 0 + local out_packets = 0 + + if redis.call('HEXISTS', counters_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_IN_OCTETS') == 1 then + in_octets = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_IN_OCTETS') + end + if redis.call('HEXISTS', counters_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_IN_PACKETS') == 1 then + in_packets = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_IN_PACKETS') + end + if redis.call('HEXISTS', counters_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_OUT_OCTETS') == 1 then + out_octets = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_OUT_OCTETS') + end + if redis.call('HEXISTS', counters_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_OUT_PACKETS') == 1 then + out_packets = redis.call('HGET', counters_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_OUT_PACKETS') + end if initialized == "DONE" or initialized == "COUNTERS_LAST" then -- Get old COUNTERS values local in_octets_last = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_IN_OCTETS_last') - local in_pkts_last = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_IN_PACKETS_last') + local in_packets_last = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_IN_PACKETS_last') local out_octets_last = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_OUT_OCTETS_last') - local out_pkts_last = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_OUT_PACKETS_last') + local out_packets_last = redis.call('HGET', rates_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_OUT_PACKETS_last') -- Calculate new rates values local rx_bps_new = (in_octets - in_octets_last)*sec_to_ms/delta local tx_bps_new = (out_octets - out_octets_last)*sec_to_ms/delta - local rx_pps_new = (in_pkts - in_pkts_last)*sec_to_ms/delta - local tx_pps_new = (out_pkts - out_pkts_last)*sec_to_ms/delta + local rx_pps_new = (in_packets - in_packets_last)*sec_to_ms/delta + local tx_pps_new = (out_packets - out_packets_last)*sec_to_ms/delta if initialized == "DONE" then -- Get old rates values @@ -77,9 +90,9 @@ for i = 1, n do -- Set old COUNTERS values redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_IN_OCTETS_last', in_octets) - redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_IN_PACKETS_last', in_pkts) + redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_IN_PACKETS_last', in_packets) redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_OUT_OCTETS_last', out_octets) - redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_OUT_PACKETS_last', out_pkts) + redis.call('HSET', rates_table_name .. ':' .. KEYS[i], 'SAI_TUNNEL_STAT_OUT_PACKETS_last', out_packets) end return logtable From 7ddb0ab481f7463a22eeec9c02d387b8dfea64cf Mon Sep 17 00:00:00 2001 From: Sudharsan Dhamal Gopalarathnam Date: Thu, 21 Oct 2021 04:25:40 +0000 Subject: [PATCH 13/15] Addressing code review comments --- orchagent/vxlanorch.cpp | 69 ++++++++++++++++++++++++++++------------- orchagent/vxlanorch.h | 6 ++++ 2 files changed, 54 insertions(+), 21 deletions(-) diff --git a/orchagent/vxlanorch.cpp b/orchagent/vxlanorch.cpp index 3a47fcd15e..6888f61df3 100644 --- a/orchagent/vxlanorch.cpp +++ b/orchagent/vxlanorch.cpp @@ -29,6 +29,8 @@ extern PortsOrch* gPortsOrch; extern sai_object_id_t gUnderlayIfId; extern FlexManagerDirectory g_FlexManagerDirectory; +#define FLEX_COUNTER_UPD_INTERVAL 1 + const map vxlanTunnelMap = { { MAP_T::VNI_TO_VLAN_ID, SAI_TUNNEL_MAP_TYPE_VNI_TO_VLAN_ID }, @@ -1190,6 +1192,7 @@ VxlanTunnelOrch::VxlanTunnelOrch(DBConnector *statedb, DBConnector *db, const st FieldValueTuple fv; string tunnel_rate_plugin = "tunnel_rates.lua"; m_counter_db = shared_ptr(new DBConnector("COUNTERS_DB", 0)); + m_asic_db = shared_ptr(new DBConnector("ASIC_DB", 0)); try { string tunnel_rate_script = swss::loadLuaScript(tunnel_rate_plugin); @@ -1207,28 +1210,53 @@ VxlanTunnelOrch::VxlanTunnelOrch(DBConnector *statedb, DBConnector *db, const st m_tunnelNameTable = unique_ptr
(new Table(m_counter_db.get(), COUNTERS_TUNNEL_NAME_MAP)); m_tunnelTypeTable = unique_ptr
(new Table(m_counter_db.get(), COUNTERS_TUNNEL_TYPE_MAP)); + m_vidToRidTable = unique_ptr
(new Table(m_asic_db.get(), "VIDTORID")); + + auto intervT = timespec { .tv_sec = FLEX_COUNTER_UPD_INTERVAL , .tv_nsec = 0 }; + m_FlexCounterUpdTimer = new SelectableTimer(intervT); + auto executorT = new ExecutableTimer(m_FlexCounterUpdTimer, this, "FLEX_COUNTER_UPD_TIMER"); + Orch::addExecutor(executorT); } -void VxlanTunnelOrch::addTunnelToFlexCounter(sai_object_id_t oid, const string &name) +void VxlanTunnelOrch::doTask(SelectableTimer &timer) { SWSS_LOG_ENTER(); - string type = "SAI_TUNNEL_TYPE_VXLAN"; - string sai_oid = sai_serialize_object_id(oid); - vector tunnelNameFvs; - vector tunnelTypeFvs; + SWSS_LOG_DEBUG("Registering %" PRId64 " new tunnels", m_pendingAddToFlexCntr.size()); + for (auto it = m_pendingAddToFlexCntr.begin(); it != m_pendingAddToFlexCntr.end(); ) + { + string value; + const auto id = sai_serialize_object_id(it->first); + + if (m_vidToRidTable->hget("", id, value)) + { + SWSS_LOG_INFO("Registering %s, id %s", it->second.c_str(), id.c_str()); + vector tunnelNameFvs; + vector tunnelTypeFvs; + string type = "SAI_TUNNEL_TYPE_VXLAN"; + + tunnelNameFvs.emplace_back(it->second, id); + tunnelTypeFvs.emplace_back(id, type); - tunnelNameFvs.emplace_back(name, sai_oid); - tunnelTypeFvs.emplace_back(sai_oid, type); + m_tunnelNameTable->set("", tunnelNameFvs); + m_tunnelTypeTable->set("", tunnelTypeFvs); + auto tunnel_stats = generateTunnelCounterStats(); - m_tunnelNameTable->set("", tunnelNameFvs); - m_tunnelTypeTable->set("", tunnelTypeFvs); + tunnel_stat_manager->setCounterIdList(it->first, CounterType::TUNNEL, + tunnel_stats); + it = m_pendingAddToFlexCntr.erase(it); + } + else + { + ++it; + } + } +} - auto tunnel_stats = generateTunnelCounterStats(); - tunnel_stat_manager->setCounterIdList(oid, CounterType::TUNNEL, - tunnel_stats); - SWSS_LOG_DEBUG("Registered tunnel %s to Flex counter", name.c_str()); +void VxlanTunnelOrch::addTunnelToFlexCounter(sai_object_id_t oid, const string &name) +{ + m_pendingAddToFlexCntr[oid] = name; } void VxlanTunnelOrch::removeTunnelFromFlexCounter(sai_object_id_t oid, const string &name) @@ -1241,6 +1269,12 @@ void VxlanTunnelOrch::removeTunnelFromFlexCounter(sai_object_id_t oid, const str return; } + if (m_pendingAddToFlexCntr.find(oid) != m_pendingAddToFlexCntr.end()) + { + m_pendingAddToFlexCntr.erase(oid); + return; + } + string sai_oid = sai_serialize_object_id(oid); m_tunnelNameTable->hdel("", name); @@ -1267,14 +1301,7 @@ void VxlanTunnelOrch::generateTunnelCounterMap() return; } - for (const auto& it: vxlan_tunnel_table_) - { - auto tunnel_id = it.second.get()->getTunnelId(); - if (tunnel_id != SAI_NULL_OBJECT_ID) - { - addTunnelToFlexCounter(it.second.get()->getTunnelId(), it.second.get()->getTunnelName()); - } - } + m_FlexCounterUpdTimer->start(); m_isTunnelCounterMapGenerated = true; } diff --git a/orchagent/vxlanorch.h b/orchagent/vxlanorch.h index d6b9eece8d..6082d4e4b7 100644 --- a/orchagent/vxlanorch.h +++ b/orchagent/vxlanorch.h @@ -7,6 +7,7 @@ #include "request_parser.h" #include "portsorch.h" #include "vrforch.h" +#include "timer.h" enum class MAP_T { @@ -345,18 +346,23 @@ class VxlanTunnelOrch : public Orch2 private: virtual bool addOperation(const Request& request); virtual bool delOperation(const Request& request); + void doTask(swss::SelectableTimer&); VxlanTunnelTable vxlan_tunnel_table_; VxlanTunnelRequest request_; VxlanVniVlanMapTable vxlan_vni_vlan_map_table_; VTEPTable vtep_table_; Table m_stateVxlanTable; + std::map m_pendingAddToFlexCntr; FlexCounterManager vxlan_tunnel_stat_manager; bool m_isTunnelCounterMapGenerated = false; FlexCounterManager *tunnel_stat_manager; unique_ptr
m_tunnelNameTable; unique_ptr
m_tunnelTypeTable; + unique_ptr
m_vidToRidTable; shared_ptr m_counter_db; + shared_ptr m_asic_db; + SelectableTimer* m_FlexCounterUpdTimer = nullptr; }; const request_description_t vxlan_tunnel_map_request_description = { From 366c14a3c3287540397fbcd171371d1a6783ae79 Mon Sep 17 00:00:00 2001 From: Sudharsan Dhamal Gopalarathnam Date: Thu, 21 Oct 2021 04:43:44 +0000 Subject: [PATCH 14/15] Removing leftout merge macros --- orchagent/vxlanorch.h | 1 - 1 file changed, 1 deletion(-) diff --git a/orchagent/vxlanorch.h b/orchagent/vxlanorch.h index 91e45d1737..0b56e76faa 100644 --- a/orchagent/vxlanorch.h +++ b/orchagent/vxlanorch.h @@ -46,7 +46,6 @@ typedef enum #define MAX_VLAN_ID 4095 #define MAX_VNI_ID 16777215 ->>>>>>> upstream/master typedef enum { From c50bbdea066a42ee8ef7304af01646397e38cd5c Mon Sep 17 00:00:00 2001 From: Sudharsan Dhamal Gopalarathnam Date: Fri, 22 Oct 2021 03:49:31 +0000 Subject: [PATCH 15/15] Removing unnecessary log --- orchagent/vxlanorch.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/orchagent/vxlanorch.cpp b/orchagent/vxlanorch.cpp index 4f9fab4ec5..fc6a505a1f 100644 --- a/orchagent/vxlanorch.cpp +++ b/orchagent/vxlanorch.cpp @@ -1292,7 +1292,6 @@ void VxlanTunnelOrch::doTask(SelectableTimer &timer) { SWSS_LOG_ENTER(); - SWSS_LOG_DEBUG("Registering %" PRId64 " new tunnels", m_pendingAddToFlexCntr.size()); for (auto it = m_pendingAddToFlexCntr.begin(); it != m_pendingAddToFlexCntr.end(); ) { string value;