summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRui Salvaterra <rsalvaterra@gmail.com>2020-01-24 15:56:32 +0000
committerJo-Philipp Wich <jo@mein.io>2020-01-28 18:48:43 +0100
commit7cc2a84d5fa28a79033dcf882d474d151e3d0c89 (patch)
tree2e84b02b4a92c77e285adcf18eeff8a93772e7de
parent8174814a507489ebbe8bb85c1004e1f02919ca82 (diff)
downloadfirewall3-7cc2a84d5fa28a79033dcf882d474d151e3d0c89.tar.gz
defaults: robustify flow table detection.
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>
-rw-r--r--defaults.c25
-rw-r--r--utils.c27
-rw-r--r--utils.h2
3 files changed, 36 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..da65632 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 (!strcmp(line, 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..254bea4 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 bool ipv6, const char *target);
+
bool fw3_lock(void);
void fw3_unlock(void);
bool fw3_lock_path(int *fw3_lock_fd, const char *path);