summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac4
-rw-r--r--include/xtables.h1
-rw-r--r--iptables/ip6tables-standalone.c2
-rw-r--r--iptables/iptables-restore.c14
-rw-r--r--iptables/iptables-save.c14
-rw-r--r--iptables/iptables-standalone.c2
-rw-r--r--iptables/xtables-arp-standalone.c1
-rw-r--r--iptables/xtables-eb.c1
-rw-r--r--iptables/xtables-monitor.c2
-rw-r--r--iptables/xtables-restore.c2
-rw-r--r--iptables/xtables-save.c1
-rw-r--r--iptables/xtables-standalone.c1
-rw-r--r--iptables/xtables-translate.c2
-rw-r--r--libxtables/xtables.c44
14 files changed, 82 insertions, 9 deletions
diff --git a/configure.ac b/configure.ac
index 27e90703..02f6481c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,8 +2,8 @@
AC_INIT([iptables], [1.8.4])
# See libtool.info "Libtool's versioning system"
-libxtables_vcurrent=14
-libxtables_vage=2
+libxtables_vcurrent=15
+libxtables_vage=3
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS([config.h])
diff --git a/include/xtables.h b/include/xtables.h
index 4aa084a1..5044dd08 100644
--- a/include/xtables.h
+++ b/include/xtables.h
@@ -448,6 +448,7 @@ extern struct xtables_match *xtables_matches;
extern struct xtables_target *xtables_targets;
extern void xtables_init(void);
+extern void xtables_fini(void);
extern void xtables_set_nfproto(uint8_t);
extern void *xtables_calloc(size_t, size_t);
extern void *xtables_malloc(size_t);
diff --git a/iptables/ip6tables-standalone.c b/iptables/ip6tables-standalone.c
index 35d2d9a5..105b83ba 100644
--- a/iptables/ip6tables-standalone.c
+++ b/iptables/ip6tables-standalone.c
@@ -64,6 +64,8 @@ ip6tables_main(int argc, char *argv[])
ip6tc_free(handle);
}
+ xtables_fini();
+
if (!ret) {
if (errno == EINVAL) {
fprintf(stderr, "ip6tables: %s. "
diff --git a/iptables/iptables-restore.c b/iptables/iptables-restore.c
index fea04842..cc2c2b8b 100644
--- a/iptables/iptables-restore.c
+++ b/iptables/iptables-restore.c
@@ -372,7 +372,7 @@ static const struct iptables_restore_cb ipt_restore_cb = {
int
iptables_restore_main(int argc, char *argv[])
{
- int c;
+ int c, ret;
iptables_globals.program_name = "iptables-restore";
c = xtables_init_all(&iptables_globals, NFPROTO_IPV4);
@@ -387,7 +387,10 @@ iptables_restore_main(int argc, char *argv[])
init_extensions4();
#endif
- return ip46tables_restore_main(&ipt_restore_cb, argc, argv);
+ ret = ip46tables_restore_main(&ipt_restore_cb, argc, argv);
+
+ xtables_fini();
+ return ret;
}
#endif
@@ -403,7 +406,7 @@ static const struct iptables_restore_cb ip6t_restore_cb = {
int
ip6tables_restore_main(int argc, char *argv[])
{
- int c;
+ int c, ret;
ip6tables_globals.program_name = "ip6tables-restore";
c = xtables_init_all(&ip6tables_globals, NFPROTO_IPV6);
@@ -418,6 +421,9 @@ ip6tables_restore_main(int argc, char *argv[])
init_extensions6();
#endif
- return ip46tables_restore_main(&ip6t_restore_cb, argc, argv);
+ ret = ip46tables_restore_main(&ip6t_restore_cb, argc, argv);
+
+ xtables_fini();
+ return ret;
}
#endif
diff --git a/iptables/iptables-save.c b/iptables/iptables-save.c
index c7251e35..4efd6667 100644
--- a/iptables/iptables-save.c
+++ b/iptables/iptables-save.c
@@ -218,6 +218,8 @@ struct iptables_save_cb ipt_save_cb = {
int
iptables_save_main(int argc, char *argv[])
{
+ int ret;
+
iptables_globals.program_name = "iptables-save";
if (xtables_init_all(&iptables_globals, NFPROTO_IPV4) < 0) {
fprintf(stderr, "%s/%s Failed to initialize xtables\n",
@@ -230,7 +232,10 @@ iptables_save_main(int argc, char *argv[])
init_extensions4();
#endif
- return do_iptables_save(&ipt_save_cb, argc, argv);
+ ret = do_iptables_save(&ipt_save_cb, argc, argv);
+
+ xtables_fini();
+ return ret;
}
#endif /* ENABLE_IPV4 */
@@ -259,6 +264,8 @@ struct iptables_save_cb ip6t_save_cb = {
int
ip6tables_save_main(int argc, char *argv[])
{
+ int ret;
+
ip6tables_globals.program_name = "ip6tables-save";
if (xtables_init_all(&ip6tables_globals, NFPROTO_IPV6) < 0) {
fprintf(stderr, "%s/%s Failed to initialize xtables\n",
@@ -271,6 +278,9 @@ ip6tables_save_main(int argc, char *argv[])
init_extensions6();
#endif
- return do_iptables_save(&ip6t_save_cb, argc, argv);
+ ret = do_iptables_save(&ip6t_save_cb, argc, argv);
+
+ xtables_fini();
+ return ret;
}
#endif /* ENABLE_IPV6 */
diff --git a/iptables/iptables-standalone.c b/iptables/iptables-standalone.c
index c211fb73..8c67ea4d 100644
--- a/iptables/iptables-standalone.c
+++ b/iptables/iptables-standalone.c
@@ -64,6 +64,8 @@ iptables_main(int argc, char *argv[])
iptc_free(handle);
}
+ xtables_fini();
+
if (!ret) {
if (errno == EINVAL) {
fprintf(stderr, "iptables: %s. "
diff --git a/iptables/xtables-arp-standalone.c b/iptables/xtables-arp-standalone.c
index eca7bb97..04cf7dcc 100644
--- a/iptables/xtables-arp-standalone.c
+++ b/iptables/xtables-arp-standalone.c
@@ -56,6 +56,7 @@ int xtables_arp_main(int argc, char *argv[])
ret = nft_commit(&h);
nft_fini(&h);
+ xtables_fini();
if (!ret)
fprintf(stderr, "arptables: %s\n", nft_strerror(errno));
diff --git a/iptables/xtables-eb.c b/iptables/xtables-eb.c
index 0df1345a..5764d180 100644
--- a/iptables/xtables-eb.c
+++ b/iptables/xtables-eb.c
@@ -767,6 +767,7 @@ void nft_fini_eb(struct nft_handle *h)
free(opts);
nft_fini(h);
+ xtables_fini();
}
int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
diff --git a/iptables/xtables-monitor.c b/iptables/xtables-monitor.c
index c2b31dba..57def83e 100644
--- a/iptables/xtables-monitor.c
+++ b/iptables/xtables-monitor.c
@@ -688,6 +688,8 @@ int xtables_monitor_main(int argc, char *argv[])
}
mnl_socket_close(nl);
+ xtables_fini();
+
return EXIT_SUCCESS;
}
diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c
index 0d6fd642..a3bb4f00 100644
--- a/iptables/xtables-restore.c
+++ b/iptables/xtables-restore.c
@@ -391,6 +391,7 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[])
xtables_restore_parse(&h, &p);
nft_fini(&h);
+ xtables_fini();
fclose(p.in);
return 0;
}
@@ -473,6 +474,7 @@ int xtables_arp_restore_main(int argc, char *argv[])
nft_init_arp(&h, "arptables-restore");
xtables_restore_parse(&h, &p);
nft_fini(&h);
+ xtables_fini();
return 0;
}
diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c
index 0ce66e5d..bb3d8cd3 100644
--- a/iptables/xtables-save.c
+++ b/iptables/xtables-save.c
@@ -244,6 +244,7 @@ xtables_save_main(int family, int argc, char *argv[],
ret = do_output(&h, tablename, &d);
nft_fini(&h);
+ xtables_fini();
if (dump)
exit(0);
diff --git a/iptables/xtables-standalone.c b/iptables/xtables-standalone.c
index 022d5dd4..dd6fb791 100644
--- a/iptables/xtables-standalone.c
+++ b/iptables/xtables-standalone.c
@@ -72,6 +72,7 @@ xtables_main(int family, const char *progname, int argc, char *argv[])
ret = nft_commit(&h);
nft_fini(&h);
+ xtables_fini();
if (!ret) {
if (errno == EINVAL) {
diff --git a/iptables/xtables-translate.c b/iptables/xtables-translate.c
index 76ad7eb6..5aa42496 100644
--- a/iptables/xtables-translate.c
+++ b/iptables/xtables-translate.c
@@ -509,6 +509,7 @@ static int xtables_xlate_main(int family, const char *progname, int argc,
fprintf(stderr, "Translation not implemented\n");
nft_fini(&h);
+ xtables_fini();
exit(!ret);
}
@@ -563,6 +564,7 @@ static int xtables_restore_xlate_main(int family, const char *progname,
printf("# Completed on %s", ctime(&now));
nft_fini(&h);
+ xtables_fini();
fclose(p.in);
exit(0);
}
diff --git a/libxtables/xtables.c b/libxtables/xtables.c
index 777c2b08..7fe42580 100644
--- a/libxtables/xtables.c
+++ b/libxtables/xtables.c
@@ -206,6 +206,38 @@ struct xtables_target *xtables_targets;
static bool xtables_fully_register_pending_match(struct xtables_match *me);
static bool xtables_fully_register_pending_target(struct xtables_target *me);
+/* registry for loaded shared objects to close later */
+struct dlreg {
+ struct dlreg *next;
+ void *handle;
+};
+static struct dlreg *dlreg = NULL;
+
+static int dlreg_add(void *handle)
+{
+ struct dlreg *new = malloc(sizeof(*new));
+
+ if (!new)
+ return -1;
+
+ new->handle = handle;
+ new->next = dlreg;
+ dlreg = new;
+ return 0;
+}
+
+static void dlreg_free(void)
+{
+ struct dlreg *next;
+
+ while (dlreg) {
+ next = dlreg->next;
+ dlclose(dlreg->handle);
+ free(dlreg);
+ dlreg = next;
+ }
+}
+
void xtables_init(void)
{
xtables_libdir = getenv("XTABLES_LIBDIR");
@@ -233,6 +265,11 @@ void xtables_init(void)
xtables_libdir = XTABLES_LIBDIR;
}
+void xtables_fini(void)
+{
+ dlreg_free();
+}
+
void xtables_set_nfproto(uint8_t nfproto)
{
switch (nfproto) {
@@ -567,6 +604,8 @@ static void *load_extension(const char *search_path, const char *af_prefix,
next = dir + strlen(dir);
for (prefix = all_prefixes; *prefix != NULL; ++prefix) {
+ void *handle;
+
snprintf(path, sizeof(path), "%.*s/%s%s.so",
(unsigned int)(next - dir), dir,
*prefix, name);
@@ -578,11 +617,14 @@ static void *load_extension(const char *search_path, const char *af_prefix,
strerror(errno));
return NULL;
}
- if (dlopen(path, RTLD_NOW) == NULL) {
+ handle = dlopen(path, RTLD_NOW);
+ if (handle == NULL) {
fprintf(stderr, "%s: %s\n", path, dlerror());
break;
}
+ dlreg_add(handle);
+
if (is_target)
ptr = xtables_find_target(name, XTF_DONT_LOAD);
else