]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
Don't load ip6?_tables module when already loaded
authorMaciej Zenczykowski <maze@google.com>
Tue, 19 Apr 2011 07:14:04 +0000 (09:14 +0200)
committerPatrick McHardy <kaber@trash.net>
Tue, 19 Apr 2011 07:14:04 +0000 (09:14 +0200)
Signed-off-by: Maciej Zenczykowski <maze@google.com>
Signed-off-by: Patrick McHardy <kaber@trash.net>
xshared.h
xtables.c

index be53535b2e4ea922c2480d3e6108cbcd72637e84..34f3265cc895fec3a040dcc8f88ffcf5e25369d1 100644 (file)
--- 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;
index a260c7bb9c0723c56ef263f34a51f88c59d9b434..fab1d79d6d86412c8f76da6f400c6613d6f017aa 100644 (file)
--- a/xtables.c
+++ b/xtables.c
 #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,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;
 }