summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorNeutron Soutmun <neo.neutron@gmail.com>2012-05-10 08:05:53 +0200
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2012-05-10 08:05:53 +0200
commit2da431d3685c65d4355d387e213a3cd39d5b59f3 (patch)
treeef3fce367aa55aaae55a8b31a2782775a1adffcb /lib
parentf65b878e52494662fbb648132898575071bed75d (diff)
Add dynamic module support to ipset userspace tool
The patch adds supporting dynamic modules for the set types to ipset userspace tool. The dynamic module support can be enabled by the --enable-settype-modules of "configure". The list of set types to be compiled as dynamic modules can be specified in the --with-settype-modules-list option. Example --enable-settype-modules \ --with-settype-modules-list="ipset_hash_ip ipset_hash_ipport" The keyword "all" can be used to compile all set types as dynamic modules.
Diffstat (limited to 'lib')
-rw-r--r--lib/Make_extra.am96
-rw-r--r--lib/Makefile.am31
-rw-r--r--lib/ipset_bitmap_ip.c7
-rw-r--r--lib/ipset_bitmap_ipmac.c7
-rw-r--r--lib/ipset_bitmap_port.c7
-rw-r--r--lib/ipset_hash_ip.c7
-rw-r--r--lib/ipset_hash_ipport.c7
-rw-r--r--lib/ipset_hash_ipportip.c7
-rw-r--r--lib/ipset_hash_ipportnet.c12
-rw-r--r--lib/ipset_hash_net.c12
-rw-r--r--lib/ipset_hash_netiface.c9
-rw-r--r--lib/ipset_hash_netport.c13
-rw-r--r--lib/ipset_list_set.c7
-rw-r--r--lib/libipset.map1
-rw-r--r--lib/types.c93
15 files changed, 249 insertions, 67 deletions
diff --git a/lib/Make_extra.am b/lib/Make_extra.am
new file mode 100644
index 0000000..743f2bd
--- /dev/null
+++ b/lib/Make_extra.am
@@ -0,0 +1,96 @@
+IPSET_MODSDIR=${libdir}/ipset
+
+if ENABLE_SETTYPE_MODULES
+AM_CFLAGS += -DENABLE_SETTYPE_MODULES \
+ -DIPSET_MODSDIR="\"$(IPSET_MODSDIR)\""
+IPSET_SETTYPE_MODULES = yes
+IPSET_SETTYPE_DYNAMIC = $(if $(findstring all,$(SETTYPE_MODLIST)), \
+ $(IPSET_SETTYPE_LIST), $(SETTYPE_MODLIST))
+else
+IPSET_SETTYPE_DYNAMIC =
+endif
+
+IPSET_SETTYPE_STATIC = $(filter-out $(IPSET_SETTYPE_DYNAMIC), \
+ $(IPSET_SETTYPE_LIST))
+IPSET_SETTYPE_STATIC_OBJECTS = $(patsubst %.c, %.lo, $(IPSET_SETTYPE_STATIC))
+
+IPSET_SETTYPE_DYNAMIC_OBJECTS = $(patsubst %.c, %.lo, $(IPSET_SETTYPE_DYNAMIC))
+IPSET_SETTYPE_DYNAMIC_MODULES = $(patsubst %.c, %.la, $(IPSET_SETTYPE_DYNAMIC))
+IPSET_SETTYPE_DYNAMIC_LTFLAGS = -shared -module -avoid-version
+IPSET_SETTYPE_ALL_MODULES = $(patsubst %.c, %.la, $(IPSET_SETTYPE_STATIC)) \
+ $(IPSET_SETTYPE_DYNAMIC_MODULES)
+
+BUILT_SOURCES = ipset_settype_check types_init.c ipset_settype_modules
+CLEANFILES = ipset_settype_check types_init.c $(IPSET_SETTYPE_ALL_MODULES)
+
+ipset_%.lo: ipset_%.c
+ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`; \
+ $(LTCOMPILE) -D_INIT=ipset_$*_init \
+ $(if $(findstring ipset_$*.c,$(IPSET_SETTYPE_STATIC)), -DTYPE_INCLUSIVE,)\
+ -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< && \
+ $(am__mv) $$depbase.Tpo $$depbase.Plo
+
+ipset_%.la: $(lib_LTLIBRARIES) ipset_%.lo
+ lobj="$(patsubst %.la, %.lo, $@)"; \
+ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(CFLAGS) $(IPSET_SETTYPE_DYNAMIC_LTFLAGS) $(LDFLAGS) -o $@ \
+ -rpath $(IPSET_MODSDIR) $$lobj $(LIBS) $(top_builddir)/lib/libipset.la
+
+types_init.c: $(IPSET_SETTYPE_STATIC_OBJECTS)
+ @( \
+ static_list=`echo $(patsubst %.c,%,$(IPSET_SETTYPE_STATIC))`; \
+ echo -n "" > $@; \
+ for i in $$static_list; do \
+ echo "extern void $${i}_init(void);" >> $@; \
+ done; \
+ echo "void ipset_types_init(void);" >> $@; \
+ echo "void ipset_types_init(void)" >> $@; \
+ echo "{" >> $@; \
+ for i in $$static_list; do \
+ echo " ""$${i}_init();" >> $@; \
+ done; \
+ echo "}" >> $@; \
+ );
+
+ipset_settype_check:
+ @list="$(IPSET_SETTYPE_MODULES) $(IPSET_SETTYPE_STATIC_OBJECTS)"; \
+ test -f $@ || echo "$$list" > $@; \
+ if test "$$list" != "`cat $@`"; then \
+ $(MAKE) clean; \
+ echo "$$list" > $@; \
+ fi
+
+ipset_settype_modules: $(lib_LTLIBRARIES) $(IPSET_SETTYPE_DYNAMIC_OBJECTS) \
+ $(IPSET_SETTYPE_DYNAMIC_MODULES)
+
+install-data-local: install-settype-modules
+uninstall-local: uninstall-settype-modules
+
+install-settype-modules: ipset_settype_modules
+ @$(NORMAL_INSTALL)
+ @list='$(IPSET_SETTYPE_DYNAMIC_MODULES)'; \
+ test -n "$(IPSET_MODSDIR)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(IPSET_MODSDIR)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(IPSET_MODSDIR)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(IPSET_MODSDIR)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(IPSET_MODSDIR)"; \
+ }
+
+uninstall-settype-modules:
+ @$(NORMAL_UNINSTALL)
+ @list='$(IPSET_SETTYPE_DYNAMIC_MODULES)'; \
+ test -n "$(IPSET_MODSDIR)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(IPSET_MODSDIR)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(IPSET_MODSDIR)/$$f"; \
+ done
+
+.PHONY: ipset_settype_check ipset_settype_modules ipset_settype_modules-stamp \
+ install-settype-modules uninstall-settype-modules
diff --git a/lib/Makefile.am b/lib/Makefile.am
index eedd994..90c73e0 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -1,11 +1,26 @@
include $(top_srcdir)/Make_global.am
+IPSET_SETTYPE_LIST = \
+ ipset_bitmap_ip.c \
+ ipset_bitmap_ipmac.c \
+ ipset_bitmap_port.c \
+ ipset_hash_ip.c \
+ ipset_hash_ipport.c \
+ ipset_hash_ipportip.c \
+ ipset_hash_ipportnet.c \
+ ipset_hash_net.c \
+ ipset_hash_netport.c \
+ ipset_hash_netiface.c \
+ ipset_list_set.c
+
AM_CFLAGS += ${libmnl_CFLAGS}
lib_LTLIBRARIES = libipset.la
+include $(top_srcdir)/lib/Make_extra.am
+
libipset_la_LDFLAGS = -Wl,--version-script=$(top_srcdir)/lib/libipset.map -version-info $(LIBVERSION)
-libipset_la_LIBADD = ${libmnl_LIBS}
+libipset_la_LIBADD = ${libmnl_LIBS} $(IPSET_SETTYPE_STATIC_OBJECTS)
libipset_la_SOURCES = \
data.c \
errcode.c \
@@ -17,17 +32,9 @@ libipset_la_SOURCES = \
session.c \
types.c \
ui.c \
- ipset_bitmap_ip.c \
- ipset_bitmap_ipmac.c \
- ipset_bitmap_port.c \
- ipset_hash_ip.c \
- ipset_hash_ipport.c \
- ipset_hash_ipportip.c \
- ipset_hash_ipportnet.c \
- ipset_hash_net.c \
- ipset_hash_netport.c \
- ipset_hash_netiface.c \
- ipset_list_set.c
+ types_init.c
+
+EXTRA_DIST = $(IPSET_SETTYPE_LIST) libipset.map
#%.o: %.c
# ${AM_VERBOSE_CC} ${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} ${CFLAGS} -o $@ -c $<
diff --git a/lib/ipset_bitmap_ip.c b/lib/ipset_bitmap_ip.c
index 9e97b67..8290803 100644
--- a/lib/ipset_bitmap_ip.c
+++ b/lib/ipset_bitmap_ip.c
@@ -56,7 +56,7 @@ static const char bitmap_ip_usage[] =
"where IP, FROM and TO are IPv4 addresses (or hostnames),\n"
" CIDR is a valid IPv4 CIDR prefix.\n";
-struct ipset_type ipset_bitmap_ip0 = {
+static struct ipset_type ipset_bitmap_ip0 = {
.name = "bitmap:ip",
.alias = { "ipmap", NULL },
.revision = 0,
@@ -95,3 +95,8 @@ struct ipset_type ipset_bitmap_ip0 = {
.usage = bitmap_ip_usage,
};
+
+void _init(void)
+{
+ ipset_type_add(&ipset_bitmap_ip0);
+}
diff --git a/lib/ipset_bitmap_ipmac.c b/lib/ipset_bitmap_ipmac.c
index 2a58019..6f51293 100644
--- a/lib/ipset_bitmap_ipmac.c
+++ b/lib/ipset_bitmap_ipmac.c
@@ -53,7 +53,7 @@ static const char bitmap_ipmac_usage[] =
" CIDR is a valid IPv4 CIDR prefix,\n"
" MAC is a valid MAC address.\n";
-struct ipset_type ipset_bitmap_ipmac0 = {
+static struct ipset_type ipset_bitmap_ipmac0 = {
.name = "bitmap:ip,mac",
.alias = { "macipmap", NULL },
.revision = 0,
@@ -98,3 +98,8 @@ struct ipset_type ipset_bitmap_ipmac0 = {
.usage = bitmap_ipmac_usage,
};
+
+void _init(void)
+{
+ ipset_type_add(&ipset_bitmap_ipmac0);
+}
diff --git a/lib/ipset_bitmap_port.c b/lib/ipset_bitmap_port.c
index 3101b22..de02e50 100644
--- a/lib/ipset_bitmap_port.c
+++ b/lib/ipset_bitmap_port.c
@@ -47,7 +47,7 @@ static const char bitmap_port_usage[] =
"test SETNAME PORT\n\n"
"where PORT, FROM and TO are port numbers or port names from /etc/services.\n";
-struct ipset_type ipset_bitmap_port0 = {
+static struct ipset_type ipset_bitmap_port0 = {
.name = "bitmap:port",
.alias = { "portmap", NULL },
.revision = 0,
@@ -85,3 +85,8 @@ struct ipset_type ipset_bitmap_port0 = {
.usage = bitmap_port_usage,
};
+
+void _init(void)
+{
+ ipset_type_add(&ipset_bitmap_port0);
+}
diff --git a/lib/ipset_hash_ip.c b/lib/ipset_hash_ip.c
index e885b13..40f684f 100644
--- a/lib/ipset_hash_ip.c
+++ b/lib/ipset_hash_ip.c
@@ -79,7 +79,7 @@ static const char hash_ip_usage[] =
" Adding/deleting multiple elements in IP/CIDR or FROM-TO form\n"
" is supported for IPv4.\n";
-struct ipset_type ipset_hash_ip0 = {
+static struct ipset_type ipset_hash_ip0 = {
.name = "hash:ip",
.alias = { "iphash", NULL },
.revision = 0,
@@ -117,3 +117,8 @@ struct ipset_type ipset_hash_ip0 = {
.usage = hash_ip_usage,
};
+
+void _init(void)
+{
+ ipset_type_add(&ipset_hash_ip0);
+}
diff --git a/lib/ipset_hash_ipport.c b/lib/ipset_hash_ipport.c
index 54664e1..c9c3b60 100644
--- a/lib/ipset_hash_ipport.c
+++ b/lib/ipset_hash_ipport.c
@@ -85,7 +85,7 @@ static const char hash_ipport1_usage[] =
" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
" port range is supported both for IPv4 and IPv6.\n";
-struct ipset_type ipset_hash_ipport1 = {
+static struct ipset_type ipset_hash_ipport1 = {
.name = "hash:ip,port",
.alias = { "ipporthash", NULL },
.revision = 1,
@@ -142,3 +142,8 @@ struct ipset_type ipset_hash_ipport1 = {
.usage = hash_ipport1_usage,
.usagefn = ipset_port_usage,
};
+
+void _init(void)
+{
+ ipset_type_add(&ipset_hash_ipport1);
+}
diff --git a/lib/ipset_hash_ipportip.c b/lib/ipset_hash_ipportip.c
index 4599b01..ac6182b 100644
--- a/lib/ipset_hash_ipportip.c
+++ b/lib/ipset_hash_ipportip.c
@@ -85,7 +85,7 @@ static const char hash_ipportip1_usage[] =
" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
" port range is supported both for IPv4 and IPv6.\n";
-struct ipset_type ipset_hash_ipportip1 = {
+static struct ipset_type ipset_hash_ipportip1 = {
.name = "hash:ip,port,ip",
.alias = { "ipportiphash", NULL },
.revision = 1,
@@ -153,3 +153,8 @@ struct ipset_type ipset_hash_ipportip1 = {
.usage = hash_ipportip1_usage,
.usagefn = ipset_port_usage,
};
+
+void _init(void)
+{
+ ipset_type_add(&ipset_hash_ipportip1);
+}
diff --git a/lib/ipset_hash_ipportnet.c b/lib/ipset_hash_ipportnet.c
index af85639..6750208 100644
--- a/lib/ipset_hash_ipportnet.c
+++ b/lib/ipset_hash_ipportnet.c
@@ -86,7 +86,7 @@ static const char hash_ipportnet1_usage[] =
" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
" port range is supported both for IPv4 and IPv6.\n";
-struct ipset_type ipset_hash_ipportnet1 = {
+static struct ipset_type ipset_hash_ipportnet1 = {
.name = "hash:ip,port,net",
.alias = { "ipportnethash", NULL },
.revision = 1,
@@ -176,7 +176,7 @@ static const char hash_ipportnet2_usage[] =
" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
" port range is supported both for IPv4 and IPv6.\n";
-struct ipset_type ipset_hash_ipportnet2 = {
+static struct ipset_type ipset_hash_ipportnet2 = {
.name = "hash:ip,port,net",
.alias = { "ipportnethash", NULL },
.revision = 2,
@@ -280,7 +280,7 @@ static const char hash_ipportnet3_usage[] =
" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
" port range is supported both for IPv4 and IPv6.\n";
-struct ipset_type ipset_hash_ipportnet3 = {
+static struct ipset_type ipset_hash_ipportnet3 = {
.name = "hash:ip,port,net",
.alias = { "ipportnethash", NULL },
.revision = 3,
@@ -357,3 +357,9 @@ struct ipset_type ipset_hash_ipportnet3 = {
.usagefn = ipset_port_usage,
};
+void _init(void)
+{
+ ipset_type_add(&ipset_hash_ipportnet1);
+ ipset_type_add(&ipset_hash_ipportnet2);
+ ipset_type_add(&ipset_hash_ipportnet3);
+}
diff --git a/lib/ipset_hash_net.c b/lib/ipset_hash_net.c
index 5829f50..bab33e2 100644
--- a/lib/ipset_hash_net.c
+++ b/lib/ipset_hash_net.c
@@ -69,7 +69,7 @@ static const char hash_net0_usage[] =
" IP is an IPv4 or IPv6 address (or hostname),\n"
" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n";
-struct ipset_type ipset_hash_net0 = {
+static struct ipset_type ipset_hash_net0 = {
.name = "hash:net",
.alias = { "nethash", NULL },
.revision = 0,
@@ -121,7 +121,7 @@ static const char hash_net1_usage[] =
" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n"
" IP range is not supported with IPv6.\n";
-struct ipset_type ipset_hash_net1 = {
+static struct ipset_type ipset_hash_net1 = {
.name = "hash:net",
.alias = { "nethash", NULL },
.revision = 1,
@@ -187,7 +187,7 @@ static const char hash_net2_usage[] =
" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n"
" IP range is not supported with IPv6.\n";
-struct ipset_type ipset_hash_net2 = {
+static struct ipset_type ipset_hash_net2 = {
.name = "hash:net",
.alias = { "nethash", NULL },
.revision = 2,
@@ -229,3 +229,9 @@ struct ipset_type ipset_hash_net2 = {
.usage = hash_net2_usage,
};
+void _init(void)
+{
+ ipset_type_add(&ipset_hash_net0);
+ ipset_type_add(&ipset_hash_net1);
+ ipset_type_add(&ipset_hash_net2);
+}
diff --git a/lib/ipset_hash_netiface.c b/lib/ipset_hash_netiface.c
index 7fca5fe..e60acbf 100644
--- a/lib/ipset_hash_netiface.c
+++ b/lib/ipset_hash_netiface.c
@@ -62,7 +62,7 @@ static const char hash_netiface_usage[] =
" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n"
" Adding/deleting multiple elements with IPv4 is supported.\n";
-struct ipset_type ipset_hash_netiface0 = {
+static struct ipset_type ipset_hash_netiface0 = {
.name = "hash:net,iface",
.alias = { "netifacehash", NULL },
.revision = 0,
@@ -143,7 +143,7 @@ static const char hash_netiface1_usage[] =
" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n"
" Adding/deleting multiple elements with IPv4 is supported.\n";
-struct ipset_type ipset_hash_netiface1 = {
+static struct ipset_type ipset_hash_netiface1 = {
.name = "hash:net,iface",
.alias = { "netifacehash", NULL },
.revision = 1,
@@ -200,3 +200,8 @@ struct ipset_type ipset_hash_netiface1 = {
.usage = hash_netiface1_usage,
};
+void _init(void)
+{
+ ipset_type_add(&ipset_hash_netiface0);
+ ipset_type_add(&ipset_hash_netiface1);
+}
diff --git a/lib/ipset_hash_netport.c b/lib/ipset_hash_netport.c
index d8d220e..285f06c 100644
--- a/lib/ipset_hash_netport.c
+++ b/lib/ipset_hash_netport.c
@@ -63,7 +63,7 @@ static const char hash_netport1_usage[] =
" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
" port range is supported both for IPv4 and IPv6.\n";
-struct ipset_type ipset_hash_netport1 = {
+static struct ipset_type ipset_hash_netport1 = {
.name = "hash:net,port",
.alias = { "netporthash", NULL },
.revision = 1,
@@ -137,7 +137,7 @@ static const char hash_netport2_usage[] =
" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
" port range is supported both for IPv4 and IPv6.\n";
-struct ipset_type ipset_hash_netport2 = {
+static struct ipset_type ipset_hash_netport2 = {
.name = "hash:net,port",
.alias = { "netporthash", NULL },
.revision = 2,
@@ -225,7 +225,7 @@ static const char hash_netport3_usage[] =
" Adding/deleting multiple elements with TCP/SCTP/UDP/UDPLITE\n"
" port range is supported both for IPv4 and IPv6.\n";
-struct ipset_type ipset_hash_netport3 = {
+static struct ipset_type ipset_hash_netport3 = {
.name = "hash:net,port",
.alias = { "netporthash", NULL },
.revision = 3,
@@ -286,3 +286,10 @@ struct ipset_type ipset_hash_netport3 = {
.usage = hash_netport3_usage,
.usagefn = ipset_port_usage,
};
+
+void _init(void)
+{
+ ipset_type_add(&ipset_hash_netport1);
+ ipset_type_add(&ipset_hash_netport2);
+ ipset_type_add(&ipset_hash_netport3);
+}
diff --git a/lib/ipset_list_set.c b/lib/ipset_list_set.c
index 67c29b6..dc0bf53 100644
--- a/lib/ipset_list_set.c
+++ b/lib/ipset_list_set.c
@@ -46,7 +46,7 @@ static const char list_set_usage[] =
"test SETNAME NAME [before|after NAME]\n\n"
"where NAME are existing set names.\n";
-struct ipset_type ipset_list_set0 = {
+static struct ipset_type ipset_list_set0 = {
.name = "list:set",
.alias = { "setlist", NULL },
.revision = 0,
@@ -89,3 +89,8 @@ struct ipset_type ipset_list_set0 = {
.usage = list_set_usage,
};
+
+void _init(void)
+{
+ ipset_type_add(&ipset_list_set0);
+}
diff --git a/lib/libipset.map b/lib/libipset.map
index 86bb923..0eb7fad 100644
--- a/lib/libipset.map
+++ b/lib/libipset.map
@@ -114,4 +114,5 @@ LIBIPSET_2.0 {
global:
ipset_load_types;
ipset_port_usage;
+ ipset_parse_timeout;
} LIBIPSET_1.0;
diff --git a/lib/types.c b/lib/types.c
index 2c8e04f..64c9c84 100644
--- a/lib/types.c
+++ b/lib/types.c
@@ -19,25 +19,11 @@
#include <libipset/utils.h> /* STREQ */
#include <libipset/types.h> /* prototypes */
-/* The known set types: (typename, revision, family) is unique */
-extern struct ipset_type ipset_bitmap_ip0;
-extern struct ipset_type ipset_bitmap_ipmac0;
-extern struct ipset_type ipset_bitmap_port0;
-extern struct ipset_type ipset_hash_ip0;
-extern struct ipset_type ipset_hash_net0;
-extern struct ipset_type ipset_hash_net1;
-extern struct ipset_type ipset_hash_net2;
-extern struct ipset_type ipset_hash_netport1;
-extern struct ipset_type ipset_hash_netport2;
-extern struct ipset_type ipset_hash_netport3;
-extern struct ipset_type ipset_hash_netiface0;
-extern struct ipset_type ipset_hash_netiface1;
-extern struct ipset_type ipset_hash_ipport1;
-extern struct ipset_type ipset_hash_ipportip1;
-extern struct ipset_type ipset_hash_ipportnet1;
-extern struct ipset_type ipset_hash_ipportnet2;
-extern struct ipset_type ipset_hash_ipportnet3;
-extern struct ipset_type ipset_list_set0;
+#ifdef ENABLE_SETTYPE_MODULES
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <dirent.h>
+#endif
/* Userspace cache of sets which exists in the kernel */
@@ -583,25 +569,58 @@ ipset_cache_fini(void)
void
ipset_load_types(void)
{
+#ifdef ENABLE_SETTYPE_MODULES
+ const char *dir = IPSET_MODSDIR;
+ const char *next = NULL;
+ char path[256];
+ char file[256];
+ struct dirent **list = NULL;
+ int n;
+ int len;
+#endif
+
if (typelist != NULL)
return;
- ipset_type_add(&ipset_bitmap_ip0);
- ipset_type_add(&ipset_bitmap_ipmac0);
- ipset_type_add(&ipset_bitmap_port0);
- ipset_type_add(&ipset_hash_ip0);
- ipset_type_add(&ipset_hash_net0);
- ipset_type_add(&ipset_hash_net1);
- ipset_type_add(&ipset_hash_net2);
- ipset_type_add(&ipset_hash_netport1);
- ipset_type_add(&ipset_hash_netport2);
- ipset_type_add(&ipset_hash_netport3);
- ipset_type_add(&ipset_hash_netiface0);
- ipset_type_add(&ipset_hash_netiface1);
- ipset_type_add(&ipset_hash_ipport1);
- ipset_type_add(&ipset_hash_ipportip1);
- ipset_type_add(&ipset_hash_ipportnet1);
- ipset_type_add(&ipset_hash_ipportnet2);
- ipset_type_add(&ipset_hash_ipportnet3);
- ipset_type_add(&ipset_list_set0);
+ /* Initialize static types */
+ ipset_types_init();
+
+#ifdef ENABLE_SETTYPE_MODULES
+ /* Initialize dynamic types */
+ do {
+ next = strchr(dir, ':');
+ if (next == NULL)
+ next = dir + strlen(dir);
+
+ len = snprintf(path, sizeof(path), "%.*s",
+ (unsigned int)(next - dir), dir);
+
+ if (len >= sizeof(path) || len < 0)
+ continue;
+
+ n = scandir(path, &list, NULL, alphasort);
+ if (n < 0)
+ continue;
+
+ while (n--) {
+ if (strstr(list[n]->d_name, ".so") == NULL)
+ goto nextf;
+
+ len = snprintf(file, sizeof(file), "%s/%s", path, list[n]->d_name);
+ if (len >= sizeof(file) || len < 0)
+ goto nextf;
+
+ if (dlopen(file, RTLD_NOW) == NULL) {
+ fprintf(stderr, "%s: %s\n", file, dlerror());
+ }
+
+nextf:
+ free(list[n]);
+ }
+
+ free(list);
+
+ dir = next + 1;
+ } while (*next != '\0');
+#endif // ENABLE_SETTYPE_MODULES
}