Skip to content

Commit 391ef31

Browse files
yujincheng08Chen Zhenge
and
Chen Zhenge
authored
Simple support for nftables (#1117)
* Simple support for nftables Co-authored-by: Chen Zhenge <[email protected]>
1 parent 51e1ba6 commit 391ef31

File tree

12 files changed

+451
-118
lines changed

12 files changed

+451
-118
lines changed

Diff for: .clang-format

100755100644
File mode changed.

Diff for: ReadMe.md

+6-4
Original file line numberDiff line numberDiff line change
@@ -515,8 +515,8 @@ entware|ipkg update</br>ipkg install smartdns|软件源路径:https://bin.entw
515515
| 键名 | 功能说明 | 默认值 | 可用值/要求 | 举例 |
516516
| :--- | :--- | :--- | :--- | :--- |
517517
| server-name | DNS 服务器名称 | 操作系统主机名 / smartdns | 符合主机名规格的字符串 | server-name smartdns |
518-
| bind | DNS 监听端口号 | [::]:53 | 可绑定多个端口。<br>IP:PORT: 服务器 IP:端口号<br>[-group]: 请求时使用的 DNS 服务器组<br>[-no-rule-addr]:跳过 address 规则<br>[-no-rule-nameserver]:跳过 Nameserver 规则<br>[-no-rule-ipset]:跳过 ipset 规则<br>[-no-rule-soa]:跳过 SOA(#) 规则<br>[-no-dualstack-selection]:停用双栈测速<br>[-no-speed-check]:停用测速<br>[-no-cache]:停止缓存 | bind :53 |
519-
| bind-tcp | DNS TCP 监听端口号 | [::]:53 | 可绑定多个端口。<br>IP:PORT: 服务器 IP:端口号<br>[-group]: 请求时使用的 DNS 服务器组<br>[-no-rule-addr]:跳过 address 规则<br>[-no-rule-nameserver]:跳过 nameserver 规则<br>[-no-rule-ipset]:跳过 ipset 规则。<br>[-no-rule-soa]:跳过 SOA(#) 规则<br>[-no-dualstack-selection]:停用双栈测速<br>[-no-speed-check]:停用测速<br>[-no-cache]:停止缓存 | bind-tcp :53 |
518+
| bind | DNS 监听端口号 | [::]:53 | 可绑定多个端口。<br>IP:PORT: 服务器 IP:端口号<br>[-group]: 请求时使用的 DNS 服务器组<br>[-no-rule-addr]:跳过 address 规则<br>[-no-rule-nameserver]:跳过 Nameserver 规则<br>[-no-rule-ipset]:跳过 ipset 和 nftset 规则<br>[-no-rule-soa]:跳过 SOA(#) 规则<br>[-no-dualstack-selection]:停用双栈测速<br>[-no-speed-check]:停用测速<br>[-no-cache]:停止缓存 | bind :53 |
519+
| bind-tcp | DNS TCP 监听端口号 | [::]:53 | 可绑定多个端口。<br>IP:PORT: 服务器 IP:端口号<br>[-group]: 请求时使用的 DNS 服务器组<br>[-no-rule-addr]:跳过 address 规则<br>[-no-rule-nameserver]:跳过 nameserver 规则<br>[-no-rule-ipset]:跳过 ipset 和 nftset 规则。<br>[-no-rule-soa]:跳过 SOA(#) 规则<br>[-no-dualstack-selection]:停用双栈测速<br>[-no-speed-check]:停用测速<br>[-no-cache]:停止缓存 | bind-tcp :53 |
520520
| cache-size | 域名结果缓存个数 | 512 | 大于等于 0 的数字 | cache-size 512 |
521521
| cache-persist | 是否持久化缓存 | 自动。<br>当 cache-file 所在的位置有超过 128 MB 的可用空间时启用,否则禁用。 | [yes\|no] | cache-persist yes |
522522
| cache-file | 缓存持久化文件路径 | /tmp/smartdns.cache | 合法路径字符串 | cache-file /tmp/smartdns.cache |
@@ -546,8 +546,10 @@ entware|ipkg update</br>ipkg install smartdns|软件源路径:https://bin.entw
546546
| nameserver | 指定域名使用 server 组解析 || nameserver /domain/[group\|-], group 为组名,- 表示忽略此规则,配套 server 中的 -group 参数使用 | nameserver /www.example.com/office |
547547
| ipset | 域名 ipset || ipset /domain/[ipset\|-\|#[4\|6]:[ipset\|-][,#[4\|6]:[ipset\|-]]],-表示忽略 | ipset /www.example.com/#4:dns4,#6:- |
548548
| ipset-timeout | 设置 ipset 超时功能启用 | 自动 | [yes] | ipset-timeout yes |
549-
| domain-rules | 设置域名规则 || domain-rules /domain/ [-rules...]<br>[-c\|-speed-check-mode]:测速模式,参考 speed-check-mode 配置<br>[-a\|-address]:参考 address 配置<br>[-n\|-nameserver]:参考 nameserver 配置<br>[-p\|-ipset]:参考ipset配置<br>[-d\|-dualstack-ip-selection]:参考 dualstack-ip-selection | domain-rules /www.example.com/ -speed-check-mode none |
550-
| domain-set | 设置域名集合 || domain-set [options...]<br>[-n\|-name]:域名集合名称 <br>[-t\|-type]:域名集合类型,当前仅支持list,格式为域名列表,一行一个域名。<br>[-f\|-file]:域名集合文件路径。<br> 选项需要配合address, nameserver, ipset等需要指定域名的地方使用,使用方式为 /domain-set:[name]/| domain-set -name set -type list -file /path/to/list <br> address /domain-set:set/1.2.4.8 |
549+
| nftset | 域名 nftset || nftset /domain/#[4\|6]:[family#nftable#nftset\|-][,#[4\|6]:[family#nftable#nftset\|-]]],-表示忽略;ipv4 地址的 family 只支持 inet 和 ip;ipv6 地址的 family 只支持 inet 和 ip6;由于 nft 限制,两种地址只能分开存放于两个 set 中。| nftset /www.example.com/#4:inet#mytab#dns4,#6:- |
550+
| nftset-timeout | 设置 nftset 超时功能启用 | 自动 | [yes] | nftset-timeout yes |
551+
| domain-rules | 设置域名规则 || domain-rules /domain/ [-rules...]<br>[-c\|-speed-check-mode]:测速模式,参考 speed-check-mode 配置<br>[-a\|-address]:参考 address 配置<br>[-n\|-nameserver]:参考 nameserver 配置<br>[-p\|-ipset]:参考ipset配置<br>[-s\|-nftset]:参考nftset配置<br>[-d\|-dualstack-ip-selection]:参考 dualstack-ip-selection | domain-rules /www.example.com/ -speed-check-mode none |
552+
| domain-set | 设置域名集合 || domain-set [options...]<br>[-n\|-name]:域名集合名称 <br>[-t\|-type]:域名集合类型,当前仅支持list,格式为域名列表,一行一个域名。<br>[-f\|-file]:域名集合文件路径。<br> 选项需要配合address, nameserver, ipset, nftset等需要指定域名的地方使用,使用方式为 /domain-set:[name]/| domain-set -name set -type list -file /path/to/list <br> address /domain-set:set/1.2.4.8 |
551553
| bogus-nxdomain | 假冒 IP 地址过滤 || [ip/subnet],可重复 | bogus-nxdomain 1.2.3.4/16 |
552554
| ignore-ip | 忽略 IP 地址 || [ip/subnet],可重复 | ignore-ip 1.2.3.4/16 |
553555
| whitelist-ip | 白名单 IP 地址 || [ip/subnet],可重复 | whitelist-ip 1.2.3.4/16 |

Diff for: ReadMe_en.md

100755100644
+6-4
Original file line numberDiff line numberDiff line change
@@ -474,8 +474,8 @@ Note: Merlin firmware is derived from ASUS firmware and can theoretically be use
474474
|parameter|Parameter function|Default value|Value type|Example|
475475
|--|--|--|--|--|
476476
|server-name|DNS name|host name/smartdns|any string like hosname|server-name smartdns
477-
|bind|DNS listening port number|[::]:53|Support binding multiple ports<br>`IP:PORT`: server IP, port number. <br>`[-group]`: The DNS server group used when requesting. <br>`[-no-rule-addr]`: Skip the address rule. <br>`[-no-rule-nameserver]`: Skip the Nameserver rule. <br>`[-no-rule-ipset]`: Skip the Ipset rule. <br>`[-no-rule-soa]`: Skip address SOA(#) rules.<br>`[-no-dualstack-selection]`: Disable dualstack ip selection.<br>`[-no-speed-check]`: Disable speed measurement. <br>`[-no-cache]`: stop caching |bind :53
478-
|bind-tcp|TCP mode DNS listening port number|[::]:53|Support binding multiple ports<br>`IP:PORT`: server IP, port number. <br>`[-group]`: The DNS server group used when requesting. <br>`[-no-rule-addr]`: Skip the address rule. <br>`[-no-rule-nameserver]`: Skip the Nameserver rule. <br>`[-no-rule-ipset]`: Skip the Ipset rule. <br>`[-no-rule-soa]`: Skip address SOA(#) rules.<br>`[-no-dualstack-selection]`: Disable dualstack ip selection.<br>`[-no-speed-check]`: Disable speed measurement. <br>`[-no-cache]`: stop caching |bind-tcp :53
477+
|bind|DNS listening port number|[::]:53|Support binding multiple ports<br>`IP:PORT`: server IP, port number. <br>`[-group]`: The DNS server group used when requesting. <br>`[-no-rule-addr]`: Skip the address rule. <br>`[-no-rule-nameserver]`: Skip the Nameserver rule. <br>`[-no-rule-ipset]`: Skip the Ipset or nftset rules. <br>`[-no-rule-soa]`: Skip address SOA(#) rules.<br>`[-no-dualstack-selection]`: Disable dualstack ip selection.<br>`[-no-speed-check]`: Disable speed measurement. <br>`[-no-cache]`: stop caching |bind :53
478+
|bind-tcp|TCP mode DNS listening port number|[::]:53|Support binding multiple ports<br>`IP:PORT`: server IP, port number. <br>`[-group]`: The DNS server group used when requesting. <br>`[-no-rule-addr]`: Skip the address rule. <br>`[-no-rule-nameserver]`: Skip the Nameserver rule. <br>`[-no-rule-ipset]`: Skip the Ipset or nftset rules. <br>`[-no-rule-soa]`: Skip address SOA(#) rules.<br>`[-no-dualstack-selection]`: Disable dualstack ip selection.<br>`[-no-speed-check]`: Disable speed measurement. <br>`[-no-cache]`: stop caching |bind-tcp :53
479479
|cache-size|Domain name result cache number|512|integer|cache-size 512
480480
|cache-persist|enable persist cache|Auto: Enabled if the location of `cache-file` has more than 128MB of free space.|[yes\|no]|cache-persist yes
481481
|cache-file|cache persist file|/tmp/smartdns.cache|路径|cache-file /tmp/smartdns.cache
@@ -505,8 +505,10 @@ Note: Merlin firmware is derived from ASUS firmware and can theoretically be use
505505
|nameserver|To query domain with specific server group|None|nameserver /domain/[group\|-], `group` is the group name, `-` means ignore this rule, use the `-group` parameter in the related server|nameserver /www.example.com/office
506506
|ipset|Domain IPSet|None|ipset /domain/[ipset\|-\|#[4\|6]:[ipset\|-][,#[4\|6]:[ipset\|-]]], `-` for ignore|ipset /www.example.com/#4:dns4,#6:-
507507
|ipset-timeout|ipset timeout enable|auto|[yes]|ipset-timeout yes
508-
|domain-rules|set domain rules|None|domain-rules /domain/ [-rules...]<br>`[-c\|-speed-check-mode]`: set speed check mode,same as parameter `speed-check-mode`<br>`[-a\|-address]`: same as parameter `address` <br>`[-n\|-nameserver]`: same as parameter `nameserver`<br>`[-p\|-ipset]`: same as parameter `ipset`<br>`[-d\|-dualstack-ip-selection]`: same as parameter `dualstack-ip-selection`|domain-rules /www.example.com/ -speed-check-mode none
509-
| domain-set | collection of domains|None| domain-set [options...]<br>[-n\|-name]:name of set <br>[-t\|-type] [list]: set type, only support list, one domain per line <br>[-f\|-file]:file path of domain set<br> used with address, nameserver, ipset, example: /domain-set:[name]/ | domain-set -name set -type list -file /path/to/list <br> address /domain-set:set/1.2.4.8 |
508+
|nftset|Domain nftset|None|nftset /domain/#[4\|6]:[family#nftable#nftset\|-][,#[4\|6]:[family#nftable#nftset\|-]]], `-` to ignore; the valid families are inet and ip for ipv4 addresses while the valid ones are inet and ip6 for ipv6 addresses; due to the limitation of nft, two types of addresses have to be stored in two sets|nftset /www.example.com/#4:inet#mytab#dns4,#6:-
509+
|nftset-timeout|nftset timeout enable|auto|[yes]|nftset-timeout yes
510+
|domain-rules|set domain rules|None|domain-rules /domain/ [-rules...]<br>`[-c\|-speed-check-mode]`: set speed check mode,same as parameter `speed-check-mode`<br>`[-a\|-address]`: same as parameter `address` <br>`[-n\|-nameserver]`: same as parameter `nameserver`<br>`[-p\|-ipset]`: same as parameter `nftset`<br>`[-s\|-nftset]`: same as parameter `nftset`<br>`[-d\|-dualstack-ip-selection]`: same as parameter `dualstack-ip-selection`|domain-rules /www.example.com/ -speed-check-mode none
511+
| domain-set | collection of domains|None| domain-set [options...]<br>[-n\|-name]:name of set <br>[-t\|-type] [list]: set type, only support list, one domain per line <br>[-f\|-file]:file path of domain set<br> used with address, nameserver, ipset, nftset, example: /domain-set:[name]/ | domain-set -name set -type list -file /path/to/list <br> address /domain-set:set/1.2.4.8 |
510512
|bogus-nxdomain|bogus IP address|None|[IP/subnet], Repeatable| bogus-nxdomain 1.2.3.4/16
511513
|ignore-ip|ignore ip address|None|[ip/subnet], Repeatable| ignore-ip 1.2.3.4/16
512514
|whitelist-ip|ip whitelist|None|[ip/subnet], Repeatable,When the filtering server responds IPs in the IP whitelist, only result in whitelist will be accepted| whitelist-ip 1.2.3.4/16

Diff for: etc/smartdns/smartdns.conf

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
# -group: set domain request to use the appropriate server group.
2727
# -no-rule-addr: skip address rule.
2828
# -no-rule-nameserver: skip nameserver rule.
29-
# -no-rule-ipset: skip ipset rule.
29+
# -no-rule-ipset: skip ipset rule or nftset rule.
3030
# -no-speed-check: do not check speed.
3131
# -no-cache: skip cache.
3232
# -no-rule-soa: Skip address SOA(#) rules.

Diff for: package/build-pkg.sh

+5-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ showhelp()
1616
echo " --platform [luci|luci-compat|debian|openwrt|optware|linux] build for platform. "
1717
echo " --arch [all|armhf|arm64|x86-64|...] build for architecture, e.g. "
1818
echo " --cross-tool [cross-tool] cross compiler, e.g. mips-openwrt-linux-"
19+
echo " --with-nftables build with nftables support"
1920
echo ""
2021
echo "Advance Options:"
2122
echo " --static static link smartdns"
@@ -81,7 +82,7 @@ build()
8182

8283
main()
8384
{
84-
OPTS=`getopt -o o:h --long arch:,filearch:,ver:,platform:,cross-tool:,static,only-package,outputdir: \
85+
OPTS=`getopt -o o:h --long arch:,filearch:,ver:,platform:,cross-tool:,with-nftables,static,only-package,outputdir: \
8586
-n "" -- "$@"`
8687

8788
if [ "$#" -le "1" ]; then
@@ -108,6 +109,9 @@ main()
108109
--cross-tool)
109110
CROSS_TOOL="$2"
110111
shift 2;;
112+
--with-nftables)
113+
MAKE_ARGS="WITH_NFTSET=1"
114+
shift 1;;
111115
--static)
112116
export STATIC="yes"
113117
shift 1;;

Diff for: src/Makefile

+6-1
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,15 @@ else
3838
override LDFLAGS += -lssl -lcrypto -lpthread -ldl
3939
endif
4040

41+
ifdef WITH_NFTSET
42+
override CFLAGS += -DWITH_NFTSET
43+
override LDFLAGS += -lnftables
44+
endif
45+
4146
.PHONY: all clean
4247

4348
all: $(BIN)
44-
49+
4550
$(BIN) : $(OBJS)
4651
$(CC) $(OBJS) -o $@ $(LDFLAGS)
4752

Diff for: src/dns_conf.c

+187
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ struct dns_ipset_table {
4040
};
4141
static struct dns_ipset_table dns_ipset_table;
4242

43+
struct dns_nftset_table {
44+
DECLARE_HASHTABLE(nftset, 8);
45+
};
46+
static struct dns_nftset_table dns_nftset_table;
47+
4348
struct dns_qtype_soa_table dns_qtype_soa_table;
4449

4550
struct dns_domain_set_rule_table dns_domain_set_rule_table;
@@ -133,6 +138,7 @@ int dns_conf_local_ttl;
133138
int dns_conf_force_AAAA_SOA;
134139
int dns_conf_force_no_cname;
135140
int dns_conf_ipset_timeout_enable;
141+
int dns_conf_nftset_timeout_enable;
136142

137143
char dns_conf_user[DNS_CONF_USRNAME_LEN];
138144

@@ -170,6 +176,10 @@ static void *_new_dns_rule(enum domain_rule domain_rule)
170176
case DOMAIN_RULE_IPSET_IPV6:
171177
size = sizeof(struct dns_ipset_rule);
172178
break;
179+
case DOMAIN_RULE_NFTSET_IP:
180+
case DOMAIN_RULE_NFTSET_IP6:
181+
size = sizeof(struct dns_nftset_rule);
182+
break;
173183
case DOMAIN_RULE_NAMESERVER:
174184
size = sizeof(struct dns_nameserver_rule);
175185
break;
@@ -853,6 +863,165 @@ static int _config_ipset(void *data, int argc, char *argv[])
853863
return 0;
854864
}
855865

866+
static void _config_nftset_table_destroy(void)
867+
{
868+
struct dns_nftset_name *nftset = NULL;
869+
struct hlist_node *tmp = NULL;
870+
unsigned long i = 0;
871+
872+
hash_for_each_safe(dns_nftset_table.nftset, i, tmp, nftset, node)
873+
{
874+
hlist_del_init(&nftset->node);
875+
free(nftset);
876+
}
877+
}
878+
879+
static const struct dns_nftset_name *_dns_conf_get_nftable(const char *familyname, const char *tablename,
880+
const char *setname)
881+
{
882+
uint32_t key = 0;
883+
struct dns_nftset_name *nftset_name = NULL;
884+
885+
if (familyname == NULL || tablename == NULL || setname == NULL) {
886+
return NULL;
887+
}
888+
889+
const char *hasher[4] = {familyname, tablename, setname, NULL};
890+
891+
key = hash_string_array(hasher);
892+
hash_for_each_possible(dns_nftset_table.nftset, nftset_name, node, key)
893+
{
894+
if (strncmp(nftset_name->nftfamilyname, familyname, DNS_MAX_NFTSET_FAMILYLEN) == 0 &&
895+
strncmp(nftset_name->nfttablename, tablename, DNS_MAX_NFTSET_NAMELEN) == 0 &&
896+
strncmp(nftset_name->nftsetname, setname, DNS_MAX_NFTSET_NAMELEN) == 0) {
897+
return nftset_name;
898+
}
899+
}
900+
901+
nftset_name = malloc(sizeof(*nftset_name));
902+
if (nftset_name == NULL) {
903+
goto errout;
904+
}
905+
906+
safe_strncpy(nftset_name->nftfamilyname, familyname, DNS_MAX_NFTSET_FAMILYLEN);
907+
safe_strncpy(nftset_name->nfttablename, tablename, DNS_MAX_NFTSET_NAMELEN);
908+
safe_strncpy(nftset_name->nftsetname, setname, DNS_MAX_NFTSET_NAMELEN);
909+
hash_add(dns_nftset_table.nftset, &nftset_name->node, key);
910+
911+
return nftset_name;
912+
errout:
913+
if (nftset_name) {
914+
free(nftset_name);
915+
}
916+
917+
return NULL;
918+
}
919+
920+
static int _conf_domain_rule_nftset(char *domain, const char *nftsetname)
921+
{
922+
struct dns_nftset_rule *nftset_rule = NULL;
923+
const struct dns_nftset_name *nftset = NULL;
924+
char *copied_name = NULL;
925+
enum domain_rule type = 0;
926+
int ignore_flag = 0;
927+
char *setname = NULL;
928+
char *tablename = NULL;
929+
930+
copied_name = strdup(nftsetname);
931+
932+
if (copied_name == NULL) {
933+
goto errout;
934+
}
935+
936+
for (char *tok = strtok(copied_name, ","); tok; tok = strtok(NULL, ",")) {
937+
if (tok[0] == '#') {
938+
if (strncmp(tok, "#6:inet#", 8U) == 0 || strncmp(tok, "#6:ip6#", 7U) == 0) {
939+
type = DOMAIN_RULE_NFTSET_IP6;
940+
ignore_flag = DOMAIN_FLAG_NFTSET_IP6_IGN;
941+
} else if (strncmp(tok, "#4:inet#", 4U) == 0 || strncmp(tok, "#4:ip#", 6U) == 0) {
942+
type = DOMAIN_RULE_NFTSET_IP;
943+
ignore_flag = DOMAIN_FLAG_NFTSET_IP_IGN;
944+
} else {
945+
goto errout;
946+
}
947+
tok += 3;
948+
} else {
949+
goto errout;
950+
}
951+
952+
if (strncmp(tok, "-", 1U) == 0) {
953+
_config_domain_rule_flag_set(domain, ignore_flag, 0);
954+
continue;
955+
}
956+
957+
tablename = strpbrk(tok, "#");
958+
if (tablename == NULL) {
959+
goto errout;
960+
}
961+
*tablename++ = '\0';
962+
setname = strpbrk(tablename, "#");
963+
if (setname == NULL) {
964+
goto errout;
965+
}
966+
*setname++ = '\0';
967+
968+
/* new ipset domain */
969+
nftset = _dns_conf_get_nftable(tok, tablename, setname);
970+
if (nftset == NULL) {
971+
goto errout;
972+
}
973+
974+
nftset_rule = _new_dns_rule(type);
975+
if (nftset_rule == NULL) {
976+
goto errout;
977+
}
978+
979+
nftset_rule->nfttablename = nftset->nfttablename;
980+
nftset_rule->nftsetname = nftset->nftsetname;
981+
nftset_rule->familyname = nftset->nftfamilyname;
982+
983+
if (_config_domain_rule_add(domain, type, nftset_rule) != 0) {
984+
goto errout;
985+
}
986+
_dns_rule_put(&nftset_rule->head);
987+
}
988+
989+
goto clear;
990+
991+
errout:
992+
tlog(TLOG_ERROR, "add nftset %s failed", nftsetname);
993+
994+
if (nftset_rule) {
995+
_dns_rule_put(&nftset_rule->head);
996+
}
997+
998+
clear:
999+
if (copied_name) {
1000+
free(copied_name);
1001+
}
1002+
1003+
return 0;
1004+
}
1005+
1006+
static int _config_nftset(void *data, int argc, char *argv[])
1007+
{
1008+
char domain[DNS_MAX_CONF_CNAME_LEN];
1009+
char *value = argv[1];
1010+
1011+
if (argc <= 1) {
1012+
goto errout;
1013+
}
1014+
1015+
if (_get_domain(value, domain, DNS_MAX_CONF_CNAME_LEN, &value) != 0) {
1016+
goto errout;
1017+
}
1018+
1019+
return _conf_domain_rule_nftset(domain, value);
1020+
errout:
1021+
tlog(TLOG_ERROR, "add nftset %s failed", value);
1022+
return 0;
1023+
}
1024+
8561025
static int _conf_domain_rule_address(char *domain, const char *domain_address)
8571026
{
8581027
struct dns_rule_address_IPV4 *address_ipv4 = NULL;
@@ -1665,6 +1834,7 @@ static int _conf_domain_rules(void *data, int argc, char *argv[])
16651834
{"speed-check-mode", required_argument, NULL, 'c'},
16661835
{"address", required_argument, NULL, 'a'},
16671836
{"ipset", required_argument, NULL, 'p'},
1837+
{"nftset", required_argument, NULL, 's'},
16681838
{"nameserver", required_argument, NULL, 'n'},
16691839
{"dualstack-ip-selection", required_argument, NULL, 'd'},
16701840
{NULL, no_argument, NULL, 0}
@@ -1750,6 +1920,19 @@ static int _conf_domain_rules(void *data, int argc, char *argv[])
17501920

17511921
break;
17521922
}
1923+
case 's': {
1924+
const char *nftsetname = optarg;
1925+
if (nftsetname == NULL) {
1926+
goto errout;
1927+
}
1928+
1929+
if (_conf_domain_rule_nftset(domain, nftsetname) != 0) {
1930+
tlog(TLOG_ERROR, "add nftset rule failed.");
1931+
goto errout;
1932+
}
1933+
1934+
break;
1935+
}
17531936
default:
17541937
break;
17551938
}
@@ -2178,6 +2361,8 @@ static struct config_item _config_item[] = {
21782361
CONF_CUSTOM("address", _config_address, NULL),
21792362
CONF_YESNO("ipset-timeout", &dns_conf_ipset_timeout_enable),
21802363
CONF_CUSTOM("ipset", _config_ipset, NULL),
2364+
CONF_YESNO("nftset-timeout", &dns_conf_nftset_timeout_enable),
2365+
CONF_CUSTOM("nftset", _config_nftset, NULL),
21812366
CONF_CUSTOM("speed-check-mode", _config_speed_check_mode, NULL),
21822367
CONF_INT("tcp-idle-time", &dns_conf_tcp_idle_time, 0, 3600),
21832368
CONF_INT("cache-size", &dns_conf_cachesize, 0, CONF_INT_MAX),
@@ -2384,6 +2569,7 @@ static int _dns_server_load_conf_init(void)
23842569
art_tree_init(&dns_conf_domain_rule);
23852570

23862571
hash_init(dns_ipset_table.ipset);
2572+
hash_init(dns_nftset_table.nftset);
23872573
hash_init(dns_qtype_soa_table.qtype);
23882574
hash_init(dns_group_table.group);
23892575
hash_init(dns_hosts_table.hosts);
@@ -2400,6 +2586,7 @@ void dns_server_load_exit(void)
24002586
Destroy_Radix(dns_conf_address_rule.ipv4, _config_address_destroy, NULL);
24012587
Destroy_Radix(dns_conf_address_rule.ipv6, _config_address_destroy, NULL);
24022588
_config_ipset_table_destroy();
2589+
_config_nftset_table_destroy();
24032590
_config_group_table_destroy();
24042591
_config_ptr_table_destroy();
24052592
_config_host_table_destroy();

0 commit comments

Comments
 (0)