summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Kelley <simon@thekelleys.org.uk>2021-09-27 21:31:20 +0100
committerSimon Kelley <simon@thekelleys.org.uk>2021-09-27 21:49:28 +0100
commit47aefca5e405b4b6627ef952fdc42e61b1baa770 (patch)
tree853a36100c922de403e543fa779bb1ce58c7ab2e
parent981fb037102306a4ca683f14c8469db4d5e27233 (diff)
downloaddnsmasq-47aefca5e405b4b6627ef952fdc42e61b1baa770.tar.gz
Add --nftset option, like --ipset but for the newer nftables.v2.87test2
Thanks to Chen Zhenge for the original patch, which I've reworked. Any bugs down to SRK.
-rw-r--r--CHANGELOG6
-rw-r--r--Makefile7
-rw-r--r--dnsmasq.conf.example10
-rw-r--r--man/dnsmasq.89
-rw-r--r--src/cache.c2
-rw-r--r--src/config.h10
-rw-r--r--src/dnsmasq.c10
-rw-r--r--src/dnsmasq.h12
-rw-r--r--src/forward.c49
-rw-r--r--src/nftset.c94
-rw-r--r--src/option.c36
-rw-r--r--src/rfc1035.c26
12 files changed, 226 insertions, 45 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 8652dd8..6896f39 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -5,6 +5,9 @@ version 2.87
Replace --address=/#/..... functionality which got
missed in the 2.86 domain search rewrite.
+ Add --nftset option, like --ipset but for the newer nftables.
+ Thanks to Chen Zhenge for the patch.
+
version 2.86
Handle DHCPREBIND requests in the DHCPv6 server code.
@@ -100,6 +103,9 @@ version 2.86
of filename). Thanks to Ed Wildgoose for the initial patch
and motivation for this.
+ Allow adding IP address to nftables set in addition to
+ ipset.
+
version 2.85
Fix problem with DNS retries in 2.83/2.84.
diff --git a/Makefile b/Makefile
index 0cd592e..e471a4d 100644
--- a/Makefile
+++ b/Makefile
@@ -70,6 +70,7 @@ nettle_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC $(PKG_CO
HAVE_NETTLEHASH $(PKG_CONFIG) --libs nettle`
gmp_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC NO_GMP --copy -lgmp`
sunos_libs = `if uname | grep SunOS >/dev/null 2>&1; then echo -lsocket -lnsl -lposix4; fi`
+nft_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_NFTSET $(PKG_CONFIG) --libs libnftables`
version = -DVERSION='\"`$(top)/bld/get-version $(top)`\"'
sum?=$(shell $(CC) -DDNSMASQ_COMPILE_OPTS $(COPTS) -E $(top)/$(SRC)/dnsmasq.h | ( md5sum 2>/dev/null || md5 ) | cut -f 1 -d ' ')
@@ -82,7 +83,7 @@ objs = cache.o rfc1035.o util.o option.o forward.o network.o \
dhcp-common.o outpacket.o radv.o slaac.o auth.o ipset.o pattern.o \
domain.o dnssec.o blockdata.o tables.o loop.o inotify.o \
poll.o rrfilter.o edns0.o arp.o crypto.o dump.o ubus.o \
- metrics.o hash-questions.o domain-match.o
+ metrics.o hash-questions.o domain-match.o nftset.o
hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \
dns-protocol.h radv-protocol.h ip6addr.h metrics.h
@@ -91,7 +92,7 @@ all : $(BUILDDIR)
@cd $(BUILDDIR) && $(MAKE) \
top="$(top)" \
build_cflags="$(version) $(dbus_cflags) $(idn2_cflags) $(idn_cflags) $(ct_cflags) $(lua_cflags) $(nettle_cflags)" \
- build_libs="$(dbus_libs) $(idn2_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs) $(ubus_libs)" \
+ build_libs="$(dbus_libs) $(idn2_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs) $(ubus_libs) $(nft_libs)" \
-f $(top)/Makefile dnsmasq
mostly_clean :
@@ -116,7 +117,7 @@ all-i18n : $(BUILDDIR)
top="$(top)" \
i18n=-DLOCALEDIR=\'\"$(LOCALEDIR)\"\' \
build_cflags="$(version) $(dbus_cflags) $(idn2_cflags) $(idn_cflags) $(ct_cflags) $(lua_cflags) $(nettle_cflags)" \
- build_libs="$(dbus_libs) $(idn2_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs) $(ubus_libs)" \
+ build_libs="$(dbus_libs) $(idn2_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs) $(ubus_libs) $(nft_libs)" \
-f $(top)/Makefile dnsmasq
for f in `cd $(PO); echo *.po`; do \
cd $(top) && cd $(BUILDDIR) && $(MAKE) top="$(top)" -f $(top)/Makefile $${f%.po}.mo; \
diff --git a/dnsmasq.conf.example b/dnsmasq.conf.example
index bf19424..2047630 100644
--- a/dnsmasq.conf.example
+++ b/dnsmasq.conf.example
@@ -85,6 +85,16 @@
# subdomains to the vpn and search ipsets:
#ipset=/yahoo.com/google.com/vpn,search
+# Add the IPs of all queries to yahoo.com, google.com, and their
+# subdomains to netfilters sets, which is equivalent to
+# 'nft add element ip test vpn { ... }; nft add element ip test search { ... }'
+#nftset=/yahoo.com/google.com/ip#test#vpn,ip#test#search
+
+# Use netfilters sets for both IPv4 and IPv6:
+# This adds all addresses in *.yahoo.com to vpn4 and vpn6 for IPv4 and IPv6 addresses.
+#nftset=/yahoo.com/4#ip#test#vpn4
+#nftset=/yahoo.com/6#ip#test#vpn6
+
# You can control how dnsmasq talks to a server: this forces
# queries to 10.1.2.3 to be routed via eth1
# server=10.1.2.3@eth1
diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
index a71610c..1d4993c 100644
--- a/man/dnsmasq.8
+++ b/man/dnsmasq.8
@@ -550,6 +550,15 @@ These IP sets must already exist. See
.BR ipset (8)
for more details.
.TP
+.B --nftset=/<domain>[/<domain>...]/[(6|4)#[<family>#]<table>#<set>[,[(6|4)#[<family>#]<table>#<set>]...]
+Similar to the \fB--ipset\fP option, but accepts one or more nftables
+sets to add IP addresses into.
+These sets must already exist. See
+.BR nft (8)
+for more details. The family, table and set are passed directly to the nft. If the spec starts with 4# or 6# then
+only A or AAAA records respectively are added to the set. Since an nftset can hold only IPv4 or IPv6 addresses, this
+avoids errors being logged for addresses of the wrong type.
+.TP
.B --connmark-allowlist-enable[=<mask>]
Enables filtering of incoming DNS queries with associated Linux connection track marks
according to individual allowlists configured via a series of \fB--connmark-allowlist\fP
diff --git a/src/cache.c b/src/cache.c
index 568cbec..e1d17c4 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -2060,7 +2060,7 @@ void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg,
}
else if (flags & F_IPSET)
{
- source = "ipset add";
+ source = type ? "ipset add" : "nftset add";
dest = name;
name = arg;
verb = daemon->addrbuff;
diff --git a/src/config.h b/src/config.h
index 30e23d8..2bb6683 100644
--- a/src/config.h
+++ b/src/config.h
@@ -115,6 +115,10 @@ HAVE_IPSET
define this to include the ability to selectively add resolved ip addresses
to given ipsets.
+HAVE_NFTSET
+ define this to include the ability to selectively add resolved ip addresses
+ to given nftables sets.
+
HAVE_AUTH
define this to include the facility to act as an authoritative DNS
server for one or more zones.
@@ -192,7 +196,7 @@ RESOLVFILE
/* #define HAVE_CONNTRACK */
/* #define HAVE_CRYPTOHASH */
/* #define HAVE_DNSSEC */
-
+/* #define HAVE_NFTSET */
/* Default locations for important system files. */
@@ -420,6 +424,10 @@ static char *compile_opts =
"no-"
#endif
"ipset "
+#ifndef HAVE_NFTSET
+"no-"
+#endif
+"nftset "
#ifndef HAVE_AUTH
"no-"
#endif
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
index 3e1bfe8..c7fa024 100644
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -346,6 +346,16 @@ int main (int argc, char **argv)
}
#endif
+#ifdef HAVE_NFTSET
+ if (daemon->nftsets)
+ {
+ nftset_init();
+# ifdef HAVE_LINUX_NETWORK
+ need_cap_net_admin = 1;
+# endif
+ }
+#endif
+
#if defined(HAVE_LINUX_NETWORK)
netlink_warn = netlink_init();
#elif defined(HAVE_BSD_NETWORK)
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 1a66e9b..c8a918a 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -1114,7 +1114,7 @@ extern struct daemon {
struct rebind_domain *no_rebind;
int server_has_wildcard;
int serverarraysz, serverarrayhwm;
- struct ipsets *ipsets;
+ struct ipsets *ipsets, *nftsets;
u32 allowlist_mask;
struct allowlist *allowlists;
int log_fac; /* log facility */
@@ -1303,8 +1303,8 @@ unsigned int extract_request(struct dns_header *header, size_t qlen,
char *name, unsigned short *typep);
void setup_reply(struct dns_header *header, unsigned int flags, int ede);
int extract_addresses(struct dns_header *header, size_t qlen, char *name,
- time_t now, char **ipsets, int is_sign, int check_rebind,
- int no_cache_dnssec, int secure, int *doctored);
+ time_t now, struct ipsets *ipsets, struct ipsets *nftsets, int is_sign,
+ int check_rebind, int no_cache_dnssec, int secure, int *doctored);
#if defined(HAVE_CONNTRACK) && defined(HAVE_UBUS)
void report_addresses(struct dns_header *header, size_t len, u32 mark);
#endif
@@ -1588,6 +1588,12 @@ void ipset_init(void);
int add_to_ipset(const char *setname, const union all_addr *ipaddr, int flags, int remove);
#endif
+/* nftset.c */
+#ifdef HAVE_NFTSET
+void nftset_init(void);
+int add_to_nftset(const char *setpath, const union all_addr *ipaddr, int flags, int remove);
+#endif
+
/* pattern.c */
#ifdef HAVE_CONNTRACK
int is_valid_dns_name(const char *value);
diff --git a/src/forward.c b/src/forward.c
index e74e396..b921168 100644
--- a/src/forward.c
+++ b/src/forward.c
@@ -556,12 +556,33 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
return 0;
}
+static struct ipsets *domain_find_sets(struct ipsets *setlist, const char *domain) {
+ /* Similar algorithm to search_servers. */
+ struct ipsets *ipset_pos, *ret = NULL;
+ unsigned int namelen = strlen(domain);
+ unsigned int matchlen = 0;
+ for (ipset_pos = setlist; ipset_pos; ipset_pos = ipset_pos->next)
+ {
+ unsigned int domainlen = strlen(ipset_pos->domain);
+ const char *matchstart = domain + namelen - domainlen;
+ if (namelen >= domainlen && hostname_isequal(matchstart, ipset_pos->domain) &&
+ (domainlen == 0 || namelen == domainlen || *(matchstart - 1) == '.' ) &&
+ domainlen >= matchlen)
+ {
+ matchlen = domainlen;
+ ret = ipset_pos;
+ }
+ }
+
+ return ret;
+}
+
static size_t process_reply(struct dns_header *header, time_t now, struct server *server, size_t n, int check_rebind,
int no_cache, int cache_secure, int bogusanswer, int ad_reqd, int do_bit, int added_pheader,
int check_subnet, union mysockaddr *query_source, unsigned char *limit, int ede)
{
unsigned char *pheader, *sizep;
- char **sets = 0;
+ struct ipsets *ipsets = NULL, *nftsets = NULL;
int munged = 0, is_sign;
unsigned int rcode = RCODE(header);
size_t plen;
@@ -572,24 +593,12 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
#ifdef HAVE_IPSET
if (daemon->ipsets && extract_request(header, n, daemon->namebuff, NULL))
- {
- /* Similar algorithm to search_servers. */
- struct ipsets *ipset_pos;
- unsigned int namelen = strlen(daemon->namebuff);
- unsigned int matchlen = 0;
- for (ipset_pos = daemon->ipsets; ipset_pos; ipset_pos = ipset_pos->next)
- {
- unsigned int domainlen = strlen(ipset_pos->domain);
- char *matchstart = daemon->namebuff + namelen - domainlen;
- if (namelen >= domainlen && hostname_isequal(matchstart, ipset_pos->domain) &&
- (domainlen == 0 || namelen == domainlen || *(matchstart - 1) == '.' ) &&
- domainlen >= matchlen)
- {
- matchlen = domainlen;
- sets = ipset_pos->sets;
- }
- }
- }
+ ipsets = domain_find_sets(daemon->ipsets, daemon->namebuff);
+#endif
+
+#ifdef HAVE_NFTSET
+ if (daemon->nftsets && extract_request(header, n, daemon->namebuff, NULL))
+ nftsets = domain_find_sets(daemon->nftsets, daemon->namebuff);
#endif
if ((pheader = find_pseudoheader(header, n, &plen, &sizep, &is_sign, NULL)))
@@ -698,7 +707,7 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
}
}
- if (extract_addresses(header, n, daemon->namebuff, now, sets, is_sign, check_rebind, no_cache, cache_secure, &doctored))
+ if (extract_addresses(header, n, daemon->namebuff, now, ipsets, nftsets, is_sign, check_rebind, no_cache, cache_secure, &doctored))
{
my_syslog(LOG_WARNING, _("possible DNS-rebind attack detected: %s"), daemon->namebuff);
munged = 1;
diff --git a/src/nftset.c b/src/nftset.c
new file mode 100644
index 0000000..5373a1c
--- /dev/null
+++ b/src/nftset.c
@@ -0,0 +1,94 @@
+/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 dated June, 1991, or
+ (at your option) version 3 dated 29 June, 2007.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include "dnsmasq.h"
+
+#if defined (HAVE_NFTSET) && defined (HAVE_LINUX_NETWORK)
+
+#include <nftables/libnftables.h>
+
+#include <string.h>
+#include <arpa/inet.h>
+
+static struct nft_ctx *ctx = NULL;
+static const char *cmd_add = "add element %s { %s }";
+static const char *cmd_del = "delete element %s { %s }";
+
+void nftset_init()
+{
+ ctx = nft_ctx_new(NFT_CTX_DEFAULT);
+ if (ctx == NULL)
+ die(_("failed to create nftset context"), NULL, EC_MISC);
+
+ /* disable libnftables output */
+ nft_ctx_buffer_error(ctx);
+}
+
+int add_to_nftset(const char *setname, const union all_addr *ipaddr, int flags, int remove)
+{
+ const char *cmd = remove ? cmd_del : cmd_add;
+ int ret, af = (flags & F_IPV4) ? AF_INET : AF_INET6;
+ size_t new_sz;
+ char *new, *err, *nl;
+ static char *cmd_buf = NULL;
+ static size_t cmd_buf_sz = 0;
+
+ inet_ntop(af, ipaddr, daemon->addrbuff, ADDRSTRLEN);
+
+ if (setname[1] == ' ' && (setname[0] == '4' || setname[0] == '6'))
+ {
+ if (setname[0] == '4' && !(flags & F_IPV4))
+ return -1;
+
+ if (setname[0] == '6' && !(flags & F_IPV6))
+ return -1;
+
+ setname += 2;
+ }
+
+ if (cmd_buf_sz == 0)
+ new_sz = 150; /* initial allocation */
+ else
+ new_sz = snprintf(cmd_buf, cmd_buf_sz, cmd, setname, daemon->addrbuff);
+
+ if (new_sz > cmd_buf_sz)
+ {
+ if (!(new = whine_malloc(new_sz + 10)))
+ return 0;
+
+ if (cmd_buf)
+ free(cmd_buf);
+ cmd_buf = new;
+ cmd_buf_sz = new_sz + 10;
+ snprintf(cmd_buf, cmd_buf_sz, cmd, setname, daemon->addrbuff);
+ }
+
+ ret = nft_run_cmd_from_buffer(ctx, cmd_buf);
+ err = (char *)nft_ctx_get_error_buffer(ctx);
+
+ if (ret != 0)
+ {
+ /* Log only first line of error return. */
+ if ((nl = strchr(err, '\n')))
+ *nl = 0;
+ my_syslog(LOG_ERR, "nftset %s %s", setname, err);
+ }
+
+ return ret;
+}
+
+#endif
diff --git a/src/option.c b/src/option.c
index 5402170..4e533be 100644
--- a/src/option.c
+++ b/src/option.c
@@ -174,6 +174,7 @@ struct myoption {
#define LOPT_CMARK_ALST_EN 365
#define LOPT_CMARK_ALST 366
#define LOPT_QUIET_TFTP 367
+#define LOPT_NFTSET 368
#ifdef HAVE_GETOPT_LONG
static const struct option opts[] =
@@ -327,6 +328,7 @@ static const struct myoption opts[] =
{ "auth-sec-servers", 1, 0, LOPT_AUTHSFS },
{ "auth-peer", 1, 0, LOPT_AUTHPEER },
{ "ipset", 1, 0, LOPT_IPSET },
+ { "nftset", 1, 0, LOPT_NFTSET },
{ "connmark-allowlist-enable", 2, 0, LOPT_CMARK_ALST_EN },
{ "connmark-allowlist", 1, 0, LOPT_CMARK_ALST },
{ "synth-domain", 1, 0, LOPT_SYNTH },
@@ -514,6 +516,7 @@ static struct {
{ LOPT_AUTHSFS, ARG_DUP, "<NS>[,<NS>...]", gettext_noop("Secondary authoritative nameservers for forward domains"), NULL },
{ LOPT_AUTHPEER, ARG_DUP, "<ipaddr>[,<ipaddr>...]", gettext_noop("Peers which are allowed to do zone transfer"), NULL },
{ LOPT_IPSET, ARG_DUP, "/<domain>[/<domain>...]/<ipset>...", gettext_noop("Specify ipsets to which matching domains should be added"), NULL },
+ { LOPT_NFTSET, ARG_DUP, "/<domain>[/<domain>...]/<nftset>...", gettext_noop("Specify nftables sets to which matching domains should be added"), NULL },
{ LOPT_CMARK_ALST_EN, ARG_ONE, "[=<mask>]", gettext_noop("Enable filtering of DNS queries with connection-track marks."), NULL },
{ LOPT_CMARK_ALST, ARG_DUP, "<connmark>[/<mask>][,<pattern>[/<pattern>...]]", gettext_noop("Set allowed DNS patterns for a connection-track mark."), NULL },
{ LOPT_SYNTH, ARG_DUP, "<domain>,<range>,[<prefix>]", gettext_noop("Specify a domain and address range for synthesised names"), NULL },
@@ -2850,13 +2853,27 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
}
case LOPT_IPSET: /* --ipset */
+ case LOPT_NFTSET: /* --nftset */
#ifndef HAVE_IPSET
- ret_err(_("recompile with HAVE_IPSET defined to enable ipset directives"));
- break;
-#else
+ if (option == LOPT_IPSET)
+ {
+ ret_err(_("recompile with HAVE_IPSET defined to enable ipset directives"));
+ break;
+ }
+#endif
+#ifndef HAVE_NFTSET
+ if (option == LOPT_NFTSET)
+ {
+ ret_err(_("recompile with HAVE_NFTSET defined to enable nftset directives"));
+ break;
+ }
+#endif
+
{
struct ipsets ipsets_head;
struct ipsets *ipsets = &ipsets_head;
+ struct ipsets **daemon_sets =
+ (option == LOPT_IPSET) ? &daemon->ipsets : &daemon->nftsets;
int size;
char *end;
char **sets, **sets_pos;
@@ -2901,19 +2918,24 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
sets = sets_pos = opt_malloc(sizeof(char *) * size);
do {
+ char *p;
end = split(arg);
- *sets_pos++ = opt_string_alloc(arg);
+ *sets_pos = opt_string_alloc(arg);
+ /* Use '#' to delimit table and set */
+ if (option == LOPT_NFTSET)
+ while ((p = strchr(*sets_pos, '#')))
+ *p = ' ';
+ sets_pos++;
arg = end;
} while (end);
*sets_pos = 0;
for (ipsets = &ipsets_head; ipsets->next; ipsets = ipsets->next)
ipsets->next->sets = sets;
- ipsets->next = daemon->ipsets;
- daemon->ipsets = ipsets_head.next;
+ ipsets->next = *daemon_sets;
+ *daemon_sets = ipsets_head.next;
break;
}
-#endif
case LOPT_CMARK_ALST_EN: /* --connmark-allowlist-enable */
#ifndef HAVE_CONNTRACK
diff --git a/src/rfc1035.c b/src/rfc1035.c
index 3a7f3a5..124a4f2 100644
--- a/src/rfc1035.c
+++ b/src/rfc1035.c
@@ -540,8 +540,8 @@ static int print_txt(struct dns_header *header, const size_t qlen, char *name,
expired and cleaned out that way.
Return 1 if we reject an address because it look like part of dns-rebinding attack. */
int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t now,
- char **ipsets, int is_sign, int check_rebind, int no_cache_dnssec,
- int secure, int *doctored)
+ struct ipsets *ipsets, struct ipsets *nftsets, int is_sign, int check_rebind,
+ int no_cache_dnssec, int secure, int *doctored)
{
unsigned char *p, *p1, *endrr, *namep;
int j, qtype, qclass, aqtype, aqclass, ardlen, res, searched_soa = 0;
@@ -552,6 +552,11 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
#else
(void)ipsets; /* unused */
#endif
+#ifdef HAVE_NFTSET
+ char **nftsets_cur;
+#else
+ (void)nftsets; /* unused */
+#endif
int found = 0, cname_count = CNAME_CHAIN;
struct crec *cpp = NULL;
int flags = RCODE(header) == NXDOMAIN ? F_NXDOMAIN : 0;
@@ -843,14 +848,15 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
#ifdef HAVE_IPSET
if (ipsets && (flags & (F_IPV4 | F_IPV6)))
- {
- ipsets_cur = ipsets;
- while (*ipsets_cur)
- {
- log_query((flags & (F_IPV4 | F_IPV6)) | F_IPSET, name, &addr, *ipsets_cur, 0);
- add_to_ipset(*ipsets_cur++, &addr, flags, 0);
- }
- }
+ for (ipsets_cur = ipsets->sets; *ipsets_cur; ipsets_cur++)
+ if (add_to_ipset(*ipsets_cur, &addr, flags, 0) == 0)
+ log_query((flags & (F_IPV4 | F_IPV6)) | F_IPSET, ipsets->domain, &addr, *ipsets_cur, 1);
+#endif
+#ifdef HAVE_NFTSET
+ if (nftsets && (flags & (F_IPV4 | F_IPV6)))
+ for (nftsets_cur = nftsets->sets; *nftsets_cur; nftsets_cur++)
+ if (add_to_nftset(*nftsets_cur, &addr, flags, 0) == 0)
+ log_query((flags & (F_IPV4 | F_IPV6)) | F_IPSET, nftsets->domain, &addr, *nftsets_cur, 0);
#endif
}