Skip to content

Commit 69c93cf

Browse files
oleksandrivantsivShuotian Cheng
authored andcommitted
orchagent: Fixing issue setting DSCP to MIRROR_SESSION_DEFAULT_TOS (sonic-net#163)
1 parent c1530d8 commit 69c93cf

File tree

1 file changed

+78
-34
lines changed

1 file changed

+78
-34
lines changed

orchagent/mirrororch.cpp

Lines changed: 78 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <linux/if_ether.h>
22

33
#include <utility>
4+
#include <exception>
45

56
#include "logger.h"
67
#include "swssnet.h"
@@ -19,12 +20,41 @@
1920
#define MIRROR_SESSION_DEFAULT_VLAN_PRI 0
2021
#define MIRROR_SESSION_DEFAULT_VLAN_CFI 0
2122
#define MIRROR_SESSION_DEFAULT_IP_HDR_VER 4
22-
#define MIRROR_SESSION_DEFAULT_TOS 0
23+
#define MIRROR_SESSION_DSCP_SHIFT 2
24+
#define MIRROR_SESSION_DSCP_MIN 0
25+
#define MIRROR_SESSION_DSCP_MAX 63
2326

2427
extern sai_mirror_api_t *sai_mirror_api;
2528

2629
using namespace std::rel_ops;
2730

31+
static inline uint64_t to_uint64(string str, uint64_t min = numeric_limits<uint64_t>::min(), uint64_t max = numeric_limits<uint64_t>::max())
32+
{
33+
size_t idx = 0;
34+
uint64_t ret = stoul(str, &idx, 0);
35+
if (str[idx])
36+
{
37+
throw invalid_argument("failed to convert " + str + " value to uint64_t type");
38+
}
39+
40+
if (ret < min || ret > max)
41+
{
42+
throw invalid_argument("failed to convert " + str + " value is not in range " + to_string(min) + " - " + to_string(max));
43+
}
44+
45+
return ret;
46+
}
47+
48+
static inline uint16_t to_uint16(string str, uint16_t min = numeric_limits<uint16_t>::min(), uint16_t max = numeric_limits<uint16_t>::max())
49+
{
50+
return static_cast<uint16_t>(to_uint64(str, min, max));
51+
}
52+
53+
static inline uint8_t to_uint8(string str, uint8_t min = numeric_limits<uint8_t>::min(), uint8_t max = numeric_limits<uint8_t>::max())
54+
{
55+
return static_cast<uint8_t>(to_uint64(str, min, max));
56+
}
57+
2858
MirrorOrch::MirrorOrch(DBConnector *db, string tableName,
2959
PortsOrch *portOrch, RouteOrch *routeOrch, NeighOrch *neighOrch, FdbOrch *fdbOrch) :
3060
Orch(db, tableName),
@@ -161,49 +191,61 @@ void MirrorOrch::createEntry(const string& key, const vector<FieldValueTuple>& d
161191

162192
for (auto i : data)
163193
{
164-
if (fvField(i) == MIRROR_SESSION_SRC_IP)
165-
{
166-
entry.srcIp = fvValue(i);
167-
if (!entry.srcIp.isV4())
194+
try {
195+
if (fvField(i) == MIRROR_SESSION_SRC_IP)
196+
{
197+
entry.srcIp = fvValue(i);
198+
if (!entry.srcIp.isV4())
199+
{
200+
SWSS_LOG_ERROR("Unsupported version of sessions %s source IP address\n", key.c_str());
201+
return;
202+
}
203+
}
204+
else if (fvField(i) == MIRROR_SESSION_DST_IP)
205+
{
206+
entry.dstIp = fvValue(i);
207+
if (!entry.dstIp.isV4())
208+
{
209+
SWSS_LOG_ERROR("Unsupported version of sessions %s destination IP address\n", key.c_str());
210+
return;
211+
}
212+
}
213+
else if (fvField(i) == MIRROR_SESSION_GRE_TYPE)
214+
{
215+
entry.greType = to_uint16(fvValue(i));
216+
}
217+
else if (fvField(i) == MIRROR_SESSION_DSCP)
218+
{
219+
entry.dscp = to_uint8(fvValue(i), MIRROR_SESSION_DSCP_MIN, MIRROR_SESSION_DSCP_MAX);
220+
}
221+
else if (fvField(i) == MIRROR_SESSION_TTL)
222+
{
223+
entry.ttl = to_uint8(fvValue(i));
224+
}
225+
else if (fvField(i) == MIRROR_SESSION_QUEUE)
168226
{
169-
SWSS_LOG_ERROR("Unsupported version of sessions %s source IP address\n", key.c_str());
227+
entry.queue = to_uint8(fvValue(i));
228+
}
229+
else if (fvField(i) == MIRROR_SESSION_STATUS)
230+
{
231+
// Status update always caused by MirrorOrch and should
232+
// not be changed by users. Ignore it.
170233
return;
171234
}
172-
}
173-
else if (fvField(i) == MIRROR_SESSION_DST_IP)
174-
{
175-
entry.dstIp = fvValue(i);
176-
if (!entry.dstIp.isV4())
235+
else
177236
{
178-
SWSS_LOG_ERROR("Unsupported version of sessions %s destination IP address\n", key.c_str());
237+
SWSS_LOG_ERROR("Failed to parse session %s configuration. Unknown attribute %s.\n", key.c_str(), fvField(i).c_str());
179238
return;
180239
}
181240
}
182-
else if (fvField(i) == MIRROR_SESSION_GRE_TYPE)
183-
{
184-
entry.greType = stoul(fvValue(i), NULL, 0);
185-
}
186-
else if (fvField(i) == MIRROR_SESSION_DSCP)
187-
{
188-
entry.dscp = stoul(fvValue(i), NULL, 0);
189-
}
190-
else if (fvField(i) == MIRROR_SESSION_TTL)
241+
catch (const exception& e)
191242
{
192-
entry.ttl = stoul(fvValue(i), NULL, 0);
193-
}
194-
else if (fvField(i) == MIRROR_SESSION_QUEUE)
195-
{
196-
entry.queue = stoul(fvValue(i), NULL, 0);
197-
}
198-
else if (fvField(i) == MIRROR_SESSION_STATUS)
199-
{
200-
// Status update always caused by MirrorOrch and should
201-
// not be changed by users. Ignore it.
243+
SWSS_LOG_ERROR("Failed to parse session %s attribute %s error: %s.", key.c_str(), fvField(i).c_str(), e.what());
202244
return;
203245
}
204-
else
246+
catch (...)
205247
{
206-
SWSS_LOG_ERROR("Failed to parse session %s configuration. Unknown attribute %s.\n", key.c_str(), fvField(i).c_str());
248+
SWSS_LOG_ERROR("Failed to parse session %s attribute %s. Unknown error has been occurred", key.c_str(), fvField(i).c_str());
207249
return;
208250
}
209251
}
@@ -403,8 +445,10 @@ bool MirrorOrch::activateSession(const string& name, MirrorEntry& session)
403445
attr.value.u8 = MIRROR_SESSION_DEFAULT_IP_HDR_VER;
404446
attrs.push_back(attr);
405447

448+
// TOS value format is the following:
449+
// DSCP 6 bits | ECN 2 bits
406450
attr.id =SAI_MIRROR_SESSION_ATTR_TOS;
407-
attr.value.u16 = MIRROR_SESSION_DEFAULT_TOS;
451+
attr.value.u16 = session.dscp << MIRROR_SESSION_DSCP_SHIFT;
408452
attrs.push_back(attr);
409453

410454
attr.id =SAI_MIRROR_SESSION_ATTR_TTL;

0 commit comments

Comments
 (0)