Skip to content

Commit 2cfa571

Browse files
mint570bibhuprasad-hcl
authored andcommitted
Add infra of supporting unique label to be used for SAI label attribute.
Signed-off-by: SRAVANI KANASANI <kanasanis@google.com> Signed-off-by: bibhuprasad-hcl <bibhuprasad.singh@hcltech.com>
1 parent d084258 commit 2cfa571

10 files changed

Lines changed: 336 additions & 3 deletions

File tree

orchagent/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ orchagent_SOURCES = \
102102
flexcounterorch.cpp \
103103
watermarkorch.cpp \
104104
policerorch.cpp \
105+
namelabelmapper.cpp \
105106
sfloworch.cpp \
106107
chassisorch.cpp \
107108
debugcounterorch.cpp \

orchagent/namelabelmapper.cpp

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
#include "namelabelmapper.h"
2+
#include <limits>
3+
#include <sstream>
4+
#include <string>
5+
#include <nlohmann/json.hpp>
6+
#include "logger.h"
7+
#include "sai_serialize.h"
8+
extern "C" {
9+
#include "sai.h"
10+
}
11+
using ::nlohmann::json;
12+
namespace {
13+
std::string convertToDBField(_In_ const sai_object_type_t object_type,
14+
_In_ const std::string& key) {
15+
return sai_serialize_object_type(object_type) + "|" + key;
16+
}
17+
} // namespace
18+
NameLabelMapper::NameLabelMapper()
19+
: m_db("STATE_DB", 0), m_table(&m_db, "SAI_KEY_LABEL_MAP") {}
20+
bool NameLabelMapper::setLabel(_In_ sai_object_type_t object_type,
21+
_In_ const std::string& key,
22+
_In_ std::string& label) {
23+
SWSS_LOG_ENTER();
24+
if (existsLabel(object_type, key)) {
25+
SWSS_LOG_ERROR(
26+
"Key %s with SAI object type %d already exists in label mapper",
27+
key.c_str(), object_type);
28+
return false;
29+
}
30+
m_labelTables[object_type][key] = label;
31+
SWSS_LOG_INFO("Created new label %s for Key %s with SAI object type %d",
32+
label.c_str(), key.c_str(), object_type);
33+
return true;
34+
}
35+
bool NameLabelMapper::getLabel(_In_ sai_object_type_t object_type,
36+
_In_ const std::string& key,
37+
_Out_ std::string& label) {
38+
SWSS_LOG_ENTER();
39+
if (!existsLabel(object_type, key)) {
40+
SWSS_LOG_INFO(
41+
"Key %s with SAI object type %d does not exist in label mapper",
42+
key.c_str(), object_type);
43+
return false;
44+
}
45+
label = m_labelTables[object_type][key];
46+
return true;
47+
}
48+
bool NameLabelMapper::eraseLabel(_In_ sai_object_type_t object_type,
49+
_In_ const std::string& key) {
50+
SWSS_LOG_ENTER();
51+
if (!existsLabel(object_type, key)) {
52+
SWSS_LOG_ERROR(
53+
"Key %s with SAI object type %d does not exist in "
54+
"label mapper when erasing",
55+
key.c_str(), object_type);
56+
return false;
57+
}
58+
m_labelTables[object_type].erase(key);
59+
return true;
60+
}
61+
void NameLabelMapper::deleteMapperInDb() {
62+
SWSS_LOG_ENTER();
63+
m_table.del("");
64+
}
65+
size_t NameLabelMapper::getNumEntries(
66+
_In_ sai_object_type_t object_type) const {
67+
SWSS_LOG_ENTER();
68+
return (m_labelTables[object_type].size());
69+
}
70+
bool NameLabelMapper::existsLabel(_In_ sai_object_type_t object_type,
71+
_In_ const std::string& key) const {
72+
SWSS_LOG_ENTER();
73+
return m_labelTables[object_type].find(key) !=
74+
m_labelTables[object_type].end();
75+
}
76+
std::string NameLabelMapper::generateKeyFromTableAndObjectName(
77+
std::string table_name, std::string object_name) {
78+
return table_name + object_name;
79+
}
80+
std::string NameLabelMapper::generateUniqueLabel() {
81+
char label_buf[UNIQUE_LABEL_SIZE];
82+
uint64_t msec = std::chrono::duration_cast<std::chrono::microseconds>(
83+
std::chrono::system_clock::now().time_since_epoch())
84+
.count();
85+
snprintf(label_buf, UNIQUE_LABEL_SIZE, "%" PRIu64 "", msec);
86+
return std::string(reinterpret_cast<char const*>(label_buf));
87+
}
88+
bool NameLabelMapper::allocateLabel(_In_ sai_object_type_t object_type,
89+
_In_ const std::string& key,
90+
_Out_ std::string& label) {
91+
if (!getLabel(object_type, key, label)) {
92+
label = generateUniqueLabel();
93+
return false;
94+
}
95+
return true;
96+
}
97+
std::string NameLabelMapper::dumpStateCache() {
98+
json cache = json({});
99+
for (int i = 0; i < SAI_OBJECT_TYPE_MAX; i++) {
100+
if (m_labelTables[i].empty()) {
101+
continue;
102+
}
103+
json label_mapper_j = json({});
104+
for (const auto& kv_pair : m_labelTables[i]) {
105+
label_mapper_j[kv_pair.first] = kv_pair.second;
106+
}
107+
std::string sai_object_type =
108+
sai_serialize_object_type(static_cast<sai_object_type_t>(i));
109+
cache[sai_object_type] = label_mapper_j;
110+
}
111+
return cache.dump(4);
112+
}
113+
void NameLabelMapper::saveMapperToDb() {
114+
for (int i = 0; i < SAI_OBJECT_TYPE_MAX; i++) {
115+
if (m_labelTables[i].empty()) {
116+
continue;
117+
}
118+
for (const auto& kv_pair : m_labelTables[i]) {
119+
auto key = kv_pair.first;
120+
auto label = kv_pair.second;
121+
m_table.hset("", convertToDBField(static_cast<sai_object_type_t>(i), key),
122+
label);
123+
SWSS_LOG_INFO(
124+
"label %s for Key %s with SAI object type %d save into state_db",
125+
label.c_str(), key.c_str(), i);
126+
}
127+
}
128+
}
129+
void NameLabelMapper::readMapperFromDb() {
130+
std::vector<swss::FieldValueTuple> tuples;
131+
m_table.get("", tuples);
132+
SWSS_LOG_INFO("m_table->get size %zd", tuples.size());
133+
for (auto& fv : tuples) {
134+
std::string combo = fvField(fv);
135+
std::string label = fvValue(fv);
136+
SWSS_LOG_INFO("Got field %s label %s from db", combo.c_str(),
137+
label.c_str());
138+
size_t pos = 0;
139+
std::string obj_type_str, key;
140+
if ((pos = combo.find("|")) != std::string::npos) {
141+
obj_type_str = combo.substr(0, pos);
142+
key = combo.substr(pos + 1, combo.size() - pos - 1);
143+
sai_object_type_t sai_object_type;
144+
sai_deserialize_object_type(obj_type_str, sai_object_type);
145+
setLabel(sai_object_type, key, label);
146+
}
147+
}
148+
}
149+

orchagent/namelabelmapper.h

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#pragma once
2+
#include <inttypes.h>
3+
#include <chrono>
4+
#include <cstdint>
5+
#include <ctime>
6+
#include <string>
7+
#include <unordered_map>
8+
#include "dbconnector.h"
9+
#include "table.h"
10+
extern "C" {
11+
#include "sai.h"
12+
}
13+
#define UNIQUE_LABEL_SIZE 32
14+
// Interface for mapping object name/key to unique Label.
15+
// This class is not thread safe.
16+
class NameLabelMapper {
17+
public:
18+
NameLabelMapper();
19+
~NameLabelMapper() = default;
20+
// Sets label for the given key for the specific object_type. Returns false if
21+
// the key already exists.
22+
bool setLabel(_In_ sai_object_type_t object_type, _In_ const std::string& key,
23+
_In_ std::string& label);
24+
// Return true if label present in the mapper, and copy the label in the 3rd
25+
// argument; or false, and a new unique label is allocated and saved in mapper
26+
bool allocateLabel(_In_ sai_object_type_t object_type,
27+
_In_ const std::string& key, _Out_ std::string& label);
28+
// Gets label from mapper for the given key for the SAI object_type.
29+
// Returns true on success.
30+
bool getLabel(_In_ sai_object_type_t object_type, _In_ const std::string& key,
31+
_Out_ std::string& label);
32+
// Erases label for the given key for the SAI object_type.
33+
// Returns true on success.
34+
bool eraseLabel(_In_ sai_object_type_t object_type,
35+
_In_ const std::string& key);
36+
// Delete mapper table in db
37+
void deleteMapperInDb();
38+
// Gets the number of labels for the SAI object_type.
39+
size_t getNumEntries(_In_ sai_object_type_t object_type) const;
40+
// SAI object subtype and name to label mapper name
41+
// Returns concat of (subtype + object_name)
42+
// For example, for POLICER, there are 4 subtypes:
43+
// COPP trap group, ACL policer, storm policer, regular policer
44+
// One way is use APPL_DB table name in subtype field, that is
45+
// subtype = APPL_DB table name
46+
std::string generateKeyFromTableAndObjectName(std::string table_name,
47+
std::string object_name);
48+
// Save the all entries to state db
49+
void saveMapperToDb();
50+
// Read the all entries from state db
51+
void readMapperFromDb();
52+
// Returns a json string that contains each non-empty label mapper.
53+
std::string dumpStateCache();
54+
// Checks whether label mapping exists for the given key for the specific
55+
// object type.
56+
bool existsLabel(_In_ sai_object_type_t object_type,
57+
_In_ const std::string& key) const;
58+
private:
59+
// Generate and return a unique label
60+
std::string generateUniqueLabel();
61+
// Buckets of map tables, one for every SAI object type.
62+
std::unordered_map<std::string, std::string>
63+
m_labelTables[SAI_OBJECT_TYPE_MAX];
64+
swss::DBConnector m_db;
65+
swss::Table m_table;
66+
};

orchagent/orchdaemon.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "orchdaemon.h"
66
#include "logger.h"
77
#include <sairedis.h>
8+
#include "namelabelmapper.h"
89
#include "warm_restart.h"
910
#include <iostream>
1011
#include "orch_zmq_config.h"
@@ -71,7 +72,7 @@ StpOrch *gStpOrch;
7172
MuxOrch *gMuxOrch;
7273
IcmpOrch *gIcmpOrch;
7374
HFTelOrch *gHFTOrch;
74-
75+
NameLabelMapper *gLabelMapper;
7576
bool gIsNatSupported = false;
7677
event_handle_t g_events_handle;
7778

@@ -167,6 +168,7 @@ void OrchDaemon::disableRingBuffer() {
167168
bool OrchDaemon::init()
168169
{
169170
SWSS_LOG_ENTER();
171+
gLabelMapper = new NameLabelMapper();
170172

171173
string platform = getenv("platform") ? getenv("platform") : "";
172174

@@ -1058,7 +1060,8 @@ bool OrchDaemon::warmRestoreAndSyncUp()
10581060
SWSS_LOG_ENTER();
10591061

10601062
WarmStart::setWarmStartState("orchagent", WarmStart::INITIALIZED);
1061-
1063+
gLabelMapper->readMapperFromDb();
1064+
10621065
for (Orch *o : m_orchList)
10631066
{
10641067
o->bake();
@@ -1129,6 +1132,7 @@ bool OrchDaemon::warmRestoreAndSyncUp()
11291132
* The "RECONCILED" state of orchagent doesn't mean the state related to neighbor is up to date.
11301133
*/
11311134
WarmStart::setWarmStartState("orchagent", WarmStart::RECONCILED);
1135+
gLabelMapper->deleteMapperInDb();
11321136
return true;
11331137
}
11341138

orchagent/p4orch/p4orch.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include "copporch.h"
99
#include "logger.h"
10+
#include "namelabelmapper.h"
1011
#include "orch.h"
1112
#include "p4orch/acl_rule_manager.h"
1213
#include "p4orch/acl_table_manager.h"
@@ -27,8 +28,9 @@
2728
#include "sai_serialize.h"
2829
#include "timer.h"
2930
#include "timestamp.h"
30-
31+
extern NameLabelMapper* gLabelMapper;
3132
extern PortsOrch *gPortsOrch;
33+
3234
#define P4_ACL_COUNTERS_STATS_POLL_TIMER_NAME "P4_ACL_COUNTERS_STATS_POLL_TIMER"
3335
#define P4_EXT_COUNTERS_STATS_POLL_TIMER_NAME "P4_EXT_COUNTERS_STATS_POLL_TIMER"
3436
#define APP_P4RT_EXT_TABLES_MANAGER "EXT_TABLES_MANAGER"

orchagent/p4orch/tests/Makefile.am

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ p4orch_tests_SOURCES = $(ORCHAGENT_DIR)/orch.cpp \
2828
$(ORCHAGENT_DIR)/switchorch.cpp \
2929
$(ORCHAGENT_DIR)/request_parser.cpp \
3030
$(top_srcdir)/lib/recorder.cpp \
31+
$(ORCHAGENT_DIR)/namelabelmapper.cpp \
3132
$(ORCHAGENT_DIR)/flex_counter/flex_counter_manager.cpp \
3233
$(ORCHAGENT_DIR)/flex_counter/flow_counter_handler.cpp \
3334
$(ORCHAGENT_DIR)/port/port_capabilities.cpp \
@@ -64,7 +65,9 @@ p4orch_tests_SOURCES = $(ORCHAGENT_DIR)/orch.cpp \
6465
fake_notificationconsumer.cpp \
6566
fake_table.cpp \
6667
fake_aclorch.cpp \
68+
fake_namelabelmapper.cpp \
6769
p4oidmapper_test.cpp \
70+
namelabelmapper_test.cpp \
6871
p4orch_test.cpp \
6972
p4orch_util_test.cpp \
7073
return_code_test.cpp \
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#include "namelabelmapper.h"
2+
NameLabelMapper *gLabelMapper = new NameLabelMapper();

0 commit comments

Comments
 (0)