defaults: robustify flow table detection.
authorRui Salvaterra <rsalvaterra@gmail.com>
Fri, 24 Jan 2020 15:56:32 +0000 (15:56 +0000)
committerJo-Philipp Wich <jo@mein.io>
Tue, 28 Jan 2020 17:48:43 +0000 (18:48 +0100)
The flow table detection fails if the respective target module is
built into the kernel, 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@gmail.com>
[slightly reword commit message]
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
defaults.c
utils.c
utils.h

index f03765c6be17e058eea110b312b3e66930d75024..c78ab5169dc1b174751649f8c312a2debac2c6db 100644 (file)
@@ -85,26 +85,14 @@ check_policy(struct uci_element *e, enum fw3_flag *pol, const char *name)
 }
 
 static void
 }
 
 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
 }
 
 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_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 441dbd26020a7864411688e2ac8f127b051903db..da6563243c0673f8393c16f65116aeb88ba0ea6c 100644 (file)
--- a/utils.c
+++ b/utils.c
@@ -344,6 +344,33 @@ fw3_has_table(bool ipv6, const char *table)
        return seen;
 }
 
        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 (!strcmp(line, target))
+               {
+                       seen = true;
+                       break;
+               }
+       }
+
+       fclose(f);
+
+       return seen;
+}
 
 bool
 fw3_lock_path(int *fd, const char *path)
 
 bool
 fw3_lock_path(int *fd, const char *path)
diff --git a/utils.h b/utils.h
index c8cf69ac442e92c13e5ad05d9ed2ffe58ad7a4b3..254bea45d48b207ba46a3c427d47d327814195ee 100644 (file)
--- 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_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);
 bool fw3_lock(void);
 void fw3_unlock(void);
 bool fw3_lock_path(int *fw3_lock_fd, const char *path);