From cd5364d4fcf02c8b7f0a5ec3b4034a91d292b573 Mon Sep 17 00:00:00 2001
From: Grzegorz Daniluk <grzegorz.daniluk@cern.ch>
Date: Fri, 2 Dec 2016 13:59:29 +0100
Subject: [PATCH] userspace/wrs_vlans: allow port ranges in dot-config, change
 delimiter from ':' to ';'

userspace/tools/wrs_vlans.c
Signed-off-by: Grzegorz Daniluk <grzegorz.daniluk@cern.ch>
the rest:
Signed-off-by: Adam Wujek <adam.wujek@cern.ch>
---
 Kconfig_vlans.in                       | 15 ++++++----
 doc/wrs-user-manual.in                 | 13 +++++----
 userspace/host_tools/gen_vlan_kconf.sh |  5 ++--
 userspace/tools/wrs_vlans.c            | 39 ++++----------------------
 4 files changed, 24 insertions(+), 48 deletions(-)

diff --git a/Kconfig_vlans.in b/Kconfig_vlans.in
index ab1639862..79a777d75 100644
--- a/Kconfig_vlans.in
+++ b/Kconfig_vlans.in
@@ -1267,7 +1267,7 @@ config VLANS_VLAN0000
 	help
 	  Provide the configuration for VLAN0
 	  Example:
-	  fid=0,prio=4,drop=no,ports=1:18
+	  fid=0,prio=4,drop=no,ports=1;2;3-5;7
 	  Where:
 	  --"fid" is a associated Filtering ID (FID) number. One FID can be
 	    associated with many VIDs. RTU learning is performed per-FID.
@@ -1279,7 +1279,8 @@ config VLANS_VLAN0000
 	  --If "drop" is set to "y", all frames belonging to this VID are
 	    dropped (note that frame can belong to a VID as a consequence of
 	    per-port Endpoint configuration); can take values "y" and "n"
-	  --"ports" is a list of ports separated with the colon sign
+	  --"ports" is a list of ports separated with a semicolon sign(";");
+	    ports ranges are supported (with a minus sign)
 
 config VLANS_VLAN0001
 	string "VLAN1 configuration"
@@ -1430,7 +1431,7 @@ config VLANS_VLAN0023
 	help
 	  Provide the configuration for VLAN23
 	  Example:
-	  fid=23,prio=4,drop=no,ports=2:18
+	  fid=23,prio=4,drop=no,ports=1;2;3-5;7
 	  Where:
 	  --"fid" is a associated Filtering ID (FID) number. One FID can be
 	    associated with many VIDs. RTU learning is performed per-FID.
@@ -1442,7 +1443,8 @@ config VLANS_VLAN0023
 	  --If "drop" is set to "y", all frames belonging to this VID are
 	    dropped (note that frame can belong to a VID as a consequence of
 	    per-port Endpoint configuration); can take values "y" and "n"
-	  --"ports" is a list of ports separated with the colon sign
+	  --"ports" is a list of ports separated with a semicolon sign(";");
+	    ports ranges are supported (with a minus sign)
 
 config VLANS_VLAN0024
 	string "VLAN24 configuration"
@@ -1923,7 +1925,7 @@ config VLANS_VLAN0101
 	help
 	  Provide the configuration for VLAN101
 	  Example:
-	  fid=101,prio=4,drop=no,ports=3:18
+	  fid=101,prio=4,drop=no,ports=1;2;3-5;7
 	  Where:
 	  --"fid" is a associated Filtering ID (FID) number. One FID can be
 	    associated with many VIDs. RTU learning is performed per-FID.
@@ -1935,7 +1937,8 @@ config VLANS_VLAN0101
 	  --If "drop" is set to "y", all frames belonging to this VID are
 	    dropped (note that frame can belong to a VID as a consequence of
 	    per-port Endpoint configuration); can take values "y" and "n"
-	  --"ports" is a list of ports separated with the colon sign
+	  --"ports" is a list of ports separated with a semicolon sign(";");
+	    ports ranges are supported (with a minus sign)
 
 config VLANS_VLAN0102
 	string "VLAN102 configuration"
diff --git a/doc/wrs-user-manual.in b/doc/wrs-user-manual.in
index 9c82696de..98f08a470 100644
--- a/doc/wrs-user-manual.in
+++ b/doc/wrs-user-manual.in
@@ -884,7 +884,7 @@ value is changed by the web interface, proper action is taken.
 	Provide the configuration for VLAN from the range 0000-4094.
 	This option is a comma separated string in the following format:
 
-	@t{fid=<0..4094>,prio=<-1|0..7>,drop=<y|n>,ports=<1>:<2>:...:<18>}
+	@t{fid=<0..4094>,prio=<-1|0..7>,drop=<y|n>,ports=<1>;<2>;...;<...-...>;<18>}
 
 	Where:
 	@itemize
@@ -899,17 +899,18 @@ value is changed by the web interface, proper action is taken.
 	@item If @t{drop} is set to @t{y}, all frames belonging to this VID are
 	  dropped (note that frame can belong to a VID as a consequence of
 	  per-port Endpoint configuration); can take values @t{y} and @t{n}
-	@item @t{ports} is a list of ports separated with the colon sign
+	@item @t{ports} is a list of ports separated with the semicolon sign
 	VLANs configuration per VLANS.
 	@end itemize
 	Example:
 
-	@t{fid=4,prio=2,drop=n,ports=1:15}
+	@t{fid=4,prio=2,drop=n,ports=1;<3-5>;15}
 
 	It sets fid as 4, priority 2, don't drop frames belonging to this VLAN,
-	assign ports 1 and 15 to this VLAN.
+	assign ports 1, 3-5 and 15 to this VLAN.
 
-	For more details about VLANs configuration please refer to the @ref{VLANs Configuration}
+	For more details about VLANs configuration please refer to the
+	@ref{VLANs Configuration}
 
 @end table
 
@@ -1223,7 +1224,7 @@ CONFIG_VLANS_PORT03_VID=2
 
 CONFIG_VLANS_ENABLE_SET1=y
 CONFIG_VLANS_VLAN0001="fid=1,prio=4,drop=no,ports=1"
-CONFIG_VLANS_VLAN0002="fid=2,prio=4,drop=no,ports=2:3"
+CONFIG_VLANS_VLAN0002="fid=2,prio=4,drop=no,ports=2;3"
 @end smallexample
 
 @c =-------------------------------------------------------------------------
diff --git a/userspace/host_tools/gen_vlan_kconf.sh b/userspace/host_tools/gen_vlan_kconf.sh
index 679b61ce2..9c631a123 100755
--- a/userspace/host_tools/gen_vlan_kconf.sh
+++ b/userspace/host_tools/gen_vlan_kconf.sh
@@ -185,7 +185,7 @@ for set_i in {1..3}; do
 			# for the first VLAN in the menu print full help
 			echo "	  Provide the configuration for VLAN"$vlan_i
 			echo "	  Example:"
-			echo "	  fid="$vlan_min",prio=4,drop=no,ports="$set_i":18"
+			echo "	  fid="$vlan_min",prio=4,drop=no,ports=1;2;3-5;7"
 			echo "	  Where:"
 			echo "	  --\"fid\" is a associated Filtering ID (FID) number. One FID can be"
 			echo "	    associated with many VIDs. RTU learning is performed per-FID."
@@ -197,7 +197,8 @@ for set_i in {1..3}; do
 			echo "	  --If \"drop\" is set to \"y\", all frames belonging to this VID are"
 			echo "	    dropped (note that frame can belong to a VID as a consequence of"
 			echo "	    per-port Endpoint configuration); can take values \"y\" and \"n\""
-			echo "	  --\"ports\" is a list of ports separated with the colon sign"
+			echo "	  --\"ports\" is a list of ports separated with a semicolon sign(\";\");"
+			echo "	    ports ranges are supported (with a minus sign)"
 		else
 			# for the rest just refer to the first VLAN in the menu
 			echo "	  Please check the help of VLANS_VLAN"$vlan_min_0
diff --git a/userspace/tools/wrs_vlans.c b/userspace/tools/wrs_vlans.c
index 403292133..da6fe2467 100644
--- a/userspace/tools/wrs_vlans.c
+++ b/userspace/tools/wrs_vlans.c
@@ -121,7 +121,7 @@ static int parse_mask(char *arg, unsigned long *pmask)
 	char c, *newarg, *s;
 
 	newarg = strdup(arg);
-	while ( (s = strtok(newarg, ",")) ) {
+	while ( (s = strtok(newarg, ",;")) ) {
 		newarg = NULL; /* for next iteration */
 		switch (sscanf(s, "%i-%i%c", &p1, &p2, &c)) {
 		case 1:
@@ -139,7 +139,6 @@ static int parse_mask(char *arg, unsigned long *pmask)
 			return -1;
 		for (; p1 <= p2; p1++) {
 			*pmask |= (1 << p1);
-			portmask |= (1 << p1);
 		}
 	}
 	if (wrs_msg_level < LOG_DEBUG)
@@ -240,6 +239,9 @@ int main(int argc, char *argv[])
 				pr_error("wrong port mask \"%s\"\n", optarg);
 				exit(1);
 			}
+			/* add this set of ports to the global list of ports
+			 * that are configured */
+			portmask |= conf_pmask;
 			break;
 
 		case OPT_P_QMODE:
@@ -1030,8 +1032,6 @@ static void read_dot_config_vlans(int vlan_min, int vlan_max)
 	int vlan_flags;
 	int vlan;
 	char buff[60];
-	char *beg; /* beginning char of a port number */
-	char *end; /* end char of a port number */
 	int port;
 
 	for (vlan = vlan_min; vlan <= vlan_max; vlan++) {
@@ -1083,36 +1083,7 @@ static void read_dot_config_vlans(int vlan_min, int vlan_max)
 		}
 		if (!libwr_cfg_convert2("VLANS_VLAN%04d", "ports",
 					LIBWR_STRING, buff, vlan)) {
-			beg = buff;
-			while (1) {
-				port = strtol(beg, &end, 0);
-				if (end == beg) {
-					pr_error("invalid ports parameter "
-						 "\"%s\" in VLANS_VLAN%04d\n",
-						 buff, vlan);
-					exit(1);
-				}
-				if (port < 1 || port > NPORTS) {
-					pr_error("invalid port %d (\"%s\") for"
-						 " vlan %4d\n",
-						 port, buff, vlan);
-					exit(1);
-				}
-				if (wrs_msg_level >= LOG_DEBUG)
-					printf("Vlan %4d: Found port %d\n",
-					       vlan, port);
-				pmask |= 1 << (port - 1);
-				if (*end == '\0') {
-					/* end of ports' string */
-					break;
-				}
-				if (*end == ':') {
-					/* check next port */
-					beg = end;
-					beg++; /* skip ":" */
-					continue;
-				}
-			}
+			parse_mask(buff, &pmask);
 
 			if (pmask < RTU_PMASK_MIN || pmask > RTU_PMASK_MAX) {
 				pr_error("invalid port mask 0x%x (\"%s\") for "
-- 
GitLab