From b32b361a725c8fe3a3aa494e6cdec09a80785aac Mon Sep 17 00:00:00 2001 From: Maciej Zenczykowski Date: Tue, 19 Apr 2011 09:14:04 +0200 Subject: Don't load ip6?_tables module when already loaded Signed-off-by: Maciej Zenczykowski Signed-off-by: Patrick McHardy --- xshared.h | 2 ++ xtables.c | 38 +++++++++++++++++++++++++++++++++----- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/xshared.h b/xshared.h index be53535b..34f3265c 100644 --- a/xshared.h +++ b/xshared.h @@ -29,6 +29,7 @@ struct xtables_target; /** * xtables_afinfo - protocol family dependent information * @kmod: kernel module basename (e.g. "ip_tables") + * @proc_exists: file which exists in procfs when module already loaded * @libprefix: prefix of .so library name (e.g. "libipt_") * @family: nfproto family * @ipproto: used by setsockopt (e.g. IPPROTO_IP) @@ -37,6 +38,7 @@ struct xtables_target; */ struct xtables_afinfo { const char *kmod; + const char *proc_exists; const char *libprefix; uint8_t family; uint8_t ipproto; diff --git a/xtables.c b/xtables.c index a260c7bb..fab1d79d 100644 --- a/xtables.c +++ b/xtables.c @@ -27,9 +27,11 @@ #include #include #include +#include #include #include #include +#include /* for PROC_SUPER_MAGIC */ #include #include /* INT_MAX in ip_tables.h/ip6_tables.h */ @@ -139,6 +141,7 @@ struct option *xtables_merge_options(struct option *orig_opts, static const struct xtables_afinfo afinfo_ipv4 = { .kmod = "ip_tables", + .proc_exists = "/proc/net/ip_tables_names", .libprefix = "libipt_", .family = NFPROTO_IPV4, .ipproto = IPPROTO_IP, @@ -148,6 +151,7 @@ static const struct xtables_afinfo afinfo_ipv4 = { static const struct xtables_afinfo afinfo_ipv6 = { .kmod = "ip6_tables", + .proc_exists = "/proc/net/ip6_tables_names", .libprefix = "libip6t_", .family = NFPROTO_IPV6, .ipproto = IPPROTO_IPV6, @@ -369,15 +373,39 @@ int xtables_insmod(const char *modname, const char *modprobe, bool quiet) return -1; } +/* return true if a given file exists within procfs */ +static bool proc_file_exists(const char *filename) +{ + struct stat s; + struct statfs f; + + if (lstat(filename, &s)) + return false; + if (!S_ISREG(s.st_mode)) + return false; + if (statfs(filename, &f)) + return false; + if (f.f_type != PROC_SUPER_MAGIC) + return false; + return true; +} + int xtables_load_ko(const char *modprobe, bool quiet) { static bool loaded = false; - static int ret = -1; + int ret; - if (!loaded) { - ret = xtables_insmod(afinfo->kmod, modprobe, quiet); - loaded = (ret == 0); - } + if (loaded) + return 0; + + if (proc_file_exists(afinfo->proc_exists)) { + loaded = true; + return 0; + }; + + ret = xtables_insmod(afinfo->kmod, modprobe, quiet); + if (ret == 0) + loaded = true; return ret; } -- cgit v1.2.3