Skip to content

Commit 53ee0a8

Browse files
dmukunStormLiangMS
authored andcommitted
Support for tc-dot1p and tc-dscp qosmap (#2559)
* Support for tc-dot1p and tc-dscp qosmap
1 parent b953866 commit 53ee0a8

File tree

4 files changed

+258
-4
lines changed

4 files changed

+258
-4
lines changed

orchagent/orchdaemon.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ bool OrchDaemon::init()
235235
CFG_PFC_PRIORITY_TO_QUEUE_MAP_TABLE_NAME,
236236
CFG_DSCP_TO_FC_MAP_TABLE_NAME,
237237
CFG_EXP_TO_FC_MAP_TABLE_NAME,
238+
CFG_TC_TO_DOT1P_MAP_TABLE_NAME,
238239
CFG_TC_TO_DSCP_MAP_TABLE_NAME
239240
};
240241
gQosOrch = new QosOrch(m_configDb, qos_tables);

orchagent/qosorch.cpp

+64-4
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ map<string, sai_port_attr_t> qos_to_attr_map = {
5858
{mpls_tc_to_tc_field_name, SAI_PORT_ATTR_QOS_MPLS_EXP_TO_TC_MAP},
5959
{dot1p_to_tc_field_name, SAI_PORT_ATTR_QOS_DOT1P_TO_TC_MAP},
6060
{tc_to_queue_field_name, SAI_PORT_ATTR_QOS_TC_TO_QUEUE_MAP},
61+
{tc_to_dot1p_field_name, SAI_PORT_ATTR_QOS_TC_AND_COLOR_TO_DOT1P_MAP},
62+
{tc_to_dscp_field_name, SAI_PORT_ATTR_QOS_TC_AND_COLOR_TO_DSCP_MAP},
6163
{tc_to_pg_map_field_name, SAI_PORT_ATTR_QOS_TC_TO_PRIORITY_GROUP_MAP},
6264
{pfc_to_pg_map_name, SAI_PORT_ATTR_QOS_PFC_PRIORITY_TO_PRIORITY_GROUP_MAP},
6365
{pfc_to_queue_map_name, SAI_PORT_ATTR_QOS_PFC_PRIORITY_TO_QUEUE_MAP},
@@ -85,6 +87,7 @@ type_map QosOrch::m_qos_maps = {
8587
{CFG_PFC_PRIORITY_TO_QUEUE_MAP_TABLE_NAME, new object_reference_map()},
8688
{CFG_DSCP_TO_FC_MAP_TABLE_NAME, new object_reference_map()},
8789
{CFG_EXP_TO_FC_MAP_TABLE_NAME, new object_reference_map()},
90+
{CFG_TC_TO_DOT1P_MAP_TABLE_NAME, new object_reference_map()},
8891
{CFG_TC_TO_DSCP_MAP_TABLE_NAME, new object_reference_map()},
8992
{APP_TUNNEL_DECAP_TABLE_NAME, new object_reference_map()}
9093
};
@@ -94,6 +97,8 @@ map<string, string> qos_to_ref_table_map = {
9497
{mpls_tc_to_tc_field_name, CFG_MPLS_TC_TO_TC_MAP_TABLE_NAME},
9598
{dot1p_to_tc_field_name, CFG_DOT1P_TO_TC_MAP_TABLE_NAME},
9699
{tc_to_queue_field_name, CFG_TC_TO_QUEUE_MAP_TABLE_NAME},
100+
{tc_to_dot1p_field_name, CFG_TC_TO_DOT1P_MAP_TABLE_NAME},
101+
{tc_to_dscp_field_name, CFG_TC_TO_DSCP_MAP_TABLE_NAME},
97102
{tc_to_pg_map_field_name, CFG_TC_TO_PRIORITY_GROUP_MAP_TABLE_NAME},
98103
{pfc_to_pg_map_name, CFG_PFC_PRIORITY_TO_PRIORITY_GROUP_MAP_TABLE_NAME},
99104
{pfc_to_queue_map_name, CFG_PFC_PRIORITY_TO_QUEUE_MAP_TABLE_NAME},
@@ -178,7 +183,7 @@ task_process_status QosMapHandler::processWorkItem(Consumer& consumer, KeyOpFiel
178183
}
179184
if (!removeQosItem(sai_object))
180185
{
181-
SWSS_LOG_ERROR("Failed to remove dscp_to_tc map. db name:%s sai object:%" PRIx64, qos_object_name.c_str(), sai_object);
186+
SWSS_LOG_ERROR("Failed to remove QoS map. db name:%s sai object:%" PRIx64, qos_object_name.c_str(), sai_object);
182187
return task_process_status::task_failed;
183188
}
184189
auto it_to_delete = (QosOrch::getTypeMap()[qos_map_type_name])->find(qos_object_name);
@@ -470,6 +475,60 @@ task_process_status QosOrch::handleTcToQueueTable(Consumer& consumer, KeyOpField
470475
return tc_queue_handler.processWorkItem(consumer, tuple);
471476
}
472477

478+
//Functions for TC-to-DOT1P qos map handling
479+
bool TcToDot1pMapHandler::convertFieldValuesToAttributes(KeyOpFieldsValuesTuple &tuple, vector<sai_attribute_t> &attributes)
480+
{
481+
SWSS_LOG_ENTER();
482+
sai_attribute_t list_attr;
483+
sai_qos_map_list_t tc_map_list;
484+
tc_map_list.count = (uint32_t)kfvFieldsValues(tuple).size();
485+
tc_map_list.list = new sai_qos_map_t[tc_map_list.count]();
486+
uint32_t ind = 0;
487+
for (auto i = kfvFieldsValues(tuple).begin(); i != kfvFieldsValues(tuple).end(); i++, ind++)
488+
{
489+
tc_map_list.list[ind].key.tc = (uint8_t)stoi(fvField(*i));
490+
tc_map_list.list[ind].value.dot1p = (uint8_t)stoi(fvValue(*i));
491+
}
492+
list_attr.id = SAI_QOS_MAP_ATTR_MAP_TO_VALUE_LIST;
493+
list_attr.value.qosmap.count = tc_map_list.count;
494+
list_attr.value.qosmap.list = tc_map_list.list;
495+
attributes.push_back(list_attr);
496+
return true;
497+
}
498+
499+
sai_object_id_t TcToDot1pMapHandler::addQosItem(const vector<sai_attribute_t> &attributes)
500+
{
501+
SWSS_LOG_ENTER();
502+
sai_status_t sai_status;
503+
sai_object_id_t sai_object;
504+
vector<sai_attribute_t> qos_map_attrs;
505+
sai_attribute_t qos_map_attr;
506+
507+
qos_map_attr.id = SAI_QOS_MAP_ATTR_TYPE;
508+
qos_map_attr.value.s32 = SAI_QOS_MAP_TYPE_TC_AND_COLOR_TO_DOT1P;
509+
qos_map_attrs.push_back(qos_map_attr);
510+
511+
qos_map_attr.id = SAI_QOS_MAP_ATTR_MAP_TO_VALUE_LIST;
512+
qos_map_attr.value.qosmap.count = attributes[0].value.qosmap.count;
513+
qos_map_attr.value.qosmap.list = attributes[0].value.qosmap.list;
514+
qos_map_attrs.push_back(qos_map_attr);
515+
516+
sai_status = sai_qos_map_api->create_qos_map(&sai_object, gSwitchId, (uint32_t)qos_map_attrs.size(), qos_map_attrs.data());
517+
if (SAI_STATUS_SUCCESS != sai_status)
518+
{
519+
SWSS_LOG_ERROR("Failed to create tc_to_dot1p qos map. status:%d", sai_status);
520+
return SAI_NULL_OBJECT_ID;
521+
}
522+
return sai_object;
523+
}
524+
525+
task_process_status QosOrch::handleTcToDot1pTable(Consumer& consumer, KeyOpFieldsValuesTuple &tuple)
526+
{
527+
SWSS_LOG_ENTER();
528+
TcToDot1pMapHandler tc_dot1p_handler;
529+
return tc_dot1p_handler.processWorkItem(consumer, tuple);
530+
}
531+
473532
void WredMapHandler::freeAttribResources(vector<sai_attribute_t> &attributes)
474533
{
475534
SWSS_LOG_ENTER();
@@ -857,7 +916,7 @@ sai_object_id_t TcToPgHandler::addQosItem(const vector<sai_attribute_t> &attribu
857916
sai_status = sai_qos_map_api->create_qos_map(&sai_object, gSwitchId, (uint32_t)qos_map_attrs.size(), qos_map_attrs.data());
858917
if (SAI_STATUS_SUCCESS != sai_status)
859918
{
860-
SWSS_LOG_ERROR("Failed to create tc_to_queue map. status:%d", sai_status);
919+
SWSS_LOG_ERROR("Failed to create tc_to_pg map. status:%d", sai_status);
861920
return SAI_NULL_OBJECT_ID;
862921
}
863922
return sai_object;
@@ -911,7 +970,7 @@ sai_object_id_t PfcPrioToPgHandler::addQosItem(const vector<sai_attribute_t> &at
911970
sai_status = sai_qos_map_api->create_qos_map(&sai_object, gSwitchId, (uint32_t)qos_map_attrs.size(), qos_map_attrs.data());
912971
if (SAI_STATUS_SUCCESS != sai_status)
913972
{
914-
SWSS_LOG_ERROR("Failed to create tc_to_queue map. status:%d", sai_status);
973+
SWSS_LOG_ERROR("Failed to create pfc_priority_to_queue map. status:%d", sai_status);
915974
return SAI_NULL_OBJECT_ID;
916975
}
917976
return sai_object;
@@ -966,7 +1025,7 @@ sai_object_id_t PfcToQueueHandler::addQosItem(const vector<sai_attribute_t> &att
9661025
sai_status = sai_qos_map_api->create_qos_map(&sai_object, gSwitchId, (uint32_t)qos_map_attrs.size(), qos_map_attrs.data());
9671026
if (SAI_STATUS_SUCCESS != sai_status)
9681027
{
969-
SWSS_LOG_ERROR("Failed to create tc_to_queue map. status:%d", sai_status);
1028+
SWSS_LOG_ERROR("Failed to create pfc_priority_to_queue map. status:%d", sai_status);
9701029
return SAI_NULL_OBJECT_ID;
9711030
}
9721031
return sai_object;
@@ -1274,6 +1333,7 @@ void QosOrch::initTableHandlers()
12741333
m_qos_handler_map.insert(qos_handler_pair(CFG_DSCP_TO_FC_MAP_TABLE_NAME, &QosOrch::handleDscpToFcTable));
12751334
m_qos_handler_map.insert(qos_handler_pair(CFG_EXP_TO_FC_MAP_TABLE_NAME, &QosOrch::handleExpToFcTable));
12761335
m_qos_handler_map.insert(qos_handler_pair(CFG_TC_TO_DSCP_MAP_TABLE_NAME, &QosOrch::handleTcToDscpTable));
1336+
m_qos_handler_map.insert(qos_handler_pair(CFG_TC_TO_DOT1P_MAP_TABLE_NAME, &QosOrch::handleTcToDot1pTable));
12771337

12781338
m_qos_handler_map.insert(qos_handler_pair(CFG_TC_TO_PRIORITY_GROUP_MAP_TABLE_NAME, &QosOrch::handleTcToPgTable));
12791339
m_qos_handler_map.insert(qos_handler_pair(CFG_PFC_PRIORITY_TO_PRIORITY_GROUP_MAP_TABLE_NAME, &QosOrch::handlePfcPrioToPgTable));

orchagent/qosorch.h

+10
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ const string pfc_enable_name = "pfc_enable";
1717
const string pfcwd_sw_enable_name = "pfcwd_sw_enable";
1818
const string tc_to_pg_map_field_name = "tc_to_pg_map";
1919
const string tc_to_queue_field_name = "tc_to_queue_map";
20+
const string tc_to_dot1p_field_name = "tc_to_dot1p_map";
21+
const string tc_to_dscp_field_name = "tc_to_dscp_map";
2022
const string scheduler_field_name = "scheduler";
2123
const string red_max_threshold_field_name = "red_max_threshold";
2224
const string red_min_threshold_field_name = "red_min_threshold";
@@ -175,6 +177,13 @@ class TcToDscpMapHandler : public QosMapHandler
175177
sai_object_id_t addQosItem(const vector<sai_attribute_t> &attributes) override;
176178
};
177179

180+
class TcToDot1pMapHandler : public QosMapHandler
181+
{
182+
public:
183+
bool convertFieldValuesToAttributes(KeyOpFieldsValuesTuple &tuple, vector<sai_attribute_t> &attributes);
184+
sai_object_id_t addQosItem(const vector<sai_attribute_t> &attributes);
185+
};
186+
178187
class QosOrch : public Orch
179188
{
180189
public:
@@ -209,6 +218,7 @@ class QosOrch : public Orch
209218
task_process_status handleDscpToFcTable(Consumer& consumer, KeyOpFieldsValuesTuple &tuple);
210219
task_process_status handleExpToFcTable(Consumer& consumer, KeyOpFieldsValuesTuple &tuple);
211220
task_process_status handleTcToDscpTable(Consumer& consumer, KeyOpFieldsValuesTuple &tuple);
221+
task_process_status handleTcToDot1pTable(Consumer& consumer, KeyOpFieldsValuesTuple &tuple);
212222

213223
task_process_status handleGlobalQosMap(const string &op, KeyOpFieldsValuesTuple &tuple);
214224

tests/test_qos_map.py

+183
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,32 @@
33

44
from swsscommon import swsscommon
55

6+
CFG_TC_TO_DSCP_MAP_TABLE_NAME = "TC_TO_DSCP_MAP"
7+
CFG_TC_TO_DSCP_MAP_KEY = "AZURE"
8+
TC_TO_DSCP_MAP = {
9+
"0": "20",
10+
"1": "16",
11+
"2": "5",
12+
"3": "43",
13+
"4": "34",
14+
"5": "52",
15+
"6": "61",
16+
"7": "17",
17+
}
18+
19+
CFG_TC_TO_DOT1P_MAP_TABLE_NAME = "TC_TO_DOT1P_MAP"
20+
CFG_TC_TO_DOT1P_MAP_KEY = "AZURE"
21+
TC_TO_DOT1P_MAP = {
22+
"0": "0",
23+
"1": "6",
24+
"2": "5",
25+
"3": "3",
26+
"4": "4",
27+
"5": "2",
28+
"6": "1",
29+
"7": "7",
30+
}
31+
632
CFG_DOT1P_TO_TC_MAP_TABLE_NAME = "DOT1P_TO_TC_MAP"
733
CFG_DOT1P_TO_TC_MAP_KEY = "AZURE"
834
DOT1P_TO_TC_MAP = {
@@ -32,9 +58,166 @@
3258
CFG_PORT_QOS_MAP_TABLE_NAME = "PORT_QOS_MAP"
3359
CFG_PORT_QOS_DOT1P_MAP_FIELD = "dot1p_to_tc_map"
3460
CFG_PORT_QOS_MPLS_TC_MAP_FIELD = "mpls_tc_to_tc_map"
61+
CFG_PORT_QOS_TC_DOT1P_MAP_FIELD = "tc_to_dot1p_map"
62+
CFG_PORT_QOS_TC_DSCP_MAP_FIELD = "tc_to_dscp_map"
3563
CFG_PORT_TABLE_NAME = "PORT"
3664

65+
#Tests for TC-to-DSCP qos map configuration
66+
class TestTcDscp(object):
67+
def connect_dbs(self, dvs):
68+
self.asic_db = swsscommon.DBConnector(1, dvs.redis_sock, 0)
69+
self.config_db = swsscommon.DBConnector(4, dvs.redis_sock, 0)
70+
71+
def create_tc_dscp_profile(self):
72+
tbl = swsscommon.Table(self.config_db, CFG_TC_TO_DSCP_MAP_TABLE_NAME)
73+
fvs = swsscommon.FieldValuePairs(list(TC_TO_DSCP_MAP.items()))
74+
tbl.set(CFG_TC_TO_DSCP_MAP_KEY, fvs)
75+
time.sleep(1)
76+
77+
def find_tc_dscp_profile(self):
78+
found = False
79+
tc_dscp_map_raw = None
80+
tbl = swsscommon.Table(self.asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_QOS_MAP")
81+
keys = tbl.getKeys()
82+
for key in keys:
83+
(status, fvs) = tbl.get(key)
84+
assert status == True
85+
86+
for fv in fvs:
87+
if fv[0] == "SAI_QOS_MAP_ATTR_MAP_TO_VALUE_LIST":
88+
tc_dscp_map_raw = fv[1]
89+
elif fv[0] == "SAI_QOS_MAP_ATTR_TYPE" and fv[1] == "SAI_QOS_MAP_TYPE_TC_AND_COLOR_TO_DSCP":
90+
found = True
91+
92+
if found:
93+
break
94+
95+
assert found == True
96+
97+
return (key, tc_dscp_map_raw)
98+
99+
def apply_tc_dscp_profile_on_all_ports(self):
100+
tbl = swsscommon.Table(self.config_db, CFG_PORT_QOS_MAP_TABLE_NAME)
101+
fvs = swsscommon.FieldValuePairs([(CFG_PORT_QOS_TC_DSCP_MAP_FIELD, CFG_TC_TO_DSCP_MAP_KEY)])
102+
ports = swsscommon.Table(self.config_db, CFG_PORT_TABLE_NAME).getKeys()
103+
for port in ports:
104+
tbl.set(port, fvs)
105+
106+
time.sleep(1)
107+
108+
109+
def test_tc_dscp_cfg(self, dvs):
110+
self.connect_dbs(dvs)
111+
self.create_tc_dscp_profile()
112+
_, tc_dscp_map_raw = self.find_tc_dscp_profile()
113+
114+
tc_dscp_map = json.loads(tc_dscp_map_raw)
115+
for tc2dscp in tc_dscp_map['list']:
116+
tc_val = str(tc2dscp['key']['tc'])
117+
dscp_val = str(tc2dscp['value']['dscp'])
118+
assert dscp_val == TC_TO_DSCP_MAP[tc_val]
119+
120+
def test_port_tc_dscp(self, dvs):
121+
self.connect_dbs(dvs)
122+
self.create_tc_dscp_profile()
123+
oid, _ = self.find_tc_dscp_profile()
124+
125+
self.apply_tc_dscp_profile_on_all_ports()
126+
127+
cnt = 0
128+
tbl = swsscommon.Table(self.asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_PORT")
129+
keys = tbl.getKeys()
130+
for key in keys:
131+
(status, fvs) = tbl.get(key)
132+
assert status == True
133+
134+
for fv in fvs:
135+
if fv[0] == "SAI_PORT_ATTR_QOS_TC_AND_COLOR_TO_DSCP_MAP":
136+
cnt += 1
137+
assert fv[1] == oid
138+
139+
port_cnt = len(swsscommon.Table(self.config_db, CFG_PORT_TABLE_NAME).getKeys())
140+
assert port_cnt == cnt
141+
142+
143+
#Tests for TC-to-Dot1p qos map configuration
144+
class TestTcDot1p(object):
145+
def connect_dbs(self, dvs):
146+
self.asic_db = swsscommon.DBConnector(1, dvs.redis_sock, 0)
147+
self.config_db = swsscommon.DBConnector(4, dvs.redis_sock, 0)
148+
149+
def create_tc_dot1p_profile(self):
150+
tbl = swsscommon.Table(self.config_db, CFG_TC_TO_DOT1P_MAP_TABLE_NAME)
151+
fvs = swsscommon.FieldValuePairs(list(TC_TO_DOT1P_MAP.items()))
152+
tbl.set(CFG_TC_TO_DOT1P_MAP_KEY, fvs)
153+
time.sleep(1)
154+
155+
def find_tc_dot1p_profile(self):
156+
found = False
157+
tc_dot1p_map_raw = None
158+
tbl = swsscommon.Table(self.asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_QOS_MAP")
159+
keys = tbl.getKeys()
160+
for key in keys:
161+
(status, fvs) = tbl.get(key)
162+
assert status == True
163+
164+
for fv in fvs:
165+
if fv[0] == "SAI_QOS_MAP_ATTR_MAP_TO_VALUE_LIST":
166+
tc_dot1p_map_raw = fv[1]
167+
elif fv[0] == "SAI_QOS_MAP_ATTR_TYPE" and fv[1] == "SAI_QOS_MAP_TYPE_TC_AND_COLOR_TO_DOT1P":
168+
found = True
169+
170+
if found:
171+
break
172+
173+
assert found == True
174+
175+
return (key, tc_dot1p_map_raw)
176+
177+
def apply_tc_dot1p_profile_on_all_ports(self):
178+
tbl = swsscommon.Table(self.config_db, CFG_PORT_QOS_MAP_TABLE_NAME)
179+
fvs = swsscommon.FieldValuePairs([(CFG_PORT_QOS_TC_DOT1P_MAP_FIELD, CFG_TC_TO_DOT1P_MAP_KEY)])
180+
ports = swsscommon.Table(self.config_db, CFG_PORT_TABLE_NAME).getKeys()
181+
for port in ports:
182+
tbl.set(port, fvs)
183+
184+
time.sleep(1)
185+
186+
187+
def test_tc_dot1p_cfg(self, dvs):
188+
self.connect_dbs(dvs)
189+
self.create_tc_dot1p_profile()
190+
_, tc_dot1p_map_raw = self.find_tc_dot1p_profile()
191+
192+
tc_dot1p_map = json.loads(tc_dot1p_map_raw)
193+
for tc2dot1p in tc_dot1p_map['list']:
194+
tc_val = str(tc2dot1p['key']['tc'])
195+
dot1p_val = str(tc2dot1p['value']['dot1p'])
196+
assert dot1p_val == TC_TO_DOT1P_MAP[tc_val]
197+
198+
def test_port_tc_dot1p(self, dvs):
199+
self.connect_dbs(dvs)
200+
self.create_tc_dot1p_profile()
201+
oid, _ = self.find_tc_dot1p_profile()
202+
203+
self.apply_tc_dot1p_profile_on_all_ports()
204+
205+
cnt = 0
206+
tbl = swsscommon.Table(self.asic_db, "ASIC_STATE:SAI_OBJECT_TYPE_PORT")
207+
keys = tbl.getKeys()
208+
for key in keys:
209+
(status, fvs) = tbl.get(key)
210+
assert status == True
211+
212+
for fv in fvs:
213+
if fv[0] == "SAI_PORT_ATTR_QOS_TC_AND_COLOR_TO_DOT1P_MAP":
214+
cnt += 1
215+
assert fv[1] == oid
216+
217+
port_cnt = len(swsscommon.Table(self.config_db, CFG_PORT_TABLE_NAME).getKeys())
218+
assert port_cnt == cnt
37219

220+
#Tests for Dot1p-to-TC qos map configuration
38221
class TestDot1p(object):
39222
def connect_dbs(self, dvs):
40223
self.asic_db = swsscommon.DBConnector(1, dvs.redis_sock, 0)

0 commit comments

Comments
 (0)