]> granicus.if.org Git - ipset/commitdiff
Add dynamic module support to ipset userspace tool
authorNeutron Soutmun <neo.neutron@gmail.com>
Thu, 10 May 2012 06:05:53 +0000 (08:05 +0200)
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Thu, 10 May 2012 06:05:53 +0000 (08:05 +0200)
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.

20 files changed:
.gitignore
configure.ac
include/libipset/types.h
lib/Make_extra.am [new file with mode: 0644]
lib/Makefile.am
lib/ipset_bitmap_ip.c
lib/ipset_bitmap_ipmac.c
lib/ipset_bitmap_port.c
lib/ipset_hash_ip.c
lib/ipset_hash_ipport.c
lib/ipset_hash_ipportip.c
lib/ipset_hash_ipportnet.c
lib/ipset_hash_net.c
lib/ipset_hash_netiface.c
lib/ipset_hash_netport.c
lib/ipset_list_set.c
lib/libipset.map
lib/types.c
m4/.gitignore
src/Makefile.am

index 686413dd71dfd9e24c923e626c369e75f34c1d0e..da371b4d16ed45569a62a308492902a3d38d0640 100644 (file)
@@ -24,3 +24,5 @@ modules.order
 /configure
 /libtool
 /stamp-h1
+
+/libltdl/
index 00f1115edd1136bc6ef234e125ea15f2efd61743..7e7cf7511fcf7ac85196f8718facb65e90b8f631 100644 (file)
@@ -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=""}
 
index 950988fccdf28465e4448117285d15889dce140b..1fd3f926ef21f9e3216fbea67b44991b66f2af28 100644 (file)
@@ -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 (file)
index 0000000..743f2bd
--- /dev/null
@@ -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
index eedd99439b2d96a63a1e2d6a67b0a2748805cdf1..90c73e0188f5844fabb22ff1d19e3c4f776815a6 100644 (file)
@@ -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 $<
index 9e97b67cd57c0976849f330786a100fa3c85a41f..8290803ae6b05c183da2a78b163574a8606cbc00 100644 (file)
@@ -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);
+}
index 2a580198a16d9d9d6127f33fde4659d74fe3d1c1..6f51293685ffeab4d2023c6160b0d2f830327b0c 100644 (file)
@@ -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);
+}
index 3101b2245a4d6fa4c6eb37e3942cb7bd43b49597..de02e5057ab8ff834c06d78489fbcd7e0c306d24 100644 (file)
@@ -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);
+}
index e885b13813de4581ca99097f5670951b8020fda0..40f684f269df4020a5c2ff9a733af093582b38f0 100644 (file)
@@ -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);
+}
index 54664e12c9dce14a1813e1fed6214d5b88d923e7..c9c3b600f4d2bb7f091ce82d056b0072988128c4 100644 (file)
@@ -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);
+}
index 4599b01d23c5647243fb6255c95b42994611a8f9..ac6182bc3006fc2764fce3e1b7a4f0fc18a46c29 100644 (file)
@@ -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);
+}
index af8563924cc14c4d86243888b049e02f5d6d6da8..6750208402f8c5dd03f1a098b22d085f524f0624 100644 (file)
@@ -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);
+}
index 5829f504b0eaac975118a44206dd8762e89756f1..bab33e22c4a3d7d05c99a339b939aa4c480abd78 100644 (file)
@@ -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);
+}
index 7fca5fec5f247235997a0b2762c44a498faece9d..e60acbfc6f28edc237ca2c379d9cf4ce8ff2347b 100644 (file)
@@ -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);
+}
index d8d220ee913a1786bc2d871dcb2e191b3b32349c..285f06c381915104e97b55cc1124bd81307a49e8 100644 (file)
@@ -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);
+}
index 67c29b6a6486f77d353d64aa6c0bcaf1a166b7a6..dc0bf5354f778a7b461081a21815d4e2764a8b75 100644 (file)
@@ -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);
+}
index 86bb923cb9e2bc7342ccabcee9a8bccb36b71e00..0eb7fad984cc8fbc747cab75333efdcf9857012f 100644 (file)
@@ -114,4 +114,5 @@ LIBIPSET_2.0 {
 global:
   ipset_load_types;
   ipset_port_usage;
+  ipset_parse_timeout;
 } LIBIPSET_1.0;
index 2c8e04f72d4d0913f42650bb46643847cfd290ca..64c9c8483a4d32c659fcb3ff00b28f222a502c1e 100644 (file)
 #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
 }
index 64d9bbcdd5ce91dc0a4fa9556c8e0e533d703e98..4d934ba2855fec1935336c6c1d2dfe91669c0033 100644 (file)
@@ -1,2 +1,3 @@
 /libtool.m4
 /lt*.m4
+/argz.m4
index e3f65493c940c09d65eef6db62f7189b8b81c714..fcc46215fb308a6a9123f9b459cea680439f926e 100644 (file)
@@ -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