From: Maciej Åenczykowski <maze@xxxxxxxxxx> Signed-off-by: Maciej Zenczykowski <maze@xxxxxxxxxx> --- xshared.h | 2 ++ xtables.c | 34 +++++++++++++++++++++++++++++----- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/xshared.h b/xshared.h index be53535..34f3265 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 a260c7b..e424c28 100644 --- a/xtables.c +++ b/xtables.c @@ -27,9 +27,11 @@ #include <unistd.h> #include <sys/socket.h> #include <sys/stat.h> +#include <sys/statfs.h> #include <sys/types.h> #include <sys/wait.h> #include <arpa/inet.h> +#include <linux/magic.h> /* for PROC_SUPER_MAGIC */ #include <xtables.h> #include <limits.h> /* 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,35 @@ 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; } -- 1.7.3.1 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html