Do not let libxtables implicitely load extensions, do it directly from fw3 and track...
authorJo-Philipp Wich <jow@openwrt.org>
Mon, 3 Jun 2013 15:43:06 +0000 (17:43 +0200)
committerJo-Philipp Wich <jow@openwrt.org>
Mon, 3 Jun 2013 16:25:21 +0000 (18:25 +0200)
CMakeLists.txt
iptables.c
iptables.h

index cf7ee96ef5da97ffec7e8213a5106c8807e7843a..4a85e0741212a399b2ba623f3fecdc1ef5517c5f 100644 (file)
@@ -38,7 +38,7 @@ ELSE()
 ENDIF()
 
 ADD_EXECUTABLE(firewall3 main.c options.c defaults.c zones.c forwards.c rules.c redirects.c utils.c ubus.c ipsets.c includes.c iptables.c)
-TARGET_LINK_LIBRARIES(firewall3 uci ubox ubus xtables m ${iptc_libs} ${ext_libs})
+TARGET_LINK_LIBRARIES(firewall3 uci ubox ubus xtables m dl ${iptc_libs} ${ext_libs})
 
 SET(CMAKE_INSTALL_PREFIX /usr)
 
index 21c96b4cb6792eae31a3b31af762194254df041b..2fc8d36fec329b08ad8c9887237ea82d55ef30a7 100644 (file)
@@ -312,6 +312,17 @@ fw3_ipt_commit(struct fw3_ipt_handle *h)
                        fprintf(stderr, "iptc_commit(): %s\n", iptc_strerror(errno));
        }
 
+       if (h->libv)
+       {
+               while (h->libc > 0)
+               {
+                       h->libc--;
+                       dlclose(h->libv[h->libc]);
+               }
+
+               free(h->libv);
+       }
+
        free(h);
 }
 
@@ -354,10 +365,45 @@ get_protoname(struct fw3_ipt_rule *r)
        return NULL;
 }
 
+static bool
+load_extension(struct fw3_ipt_handle *h, const char *name)
+{
+       char path[256];
+       void *lib, **tmp;
+       const char *pfx = (h->family == FW3_FAMILY_V6) ? "libip6t" : "libipt";
+
+       snprintf(path, sizeof(path), "/usr/lib/iptables/libxt_%s.so", name);
+       if (!(lib = dlopen(path, RTLD_NOW)))
+       {
+               snprintf(path, sizeof(path), "/usr/lib/iptables/%s_%s.so", pfx, name);
+               lib = dlopen(path, RTLD_NOW);
+       }
+
+       if (!lib)
+               return false;
+
+       tmp = realloc(h->libv, sizeof(lib) * (h->libc + 1));
+
+       if (!tmp)
+               return false;
+
+       h->libv = tmp;
+       h->libv[h->libc++] = lib;
+
+       return true;
+}
+
 static struct xtables_match *
 find_match(struct fw3_ipt_rule *r, const char *name)
 {
-       return xtables_find_match(name, XTF_TRY_LOAD, &r->matches);
+       struct xtables_match *m;
+
+       m = xtables_find_match(name, XTF_DONT_LOAD, &r->matches);
+
+       if (!m && load_extension(r->h, name))
+               m = xtables_find_match(name, XTF_DONT_LOAD, &r->matches);
+
+       return m;
 }
 
 static void
@@ -416,6 +462,22 @@ load_protomatch(struct fw3_ipt_rule *r)
        return find_match(r, pname);
 }
 
+static struct xtables_target *
+find_target(struct fw3_ipt_rule *r, const char *name)
+{
+       struct xtables_target *t;
+
+       if (is_chain(r->h, name))
+               return xtables_find_target(XT_STANDARD_TARGET, XTF_LOAD_MUST_SUCCEED);
+
+       t = xtables_find_target(name, XTF_DONT_LOAD);
+
+       if (!t && load_extension(r->h, name))
+               t = xtables_find_target(name, XTF_DONT_LOAD);
+
+       return t;
+}
+
 static struct xtables_target *
 get_target(struct fw3_ipt_rule *r, const char *name)
 {
@@ -423,12 +485,7 @@ get_target(struct fw3_ipt_rule *r, const char *name)
        struct xtables_target *t;
        struct xtables_globals *g;
 
-       bool chain = is_chain(r->h, name);
-
-       if (chain)
-               t = xtables_find_target(XT_STANDARD_TARGET, XTF_LOAD_MUST_SUCCEED);
-       else
-               t = xtables_find_target(name, XTF_TRY_LOAD);
+       t = find_target(r, name);
 
        if (!t)
                return NULL;
index 3237a4a8d5bcf81f4cee6289029ca7e45a4cefe7..e86162d42be506225beee84d3383f444b6d82811 100644 (file)
@@ -23,6 +23,7 @@
 #include <libiptc/libip6tc.h>
 #include <xtables.h>
 
+#include <dlfcn.h>
 #include <unistd.h>
 #include <getopt.h>
 #include <sys/utsname.h>
@@ -87,6 +88,9 @@ struct fw3_ipt_handle {
        enum fw3_family family;
        enum fw3_table table;
        void *handle;
+
+       int libc;
+       void **libv;
 };
 
 struct fw3_ipt_rule {