[OpenWrt-Devel] [PATCH v2] fw3: robustify flow table detection.

Rui Salvaterra rsalvaterra at gmail.com
Sat Jan 18 13:44:47 EST 2020


v2: addressed Petr Štetiar's concerns and also changed the generic helper
to check for the availability of IPv4 or IPv6 targets, as needed.

The flowtable detection fails if the respective target module is built-in,
since it's looking for the module itself. Create a generic helper and
instead check for existence of the FLOWOFFLOAD target in
/proc/net/ip_tables_targets.

Signed-off-by: Rui Salvaterra <rsalvaterra at gmail.com>
---
 defaults.c | 25 +++++++------------------
 utils.c    | 27 +++++++++++++++++++++++++++
 utils.h    |  6 ++++++
 3 files changed, 40 insertions(+), 18 deletions(-)

diff --git a/defaults.c b/defaults.c
index f03765c..c78ab51 100644
--- a/defaults.c
+++ b/defaults.c
@@ -85,26 +85,14 @@ check_policy(struct uci_element *e, enum fw3_flag *pol, const char *name)
 }
 
 static void
-check_kmod(struct uci_element *e, bool *module, const char *name)
+check_target(struct uci_element *e, bool *available, const char *target, const bool ipv6)
 {
-	FILE *f;
-	char buf[128];
-
-	if (!*module)
-		return;
-
-	snprintf(buf, sizeof(buf), "/sys/module/%s/refcnt", name);
-
-	f = fopen(buf, "r");
-
-	if (f)
+	const bool b = fw3_has_target(ipv6, target);
+	if (!b)
 	{
-		fclose(f);
-		return;
+		warn_elem(e, "requires unavailable target extension %s, disabling", target);
 	}
-
-	warn_elem(e, "requires not available kernel module %s, disabling", name);
-	*module = false;
+	*available = b;
 }
 
 static void
@@ -171,7 +159,8 @@ fw3_load_defaults(struct fw3_state *state, struct uci_package *p)
 
 		check_any_reject_code(e, &defs->any_reject_code);
 
-		check_kmod(e, &defs->flow_offloading, "xt_FLOWOFFLOAD");
+		/* exists in both ipv4 and ipv6, if at all, so only check ipv4 */
+		check_target(e, &defs->flow_offloading, "FLOWOFFLOAD", false);
 	}
 }
 
diff --git a/utils.c b/utils.c
index 441dbd2..f68a60a 100644
--- a/utils.c
+++ b/utils.c
@@ -344,6 +344,33 @@ fw3_has_table(bool ipv6, const char *table)
 	return seen;
 }
 
+bool
+fw3_has_target(const bool ipv6, const char *target)
+{
+	FILE *f;
+
+	char line[12];
+	bool seen = false;
+
+	const char *path = ipv6
+		? "/proc/net/ip6_tables_targets" : "/proc/net/ip_tables_targets";
+
+	if (!(f = fopen(path, "r")))
+		return false;
+
+	while (fgets(line, sizeof(line), f))
+	{
+		if (!strncmp(line, target, MIN(sizeof(line), strlen(target))))
+		{
+			seen = true;
+			break;
+		}
+	}
+
+	fclose(f);
+
+	return seen;
+}
 
 bool
 fw3_lock_path(int *fd, const char *path)
diff --git a/utils.h b/utils.h
index c8cf69a..558bb4f 100644
--- a/utils.h
+++ b/utils.h
@@ -89,6 +89,10 @@ void info(const char *format, ...)
     (!(flags & ((1<<FW3_TABLE_FILTER)|(1<<FW3_TABLE_NAT)|                  \
                 (1<<FW3_TABLE_MANGLE)|(1<<FW3_TABLE_RAW))))
 
+#define MIN(a,b)				\
+	({ __typeof__ (a) _a = (a);		\
+		__typeof__ (b) _b = (b);	\
+		_a < _b ? _a : _b; })
 
 void * fw3_alloc(size_t size);
 char * fw3_strdup(const char *s);
@@ -105,6 +109,8 @@ void fw3_pr(const char *fmt, ...)
 
 bool fw3_has_table(bool ipv6, const char *table);
 
+bool fw3_has_target(const bool ipv6, const char *target);
+
 bool fw3_lock(void);
 void fw3_unlock(void);
 bool fw3_lock_path(int *fw3_lock_fd, const char *path);
-- 
2.25.0


_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel


More information about the openwrt-devel mailing list