pbr: update to 1.1.7-29
authorStan Grishin <stangri@melmac.ca>
Thu, 24 Oct 2024 20:12:35 +0000 (20:12 +0000)
committerStan Grishin <stangri@melmac.ca>
Tue, 29 Oct 2024 00:12:01 +0000 (17:12 -0700)
Changes from @stangri
* remove unneeded `\n` escapes
* cosmetic improvements to make code more consistent
* remove duplicate uci_get_device()
* add more output on start/stop
* remove wan up detection on boot/start
* address Tor policies errors
* prevent interface_routing() failures for downed interfaces

Changes from @bigsmile74:
* improve is_integer()
* improve is_domain()
* improve filter_options()
* imrove is_ipv4() so that is_ipv4_netmask() can be retired
* improve is_phys_dev so that is_phys_dev_quick() can be retired
* add the dhcp.lan.force=0 warning

Signed-off-by: Stan Grishin <stangri@melmac.ca>
net/pbr/Makefile
net/pbr/files/etc/init.d/pbr

index 4bccd55a63d5a5eeff8ba9ccda5ce1ba9c053056..33e89ddc88cf7dc59eb656f19592ff9b8ed45b55 100644 (file)
@@ -5,7 +5,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=pbr
 PKG_VERSION:=1.1.7
-PKG_RELEASE:=21
+PKG_RELEASE:=29
 PKG_LICENSE:=AGPL-3.0-or-later
 PKG_MAINTAINER:=Stan Grishin <stangri@melmac.ca>
 
index 053e6b3544a681c2825f07aa958ce65d99c96b25..bbb1cdb00c9c55a9ccac6701c64eab5c738fc5ba 100755 (executable)
@@ -14,7 +14,7 @@ USE_PROCD=1
 
 readonly packageName='pbr'
 readonly PKG_VERSION='dev-test'
-readonly packageCompat='8'
+readonly packageCompat='9'
 readonly serviceName="$packageName $PKG_VERSION"
 readonly packageConfigFile="/etc/config/${packageName}"
 readonly packageLockFile="/var/run/${packageName}.lock"
@@ -113,12 +113,12 @@ torTrafficPort=
 # shellcheck disable=SC1091
 . /usr/share/libubox/jshn.sh
 
-output_ok() { output 1 "$_OK_"; output 2 "$__OK__\\n"; }
-output_okn() { output 1 "$_OK_\\n"; output 2 "$__OK__\\n"; }
-output_okb() { output 1 "$_OKB_"; output 2 "$__OKB__\\n"; }
-output_okbn() { output 1 "$_OKB_\\n"; output 2 "$__OKB__\\n"; }
-output_fail() { output 1 "$_FAIL_"; output 2 "$__FAIL__\\n"; }
-output_failn() { output 1 "$_FAIL_\\n"; output 2 "$__FAIL__\\n"; }
+output_ok() { output 1 "$_OK_"; output 2 "$__OK__\n"; }
+output_okn() { output 1 "$_OK_\n"; output 2 "$__OK__\n"; }
+output_okb() { output 1 "$_OKB_"; output 2 "$__OKB__\n"; }
+output_okbn() { output 1 "$_OKB_\n"; output 2 "$__OKB__\n"; }
+output_fail() { output 1 "$_FAIL_"; output 2 "$__FAIL__\n"; }
+output_failn() { output 1 "$_FAIL_\n"; output 2 "$__FAIL__\n"; }
 str_contains() { [ -n "$1" ] && [ -n "$2" ] && [ "${1//$2}" != "$1" ]; }
 str_contains_word() { echo "$1" | grep -q -w "$2"; }
 str_extras_to_underscore() { echo "$1" | tr '[\. ~`!@#$%^&*()\+/,<>?//;:]' '_'; }
@@ -142,13 +142,7 @@ quiet_mode() {
 }
 output() {
 # Target verbosity level with the first parameter being an integer
-       is_integer() {
-               case "$1" in
-                       (*[!0123456789]*) return 1;;
-                       ('')              return 1;;
-                       (*)               return 0;;
-               esac
-       }
+       is_integer() { case "$1" in ''|*[!0-9]*) return 1;; esac; }
        local msg memmsg logmsg text
        local sharedMemoryOutput="/dev/shm/$packageName-output"
        if [ -z "$verbosity" ] && [ -n "$packageName" ]; then
@@ -195,89 +189,12 @@ pbr_get_gateway6() {
        eval "$1"='$gw'
 }
 filter_options() {
-       local opt="$1" value="$2"
-       local i _ret=
-
-       case "$opt" in
-               phys_dev)
-                       for i in $value; do
-                               if is_phys_dev "$i"; then
-                                       _ret="${_ret:+$_ret }$i"
-                               fi
-                       done
-               ;;
-               phys_dev_negative)
-                       for i in $value; do
-                               if is_negation "$i" && is_phys_dev "${i:1}"; then
-                                       _ret="${_ret:+$_ret }$i"
-                               fi
-                       done
-               ;;
-               mac_address)
-                       for i in $value; do
-                               if is_mac_address "$i"; then
-                                       _ret="${_ret:+$_ret }$i"
-                               fi
-                       done
-               ;;
-               mac_address_negative)
-                       for i in $value; do
-                               if is_negation "$i" && is_mac_address "${i:1}"; then
-                                       _ret="${_ret:+$_ret }$i"
-                               fi
-                       done
-               ;;
-               domain)
-                       for i in $value; do
-                               if is_domain "$i"; then
-                                       _ret="${_ret:+$_ret }$i"
-                               fi
-                       done
-               ;;
-               domain_negative)
-                       for i in $value; do
-                               if is_negation "$i" && is_domain "${i:1}"; then
-                                       _ret="${_ret:+$_ret }$i"
-                               fi
-                       done
-               ;;
-               ipv4)
-                       for i in $value; do
-                               if is_ipv4 "$i" || is_ipv4_netmask "$i"; then
-                                       _ret="${_ret:+$_ret }$i"
-                               fi
-                       done
-               ;;
-               ipv4_negative)
-                       for i in $value; do
-                               if is_negation "$i" && { is_ipv4 "${i:1}" || is_ipv4_netmask "${i:1}"; }; then
-                                       _ret="${_ret:+$_ret }$i"
-                               fi
-                       done
-               ;;
-               ipv6)
-                       for i in $value; do
-                               if is_ipv6 "$i"; then
-                                       _ret="${_ret:+$_ret }$i"
-                               fi
-                       done
-               ;;
-               ipv6_negative)
-                       for i in $value; do
-                               if is_negation "$i" && is_ipv6 "${i:1}"; then
-                                       _ret="${_ret:+$_ret }$i"
-                               fi
-                       done
-               ;;
-               none)
-                       :
-               ;;
-               *)
-                       echo ''
-                       return 1
-               ;;
-       esac
-
+       local opt="$1" values="$2" v _ret
+       for v in $values; do
+               str_contains "$opt" _negative && { is_negation "$v" || continue; }
+               eval "is_$opt" "${v#!}" || continue
+               _ret="${_ret:+$_ret }$v"
+       done
        echo "$_ret"
        return 0
 }
@@ -291,7 +208,7 @@ inline_set() {
        echo "$inline_set"
 }
 # shellcheck disable=SC2016
-is_bad_user_file_nft_call() { grep -q '"\$nft" list' "$1" || grep '"\$nft" -f' "$1";}
+is_bad_user_file_nft_call() { grep -q '"\$nft" list' "$1" || grep '"\$nft" -f' "$1"; }
 is_config_enabled() {
 # shellcheck disable=SC2317
        _check_config() { local en; config_get_bool en "$1" 'enabled' '1'; [ "$en" -gt '0' ] && _cfg_enabled=0; }
@@ -306,27 +223,20 @@ uci_get_device() { uci_get 'network' "$1" 'device' || uci_get 'network' "$1" 'de
 uci_get_protocol() { uci_get 'network' "$1" 'proto'; }
 is_default_dev() { [ "$1" = "$(ip -4 r | grep -m1 'dev' | grep -Eso 'dev [^ ]*' | awk '{print $2}')" ]; }
 is_disabled_interface() { [ "$(uci_get 'network' "$1" 'disabled')" = '1' ]; }
-is_domain() { ! is_ipv6 "$1" && ! is_mac_address "$1" && ! is_phys_dev "$1" && str_contains "$1" '[a-zA-Z]'; }
+is_domain(){ echo "$1" | grep -qE '^([a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]\.)*[a-zA-Z]{2,}$'; }
 is_dslite() { local p; network_get_protocol p "$1"; [ "${p:0:6}" = "dslite" ]; }
-is_family_mismatch() { ( is_ipv4_netmask "${1//!}" && is_ipv6 "${2//!}" ) || ( is_ipv6 "${1//!}" && is_ipv4_netmask "${2//!}" ); }
+is_family_mismatch() { ( is_ipv4 "${1//!}" && is_ipv6 "${2//!}" ) || ( is_ipv6 "${1//!}" && is_ipv4 "${2//!}" ); }
 is_greater() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"; }
 is_greater_or_equal() { test "$(printf '%s\n' "$@" | sort -V | head -n '1')" = "$2"; }
 is_ignored_interface() { str_contains_word "$ignored_interface" "$1"; }
 is_ignore_target() { [ "$(str_to_lower "$1")" = 'ignore' ]; }
-is_integer() {
-       case "$1" in
-               (*[!0123456789]*) return 1;;
-               ('')              return 1;;
-               (*)               return 0;;
-       esac
-}
-is_ipv4() { expr "$1" : '[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' >/dev/null; }
+is_integer() { case "$1" in ''|*[!0-9]*) return 1;; esac; }
+is_ipv4() { expr "${1%/*}" : '[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' >/dev/null; }
 is_ipv6() { ! is_mac_address "$1" && str_contains "$1" ':'; }
 is_ipv6_global() { [ "${1:0:4}" = '2001' ]; }
 is_ipv6_link_local() { [ "${1:0:4}" = 'fe80' ]; }
 is_ipv6_unique_local() { [ "${1:0:2}" = 'fc' ] || [ "${1:0:2}" = 'fd' ]; }
 is_list() { str_contains "$1" ',' || str_contains "$1" ' '; }
-is_ipv4_netmask() { local ip="${1%/*}"; [ "$ip" != "$1" ] && is_ipv4 "$ip"; }
 is_lan() { local d; network_get_device d "$1"; str_contains "$procd_lan_interface" "$d"; }
 is_l2tp() { local p; network_get_protocol p "$1"; [ "${p:0:4}" = "l2tp" ]; }
 is_mac_address() { expr "$1" : '[0-9a-fA-F][0-9a-fA-F]:[0-9a-fA-F][0-9a-fA-F]:[0-9a-fA-F][0-9a-fA-F]:[0-9a-fA-F][0-9a-fA-F]:[0-9a-fA-F][0-9a-fA-F]:[0-9a-fA-F][0-9a-fA-F]$' >/dev/null; }
@@ -336,8 +246,7 @@ is_netifd_table_interface() { local iface="$1"; [ "$(uci_get 'network' "$iface"
 is_oc() { local p; network_get_protocol p "$1"; [ "${p:0:11}" = "openconnect" ]; }
 is_ovpn() { local d; uci_get_device d "$1"; [ "${d:0:3}" = "tun" ] || [ "${d:0:3}" = "tap" ] || [ -f "/sys/devices/virtual/net/${d}/tun_flags" ]; }
 is_ovpn_valid() { local dev_net dev_ovpn; uci_get_device dev_net "$1"; dev_ovpn="$(uci_get 'openvpn' "$1" 'dev')"; [ -n "$dev_net" ] && [ -n "$dev_ovpn" ] && [ "$dev_net" = "$dev_ovpn" ]; }
-is_phys_dev() { [ "${1:0:1}" = "@" ] && ip l show | grep -E -q "^\\d+\\W+${1:1}"; }
-is_phys_dev_quick() { [ "${1:0:1}" = "@" ]; }
+is_phys_dev(){ [ "${1:0:1}" = "@" ] && [ -L "/sys/class/net/${1#@}" ]; }
 is_present() { command -v "$1" >/dev/null 2>&1; }
 is_service_running() { is_service_running_nft; }
 is_service_running_nft() { [ -x "$nft" ] && [ -n "$(get_mark_nft_chains)" ]; }
@@ -363,10 +272,10 @@ is_tor_running() {
 is_tunnel() { is_dslite "$1" || is_l2tp "$1" || is_oc "$1" || is_ovpn "$1" || is_pptp "$1" || is_softether "$1" || is_tailscale "$1" || is_tor "$1" || is_wg "$1"; }
 is_url() { is_url_file "$1" || is_url_dl "$1"; }
 is_url_dl() { is_url_ftp "$1" || is_url_http "$1" || is_url_https "$1"; }
-is_url_file() { [ "$1" != "${1#file://}" ];}
-is_url_ftp() { [ "$1" != "${1#ftp://}" ];}
-is_url_http() { [ "$1" != "${1#http://}" ];}
-is_url_https() { [ "$1" != "${1#https://}" ];}
+is_url_file() { [ "$1" != "${1#file://}" ]; }
+is_url_ftp() { [ "$1" != "${1#ftp://}" ]; }
+is_url_http() { [ "$1" != "${1#http://}" ]; }
+is_url_https() { [ "$1" != "${1#https://}" ]; }
 is_wan() { [ "$1" = "$wanIface4" ] || { [ "${1##wan}" != "$1" ] && [ "${1##wan6}" = "$1" ]; } || [ "${1%%wan}" != "$1" ]; }
 is_wan6() { [ -n "$wanIface6" ] && [ "$1" = "$wanIface6" ] || [ "${1/#wan6}" != "$1" ] || [ "${1/%wan6}" != "$1" ]; }
 is_wg() { local p lp; network_get_protocol p "$1"; uci_get_listen_port lp "$1"; [ -z "$lp" ] && [ "${p:0:9}" = "wireguard" ]; }
@@ -400,12 +309,6 @@ __ubus_get() { ubus call service list "{ 'name': '$packageName' }" | jsonfilter
 ubus_get_status() { __ubus_get "@.${packageName}.instances.main.data.status.${1}"; }
 ubus_get_interface() { __ubus_get "@.${packageName}.instances.main.data.gateways[@.name='${1}']${2:+.$2}"; }
 ubus_get_gateways() { __ubus_get "@.${packageName}.instances.main.data.gateways"; }
-uci_get_device() {
-       local __tmp
-       __tmp="$(uci_get 'network' "$2" 'device')"
-       [ -z "$__tmp" ] && unset "$1" && return 1
-       eval "$1=$__tmp"
-}
 uci_get_listen_port() {
        local __tmp
        __tmp="$(uci_get 'network' "$2" 'listen_port')"
@@ -510,6 +413,7 @@ get_text() {
                warningOutdatedWebUIApp) r="The WebUI application is outdated (version %s), please update it.";;
                warningBadNftCallsInUserFile) r="Incompatible nft calls detected in user include file, disabling fw4 nft file support.";;
                warningDnsmasqInstanceNoConfdir) r="Dnsmasq instance '%s' targeted in settings, but it doesn't have its own confdir.";;
+               warningDhcpLanForce) r="Please set 'dhcp.lan.force=1' to speed up service start-up.";;
        esac
        echo "$r"
 }
@@ -625,53 +529,67 @@ load_package_config() {
 
 load_environment() {
        _system_health_check() {
-               local i
+               local i _ret=0
+               if [ "$(uci_get 'firewall' 'defaults' 'auto_includes')" = '0' ]; then
+                       uci_remove 'firewall' 'defaults' 'auto_includes'
+                       uci_commit firewall
+               fi
+               if [ "$(uci_get dhcp lan force 0)" = '0' ]; then
+                       state add 'warningSummary' 'warningDhcpLanForce'
+               fi
                # TODO: implement ip-full check
                # state add 'errorSummary' 'errorRequiredBinaryMissing' 'ip-full'
                if ! nft_call list table inet fw4; then
                        state add 'errorSummary' 'errorDefaultFw4TableMissing' 'fw4'
-                       return 1
+                       _ret='1'
                fi
                if is_config_enabled 'dns_policy' || is_tor_running; then
                        if ! nft_call list chain inet fw4 dstnat; then
                                state add 'errorSummary' 'errorDefaultFw4ChainMissing' 'dstnat'
-                               return 1
+                               _ret='1'
                        fi
                fi
                for i in $chainsList; do
                        if ! nft_call list chain inet fw4 "mangle_${i}"; then
                                state add 'errorSummary' 'errorDefaultFw4ChainMissing' "mangle_${i}"
-                               return 1
+                               _ret='1'
                        fi
                done
-               return 0
+               return "$_ret"
        }
        local param="$1" validation_result="$2"
-       load_package_config "$param"
        case "$param" in
                on_start)
+                       output 1 "Loading environment ($param) "
+                       load_package_config "$param"
                        if [ "$enabled" -eq '0' ]; then
+                               output 1 "$_FAIL_\n"
                                state add 'errorSummary' 'errorServiceDisabled'
                                return 1
                        fi
                        if [ -n "$validation_result" ] && [ "$validation_result" != '0' ]; then
-                               output "${_ERROR_}: The $packageName config validation failed!\\n"
-                               output "Please check if the '$packageConfigFile' contains correct values for config options.\\n"
+                               output 1 "$_FAIL_\n"
+                               output "${_ERROR_}: The $packageName config validation failed!\n"
+                               output "Please check if the '$packageConfigFile' contains correct values for config options.\n"
                                state add 'errorSummary' 'errorConfigValidation'
                                return 1
                        fi
-                       _system_health_check || return 1
-                       if [ "$(uci_get 'firewall' 'defaults' 'auto_includes')" = '0' ]; then
-                               uci_remove 'firewall' 'defaults' 'auto_includes'
-                               uci_commit firewall
-                       fi
+                       _system_health_check || { output 1 "$_FAIL_\n"; return 1; }
+                       resolver 'check_support' && resolver 'configure_instances'
+                       load_network "$param"
+                       output 1 "$_OK_\n"
                ;;
                on_stop)
-                       :
+                       output 1 "Loading environment ($param) "
+                       load_package_config "$param"
+                       load_network "$param"
+                       output 1 "$_OK_\n"
+               ;;
+               on_triggers|*)
+                       load_package_config "$param"
+                       load_network "$param"
                ;;
        esac
-       resolver 'check_support' && resolver 'configure_instances'
-       load_network "$param"
 }
 
 load_network() {
@@ -703,10 +621,10 @@ load_network() {
 
        case "$param" in
                on_boot|on_start)
-                       [ -n "$wanIface4" ] && output 2 "Using wan interface (${param}): $wanIface4 \\n"
-                       [ -n "$wanGW4" ] && output 2 "Found wan gateway (${param}): $wanGW4 \\n"
-                       [ -n "$wanIface6" ] && output 2 "Using wan6 interface (${param}): $wanIface6 \\n"
-                       [ -n "$wanGW6" ] && output 2 "Found wan6 gateway (${param}): $wanGW6 \\n"
+                       [ -n "$wanIface4" ] && output 2 "Using wan interface (${param}): $wanIface4 \n"
+                       [ -n "$wanGW4" ] && output 2 "Found wan gateway (${param}): $wanGW4 \n"
+                       [ -n "$wanIface6" ] && output 2 "Using wan6 interface (${param}): $wanIface6 \n"
+                       [ -n "$wanGW6" ] && output 2 "Found wan6 gateway (${param}): $wanGW6 \n"
                ;;
        esac
        wanGW="${wanGW4:-$wanGW6}"
@@ -714,17 +632,17 @@ load_network() {
 
 is_wan_up() {
        local sleepCount='1' param="$1"
-       [ "$procd_wan_ignore_status" -eq '0' ] || return 0
+       [ "$procd_wan_ignore_status" -eq '1' ] && return 0
        [ "$param" = 'on_boot' ] || procd_boot_timeout='1'
        if [ -z "$(uci_get network "$procd_wan_interface")" ]; then
                state add 'errorSummary' 'errorNoWanInterface' "$procd_wan_interface"
                state add 'errorSummary' 'errorNoWanInterfaceHint'
                return 1
        fi
-       while [ -z "$wanGW" ] ; do
+       while [ -z "$wanGW" ]; do
                load_network "$param"
                if [ "$((sleepCount))" -gt "$((procd_boot_timeout))" ] || [ -n "$wanGW" ]; then break; fi
-               output "$serviceName waiting for $procd_wan_interface gateway...\\n"
+               output "$serviceName waiting for $procd_wan_interface gateway...\n"
                sleep 1
                network_flush_cache
                sleepCount=$((sleepCount+1))
@@ -797,7 +715,7 @@ nftset() {
                        if is_mac_address "$param" || is_list "$param"; then
                                nft4 add element inet "$nftTable" "$nftset4" "{ $param }" && ipv4_error=0
                                nft6 add element inet "$nftTable" "$nftset6" "{ $param }" && ipv6_error=0
-                       elif is_ipv4_netmask "$param" || is_ipv4 "$param"; then
+                       elif is_ipv4 "$param"; then
                                nft4 add element inet "$nftTable" "$nftset4" "{ $param }" && ipv4_error=0
                        elif is_ipv6 "$param"; then
                                nft6 add element inet "$nftTable" "$nftset6" "{ $param }" && ipv6_error=0
@@ -825,23 +743,23 @@ nftset() {
                        case "$type" in
                                ip|net)
                                        nft4 add set inet "$nftTable" "$nftset4" "{ type ipv4_addr; $nft_set_params comment \"$comment\";}" && ipv4_error=0
-                                       nft6 add set inet "$nftTable" "$nftset6" "{ type ipv6_addr; $nft_set_params comment \"$comment\"; }" && ipv6_error=0
+                                       nft6 add set inet "$nftTable" "$nftset6" "{ type ipv6_addr; $nft_set_params comment \"$comment\";}" && ipv6_error=0
                                ;;
                                mac)
-                                       nft4 add set inet "$nftTable" "$nftset4" "{ type ether_addr; $nft_set_params comment \"$comment\"; }" && ipv4_error=0
-                                       nft6 add set inet "$nftTable" "$nftset6" "{ type ether_addr; $nft_set_params comment \"$comment\"; }" && ipv6_error=0
+                                       nft4 add set inet "$nftTable" "$nftset4" "{ type ether_addr; $nft_set_params comment \"$comment\";}" && ipv4_error=0
+                                       nft6 add set inet "$nftTable" "$nftset6" "{ type ether_addr; $nft_set_params comment \"$comment\";}" && ipv6_error=0
                                ;;
                                esac
                ;;
                create_dnsmasq_set)
-                       nft4 add set inet "$nftTable" "$nftset4" "{ type ipv4_addr; $nft_set_params comment \"$comment\"; }" && ipv4_error=0
-                       nft6 add set inet "$nftTable" "$nftset6" "{ type ipv6_addr; $nft_set_params comment \"$comment\"; }" && ipv6_error=0
+                       nft4 add set inet "$nftTable" "$nftset4" "{ type ipv4_addr; $nft_set_params comment \"$comment\";}" && ipv4_error=0
+                       nft6 add set inet "$nftTable" "$nftset6" "{ type ipv6_addr; $nft_set_params comment \"$comment\";}" && ipv6_error=0
                ;;
                create_user_set)
                        case "$type" in
                                ip|net)
-                                       nft4 add set inet "$nftTable" "$nftset4" "{ type ipv4_addr; $nft_set_params comment \"$comment\"; }" && ipv4_error=0
-                                       nft6 add set inet "$nftTable" "$nftset6" "{ type ipv6_addr; $nft_set_params comment \"$comment\"; }" && ipv6_error=0
+                                       nft4 add set inet "$nftTable" "$nftset4" "{ type ipv4_addr; $nft_set_params comment \"$comment\";}" && ipv4_error=0
+                                       nft6 add set inet "$nftTable" "$nftset6" "{ type ipv6_addr; $nft_set_params comment \"$comment\";}" && ipv6_error=0
                                        case "$target" in
                                                dst)
                                                        nft4 add rule inet "$nftTable" "${nftPrefix}_prerouting" "${nftIPv4Flag}" daddr "@${nftset4}" "${nft_rule_params}" goto "${nftPrefix}_mark_${mark}" && ipv4_error=0
@@ -986,10 +904,10 @@ EOF
                                        if str_contains "$line" ' '; then
                                                error_id="${line% *}"
                                                error_extra="${line#* }"
-                                               printf "%b $(get_text "$error_id")\\n" "$label" "$error_extra"
+                                               printf "%b $(get_text "$error_id")\n" "$label" "$error_extra"
                                        else
                                                error_id="$line"
-                                               printf "%b $(get_text "$error_id")\\n" "$label"
+                                               printf "%b $(get_text "$error_id")\n" "$label"
                                        fi
                                done <<EOF
 $(eval echo "\$$param" | tr \# \\n)
@@ -1210,7 +1128,7 @@ dns_policy_routing() {
                        fi
                        value="$src_addr"
                        first_value="$(str_first_word "$value")"
-                       if is_phys_dev_quick "$first_value"; then
+                       if is_phys_dev "$first_value"; then
                                param4="${param4:+$param4 }iifname ${negation:+$negation }{ $(inline_set "$value") }"
                                param6="${param6:+$param6 }iifname ${negation:+$negation }{ $(inline_set "$value") }"
                        elif is_mac_address "$first_value"; then
@@ -1344,7 +1262,7 @@ policy_routing() {
                                unset negation; value="$src_addr"; unset nftset_suffix;
                        fi
                        first_value_src="$(str_first_word "$value")"
-                       if is_phys_dev_quick "$first_value_src"; then
+                       if is_phys_dev "$first_value_src"; then
                                param4="${param4:+$param4 }iifname ${negation:+$negation }{ $(inline_set "$value") }"
                                param6="${param6:+$param6 }iifname ${negation:+$negation }{ $(inline_set "$value") }"
                        elif is_mac_address "$first_value_src"; then
@@ -1382,7 +1300,7 @@ policy_routing() {
                                unset negation; value="$dest_addr"; unset nftset_suffix;
                        fi
                        first_value_dest="$(str_first_word "$value")"
-                       if is_phys_dev_quick "$first_value_dest"; then
+                       if is_phys_dev "$first_value_dest"; then
                                param4="${param4:+$param4 }oifname ${negation:+$negation }{ $(inline_set "$value") }"
                                param6="${param6:+$param6 }oifname ${negation:+$negation }{ $(inline_set "$value") }"
                        elif is_domain "$first_value_dest"; then
@@ -1444,11 +1362,11 @@ policy_routing() {
                        chain='dstnat'
                        param4="$nftInsertOption rule inet $nftTable ${nftPrefix}_${chain} ${nft_rule_params} meta nfproto ipv4 $param4"
                        param6="$nftInsertOption rule inet $nftTable ${nftPrefix}_${chain} ${nft_rule_params} meta nfproto ipv6 $param6"
-                       dest_udp_53="udp dport 53 redirect to :${torDnsPort} comment 'Tor-DNS-UDP'"
-                       dest_tcp_80="tcp dport 80 redirect to :${torTrafficPort} comment 'Tor-HTTP-TCP'"
-                       dest_udp_80="udp dport 80 redirect to :${torTrafficPort} comment 'Tor-HTTP-UDP'"
-                       dest_tcp_443="tcp dport 443 redirect to :${torTrafficPort} comment 'Tor-HTTPS-TCP'"
-                       dest_udp_443="udp dport 443 redirect to :${torTrafficPort} comment 'Tor-HTTPS-UDP'"
+                       dest_udp_53="udp dport 53 redirect to :${torDnsPort} comment \"Tor-DNS-UDP\""
+                       dest_tcp_80="tcp dport 80 redirect to :${torTrafficPort} comment \"Tor-HTTP-TCP\""
+                       dest_udp_80="udp dport 80 redirect to :${torTrafficPort} comment \"Tor-HTTP-UDP\""
+                       dest_tcp_443="tcp dport 443 redirect to :${torTrafficPort} comment \"Tor-HTTPS-TCP\""
+                       dest_udp_443="udp dport 443 redirect to :${torTrafficPort} comment \"Tor-HTTPS-UDP\""
                        for dest_i in dest_udp_53 dest_tcp_80 dest_udp_80 dest_tcp_443 dest_udp_443; do
                                eval "dest4=\$$dest_i"
                                eval "dest6=\$$dest_i"
@@ -1689,10 +1607,10 @@ interface_routing() {
 EOF
 #                                      $(ip -4 route list table main proto static)
                                        try ip -4 rule add fwmark "${mark}/${fw_mask}" table "$tid" priority "$priority" || ipv4_error=1
-                                       try nft add chain inet "$nftTable" "${nftPrefix}_mark_${mark}" || ipv4_error=1 
-                                       try nft add rule inet "$nftTable" "${nftPrefix}_mark_${mark} ${nft_rule_params} mark set mark and ${fw_maskXor} xor ${mark}" || ipv4_error=1
-                                       try nft add rule inet "$nftTable" "${nftPrefix}_mark_${mark} return" || ipv4_error=1
                                fi
+                               try nft add chain inet "$nftTable" "${nftPrefix}_mark_${mark}" || ipv4_error=1 
+                               try nft add rule inet "$nftTable" "${nftPrefix}_mark_${mark} ${nft_rule_params} mark set mark and ${fw_maskXor} xor ${mark}" || ipv4_error=1
+                               try nft add rule inet "$nftTable" "${nftPrefix}_mark_${mark} return" || ipv4_error=1
                                if [ -n "$ipv6_enabled" ]; then
                                        ipv6_error=0
                                        ip -6 rule flush table "$tid" >/dev/null 2>&1
@@ -1714,8 +1632,8 @@ EOF
                                                        try ip -6 route add "$(ip -6 -o a show "$dev6" | awk '{print $4}')" dev "$dev6" table "$tid" >/dev/null 2>&1 || ipv6_error=1
                                                        try ip -6 route add default dev "$dev6" table "$tid" >/dev/null 2>&1 || ipv6_error=1
                                                fi
+                                               try ip -6 rule add fwmark "${mark}/${fw_mask}" table "$tid" priority "$((priority-1))" >/dev/null 2>&1 || ipv6_error=1
                                        fi
-                                       try ip -6 rule add fwmark "${mark}/${fw_mask}" table "$tid" priority "$((priority-1))" >/dev/null 2>&1 || ipv6_error=1
                                fi
                        fi
                        if [ "$ipv4_error" -eq '0' ] || [ "$ipv6_error" -eq '0' ]; then
@@ -1836,7 +1754,7 @@ process_interface() {
                                torDnsPort="$(get_tor_dns_port)"
                                torTrafficPort="$(get_tor_traffic_port)"
                                displayText="${iface}/53->${torDnsPort}/80,443->${torTrafficPort}"
-                               gatewaySummary="${gatewaySummary}${displayText}\\n"
+                               gatewaySummary="${gatewaySummary}${displayText}\n"
                                ;;
                        destroy)
                                ;;
@@ -1918,7 +1836,7 @@ process_interface() {
                        output 2 "Setting up routing for '$displayText' "
                        if interface_routing 'create' "$ifaceTableID" "$ifaceMark" "$iface" "$gw4" "$dev" "$gw6" "$dev6" "$ifacePriority"; then
                                json_add_gateway 'create' "$ifaceTableID" "$ifaceMark" "$iface" "$gw4" "$dev" "$gw6" "$dev6" "$ifacePriority" "$dispStatus"
-                               gatewaySummary="${gatewaySummary}${displayText}${dispStatus:+ $dispStatus}\\n"
+                               gatewaySummary="${gatewaySummary}${displayText}${dispStatus:+ $dispStatus}\n"
                                if is_netifd_table_interface "$iface"; then output_okb; else output_ok; fi
                        else
                                state add 'errorSummary' 'errorFailedSetup' "$displayText"
@@ -1974,7 +1892,7 @@ process_interface() {
                                [ "$verbosity" = '1' ] && dispStatus="$_OK_" || dispStatus="$__OK__"
                        fi
                        displayText="${iface}/${dispDev:+$dispDev/}${dispGw4}${ipv6_enabled:+/$dispGw6}"
-                       gatewaySummary="${gatewaySummary}${displayText}${dispStatus:+ $dispStatus}\\n"
+                       gatewaySummary="${gatewaySummary}${displayText}${dispStatus:+ $dispStatus}\n"
                ;;
                reload_interface)
                        ifaceTableID="$(get_rt_tables_id "$iface")"
@@ -1994,14 +1912,14 @@ process_interface() {
                                output 2 "Reloading routing for '$displayText' "
                                if interface_routing 'reload_interface' "$ifaceTableID" "$ifaceMark" "$iface" "$gw4" "$dev" "$gw6" "$dev6" "$ifacePriority"; then
                                        json_add_gateway 'reload_interface' "$ifaceTableID" "$ifaceMark" "$iface" "$gw4" "$dev" "$gw6" "$dev6" "$ifacePriority" "$dispStatus"
-                                       gatewaySummary="${gatewaySummary}${displayText}${dispStatus:+ $dispStatus}\\n"
+                                       gatewaySummary="${gatewaySummary}${displayText}${dispStatus:+ $dispStatus}\n"
                                        if is_netifd_table_interface "$iface"; then output_okb; else output_ok; fi
                                else
                                        state add 'errorSummary' 'errorFailedReload' "$displayText"
                                        output_fail
                                fi
                        else
-                               gatewaySummary="${gatewaySummary}${displayText}${dispStatus:+ $dispStatus}\\n"
+                               gatewaySummary="${gatewaySummary}${displayText}${dispStatus:+ $dispStatus}\n"
                        fi
                ;;
        esac
@@ -2080,7 +1998,7 @@ start_service() {
        local resolverStoredHash resolverNewHash i param="$1" reloadedIface
 
        load_environment "${param:-on_start}" "$(load_validate_config)" || return 1
-       is_wan_up "$param" || return 1
+#      is_wan_up "$param" || return 1
 
        process_interface 'all' 'prepare'
        config_foreach process_interface 'interface' 'pre_init'
@@ -2215,13 +2133,13 @@ service_started() {
        if nft_file 'exists'; then
                procd_set_config_changed firewall
                if nft_file 'exists'; then
-                       [ -n "$gatewaySummary" ] && output "$serviceName (fw4 nft file mode) started with gateways:\\n${gatewaySummary}"
+                       [ -n "$gatewaySummary" ] && output "$serviceName (fw4 nft file mode) started with gateways:\n${gatewaySummary}"
                else
                        output "$serviceName FAILED TO START in fw4 nft file mode!!!"
                        output "Check the output of nft -c -f $nftTempFile"
                fi
        else
-               [ -n "$gatewaySummary" ] && output "$serviceName (nft mode) started with gateways:\\n${gatewaySummary}"
+               [ -n "$gatewaySummary" ] && output "$serviceName (nft mode) started with gateways:\n${gatewaySummary}"
        fi
        state print 'errorSummary'
        state print 'warningSummary'
@@ -2254,28 +2172,31 @@ service_triggers() {
        procd_close_trigger
 #      procd_add_raw_trigger "interface.*.up" 4000 "/etc/init.d/${packageName}" restart 'on_interface_up'
        if [ "$serviceStartTrigger" = 'on_start' ]; then
-               output 3 "$serviceName monitoring interfaces: ${ifacesSupported}\\n"
+               output 3 "$serviceName monitoring interfaces: ${ifacesSupported}\n"
        fi
 }
 
+# shellcheck disable=SC2015
 stop_service() {
        local i nft_file_mode
-       load_environment 'on_stop'
        ! is_service_running && [ "$(get_rt_tables_next_id)" = "$(get_rt_tables_non_pbr_next_id)" ] && return 0
        [ "$1" = 'quiet' ] && quiet_mode 'on'
+       load_environment 'on_stop'
        if nft_file 'exists'; then
                nft_file_mode=1
        fi
-       nft_file 'delete'
-       cleanup_main_chains
-       cleanup_sets
-       cleanup_marking_chains
+       output 'Resetting chains and sets '
+       if nft_file 'delete' && cleanup_main_chains && cleanup_sets && cleanup_marking_chains; then
+               output_okn
+       else
+               output_failn
+       fi 
        output 1 'Resetting interfaces '
        config_load 'network'
        config_foreach process_interface 'interface' 'destroy'
        process_interface 'tor' 'destroy'
        cleanup_rt_tables
-       output 1 "\\n"
+       output 1 "\n"
        ip route flush cache
        unset ifaceMark
        unset ifaceTableID