From 865ddfd7df6a49f9346207cc105fc4f57da529c7 Mon Sep 17 00:00:00 2001
From: Jo-Philipp Wich <jow@openwrt.org>
Date: Thu, 7 Mar 2013 11:05:15 +0100
Subject: [PATCH] Support abstract "tcpudp" protocol

---
 options.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/options.c b/options.c
index a35247f..6c5e2cf 100644
--- a/options.c
+++ b/options.c
@@ -665,7 +665,7 @@ void
 fw3_parse_options(void *s, const struct fw3_option *opts,
                   struct uci_section *section)
 {
-	char *p;
+	char *p, *v;
 	bool known;
 	struct uci_element *e, *l;
 	struct uci_option *o;
@@ -720,9 +720,15 @@ fw3_parse_options(void *s, const struct fw3_option *opts,
 			}
 			else
 			{
-				if (!o->v.string)
+				v = o->v.string;
+
+				if (!v)
 					continue;
 
+				/* protocol "tcpudp" compatibility hack */
+				if (opt->parse == fw3_parse_protocol && !strcmp(v, "tcpudp"))
+					v = strdup("tcp udp");
+
 				if (!opt->elem_size)
 				{
 					if (!opt->parse((char *)s + opt->offset, o->v.string))
@@ -730,9 +736,7 @@ fw3_parse_options(void *s, const struct fw3_option *opts,
 				}
 				else
 				{
-					for (p = strtok(o->v.string, " \t");
-					     p != NULL;
-					     p = strtok(NULL, " \t"))
+					for (p = strtok(v, " \t"); p != NULL; p = strtok(NULL, " \t"))
 					{
 						item = malloc(opt->elem_size);
 
@@ -752,6 +756,9 @@ fw3_parse_options(void *s, const struct fw3_option *opts,
 						list_add_tail(item, dest);
 					}
 				}
+
+				if (v != o->v.string)
+					free(v);
 			}
 
 			known = true;
-- 
2.25.1