Skip to content

Commit c9ad7c3

Browse files
bingwang-mspreetham-singh
authored andcommitted
Support tunnel traffic QoS remapping (sonic-net#2190)
* Support tunnel traffic remap Signed-off-by: bingwang <[email protected]>
1 parent 7af671c commit c9ad7c3

File tree

8 files changed

+649
-81
lines changed

8 files changed

+649
-81
lines changed

orchagent/muxorch.cpp

+64-4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "aclorch.h"
2424
#include "routeorch.h"
2525
#include "fdborch.h"
26+
#include "qosorch.h"
2627

2728
/* Global variables */
2829
extern Directory<Orch*> gDirectory;
@@ -32,6 +33,7 @@ extern RouteOrch *gRouteOrch;
3233
extern AclOrch *gAclOrch;
3334
extern PortsOrch *gPortsOrch;
3435
extern FdbOrch *gFdbOrch;
36+
extern QosOrch *gQosOrch;
3537

3638
extern sai_object_id_t gVirtualRouterId;
3739
extern sai_object_id_t gUnderlayIfId;
@@ -42,7 +44,6 @@ extern sai_next_hop_api_t* sai_next_hop_api;
4244
extern sai_router_interface_api_t* sai_router_intfs_api;
4345

4446
/* Constants */
45-
#define MUX_TUNNEL "MuxTunnel0"
4647
#define MUX_ACL_TABLE_NAME INGRESS_TABLE_DROP
4748
#define MUX_ACL_RULE_NAME "mux_acl_rule"
4849
#define MUX_HW_STATE_UNKNOWN "unknown"
@@ -162,7 +163,12 @@ static sai_status_t remove_route(IpPrefix &pfx)
162163
return status;
163164
}
164165

165-
static sai_object_id_t create_tunnel(const IpAddress* p_dst_ip, const IpAddress* p_src_ip)
166+
static sai_object_id_t create_tunnel(
167+
const IpAddress* p_dst_ip,
168+
const IpAddress* p_src_ip,
169+
sai_object_id_t tc_to_dscp_map_id,
170+
sai_object_id_t tc_to_queue_map_id,
171+
string dscp_mode_name)
166172
{
167173
sai_status_t status;
168174

@@ -206,6 +212,22 @@ static sai_object_id_t create_tunnel(const IpAddress* p_dst_ip, const IpAddress*
206212
attr.value.s32 = SAI_TUNNEL_TTL_MODE_PIPE_MODEL;
207213
tunnel_attrs.push_back(attr);
208214

215+
if (dscp_mode_name == "uniform" || dscp_mode_name == "pipe")
216+
{
217+
sai_tunnel_dscp_mode_t dscp_mode;
218+
if (dscp_mode_name == "uniform")
219+
{
220+
dscp_mode = SAI_TUNNEL_DSCP_MODE_UNIFORM_MODEL;
221+
}
222+
else
223+
{
224+
dscp_mode = SAI_TUNNEL_DSCP_MODE_PIPE_MODEL;
225+
}
226+
attr.id = SAI_TUNNEL_ATTR_ENCAP_DSCP_MODE;
227+
attr.value.s32 = dscp_mode;
228+
tunnel_attrs.push_back(attr);
229+
}
230+
209231
attr.id = SAI_TUNNEL_ATTR_LOOPBACK_PACKET_ACTION;
210232
attr.value.s32 = SAI_PACKET_ACTION_DROP;
211233
tunnel_attrs.push_back(attr);
@@ -224,6 +246,22 @@ static sai_object_id_t create_tunnel(const IpAddress* p_dst_ip, const IpAddress*
224246
tunnel_attrs.push_back(attr);
225247
}
226248

249+
// DSCP rewriting
250+
if (tc_to_dscp_map_id != SAI_NULL_OBJECT_ID)
251+
{
252+
attr.id = SAI_TUNNEL_ATTR_ENCAP_QOS_TC_AND_COLOR_TO_DSCP_MAP;
253+
attr.value.oid = tc_to_dscp_map_id;
254+
tunnel_attrs.push_back(attr);
255+
}
256+
257+
// TC remapping
258+
if (tc_to_queue_map_id != SAI_NULL_OBJECT_ID)
259+
{
260+
attr.id = SAI_TUNNEL_ATTR_ENCAP_QOS_TC_TO_QUEUE_MAP;
261+
attr.value.oid = tc_to_queue_map_id;
262+
tunnel_attrs.push_back(attr);
263+
}
264+
227265
sai_object_id_t tunnel_id;
228266
status = sai_tunnel_api->create_tunnel(&tunnel_id, gSwitchId, (uint32_t)tunnel_attrs.size(), tunnel_attrs.data());
229267
if (status != SAI_STATUS_SUCCESS)
@@ -1229,10 +1267,32 @@ bool MuxOrch::handlePeerSwitch(const Request& request)
12291267
MUX_TUNNEL, peer_ip.to_string().c_str());
12301268
return false;
12311269
}
1232-
12331270
auto it = dst_ips.getIpAddresses().begin();
12341271
const IpAddress& dst_ip = *it;
1235-
mux_tunnel_id_ = create_tunnel(&peer_ip, &dst_ip);
1272+
1273+
// Read dscp_mode of MuxTunnel0 from decap_orch
1274+
string dscp_mode_name = decap_orch_->getDscpMode(MUX_TUNNEL);
1275+
if (dscp_mode_name == "")
1276+
{
1277+
SWSS_LOG_NOTICE("dscp_mode for tunnel %s is not available. Will not be applied", MUX_TUNNEL);
1278+
}
1279+
1280+
// Read tc_to_dscp_map_id of MuxTunnel0 from decap_orch
1281+
sai_object_id_t tc_to_dscp_map_id = SAI_NULL_OBJECT_ID;
1282+
decap_orch_->getQosMapId(MUX_TUNNEL, encap_tc_to_dscp_field_name, tc_to_dscp_map_id);
1283+
if (tc_to_dscp_map_id == SAI_NULL_OBJECT_ID)
1284+
{
1285+
SWSS_LOG_NOTICE("tc_to_dscp_map_id for tunnel %s is not available. Will not be applied", MUX_TUNNEL);
1286+
}
1287+
// Read tc_to_queue_map_id of MuxTunnel0 from decap_orch
1288+
sai_object_id_t tc_to_queue_map_id = SAI_NULL_OBJECT_ID;
1289+
decap_orch_->getQosMapId(MUX_TUNNEL, encap_tc_to_queue_field_name, tc_to_queue_map_id);
1290+
if (tc_to_queue_map_id == SAI_NULL_OBJECT_ID)
1291+
{
1292+
SWSS_LOG_NOTICE("tc_to_queue_map_id for tunnel %s is not available. Will not be applied", MUX_TUNNEL);
1293+
}
1294+
1295+
mux_tunnel_id_ = create_tunnel(&peer_ip, &dst_ip, tc_to_dscp_map_id, tc_to_queue_map_id, dscp_mode_name);
12361296
SWSS_LOG_NOTICE("Mux peer ip '%s' was added, peer name '%s'",
12371297
peer_ip.to_string().c_str(), peer_name.c_str());
12381298
}

orchagent/orchdaemon.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,8 @@ bool OrchDaemon::init()
227227
CFG_PFC_PRIORITY_TO_PRIORITY_GROUP_MAP_TABLE_NAME,
228228
CFG_PFC_PRIORITY_TO_QUEUE_MAP_TABLE_NAME,
229229
CFG_DSCP_TO_FC_MAP_TABLE_NAME,
230-
CFG_EXP_TO_FC_MAP_TABLE_NAME
230+
CFG_EXP_TO_FC_MAP_TABLE_NAME,
231+
CFG_TC_TO_DSCP_MAP_TABLE_NAME
231232
};
232233
gQosOrch = new QosOrch(m_configDb, qos_tables);
233234

orchagent/qosorch.cpp

+123-1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ type_map QosOrch::m_qos_maps = {
7979
{CFG_PFC_PRIORITY_TO_QUEUE_MAP_TABLE_NAME, new object_reference_map()},
8080
{CFG_DSCP_TO_FC_MAP_TABLE_NAME, new object_reference_map()},
8181
{CFG_EXP_TO_FC_MAP_TABLE_NAME, new object_reference_map()},
82+
{CFG_TC_TO_DSCP_MAP_TABLE_NAME, new object_reference_map()},
83+
{APP_TUNNEL_DECAP_TABLE_NAME, new object_reference_map()}
8284
};
8385

8486
map<string, string> qos_to_ref_table_map = {
@@ -92,7 +94,11 @@ map<string, string> qos_to_ref_table_map = {
9294
{scheduler_field_name, CFG_SCHEDULER_TABLE_NAME},
9395
{wred_profile_field_name, CFG_WRED_PROFILE_TABLE_NAME},
9496
{dscp_to_fc_field_name, CFG_DSCP_TO_FC_MAP_TABLE_NAME},
95-
{exp_to_fc_field_name, CFG_EXP_TO_FC_MAP_TABLE_NAME}
97+
{exp_to_fc_field_name, CFG_EXP_TO_FC_MAP_TABLE_NAME},
98+
{decap_dscp_to_tc_field_name, CFG_DSCP_TO_TC_MAP_TABLE_NAME},
99+
{decap_tc_to_pg_field_name, CFG_TC_TO_PRIORITY_GROUP_MAP_TABLE_NAME},
100+
{encap_tc_to_dscp_field_name, CFG_TC_TO_DSCP_MAP_TABLE_NAME},
101+
{encap_tc_to_queue_field_name, CFG_TC_TO_QUEUE_MAP_TABLE_NAME}
96102
};
97103

98104
#define DSCP_MAX_VAL 63
@@ -1063,6 +1069,82 @@ sai_object_id_t ExpToFcMapHandler::addQosItem(const vector<sai_attribute_t> &att
10631069
return sai_object;
10641070
}
10651071

1072+
bool TcToDscpMapHandler::convertFieldValuesToAttributes(KeyOpFieldsValuesTuple &tuple,
1073+
vector<sai_attribute_t> &attributes)
1074+
{
1075+
SWSS_LOG_ENTER();
1076+
1077+
sai_attribute_t list_attr;
1078+
list_attr.id = SAI_QOS_MAP_ATTR_MAP_TO_VALUE_LIST;
1079+
list_attr.value.qosmap.count = (uint32_t)kfvFieldsValues(tuple).size();
1080+
list_attr.value.qosmap.list = new sai_qos_map_t[list_attr.value.qosmap.count]();
1081+
uint32_t ind = 0;
1082+
1083+
for (auto i = kfvFieldsValues(tuple).begin(); i != kfvFieldsValues(tuple).end(); i++, ind++)
1084+
{
1085+
try
1086+
{
1087+
auto value = stoi(fvValue(*i));
1088+
if (value < 0)
1089+
{
1090+
SWSS_LOG_ERROR("DSCP value %d is negative", value);
1091+
delete[] list_attr.value.qosmap.list;
1092+
return false;
1093+
}
1094+
else if (value > DSCP_MAX_VAL)
1095+
{
1096+
SWSS_LOG_ERROR("DSCP value %d is greater than max value %d", value, DSCP_MAX_VAL);
1097+
delete[] list_attr.value.qosmap.list;
1098+
return false;
1099+
}
1100+
list_attr.value.qosmap.list[ind].key.tc = static_cast<sai_uint8_t>(stoi(fvField(*i)));
1101+
list_attr.value.qosmap.list[ind].value.dscp = static_cast<sai_uint8_t>(value);
1102+
1103+
SWSS_LOG_DEBUG("key.tc:%d, value.dscp:%d",
1104+
list_attr.value.qosmap.list[ind].key.tc,
1105+
list_attr.value.qosmap.list[ind].value.dscp);
1106+
}
1107+
catch(const invalid_argument& e)
1108+
{
1109+
SWSS_LOG_ERROR("Got exception during conversion: %s", e.what());
1110+
delete[] list_attr.value.qosmap.list;
1111+
return false;
1112+
}
1113+
}
1114+
attributes.push_back(list_attr);
1115+
return true;
1116+
}
1117+
1118+
sai_object_id_t TcToDscpMapHandler::addQosItem(const vector<sai_attribute_t> &attributes)
1119+
{
1120+
SWSS_LOG_ENTER();
1121+
sai_status_t sai_status;
1122+
sai_object_id_t sai_object;
1123+
vector<sai_attribute_t> qos_map_attrs;
1124+
1125+
sai_attribute_t qos_map_attr;
1126+
qos_map_attr.id = SAI_QOS_MAP_ATTR_TYPE;
1127+
qos_map_attr.value.u32 = SAI_QOS_MAP_TYPE_TC_AND_COLOR_TO_DSCP;
1128+
qos_map_attrs.push_back(qos_map_attr);
1129+
1130+
qos_map_attr.id = SAI_QOS_MAP_ATTR_MAP_TO_VALUE_LIST;
1131+
qos_map_attr.value.qosmap.count = attributes[0].value.qosmap.count;
1132+
qos_map_attr.value.qosmap.list = attributes[0].value.qosmap.list;
1133+
qos_map_attrs.push_back(qos_map_attr);
1134+
1135+
sai_status = sai_qos_map_api->create_qos_map(&sai_object,
1136+
gSwitchId,
1137+
(uint32_t)qos_map_attrs.size(),
1138+
qos_map_attrs.data());
1139+
if (SAI_STATUS_SUCCESS != sai_status)
1140+
{
1141+
SWSS_LOG_ERROR("Failed to create tc_to_dscp map. status:%d", sai_status);
1142+
return SAI_NULL_OBJECT_ID;
1143+
}
1144+
SWSS_LOG_DEBUG("created QosMap object:%" PRIx64, sai_object);
1145+
return sai_object;
1146+
}
1147+
10661148
task_process_status QosOrch::handleExpToFcTable(Consumer& consumer, KeyOpFieldsValuesTuple &tuple)
10671149
{
10681150
SWSS_LOG_ENTER();
@@ -1077,6 +1159,13 @@ task_process_status QosOrch::handlePfcToQueueTable(Consumer& consumer, KeyOpFiel
10771159
return pfc_to_queue_handler.processWorkItem(consumer, tuple);
10781160
}
10791161

1162+
task_process_status QosOrch::handleTcToDscpTable(Consumer& consumer, KeyOpFieldsValuesTuple &tuple)
1163+
{
1164+
SWSS_LOG_ENTER();
1165+
TcToDscpMapHandler tc_to_dscp_handler;
1166+
return tc_to_dscp_handler.processWorkItem(consumer, tuple);
1167+
}
1168+
10801169
QosOrch::QosOrch(DBConnector *db, vector<string> &tableNames) : Orch(db, tableNames)
10811170
{
10821171
SWSS_LOG_ENTER();
@@ -1103,6 +1192,7 @@ void QosOrch::initTableHandlers()
11031192
m_qos_handler_map.insert(qos_handler_pair(CFG_WRED_PROFILE_TABLE_NAME, &QosOrch::handleWredProfileTable));
11041193
m_qos_handler_map.insert(qos_handler_pair(CFG_DSCP_TO_FC_MAP_TABLE_NAME, &QosOrch::handleDscpToFcTable));
11051194
m_qos_handler_map.insert(qos_handler_pair(CFG_EXP_TO_FC_MAP_TABLE_NAME, &QosOrch::handleExpToFcTable));
1195+
m_qos_handler_map.insert(qos_handler_pair(CFG_TC_TO_DSCP_MAP_TABLE_NAME, &QosOrch::handleTcToDscpTable));
11061196

11071197
m_qos_handler_map.insert(qos_handler_pair(CFG_TC_TO_PRIORITY_GROUP_MAP_TABLE_NAME, &QosOrch::handleTcToPgTable));
11081198
m_qos_handler_map.insert(qos_handler_pair(CFG_PFC_PRIORITY_TO_PRIORITY_GROUP_MAP_TABLE_NAME, &QosOrch::handlePfcPrioToPgTable));
@@ -1859,3 +1949,35 @@ void QosOrch::doTask(Consumer &consumer)
18591949
}
18601950
}
18611951
}
1952+
1953+
/**
1954+
* Function Description:
1955+
* @brief Resolve the id of QoS map that is referenced by tunnel
1956+
*
1957+
* Arguments:
1958+
* @param[in] referencing_table_name - The name of table that is referencing the QoS map
1959+
* @param[in] tunnle_name - The name of tunnel
1960+
* @param[in] map_type_name - The type of referenced QoS map
1961+
* @param[in] tuple - The KeyOpFieldsValuesTuple that contains keys - values
1962+
*
1963+
* Return Values:
1964+
* @return The sai_object_id of referenced map, or SAI_NULL_OBJECT_ID if there's an error
1965+
*/
1966+
sai_object_id_t QosOrch::resolveTunnelQosMap(std::string referencing_table_name, std::string tunnel_name, std::string map_type_name, KeyOpFieldsValuesTuple& tuple)
1967+
{
1968+
sai_object_id_t id;
1969+
string object_name;
1970+
ref_resolve_status status = resolveFieldRefValue(m_qos_maps, map_type_name, qos_to_ref_table_map.at(map_type_name), tuple, id, object_name);
1971+
if (status == ref_resolve_status::success)
1972+
{
1973+
1974+
setObjectReference(m_qos_maps, referencing_table_name, tunnel_name, map_type_name, object_name);
1975+
SWSS_LOG_INFO("Resolved QoS map for table %s tunnel %s type %s name %s", referencing_table_name.c_str(), tunnel_name.c_str(), map_type_name.c_str(), object_name.c_str());
1976+
return id;
1977+
}
1978+
else
1979+
{
1980+
SWSS_LOG_ERROR("Failed to resolve QoS map for table %s tunnel %s type %s", referencing_table_name.c_str(), tunnel_name.c_str(), map_type_name.c_str());
1981+
return SAI_NULL_OBJECT_ID;
1982+
}
1983+
}

orchagent/qosorch.h

+15
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ const string yellow_drop_probability_field_name = "yellow_drop_probability";
2828
const string green_drop_probability_field_name = "green_drop_probability";
2929
const string dscp_to_fc_field_name = "dscp_to_fc_map";
3030
const string exp_to_fc_field_name = "exp_to_fc_map";
31+
const string decap_dscp_to_tc_field_name = "decap_dscp_to_tc_map";
32+
const string decap_tc_to_pg_field_name = "decap_tc_to_pg_map";
33+
const string encap_tc_to_queue_field_name = "encap_tc_to_queue_map";
34+
const string encap_tc_to_dscp_field_name = "encap_tc_to_dscp_map";
3135

3236
const string wred_profile_field_name = "wred_profile";
3337
const string wred_red_enable_field_name = "wred_red_enable";
@@ -147,13 +151,23 @@ class ExpToFcMapHandler : public QosMapHandler
147151
sai_object_id_t addQosItem(const vector<sai_attribute_t> &attributes) override;
148152
};
149153

154+
// Handler for TC_TO_DSCP_MAP
155+
class TcToDscpMapHandler : public QosMapHandler
156+
{
157+
public:
158+
bool convertFieldValuesToAttributes(KeyOpFieldsValuesTuple &tuple, vector<sai_attribute_t> &attributes) override;
159+
sai_object_id_t addQosItem(const vector<sai_attribute_t> &attributes) override;
160+
};
161+
150162
class QosOrch : public Orch
151163
{
152164
public:
153165
QosOrch(DBConnector *db, vector<string> &tableNames);
154166

155167
static type_map& getTypeMap();
156168
static type_map m_qos_maps;
169+
170+
sai_object_id_t resolveTunnelQosMap(std::string referencing_table_name, std::string tunnel_name, std::string map_type_name, KeyOpFieldsValuesTuple& tuple);
157171
private:
158172
void doTask() override;
159173
virtual void doTask(Consumer& consumer);
@@ -177,6 +191,7 @@ class QosOrch : public Orch
177191
task_process_status handleWredProfileTable(Consumer& consumer, KeyOpFieldsValuesTuple &tuple);
178192
task_process_status handleDscpToFcTable(Consumer& consumer, KeyOpFieldsValuesTuple &tuple);
179193
task_process_status handleExpToFcTable(Consumer& consumer, KeyOpFieldsValuesTuple &tuple);
194+
task_process_status handleTcToDscpTable(Consumer& consumer, KeyOpFieldsValuesTuple &tuple);
180195

181196
sai_object_id_t getSchedulerGroup(const Port &port, const sai_object_id_t queue_id);
182197

0 commit comments

Comments
 (0)