diff options
author | Rui Salvaterra <rsalvaterra@gmail.com> | 2020-01-24 15:56:32 +0000 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2020-01-28 18:48:43 +0100 |
commit | 7cc2a84d5fa28a79033dcf882d474d151e3d0c89 (patch) | |
tree | 2e84b02b4a92c77e285adcf18eeff8a93772e7de | |
parent | 8174814a507489ebbe8bb85c1004e1f02919ca82 (diff) | |
download | firewall3-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.c | 25 | ||||
-rw-r--r-- | utils.c | 27 | ||||
-rw-r--r-- | utils.h | 2 |
3 files changed, 36 insertions, 18 deletions
@@ -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); } } @@ -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) @@ -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); |