From: Neutron Soutmun Date: Thu, 10 May 2012 06:05:53 +0000 (+0200) Subject: Add dynamic module support to ipset userspace tool X-Git-Tag: v6.12.1~13 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2da431d3685c65d4355d387e213a3cd39d5b59f3;p=thirdparty%2Fipset.git 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. --- diff --git a/.gitignore b/.gitignore index 686413dd..da371b4d 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 00f1115e..7e7cf751 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 950988fc..1fd3f926 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 00000000..743f2bda --- /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 eedd9943..90c73e01 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 9e97b67c..8290803a 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 2a580198..6f512936 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 3101b224..de02e505 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 e885b138..40f684f2 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 54664e12..c9c3b600 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 4599b01d..ac6182bc 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 af856392..67502084 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 5829f504..bab33e22 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 7fca5fec..e60acbfc 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 d8d220ee..285f06c3 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 67c29b6a..dc0bf535 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 86bb923c..0eb7fad9 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 2c8e04f7..64c9c848 100644 --- a/lib/types.c +++ b/lib/types.c @@ -19,25 +19,11 @@ #include /* STREQ */ #include /* 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 +#include +#include +#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 64d9bbcd..4d934ba2 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 e3f65493..fcc46215 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