summaryrefslogtreecommitdiffstats
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
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.
-rw-r--r--.gitignore2
-rw-r--r--configure.ac42
-rw-r--r--include/libipset/types.h12
-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
-rw-r--r--m4/.gitignore1
-rw-r--r--src/Makefile.am7
20 files changed, 313 insertions, 67 deletions
diff --git a/.gitignore b/.gitignore
index 686413d..da371b4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,3 +24,5 @@ modules.order
/configure
/libtool
/stamp-h1
+
+/libltdl/
diff --git a/configure.ac b/configure.ac
index 00f1115..7e7cf75 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6,6 +6,11 @@ AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADER([config.h])
AM_INIT_AUTOMAKE([foreign subdir-objects tar-pax])
+AC_ENABLE_STATIC
+LT_INIT([dlopen])
+LT_CONFIG_LTDL_DIR([libltdl])
+LTDL_INIT([nonrecursive])
+
dnl Shortcut: Linux supported alone
case "$host" in
*-*-linux*) ;;
@@ -100,6 +105,43 @@ AC_ARG_ENABLE([debug],
AM_CONDITIONAL([ENABLE_DEBUG], [test "x$enable_debug" = xyes])
+dnl Enable type modules
+AC_ARG_ENABLE([settype_modules],
+ AS_HELP_STRING([--enable-settype-modules],
+ [Enable set type modules support]),
+ [enable_settype_modules="$enableval"],
+ [enable_settype_modules="no"])
+
+AC_ARG_WITH([settype_modules_list],
+ AS_HELP_STRING([--with-settype-modules-list="mod1 mod2 ..."],
+ [List of dynamic loading modules, ignored if settype-modules is disabled. It could be "all" to build all available settypes as modules]),
+ [SETTYPE_MODLIST_RAW="$withval";])
+
+SETTYPE_MODLIST=
+if test "x$enable_settype_modules" = "xyes"; then
+ for mod in $SETTYPE_MODLIST_RAW; do
+ if echo $mod | grep "all"; then
+ m="${mod}"
+ else
+ if echo $mod | grep "ipset_"; then
+ m="${mod}.c"
+ else
+ m="ipset_${mod}.c"
+ fi
+ fi
+
+ SETTYPE_MODLIST="${SETTYPE_MODLIST} $m"
+ done
+
+ AC_MSG_RESULT([checking for configuration with dynamic loading modules... $SETTYPE_MODLIST_RAW])
+fi
+AC_SUBST(SETTYPE_MODLIST)
+
+AM_CONDITIONAL([ENABLE_SETTYPE_MODULES], [test "x$enable_settype_modules" = xyes])
+
+AM_CONDITIONAL([ENABLE_STATIC], [test "x$enable_static" = xyes])
+AM_CONDITIONAL([ENABLE_SHARED], [test "x$enable_shared" = xyes])
+
dnl Checks for programs
: ${CFLAGS=""}
diff --git a/include/libipset/types.h b/include/libipset/types.h
index 950988f..1fd3f92 100644
--- a/include/libipset/types.h
+++ b/include/libipset/types.h
@@ -107,4 +107,16 @@ extern bool ipset_match_typename(const char *str,
const struct ipset_type *t);
extern void ipset_load_types(void);
+extern void ipset_types_init(void);
+
+#ifdef TYPE_INCLUSIVE
+# ifdef _INIT
+# undef _init
+# define _init _INIT
+# endif
+#else
+# undef _init
+# define _init __attribute__((constructor)) _INIT
+#endif
+
#endif /* LIBIPSET_TYPES_H */
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
}
diff --git a/m4/.gitignore b/m4/.gitignore
index 64d9bbc..4d934ba 100644
--- a/m4/.gitignore
+++ b/m4/.gitignore
@@ -1,2 +1,3 @@
/libtool.m4
/lt*.m4
+/argz.m4
diff --git a/src/Makefile.am b/src/Makefile.am
index e3f6549..fcc4621 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -3,7 +3,14 @@ include $(top_srcdir)/Make_global.am
sbin_PROGRAMS = ipset
ipset_SOURCES = ipset.c ui.c
ipset_LDADD = ../lib/libipset.la
+
+if ENABLE_SETTYPE_MODULES
+AM_LDFLAGS = -shared
+else
+if ENABLE_STATIC
AM_LDFLAGS = -static
+endif
+endif
dist_man_MANS = ipset.8