Skip to content

Commit a169dde

Browse files
committed
[trim]: Add Packet Trimming Asym DSCP to OA
Signed-off-by: Nazarii Hnydyn <[email protected]>
1 parent f53cc8c commit a169dde

25 files changed

Lines changed: 2510 additions & 142 deletions

orchagent/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ orchagent_SOURCES = \
6868
copporch.cpp \
6969
tunneldecaporch.cpp \
7070
qosorch.cpp \
71+
buffer/bufferhelper.cpp \
7172
bufferorch.cpp \
7273
mirrororch.cpp \
7374
fdborch.cpp \

orchagent/buffer/buffercontainer.h

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#pragma once
2+
3+
#include <cstdbool>
4+
#include <cstdint>
5+
6+
#include <unordered_map>
7+
#include <unordered_set>
8+
#include <string>
9+
10+
class BufferContainer
11+
{
12+
public:
13+
BufferContainer() = default;
14+
virtual ~BufferContainer() = default;
15+
16+
std::unordered_map<std::string, std::string> fieldValueMap;
17+
};
18+
19+
class BufferProfileConfig final : public BufferContainer
20+
{
21+
public:
22+
BufferProfileConfig() = default;
23+
~BufferProfileConfig() = default;
24+
25+
inline bool isTrimmingProhibited() const
26+
{
27+
return ((pgRefCount > 0) || (iBufProfListRefCount > 0) || (eBufProfListRefCount)) ? true : false;
28+
}
29+
30+
std::uint64_t pgRefCount = 0;
31+
std::uint64_t iBufProfListRefCount = 0;
32+
std::uint64_t eBufProfListRefCount = 0;
33+
34+
bool isTrimmingEligible = false;
35+
};
36+
37+
class BufferPriorityGroupConfig final : public BufferContainer
38+
{
39+
public:
40+
BufferPriorityGroupConfig() = default;
41+
~BufferPriorityGroupConfig() = default;
42+
43+
struct {
44+
std::string value;
45+
bool is_set = false;
46+
} profile;
47+
};
48+
49+
class IngressBufferProfileListConfig final : public BufferContainer
50+
{
51+
public:
52+
IngressBufferProfileListConfig() = default;
53+
~IngressBufferProfileListConfig() = default;
54+
55+
struct {
56+
std::unordered_set<std::string> value;
57+
bool is_set = false;
58+
} profile_list;
59+
};
60+
61+
class EgressBufferProfileListConfig final : public BufferContainer
62+
{
63+
public:
64+
EgressBufferProfileListConfig() = default;
65+
~EgressBufferProfileListConfig() = default;
66+
67+
struct {
68+
std::unordered_set<std::string> value;
69+
bool is_set = false;
70+
} profile_list;
71+
};

orchagent/buffer/bufferhelper.cpp

Lines changed: 303 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,303 @@
1+
// includes -----------------------------------------------------------------------------------------------------------
2+
3+
#include <unordered_map>
4+
#include <string>
5+
6+
#include <tokenize.h>
7+
8+
#include "bufferschema.h"
9+
10+
#include "bufferhelper.h"
11+
12+
using namespace swss;
13+
14+
// helper -------------------------------------------------------------------------------------------------------------
15+
16+
void BufferHelper::parseBufferConfig(BufferProfileConfig &cfg) const
17+
{
18+
auto &map = cfg.fieldValueMap;
19+
20+
const auto &cit = map.find(BUFFER_PROFILE_PACKET_DISCARD_ACTION);
21+
if (cit != map.cend())
22+
{
23+
cfg.isTrimmingEligible = cit->second == BUFFER_PROFILE_PACKET_DISCARD_ACTION_TRIM ? true : false;
24+
}
25+
}
26+
27+
void BufferHelper::parseBufferConfig(BufferPriorityGroupConfig &cfg) const
28+
{
29+
auto &map = cfg.fieldValueMap;
30+
31+
const auto &cit = map.find(BUFFER_PG_PROFILE);
32+
if (cit != map.cend())
33+
{
34+
cfg.profile.value = cit->second;
35+
cfg.profile.is_set = true;
36+
}
37+
}
38+
39+
void BufferHelper::parseBufferConfig(IngressBufferProfileListConfig &cfg) const
40+
{
41+
auto &map = cfg.fieldValueMap;
42+
43+
const auto &cit = map.find(BUFFER_PORT_INGRESS_PROFILE_LIST_PROFILE_LIST);
44+
if (cit != map.cend())
45+
{
46+
auto profList = tokenize(cit->second, ',');
47+
48+
cfg.profile_list.value.insert(profList.begin(), profList.end());
49+
cfg.profile_list.is_set = true;
50+
}
51+
}
52+
53+
void BufferHelper::parseBufferConfig(EgressBufferProfileListConfig &cfg) const
54+
{
55+
auto &map = cfg.fieldValueMap;
56+
57+
const auto &cit = map.find(BUFFER_PORT_EGRESS_PROFILE_LIST_PROFILE_LIST);
58+
if (cit != map.cend())
59+
{
60+
auto profList = tokenize(cit->second, ',');
61+
62+
cfg.profile_list.value.insert(profList.begin(), profList.end());
63+
cfg.profile_list.is_set = true;
64+
}
65+
}
66+
67+
template<>
68+
void BufferHelper::setObjRef(const BufferProfileConfig &cfg)
69+
{
70+
// No actions are required
71+
}
72+
73+
template<>
74+
void BufferHelper::setObjRef(const BufferPriorityGroupConfig &cfg)
75+
{
76+
if (cfg.profile.is_set)
77+
{
78+
const auto &cit = profMap.find(cfg.profile.value);
79+
if (cit != profMap.cend())
80+
{
81+
cit->second.pgRefCount++;
82+
}
83+
}
84+
}
85+
86+
template<>
87+
void BufferHelper::setObjRef(const IngressBufferProfileListConfig &cfg)
88+
{
89+
if (cfg.profile_list.is_set)
90+
{
91+
for (const auto &cit1 : cfg.profile_list.value)
92+
{
93+
const auto &cit2 = profMap.find(cit1);
94+
if (cit2 != profMap.cend())
95+
{
96+
cit2->second.iBufProfListRefCount++;
97+
}
98+
}
99+
}
100+
}
101+
102+
template<>
103+
void BufferHelper::setObjRef(const EgressBufferProfileListConfig &cfg)
104+
{
105+
if (cfg.profile_list.is_set)
106+
{
107+
for (const auto &cit1 : cfg.profile_list.value)
108+
{
109+
const auto &cit2 = profMap.find(cit1);
110+
if (cit2 != profMap.cend())
111+
{
112+
cit2->second.eBufProfListRefCount++;
113+
}
114+
}
115+
}
116+
}
117+
118+
template<>
119+
void BufferHelper::delObjRef(const BufferProfileConfig &cfg)
120+
{
121+
// No actions are required
122+
}
123+
124+
template<>
125+
void BufferHelper::delObjRef(const BufferPriorityGroupConfig &cfg)
126+
{
127+
if (cfg.profile.is_set)
128+
{
129+
const auto &cit = profMap.find(cfg.profile.value);
130+
if (cit != profMap.cend())
131+
{
132+
cit->second.pgRefCount--;
133+
}
134+
}
135+
}
136+
137+
template<>
138+
void BufferHelper::delObjRef(const IngressBufferProfileListConfig &cfg)
139+
{
140+
if (cfg.profile_list.is_set)
141+
{
142+
for (const auto &cit1 : cfg.profile_list.value)
143+
{
144+
const auto &cit2 = profMap.find(cit1);
145+
if (cit2 != profMap.cend())
146+
{
147+
cit2->second.iBufProfListRefCount--;
148+
}
149+
}
150+
}
151+
}
152+
153+
template<>
154+
void BufferHelper::delObjRef(const EgressBufferProfileListConfig &cfg)
155+
{
156+
if (cfg.profile_list.is_set)
157+
{
158+
for (const auto &cit1 : cfg.profile_list.value)
159+
{
160+
const auto &cit2 = profMap.find(cit1);
161+
if (cit2 != profMap.cend())
162+
{
163+
cit2->second.eBufProfListRefCount--;
164+
}
165+
}
166+
}
167+
}
168+
169+
template<>
170+
auto BufferHelper::getBufferObjMap() const -> const std::unordered_map<std::string, BufferProfileConfig>&
171+
{
172+
return profMap;
173+
}
174+
175+
template<>
176+
auto BufferHelper::getBufferObjMap() const -> const std::unordered_map<std::string, BufferPriorityGroupConfig>&
177+
{
178+
return pgMap;
179+
}
180+
181+
template<>
182+
auto BufferHelper::getBufferObjMap() const -> const std::unordered_map<std::string, IngressBufferProfileListConfig>&
183+
{
184+
return iBufProfListMap;
185+
}
186+
187+
template<>
188+
auto BufferHelper::getBufferObjMap() const -> const std::unordered_map<std::string, EgressBufferProfileListConfig>&
189+
{
190+
return eBufProfListMap;
191+
}
192+
193+
template<>
194+
auto BufferHelper::getBufferObjMap() -> std::unordered_map<std::string, BufferProfileConfig>&
195+
{
196+
return profMap;
197+
}
198+
199+
template<>
200+
auto BufferHelper::getBufferObjMap() -> std::unordered_map<std::string, BufferPriorityGroupConfig>&
201+
{
202+
return pgMap;
203+
}
204+
205+
template<>
206+
auto BufferHelper::getBufferObjMap() -> std::unordered_map<std::string, IngressBufferProfileListConfig>&
207+
{
208+
return iBufProfListMap;
209+
}
210+
211+
template<>
212+
auto BufferHelper::getBufferObjMap() -> std::unordered_map<std::string, EgressBufferProfileListConfig>&
213+
{
214+
return eBufProfListMap;
215+
}
216+
217+
template<typename T>
218+
void BufferHelper::setBufferConfig(const std::string &key, const T &cfg)
219+
{
220+
auto &map = getBufferObjMap<T>();
221+
222+
const auto &cit = map.find(key);
223+
if (cit != map.cend())
224+
{
225+
delObjRef(cit->second);
226+
}
227+
setObjRef(cfg);
228+
229+
map[key] = cfg;
230+
}
231+
232+
template void BufferHelper::setBufferConfig(const std::string &key, const BufferProfileConfig &cfg);
233+
template void BufferHelper::setBufferConfig(const std::string &key, const BufferPriorityGroupConfig &cfg);
234+
template void BufferHelper::setBufferConfig(const std::string &key, const IngressBufferProfileListConfig &cfg);
235+
template void BufferHelper::setBufferConfig(const std::string &key, const EgressBufferProfileListConfig &cfg);
236+
237+
template<typename T>
238+
bool BufferHelper::getBufferConfig(T &cfg, const std::string &key) const
239+
{
240+
auto &map = getBufferObjMap<T>();
241+
242+
const auto &cit = map.find(key);
243+
if (cit != map.cend())
244+
{
245+
cfg = cit->second;
246+
return true;
247+
}
248+
249+
return false;
250+
}
251+
252+
template bool BufferHelper::getBufferConfig(BufferProfileConfig &cfg, const std::string &key) const;
253+
template bool BufferHelper::getBufferConfig(BufferPriorityGroupConfig &cfg, const std::string &key) const;
254+
template bool BufferHelper::getBufferConfig(IngressBufferProfileListConfig &cfg, const std::string &key) const;
255+
template bool BufferHelper::getBufferConfig(EgressBufferProfileListConfig &cfg, const std::string &key) const;
256+
257+
void BufferHelper::delBufferProfileConfig(const std::string &key)
258+
{
259+
const auto &cit = profMap.find(key);
260+
if (cit == profMap.cend())
261+
{
262+
return;
263+
}
264+
265+
delObjRef(cit->second);
266+
profMap.erase(cit);
267+
}
268+
269+
void BufferHelper::delBufferPriorityGroupConfig(const std::string &key)
270+
{
271+
const auto &cit = pgMap.find(key);
272+
if (cit == pgMap.cend())
273+
{
274+
return;
275+
}
276+
277+
delObjRef(cit->second);
278+
pgMap.erase(cit);
279+
}
280+
281+
void BufferHelper::delIngressBufferProfileListConfig(const std::string &key)
282+
{
283+
const auto &cit = iBufProfListMap.find(key);
284+
if (cit == iBufProfListMap.cend())
285+
{
286+
return;
287+
}
288+
289+
delObjRef(cit->second);
290+
iBufProfListMap.erase(cit);
291+
}
292+
293+
void BufferHelper::delEgressBufferProfileListConfig(const std::string &key)
294+
{
295+
const auto &cit = eBufProfListMap.find(key);
296+
if (cit == eBufProfListMap.cend())
297+
{
298+
return;
299+
}
300+
301+
delObjRef(cit->second);
302+
eBufProfListMap.erase(cit);
303+
}

0 commit comments

Comments
 (0)