From dc2ca41afde26f016590305fb411cd0bc1fec76b Mon Sep 17 00:00:00 2001 From: gSpot Date: Tue, 26 Nov 2024 17:27:10 +0300 Subject: [PATCH] Dnsmasq confdir from ubus. --- autoinstall/2.x/autoinstall.sh | 6 +- luci-app-ruantiblock/Makefile | 4 +- .../resources/view/ruantiblock/service.js | 59 +++++++++++-------- .../resources/view/ruantiblock/tools.js | 1 - luci-app-ruantiblock/po/ru/ruantiblock.po | 3 + .../po/templates/ruantiblock.pot | 3 + .../rpcd/acl.d/luci-app-ruantiblock.json | 3 +- ruantiblock-mod-lua/Makefile | 4 +- ruantiblock-mod-py/Makefile | 4 +- ruantiblock/Makefile | 4 +- ruantiblock/files/etc/init.d/ruantiblock | 41 ++++++++----- .../files/etc/ruantiblock/ruantiblock.conf | 6 +- ruantiblock/files/usr/bin/ruantiblock | 30 +++++----- .../files/usr/share/ruantiblock/config_script | 3 +- 14 files changed, 100 insertions(+), 71 deletions(-) diff --git a/autoinstall/2.x/autoinstall.sh b/autoinstall/2.x/autoinstall.sh index 5ccde6b..c87f781 100755 --- a/autoinstall/2.x/autoinstall.sh +++ b/autoinstall/2.x/autoinstall.sh @@ -10,9 +10,9 @@ LUCI_APP=1 HTTPS_DNS_PROXY=1 OWRT_VERSION="current" -RUAB_VERSION="2.1.0-r2" -RUAB_MOD_LUA_VERSION="2.1.0-r2" -RUAB_LUCI_APP_VERSION="2.1.0-2" +RUAB_VERSION="2.1.1-r1" +RUAB_MOD_LUA_VERSION="2.1.1-r1" +RUAB_LUCI_APP_VERSION="2.1.1-1" BASE_URL="https://raw.githubusercontent.com/gSpotx2f/packages-openwrt/master" PKG_DIR="/tmp" diff --git a/luci-app-ruantiblock/Makefile b/luci-app-ruantiblock/Makefile index 00b3b41..b973969 100644 --- a/luci-app-ruantiblock/Makefile +++ b/luci-app-ruantiblock/Makefile @@ -5,8 +5,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-ruantiblock -PKG_VERSION:=2.1.0 -PKG_RELEASE:=2 +PKG_VERSION:=2.1.1 +PKG_RELEASE:=1 LUCI_TITLE:=LuCI support for ruantiblock LUCI_DEPENDS:=+ruantiblock LUCI_PKGARCH:=all diff --git a/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/service.js b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/service.js index a7c6b9a..ed0b391 100644 --- a/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/service.js +++ b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/service.js @@ -2,6 +2,7 @@ 'require baseclass'; 'require fs'; 'require poll'; +'require rpc'; 'require uci'; 'require ui'; 'require view'; @@ -16,6 +17,12 @@ const btn_style_warning = 'btn cbi-button-negative important' return view.extend({ statusTokenValue: null, + callServicesList: rpc.declare({ + object: 'service', + method: 'list', + expect: { '': {} } + }), + dialogDestroy: baseclass.extend({ __init__(context) { this.context = context; @@ -25,33 +32,39 @@ return view.extend({ dnsmasqCfgDirsSelect: null, - cancelButton : E('button', { + cancelButton : E('button', { 'id' : 'btn_cancel', 'class': btn_style_neutral, 'click': ui.hideModal, }, _('Cancel')), load() { - return L.resolveDefault(fs.list(tools.dnsmasqCfgDirsRoot), null); + return this.context.callServicesList(); }, render(data) { let section = uci.get(tools.appName, 'config'); - this.currentDnsmasqCfgDir = section.dnsmasq_cfg_dir; + this.currentDnsmasqCfgDir = section.dnsmasq_confdir; let available_cfg_dirs = []; - let dnsmasq_cfg_dirs_arr = data; - if(dnsmasq_cfg_dirs_arr) { - dnsmasq_cfg_dirs_arr.forEach(e => { - let fname = e.name; - if(fname.startsWith('dnsmasq')) { - available_cfg_dirs.push([ fname, tools.dnsmasqCfgDirsRoot + '/' + fname ]); + if(data.dnsmasq && data.dnsmasq.instances) { + let ubus_dirs = new Set(); + for(let [k, v] of Object.entries(data.dnsmasq.instances)) { + if(v.mount) { + for(let i of Object.keys(v.mount)) { + if(!ubus_dirs.has(i) && i.startsWith('/tmp/dnsmasq.')) { + if(i == "/tmp/dnsmasq.d") { + k = _("default"); + }; + available_cfg_dirs.push([ `${i} [ ${k} ]`, i ]); + ubus_dirs.add(i); + }; + }; }; - }); + }; }; - this.dnsmasqCfgDirsSelect = E('select', { - 'id' : 'dnsmasq_cfg_dirs_list', + 'id' : 'dnsmasq_confdirs_list', 'class': "cbi-input-select", }), @@ -90,7 +103,7 @@ return view.extend({ this.cancelButton.disabled = true; return this.context.appAction('destroy').then(() => { if(this.dnsmasqCfgDirsSelect.value !== this.currentDnsmasqCfgDir) { - uci.set(tools.appName, 'config', 'dnsmasq_cfg_dir', + uci.set(tools.appName, 'config', 'dnsmasq_confdir', this.dnsmasqCfgDirsSelect.value); uci.save(); uci.apply(); @@ -171,21 +184,21 @@ return view.extend({ return; }; - let app_status_code = (force_app_code) ? force_app_code : status_array[0].code; + let app_status_code = (force_app_code) ? force_app_code : status_array[0].code; let vpn_route_status_code = status_array[1].code; let enabled_flag = status_array[2]; - let dnsmasq_cfg_dir = section.dnsmasq_cfg_dir; + let dnsmasq_confdir = section.dnsmasq_confdir; let bllist_preset = section.bllist_preset; let bllist_module = section.bllist_module; let btn_enable = elems[2] || document.getElementById('btn_enable'); if(enabled_flag == true) { - btn_enable.onclick = ui.createHandlerFn( + btn_enable.onclick = ui.createHandlerFn( this, this.serviceAction, 'disable', 'btn_enable'); btn_enable.textContent = _('Enabled'); btn_enable.className = btn_style_positive; } else { - btn_enable.onclick = ui.createHandlerFn( + btn_enable.onclick = ui.createHandlerFn( this, this.serviceAction, 'enable', 'btn_enable'); btn_enable.textContent = _('Disabled'); btn_enable.className = btn_style_negative; @@ -196,14 +209,14 @@ return view.extend({ let btn_destroy = elems[4] || document.getElementById('btn_destroy'); let btnStartStateOn = () => { - btn_start.onclick = ui.createHandlerFn( + btn_start.onclick = ui.createHandlerFn( this, this.appAction, 'stop', 'btn_start'); btn_start.textContent = _('Enabled'); btn_start.className = btn_style_positive; } let btnStartStateOff = () => { - btn_start.onclick = ui.createHandlerFn( + btn_start.onclick = ui.createHandlerFn( this, this.appAction,'start', 'btn_start'); btn_start.textContent = _('Disabled'); btn_start.className = btn_style_negative; @@ -308,8 +321,8 @@ return view.extend({ return; }; - let section = uci.get(tools.appName, 'config'); - this.statusTokenValue = (Array.isArray(status_array)) ? + let section = uci.get(tools.appName, 'config'); + this.statusTokenValue = (Array.isArray(status_array)) ? tools.normalizeValue(status_array[4]) : null; let dialog_destroy = new this.dialogDestroy(this); @@ -399,7 +412,7 @@ return view.extend({ ]); }, - handleSave : null, + handleSave : null, handleSaveApply: null, - handleReset : null, + handleReset : null, }); diff --git a/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/tools.js b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/tools.js index 499b43e..384d255 100644 --- a/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/tools.js +++ b/luci-app-ruantiblock/htdocs/luci-static/resources/view/ruantiblock/tools.js @@ -38,7 +38,6 @@ return baseclass.extend({ execPath : '/usr/bin/ruantiblock', tokenFile : '/var/run/ruantiblock.token', parsersDir : '/usr/libexec/ruantiblock', - dnsmasqCfgDirsRoot : '/tmp', torrcFile : '/etc/tor/torrc', userEntriesFile : '/etc/ruantiblock/user_entries', userListsDir : '/etc/ruantiblock/user_lists', diff --git a/luci-app-ruantiblock/po/ru/ruantiblock.po b/luci-app-ruantiblock/po/ru/ruantiblock.po index 49f969c..22e75f4 100644 --- a/luci-app-ruantiblock/po/ru/ruantiblock.po +++ b/luci-app-ruantiblock/po/ru/ruantiblock.po @@ -607,6 +607,9 @@ msgstr "все" msgid "ascending" msgstr "по возрастанию" +msgid "default" +msgstr "по умолчанию" + msgid "descending" msgstr "по убыванию" diff --git a/luci-app-ruantiblock/po/templates/ruantiblock.pot b/luci-app-ruantiblock/po/templates/ruantiblock.pot index bf117fd..3dec46d 100644 --- a/luci-app-ruantiblock/po/templates/ruantiblock.pot +++ b/luci-app-ruantiblock/po/templates/ruantiblock.pot @@ -562,6 +562,9 @@ msgstr "все" msgid "ascending" msgstr "" +msgid "default" +msgstr "" + msgid "descending" msgstr "" diff --git a/luci-app-ruantiblock/root/usr/share/rpcd/acl.d/luci-app-ruantiblock.json b/luci-app-ruantiblock/root/usr/share/rpcd/acl.d/luci-app-ruantiblock.json index 6dfe703..4c953f0 100644 --- a/luci-app-ruantiblock/root/usr/share/rpcd/acl.d/luci-app-ruantiblock.json +++ b/luci-app-ruantiblock/root/usr/share/rpcd/acl.d/luci-app-ruantiblock.json @@ -21,7 +21,8 @@ }, "uci": [ "network", "ruantiblock" ], "ubus": { - "luci": [ "getInitList", "setInitAction" ] + "luci": [ "getInitList", "setInitAction" ], + "service": [ "list" ] } }, "write": { diff --git a/ruantiblock-mod-lua/Makefile b/ruantiblock-mod-lua/Makefile index 62bbd40..bfd05be 100644 --- a/ruantiblock-mod-lua/Makefile +++ b/ruantiblock-mod-lua/Makefile @@ -5,8 +5,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ruantiblock-mod-lua -PKG_VERSION:=2.1.0 -PKG_RELEASE:=2 +PKG_VERSION:=2.1.1 +PKG_RELEASE:=1 PKG_MAINTAINER:=gSpot include $(INCLUDE_DIR)/package.mk diff --git a/ruantiblock-mod-py/Makefile b/ruantiblock-mod-py/Makefile index f5d444b..d2a4772 100644 --- a/ruantiblock-mod-py/Makefile +++ b/ruantiblock-mod-py/Makefile @@ -5,8 +5,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ruantiblock-mod-py -PKG_VERSION:=2.1.0 -PKG_RELEASE:=2 +PKG_VERSION:=2.1.1 +PKG_RELEASE:=1 PKG_MAINTAINER:=gSpot include $(INCLUDE_DIR)/package.mk diff --git a/ruantiblock/Makefile b/ruantiblock/Makefile index 6f52565..020c135 100644 --- a/ruantiblock/Makefile +++ b/ruantiblock/Makefile @@ -5,8 +5,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ruantiblock -PKG_VERSION:=2.1.0 -PKG_RELEASE:=2 +PKG_VERSION:=2.1.1 +PKG_RELEASE:=1 PKG_MAINTAINER:=gSpot include $(INCLUDE_DIR)/package.mk diff --git a/ruantiblock/files/etc/init.d/ruantiblock b/ruantiblock/files/etc/init.d/ruantiblock index 4cbe01a..68db8e7 100755 --- a/ruantiblock/files/etc/init.d/ruantiblock +++ b/ruantiblock/files/etc/init.d/ruantiblock @@ -5,17 +5,30 @@ STOP=01 APP_NAME="ruantiblock" APP_EXEC="/usr/bin/${APP_NAME}" -DNSMASQ_VAR_DIR="/tmp" +VAR_DIR="/tmp" -get_dnsmasq_cfg_dir() { - local _first_instance - if [ -d "${DNSMASQ_VAR_DIR}/dnsmasq.d" ]; then - printf "${DNSMASQ_VAR_DIR}/dnsmasq.d" +get_dnsmasq_confdir() { + local _first_instance_dir + if [ -d "${VAR_DIR}/dnsmasq.d" ]; then + printf "${VAR_DIR}/dnsmasq.d" return 0 else - _first_instance=`ls -1 "$DNSMASQ_VAR_DIR" | grep -e "^dnsmasq" | head -n 1` - if [ -n "$_first_instance" ]; then - printf "${DNSMASQ_VAR_DIR}/${_first_instance}" + _first_instance_dir=`ubus call service list | jsonfilter -e "VAR=$.dnsmasq.instances.*.mount" | awk ' + BEGIN { + RS = " "; + } + { + sub("VAR=", "", $0); + gsub(/[\047,\134,\073]/, "", $0); + if($0 ~ /^\/tmp\/dnsmasq\./ && !($0 in a)) { + a[length(a)] = $0; + }; + } + END { + print a[0]; + }'` + if [ -n "$_first_instance_dir" ]; then + printf "$_first_instance_dir" return 0 fi fi @@ -23,14 +36,14 @@ get_dnsmasq_cfg_dir() { } start() { - local _update_at_startup _dnsmasq_cfg_dir + local _update_at_startup _dnsmasq_confdir config_load $APP_NAME config_get _update_at_startup config update_at_startup - config_get _dnsmasq_cfg_dir config dnsmasq_cfg_dir "" - if [ -z "$_dnsmasq_cfg_dir" ]; then - _dnsmasq_cfg_dir=`get_dnsmasq_cfg_dir` - if [ $? -eq 0 -a -n "$_dnsmasq_cfg_dir" ]; then - uci set "${APP_NAME}.config.dnsmasq_cfg_dir"="$_dnsmasq_cfg_dir" + config_get _dnsmasq_confdir config dnsmasq_confdir "" + if [ -z "$_dnsmasq_confdir" ]; then + _dnsmasq_confdir=`get_dnsmasq_confdir` + if [ $? -eq 0 -a -n "$_dnsmasq_confdir" ]; then + uci set "${APP_NAME}.config.dnsmasq_confdir"="$_dnsmasq_confdir" uci commit ruantiblock else exit 1 diff --git a/ruantiblock/files/etc/ruantiblock/ruantiblock.conf b/ruantiblock/files/etc/ruantiblock/ruantiblock.conf index 6006743..01c3bdf 100644 --- a/ruantiblock/files/etc/ruantiblock/ruantiblock.conf +++ b/ruantiblock/files/etc/ruantiblock/ruantiblock.conf @@ -8,7 +8,7 @@ MODULES_DIR="/usr/libexec/ruantiblock" ### Директория PID-файлов и файлов статуса RUN_FILES_DIR="/var/run" ### Директория доп. конфигов dnsmasq -DNSMASQ_CFG_DIR="/var/dnsmasq.d" +DNSMASQ_CONFDIR="/var/dnsmasq.d" ### Команда для перезапуска dnsmasq DNSMASQ_RESTART_CMD="/etc/init.d/dnsmasq restart" ### Директория для html-страницы статуса (не используется в OpenWrt) @@ -103,7 +103,7 @@ BLLIST_MODULE="" BLLIST_PRESET="" ### В случае если из источника получено менее указанного кол-ва записей, то обновления списков не происходит BLLIST_MIN_ENTRIES=3000 -### Лимит ip адресов. При достижении, в конфиг ipset будет добавлена вся подсеть /24 вместо множества ip-адресов пренадлежащих этой сети (0 - выкл) +### Лимит ip адресов. При достижении, в конфиг nftables будет добавлена вся подсеть /24 вместо множества ip-адресов пренадлежащих этой сети (0 - выкл) BLLIST_IP_LIMIT=0 ### Файл с подсетями класса C (/24). IP адреса из этих подсетей не группируются при оптимизации (записи д.б. в виде: 68.183.221. 149.154.162. и пр. Одна запись на строку) BLLIST_GR_EXCLUDED_NETS_FILE="/etc/ruantiblock/gr_excluded_nets" @@ -111,7 +111,7 @@ BLLIST_GR_EXCLUDED_NETS_FILE="/etc/ruantiblock/gr_excluded_nets" BLLIST_SUMMARIZE_IP=0 ### Группировать идущие подряд подсети /24 в диапазоны CIDR BLLIST_SUMMARIZE_CIDR=0 -### Фильтрация записей блэклиста по шаблонам из файла BLLIST_IP_FILTER_FILE. Записи (IP, CIDR) попадающие под шаблоны исключаются из кофига ipset (0 - выкл, 1 - вкл) +### Фильтрация записей блэклиста по шаблонам из файла BLLIST_IP_FILTER_FILE. Записи (IP, CIDR) попадающие под шаблоны исключаются из кофига nftables (0 - выкл, 1 - вкл) BLLIST_IP_FILTER=0 ### Тип фильтра IP (0 - все записи, кроме совпадающих с шаблонами; 1 - только записи, совпадающие с шаблонами) BLLIST_IP_FILTER_TYPE=0 diff --git a/ruantiblock/files/usr/bin/ruantiblock b/ruantiblock/files/usr/bin/ruantiblock index 996dee7..9da6ffb 100755 --- a/ruantiblock/files/usr/bin/ruantiblock +++ b/ruantiblock/files/usr/bin/ruantiblock @@ -22,7 +22,7 @@ export DATA_DIR="/var/${NAME}" export MODULES_DIR="/usr/libexec/${NAME}" RUN_FILES_DIR="/var/run" ### Директория доп. конфигов dnsmasq -export DNSMASQ_CFG_DIR="/var/dnsmasq.d" +export DNSMASQ_CONFDIR="/var/dnsmasq.d" ### Команда для перезапуска dnsmasq export DNSMASQ_RESTART_CMD="/etc/init.d/dnsmasq restart" ### Директория для html-страницы статуса (не используется в OpenWrt) @@ -137,7 +137,7 @@ export BLLIST_MODULE="" export BLLIST_PRESET="" ### В случае если из источника получено менее указанного кол-ва записей, то обновления списков не происходит export BLLIST_MIN_ENTRIES=3000 -### Лимит IP адресов. При достижении, в конфиг ipset будет добавлена вся подсеть /24 вместо множества IP адресов пренадлежащих этой сети (0 - выкл) +### Лимит IP адресов. При достижении, в конфиг nftables будет добавлена вся подсеть /24 вместо множества IP адресов пренадлежащих этой сети (0 - выкл) export BLLIST_IP_LIMIT=0 ### Файл с подсетями класса C (/24). IP адреса из этих подсетей не группируются при оптимизации (записи д.б. в виде: 68.183.221. 149.154.162. и пр. Одна запись на строку) export BLLIST_GR_EXCLUDED_NETS_FILE="${CONFIG_DIR}/gr_excluded_nets" @@ -145,7 +145,7 @@ export BLLIST_GR_EXCLUDED_NETS_FILE="${CONFIG_DIR}/gr_excluded_nets" export BLLIST_SUMMARIZE_IP=0 ### Группировать идущие подряд подсети /24 в диапазоны CIDR export BLLIST_SUMMARIZE_CIDR=0 -### Фильтрация записей блэклиста по шаблонам из файла BLLIST_IP_FILTER_FILE. Записи (IP, CIDR) попадающие под шаблоны исключаются из кофига ipset (0 - выкл, 1 - вкл) +### Фильтрация записей блэклиста по шаблонам из файла BLLIST_IP_FILTER_FILE. Записи (IP, CIDR) попадающие под шаблоны исключаются из кофига nftables (0 - выкл, 1 - вкл) export BLLIST_IP_FILTER=0 ### Тип фильтра IP (0 - все записи, кроме совпадающих с шаблонами; 1 - только записи, совпадающие с шаблонами) export BLLIST_IP_FILTER_TYPE=0 @@ -195,9 +195,9 @@ BLLIST_SOURCES_SCRIPT="${SCRIPTS_DIR}/blacklist_sources" ### Config script [ -f "$CONFIG_SCRIPT" ] && . "$CONFIG_SCRIPT" -export DNSMASQ_DATA_FILE_BYPASS="${DNSMASQ_CFG_DIR}/00-${NAME}_bypass.dnsmasq" -export DNSMASQ_DATA_FILE_USER_INSTANCES="${DNSMASQ_CFG_DIR}/01-${NAME}_user_instances.dnsmasq" -export DNSMASQ_DATA_FILE="${DNSMASQ_CFG_DIR}/02-${NAME}.dnsmasq" +export DNSMASQ_DATA_FILE_BYPASS="${DNSMASQ_CONFDIR}/00-${NAME}_bypass.dnsmasq" +export DNSMASQ_DATA_FILE_USER_INSTANCES="${DNSMASQ_CONFDIR}/01-${NAME}_user_instances.dnsmasq" +export DNSMASQ_DATA_FILE="${DNSMASQ_CONFDIR}/02-${NAME}.dnsmasq" ### Utilities AWK_CMD="awk" @@ -694,9 +694,8 @@ AddBypassEntries() { if [ "$BYPASS_MODE" = "1" ]; then if [ -f "$BYPASS_ENTRIES_FILE" ]; then $AWK_CMD 'BEGIN { - null = ""; - ip_array[0] = null; - fqdn_array[0] = null; + ip_array[0]; + fqdn_array[0]; } function writeIpList(array, _str) { _str = ""; @@ -724,7 +723,7 @@ AddBypassEntries() { ($0 !~ /^([\040\011]*$|#)/) { sub("\015", "", $0); if($0 ~ /^[0-9]{1,3}([.][0-9]{1,3}){3}([\057][0-9]{1,2})?$/) { - ip_array[$0] = null; + ip_array[$0]; } else if($0 ~ /^([a-z0-9._-]+[.])*([a-z]{2,}|xn--[a-z0-9]+)([ ][0-9]{1,3}([.][0-9]{1,3}){3}([#][0-9]{2,5})?)?$/) { fqdn_array[length(fqdn_array)] = $1 " " $2; @@ -748,10 +747,9 @@ ParseUserEntries() { -v IP_DATA_FILE="$4" -v DNSMASQ_DATA_FILE="$5" -v USER_ENTRIES_STATUS_FILE="$6" \ -v ID="$7" -v USER_ENTRIES_DNS="$8" ' BEGIN { - null = ""; - ip_array[0] = null; - cidr_array[0] = null; - fqdn_array[0] = null; + ip_array[0]; + cidr_array[0]; + fqdn_array[0]; } function writeIpList(array, _str) { _str = ""; @@ -779,10 +777,10 @@ ParseUserEntries() { ($0 !~ /^([\040\011]*$|#)/) { sub("\015", "", $0); if($0 ~ /^[0-9]{1,3}([.][0-9]{1,3}){3}$/) { - ip_array[$0] = null; + ip_array[$0]; } else if($0 ~ /^[0-9]{1,3}([.][0-9]{1,3}){3}[\057][0-9]{1,2}$/) { - cidr_array[$0] = null; + cidr_array[$0]; } else if($0 ~ /^([a-z0-9._-]+[.])*([a-z]{2,}|xn--[a-z0-9]+)([ ][0-9]{1,3}([.][0-9]{1,3}){3}([#][0-9]{2,5})?)?$/) { fqdn_array[length(fqdn_array)] = $1 " " $2; diff --git a/ruantiblock/files/usr/share/ruantiblock/config_script b/ruantiblock/files/usr/share/ruantiblock/config_script index 94d6d17..1290863 100644 --- a/ruantiblock/files/usr/share/ruantiblock/config_script +++ b/ruantiblock/files/usr/share/ruantiblock/config_script @@ -1,6 +1,5 @@ - UCI_SECTION="ruantiblock.config" -UCI_VARS="dnsmasq_cfg_dir proxy_mode proxy_local_clients nftset_clear_sets allowed_hosts_mode allowed_hosts_list bypass_mode bypass_entries_dns enable_fproxy fproxy_list enable_bllist_proxy if_vpn vpn_gw_ip vpn_route_check tor_trans_port onion_dns_addr t_proxy_type t_proxy_port_tcp t_proxy_port_udp t_proxy_allow_udp enable_logging bllist_min_entries bllist_module bllist_preset bllist_ip_limit bllist_summarize_ip bllist_summarize_cidr bllist_ip_filter bllist_ip_filter_type bllist_sd_limit bllist_fqdn_filter bllist_fqdn_filter_type bllist_enable_idn bllist_alt_nslookup bllist_alt_dns_addr update_at_startup enable_tmp_downloads" +UCI_VARS="dnsmasq_confdir proxy_mode proxy_local_clients nftset_clear_sets allowed_hosts_mode allowed_hosts_list bypass_mode bypass_entries_dns enable_fproxy fproxy_list enable_bllist_proxy if_vpn vpn_gw_ip vpn_route_check tor_trans_port onion_dns_addr t_proxy_type t_proxy_port_tcp t_proxy_port_udp t_proxy_allow_udp enable_logging bllist_min_entries bllist_module bllist_preset bllist_ip_limit bllist_summarize_ip bllist_summarize_cidr bllist_ip_filter bllist_ip_filter_type bllist_sd_limit bllist_fqdn_filter bllist_fqdn_filter_type bllist_enable_idn bllist_alt_nslookup bllist_alt_dns_addr update_at_startup enable_tmp_downloads" UCI_CMD=`which uci` if [ $? -ne 0 ]; then echo " Error! UCI doesn't exists" >&2