diff mbox series

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

Message ID 20200116211643.24117-1-rsalvaterra@gmail.com
State Changes Requested
Headers show
Series [OpenWrt-Devel] fw3: robustify flow table detection. | expand

Commit Message

Rui Salvaterra Jan. 16, 2020, 9:16 p.m. UTC
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 FLOWTABLE target in
/proc/net/ip_tables_targets.

Signed-off-by: Rui Salvaterra <rsalvaterra@gmail.com>
---
 defaults.c | 24 ++++++------------------
 utils.c    | 26 ++++++++++++++++++++++++++
 utils.h    |  2 ++
 3 files changed, 34 insertions(+), 18 deletions(-)

Comments

Petr Štetiar Jan. 18, 2020, 1:01 p.m. UTC | #1
Rui Salvaterra <rsalvaterra@gmail.com> [2020-01-16 21:16:43]:

Hi,

> +fw3_has_target(const char *target)
> +{
> +	FILE *f;
> +
> +	char line[12];
> +	bool seen = false;
> +
> +	const char *path = "/proc/net/ip_tables_targets";
> +
> +	if (!(f = fopen(path, "r")))
> +		return false;
> +
> +	while (fgets(line, sizeof(line), f))
> +	{
> +		if (!strncmp(line, target, strlen(target)))

This doesn't seem right to me in case target > 12,
MIN(sizeof(line), strlen(target)) perhaps?

-- ynezz
Jo-Philipp Wich Jan. 23, 2020, 8:32 a.m. UTC | #2
Hi,

> This doesn't seem right to me in case target > 12,
> MIN(sizeof(line), strlen(target)) perhaps?

a simple strcmp() without len will be the most appropriate since both
line (produced by fgets()) and target (a constant string literal) will
be \0 terminated.

~ Jo
diff mbox series

Patch

diff --git a/defaults.c b/defaults.c
index f03765c..51ed142 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)
 {
-	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(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,7 @@  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");
+		check_target(e, &defs->flow_offloading, "FLOWOFFLOAD");
 	}
 }
 
diff --git a/utils.c b/utils.c
index 441dbd2..df100a7 100644
--- a/utils.c
+++ b/utils.c
@@ -344,6 +344,32 @@  fw3_has_table(bool ipv6, const char *table)
 	return seen;
 }
 
+bool
+fw3_has_target(const char *target)
+{
+	FILE *f;
+
+	char line[12];
+	bool seen = false;
+
+	const char *path = "/proc/net/ip_tables_targets";
+
+	if (!(f = fopen(path, "r")))
+		return false;
+
+	while (fgets(line, sizeof(line), f))
+	{
+		if (!strncmp(line, target, 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..093d2c6 100644
--- a/utils.h
+++ b/utils.h
@@ -105,6 +105,8 @@  void fw3_pr(const char *fmt, ...)
 
 bool fw3_has_table(bool ipv6, const char *table);
 
+bool fw3_has_target(const char *target);
+
 bool fw3_lock(void);
 void fw3_unlock(void);
 bool fw3_lock_path(int *fw3_lock_fd, const char *path);