From 3c915f5f17ff339487a3b8533d384a23888b9c9a Mon Sep 17 00:00:00 2001
From: Maxim Menshikov <maxim.menshikov@iopsys.eu>
Date: Fri, 10 Nov 2023 19:52:33 +0000
Subject: [PATCH] Parse QoS dscp_pcp as list of dscp_min[-dscp_max],pcp pairs

---
 src/config_qos.c | 38 ++++++++++++++++++++++++++++----------
 1 file changed, 28 insertions(+), 10 deletions(-)

diff --git a/src/config_qos.c b/src/config_qos.c
index 17f84821..2fc9bcf6 100644
--- a/src/config_qos.c
+++ b/src/config_qos.c
@@ -127,7 +127,7 @@ static int cntlr_config_get_qos_rule_dscp_pcp(struct controller_config *cc,
 	const struct uci_parse_option opts[] = {
 		[QOS_RULE_DSCP_PCP_DSCP_PCP] = {
 			.name = "dscp_pcp",
-			.type = UCI_TYPE_STRING
+			.type = UCI_TYPE_LIST
 		},
 	};
 	struct uci_option *tb[NUM_QOS_RULE_DSCP_PCP_ATTRS];
@@ -138,15 +138,33 @@ static int cntlr_config_get_qos_rule_dscp_pcp(struct controller_config *cc,
 
 
 	if (tb[QOS_RULE_DSCP_PCP_DSCP_PCP]) {
-		const char *str = tb[QOS_RULE_DSCP_PCP_DSCP_PCP]->v.string;
-		int 		val;
-		size_t      idx = 0;
-
-		while (str != NULL && sscanf(str, "%d", &val) == 1) {
-			dscp_pcp->dscp_pcp[idx++] = val;
-			str = strstr(str, ",");
-			if (str != NULL)
-				str++;
+		struct uci_element *x;
+
+		uci_foreach_element(&tb[QOS_RULE_DSCP_PCP_DSCP_PCP]->v.list, x) {
+			int dscp_min = 0;
+			int dscp_max = 0;
+			int pcp = 0;
+
+			if (sscanf(x->name, "%d-%d,%d", &dscp_min, &dscp_max, &pcp) == 3) {
+				if (pcp <= 7 && pcp >= 0 && dscp_min >= 0 && dscp_max >= 0 &&
+				    dscp_min < dscp_max &&
+				    dscp_min < (sizeof(dscp_pcp->dscp_pcp) /
+				                sizeof(dscp_pcp->dscp_pcp[0])) &&
+				    dscp_max < (sizeof(dscp_pcp->dscp_pcp) /
+				                sizeof(dscp_pcp->dscp_pcp[0]))) {
+					uint8_t dscp;
+
+					for (dscp = dscp_min; dscp <= dscp_max; ++dscp) {
+						dscp_pcp->dscp_pcp[dscp] = pcp;
+					}
+				}
+			} else if (sscanf(x->name, "%d,%d", &dscp_min, &pcp) == 2) {
+				if (pcp <= 7 && pcp >= 0 && dscp_min >= 0 &&
+				    dscp_min < (sizeof(dscp_pcp->dscp_pcp) /
+				                sizeof(dscp_pcp->dscp_pcp[0]))) {
+					dscp_pcp->dscp_pcp[dscp_min] = pcp;
+				}
+			}
 		}
 	}
 
-- 
GitLab