|
1 | 1 | #include <linux/if_ether.h>
|
2 | 2 |
|
3 | 3 | #include <utility>
|
| 4 | +#include <exception> |
4 | 5 |
|
5 | 6 | #include "logger.h"
|
6 | 7 | #include "swssnet.h"
|
|
19 | 20 | #define MIRROR_SESSION_DEFAULT_VLAN_PRI 0
|
20 | 21 | #define MIRROR_SESSION_DEFAULT_VLAN_CFI 0
|
21 | 22 | #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 |
23 | 26 |
|
24 | 27 | extern sai_mirror_api_t *sai_mirror_api;
|
25 | 28 |
|
26 | 29 | using namespace std::rel_ops;
|
27 | 30 |
|
| 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 | + |
28 | 58 | MirrorOrch::MirrorOrch(DBConnector *db, string tableName,
|
29 | 59 | PortsOrch *portOrch, RouteOrch *routeOrch, NeighOrch *neighOrch, FdbOrch *fdbOrch) :
|
30 | 60 | Orch(db, tableName),
|
@@ -161,49 +191,61 @@ void MirrorOrch::createEntry(const string& key, const vector<FieldValueTuple>& d
|
161 | 191 |
|
162 | 192 | for (auto i : data)
|
163 | 193 | {
|
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) |
168 | 226 | {
|
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. |
170 | 233 | return;
|
171 | 234 | }
|
172 |
| - } |
173 |
| - else if (fvField(i) == MIRROR_SESSION_DST_IP) |
174 |
| - { |
175 |
| - entry.dstIp = fvValue(i); |
176 |
| - if (!entry.dstIp.isV4()) |
| 235 | + else |
177 | 236 | {
|
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()); |
179 | 238 | return;
|
180 | 239 | }
|
181 | 240 | }
|
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) |
191 | 242 | {
|
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()); |
202 | 244 | return;
|
203 | 245 | }
|
204 |
| - else |
| 246 | + catch (...) |
205 | 247 | {
|
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()); |
207 | 249 | return;
|
208 | 250 | }
|
209 | 251 | }
|
@@ -403,8 +445,10 @@ bool MirrorOrch::activateSession(const string& name, MirrorEntry& session)
|
403 | 445 | attr.value.u8 = MIRROR_SESSION_DEFAULT_IP_HDR_VER;
|
404 | 446 | attrs.push_back(attr);
|
405 | 447 |
|
| 448 | + // TOS value format is the following: |
| 449 | + // DSCP 6 bits | ECN 2 bits |
406 | 450 | 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; |
408 | 452 | attrs.push_back(attr);
|
409 | 453 |
|
410 | 454 | attr.id =SAI_MIRROR_SESSION_ATTR_TTL;
|
|
0 commit comments