From 148afbbeb55d7a6d2049a22dccf12eaa4940933b Mon Sep 17 00:00:00 2001 From: Stijn Tintel Date: Sun, 14 Aug 2022 00:52:24 +0300 Subject: [PATCH 01/39] vallumd: point PKG_SOURCE_URL to Codeberg The github repository has been archived; the project is now hosted on Codeberg. Update the PKG_SOURCE_URL accordingly. Gitea doesn't seem to add a version suffix to the directory in the tarball, so use a custom PKG_BUILD_DIR. Signed-off-by: Stijn Tintel --- net/vallumd/Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/vallumd/Makefile b/net/vallumd/Makefile index 5edc128a5..8a20fd74c 100644 --- a/net/vallumd/Makefile +++ b/net/vallumd/Makefile @@ -9,11 +9,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=vallumd PKG_VERSION:=0.2.0 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:=https://codeload.github.com/stintel/vallumd/tar.gz/$(PKG_VERSION)? -PKG_HASH:=7c1baffa3f7889c9c6f2795aac134c50a309ef201764d5ce6bbbce5d657416c0 +PKG_SOURCE_URL:=https://codeberg.org/stintel/vallumd/archive/$(PKG_VERSION).tar.gz? +PKG_HASH:=b4459e9bec2eab2b1a88ea1830333145033f0ddb7ae1c6ccae83560227ce8253 +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) PKG_MAINTAINER:=Stijn Tintel PKG_LICENSE:=GPL-3.0 From b40d47f259b19415a0542042adb7b99e40a959be Mon Sep 17 00:00:00 2001 From: Stijn Tintel Date: Fri, 18 Nov 2022 08:31:35 +0200 Subject: [PATCH 02/39] vallumd: bump to 0.2.1 Signed-off-by: Stijn Tintel --- net/vallumd/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/vallumd/Makefile b/net/vallumd/Makefile index 8a20fd74c..49341aa6c 100644 --- a/net/vallumd/Makefile +++ b/net/vallumd/Makefile @@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=vallumd -PKG_VERSION:=0.2.0 -PKG_RELEASE:=2 +PKG_VERSION:=0.2.1 +PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeberg.org/stintel/vallumd/archive/$(PKG_VERSION).tar.gz? -PKG_HASH:=b4459e9bec2eab2b1a88ea1830333145033f0ddb7ae1c6ccae83560227ce8253 +PKG_HASH:=eb48bf42295f1b33b2c0a5cf2ca18e8712ec42b95fc1e859e657b2bd56dec95e PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) PKG_MAINTAINER:=Stijn Tintel From 1136e0ac3ca4eacd2de0ca51db0a2e652e0f8cce Mon Sep 17 00:00:00 2001 From: Stijn Tintel Date: Fri, 18 Nov 2022 08:43:31 +0200 Subject: [PATCH 03/39] vallumd: bump to 0.2.2 Add upstream patch to fix building from source tarballs. Signed-off-by: Stijn Tintel --- net/vallumd/Makefile | 4 +- ...skip-git-magic-if-no-.git-dir-exists.patch | 78 +++++++++++++++++++ 2 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 net/vallumd/patches/001-CMake-skip-git-magic-if-no-.git-dir-exists.patch diff --git a/net/vallumd/Makefile b/net/vallumd/Makefile index 49341aa6c..75b2470da 100644 --- a/net/vallumd/Makefile +++ b/net/vallumd/Makefile @@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=vallumd -PKG_VERSION:=0.2.1 +PKG_VERSION:=0.2.2 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeberg.org/stintel/vallumd/archive/$(PKG_VERSION).tar.gz? -PKG_HASH:=eb48bf42295f1b33b2c0a5cf2ca18e8712ec42b95fc1e859e657b2bd56dec95e +PKG_HASH:=f88cafce41cc118862869268b5e6c9b315a6f084aa8a498d4484e9dac49c575c PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) PKG_MAINTAINER:=Stijn Tintel diff --git a/net/vallumd/patches/001-CMake-skip-git-magic-if-no-.git-dir-exists.patch b/net/vallumd/patches/001-CMake-skip-git-magic-if-no-.git-dir-exists.patch new file mode 100644 index 000000000..82a659dfb --- /dev/null +++ b/net/vallumd/patches/001-CMake-skip-git-magic-if-no-.git-dir-exists.patch @@ -0,0 +1,78 @@ +From b70137d0cc62be7f43816a3ba33b7c3e6a2fbd4e Mon Sep 17 00:00:00 2001 +From: Stijn Tintel +Date: Fri, 18 Nov 2022 09:19:02 +0200 +Subject: [PATCH] CMake: skip git magic if no .git dir exists + +The checks to fail CMake if git describe isn't working break build when +building from source tarballs. + +Test if there is a git directory, and completely skip the git magic if +not. + +Fixes: f42e7beec46e ("CI: add explicit clone to fetch tags") +Signed-off-by: Stijn Tintel +--- + CMakeLists.txt | 51 +++++++++++++++++++++++++------------------------- + 1 file changed, 26 insertions(+), 25 deletions(-) + +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -9,35 +9,36 @@ set (VERSION_MAJOR 0) + set (VERSION_MINOR 2) + set (VERSION_PATCH 2) + +-execute_process(COMMAND git describe --tags --dirty +- OUTPUT_VARIABLE GIT_DESCRIBE +- OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET) +-execute_process(COMMAND git describe --abbrev=0 +- OUTPUT_VARIABLE GIT_LAST_TAG +- OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET) ++if (EXISTS .git/) ++ execute_process(COMMAND git describe --tags --dirty ++ OUTPUT_VARIABLE GIT_DESCRIBE ++ OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET) ++ execute_process(COMMAND git describe --abbrev=0 ++ OUTPUT_VARIABLE GIT_LAST_TAG ++ OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET) + +-string(LENGTH "${GIT_DESCRIBE}" GIT_DESCRIBE_LEN) +-string(LENGTH "${GIT_LAST_TAG}" GIT_LAST_TAG_LEN) ++ string(LENGTH "${GIT_DESCRIBE}" GIT_DESCRIBE_LEN) ++ string(LENGTH "${GIT_LAST_TAG}" GIT_LAST_TAG_LEN) + +-if (GIT_DESCRIBE_LEN EQUAL 0 OR GIT_LAST_TAG_LEN EQUAL 0) +- message(FATAL_ERROR "git describe output empty") +-endif () ++ if (GIT_DESCRIBE_LEN EQUAL 0 OR GIT_LAST_TAG_LEN EQUAL 0) ++ message(FATAL_ERROR "git describe output empty") ++ endif () + +-string(REGEX REPLACE "^${GIT_LAST_TAG}-" "" GIT_DESCRIBE_NOTAG "${GIT_DESCRIBE}") ++ string(REGEX REPLACE "^${GIT_LAST_TAG}-" "" GIT_DESCRIBE_NOTAG "${GIT_DESCRIBE}") + +-if (NOT "${GIT_DESCRIBE}" STREQUAL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") +- if ("${GIT_LAST_TAG}" VERSION_LESS +- "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") +- string(REGEX REPLACE "^${GIT_LAST_TAG}-" +- "" VERSION_TWEAK "0-pre-${GIT_DESCRIBE_NOTAG}") +- else () +- string(REGEX REPLACE +- "^${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-" +- "" VERSION_TWEAK "${GIT_DESCRIBE}") ++ if (NOT "${GIT_DESCRIBE}" STREQUAL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") ++ if ("${GIT_LAST_TAG}" VERSION_LESS ++ "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") ++ string(REGEX REPLACE "^${GIT_LAST_TAG}-" ++ "" VERSION_TWEAK "0-pre-${GIT_DESCRIBE_NOTAG}") ++ else () ++ string(REGEX REPLACE ++ "^${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-" ++ "" VERSION_TWEAK "${GIT_DESCRIBE}") ++ endif () + endif () + endif () + +- + configure_file ( + "${PROJECT_SOURCE_DIR}/src/config.h.in" + "${PROJECT_BINARY_DIR}/config.h" From 8047d2ccb716ac90f267cc2ceb3723c15c375bd2 Mon Sep 17 00:00:00 2001 From: Stan Grishin Date: Tue, 29 Nov 2022 22:37:53 +0000 Subject: [PATCH 04/39] simple-adblock: localizable error/warning messages * store all error/warning messages with the error text id so that they can be made localizable for the luci app Signed-off-by: Stan Grishin --- net/simple-adblock/Makefile | 2 +- net/simple-adblock/files/simple-adblock.init | 180 +++++++++++-------- 2 files changed, 102 insertions(+), 80 deletions(-) diff --git a/net/simple-adblock/Makefile b/net/simple-adblock/Makefile index 6778f3a7b..d6fdd316f 100644 --- a/net/simple-adblock/Makefile +++ b/net/simple-adblock/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=simple-adblock PKG_VERSION:=1.9.3 -PKG_RELEASE:=2 +PKG_RELEASE:=3 PKG_MAINTAINER:=Stan Grishin PKG_LICENSE:=GPL-3.0-or-later diff --git a/net/simple-adblock/files/simple-adblock.init b/net/simple-adblock/files/simple-adblock.init index 7c9829d15..19a6b1fa2 100644 --- a/net/simple-adblock/files/simple-adblock.init +++ b/net/simple-adblock/files/simple-adblock.init @@ -100,49 +100,60 @@ uci_changes() { ipset() { "$ipset" "$@" >/dev/null 2>&1; } nft() { "$nft" "$@" >/dev/null 2>&1; } -get_status_text() { - local _ret +get_text() { + local r case "$1" in - statusNoInstall) _ret="$serviceName is not installed or not found";; - statusStopped) _ret="Stopped";; - statusStarting) _ret="Starting";; - statusRestarting) _ret="Restarting";; - statusForceReloading) _ret="Force Reloading";; - statusDownloading) _ret="Downloading";; - statusProcessing) _ret="Processing";; - statusError) _ret="Error";; - statusWarning) _ret="Warning";; - statusFail) _ret="Fail";; - statusSuccess) _ret="Success";; + errorConfigValidationFail) r="$packageName config validation failed";; + errorServiceDisabled) r="$packageName is currently disabled";; + errorNoDnsmasqIpset) + r="dnsmasq ipset support is enabled in $packageName, but dnsmasq is either not installed or installed dnsmasq does not support ipset";; + errorNoIpset) + r="dnsmasq ipset support is enabled in $packageName, but ipset is either not installed or installed ipset does not support 'hash:net' type";; + errorNoDnsmasqNftset) + r="dnsmasq nft set support is enabled in $packageName, but dnsmasq is either not installed or installed dnsmasq does not support nft set";; + errorNoNft) r="dnsmasq nft sets support is enabled in $packageName, but nft is not installed";; + errorMkdirFail) r="Unable to create directory for";; + errorNoWanGateway) r="The ${serviceName} service failed to discover WAN gateway!";; + errorOutputDirCreate) r="failed to create directory for %s file";; + errorOutputFileCreate) r="failed to create $outputFile file";; + errorFailDNSReload) r="failed to restart/reload DNS resolver";; + errorSharedMemory) r="failed to access shared memory";; + errorSorting) r="failed to sort data file";; + errorOptimization) r="failed to optimize data file";; + errorAllowListProcessing) r="failed to process allow-list";; + errorDataFileFormatting) r="failed to format data file";; + errorMovingDataFile) r="failed to move data file '${A_TMP}' to '${outputFile}'";; + errorCreatingCompressedCache) r="failed to create compressed cache";; + errorRemovingTempFiles) r="failed to remove temporary files";; + errorRestoreCompressedCache) r="failed to unpack compressed cache";; + errorRestoreCache) r="failed to move '$outputCache' to '$outputFile'";; + errorOhSnap) r="failed to create block-list or restart DNS resolver";; + errorStopping) r="failed to stop $serviceName";; + errorDNSReload) r="failed to reload/restart DNS resolver";; + errorDownloadingConfigUpdate) r="failed to download Config Update file";; + errorDownloadingList) r="failed to download";; + errorParsingConfigUpdate) r="failed to parse Config Update file";; + errorParsingList) r="failed to parse";; + errorNoSSLSupport) r="no HTTPS/SSL support on device";; + errorCreatingDirectory) r="failed to create output/cache/gzip file directory";; + + statusNoInstall) r="$serviceName is not installed or not found";; + statusStopped) r="Stopped";; + statusStarting) r="Starting";; + statusRestarting) r="Restarting";; + statusForceReloading) r="Force Reloading";; + statusDownloading) r="Downloading";; + statusProcessing) r="Processing";; + statusError) r="Error";; + statusWarning) r="Warning";; + statusFail) r="Fail";; + statusSuccess) r="Success";; + + warningExternalDnsmasqConfig) + r="use of external dnsmasq config file detected, please set 'dns' option to 'dnsmasq.conf'";; + warningMissingRecommendedPackages) r="Some recommended packages are missing";; esac - printf "%b" "$_ret" -} -get_error_text() { - local _ret - case "$1" in - errorOutputFileCreate) _ret="failed to create $outputFile file";; - errorFailDNSReload) _ret="failed to restart/reload DNS resolver";; - errorSharedMemory) _ret="failed to access shared memory";; - errorSorting) _ret="failed to sort data file";; - errorOptimization) _ret="failed to optimize data file";; - errorAllowListProcessing) _ret="failed to process allow-list";; - errorDataFileFormatting) _ret="failed to format data file";; - errorMovingDataFile) _ret="failed to move data file '${A_TMP}' to '${outputFile}'";; - errorCreatingCompressedCache) _ret="failed to create compressed cache";; - errorRemovingTempFiles) _ret="failed to remove temporary files";; - errorRestoreCompressedCache) _ret="failed to unpack compressed cache";; - errorRestoreCache) _ret="failed to move '$outputCache' to '$outputFile'";; - errorOhSnap) _ret="failed to create block-list or restart DNS resolver";; - errorStopping) _ret="failed to stop $serviceName";; - errorDNSReload) _ret="failed to reload/restart DNS resolver";; - errorDownloadingConfigUpdate) _ret="failed to download Config Update file";; - errorDownloadingList) _ret="failed to download";; - errorParsingConfigUpdate) _ret="failed to parse Config Update file";; - errorParsingList) _ret="failed to parse";; - errorNoSSLSupport) _ret="no HTTPS/SSL support on device";; - errorCreatingDirectory) _ret="failed to create output/cache/gzip file directory";; - esac - printf "%b" "$_ret" + echo "$r" } output_ok() { output 1 "$_OK_"; output 2 "$__OK__\\n"; } @@ -187,13 +198,15 @@ load_environment() { local validation_result="$1" quiet="$2" if [ "$validation_result" != '0' ]; then - output "${_ERROR_}: $packageName config validation failed!\\n" + json add error "errorConfigValidationFail" + output "${_ERROR_}: $(get_text 'errorConfigValidationFail')!\\n" output "Please check if the '$packageConfigFile' contains correct values for config options.\\n" return 1 fi if [ "$enabled" -eq 0 ]; then - output "$packageName is currently disabled.\\n" + json add error "errorServiceDisabled" + output "${_ERROR_}: $(get_text 'errorServiceDisabled')!\\n" output "Run the following commands before starting service again:\\n" output "uci set ${packageName}.config.enabled='1'; uci commit $packageName;\\n" return 1 @@ -210,7 +223,8 @@ load_environment() { dnsmasq.conf) :;; *) if [ -z "$quiet" ]; then - output "$_WARNING_: use of external dnsmasq config file detected, please set 'dns' option to 'dnsmasq.conf'!\\n" + json add warning "warningExternalDnsmasqConfig" + output "${_WARNING_}: $(get_text 'warningExternalDnsmasqConfig')!\\n" fi ;; esac @@ -230,13 +244,15 @@ load_environment() { dnsmasq.ipset) if dnsmasq -v 2>/dev/null | grep -q 'no-ipset' || ! dnsmasq -v 2>/dev/null | grep -q -w 'ipset'; then if [ -z "$quiet" ]; then - output "$_ERROR_: dnsmasq ipset support is enabled in $packageName, but dnsmasq is either not installed or installed dnsmasq does not support ipset!\\n" + json add error "errorNoDnsmasqIpset" + output "${_ERROR_}: $(get_text 'errorNoDnsmasqIpset')!\\n" fi dns='dnsmasq.servers' fi if ! ipset help hash:net; then if [ -z "$quiet" ]; then - output "$_ERROR_: dnsmasq ipset support is enabled in $packageName, but ipset is either not installed or installed ipset does not support 'hash:net' type!\\n" + json add error "errorNoIpset" + output "${_ERROR_}: $(get_text 'errorNoIpset')!\\n" fi dns='dnsmasq.servers' fi @@ -244,13 +260,15 @@ load_environment() { dnsmasq.nftset) if dnsmasq -v 2>/dev/null | grep -q 'no-nftset' || ! dnsmasq -v 2>/dev/null | grep -q -w 'nftset'; then if [ -z "$quiet" ]; then - output "$_ERROR_: dnsmasq nft sets support is enabled in $packageName, but dnsmasq is either not installed or installed dnsmasq does not support nft sets!\\n" + json add error "errorNoDnsmasqNftset" + output "${_ERROR_}: $(get_text 'errorNoDnsmasqNftset')!\\n" fi dns='dnsmasq.servers' fi if [ -z "$nft" ]; then if [ -z "$quiet" ]; then - output "$_ERROR_: dnsmasq nft sets support is enabled in $packageName, but nft is not installed!\\n" + json add error "errorNoNft" + output "${_ERROR_}: $(get_text 'errorNoNft')!\\n" fi dns='dnsmasq.servers' fi @@ -335,8 +353,8 @@ load_environment() { for i in "$outputFile" "$outputCache" "$outputGzip"; do if ! mkdir -p "$(dirname "$i")"; then - output "$_ERROR_: Unable to create directory for $i!\\n" - json add error "errorOutputFileCreate" + json add error "errorOutputDirCreate" "$i" + output "${_ERROR_}: $(get_text 'errorMkdirFail' "$i")!\\n" fi done @@ -352,7 +370,8 @@ load_environment() { is_present '/usr/libexec/sed-gnu' || s="$s sed" is_present '/usr/libexec/sort-coreutils' || s="$s coreutils-sort" if [ -z "$quiet" ]; then - output "$_WARNING_: Some recommended packages are missing, install them by running:\\n" + json add warning "errorOutputFileCreate" "${i}" + output "${_WARNING_}: $(get_text 'warningMissingRecommendedPackages'), install them by running:\\n" output "$s;\\n" fi fi @@ -390,7 +409,8 @@ load_environment() { cache 'test_gzip' && return 0 network_flush_cache; network_find_wan wan_if; network_get_gateway wan_gw "$wan_if"; [ -n "$wan_gw" ] && return 0 - output "$_ERROR_: $serviceName failed to discover WAN gateway.\\n"; return 1; + json add error "errorNoWanGateway" + output "${_ERROR_}: $(get_text 'errorNoWanGateway')!\\n"; return 1; } resolver() { @@ -424,7 +444,7 @@ dns() { if [ ! -s "$outputFile" ]; then json set status "statusFail" json add error "errorOutputFileCreate" - output "$_ERROR_: $(get_error_text 'errorOutputFileCreate')!\\n" + output "${_ERROR_}: $(get_text 'errorOutputFileCreate')!\\n" return 1 fi @@ -473,7 +493,7 @@ dns() { output_fail json set status "statusFail" json add error "errorDNSReload" - output "$_ERROR_: $(get_error_text 'errorDNSReload')!\\n" + output "${_ERROR_}: $(get_text 'errorDNSReload')!\\n" return 1 fi ;; @@ -518,6 +538,9 @@ dns() { json() { # shellcheck disable=SC2034 local action="$1" param="$2" value="$3" + shift 3 +# shellcheck disable=SC2124 + local extras="$@" line local status message error stats local reload restart curReload curRestart ret i if [ -s "$jsonFile" ]; then @@ -549,10 +572,8 @@ json() { esac ;; add) - if [ -n "$(eval echo "\$$param")" ]; then - value="$(eval echo "\$$param") ${value}" - fi - eval "$param"='${value}' + line="$(eval echo "\$$param")" + eval "$param"='${line:+$line }${value}${extras:+|$extras}' ;; del) case "$param" in @@ -573,7 +594,7 @@ json() { restart="$compressed_cache $force_dns $led $force_dns_port" ;; *) - eval "$param"='$value';; + eval "$param"='${value}${extras:+|$extras}';; esac ;; esac @@ -678,7 +699,7 @@ process_url() { download_dnsmasq_file() { local hf allow_filter j=0 R_TMP - json set message "$(get_status_text "statusDownloading")..." + json set message "$(get_text "statusDownloading")..." json set status "statusDownloading" rm -f "$A_TMP" "$B_TMP" "$outputFile" "$outputCache" "$outputGzip" @@ -714,7 +735,7 @@ download_dnsmasq_file() { download_lists() { local hf allow_filter j=0 R_TMP - json set message "$(get_status_text "statusDownloading")..." + json set message "$(get_text "statusDownloading")..." json set status "statusDownloading" rm -f "$A_TMP" "$B_TMP" "$outputFile" "$outputCache" "$outputGzip" @@ -775,7 +796,8 @@ $(cat $A_TMP)" output 1 'Processing downloads ' output 2 'Sorting combined list ' - json set message "$(get_status_text "statusProcessing"): sorting combined list" + json set status "statusProcessing" + json set message "$(get_text "statusProcessing"): sorting combined list" if [ "$allow_non_ascii" -gt 0 ]; then if sort -u "$B_TMP" > "$A_TMP"; then output_ok @@ -799,7 +821,7 @@ $(cat $A_TMP)" [ "$dns" = 'unbound.adb_list' ]; then # TLD optimization written by Dirk Brenken (dev@brenken.org) output 2 'Optimizing combined list ' - json set message "$(get_status_text "statusProcessing"): optimizing combined list" + json set message "$(get_text "statusProcessing"): optimizing combined list" # sed -E 'G;:t;s/(.*)(\.)(.*)(\n)(.*)/\1\4\5\2\3/;tt;s/(.*)\n(\.)(.*)/\3\2\1/' is actually slower than command below if $awk -F "." '{for(f=NF;f>1;f--)printf "%s.",$f;print $1}' "$A_TMP" > "$B_TMP"; then if sort "$B_TMP" > "$A_TMP"; then @@ -835,7 +857,7 @@ $(cat $A_TMP)" fi output 2 'Allowing domains ' - json set message "$(get_status_text "statusProcessing"): allowing domains" + json set message "$(get_text "statusProcessing"): allowing domains" if sed -i -E "$allow_filter" "$B_TMP"; then output_ok else @@ -844,7 +866,7 @@ $(cat $A_TMP)" fi output 2 'Formatting merged file ' - json set message "$(get_status_text "statusProcessing"): formatting merged file" + json set message "$(get_text "statusProcessing"): formatting merged file" if [ -z "$outputFilterIPv6" ]; then if sed "$outputFilter" "$B_TMP" > "$A_TMP"; then output_ok @@ -869,27 +891,27 @@ $(cat $A_TMP)" case "$dns" in dnsmasq.addnhosts) output 2 'Creating dnsmasq addnhosts file ' - json set message "$(get_status_text "statusProcessing"): creating dnsmasq addnhosts file" + json set message "$(get_text "statusProcessing"): creating dnsmasq addnhosts file" ;; dnsmasq.conf) output 2 'Creating dnsmasq config file ' - json set message "$(get_status_text "statusProcessing"): creating dnsmasq config file" + json set message "$(get_text "statusProcessing"): creating dnsmasq config file" ;; dnsmasq.ipset) output 2 'Creating dnsmasq ipset file ' - json set message "$(get_status_text "statusProcessing"): creating dnsmasq ipset file" + json set message "$(get_text "statusProcessing"): creating dnsmasq ipset file" ;; dnsmasq.nftset) output 2 'Creating dnsmasq nft set file ' - json set message "$(get_status_text "statusProcessing"): creating dnsmasq nft set file" + json set message "$(get_text "statusProcessing"): creating dnsmasq nft set file" ;; dnsmasq.servers) output 2 'Creating dnsmasq servers file ' - json set message "$(get_status_text "statusProcessing"): creating dnsmasq servers file" + json set message "$(get_text "statusProcessing"): creating dnsmasq servers file" ;; unbound.adb_list) output 2 'Creating Unbound adb_list file ' - json set message "$(get_status_text "statusProcessing"): creating Unbound adb_list file" + json set message "$(get_text "statusProcessing"): creating Unbound adb_list file" ;; esac @@ -901,7 +923,7 @@ $(cat $A_TMP)" fi if [ "$compressed_cache" -gt 0 ]; then output 2 'Creating compressed cache ' - json set message "$(get_status_text "statusProcessing"): creating compressed cache" + json set message "$(get_text "statusProcessing"): creating compressed cache" if cache 'create_gzip'; then output_ok else @@ -912,7 +934,7 @@ $(cat $A_TMP)" rm -f "$outputGzip" fi output 2 'Removing temporary files ' - json set message "$(get_status_text "statusProcessing"): removing temporary files" + json set message "$(get_text "statusProcessing"): removing temporary files" rm -f "/tmp/${packageName}_tmp.*" "$A_TMP" "$B_TMP" "$outputCache" || j=1 if [ $j -eq 0 ]; then output_ok @@ -1183,7 +1205,7 @@ adb_start() { else output_failn json add error "errorRestoreCompressedCache" - output "$_ERROR_: $(get_error_text 'errorRestoreCompressedCache')!\\n" + output "${_ERROR_}: $(get_text 'errorRestoreCompressedCache')!\\n" action='download' fi fi @@ -1196,7 +1218,7 @@ adb_start() { else output_failn json add error "errorRestoreCache" - output "$_ERROR_: $(get_error_text 'errorRestoreCache')!\\n" + output "${_ERROR_}: $(get_text 'errorRestoreCache')!\\n" action='download' fi fi @@ -1342,7 +1364,7 @@ adb_status() { if [ "$status" = "statusSuccess" ]; then output "$stats "; output_okn; else - [ -n "$status" ] && status="$(get_status_text "$status")" + [ -n "$status" ] && status="$(get_text "$status")" if [ -n "$status" ] && [ -n "$message" ]; then status="${status}: $message" fi @@ -1354,9 +1376,9 @@ adb_status() { c="${c%|*}" case "$c" in errorDownloadingList|errorParsingList) - output "$_ERROR_: $(get_error_text "$c") $url!\\n";; + output "${_ERROR_}: $(get_text "$c") $url!\\n";; *) - output "$_ERROR_: $(get_error_text "$c")!\\n";; + output "${_ERROR_}: $(get_text "$c")!\\n";; esac n=$((n+1)) done @@ -1382,7 +1404,7 @@ adb_stop() { output 0 "$__FAIL__\\n"; output_fail; json set status "statusFail" json add error "errorStopping" - output "$_ERROR_: $(get_error_text 'errorStopping')!\\n" + output "${_ERROR_}: $(get_text 'errorStopping')!\\n" fi fi } From f6e1fc8d8fca94e04bb65fbd4a5080fde4900047 Mon Sep 17 00:00:00 2001 From: Lucian Cristian Date: Fri, 2 Dec 2022 10:20:10 +0000 Subject: [PATCH 05/39] frr: update to 8.4.1 Signed-off-by: Lucian Cristian --- net/frr/Makefile | 10 +++++----- net/frr/patches/997-reverse_python_test.patch | 2 +- net/frr/patches/999-thread_reverse.patch | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/net/frr/Makefile b/net/frr/Makefile index ba659b7c5..c65c59cb8 100644 --- a/net/frr/Makefile +++ b/net/frr/Makefile @@ -7,16 +7,16 @@ include $(TOPDIR)/rules.mk PKG_NAME:=frr -PKG_VERSION:=8.3.1 -PKG_RELEASE:=$(AUTORELEASE) -PKG_SOURCE_DATE:=2022-10-14 +PKG_VERSION:=8.4.1 +PKG_RELEASE:=1 +PKG_SOURCE_DATE:=2022-11-29 PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_DATE).tar.gz -PKG_SOURCE_VERSION:=b9cb689f3c4b78fb047216ed41d8c79424b1774f +PKG_SOURCE_VERSION:=7d7b33a0281b233757606bb1fa4e9c056c57084f PKG_SOURCE_URL:=https://codeload.github.com/FRRouting/frr/tar.gz/$(PKG_SOURCE_VERSION)? -PKG_HASH:=bc4aa020f3725c499093ea3c98f9c21160fc1ae06439a698f39f6a9c55c2825a +PKG_HASH:=9899f2c6ecb6cce5bf7d56ddb9fc137dd8388f7201a52595c93d33572092fcaf PKG_MAINTAINER:=Lucian Cristian PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_SOURCE_VERSION) diff --git a/net/frr/patches/997-reverse_python_test.patch b/net/frr/patches/997-reverse_python_test.patch index 96ef9e2bc..04a2884c0 100644 --- a/net/frr/patches/997-reverse_python_test.patch +++ b/net/frr/patches/997-reverse_python_test.patch @@ -1,6 +1,6 @@ --- a/configure.ac +++ b/configure.ac -@@ -833,7 +833,6 @@ fi +@@ -835,7 +835,6 @@ fi # AS_IF([test "$host" = "$build"], [ diff --git a/net/frr/patches/999-thread_reverse.patch b/net/frr/patches/999-thread_reverse.patch index 740c83745..e7bf99e38 100644 --- a/net/frr/patches/999-thread_reverse.patch +++ b/net/frr/patches/999-thread_reverse.patch @@ -1,6 +1,6 @@ --- a/lib/thread.c +++ b/lib/thread.c -@@ -867,13 +867,9 @@ static void thread_free(struct thread_ma +@@ -870,13 +870,9 @@ static void thread_free(struct thread_ma XFREE(MTYPE_THREAD, thread); } @@ -16,7 +16,7 @@ /* * If timer_wait is null here, that means poll() should block * indefinitely, unless the thread_master has overridden it by setting -@@ -904,58 +900,15 @@ static int fd_poll(struct thread_master +@@ -907,58 +903,15 @@ static int fd_poll(struct thread_master rcu_assert_read_unlocked(); /* add poll pipe poker */ @@ -82,7 +82,7 @@ while (read(m->io_pipe[0], &trash, sizeof(trash)) > 0) ; -@@ -1762,7 +1715,7 @@ struct thread *thread_fetch(struct threa +@@ -1768,7 +1721,7 @@ struct thread *thread_fetch(struct threa struct timeval zerotime = {0, 0}; struct timeval tv; struct timeval *tw = NULL; @@ -91,7 +91,7 @@ int num = 0; do { -@@ -1838,14 +1791,14 @@ struct thread *thread_fetch(struct threa +@@ -1844,14 +1797,14 @@ struct thread *thread_fetch(struct threa pthread_mutex_unlock(&m->mtx); { From 318e48c6f953fd078dd7a054eea0391d5b4ee245 Mon Sep 17 00:00:00 2001 From: Rudy Andram Date: Thu, 1 Dec 2022 06:01:33 +0000 Subject: [PATCH 06/39] stubby: bump to latest 0.4.2 Maintainer: @neheb (find it by checking history of the package Makefile) Compile tested: aarch64/ipq8074 Run tested: aarch64/ipq8074 Description: stubby: bump to latest 0.4.2 Signed-off-by: Rudy Andram --- net/stubby/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/stubby/Makefile b/net/stubby/Makefile index 77f8d8770..bb0b2be54 100644 --- a/net/stubby/Makefile +++ b/net/stubby/Makefile @@ -5,13 +5,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=stubby -PKG_VERSION:=0.4.0 -PKG_RELEASE:=6 +PKG_VERSION:=0.4.2 +PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/getdnsapi/$(PKG_NAME) PKG_SOURCE_VERSION:=v$(PKG_VERSION) -PKG_MIRROR_HASH:=bc5f604da1b70287a6c3d89eac2e13ce8bca52840e7b72ab098a3deeb9935082 +PKG_MIRROR_HASH:=0a40e3eec2ef86a83977b69f03bc63f232fe52ca15703273a0d097e64fa3bf05 PKG_MAINTAINER:= PKG_LICENSE:=BSD-3-Clause From 75ff4ba358aa0357f0af62cb980568bdc8d390a1 Mon Sep 17 00:00:00 2001 From: Paul Spooren Date: Thu, 1 Dec 2022 21:02:10 +0100 Subject: [PATCH 07/39] ci: only comment AUTORELEASE deprecation if exists If it doesn't exists, don't confuse the contributors. Signed-off-by: Paul Spooren --- .github/workflows/check-autorelease-deprecation.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/check-autorelease-deprecation.yml b/.github/workflows/check-autorelease-deprecation.yml index c19911bfa..b85b3243f 100644 --- a/.github/workflows/check-autorelease-deprecation.yml +++ b/.github/workflows/check-autorelease-deprecation.yml @@ -28,6 +28,8 @@ jobs: - name: Determine changed packages run: | + RET=0 + # only detect packages with changes PKG_ROOTS=$(find . -name Makefile | \ grep -v ".*/src/Makefile" | \ @@ -46,14 +48,13 @@ jobs: done if [ -n "$CONTAINS_AUTORELEASE" ]; then + RET=1 cat > "$GITHUB_WORKSPACE/pr_comment.md" << EOF Please do no longer set *PKG_RELEASE* to *AUTORELEASE* as the feature is deprecated. Please use an integer instead. Below is a list of affected packages including correct *PKG_RELEASE*: EOF - else - echo "No usage of *AUTORELEASE* found in changes" > "$GITHUB_WORKSPACE/pr_comment.md" fi for ROOT in $CONTAINS_AUTORELEASE; do @@ -70,8 +71,11 @@ jobs: echo >> "$GITHUB_WORKSPACE/pr_comment.md" done + exit $RET + - name: Find Comment uses: peter-evans/find-comment@v2 + if: ${{ failure() }} id: fc with: issue-number: ${{ github.event.pull_request.number }} @@ -79,6 +83,7 @@ jobs: - name: Create or update comment uses: peter-evans/create-or-update-comment@v2 + if: ${{ failure() }} with: comment-id: ${{ steps.fc.outputs.comment-id }} issue-number: ${{ github.event.pull_request.number }} From 865412cd046d22f53573d5cf640d5c14bc6571ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20L=C3=BCssing?= Date: Sun, 27 Nov 2022 10:55:37 +0100 Subject: [PATCH 08/39] bpfcountd: add initial package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bpfcountd was created to obtain packet statistics in larger networks without stressing the cpu resources. bpfcountd will count the amount of packages and bytes over time (for each defined rule). The rules are defined using the tcpdump filter syntax (bpf). The collected data is provided on a unix socket in plaintext. Signed-off-by: Linus Lüssing --- net/bpfcountd/Makefile | 42 ++++++++++ net/bpfcountd/files/etc/bpfcountd.filters | 2 + net/bpfcountd/files/etc/config/bpfcountd | 13 +++ net/bpfcountd/files/etc/init.d/bpfcountd | 99 +++++++++++++++++++++++ 4 files changed, 156 insertions(+) create mode 100644 net/bpfcountd/Makefile create mode 100644 net/bpfcountd/files/etc/bpfcountd.filters create mode 100644 net/bpfcountd/files/etc/config/bpfcountd create mode 100755 net/bpfcountd/files/etc/init.d/bpfcountd diff --git a/net/bpfcountd/Makefile b/net/bpfcountd/Makefile new file mode 100644 index 000000000..f6b97c2e4 --- /dev/null +++ b/net/bpfcountd/Makefile @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: MIT +# Copyright (C) 2022 Linus Lüssing + +include $(TOPDIR)/rules.mk + +PKG_NAME:=bpfcountd +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2021-06-26 +PKG_SOURCE_URL=https://github.com/lemoer/bpfcountd.git +PKG_SOURCE_VERSION:=8b1aeb18d686815f93e2bfe976e536c5699d6371 +PKG_MIRROR_HASH:=e6e7adcc11c0fd33c6d3ac31423d3288812270944c2f31d9610ac8c3173a8c5f + +PKG_MAINTAINER:=Linus Lüssing +PKG_LICENSE:=MIT +PKG_LICENSE_FILES:=LICENSE + +include $(INCLUDE_DIR)/package.mk + +define Package/bpfcountd + SECTION:=net + CATEGORY:=Network + TITLE:=Berkeley Packet Filter Counting Daemon + DEPENDS:=+libpcap +endef + +define Package/bpfcountd/description + bpfcountd was created to obtain packet statistics in larger networks + without stressing the cpu resources. bpfcountd will count the amount + of packages and bytes over time (for each defined rule). The rules + are defined using the tcpdump filter syntax (bpf). The collected + data is provided on a unix socket in plaintext. +endef + +define Package/bpfcountd/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/bpfcountd $(1)/usr/sbin/ + $(CP) ./files/* $(1)/ +endef + +$(eval $(call BuildPackage,bpfcountd)) diff --git a/net/bpfcountd/files/etc/bpfcountd.filters b/net/bpfcountd/files/etc/bpfcountd.filters new file mode 100644 index 000000000..8c1029a25 --- /dev/null +++ b/net/bpfcountd/files/etc/bpfcountd.filters @@ -0,0 +1,2 @@ +arp;arp +icmp6;icmp6 diff --git a/net/bpfcountd/files/etc/config/bpfcountd b/net/bpfcountd/files/etc/config/bpfcountd new file mode 100644 index 000000000..790de16ca --- /dev/null +++ b/net/bpfcountd/files/etc/config/bpfcountd @@ -0,0 +1,13 @@ +config bpfcountd 'eth0_in' + option ifname 'eth0' + option prefilter 'inbound' + option filterfile '/etc/bpfcountd.filters' + option buffersize '2097152' + option disabled '1' + +config bpfcountd 'eth0_out' + option ifname 'eth0' + option prefilter 'outbound' + option filterfile '/etc/bpfcountd.filters' + option buffersize '2097152' + option disabled '1' diff --git a/net/bpfcountd/files/etc/init.d/bpfcountd b/net/bpfcountd/files/etc/init.d/bpfcountd new file mode 100755 index 000000000..1639da720 --- /dev/null +++ b/net/bpfcountd/files/etc/init.d/bpfcountd @@ -0,0 +1,99 @@ +#!/bin/sh /etc/rc.common +# SPDX-License-Identifier: MIT +# Copyright (C) 2022 Linus Lüssing + +USE_PROCD=1 +START=20 +STOP=90 + +UNIXSOCKDIR=/var/run/bpfcountd + +bpfcountd_start() { + local cfg="$1" + local namespace="$2" + local disabled + + local ifname + local prefilter + local filterfile + local buffersize + + config_get_bool disabled "$cfg" disabled 0 + [ "$disabled" -gt 0 ] && return 0 + + mkdir -p "$UNIXSOCKDIR" + + config_get ifname "$cfg" "ifname" + config_get prefilter "$cfg" "prefilter" + config_get filterfile "$cfg" "filterfile" + config_get buffersize "$cfg" "buffersize" + + [ -z "$ifname" ] && { + echo "Error: no ifname specified for $cfg" >&2 + return 0 + } + [ -z "$filterfile" ] && { + echo "Error: no filterfile specified for $cfg" >&2 + return 0 + } + + [ -z "$namespace" ] && namespace="bpfcountd" + + procd_open_instance "$namespace.$cfg" + + procd_set_param command /usr/sbin/bpfcountd + procd_append_param command -i "$ifname" + procd_append_param command -f "$filterfile" + procd_append_param command -u $UNIXSOCKDIR/"$namespace.$cfg".sock + [ -n "$prefilter" ] && procd_append_param command -F "$prefilter" + [ -n "$buffersize" ] && procd_append_param command -b "$buffersize" + + procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5} + + procd_set_param stderr 1 + procd_close_instance +} + +start_service() { + local cfg="$1" + local namespace="$2" + local instance_found=0 + + . /lib/functions/network.sh + + config_cb() { + local type="$1" + local name="$2" + if [ "$type" = "bpfcountd" ]; then + if [ -n "$cfg" -a "$cfg" = "$name" ]; then + instance_found=1 + fi + fi + } + + config_load bpfcountd + + if [ -n "$cfg" ]; then + [ "$instance_found" -gt 0 ] || return + bpfcountd_start "$cfg" "$namespace" + else + config_foreach bpfcountd_start bpfcountd "$namespace" + fi +} + +stop_service() { + local cfg="$1" + local namespace="$2" + + [ -z "$namespace" ] && namespace="bpfcountd" + + if [ -n "$cfg" ]; then + rm $UNIXSOCKDIR/$namespace.$cfg.sock + else + rm $UNIXSOCKDIR/$namespace.*.sock + fi +} + +service_triggers() { + procd_add_reload_trigger bpfcountd +} From 47eca64cb82a5459668fc14df9422e365c8343b6 Mon Sep 17 00:00:00 2001 From: Stan Grishin Date: Mon, 31 Oct 2022 23:08:01 +0000 Subject: [PATCH 09/39] pbr: initial commit * The makefile produces the nft and iptables capable `pbr` package and the `pbr-iptables` package for legacy setups * This replaces `vpnbypass` and `vpn-policy-routing` packages * I'm soliciting feedback on this package and my intention is to update the version to 1.0.0 before this is merged, but I need the feedback on this and luci-app-pbr before then. Signed-off-by: Stan Grishin --- net/pbr/Makefile | 201 ++ net/pbr/files/README.md | 3 + net/pbr/files/etc/config/pbr | 45 + net/pbr/files/etc/config/pbr.iptables | 45 + net/pbr/files/etc/hotplug.d/firewall/70-pbr | 6 + net/pbr/files/etc/hotplug.d/iface/70-pbr | 8 + net/pbr/files/etc/init.d/pbr.init | 2394 +++++++++++++++++ net/pbr/files/etc/uci-defaults/90-pbr | 34 + net/pbr/files/etc/uci-defaults/91-pbr | 58 + .../chain-post/mangle_forward/30-pbr.nft | 1 + .../chain-post/mangle_input/30-pbr.nft | 1 + .../chain-post/mangle_output/30-pbr.nft | 1 + .../chain-post/mangle_postrouting/30-pbr.nft | 1 + .../chain-post/mangle_prerouting/30-pbr.nft | 1 + .../share/nftables.d/table-post/30-pbr.nft | 5 + .../files/usr/share/pbr/pbr.firewall.include | 5 + net/pbr/files/usr/share/pbr/pbr.user.aws | 33 + net/pbr/files/usr/share/pbr/pbr.user.netflix | 49 + net/{vpn-policy-routing => pbr}/test.sh | 0 net/vpn-policy-routing/Makefile | 68 - net/vpn-policy-routing/files/README.md | 3 - .../files/vpn-policy-routing.aws.user | 19 - .../files/vpn-policy-routing.config | 30 - .../files/vpn-policy-routing.firewall.hotplug | 6 - .../files/vpn-policy-routing.init | 1322 --------- .../files/vpn-policy-routing.netflix.user | 37 - net/vpnbypass/Makefile | 69 - net/vpnbypass/files/README.md | 3 - net/vpnbypass/files/vpnbypass.config | 5 - net/vpnbypass/files/vpnbypass.hotplug | 2 - net/vpnbypass/files/vpnbypass.init | 146 - net/vpnbypass/test.sh | 3 - 32 files changed, 2891 insertions(+), 1713 deletions(-) create mode 100644 net/pbr/Makefile create mode 100644 net/pbr/files/README.md create mode 100644 net/pbr/files/etc/config/pbr create mode 100644 net/pbr/files/etc/config/pbr.iptables create mode 100755 net/pbr/files/etc/hotplug.d/firewall/70-pbr create mode 100644 net/pbr/files/etc/hotplug.d/iface/70-pbr create mode 100755 net/pbr/files/etc/init.d/pbr.init create mode 100644 net/pbr/files/etc/uci-defaults/90-pbr create mode 100644 net/pbr/files/etc/uci-defaults/91-pbr create mode 100644 net/pbr/files/usr/share/nftables.d/chain-post/mangle_forward/30-pbr.nft create mode 100644 net/pbr/files/usr/share/nftables.d/chain-post/mangle_input/30-pbr.nft create mode 100644 net/pbr/files/usr/share/nftables.d/chain-post/mangle_output/30-pbr.nft create mode 100644 net/pbr/files/usr/share/nftables.d/chain-post/mangle_postrouting/30-pbr.nft create mode 100644 net/pbr/files/usr/share/nftables.d/chain-post/mangle_prerouting/30-pbr.nft create mode 100644 net/pbr/files/usr/share/nftables.d/table-post/30-pbr.nft create mode 100644 net/pbr/files/usr/share/pbr/pbr.firewall.include create mode 100644 net/pbr/files/usr/share/pbr/pbr.user.aws create mode 100644 net/pbr/files/usr/share/pbr/pbr.user.netflix rename net/{vpn-policy-routing => pbr}/test.sh (100%) delete mode 100644 net/vpn-policy-routing/Makefile delete mode 100644 net/vpn-policy-routing/files/README.md delete mode 100644 net/vpn-policy-routing/files/vpn-policy-routing.aws.user delete mode 100644 net/vpn-policy-routing/files/vpn-policy-routing.config delete mode 100755 net/vpn-policy-routing/files/vpn-policy-routing.firewall.hotplug delete mode 100755 net/vpn-policy-routing/files/vpn-policy-routing.init delete mode 100644 net/vpn-policy-routing/files/vpn-policy-routing.netflix.user delete mode 100644 net/vpnbypass/Makefile delete mode 100644 net/vpnbypass/files/README.md delete mode 100644 net/vpnbypass/files/vpnbypass.config delete mode 100644 net/vpnbypass/files/vpnbypass.hotplug delete mode 100644 net/vpnbypass/files/vpnbypass.init delete mode 100644 net/vpnbypass/test.sh diff --git a/net/pbr/Makefile b/net/pbr/Makefile new file mode 100644 index 000000000..0f2842ed8 --- /dev/null +++ b/net/pbr/Makefile @@ -0,0 +1,201 @@ +# Copyright 2017-2022 Stan Grishin (stangri@melmac.ca) +# This is free software, licensed under the GNU General Public License v3. + +include $(TOPDIR)/rules.mk + +PKG_NAME:=pbr +PKG_VERSION:=1.0.0 +PKG_RELEASE:=1 +PKG_LICENSE:=GPL-3.0-or-later +PKG_MAINTAINER:=Stan Grishin + +include $(INCLUDE_DIR)/package.mk + +define Package/pbr/default + SECTION:=net + CATEGORY:=Network + SUBMENU:=VPN + PROVIDES:=pbr + TITLE:=Policy Based Routing Service + URL:=https://docs.openwrt.melmac.net/pbr/ + DEPENDS:=+ip-full +jshn +jsonfilter +resolveip + CONFLICTS:=vpnbypass vpn-policy-routing + PROVIDES:=vpnbypass vpn-policy-routing + PKGARCH:=all +endef + +define Package/pbr +$(call Package/pbr/default) + TITLE+= with nft/nft set support + DEPENDS+=+firewall4 +kmod-nft-core +kmod-nft-nat +nftables-json +endef + +define Package/pbr-iptables +$(call Package/pbr/default) + TITLE+= with iptables/ipset support + DEPENDS+=+ipset +iptables +kmod-ipt-ipset +iptables-mod-ipopt +endef + +define Package/pbr-netifd +$(call Package/pbr/default) + TITLE+= with netifd support +endef + +define Package/pbr/description +This service enables policy-based routing for WAN interfaces and various VPN tunnels. +This version supports OpenWrt with both fw3/ipset/iptables and fw4/nft. +endef + +define Package/pbr-iptables/description +This service enables policy-based routing for WAN interfaces and various VPN tunnels. +This version supports OpenWrt with fw3/ipset/iptables. +endef + +define Package/pbr-netifd/description +This service enables policy-based routing for WAN interfaces and various VPN tunnels. +This version supports OpenWrt with both fw3/ipset/iptables and fw4/nft. +This version uses OpenWrt native netifd/tables to set up interfaces. This is WIP. +endef + +define Package/pbr/conffiles +/etc/config/pbr +endef + +Package/pbr-iptables/conffiles = $(Package/pbr/conffiles) +Package/pbr-netifd/conffiles = $(Package/pbr/conffiles) + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/pbr/default/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/etc/init.d/pbr.init $(1)/etc/init.d/pbr + $(SED) "s|^\(readonly PKG_VERSION\).*|\1='$(PKG_VERSION)-$(PKG_RELEASE)'|" $(1)/etc/init.d/pbr + $(INSTALL_DIR) $(1)/etc/hotplug.d/firewall + $(INSTALL_DIR) $(1)/etc/hotplug.d/iface + $(INSTALL_DATA) ./files/etc/hotplug.d/iface/70-pbr $(1)/etc/hotplug.d/iface/70-pbr + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) ./files/etc/uci-defaults/90-pbr $(1)/etc/uci-defaults/90-pbr + $(INSTALL_DIR) $(1)/usr/share/pbr + $(INSTALL_DATA) ./files/usr/share/pbr/pbr.firewall.include $(1)/usr/share/pbr/pbr.firewall.include + $(INSTALL_DATA) ./files/usr/share/pbr/pbr.user.aws $(1)/usr/share/pbr/pbr.user.aws + $(INSTALL_DATA) ./files/usr/share/pbr/pbr.user.netflix $(1)/usr/share/pbr/pbr.user.netflix +endef + +define Package/pbr/install +$(call Package/pbr/default/install,$(1)) + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) ./files/etc/config/pbr $(1)/etc/config/pbr + $(INSTALL_DIR) $(1)/usr/share/nftables.d + $(CP) ./files/usr/share/nftables.d/* $(1)/usr/share/nftables.d/ +endef + +define Package/pbr-iptables/install +$(call Package/pbr/default/install,$(1)) + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) ./files/etc/config/pbr.iptables $(1)/etc/config/pbr +endef + +define Package/pbr-netifd/install +$(call Package/pbr/default/install,$(1)) + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) ./files/etc/config/pbr $(1)/etc/config/pbr + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) ./files/etc/uci-defaults/91-pbr $(1)/etc/uci-defaults/91-pbr +endef + +define Package/pbr/postinst + #!/bin/sh + # check if we are on real system + if [ -z "$${IPKG_INSTROOT}" ]; then + chmod -x /etc/init.d/pbr || true + fw4 -q reload || true + chmod +x /etc/init.d/pbr || true + echo -n "Installing rc.d symlink for pbr... " + /etc/init.d/pbr enable && echo "OK" || echo "FAIL" + fi + exit 0 +endef + +define Package/pbr/prerm + #!/bin/sh + # check if we are on real system + if [ -z "$${IPKG_INSTROOT}" ]; then + uci -q delete firewall.pbr || true + echo "Stopping pbr service... " + /etc/init.d/pbr stop || true + echo -n "Removing rc.d symlink for pbr... " + /etc/init.d/pbr disable && echo "OK" || echo "FAIL" + fi + exit 0 +endef + +define Package/pbr/postrm + #!/bin/sh + # check if we are on real system + if [ -z "$${IPKG_INSTROOT}" ]; then + fw4 -q reload || true + fi + exit 0 +endef + +define Package/pbr-iptables/postinst + #!/bin/sh + # check if we are on real system + if [ -z "$${IPKG_INSTROOT}" ]; then + echo -n "Installing rc.d symlink for pbr... " + /etc/init.d/pbr enable && echo "OK" || echo "FAIL" + fi + exit 0 +endef + +define Package/pbr-iptables/prerm + #!/bin/sh + # check if we are on real system + if [ -z "$${IPKG_INSTROOT}" ]; then + uci -q delete firewall.pbr || true + echo "Stopping pbr service... " + /etc/init.d/pbr stop || true + echo -n "Removing rc.d symlink for pbr... " + /etc/init.d/pbr disable && echo "OK" || echo "FAIL" + fi + exit 0 +endef + +define Package/pbr-netifd/postinst + #!/bin/sh + # check if we are on real system + if [ -z "$${IPKG_INSTROOT}" ]; then + echo -n "Installing rc.d symlink for pbr... " + /etc/init.d/pbr enable && echo "OK" || echo "FAIL" + # echo -n "Installing netifd support for pbr... " + # /etc/init.d/pbr netifd install && echo "OK" || echo "FAIL" + # echo -n "Restarting network... " + # /etc/init.d/network restart && echo "OK" || echo "FAIL" + fi + exit 0 +endef + +define Package/pbr-netifd/prerm + #!/bin/sh + # check if we are on real system + if [ -z "$${IPKG_INSTROOT}" ]; then + uci -q delete firewall.pbr || true + echo "Stopping pbr service... " + /etc/init.d/pbr stop || true + # echo -n "Removing netifd support for pbr... " + # /etc/init.d/pbr netifd remove && echo "OK" || echo "FAIL" + echo -n "Removing rc.d symlink for pbr... " + /etc/init.d/pbr disable && echo "OK" || echo "FAIL" + # echo -n "Restarting network... " + # /etc/init.d/network restart && echo "OK" || echo "FAIL" + fi + exit 0 +endef + +$(eval $(call BuildPackage,pbr)) +$(eval $(call BuildPackage,pbr-iptables)) +#$(eval $(call BuildPackage,pbr-netifd)) diff --git a/net/pbr/files/README.md b/net/pbr/files/README.md new file mode 100644 index 000000000..494a97c13 --- /dev/null +++ b/net/pbr/files/README.md @@ -0,0 +1,3 @@ +# README + +README is available at [https://docs.openwrt.melmac.net/pbr/](https://docs.openwrt.melmac.net/pbr/). diff --git a/net/pbr/files/etc/config/pbr b/net/pbr/files/etc/config/pbr new file mode 100644 index 000000000..355fac205 --- /dev/null +++ b/net/pbr/files/etc/config/pbr @@ -0,0 +1,45 @@ +config pbr 'config' + option enabled '0' + option verbosity '2' + option strict_enforcement '1' + option resolver_set 'none' + option ipv6_enabled '0' + list ignored_interface 'vpnserver' + list ignored_interface 'wgserver' + option boot_timeout '30' + option rule_create_option 'add' + option procd_reload_delay '1' + option webui_show_ignore_target '0' + list webui_supported_protocol 'all' + list webui_supported_protocol 'tcp' + list webui_supported_protocol 'udp' + list webui_supported_protocol 'tcp udp' + list webui_supported_protocol 'icmp' + +config include + option path '/usr/share/pbr/pbr.user.aws' + option enabled 0 + +config include + option path '/usr/share/pbr/pbr.user.netflix' + option enabled 0 + +config policy + option name 'Plex/Emby Local Server' + option interface 'wan' + option src_port '8096 8920 32400' + option enabled '0' + +config policy + option name 'Plex/Emby Remote Servers' + option interface 'wan' + option dest_addr 'plex.tv my.plexapp.com emby.media app.emby.media tv.emby.media' + option enabled '0' + +config policy + option name 'WireGuard Server' + option interface 'wan' + option src_port '51820' + option chain 'OUTPUT' + option proto 'udp' + option enabled '0' diff --git a/net/pbr/files/etc/config/pbr.iptables b/net/pbr/files/etc/config/pbr.iptables new file mode 100644 index 000000000..c62712644 --- /dev/null +++ b/net/pbr/files/etc/config/pbr.iptables @@ -0,0 +1,45 @@ +config pbr 'config' + option enabled '0' + option verbosity '2' + option strict_enforcement '1' + option resolver_set 'dnsmasq.ipset' + option ipv6_enabled '0' + list ignored_interface 'vpnserver' + list ignored_interface 'wgserver' + option boot_timeout '30' + option rule_create_option 'add' + option procd_reload_delay '1' + option webui_show_ignore_target '0' + list webui_supported_protocol 'all' + list webui_supported_protocol 'tcp' + list webui_supported_protocol 'udp' + list webui_supported_protocol 'tcp udp' + list webui_supported_protocol 'icmp' + +config include + option path '/usr/share/pbr/pbr.user.aws' + option enabled 0 + +config include + option path '/usr/share/pbr/pbr.user.netflix' + option enabled 0 + +config policy + option name 'Plex/Emby Local Server' + option interface 'wan' + option src_port '8096 8920 32400' + option enabled '0' + +config policy + option name 'Plex/Emby Remote Servers' + option interface 'wan' + option dest_addr 'plex.tv my.plexapp.com emby.media app.emby.media tv.emby.media' + option enabled '0' + +config policy + option name 'WireGuard Server' + option interface 'wan' + option src_port '51820' + option chain 'OUTPUT' + option proto 'udp' + option enabled '0' diff --git a/net/pbr/files/etc/hotplug.d/firewall/70-pbr b/net/pbr/files/etc/hotplug.d/firewall/70-pbr new file mode 100755 index 000000000..c129006c5 --- /dev/null +++ b/net/pbr/files/etc/hotplug.d/firewall/70-pbr @@ -0,0 +1,6 @@ +#!/bin/sh +[ "$ACTION" = "reload" ] ||[ "$ACTION" = "restart" ] || exit 0 +if [ -x /etc/init.d/pbr ] && /etc/init.d/pbr enabled; then + logger -t "pbr" "Reloading pbr due to $ACTION of firewall" + /etc/init.d/pbr reload +fi diff --git a/net/pbr/files/etc/hotplug.d/iface/70-pbr b/net/pbr/files/etc/hotplug.d/iface/70-pbr new file mode 100644 index 000000000..172385a11 --- /dev/null +++ b/net/pbr/files/etc/hotplug.d/iface/70-pbr @@ -0,0 +1,8 @@ +#!/bin/sh +# shellcheck disable=SC1091,SC3060 +[ -s /etc/openwrt_release ] && . /etc/openwrt_release +[ "${DISTRIB_RELEASE//19.07}" = "$DISTRIB_RELEASE" ] && exit 0 +if [ -x /etc/init.d/pbr ] && /etc/init.d/pbr enabled; then + logger -t pbr "Reloading pbr $INTERFACE due to $ACTION of $INTERFACE ($DEVICE)" + /etc/init.d/pbr reload_interface "$INTERFACE" +fi diff --git a/net/pbr/files/etc/init.d/pbr.init b/net/pbr/files/etc/init.d/pbr.init new file mode 100755 index 000000000..cf807f433 --- /dev/null +++ b/net/pbr/files/etc/init.d/pbr.init @@ -0,0 +1,2394 @@ +#!/bin/sh /etc/rc.common +# Copyright 2020-2022 Stan Grishin (stangri@melmac.ca) +# shellcheck disable=SC1091,SC2018,SC2019,SC3043,SC3057,SC3060 + +# sysctl net.ipv4.conf.default.rp_filter=1 +# sysctl net.ipv4.conf.all.rp_filter=1 + +# shellcheck disable=SC2034 +START=94 +# shellcheck disable=SC2034 +USE_PROCD=1 + +if type extra_command >/dev/null 2>&1; then + extra_command 'status' "Generates output required to troubleshoot routing issues + Use '-d' option for more detailed output + Use '-p' option to automatically upload data under VPR paste.ee account + WARNING: while paste.ee uploads are unlisted, they are still publicly available + List domain names after options to include their lookup in report" + extra_command 'version' 'Show version information' + extra_command 'on_firewall_reload' ' Run service on firewall reload' + extra_command 'on_interface_reload' ' Run service on indicated interface reload' +else +# shellcheck disable=SC2034 + EXTRA_COMMANDS='on_firewall_reload on_interface_reload status version' +# shellcheck disable=SC2034 + EXTRA_HELP=" status Generates output required to troubleshoot routing issues + Use '-d' option for more detailed output + Use '-p' option to automatically upload data under VPR paste.ee account + WARNING: while paste.ee uploads are unlisted, they are still publicly available + List domain names after options to include their lookup in report" +fi + +readonly PKG_VERSION='dev-test' +readonly packageName='pbr' +readonly serviceName="$packageName $PKG_VERSION" +readonly serviceTrapSignals='exit SIGHUP SIGQUIT SIGKILL' +readonly packageConfigFile="/etc/config/${packageName}" +readonly nftTempFile="/var/run/${packageName}.nft" +#readonly nftPermFile="/etc/nftables.d/table-post/30-pbr.nft" +readonly dnsmasqFile="/var/dnsmasq.d/${packageName}" +readonly sharedMemoryOutput="/dev/shm/$packageName-output" +readonly _OK_='\033[0;32m\xe2\x9c\x93\033[0m' +readonly _FAIL_='\033[0;31m\xe2\x9c\x97\033[0m' +readonly __OK__='\033[0;32m[\xe2\x9c\x93]\033[0m' +readonly __FAIL__='\033[0;31m[\xe2\x9c\x97]\033[0m' +readonly _ERROR_='\033[0;31mERROR\033[0m' +readonly _WARNING_='\033[0;33mWARNING\033[0m' +readonly ip_full='/usr/libexec/ip-full' +readonly ipTablePrefix='pbr' +# shellcheck disable=SC2155 +readonly iptables="$(command -v iptables)" +# shellcheck disable=SC2155 +readonly ip6tables="$(command -v ip6tables)" +# shellcheck disable=SC2155 +readonly ipset="$(command -v ipset)" +readonly ipsPrefix='pbr' +readonly iptPrefix='PBR' +# shellcheck disable=SC2155 +readonly agh="$(command -v AdGuardHome)" +readonly aghConfigFile='/etc/adguardhome.yaml' +readonly aghIpsetFile="/var/run/${packageName}.adguardhome.ipsets" +# shellcheck disable=SC2155 +readonly nft="$(command -v nft)" +readonly nftTable="fw4" +readonly nftPrefix='pbr' +readonly chainsList='forward input output postrouting prerouting' + +# package config options +boot_timeout= +enabled= +fw_mask= +icmp_interface= +ignored_interface= +ipv6_enabled= +procd_boot_delay= +procd_reload_delay= +resolver_set= +rule_create_option= +secure_reload= +strict_enforcement= +supported_interface= +verbosity= +wan_ip_rules_priority= +wan_mark= + +# run-time +gatewaySummary= +errorSummary= +warningSummary= +wanIface4= +wanIface6= +ifaceMark= +ifaceTableID= +ifacePriority= +ifacesAll= +ifacesSupported= +wanGW4= +wanGW6= +serviceStartTrigger= +processPolicyError= +processPolicyWarning= +resolver_set_supported= +nftPrevParam4= +nftPrevParam6= + + +get_text() { + local r + case "$1" in + errorConfigValidation) r="Config ($packageConfigFile) validation failure!";; + errorNoIpFull) r="ip-full binary cannot be found!";; + errorNoIpset) r="Resolver set support (${resolver_set}) requires ipset, but ipset binary cannot be found!";; + errorNoNft) r="Resolver set support (${resolver_set}) requires nftables, but nft binary cannot be found!";; + errorResolverNotSupported) r="Resolver set (${resolver_set}) is not supported on this system!";; + errorServiceDisabled) r="The ${packageName} service is currently disabled!";; + errorNoWanGateway) r="The ${serviceName} service failed to discover WAN gateway!";; + errorIpsetNameTooLong) r="The ipset name '%s' is longer than allowed 31 characters!";; + errorNftsetNameTooLong) r="The nft set name '%s' is longer than allowed 31 characters!";; + errorUnexpectedExit) r="Unexpected exit or service termination: '%s'!";; + errorPolicyNoSrcDest) r="Policy '%s' has no source/destination parameters!";; + errorPolicyNoInterface) r="Policy '%s' has no assigned interface!";; + errorPolicyUnknownInterface) r="Policy '%s' has an unknown interface!";; + errorPolicyProcess) r="%s";; + errorFailedSetup) r="Failed to set up '%s'!";; + errorFailedReload) r="Failed to reload '%s'!";; + errorUserFileNotFound) r="Custom user file '%s' not found or empty!";; + ererrorUserFileSyntax) r="Syntax error in custom user file '%s'!";; + errorUserFileRunning) r="Error running custom user file '%s'!";; + errorUserFileNoCurl) r="Use of 'curl' is detected in custom user file '%s', but 'curl' isn't installed!";; + errorNoGateways) r="Failed to set up any gateway!";; + warningResolverNotSupported) r="Resolver set (${resolver_set}) is not supported on this system.";; + warningAGHVersionTooLow) r="Installed AdGuardHome (%s) doesn't support 'ipset_file' option.";; + warningPolicyProcess) r="%s";; + esac + echo "$r" +} + +version() { echo "$PKG_VERSION"; } +output_ok() { output 1 "$_OK_"; output 2 "$__OK__\\n"; } +output_okn() { output 1 "$_OK_\\n"; output 2 "$__OK__\\n"; } +output_fail() { s=1; output 1 "$_FAIL_"; output 2 "$__FAIL__\\n"; } +output_failn() { output 1 "$_FAIL_\\n"; output 2 "$__FAIL__\\n"; } +str_replace() { printf "%b" "$1" | sed -e "s/$(printf "%b" "$2")/$(printf "%b" "$3")/g"; } +str_replace() { echo "${1//$2/$3}"; } +str_contains() { [ -n "$1" ] &&[ -n "$2" ] && [ "${1//$2}" != "$1" ]; } +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"; } +str_contains_word() { echo "$1" | grep -q -w "$2"; } +str_to_lower() { echo "$1" | tr 'A-Z' 'a-z'; } +str_to_upper() { echo "$1" | tr 'a-z' 'A-Z'; } +str_extras_to_underscore() { echo "$1" | tr '[\. ~`!@#$%^&*()\+/,<>?//;:]' '_'; } +str_extras_to_space() { echo "$1" | tr ';{}' ' '; } +debug() { local i j; for i in "$@"; do eval "j=\$$i"; echo "${i}: ${j} "; done; } +output() { +# Can take a single parameter (text) to be output at any verbosity +# Or target verbosity level and text to be output at specifc verbosity + local msg memmsg logmsg + verbosity="${verbosity:-2}" + if [ "$#" -ne 1 ]; then + if [ $((verbosity & $1)) -gt 0 ] || [ "$verbosity" = "$1" ]; then shift; else return 0; fi + fi + [ -t 1 ] && printf "%b" "$1" + msg="${1//$serviceName /service }"; + if [ "$(printf "%b" "$msg" | wc -l)" -gt 0 ]; then + [ -s "$sharedMemoryOutput" ] && memmsg="$(cat "$sharedMemoryOutput")" + logmsg="$(printf "%b" "${memmsg}${msg}" | sed 's/\x1b\[[0-9;]*m//g')" + logger -t "${packageName:-service}" "$(printf "%b" "$logmsg")" + rm -f "$sharedMemoryOutput" + else + printf "%b" "$msg" >> "$sharedMemoryOutput" + fi +} +is_present() { command -v "$1" >/dev/null 2>&1; } +is_installed() { [ -s "/usr/lib/opkg/info/${1}.control" ]; } +is_variant_installed() { [ "$(echo /usr/lib/opkg/info/"${1}"*.control)" != "/usr/lib/opkg/info/${1}*.control" ]; } +is_nft() { [ -x "$nft" ] && ! str_contains "$resolver_set" 'ipset' && "$nft" list chains inet | grep -q "${nftPrefix}_prerouting"; } +_build_ifaces_all() { ifacesAll="${ifacesAll}${1} "; } +_build_ifaces_supported() { is_supported_interface "$1" && ifacesSupported="${ifacesSupported}${1} "; } +pbr_find_iface() { + local iface i param="$2" + [ "$param" = 'wan6' ] || param='wan' + "network_find_${param}" iface + is_tunnel "$iface" && unset iface + if [ -z "$iface" ]; then + for i in $ifacesAll; do + if "is_${param}" "$i"; then break; else unset i; fi + done + fi + eval "$1"='${iface:-$i}' +} +pbr_get_gateway() { + local iface="$2" dev="$3" gw + network_get_gateway gw "$iface" true +# if [ -z "$gw" ] || [ "$gw" = '0.0.0.0' ]; then +# gw="$(ubus call "network.interface.${iface}" status | jsonfilter -e "@.route[0].nexthop")" +# fi + if [ -z "$gw" ] || [ "$gw" = '0.0.0.0' ]; then + gw="$($ip_full -4 a list dev "$dev" 2>/dev/null | grep inet | awk '{print $2}' | awk -F "/" '{print $1}')" + fi + eval "$1"='$gw' +} +pbr_get_gateway6() { + local iface="$2" dev="$3" gw + network_get_gateway6 gw "$iface" true + if [ -z "$gw" ] || [ "$gw" = '::/0' ] || [ "$gw" = '::0/0' ] || [ "$gw" = '::' ]; then + gw="$($ip_full -6 a list dev "$dev" 2>/dev/null | grep inet6 | awk '{print $2}')" + fi + eval "$1"='$gw' +} +is_dslite() { local proto; proto=$(uci -q get network."$1".proto); [ "${proto:0:6}" = "dslite" ]; } +is_l2tp() { local proto; proto=$(uci -q get network."$1".proto); [ "${proto:0:4}" = "l2tp" ]; } +is_oc() { local proto; proto=$(uci -q get network."$1".proto); [ "${proto:0:11}" = "openconnect" ]; } +is_ovpn() { local dev; network_get_device dev "$1"; [ "${dev:0:3}" = "tun" ] || [ "${dev:0:3}" = "tap" ] || [ -f "/sys/devices/virtual/net/${dev}/tun_flags" ]; } +is_pptp() { local proto; proto=$(uci -q get network."$1".proto); [ "${proto:0:4}" = "pptp" ]; } +is_softether() { local dev; network_get_device dev "$1"; [ "${dev:0:4}" = "vpn_" ]; } +is_tor() { [ "$(str_to_lower "$1")" = "tor" ]; } +is_tor_running() { + local ret=0 + if [ -s "/etc/tor/torrc" ]; then + json_load "$(ubus call service list "{ 'name': 'tor' }")" + json_select 'tor'; json_select 'instances'; json_select 'instance1'; + json_get_var ret 'running'; json_cleanup + fi + if [ "$ret" = "0" ]; then return 1; else return 0; fi +} +is_wg() { local proto; proto=$(uci -q get network."$1".proto); [ "${proto:0:9}" = "wireguard" ]; } +is_tunnel() { is_dslite "$1" || is_l2tp "$1" || is_oc "$1" || is_ovpn "$1" || is_pptp "$1" || is_softether "$1" || is_tor "$1" || is_wg "$1"; } +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_ignored_interface() { str_contains_word "$ignored_interface" "$1"; } +is_supported_interface() { str_contains_word "$supported_interface" "$1" || { ! is_ignored_interface "$1" && { is_wan "$1" || is_wan6 "$1" || is_tunnel "$1"; }; } || is_ignore_target "$1"; } +is_ignore_target() { [ "$(str_to_lower "$1")" = 'ignore' ]; } +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; } +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_family_mismatch() { ( is_netmask "${1//!}" && is_ipv6 "${2//!}" ) || ( is_ipv6 "${1//!}" && is_netmask "${2//!}" ); } +is_ipv6_link_local() { [ "${1:0:4}" = "fe80" ]; } +is_ipv6_unique_local() { [ "${1:0:2}" = "fc" ] || [ "${1:0:2}" = "fd" ]; } +is_ipv6_global() { [ "${1:0:4}" = "2001" ]; } +# is_ipv6_global() { is_ipv6 "$1" && ! is_ipv6_link_local "$1" && ! is_ipv6_link_local "$1"; } +is_list() { str_contains "$1" "," || str_contains "$1" " "; } +is_netmask() { local ip="${1%/*}"; [ "$ip" != "$1" ] && is_ipv4 "$ip"; } +is_domain() { str_contains "$1" '[a-zA-Z]'; } +is_phys_dev() { [ "${1:0:1}" = "@" ] && ip l show | grep -E -q "^\\d+\\W+${1:1}"; } +dnsmasq_kill() { killall -q -s HUP dnsmasq; } +dnsmasq_restart() { output 3 'Restarting dnsmasq '; if /etc/init.d/dnsmasq restart >/dev/null 2>&1; then output_okn; else output_failn; fi; } +is_default_dev() { [ "$1" = "$($ip_full -4 r | grep -m1 'dev' | grep -Eso 'dev [^ ]*' | awk '{print $2}')" ]; } +is_supported_iface_dev() { local n dev; for n in $ifacesSupported; do network_get_device dev "$n"; [ "$1" = "$dev" ] && return 0; done; return 1; } +is_supported_protocol() { grep -o '^[^#]*' /etc/protocols | grep -w -v '0' | grep . | awk '{print $1}' | grep -q "$1"; } +is_service_running_iptables() { [ -x "$iptables" ] && "$iptables" -t mangle -L | grep -q "${iptPrefix}_PREROUTING" >/dev/null 2>&1; } +is_service_running_nft() { [ -x "$nft" ] && [ -n "$(get_mark_nft_chains)" ]; } +# atomic +# is_service_running_nft() { [ -x "$nft" ] && [ -s "$nftPermFile" ]; } +is_service_running() { if is_nft; then is_service_running_nft; else is_service_running_iptables; fi; } +is_netifd_table() { local iface="$1"; [ "$(uci -q get "network.${iface}.ip4table")" = "${packageName}_${iface%6}" ]; } +get_rt_tables_id() { grep "${packageName}_${iface}" /etc/iproute2/rt_tables | awk '{print $1;}'; } +get_rt_tables_next_id() { echo "$(($(sort -r -n /etc/iproute2/rt_tables | grep -o -E -m 1 "^[0-9]+")+1))"; } +_check_config() { local en; config_get_bool en "$1" 'enabled' 1; [ "$en" -gt 0 ] && _cfg_enabled=0; } +is_config_enabled() { + local cfg="$1" _cfg_enabled=1 + [ -n "$1" ] || return 1 + config_load "$packageName" + config_foreach _check_config "$cfg" + return "$_cfg_enabled" +} +# shellcheck disable=SC2016 +resolveip_to_ipt() { resolveip "$@" | sed -n 'H;${x;s/\n/,/g;s/^,//;p;};d'; } +# shellcheck disable=SC2016 +resolveip_to_nftset() { resolveip "$@" | sed -n 'H;${x;s/\n/,/g;s/^,//;p;};d' | tr '\n' ' '; } +resolveip_to_nftset4() { resolveip_to_nftset -4 "$@"; } +resolveip_to_nftset6() { [ -n "$ipv6_enabled" ] && resolveip_to_nftset -6 "$@"; } +# shellcheck disable=SC2016 +ipv4_leases_to_nftset() { [ -s '/tmp/dhcp.leases' ] || return 1; grep "$1" '/tmp/dhcp.leases' | awk '{print $3}' | sed -n 'H;${x;s/\n/,/g;s/^,//;p;};d' | tr '\n' ' '; } +# shellcheck disable=SC2016 +ipv6_leases_to_nftset() { [ -s '/tmp/hosts/odhcpd' ] || return 1; grep -v '^\#' '/tmp/hosts/odhcpd' | grep "$1" | awk '{print $1}' | sed -n 'H;${x;s/\n/,/g;s/^,//;p;};d' | tr '\n' ' '; } +# shellcheck disable=SC3037 +ports_to_nftset() { echo -ne "$value"; } +get_mark_ipt_chains() { [ -n "$(command -v iptables-save)" ] && iptables-save | grep ":${iptPrefix}_MARK_" | awk '{ print $1 }' | sed 's/://'; } +get_mark_nft_chains() { [ -x "$nft" ] && "$nft" list table inet "$nftTable" 2>/dev/null | grep chain | grep "${nftPrefix}_mark_" | awk '{ print $2 }'; } +get_ipsets() { [ -x "$(command -v ipset)" ] && ipset list | grep "${ipsPrefix}_" | awk '{ print $2 }'; } +get_nft_sets() { [ -x "$nft" ] && "$nft" list table inet "$nftTable" 2>/dev/null | grep 'set' | grep "${nftPrefix}_" | awk '{ print $2 }'; } +is_ipset_type_supported() { ipset help hash:"$1" >/dev/null 2>&1; } +ubus_get_status() { ubus call service list "{ 'name': '$packageName' }" | jsonfilter -e "@.${packageName}.instances.main.data.status.${1}"; } +ubus_get_iface() { ubus call service list "{ 'name': '$packageName' }" | jsonfilter -e "@.${packageName}.instances.main.data.interfaces[@.name='${1}']${2:+.$2}"; } + +load_package_config() { + config_load "$packageName" + config_get boot_timeout 'config' 'boot_timeout' '30' + config_get_bool enabled 'config' 'enabled' '0' + config_get fw_mask 'config' 'fw_mask' 'ff0000' + config_get icmp_interface 'config' 'icmp_interface' + config_get ignored_interface 'config' 'ignored_interface' + config_get_bool ipv6_enabled 'config' 'ipv6_enabled' '0' + config_get procd_boot_delay 'config' 'procd_boot_delay' '0' + config_get resolver_set 'config' 'resolver_set' + config_get rule_create_option 'config' 'rule_create_option' 'add' + config_get_bool secure_reload 'config' 'secure_reload' '1' + config_get_bool strict_enforcement 'config' 'strict_enforcement' '0' + config_get supported_interface 'config' 'supported_interface' + config_get verbosity 'config' 'verbosity' '2' + config_get wan_ip_rules_priority 'config' 'wan_ip_rules_priority' '30000' + config_get wan_mark 'config' 'wan_mark' '010000' + fw_mask="0x${fw_mask}" + wan_mark="0x${wan_mark}" + [ -n "$ipv6_enabled" ] && [ "$ipv6_enabled" -eq 0 ] && unset ipv6_enabled + . /lib/functions/network.sh + . /usr/share/libubox/jshn.sh + mkdir -p "${dnsmasqFile%/*}" + if is_nft; then + fw_maskXor="$(printf '%#x' "$((fw_mask ^ 0xffffffff))")" + fw_maskXor="${fw_maskXor:-0xff00ffff}" + else + case $rule_create_option in + insert|-i|-I) rule_create_option='-I';; + add|-a|-A|*) rule_create_option='-A';; + esac + fi +} + +load_environment() { + local param="$1" validation_result="$2" + load_package_config + + if [ "$param" = 'on_start' ]; then + 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" + state add 'errorSummary' 'errorConfigValidation' + return 1 + fi + if [ "$enabled" -eq 0 ]; then + state add 'errorSummary' 'errorServiceDisabled' + return 1 + fi + if [ ! -x "$ip_full" ]; then + state add 'errorSummary' 'errorNoIpFull' + return 1 + fi + resolver 'check_support' + fi + + load_network "$param" +} + +load_network() { + config_load 'network' + [ -z "$ifacesAll" ] && config_foreach _build_ifaces_all 'interface' + [ -z "$ifacesSupported" ] && config_foreach _build_ifaces_supported 'interface' + pbr_find_iface wanIface4 'wan' + [ -n "$ipv6_enabled" ] && pbr_find_iface wanIface6 'wan6' + [ -n "$wanIface4" ] && network_get_gateway wanGW4 "$wanIface4" + [ -n "$wanIface6" ] && network_get_gateway6 wanGW6 "$wanIface6" + wanGW="${wanGW4:-$wanGW6}" +} + +is_wan_up() { + local sleepCount='1' + load_network + while [ -z "$wanGW" ] ; do + load_network + if [ $((sleepCount)) -gt $((boot_timeout)) ] || [ -n "$wanGW" ]; then break; fi + output "$serviceName waiting for wan gateway...\\n" + sleep 1 + network_flush_cache + sleepCount=$((sleepCount+1)) + done + if [ -n "$wanGW" ]; then + return 0 + else + state add 'errorSummary' 'errorNoWanGateway' + return 1 + fi +} + +# shellcheck disable=SC2086 +ipt4() { + local d + [ -x "$iptables" ] || return 1 + for d in "${*//-A/-D}" "${*//-I/-D}" "${*//-N/-F}" "${*//-N/-X}"; do + [ "$d" != "$*" ] && "$iptables" $d >/dev/null 2>&1 + done + d="$*"; "$iptables" $d >/dev/null 2>&1 +} + +# shellcheck disable=SC2086 +ipt6() { + local d + [ -n "$ipv6_enabled" ] || return 0 + [ -x "$ip6tables" ] || return 1 + for d in "${*//-A/-D}" "${*//-I/-D}" "${*//-N/-F}" "${*//-N/-X}"; do + [ "$d" != "$*" ] && "$ip6tables" $d >/dev/null 2>&1 + done + d="$*" + "$ip6tables" $d >/dev/null 2>&1 +} + +# shellcheck disable=SC2086 +ipt() { + local d failFlagIpv4=1 failFlagIpv6=1 + [ -x "$iptables" ] || return 1 + for d in "${*//-A/-D}" "${*//-I/-D}" "${*//-N/-F}" "${*//-N/-X}"; do + if [ "$d" != "$*" ]; then + "$iptables" $d >/dev/null 2>&1 + [ -x "$ip6tables" ] && "$ip6tables" $d >/dev/null 2>&1 + fi + done + d="$*"; "$iptables" $d >/dev/null 2>&1 && failFlagIpv4=0; + if [ -n "$ipv6_enabled" ] && [ -x "$ip6tables" ]; then + "$ip6tables" $d >/dev/null 2>&1 && failFlagIpv6=0 + fi + [ "$failFlagIpv4" -eq 0 ] || [ "$failFlagIpv6" -eq 0 ] +} + +# shellcheck disable=SC2086 +ips4() { [ -x "$ipset" ] && "$ipset" "$@" >/dev/null 2>&1; } +ips6() { [ -x "$ipset" ] && { if [ -n "$ipv6_enabled" ] && [ -n "$*" ]; then "$ipset" "$@" >/dev/null 2>&1; else return 1; fi; }; } +ips() { + local command="$1" iface="$2" target="${3:-dst}" type="${4:-ip}" uid="$5" comment="$6" param="$7" mark="$7" + local ipset4 ipset6 i + local ipv4_error=1 ipv6_error=1 + ipset4="${ipsPrefix}${iface:+_$iface}_4${target:+_$target}${type:+_$type}${uid:+_$uid}" + ipset6="${ipsPrefix}${iface:+_$iface}_6${target:+_$target}${type:+_$type}${uid:+_$uid}" + + [ -x "$ipset" ] || return 1 + + if [ "${#ipset4}" -gt 31 ]; then + state add 'errorSummary' 'errorIpsetNameTooLong' "$ipset4" + return 1 + fi + + case "$command" in + add) + ips4 -q -! add "$ipset4" comment "$comment" && ipv4_error=0 + ips6 -q -! add "$ipset6" comment "$comment" && ipv6_error=0 + ;; + add_agh_element) + [ -n "$ipv6_enabled" ] || unset ipset6 + echo "${param}/${ipset4}${ipset6:+,$ipset6}" >> "$aghIpsetFile" && ipv4_error=0 + ;; + add_dnsmasq_element) + [ -n "$ipv6_enabled" ] || unset ipset6 + echo "ipset=/${param}/${ipset4}${ipset6:+,$ipset6} # $comment" >> "$dnsmasqFile" && ipv4_error=0 + ;; + create) + ips4 -q -! create "$ipset4" "hash:$type" comment && ipv4_error=0 + ips6 -q -! create "$ipset6" "hash:$type" comment family inet6 && ipv6_error=0 + ;; + create_agh_set) + ips4 -q -! create "$ipset4" "hash:$type" comment && ipv4_error=0 + ips6 -q -! create "$ipset6" "hash:$type" comment family inet6 && ipv6_error=0 + ;; + create_dnsmasq_set) + ips4 -q -! create "$ipset4" "hash:$type" comment && ipv4_error=0 + ips6 -q -! create "$ipset6" "hash:$type" comment family inet6 && ipv6_error=0 + ;; + create_user_set) + case "$type" in + ip|net) + ips4 -q -! create "$ipset4" "hash:$type" comment && ipv4_error=0 + ips6 -q -! create "$ipset6" "hash:$type" comment family inet6 && ipv4_error=0 + case "$target" in + dst) + ipt4 -t mangle -A "${iptPrefix}_PREROUTING" -m set --match-set "$ipset4" dst -g "${iptPrefix}_MARK_${mark}" && ipv4_error=0 + ipt6 -t mangle -A "${iptPrefix}_PREROUTING" -m set --match-set "$ipset6" dst -g "${iptPrefix}_MARK_${mark}" && ipv6_error=0 + ;; + src) + ipt4 -t mangle -A "${iptPrefix}_PREROUTING" -m set --match-set "$ipset4" src -g "${iptPrefix}_MARK_${mark}" && ipv4_error=0 + ipt6 -t mangle -A "${iptPrefix}_PREROUTING" -m set --match-set "$ipset6" src -g "${iptPrefix}_MARK_${mark}" && ipv6_error=0 + ;; + esac + ;; + mac) + ips4 -q -! create "$ipset4" "hash:$type" comment && ipv4_error=0 + ips6 -q -! create "$ipset6" "hash:$type" comment family inet6 && ipv4_error=0 + ipt4 -t mangle -A "${iptPrefix}_PREROUTING" -m set --match-set "$ipset4" src -g "${iptPrefix}_MARK_${mark}" && ipv4_error=0 + ipt6 -t mangle -A "${iptPrefix}_PREROUTING" -m set --match-set "$ipset6" src -g "${iptPrefix}_MARK_${mark}" && ipv6_error=0 + ;; + esac + ;; + delete|destroy) + ips4 -q -! destroy "$ipset4" && ipv4_error=0 + ips6 -q -! destroy "$ipset6" && ipv6_error=0 + ;; + delete_user_set) + ips4 -q -! destroy "$ipset4" && ipv4_error=0 + ips6 -q -! destroy "$ipset6" family inet6 && ipv6_error=0 + case "$type" in + ip|net) + case "$target" in + dst) + ipt4 -t mangle -D "${iptPrefix}_PREROUTING" -m set --match-set "$ipset4" dst -g "${iptPrefix}_MARK_${mark}" && ipv4_error=0 + ipt6 -t mangle -D "${iptPrefix}_PREROUTING" -m set --match-set "$ipset6" dst -g "${iptPrefix}_MARK_${mark}" && ipv6_error=0 + ;; + src) + ipt4 -t mangle -D "${iptPrefix}_PREROUTING" -m set --match-set "$ipset4" src -g "${iptPrefix}_MARK_${mark}" && ipv4_error=0 + ipt6 -t mangle -D "${iptPrefix}_PREROUTING" -m set --match-set "$ipset6" src -g "${iptPrefix}_MARK_${mark}" && ipv6_error=0 + ;; + esac + ;; + mac) + ipt4 -t mangle -D "${iptPrefix}_PREROUTING" -m set --match-set "$ipset4" src -g "${iptPrefix}_MARK_${mark}" && ipv4_error=0 + ipt6 -t mangle -D "${iptPrefix}_PREROUTING" -m set --match-set "$ipset6" src -g "${iptPrefix}_MARK_${mark}" && ipv6_error=0 + ;; + esac + ;; + flush|flush_user_set) + ips4 -q -! flush "$ipset4" && ipv4_error=0 + ips6 -q -! flush "$ipset6" && ipv6_error=0 + ;; + esac + return $ipv4_error || $ipv6_error +} + +# atomic +#nfta() { echo "$@" >> "$nftTempFile"; } +#nfta4() { echo "$@" >> "$nftTempFile"; } +#nfta6() { [ -z "$ipv6_enabled" ] || echo "$@" >> "$nftTempFile"; } +#nft() { nfta "$@"; [ -x "$nft" ] && "$nft" "$@" >/dev/null 2>&1; } +#nft4() { nfta "$@"; [ -x "$nft" ] && "$nft" "$@" >/dev/null 2>&1; } +#nft6() { nfta "$@"; [ -n "$ipv6_enabled" ] || return 0; [ -x "$nft" ] && [ -n "$*" ] && "$nft" "$@" >/dev/null 2>&1; } +nft() { [ -x "$nft" ] && "$nft" "$@" >/dev/null 2>&1; } +nft4() { [ -x "$nft" ] && "$nft" "$@" >/dev/null 2>&1; } +nft6() { [ -n "$ipv6_enabled" ] || return 0; [ -x "$nft" ] && [ -n "$*" ] && "$nft" "$@" >/dev/null 2>&1; } +nftset() { + local command="$1" iface="$2" target="${3:-dst}" type="${4:-ip}" uid="$5" comment="$6" param="$7" mark="$7" + local nftset4 nftset6 i param4 param6 + local ipv4_error=1 ipv6_error=1 + nftset4="${nftPrefix}${iface:+_$iface}_4${target:+_$target}${type:+_$type}${uid:+_$uid}" + nftset6="${nftPrefix}${iface:+_$iface}_6${target:+_$target}${type:+_$type}${uid:+_$uid}" + + [ -x "$nft" ] || return 1 + + if [ "${#nftset4}" -gt 255 ]; then + state add 'errorSummary' 'errorNftsetNameTooLong' "$nftset4" + return 1 + fi + + case "$command" in + add) + if is_netmask "$param" || is_ipv4 "$param" || is_ipv6 "$param" \ + || 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 + else +# elif is_domain "$param"; then + if [ "$target" = 'src' ]; then + param4="$(ipv4_leases_to_nftset "$param")" + param6="$(ipv6_leases_to_nftset "$param")" + fi + [ -z "$param4" ] && param4="$(resolveip_to_nftset4 "$param")" + [ -z "$param6" ] && param6="$(resolveip_to_nftset6 "$param")" + nft4 add element inet "$nftTable" "$nftset4" "{ $param4 }" && ipv4_error=0 + nft6 add element inet "$nftTable" "$nftset6" "{ $param6 }" && ipv6_error=0 + fi + ;; + add_dnsmasq_element) + [ -n "$ipv6_enabled" ] || unset nftset6 + echo "nftset=/${param}/4#inet#${nftTable}#${nftset4}${nftset6:+,6#inet#${nftTable}#$nftset6} # $comment" >> "$dnsmasqFile" && ipv4_error=0 + ;; + create) + case "$type" in + ip|net) + nft4 add set inet "$nftTable" "$nftset4" "{ type ipv4_addr; flags interval; auto-merge; comment \"$comment\"; }" && ipv4_error=0 + nft6 add set inet "$nftTable" "$nftset6" "{ type ipv6_addr; flags interval; auto-merge; comment \"$comment\"; }" && ipv6_error=0 + ;; + mac) + nft4 add set inet "$nftTable" "$nftset4" "{ type ether_addr; flags interval; auto-merge; comment \"$comment\"; }" && ipv4_error=0 + nft6 add set inet "$nftTable" "$nftset6" "{ type ether_addr; flags interval; auto-merge; comment \"$comment\"; }" && ipv6_error=0 + ;; + esac + ;; + create_dnsmasq_set) + nft4 add set inet "$nftTable" "$nftset4" "{ type ipv4_addr; flags interval; auto-merge; comment \"$comment\"; }" && ipv4_error=0 + nft6 add set inet "$nftTable" "$nftset6" "{ type ipv6_addr; flags interval; auto-merge; comment \"$comment\"; }" && ipv6_error=0 + ;; + create_user_set) + case "$type" in + ip|net) + nft4 add set inet "$nftTable" "$nftset4" "{ type ipv4_addr; flags interval; auto-merge; policy memory; comment \"$comment\"; }" && ipv4_error=0 + nft6 add set inet "$nftTable" "$nftset6" "{ type ipv6_addr; flags interval; auto-merge; policy memory; comment \"$comment\"; }" && ipv6_error=0 + case "$target" in + dst) + nft add rule inet "$nftTable" "${nftPrefix}_prerouting" ip daddr "@${nftset4}" goto "${nftPrefix}_mark_${mark}" && ipv4_error=0 + nft add rule inet "$nftTable" "${nftPrefix}_prerouting" ip daddr "@${nftset6}" goto "${nftPrefix}_mark_${mark}" && ipv6_error=0 + ;; + src) + nft add rule inet "$nftTable" "${nftPrefix}_prerouting" ip saddr "@${nftset4}" goto "${nftPrefix}_mark_${mark}" && ipv4_error=0 + nft add rule inet "$nftTable" "${nftPrefix}_prerouting" ip saddr "@${nftset6}" goto "${nftPrefix}_mark_${mark}" && ipv6_error=0 + ;; + esac + ;; + mac) + nft4 add set inet "$nftTable" "$nftset4" "{ type ether_addr; flags interval; auto-merge; policy memory; comment \"$comment\"; }" && ipv4_error=0 + nft6 add set inet "$nftTable" "$nftset6" "{ type ether_addr; flags interval; auto-merge; policy memory; comment \"$comment\"; }" && ipv6_error=0 + nft add rule inet "$nftTable" "${nftPrefix}_prerouting" ether saddr "@${nftset4}" goto "${nftPrefix}_mark_${mark}" && ipv4_error=0 + nft add rule inet "$nftTable" "${nftPrefix}_prerouting" ether saddr "@${nftset6}" goto "${nftPrefix}_mark_${mark}" && ipv6_error=0 + ;; + esac + ;; + delete|destroy) + nft delete set inet "$nftTable" "$nftset4" && ipv4_error=0 + nft delete set inet "$nftTable" "$nftset6" && ipv6_error=0 + ;; + delete_user_set) + nft delete set inet "$nftTable" "$nftset4" && ipv4_error=0 + nft delete set inet "$nftTable" "$nftset6" && ipv6_error=0 + case "$type" in + ip|net) + case "$target" in + dst) + nft delete rule inet "$nftTable" "${nftPrefix}_prerouting" ip daddr "@${nftset4}" goto "${nftPrefix}_mark_${mark}" && ipv4_error=0 + nft delete rule inet "$nftTable" "${nftPrefix}_prerouting" ip daddr "@${nftset6}" goto "${nftPrefix}_mark_${mark}" && ipv6_error=0 + ;; + src) + nft delete rule inet "$nftTable" "${nftPrefix}_prerouting" ip saddr "@${nftset4}" goto "${nftPrefix}_mark_${mark}" && ipv4_error=0 + nft delete rule inet "$nftTable" "${nftPrefix}_prerouting" ip saddr "@${nftset6}" goto "${nftPrefix}_mark_${mark}" && ipv6_error=0 + ;; + esac + ;; + mac) + nft delete rule inet "$nftTable" "${nftPrefix}_prerouting" ether saddr "@${nftset4}" goto "${nftPrefix}_mark_${mark}" && ipv4_error=0 + nft delete rule inet "$nftTable" "${nftPrefix}_prerouting" ether saddr "@${nftset6}" goto "${nftPrefix}_mark_${mark}" && ipv6_error=0 + ;; + esac + ;; + flush|flush_user_set) + nft flush set inet "$nftTable" "$nftset4" && ipv4_error=0 + nft flush set inet "$nftTable" "$nftset6" && ipv6_error=0 + ;; + esac +# nft6 returns true if IPv6 support is not enabled + [ -z "$ipv6_enabled" ] && ipv6_error='1' + return $ipv4_error || $ipv6_error +} + +cleanup_dnsmasq() { [ -s "$dnsmasqFile" ] && resolverStoredHash="$(md5sum $dnsmasqFile | awk '{ print $1; }')" && rm "$dnsmasqFile" >/dev/null 2>&1; } +cleanup_main_chains() { + local i + for i in $chainsList; do + i="$(str_to_lower "$i")" + nft flush chain inet "$nftTable" "${nftPrefix}_${i}" + done + for i in $chainsList; do + i="$(str_to_upper "$i")" + ipt -t mangle -D "${i}" -m mark --mark "0x0/${fw_mask}" -j "${iptPrefix}_${i}" + ipt -t mangle -F "${iptPrefix}_${i}" + ipt -t mangle -X "${iptPrefix}_${i}" + done +} + +cleanup_marking_chains() { + local i + for i in $(get_mark_nft_chains); do + nft flush chain inet "$nftTable" "$i" + nft delete chain inet "$nftTable" "$i" + done + for i in $(get_mark_ipt_chains); do + ipt -t mangle -F "$i" + ipt -t mangle -X "$i" + done +} + +cleanup_sets() { + local i + for i in $(get_nft_sets); do + nft flush set inet "$nftTable" "$i" + nft delete set inet "$nftTable" "$i" + done + for i in $(get_ipsets); do + ipset -q -! flush "$i" >/dev/null 2>&1 + ipset -q -! destroy "$i" >/dev/null 2>&1 + done +} + +state() { + local action="$1" param="$2" value="${3//#/_}" + shift 3 +# shellcheck disable=SC2124 + local extras="$@" + local line error_id error_extra label + case "$action" in + add) + line="$(eval echo "\$$param")" + eval "$param"='${line:+$line#}${value}${extras:+ $extras}' + ;; + json) + case "$param" in + errorSummary) + json_add_array 'errors';; + warningSummary) + json_add_array 'warnings';; + esac + if [ -n "$(eval echo "\$$param")" ]; then + while read -r line; do + if str_contains "$line" ' '; then +# url="${c##*|}" +# c="${c%|*}" + error_id="${line% *}" + error_extra="${line#* }" + else + error_id="$line" + fi + json_add_object + json_add_string 'id' "$error_id" + json_add_string 'extra' "$error_extra" + json_close_object + done </dev/null 2>&1 + rm -f "$aghIpsetFile" + rm -f "$dnsmasqFile" + return 0 + fi + + case "$resolver_set" in + ''|none) + case "$param" in + add_resolver_element) return 1;; + create_resolver_set) return 1;; + check_support) return 0;; + cleanup) return 0;; + configure) return 0;; + init) return 0;; + init_end) return 0;; + kill) return 0;; + reload) return 0;; + restart) return 0;; + compare_hash) return 0;; + store_hash) return 0;; + esac + ;; + adguardhome.ipset) + case "$param" in + add_resolver_element) + [ -n "$resolver_set_supported" ] && ips 'add_agh_element' "$@";; + create_resolver_set) + [ -n "$resolver_set_supported" ] && ips 'create_agh_set' "$@";; + check_support) + if [ ! -x "$ipset" ]; then + state add 'errorSummary' 'errorNoIpset' + return 1 + fi + if [ -n "$agh" ] && [ -s "$aghConfigFile" ]; then + agh_version="$($agh --version | sed 's|AdGuard Home, version v\(.*\)|\1|')" + if is_greater_or_equal "$agh_version" '0.107.13'; then + resolver_set_supported='true' + return 0 + else + state add 'warningSummary' 'warningAGHVersionTooLow' "$agh_version" + return 1 + fi + else + state add 'warningSummary' 'warningResolverNotSupported' + return 1 + fi + ;; + cleanup) + [ -z "$resolver_set_supported" ] && return 0 + rm -f "$aghIpsetFile" + sed -i "/ipset_file: ${aghIpsetFile}/d" "$aghConfigFile" >/dev/null 2>&1 + ;; + configure) + [ -z "$resolver_set_supported" ] && return 1 + mkdir -p "${aghIpsetFile%/*}" + touch "$aghIpsetFile" + sed -i '/ipset_file/d' "$aghConfigFile" >/dev/null 2>&1 + sed -i "/ ipset:/a \ \ ipset_file: $aghIpsetFile" "$aghConfigFile" + ;; + init) :;; + init_end) :;; + kill) + [ -n "$resolver_set_supported" ] && [ -n "$agh" ] && killall -q -s HUP "$agh";; + reload) + [ -z "$resolver_set_supported" ] && return 1 + output 3 'Reloading adguardhome ' + if /etc/init.d/adguardhome reload >/dev/null 2>&1; then + output_okn + return 0 + else + output_failn + return 1 + fi + ;; + restart) + [ -z "$resolver_set_supported" ] && return 1 + output 3 'Restarting adguardhome ' + if /etc/init.d/adguardhome restart >/dev/null 2>&1; then + output_okn + return 0 + else + output_failn + return 1 + fi + ;; + compare_hash) + [ -z "$resolver_set_supported" ] && return 1 + local resolverNewHash + if [ -s "$aghIpsetFile" ]; then + resolverNewHash="$(md5sum $aghIpsetFile | awk '{ print $1; }')" + fi + [ "$resolverNewHash" != "$resolverStoredHash" ] + ;; + store_hash) + [ -s "$aghIpsetFile" ] && resolverStoredHash="$(md5sum $aghIpsetFile | awk '{ print $1; }')";; + esac + ;; + dnsmasq.ipset) + case "$param" in + add_resolver_element) + [ -n "$resolver_set_supported" ] && ips 'add_dnsmasq_element' "$@";; + create_resolver_set) + [ -n "$resolver_set_supported" ] && ips 'create_dnsmasq_set' "$@";; + check_support) + if [ ! -x "$ipset" ]; then + state add 'errorSummary' 'errorNoIpset' + return 1 + fi + if ! dnsmasq -v 2>/dev/null | grep -q 'no-ipset' && dnsmasq -v 2>/dev/null | grep -q 'ipset'; then + resolver_set_supported='true' + return 0 + else + state add 'warningSummary' 'warningResolverNotSupported' + return 1 + fi + ;; + cleanup) + [ -n "$resolver_set_supported" ] && rm -f "$dnsmasqFile";; + configure) + [ -n "$resolver_set_supported" ] && mkdir -p "${dnsmasqFile%/*}";; + init) :;; + init_end) :;; + kill) + [ -n "$resolver_set_supported" ] && killall -q -s HUP dnsmasq;; + reload) + [ -z "$resolver_set_supported" ] && return 1 + output 3 'Reloading dnsmasq ' + if /etc/init.d/dnsmasq reload >/dev/null 2>&1; then + output_okn + return 0 + else + output_failn + return 1 + fi + ;; + restart) + [ -z "$resolver_set_supported" ] && return 1 + output 3 'Restarting dnsmasq ' + if /etc/init.d/dnsmasq restart >/dev/null 2>&1; then + output_okn + return 0 + else + output_failn + return 1 + fi + ;; + compare_hash) + [ -z "$resolver_set_supported" ] && return 1 + local resolverNewHash + if [ -s "$dnsmasqFile" ]; then + resolverNewHash="$(md5sum $dnsmasqFile | awk '{ print $1; }')" + fi + [ "$resolverNewHash" != "$resolverStoredHash" ] + ;; + store_hash) + [ -s "$dnsmasqFile" ] && resolverStoredHash="$(md5sum $dnsmasqFile | awk '{ print $1; }')";; + esac + ;; + dnsmasq.nftset) + case "$param" in + add_resolver_element) + [ -n "$resolver_set_supported" ] && nftset 'add_dnsmasq_element' "$@";; + create_resolver_set) + [ -n "$resolver_set_supported" ] && nftset 'create_dnsmasq_set' "$@";; + check_support) + if [ ! -x "$nft" ]; then + state add 'errorSummary' 'errorNoNft' + return 1 + fi + if ! dnsmasq -v 2>/dev/null | grep -q 'no-nftset' && dnsmasq -v 2>/dev/null | grep -q 'nftset'; then + resolver_set_supported='true' + return 0 + else + state add 'warningSummary' 'warningResolverNotSupported' + return 1 + fi + ;; + cleanup) + [ -n "$resolver_set_supported" ] && rm -f "$dnsmasqFile";; + configure) + [ -n "$resolver_set_supported" ] && mkdir -p "${dnsmasqFile%/*}";; + init) :;; + init_end) :;; + kill) + [ -n "$resolver_set_supported" ] && killall -q -s HUP dnsmasq;; + reload) + [ -z "$resolver_set_supported" ] && return 1 + output 3 'Reloading dnsmasq ' + if /etc/init.d/dnsmasq reload >/dev/null 2>&1; then + output_okn + return 0 + else + output_failn + return 1 + fi + ;; + restart) + [ -z "$resolver_set_supported" ] && return 1 + output 3 'Restarting dnsmasq ' + if /etc/init.d/dnsmasq restart >/dev/null 2>&1; then + output_okn + return 0 + else + output_failn + return 1 + fi + ;; + compare_hash) + [ -z "$resolver_set_supported" ] && return 1 + local resolverNewHash + if [ -s "$dnsmasqFile" ]; then + resolverNewHash="$(md5sum $dnsmasqFile | awk '{ print $1; }')" + fi + [ "$resolverNewHash" != "$resolverStoredHash" ] + ;; + store_hash) + [ -s "$dnsmasqFile" ] && resolverStoredHash="$(md5sum $dnsmasqFile | awk '{ print $1; }')";; + esac + ;; + unbound.ipset) + case "$param" in + add_resolver_element) :;; + create_resolver_set) :;; + check_support) :;; + cleanup) :;; + configure) :;; + init) :;; + init_end) :;; + kill) :;; + reload) :;; + restart) :;; + compare_hash) :;; + store_hash) :;; + esac + ;; + unbound.nftset) + case "$param" in + add_resolver_element) :;; + create_resolver_set) :;; + check_support) :;; + cleanup) :;; + configure) :;; + init) :;; + init_end) :;; + kill) :;; + reload) :;; + restart) :;; + compare_hash) :;; + store_hash) :;; + esac + ;; + esac +} + +trap_process() { +# verbosity=0 + output "\\n" + output "Unexpected exit or service termination: '${1}'!\\n" + state add 'errorSummary' 'errorUnexpectedExit' "$1" + traffic_killswitch 'remove' +} + +traffic_killswitch() { + local s=0 + case "$1" in + insert) + local lan_subnet wan_device + [ "$secure_reload" -ne 0 ] || return 0 + for i in $serviceTrapSignals; do +# shellcheck disable=SC2064 + trap "trap_process $i" "$i" + done + output 3 'Activating traffic killswitch ' + network_get_subnet lan_subnet 'lan' + network_get_physdev wan_device 'wan' + if is_nft; then + nft add chain inet "$nftTable" "${nftPrefix}_killswitch" '{ type filter hook forward priority 0; policy accept; }' || s=1 + nft add rule inet "$nftTable" "${nftPrefix}_killswitch" oifname "$wan_device" ip saddr "$lan_subnet" counter reject || s=1 +# nft add rule inet "$nftTable" "${nftPrefix}_killswitch" oifname '$wan_devices' ip saddr '$lan_subnet' counter reject || s=1 + else + ipt -N "${iptPrefix}_KILLSWITCH" || s=1 + ipt -A "${iptPrefix}_KILLSWITCH" -s "$lan_subnet" -o "$wan_device" -j REJECT || s=1 + ipt -I FORWARD -j "${iptPrefix}_KILLSWITCH" || s=1 + fi + if [ "$s" -eq 0 ]; then + output_okn + else + output_failn + fi + ;; + remove) + if [ "$secure_reload" -ne 0 ]; then + output 3 'Deactivating traffic killswitch ' + fi + if is_nft; then + nft flush chain inet "$nftTable" "${nftPrefix}_killswitch" || s=1 + nft delete chain inet "$nftTable" "${nftPrefix}_killswitch" || s=1 + else + ipt -D FORWARD -j "${iptPrefix}_KILLSWITCH" || s=1 + ipt -F "${iptPrefix}_KILLSWITCH" || s=1 + ipt -X "${iptPrefix}_KILLSWITCH" || s=1 + fi + if [ "$secure_reload" -ne 0 ]; then + if [ "$s" -eq 0 ]; then + output_okn + else + output_failn + fi + fi +# shellcheck disable=SC2086 + trap - $serviceTrapSignals + ;; + esac +} + +policy_routing_tor() { if is_nft; then policy_routing_tor_nft "$@"; else policy_routing_tor_iptables "$@"; fi; } +policy_routing_tor_iptables() { + local comment="$1" iface="$2" src_addr="$3" src_port="$4" dest_addr="$5" dest_port="$6" proto chain uid="$9" + proto="$(str_to_lower "$7")" + chain="$(str_to_upper "$8")" + chain="${chain:-PREROUTING}" + if [ -n "${src_addr}${src_port}${dest_port}" ]; then + processPolicyWarning="${processPolicyWarning}${_WARNING_}: Please unset 'src_addr', 'src_port' and 'dest_port' for policy '$comment'\\n" + fi + if [ -n "$proto" ] && [ "$proto" != "all" ]; then + processPolicyWarning="${processPolicyWarning}${_WARNING_}: Please unset 'proto' or set 'proto' to 'all' for policy '$comment'\\n" + fi + if [ "$chain" != "PREROUTING" ]; then + processPolicyWarning="${processPolicyWarning}${_WARNING_}: Please unset 'chain' or set 'chain' to 'PREROUTING' for policy '$comment'\\n" + fi + resolver 'add_resolver_element' "$iface" 'dst' 'ip' '' "${comment}: $dest_addr" "$dest_addr" || \ + processPolicyError="${processPolicyError}${_ERROR_}: resolver 'add_resolver_element' '$iface' 'dst' 'ip' '${comment}: $dest_addr' '$dest_addr'\\n" + return 0 +} +policy_routing_tor_nft() { + local comment="$1" iface="$2" src_addr="$3" src_port="$4" dest_addr="$5" dest_port="$6" proto chain uid="$9" + proto="$(str_to_lower "$7")" + chain="$(str_to_lower "$8")" + chain="${chain:-prerouting}" + if [ -n "${src_addr}${src_port}${dest_port}" ]; then + processPolicyWarning="${processPolicyWarning}${_WARNING_}: Please unset 'src_addr', 'src_port' and 'dest_port' for policy '$comment'\\n" + fi + if [ -n "$proto" ] && [ "$proto" != "all" ]; then + processPolicyWarning="${processPolicyWarning}${_WARNING_}: Please unset 'proto' or set 'proto' to 'all' for policy '$comment'\\n" + fi + if [ "$chain" != "prerouting" ]; then + processPolicyWarning="${processPolicyWarning}${_WARNING_}: Please unset 'chain' or set 'chain' to 'prerouting' for policy '$comment'\\n" + fi + resolver 'add_resolver_element' "$iface" 'dst' 'ip' '' "${comment}: $dest_addr" "$dest_addr" || \ + processPolicyError="${processPolicyError}${_ERROR_}: resolver 'add_resolver_element' '$iface' 'dst' 'ip' '${comment}: $dest_addr' '$dest_addr'\\n" + return 0 +} + +policy_routing() { if is_nft; then policy_routing_nft "$@"; else policy_routing_iptables "$@"; fi; } +policy_routing_iptables() { + local mark param4 param6 i negation value dest ipInsertOption="-A" + local ip4error='1' ip6error='1' + local name="$1" iface="$2" laddr="$3" lport="$4" raddr="$5" rport="$6" proto chain uid="$9" + proto="$(str_to_lower "$7")" + chain="$(str_to_upper "$8")" + chain="${chain:-PREROUTING}" + mark=$(eval echo "\$mark_${iface//-/_}") + + if [ -n "$ipv6_enabled" ] && { is_ipv6 "$laddr" || is_ipv6 "$raddr"; }; then + processPolicyError="${processPolicyError}${_ERROR_}: Skipping IPv6 policy '$name' as IPv6 support is disabled\\n" + return 1 + fi + + if [ -n "$mark" ]; then + dest="-g ${iptPrefix}_MARK_${mark}" + elif [ "$iface" = "ignore" ]; then + dest="-j RETURN" + else + processPolicyError="${processPolicyError}${_ERROR_}: Unknown fw_mark for ${iface}\\n" + return 1 + fi + + if [ -z "$proto" ]; then + if [ -n "$lport" ] || [ -n "$rport" ]; then + proto='tcp udp' + else + proto='all' + fi + fi + + if is_family_mismatch "$laddr" "$raddr"; then + processPolicyError="${processPolicyError}${_ERROR_}: Mismatched IP family between '$laddr' and '$raddr' in policy '$name'\\n" + return 1 + fi + + for i in $proto; do + if [ "$i" = 'all' ]; then + param4="-t mangle ${ipInsertOption} ${iptPrefix}_${chain} $dest" + param6="-t mangle ${ipInsertOption} ${iptPrefix}_${chain} $dest" + elif ! is_supported_protocol "$i"; then + processPolicyError="${processPolicyError}${_ERROR_}: Unknown protocol '$i' in policy '$name'\\n" + return 1 + else + param4="-t mangle ${ipInsertOption} ${iptPrefix}_${chain} $dest -p $i" + param6="-t mangle ${ipInsertOption} ${iptPrefix}_${chain} $dest -p $i" + fi + + if [ -n "$laddr" ]; then + if [ "${laddr:0:1}" = "!" ]; then + negation='!'; value="${laddr:1}" + else + unset negation; value="$laddr"; + fi + if is_phys_dev "$value"; then + param4="$param4 $negation -m physdev --physdev-in ${value:1}" + param6="$param6 $negation -m physdev --physdev-in ${value:1}" + elif is_netmask "$value"; then + local target='src' type='net' + if ips 'create' "$iface" "$target" "$type" "$uid" "${name}: $laddr" && \ + ips 'add' "$iface" "$target" "$type" "$uid" "${name}: $laddr" "$value"; then + param4="$param4 -m set $negation --match-set ${ipsPrefix}_${iface}_4_${target}_${type}_${uid} $target" + param6="$param6 -m set $negation --match-set ${ipsPrefix}_${iface}_6_${target}_${type}_${uid} $target" + else + param4="$param4 $negation -s $value" + param6="$param6 $negation -s $value" + fi + elif is_mac_address "$value"; then + local target='src' type='mac' + if ips 'create' "$iface" "$target" "$type" "$uid" "${name}: $laddr" && \ + ips 'add' "$iface" "$target" "$type" "$uid" "${name}: $laddr" "$value"; then + param4="$param4 -m set $negation --match-set ${ipsPrefix}_${iface}_4_${target}_${type}_${uid} $target" + param6="$param6 -m set $negation --match-set ${ipsPrefix}_${iface}_6_${target}_${type}_${uid} $target" + else + param4="$param4 -m mac $negation --mac-source $value" + param6="$param6 -m mac $negation --mac-source $value" + fi + else + local target='src' type='ip' + if ips 'create' "$iface" "$target" "$type" "$uid" "${name}: $laddr" && \ + ips 'add' "$iface" "$target" "$type" "$uid" "${name}: $laddr" "$value"; then + param4="$param4 -m set $negation --match-set ${ipsPrefix}_${iface}_4_${target}_${type}_${uid} $target" + param6="$param6 -m set $negation --match-set ${ipsPrefix}_${iface}_6_${target}_${type}_${uid} $target" + else + param4="$param4 $negation -s $(resolveip_to_ipt -4 "$value")" + param6="$param6 $negation -s $(resolveip_to_ipt -6 "$value")" + fi + fi + fi + + if [ -n "$lport" ]; then + if [ "${lport:0:1}" = "!" ]; then + negation='!'; value="${lport:1}" + else + unset negation; value="$lport"; + fi + param4="$param4 -m multiport $negation --sport ${value//-/:}" + param6="$param6 -m multiport $negation --sport ${value//-/:}" + fi + + if [ -n "$raddr" ]; then + if [ "${raddr:0:1}" = "!" ]; then + negation='!'; value="${raddr:1}" + else + unset negation; value="$raddr"; + fi + if is_netmask "$value"; then + local target='dst' type='net' + if ips 'create' "$iface" "$target" "$type" "$uid" "${name}: $raddr" && \ + ips 'add' "$iface" "$target" "$type" "$uid" "${name}: $raddr" "$value"; then + param4="$param4 -m set $negation --match-set ${ipsPrefix}_${iface}_4_${target}_${type}_${uid} $target" + param6="$param6 -m set $negation --match-set ${ipsPrefix}_${iface}_6_${target}_${type}_${uid} $target" + else + param4="$param4 $negation -d $value" + param6="$param6 $negation -d $value" + fi + elif is_domain "$value"; then + local target='dst' type='ip' + if resolver 'create_resolver_set' "$iface" "$target" "$type" "$uid" "${name}: $raddr" && \ + resolver 'add_resolver_element' "$iface" "$target" "$type" "$uid" "${name}: $raddr" "$value"; then + param4="$param4 -m set $negation --match-set ${ipsPrefix}_${iface}_4_${target}_${type}_${uid} $target" + param6="$param6 -m set $negation --match-set ${ipsPrefix}_${iface}_6_${target}_${type}_${uid} $target" + elif ips 'create' "$iface" "$target" "$type" "$uid" "${name}: $raddr" && \ + ips 'add' "$iface" "$target" "$type" "$uid" "${name}: $raddr" "$value"; then + param4="$param4 -m set $negation --match-set ${ipsPrefix}_${iface}_4_${target}_${type}_${uid} $target" + param6="$param6 -m set $negation --match-set ${ipsPrefix}_${iface}_6_${target}_${type}_${uid} $target" + else + param4="$param4 $negation -d $(resolveip_to_ipt -4 "$value")" + param6="$param6 $negation -d $(resolveip_to_ipt -6 "$value")" + fi + else + local target='dst' type='ip' + if ips 'create' "$iface" "$target" "$type" "$uid" "${name}: $raddr" && \ + ips 'add' "$iface" "$target" "$type" "$uid" "${name}: $raddr" "$value"; then + param4="$param4 -m set $negation --match-set ${ipsPrefix}_${iface}_4_${target}_${type}_${uid} $target" + param6="$param6 -m set $negation --match-set ${ipsPrefix}_${iface}_6_${target}_${type}_${uid} $target" + else + param4="$param4 $negation -d $value" + param6="$param6 $negation -d $value" + fi + fi + fi + + if [ -n "$rport" ]; then + if [ "${rport:0:1}" = "!" ]; then + negation='!'; value="${rport:1}" + else + unset negation; value="$rport"; + fi + param4="$param4 -m multiport $negation --dport ${value//-/:}" + param6="$param6 -m multiport $negation --dport ${value//-/:}" + fi + + if [ -n "$name" ]; then + param4="$param4 -m comment --comment $(str_extras_to_underscore "$name")" + param6="$param6 -m comment --comment $(str_extras_to_underscore "$name")" + fi + + local ipv4_error='0' ipv6_error='0' + if [ "$param4" = "$param6" ]; then + ipt4 "$param4" || ipv4_error='1' + else + ipt4 "$param4" || ipv4_error='1' + ipt6 "$param6" || ipv6_error='1' + fi + +# ipt6 returns true if IPv6 support is not enabled + [ -z "$ipv6_enabled" ] && ipv6_error='1' + if [ "$ipv4_error" -eq '1' ] && [ "$ipv6_error" -eq '1' ]; then + if [ -n "$ipv6_enabled" ]; then + processPolicyError="${processPolicyError}${_ERROR_}: Policy insertion failed for both IPv4 and IPv6!\\n" + processPolicyError="${processPolicyError}${_ERROR_}: iptables $param4\\n" + processPolicyError="${processPolicyError}${_ERROR_}: iptables $param6\\n" + else + processPolicyError="${processPolicyError}${_ERROR_}: iptables $param4\\n" + fi + fi + + done +} +policy_routing_nft() { + local mark param4 param6 i negation value dest nftInsertOption='add' + local ip4Flag='ip' ip6Flag='ip6' + local name="$1" iface="$2" laddr="$3" lport="$4" raddr="$5" rport="$6" proto chain uid="$9" + proto="$(str_to_lower "$7")" + chain="$(str_to_lower "$8")" + chain="${chain:-prerouting}" + mark=$(eval echo "\$mark_${iface//-/_}") + + if [ -z "$ipv6_enabled" ] && { is_ipv6 "$src_addr" || is_ipv6 "$dest_addr"; }; then + processPolicyError="${processPolicyError}${_ERROR_}: Skipping IPv6 policy '$name' as IPv6 support is disabled\\n" + return 1 + fi + + if [ -n "$mark" ]; then + dest="goto ${nftPrefix}_mark_${mark}" + elif [ "$iface" = "ignore" ]; then + dest="return" + else + processPolicyError="${processPolicyError}${_ERROR_}: Unknown packet mark for ${iface}\\n" + return 1 + fi + + if is_family_mismatch "$src_addr" "$dest_addr"; then + processPolicyError="${processPolicyError}${_ERROR_}: Mismatched IP family between '$src_addr' and '$dest_addr' in policy '$name'\\n" + return 1 + fi + + if [ -n "$proto" ] && ! is_supported_protocol "$proto"; then + processPolicyError="${processPolicyError}${_ERROR_}: Unknown protocol '$i' in policy '$name'\\n" + return 1 + fi + + if [ -n "$src_addr" ]; then + if [ "${src_addr:0:1}" = "!" ]; then + negation='!='; value="${src_addr:1}" + else + unset negation; value="$src_addr"; + fi + if is_phys_dev "$value"; then + param4="$param4 iifname $negation ${value:1}" + param6="$param6 iifname $negation ${value:1}" + elif is_mac_address "$value"; then + local target='src' type='mac' + if nftset 'create' "$iface" "$target" "$type" "$uid" "$name" && \ + nftset 'add' "$iface" "$target" "$type" "$uid" "$name" "$value"; then + param4="$param4 ether saddr $negation @${nftPrefix}_${iface}_4_${target}_${type}_${uid}" + param6="$param6 ether saddr $negation @${nftPrefix}_${iface}_6_${target}_${type}_${uid}" + else + param4="$param4 ether saddr $negation $value" + param6="$param6 ether saddr $negation $value" + fi + else + local target='src' type='ip' + if nftset 'create' "$iface" "$target" "$type" "$uid" "$name" && \ + nftset 'add' "$iface" "$target" "$type" "$uid" "$name" "$value"; then + param4="$param4 $ip4Flag saddr $negation @${nftPrefix}_${iface}_4_${target}_${type}_${uid}" + param6="$param6 $ip6Flag saddr $negation @${nftPrefix}_${iface}_6_${target}_${type}_${uid}" + else + param4="$param4 $ip4Flag saddr $negation $value" + param6="$param6 $ip6Flag saddr $negation $value" + fi + fi + fi + + if [ -n "$dest_addr" ]; then + if [ "${dest_addr:0:1}" = "!" ]; then + negation='!='; value="${dest_addr:1}" + else + unset negation; value="$dest_addr"; + fi + if is_phys_dev "$value"; then + param4="$param4 oifname $negation ${value:1}" + param6="$param6 oifname $negation ${value:1}" + elif is_domain "$value"; then + local target='dst' type='ip' + if resolver 'create_resolver_set' "$iface" "$target" "$type" "$uid" "$name" && \ + resolver 'add_resolver_element' "$iface" "$target" "$type" "$uid" "$name" "$value"; then + param4="$param4 $ip4Flag daddr $negation @${nftPrefix}_${iface}_4_${target}_${type}_${uid}" + param6="$param6 $ip6Flag daddr $negation @${nftPrefix}_${iface}_6_${target}_${type}_${uid}" + elif nftset 'create' "$iface" "$target" "$type" "$uid" "$name" && \ + nftset 'add' "$iface" "$target" "$type" "$uid" "$name" "$value"; then + param4="$param4 $ip4Flag daddr $negation @${nftPrefix}_${iface}_4_${target}_${type}_${uid}" + param6="$param6 $ip6Flag daddr $negation @${nftPrefix}_${iface}_6_${target}_${type}_${uid}" + else + param4="$param4 $ip4Flag daddr $negation {$(resolveip_to_nftset4 "$value")}" + param6="$param6 $ip6Flag daddr $negation {$(resolveip_to_nftset6 "$value")}" + fi + else + local target='dst' type='ip' + if nftset 'create' "$iface" "$target" "$type" "$uid" "$name" && \ + nftset 'add' "$iface" "$target" "$type" "$uid" "$name" "$value"; then + param4="$param4 $ip4Flag daddr $negation @${nftPrefix}_${iface}_4_${target}_${type}_${uid}" + param6="$param6 $ip6Flag daddr $negation @${nftPrefix}_${iface}_6_${target}_${type}_${uid}" + else + param4="$param4 $ip4Flag daddr $negation $value" + param6="$param6 $ip6Flag daddr $negation $value" + fi + fi + fi + + if [ -n "${src_port}${dest_port}" ]; then + proto="${proto:-tcp}" + fi + + if [ -n "$src_port" ]; then + if [ "${src_port:0:1}" = "!" ]; then + negation='!='; value="${src_port:1}" + else + unset negation; value="$src_port"; + fi + param4="$param4 ${proto:+$proto }sport $negation {$(ports_to_nftset "$value")}" + param6="$param6 ${proto:+$proto }sport $negation {$(ports_to_nftset "$value")}" + fi + + if [ -n "$dest_port" ]; then + if [ "${dest_port:0:1}" = "!" ]; then + negation='!='; value="${dest_port:1}" + else + unset negation; value="$dest_port"; + fi + param4="$param4 ${proto:+$proto }dport $negation {$(ports_to_nftset "$value")}" + param6="$param6 ${proto:+$proto }dport $negation {$(ports_to_nftset "$value")}" + fi + + param4="$nftInsertOption rule inet $nftTable ${nftPrefix}_${chain} $param4 $dest comment \"$name\"" + param6="$nftInsertOption rule inet $nftTable ${nftPrefix}_${chain} $param6 $dest comment \"$name\"" + + local ipv4_error='0' ipv6_error='0' + if [ "$nftPrevParam4" != "$param4" ]; then + nft4 "$param4" || ipv4_error='1' + nftPrevParam4="$param4" + fi + if [ "$nftPrevParam6" != "$param6" ]; then + nft6 "$param6" || ipv6_error='1' + nftPrevParam6="$param6" + fi + +# nft6 returns true if IPv6 support is not enabled + [ -z "$ipv6_enabled" ] && ipv6_error='1' + if [ "$ipv4_error" -eq '1' ] && [ "$ipv6_error" -eq '1' ]; then + if [ -n "$ipv6_enabled" ]; then + processPolicyError="${processPolicyError}${_ERROR_}: Policy insertion failed for both IPv4 and IPv6!\\n" + processPolicyError="${processPolicyError}${_ERROR_}: nft '$param4'\\n" + processPolicyError="${processPolicyError}${_ERROR_}: nft '$param6'\\n" + else + processPolicyError="${processPolicyError}${_ERROR_}: nft '$param4'\\n" + fi + fi +} + +policy_process() { + local i j uid="$9" + if [ -z "$uid" ]; then # first non-recursive call + [ "$enabled" -gt 0 ] || return 0 + unset processPolicyWarning + unset processPolicyError + uid="$1" + if is_nft; then + chain="$(str_to_lower "$chain")" + else + chain="$(str_to_upper "$chain")" + fi + proto="$(str_to_lower "$proto")" + [ "$proto" = 'auto' ] && unset proto + [ "$proto" = 'all' ] && unset proto + output 2 "Routing '$name' via $interface " + if [ -z "${src_addr}${src_port}${dest_addr}${dest_port}" ]; then + state add 'errorSummary' 'errorPolicyNoSrcDest' "$name" + output_fail; return 1; + fi + if [ -z "$interface" ]; then + state add 'errorSummary' 'errorPolicyNoInterface' "$name" + output_fail; return 1; + fi + if ! is_supported_interface "$interface"; then + state add 'errorSummary' 'errorPolicyUnknownInterface' "$name" + output_fail; return 1; + fi + src_port="${src_port// / }"; src_port="${src_port// /,}"; src_port="${src_port//,\!/ !}"; + dest_port="${dest_port// / }"; dest_port="${dest_port// /,}"; dest_port="${dest_port//,\!/ !}"; + if is_nft; then + nftset 'flush' "$interface" "dst" "ip" "$uid" + nftset 'flush' "$interface" "src" "ip" "$uid" + nftset 'flush' "$interface" "src" "mac" "$uid" + else + ips 'flush' "$interface" "dst" "ip" "$uid" + ips 'flush' "$interface" "src" "ip" "$uid" + ips 'flush' "$interface" "src" "mac" "$uid" + fi + policy_process "$name" "$interface" "$src_addr" "$src_port" "$dest_addr" "$dest_port" "$proto" "$chain" "$uid" + if [ -n "$processPolicyWarning" ]; then + state add 'warningSummary' 'warningPolicyProcess' "$processPolicyWarning" + fi + if [ -n "$processPolicyError" ]; then + output_fail + state add 'errorSummary' 'errorPolicyProcess' "$processPolicyError" + else + output_ok + fi + else # recursive call, get options from passed variables + local name="$1" interface="$2" src_addr="$3" src_port="$4" dest_addr="$5" dest_port="$6" proto="$7" chain="$8" + if str_contains "$src_addr" '[ ;\{\}]'; then + for i in $(str_extras_to_space "$src_addr"); do [ -n "$i" ] && policy_process "$name" "$interface" "$i" "$src_port" "$dest_addr" "$dest_port" "$proto" "$chain" "$uid"; done + elif str_contains "$src_port" '[ ;\{\}]'; then + for i in $(str_extras_to_space "$src_port"); do [ -n "$i" ] && policy_process "$name" "$interface" "$src_addr" "$i" "$dest_addr" "$dest_port" "$proto" "$chain" "$uid"; done + elif str_contains "$dest_addr" '[ ;\{\}]'; then + for i in $(str_extras_to_space "$dest_addr"); do [ -n "$i" ] && policy_process "$name" "$interface" "$src_addr" "$src_port" "$i" "$dest_port" "$proto" "$chain" "$uid"; done + elif str_contains "$dest_port" '[ ;\{\}]'; then + for i in $(str_extras_to_space "$dest_port"); do [ -n "$i" ] && policy_process "$name" "$interface" "$src_addr" "$src_port" "$dest_addr" "$i" "$proto" "$chain" "$uid"; done + elif str_contains "$proto" '[ ;\{\}]'; then + for i in $(str_extras_to_space "$proto"); do [ -n "$i" ] && policy_process "$name" "$interface" "$src_addr" "$src_port" "$dest_addr" "$dest_port" "$i" "$chain" "$uid"; done + else + if is_tor "$interface"; then + policy_routing_tor "$name" "$interface" "$src_addr" "$src_port" "$dest_addr" "$dest_port" "$proto" "$chain" "$uid" + else + policy_routing "$name" "$interface" "$src_addr" "$src_port" "$dest_addr" "$dest_port" "$proto" "$chain" "$uid" + fi + fi + fi +} + +interface_process_tor() { if is_nft; then interface_process_tor_nft "$@"; else interface_process_tor_iptables "$@"; fi; } +interface_process_tor_iptables() { + local s=0 iface="$1" action="$2" + local displayText set_name4 set_name6 + local dnsPort trafficPort + case "$action" in + reload) + displayText="${iface}/53->${dnsPort}/80,443->${trafficPort}" + gatewaySummary="${gatewaySummary}${displayText}\\n" + ;; + destroy) + for i in $chainsList; do + i="$(str_to_upper "$i")" + ipt -t nat -D "${i}" -m mark --mark "0x0/${fw_mask}" -j "${nftPrefix}_${i}" + ipt -t nat -F "${nftPrefix}_${i}"; ipt -t nat -X "${nftPrefix}_${i}"; + done + ;; + create) + output 2 "Creating TOR redirects " + dnsPort="$(grep -m1 DNSPort /etc/tor/torrc | awk -F: '{print $2}')" + trafficPort="$(grep -m1 TransPort /etc/tor/torrc | awk -F: '{print $2}')" + dnsPort="${dnsPort:-9053}"; trafficPort="${trafficPort:-9040}"; + for i in $chainsList; do + ipt -t nat -N "${nftPrefix}_${i}" + ipt -t nat -A "$i" -m mark --mark "0x0/${fw_mask}" -j "${nftPrefix}_${i}" + done + if resolver 'create_resolver_set' "$iface" 'dst' 'ip' && ips 'flush' "$iface" 'dst' 'ip'; then + set_name4="${ipsPrefix}_${iface}_4_dst_ip" + for i in $chainsList; do + i="$(str_to_lower "$i")" + ipt -t nat -I "${nftPrefix}_${i}" -p udp -m udp --dport 53 -m set --match-set "${set_name4}" dst -j REDIRECT --to-ports "$dnsPort" -m comment --comment "TorDNS-UDP" || s=1 + ipt -t nat -I "${nftPrefix}_${i}" -p tcp -m tcp --dport 80 -m set --match-set "${set_name4}" dst -j REDIRECT --to-ports "$trafficPort" -m comment --comment "TorHTTP-TCP" || s=1 + ipt -t nat -I "${nftPrefix}_${i}" -p udp -m udp --dport 80 -m set --match-set "${set_name4}" dst -j REDIRECT --to-ports "$trafficPort" -m comment --comment "TorHTTP-UDP" || s=1 + ipt -t nat -I "${nftPrefix}_${i}" -p tcp -m tcp --dport 443 -m set --match-set "${set_name4}" dst -j REDIRECT --to-ports "$trafficPort" -m comment --comment "TorHTTPS-TCP" || s=1 + ipt -t nat -I "${nftPrefix}_${i}" -p udp -m udp --dport 443 -m set --match-set "${set_name4}" dst -j REDIRECT --to-ports "$trafficPort" -m comment --comment "TorHTTPS-UDP" || s=1 + done + else + s=1 + fi + displayText="${iface}/53->${dnsPort}/80,443->${trafficPort}" + if [ "$s" -eq 0 ]; then + gatewaySummary="${gatewaySummary}${displayText}\\n" + output_ok + else + state add 'errorSummary' 'errorFailedSetup' "$displayText" + output_fail + fi + ;; + esac + return $s +} +interface_process_tor_nft() { + local s=0 iface="$1" action="$2" + local displayText set_name4 set_name6 + local dnsPort trafficPort + case "$action" in + reload) + displayText="${iface}/53->${dnsPort}/80,443->${trafficPort}" + gatewaySummary="${gatewaySummary}${displayText}\\n" + ;; + destroy) + ;; + create) + output 2 "Creating TOR redirects " + dnsPort="$(grep -m1 DNSPort /etc/tor/torrc | awk -F: '{print $2}')" + trafficPort="$(grep -m1 TransPort /etc/tor/torrc | awk -F: '{print $2}')" + dnsPort="${dnsPort:-9053}"; trafficPort="${trafficPort:-9040}"; + if resolver 'create_resolver_set' "$iface" 'dst' 'ip' && nftset 'flush' "$iface" 'dst' 'ip'; then + set_name4="${nftPrefix}_${iface}_4_dst_ip" + set_name6="${nftPrefix}_${iface}_6_dst_ip" + nft meta nfproto ipv4 udp daddr "@${set_name4}" dport 53 counter redirect to :"$dnsPort" comment "Tor-DNS-UDP-ipv4" || s=1 + nft meta nfproto ipv4 tcp daddr "@${set_name4}" dport 80 counter redirect to :"$trafficPort" comment "Tor-HTTP-TCP-ipv4" || s=1 + nft meta nfproto ipv4 udp daddr "@${set_name4}" dport 80 counter redirect to :"$trafficPort" comment "Tor-HTTP-UDP-ipv4" || s=1 + nft meta nfproto ipv4 tcp daddr "@${set_name4}" dport 443 counter redirect to :"$trafficPort" comment "Tor-HTTPS-TCP-ipv4" || s=1 + nft meta nfproto ipv4 udp daddr "@${set_name4}" dport 443 counter redirect to :"$trafficPort" comment "Tor-HTTPS-UDP-ipv4" || s=1 + nft6 meta nfproto ipv6 udp daddr "@${set_name6}" dport 53 counter redirect to :"$dnsPort" comment "Tor-DNS-UDP-ipv6" || s=1 + nft6 meta nfproto ipv6 tcp daddr "@${set_name6}" dport 80 counter redirect to :"$trafficPort" comment "Tor-HTTP-TCP-ipv6" || s=1 + nft6 meta nfproto ipv6 udp daddr "@${set_name6}" dport 80 counter redirect to :"$trafficPort" comment "Tor-HTTP-UDP-ipv6" || s=1 + nft6 meta nfproto ipv6 tcp daddr "@${set_name6}" dport 443 counter redirect to :"$trafficPort" comment "Tor-HTTPS-TCP-ipv6" || s=1 + nft6 meta nfproto ipv6 udp daddr "@${set_name6}" dport 443 counter redirect to :"$trafficPort" comment "Tor-HTTPS-UDP-ipv6" || s=1 + else + s=1 + fi + displayText="${iface}/53->${dnsPort}/80,443->${trafficPort}" + if [ "$s" -eq 0 ]; then + gatewaySummary="${gatewaySummary}${displayText}\\n" + output_ok + else + state add 'errorSummary' 'errorFailedSetup' "$displayText" + output_fail + fi + ;; + esac + return $s +} + +interface_routing() { + local action="$1" tid="$2" mark="$3" iface="$4" gw4="$5" dev="$6" gw6="$7" dev6="$8" priority="$9" + local dscp s=0 i ipv4_error=1 ipv6_error=1 + if [ -z "$tid" ] || [ -z "$mark" ] || [ -z "$iface" ]; then + return 1 + fi + case "$action" in + create) + if is_netifd_table "$iface"; then + ipv4_error=0 + $ip_full -4 rule del fwmark "${mark}/${fw_mask}" table "$tid" >/dev/null 2>&1 + $ip_full -4 rule add fwmark "${mark}/${fw_mask}" table "$tid" priority "$priority" || ipv4_error=1 + if is_nft; then + nft add chain inet "$nftTable" "${nftPrefix}_mark_${mark}" || ipv4_error=1 + nft add rule inet "$nftTable" "${nftPrefix}_mark_${mark} counter mark set mark and ${fw_maskXor} xor ${mark}" || ipv4_error=1 + nft add rule inet "$nftTable" "${nftPrefix}_mark_${mark} return" || ipv4_error=1 + else + ipt -t mangle -N "${iptPrefix}_MARK_${mark}" || ipv4_error=1 + ipt -t mangle -A "${iptPrefix}_MARK_${mark}" -j MARK --set-xmark "${mark}/${fw_mask}" || ipv4_error=1 + ipt -t mangle -A "${iptPrefix}_MARK_${mark}" -j RETURN || ipv4_error=1 + fi + if [ -n "$ipv6_enabled" ]; then + ipv6_error=0 + $ip_full -6 rule del fwmark "${mark}/${fw_mask}" table "$tid" >/dev/null 2>&1 + $ip_full -6 rule add fwmark "${mark}/${fw_mask}" table "$tid" priority "$priority" || ipv6_error=1 + fi + else + sed -i "/${ipTablePrefix}_${iface}/d" /etc/iproute2/rt_tables + $ip_full -4 rule del fwmark "${mark}/${fw_mask}" table "$tid" >/dev/null 2>&1 + $ip_full -4 route flush table "$tid" >/dev/null 2>&1 + if [ -n "$gw4" ] || [ "$strict_enforcement" -ne 0 ]; then + ipv4_error=0 + echo "$tid ${ipTablePrefix}_${iface}" >> /etc/iproute2/rt_tables + if [ -z "$gw4" ]; then + $ip_full -4 route add unreachable default table "$tid" >/dev/null 2>&1 || ipv4_error=1 + else + $ip_full -4 route add default via "$gw4" dev "$dev" table "$tid" >/dev/null 2>&1 || ipv4_error=1 + fi + # shellcheck disable=SC2086 + while read -r i; do + i="$(echo "$i" | sed 's/ linkdown$//')" + i="$(echo "$i" | sed 's/ onlink$//')" + idev="$(echo "$i" | grep -Eso 'dev [^ ]*' | awk '{print $2}')" + if ! is_supported_iface_dev "$idev"; then + $ip_full -4 route add $i table "$tid" >/dev/null 2>&1 || ipv4_error=1 + fi + done << EOF + $($ip_full -4 route list table main) +EOF + $ip_full -4 rule add fwmark "${mark}/${fw_mask}" table "$tid" priority "$priority" || ipv4_error=1 + if is_nft; then + nft add chain inet "$nftTable" "${nftPrefix}_mark_${mark}" || ipv4_error=1 + nft add rule inet "$nftTable" "${nftPrefix}_mark_${mark} counter mark set mark and ${fw_maskXor} xor ${mark}" || ipv4_error=1 + nft add rule inet "$nftTable" "${nftPrefix}_mark_${mark} return" || ipv4_error=1 + else + ipt -t mangle -N "${iptPrefix}_MARK_${mark}" || ipv4_error=1 + ipt -t mangle -A "${iptPrefix}_MARK_${mark}" -j MARK --set-xmark "${mark}/${fw_mask}" || ipv4_error=1 + ipt -t mangle -A "${iptPrefix}_MARK_${mark}" -j RETURN || ipv4_error=1 + fi + fi + if [ -n "$ipv6_enabled" ]; then + ipv6_error=0 + $ip_full -6 rule del fwmark "${mark}/${fw_mask}" table "$tid" >/dev/null 2>&1 + $ip_full -6 route flush table "$tid" >/dev/null 2>&1 + if { [ -n "$gw6" ] && [ "$gw6" != "::/0" ]; } || [ "$strict_enforcement" -ne 0 ]; then + if [ -z "$gw6" ] || [ "$gw6" = "::/0" ]; then + $ip_full -6 route add unreachable default table "$tid" || ipv6_error=1 + elif $ip_full -6 route list table main | grep -q " dev $dev6 "; then + while read -r i; do + i="$(echo "$i" | sed 's/ linkdown$//')" + i="$(echo "$i" | sed 's/ onlink$//')" + $ip_full -6 route add "$i" table "$tid" >/dev/null 2>&1 || ipv6_error=1 + done << EOF + $($ip_full -6 route list table main | grep " dev $dev6 ") +EOF + else + $ip_full -6 route add "$($ip_full -6 -o a show "$dev6" | awk '{print $4}')" dev "$dev6" table "$tid" >/dev/null 2>&1 || ipv6_error=1 + $ip_full -6 route add default dev "$dev6" table "$tid" >/dev/null 2>&1 || ipv6_error=1 + fi + fi + $ip_full -6 rule add fwmark "${mark}/${fw_mask}" table "$tid" priority "$priority" || ipv6_error=1 + fi + fi + if [ "$ipv4_error" -eq 0 ] || [ "$ipv6_error" -eq 0 ]; then + dscp="$(uci -q get "${packageName}".config."${iface}"_dscp)" + if is_nft; then + if [ "${dscp:-0}" -ge 1 ] && [ "${dscp:-0}" -le 63 ]; then + nft add rule inet "$nftTable" "${nftPrefix}_prerouting ip dscp ${dscp} goto ${nftPrefix}_mark_${mark}" || s=1 + fi + if [ "$iface" = "$icmp_interface" ]; then + nft add rule inet "$nftTable" "${nftPrefix}_output ip protocol icmp goto ${nftPrefix}_mark_${mark}" || s=1 + fi + else + if [ "${dscp:-0}" -ge 1 ] && [ "${dscp:-0}" -le 63 ]; then + ipt -t mangle -I "${iptPrefix}_PREROUTING" -m dscp --dscp "${dscp}" -g "${iptPrefix}_MARK_${mark}" || s=1 + fi + if [ "$iface" = "$icmp_interface" ]; then + ipt -t mangle -I "${iptPrefix}_OUTPUT" -p icmp -g "${iptPrefix}_MARK_${mark}" || s=1 + fi + fi + else + s=1 + fi + return "$s" + ;; + create_user_set) + [ -z "$createUserSets" ] && return 0; + if is_nft; then + nftset 'create_user_set' "$iface" 'dst' 'ip' 'user' '' "$mark" || s=1 + nftset 'create_user_set' "$iface" 'src' 'ip' 'user' '' "$mark" || s=1 + nftset 'create_user_set' "$iface" 'src' 'mac' 'user' '' "$mark" || s=1 + else + ips 'create_user_set' "$iface" 'dst' 'ip' 'user' '' "$mark" || s=1 + ips 'create_user_set' "$iface" 'src' 'ip' 'user' '' "$mark" || s=1 + ips 'create_user_set' "$iface" 'dst' 'net' 'user' '' "$mark" || s=1 + ips 'create_user_set' "$iface" 'src' 'net' 'user' '' "$mark" || s=1 + ips 'create_user_set' "$iface" 'src' 'mac' 'user' '' "$mark" || s=1 + fi + return "$s" + ;; + delete|destroy) + $ip_full rule del fwmark "${mark}/${fw_mask}" table "$tid" >/dev/null 2>&1 + if ! is_netifd_table "$iface"; then + $ip_full route flush table "$tid" >/dev/null 2>&1 + sed -i "/${ipTablePrefix}_${iface}/d" /etc/iproute2/rt_tables + fi + return "$s" + ;; + reload_interface) + is_netifd_table "$iface" && return 0; + ipv4_error=0 + $ip_full -4 rule del fwmark "${mark}/${fw_mask}" table "$tid" >/dev/null 2>&1 + $ip_full -4 route flush table "$tid" >/dev/null 2>&1 + if [ -n "$gw4" ] || [ "$strict_enforcement" -ne 0 ]; then + if [ -z "$gw4" ]; then + $ip_full -4 route add unreachable default table "$tid" >/dev/null 2>&1 || ipv4_error=1 + else + $ip_full -4 route add default via "$gw4" dev "$dev" table "$tid" >/dev/null 2>&1 || ipv4_error=1 + fi + $ip_full rule add fwmark "${mark}/${fw_mask}" table "$tid" priority "$priority" || ipv4_error=1 + fi + if [ -n "$ipv6_enabled" ]; then + ipv6_error=0 + $ip_full -6 rule del fwmark "${mark}/${fw_mask}" table "$tid" >/dev/null 2>&1 + $ip_full -6 route flush table "$tid" >/dev/null 2>&1 + if { [ -n "$gw6" ] && [ "$gw6" != "::/0" ]; } || [ "$strict_enforcement" -ne 0 ]; then + if [ -z "$gw6" ] || [ "$gw6" = "::/0" ]; then + $ip_full -6 route add unreachable default table "$tid" || ipv6_error=1 + elif $ip_full -6 route list table main | grep -q " dev $dev6 "; then + while read -r i; do + $ip_full -6 route add "$i" table "$tid" >/dev/null 2>&1 || ipv6_error=1 + done << EOF + $($ip_full -6 route list table main | grep " dev $dev6 ") +EOF + else + $ip_full -6 route add "$($ip_full -6 -o a show "$dev6" | awk '{print $4}')" dev "$dev6" table "$tid" >/dev/null 2>&1 || ipv6_error=1 + $ip_full -6 route add default dev "$dev6" table "$tid" >/dev/null 2>&1 || ipv6_error=1 + fi + fi + $ip_full -6 rule add fwmark "${mark}/${fw_mask}" table "$tid" priority "$priority" || ipv6_error=1 + fi + if [ "$ipv4_error" -eq 0 ] || [ "$ipv6_error" -eq 0 ]; then + s=0 + else + s=1 + fi + return "$s" + ;; + esac +} + +json_add_gateway() { + local action="$1" tid="$2" mark="$3" iface="$4" gw4="$5" dev4="$6" gw6="$7" dev6="$8" priority="$9" default="${10}" + json_add_object '' + json_add_string name "$iface" + json_add_string device_ipv4 "$dev4" + json_add_string gateway_ipv4 "$gw4" + json_add_string device_ipv6 "$dev6" + json_add_string gateway_ipv6 "$gw6" + if [ -n "$default" ]; then + json_add_boolean default true + else + json_add_boolean default false + fi + json_add_string action "$action" + json_add_string table_id "$tid" + json_add_string mark "$mark" + json_add_string priority "$priority" + json_close_object +} + +interface_process() { + local gw4 gw6 dev dev6 s=0 dscp iface="$1" action="$2" reloadedIface="$3" + local displayText dispDev dispGw4 dispGw6 dispStatus + + if [ "$iface" = 'all' ] && [ "$action" = 'prepare' ]; then + config_load 'network' + ifaceMark="$(printf '0x%06x' "$wan_mark")" + ifacePriority="$wan_ip_rules_priority" + return 0 + fi + + is_supported_interface "$iface" || return 0 + is_wan6 "$iface" && return 0 + [ $((ifaceMark)) -gt $((fw_mask)) ] && return 1 + + network_get_device dev "$iface" + if is_wan "$iface" && [ -n "$wanIface6" ] && str_contains "$wanIface6" "$iface"; then + network_get_device dev6 "$wanIface6" + fi + + [ -z "$dev6" ] && dev6="$dev" + [ -z "$ifaceMark" ] && ifaceMark="$(printf '0x%06x' "$wan_mark")" + [ -z "$ifacePriority" ] && ifacePriority="$wan_ip_rules_priority" + + ifaceTableID="$(get_rt_tables_id "$iface")" + [ -z "$ifaceTableID" ] && ifaceTableID="$(get_rt_tables_next_id)" + eval "mark_${iface//-/_}"='$ifaceMark' + eval "tid_${iface//-/_}"='$ifaceTableID' + pbr_get_gateway gw4 "$iface" "$dev" + pbr_get_gateway6 gw6 "$iface" "$dev6" + dispGw4="${gw4:-0.0.0.0}" + dispGw6="${gw6:-::/0}" + [ "$iface" != "$dev" ] && dispDev="$dev" + is_default_dev "$dev" && dispStatus="${__OK__}" + displayText="${iface}/${dispDev:+$dispDev/}${dispGw4}${ipv6_enabled:+/$dispGw6}" + + case "$action" in + create) + output 2 "Setting up routing for '$displayText' " + if interface_routing 'create' "$ifaceTableID" "$ifaceMark" "$iface" "$gw4" "$dev" "$gw6" "$dev6" "$ifacePriority" && \ + interface_routing 'create_user_set' "$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" + output_ok + else + state add 'errorSummary' 'errorFailedSetup' "$displayText" + output_fail + fi + ;; +# create_user_set) +# interface_routing 'create_user_set' "$ifaceTableID" "$ifaceMark" "$iface" "$gw4" "$dev" "$gw6" "$dev6" "$ifacePriority" +# ;; + destroy) + displayText="${iface}/${dispDev:+$dispDev/}${dispGw4}${ipv6_enabled:+/$dispGw6}" + output 2 "Removing routing for '$displayText' " + interface_routing 'destroy' "${ifaceTableID}" "${ifaceMark}" "${iface}" + output_ok + ;; + reload) + gatewaySummary="${gatewaySummary}${displayText}${dispStatus:+ $dispStatus}\\n" + ;; + reload_interface) + if [ "$iface" = "$reloadedIface" ]; then + 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" + output_ok + else + state add 'errorSummary' 'errorFailedReload' "$displayText" + output_fail + fi + else + gatewaySummary="${gatewaySummary}${displayText}${dispStatus:+ $dispStatus}\\n" + fi + ;; + esac +# ifaceTableID="$((ifaceTableID + 1))" + ifaceMark="$(printf '0x%06x' $((ifaceMark + wan_mark)))" + ifacePriority="$((ifacePriority + 1))" + return $s +} + +user_file_process() { + local shellBin="${SHELL:-/bin/ash}" + [ "$enabled" -gt 0 ] || return 0 + if [ ! -s "$path" ]; then + state add 'errorSummary' 'errorUserFileNotFound' "$path" + output_fail + return 1 + fi + if ! $shellBin -n "$path"; then + state add 'errorSummary' 'ererrorUserFileSyntax' "$path" + output_fail + return 1 + fi + output 2 "Running $path " +# shellcheck disable=SC1090 + if ! . "$path"; then + state add 'errorSummary' 'errorUserFileRunning' "$path" + if grep -q -w 'curl' "$path" && ! is_present 'curl'; then + state add 'errorSummary' 'errorUserFileNoCurl' "$path" + fi + output_fail + return 1 + else + output_ok + return 0 + fi +} + +on_firewall_reload() { + if [ -z "$(ubus_get_status 'gateways')" ]; then # service is not running, do not start it on firewall reload + logger -t "$packageName" "Reload on firewall action aborted: service not running." + return 0; + else + rc_procd start_service 'on_firewall_reload' "$1" + fi +} +on_interface_reload() { rc_procd start_service 'on_interface_reload' "$1"; } + +start_service() { + local resolverStoredHash resolverNewHash i reloadedIface param="$1" + local createUserSets + + load_environment 'on_start' "$(load_validate_config)" || return 1 + is_wan_up || return 1 + rm -f "$nftTempFile" + + case "$param" in + on_boot) + serviceStartTrigger='on_start' + ;; + on_firewall_reload) + serviceStartTrigger='on_start' + ;; + on_interface_reload) + serviceStartTrigger='on_interface_reload' + reloadedIface="$2" + ;; + on_reload) + serviceStartTrigger='on_reload' + ;; + on_restart) + serviceStartTrigger='on_start' + ;; + esac + + if [ -n "$reloadedIface" ] && ! is_supported_interface "$reloadedIface"; then + return 0 + fi + + if [ -n "$(ubus_get_status error)" ] || [ -n "$(ubus_get_status warning)" ]; then + serviceStartTrigger='on_start' + unset reloadedIface + elif ! is_service_running; then + serviceStartTrigger='on_start' + unset reloadedIface + elif [ -z "$(ubus_get_status gateway)" ]; then + serviceStartTrigger='on_start' + unset reloadedIface + elif [ "$serviceStartTrigger" = 'on_interface_reload' ] && \ + [ -z "$(ubus_get_interface "$reloadedIface" 'gateway_4')" ] && \ + [ -z "$(ubus_get_interface "$reloadedIface" 'gateway_6')" ]; then + serviceStartTrigger='on_start' + unset reloadedIface + else + serviceStartTrigger="${serviceStartTrigger:-on_start}" + fi + + if is_config_enabled 'include'; then + createUserSets='true' + fi + + procd_open_instance "main" + procd_set_param command /bin/true + procd_set_param stdout 1 + procd_set_param stderr 1 + procd_open_data + + case $serviceStartTrigger in + on_interface_reload) + output 1 "Reloading Interface: $reloadedIface " + json_add_array 'gateways' + interface_process 'all' 'prepare' + config_foreach interface_process 'interface' 'reload_interface' "$reloadedIface" + json_close_array + output 1 '\n' + ;; + on_reload) + traffic_killswitch 'insert' + resolver 'store_hash' + resolver 'cleanup_all' + resolver 'configure' + resolver 'init' + cleanup_main_chains + cleanup_sets + if ! is_nft; then + for i in $chainsList; do + i="$(str_to_upper "$i")" + ipt -t mangle -N "${iptPrefix}_${i}" + ipt -t mangle "$rule_create_option" "$i" -m mark --mark "0x0/${fw_mask}" -j "${iptPrefix}_${i}" + done + fi + json_add_array 'gateways' + interface_process 'all' 'prepare' + config_foreach interface_process 'interface' 'reload' + interface_process_tor 'tor' 'destroy' + is_tor_running && interface_process_tor 'tor' 'reload' + json_close_array + if is_config_enabled 'policy'; then + output 1 'Processing policies ' + config_load "$packageName" + config_foreach load_validate_policy 'policy' policy_process + output 1 '\n' + fi + if is_config_enabled 'include'; then + traffic_killswitch 'remove' + output 1 'Processing user file(s) ' + config_load "$packageName" + config_foreach load_validate_include 'include' user_file_process + output 1 '\n' + resolver 'init_end' + resolver 'compare_hash' && resolver 'restart' + else + resolver 'init_end' + resolver 'compare_hash' && resolver 'restart' + traffic_killswitch 'remove' + fi + ;; + on_start|*) + traffic_killswitch 'insert' + resolver 'store_hash' + resolver 'cleanup_all' + resolver 'configure' + resolver 'init' + cleanup_main_chains + cleanup_sets + cleanup_marking_chains + if ! is_nft; then + for i in $chainsList; do + i="$(str_to_upper "$i")" + ipt -t mangle -N "${iptPrefix}_${i}" + ipt -t mangle "$rule_create_option" "$i" -m mark --mark "0x0/${fw_mask}" -j "${iptPrefix}_${i}" + done + fi + output 1 'Processing interfaces ' + json_add_array 'gateways' + interface_process 'all' 'prepare' + config_foreach interface_process 'interface' 'create' + interface_process_tor 'tor' 'destroy' + is_tor_running && interface_process_tor 'tor' 'create' + json_close_array + ip route flush cache + output 1 '\n' + if is_config_enabled 'policy'; then + output 1 'Processing policies ' + config_load "$packageName" + config_foreach load_validate_policy 'policy' policy_process + output 1 '\n' + fi + if is_config_enabled 'include'; then + traffic_killswitch 'remove' + output 1 'Processing user file(s) ' + config_load "$packageName" + config_foreach load_validate_include 'include' user_file_process + output 1 '\n' + resolver 'init_end' + resolver 'compare_hash' && resolver 'restart' + else + resolver 'init_end' + resolver 'compare_hash' && resolver 'restart' + traffic_killswitch 'remove' + fi + ;; + esac + + if [ -z "$gatewaySummary" ]; then + state add 'errorSummary' 'errorNoGateways' + fi + json_add_object 'status' + [ -n "$gatewaySummary" ] && json_add_string 'gateways' "$gatewaySummary" + [ -n "$errorSummary" ] && json_add_string 'errors' "$errorSummary" + [ -n "$warningSummary" ] && json_add_string 'warnings' "$warningSummary" + if [ "$strict_enforcement" -ne 0 ] && str_contains "$gatewaySummary" '0.0.0.0'; then + json_add_string 'mode' "strict" + fi + json_close_object + procd_close_data + procd_close_instance +} + +service_started() { + if is_nft; then + [ -n "$gatewaySummary" ] && output "$serviceName (nft) started with gateways:\\n${gatewaySummary}" + else + [ -n "$gatewaySummary" ] && output "$serviceName (iptables) started with gateways:\\n${gatewaySummary}" + fi + state print 'errorSummary' + state print 'warningSummary' + if [ -n "$errorSummary" ]; then + return 2 + elif [ -n "$warningSummary" ]; then + return 1 + else + return 0 + fi +} + +service_triggers() { + local n + load_environment 'on_triggers' +# shellcheck disable=SC2034 + PROCD_RELOAD_DELAY=$(( procd_reload_delay * 1000 )) + procd_open_validate + load_validate_config + load_validate_policy + load_validate_include + procd_close_validate + procd_open_trigger + procd_add_reload_trigger 'openvpn' + procd_add_config_trigger "config.change" "${packageName}" /etc/init.d/${packageName} reload + for n in $ifacesSupported; do + procd_add_interface_trigger "interface.*" "$n" /etc/init.d/${packageName} on_interface_reload "$n" + done + procd_close_trigger + if [ "$serviceStartTrigger" = 'on_start' ]; then + output 3 "$serviceName monitoring interfaces: ${ifacesSupported}\\n" + fi +} + +stop_service() { + local i + load_environment 'on_stop' + is_service_running || return 0 + traffic_killswitch 'insert' + cleanup_main_chains + cleanup_sets + cleanup_marking_chains + output 1 'Resetting interfaces ' + config_load 'network' + config_foreach interface_process 'interface' 'destroy' + interface_process_tor 'tor' 'destroy' + output 1 "\\n" + ip route flush cache + unset ifaceMark + unset ifaceTableID + resolver 'store_hash' + resolver 'cleanup_all' + resolver 'compare_hash' && resolver 'restart' + traffic_killswitch 'remove' + if [ "$enabled" -ne 0 ]; then + if is_nft; then + output "$serviceName (nft) stopped "; output_okn; + else + output "$serviceName (iptables) stopped "; output_okn; + fi + fi +} + +status_service() { + local _SEPARATOR_='============================================================' + load_environment 'on_status' + if is_nft; then + status_service_nft "$@" + else + status_service_iptables "$@" + fi +} + +status_service_nft() { + local i dev dev6 wan_tid + + json_load "$(ubus call system board)"; json_select release; json_get_var dist distribution; json_get_var vers version + if [ -n "$wanIface4" ]; then + network_get_gateway wanGW4 "$wanIface4" + network_get_device dev "$wanIface4" + fi + if [ -n "$wanIface6" ]; then + network_get_device dev6 "$wanIface6" + wanGW6=$($ip_full -6 route show | grep -m1 " dev $dev6 " | awk '{print $1}') + [ "$wanGW6" = "default" ] && wanGW6=$($ip_full -6 route show | grep -m1 " dev $dev6 " | awk '{print $3}') + fi + while [ "${1:0:1}" = "-" ]; do param="${1//-/}"; eval "set_$param=1"; shift; done + [ -e "/var/${packageName}-support" ] && rm -f "/var/${packageName}-support" + status="$serviceName running on $dist $vers." + [ -n "$wanIface4" ] && status="$status WAN (IPv4): ${wanIface4}/${dev}/${wanGW4:-0.0.0.0}." + [ -n "$wanIface6" ] && status="$status WAN (IPv6): ${wanIface6}/${dev6}/${wanGW6:-::/0}." + + echo "$_SEPARATOR_" + echo "$packageName - environment" + echo "$status" + echo "$_SEPARATOR_" + dnsmasq --version 2>/dev/null | sed '/^$/,$d' + echo "$_SEPARATOR_" + echo "$packageName chains - policies" + for i in forward input output prerouting postrouting; do + "$nft" list table inet "$nftTable" | sed -n "/chain ${nftPrefix}_${i} {/,/\t}/p" + done + echo "$_SEPARATOR_" + echo "$packageName chains - marking" + for i in $(get_mark_nft_chains); do + "$nft" list table inet "$nftTable" | sed -n "/chain ${i} {/,/\t}/p" + done + echo "$_SEPARATOR_" + echo "$packageName nft sets" + for i in $(get_nft_sets); do + "$nft" list table inet "$nftTable" | sed -n "/set ${i} {/,/\t}/p" + done + if [ -s "$dnsmasqFile" ]; then + echo "$_SEPARATOR_" + echo "dnsmasq sets" + cat "$dnsmasqFile" + fi +# echo "$_SEPARATOR_" +# ip rule list | grep "${packageName}_" + echo "$_SEPARATOR_" + tableCount="$(grep -c "${packageName}_" /etc/iproute2/rt_tables)" || tableCount=0 + wan_tid=$(($(get_rt_tables_next_id)-tableCount)) + i=0; while [ $i -lt $tableCount ]; do + echo "IPv4 table $((wan_tid + i)) route: $($ip_full -4 route show table $((wan_tid + i)) | grep default)" + echo "IPv4 table $((wan_tid + i)) rule(s):" + $ip_full -4 rule list table "$((wan_tid + i))" + i=$((i + 1)) + done +} + +status_service_iptables() { + local dist vers out id s param status set_d set_p tableCount i=0 dev dev6 j wan_tid + + json_load "$(ubus call system board)"; json_select release; json_get_var dist distribution; json_get_var vers version + if [ -n "$wanIface4" ]; then + network_get_gateway wanGW4 "$wanIface4" + network_get_device dev "$wanIface4" + fi + if [ -n "$wanIface6" ]; then + network_get_device dev6 "$wanIface6" + wanGW6=$($ip_full -6 route show | grep -m1 " dev $dev6 " | awk '{print $1}') + [ "$wanGW6" = "default" ] && wanGW6=$($ip_full -6 route show | grep -m1 " dev $dev6 " | awk '{print $3}') + fi + while [ "${1:0:1}" = "-" ]; do param="${1//-/}"; eval "set_$param=1"; shift; done + [ -e "/var/${packageName}-support" ] && rm -f "/var/${packageName}-support" + status="$serviceName running on $dist $vers." + [ -n "$wanIface4" ] && status="$status WAN (IPv4): ${wanIface4}/${dev}/${wanGW4:-0.0.0.0}." + [ -n "$wanIface6" ] && status="$status WAN (IPv6): ${wanIface6}/${dev6}/${wanGW6:-::/0}." + { + echo "$status" + echo "$_SEPARATOR_" + dnsmasq --version 2>/dev/null | sed '/^$/,$d' + if [ -n "$1" ]; then + echo "$_SEPARATOR_" + echo "Resolving domains" + for i in $1; do + echo "$i: $(resolveip "$i" | tr '\n' ' ')" + done + fi + + echo "$_SEPARATOR_" + echo "Routes/IP Rules" + tableCount="$(grep -c "${packageName}_" /etc/iproute2/rt_tables)" || tableCount=0 + if [ -n "$set_d" ]; then route; else route | grep '^default'; fi + if [ -n "$set_d" ]; then ip rule list; fi + wan_tid=$(($(get_rt_tables_next_id)-tableCount)) + i=0; while [ $i -lt $tableCount ]; do + echo "IPv4 table $((wan_tid + i)) route: $($ip_full -4 route show table $((wan_tid + i)) | grep default)" + echo "IPv4 table $((wan_tid + i)) rule(s):" + $ip_full -4 rule list table "$((wan_tid + i))" + i=$((i + 1)) + done + + if [ -n "$ipv6_enabled" ]; then + i=0; while [ $i -lt $tableCount ]; do + $ip_full -6 route show table $((wan_tid + i)) | while read -r param; do + echo "IPv6 Table $((wan_tid + i)): $param" + done + i=$((i + 1)) + done + fi + + for j in Mangle NAT; do + if [ -z "$set_d" ]; then + for i in $chainsList; do + i="$(str_to_upper "$i")" + if iptables -v -t "$(str_to_lower $j)" -S "${iptPrefix}_${i}" >/dev/null 2>&1; then + echo "$_SEPARATOR_" + echo "$j IP Table: $i" + iptables -v -t "$(str_to_lower $j)" -S "${iptPrefix}_${i}" + if [ -n "$ipv6_enabled" ]; then + echo "$_SEPARATOR_" + echo "$j IPv6 Table: $i" + iptables -v -t "$(str_to_lower $j)" -S "${iptPrefix}_${i}" + fi + fi + done + else + echo "$_SEPARATOR_" + echo "$j IP Table" + iptables -L -t "$(str_to_lower $j)" + if [ -n "$ipv6_enabled" ]; then + echo "$_SEPARATOR_" + echo "$j IPv6 Table" + iptables -L -t "$(str_to_lower $j)" + fi + fi + i=0; ifaceMark="$wan_mark"; + while [ $i -lt $tableCount ]; do + if iptables -v -t "$(str_to_lower $j)" -S "${iptPrefix}_MARK_${ifaceMark}" >/dev/null 2>&1; then + echo "$_SEPARATOR_" + echo "$j IP Table MARK Chain: ${iptPrefix}_MARK_${ifaceMark}" + iptables -v -t "$(str_to_lower $j)" -S "${iptPrefix}_MARK_${ifaceMark}" + ifaceMark="$(printf '0x%06x' $((ifaceMark + wan_mark)))"; + fi + i=$((i + 1)) + done + done + + echo "$_SEPARATOR_" + echo "Current ipsets" + ipset save + if [ -s "$dnsmasqFile" ]; then + echo "$_SEPARATOR_" + echo "DNSMASQ sets" + cat "$dnsmasqFile" + fi + if [ -s "$aghIpsetFile" ]; then + echo "$_SEPARATOR_" + echo "AdGuardHome sets" + cat "$aghIpsetFile" + fi + echo "$_SEPARATOR_" + } | tee -a /var/${packageName}-support + if [ -n "$set_p" ]; then + printf "%b" "Pasting to paste.ee... " + if is_present 'curl' && is_variant_installed 'libopenssl' && is_installed 'ca-bundle'; then + json_init; json_add_string "description" "${packageName}-support" + json_add_array "sections"; json_add_object '0' + json_add_string "name" "$(uci -q get system.@system[0].hostname)" + json_add_string "contents" "$(cat /var/${packageName}-support)" + json_close_object; json_close_array; payload=$(json_dump) + out=$(curl -s -k "https://api.paste.ee/v1/pastes" -X "POST" -H "Content-Type: application/json" -H "X-Auth-Token:uVOJt6pNqjcEWu7qiuUuuxWQafpHhwMvNEBviRV2B" -d "$payload") + json_load "$out"; json_get_var id id; json_get_var s success + [ "$s" = "1" ] && printf "%b" "https://paste.ee/p/$id $__OK__\\n" || printf "%b" "$__FAIL__\\n" + [ -e "/var/${packageName}-support" ] && rm -f "/var/${packageName}-support" + else + printf "%b" "${__FAIL__}\\n" + printf "%b" "${_ERROR_}: The curl, libopenssl or ca-bundle packages were not found!\\nRun 'opkg update; opkg install curl libopenssl ca-bundle' to install them.\\n" + fi + else + printf "%b" "Your support details have been logged to '/var/${packageName}-support'. $__OK__\\n" + fi +} + +# shellcheck disable=SC2120 +load_validate_config() { + uci_load_validate "$packageName" "$packageName" "$1" "${2}${3:+ $3}" \ + 'enabled:bool:0' \ + 'procd_boot_delay:integer:0' \ + 'strict_enforcement:bool:1' \ + 'secure_reload:bool:0' \ + 'ipv6_enabled:bool:0' \ + 'resolver_set:or("", "none", "dnsmasq.ipset", "dnsmasq.nftset")' \ + 'verbosity:range(0,2):1' \ + "wan_mark:regex('0x[A-Fa-f0-9]{8}'):0x010000" \ + "fw_mask:regex('0x[A-Fa-f0-9]{8}'):0xff0000" \ + 'icmp_interface:or("","ignore", uci("network", "@interface"))' \ + 'ignored_interface:list(uci("network", "@interface"))' \ + 'supported_interface:list(uci("network", "@interface"))' \ + 'boot_timeout:integer:30' \ + 'wan_ip_rules_priority:uinteger:30000' \ + 'rule_create_option:or("", "add", "insert"):add' \ + 'procd_reload_delay:integer:0' \ + 'webui_supported_protocol:list(string)' +} + +# shellcheck disable=SC2120 +load_validate_policy() { + local name + local enabled + local interface + local proto + local chain + local src_addr + local src_port + local dest_addr + local dest_port + uci_load_validate "$packageName" 'policy' "$1" "${2}${3:+ $3}" \ + 'name:string:Untitled' \ + 'enabled:bool:1' \ + 'interface:or(uci("network", "@interface"),"ignore"):wan' \ + 'proto:or(string)' \ + 'chain:or("", "forward", "input", "output", "prerouting", "postrouting", "FORWARD", "INPUT", "OUTPUT", "PREROUTING", "POSTROUTING"):prerouting' \ + 'src_addr:list(neg(or(host,network,macaddr,string)))' \ + 'src_port:list(neg(or(portrange,string)))' \ + 'dest_addr:list(neg(or(host,network,string)))' \ + 'dest_port:list(neg(or(portrange,string)))' +} + +# shellcheck disable=SC2120 +load_validate_include() { + local path= + local enabled= + uci_load_validate "$packageName" 'include' "$1" "${2}${3:+ $3}" \ + 'path:file' \ + 'enabled:bool:0' +} diff --git a/net/pbr/files/etc/uci-defaults/90-pbr b/net/pbr/files/etc/uci-defaults/90-pbr new file mode 100644 index 000000000..237ebac58 --- /dev/null +++ b/net/pbr/files/etc/uci-defaults/90-pbr @@ -0,0 +1,34 @@ +#!/bin/sh +# shellcheck disable=SC1091,SC3037,SC3043 + +readonly __OK__='\033[0;32m[\xe2\x9c\x93]\033[0m' + +# Transition from vpn-policy-routing +if [ -s '/etc/config/vpn-policy-routing' ] && [ ! -s '/etc/config/pbr-opkg' ]; then + echo "Migrating vpn-policy-routing config file." + mv '/etc/config/pbr' '/etc/config/pbr-opkg' + sed 's/vpn-policy-routing/pbr/g' /etc/config/vpn-policy-routing > /etc/config/pbr + uci set vpn-policy-routing.config.enabled=0; uci commit vpn-policy-routing; +fi + +# Transition from older versions of pbr +sed -i 's/resolver_ipset/resolver_set/g' /etc/config/pbr +sed -i 's/iptables_rule_option/rule_create_option/g' /etc/config/pbr +sed -i "s/'FORWARD'/'forward'/g" /etc/config/pbr +sed -i "s/'INPUT'/'input'/g" /etc/config/pbr +sed -i "s/'OUTPUT'/'output'/g" /etc/config/pbr +sed -i "s/'PREROUTING'/'prerouting'/g" /etc/config/pbr +sed -i "s/'POSTROUTING'/'postrouting'/g" /etc/config/pbr +sed -i "s/option fw_mask '0x\(.*\)'/option fw_mask '\1'/g" /etc/config/pbr +sed -i "s/option wan_mark '0x\(.*\)'/option wan_mark '\1'/g" /etc/config/pbr + +uci -q batch <<-EOT + delete firewall.pbr + set firewall.pbr='include' + set firewall.pbr.fw4_compatible='1' + set firewall.pbr.type='script' + set firewall.pbr.path='/usr/share/pbr/pbr.firewall.include' + commit firewall +EOT + +exit 0 diff --git a/net/pbr/files/etc/uci-defaults/91-pbr b/net/pbr/files/etc/uci-defaults/91-pbr new file mode 100644 index 000000000..0d759c278 --- /dev/null +++ b/net/pbr/files/etc/uci-defaults/91-pbr @@ -0,0 +1,58 @@ +#!/bin/sh +# shellcheck disable=SC1091,SC3037,SC3043 + +readonly packageName='pbr' +readonly __OK__='\033[0;32m[\xe2\x9c\x93]\033[0m' + +pbr_iface_setup() { + local iface="${1}" + local proto + config_get proto "${iface}" proto + case "${iface}" in + (lan|loopback) return 0 ;; + esac + case "${proto}" in + (gre*|nebula|relay|vti*|vxlan|xfrm) return 0 ;; + (none) + uci -q set "network.${iface}_rt=route" + uci -q set "network.${iface}_rt.interface=${iface}" + uci -q set "network.${iface}_rt.target=0.0.0.0/0" + uci -q set "network.${iface}_rt6=route6" + uci -q set "network.${iface}_rt6.interface=${iface}" + uci -q set "network.${iface}_rt6.target=::/0" + ;; + esac + echo -en "Setting up ${packageName} routing tables for ${iface}... " + uci -q set "network.${iface}.ip4table=${packageName}_${iface%6}" + uci -q set "network.${iface}.ip6table=${packageName}_${iface%6}" + if ! grep -q -E -e "^[0-9]+\s+${packageName}_${iface%6}$" /etc/iproute2/rt_tables; then + sed -i -e "\$a $(($(sort -r -n /etc/iproute2/rt_tables | grep -o -E -m 1 "^[0-9]+")+1))\t${packageName}_${iface%6}" \ + /etc/iproute2/rt_tables + fi + echo -e "${__OK__}" +} + +. /lib/functions.sh +. /lib/functions/network.sh +config_load network +config_foreach pbr_iface_setup interface +network_flush_cache +network_find_wan iface +network_find_wan6 iface6 +# shellcheck disable=SC2154 +[ -n "$iface" ] && uci -q batch << EOF +set network.default='rule' +set network.default.lookup='${packageName}_${iface%6}' +set network.default.priority='80000' +EOF +[ -n "$iface6" ] && uci -q batch << EOF +set network.default6='rule6' +set network.default6.lookup='${packageName}_${iface6%6}' +set network.default6.priority='80000' +EOF +uci commit network +echo -en "Restarting network... " +/etc/init.d/network restart +echo -e "${__OK__}" + +exit 0 diff --git a/net/pbr/files/usr/share/nftables.d/chain-post/mangle_forward/30-pbr.nft b/net/pbr/files/usr/share/nftables.d/chain-post/mangle_forward/30-pbr.nft new file mode 100644 index 000000000..d11ad8472 --- /dev/null +++ b/net/pbr/files/usr/share/nftables.d/chain-post/mangle_forward/30-pbr.nft @@ -0,0 +1 @@ +jump pbr_forward comment "Jump into pbr forward chain"; diff --git a/net/pbr/files/usr/share/nftables.d/chain-post/mangle_input/30-pbr.nft b/net/pbr/files/usr/share/nftables.d/chain-post/mangle_input/30-pbr.nft new file mode 100644 index 000000000..b3ce9db95 --- /dev/null +++ b/net/pbr/files/usr/share/nftables.d/chain-post/mangle_input/30-pbr.nft @@ -0,0 +1 @@ +jump pbr_input comment "Jump into pbr input chain"; diff --git a/net/pbr/files/usr/share/nftables.d/chain-post/mangle_output/30-pbr.nft b/net/pbr/files/usr/share/nftables.d/chain-post/mangle_output/30-pbr.nft new file mode 100644 index 000000000..c98514bc5 --- /dev/null +++ b/net/pbr/files/usr/share/nftables.d/chain-post/mangle_output/30-pbr.nft @@ -0,0 +1 @@ +jump pbr_output comment "Jump into pbr output chain"; diff --git a/net/pbr/files/usr/share/nftables.d/chain-post/mangle_postrouting/30-pbr.nft b/net/pbr/files/usr/share/nftables.d/chain-post/mangle_postrouting/30-pbr.nft new file mode 100644 index 000000000..cd5d1b4d3 --- /dev/null +++ b/net/pbr/files/usr/share/nftables.d/chain-post/mangle_postrouting/30-pbr.nft @@ -0,0 +1 @@ +jump pbr_postrouting comment "Jump into pbr postrouting chain"; diff --git a/net/pbr/files/usr/share/nftables.d/chain-post/mangle_prerouting/30-pbr.nft b/net/pbr/files/usr/share/nftables.d/chain-post/mangle_prerouting/30-pbr.nft new file mode 100644 index 000000000..a4471d376 --- /dev/null +++ b/net/pbr/files/usr/share/nftables.d/chain-post/mangle_prerouting/30-pbr.nft @@ -0,0 +1 @@ +jump pbr_prerouting comment "Jump into pbr prerouting chain"; diff --git a/net/pbr/files/usr/share/nftables.d/table-post/30-pbr.nft b/net/pbr/files/usr/share/nftables.d/table-post/30-pbr.nft new file mode 100644 index 000000000..4dd9b2813 --- /dev/null +++ b/net/pbr/files/usr/share/nftables.d/table-post/30-pbr.nft @@ -0,0 +1,5 @@ +chain pbr_forward {} +chain pbr_input {} +chain pbr_output {} +chain pbr_prerouting {} +chain pbr_postrouting {} diff --git a/net/pbr/files/usr/share/pbr/pbr.firewall.include b/net/pbr/files/usr/share/pbr/pbr.firewall.include new file mode 100644 index 000000000..3fe906ee1 --- /dev/null +++ b/net/pbr/files/usr/share/pbr/pbr.firewall.include @@ -0,0 +1,5 @@ +#!/bin/sh +if [ -x /etc/init.d/pbr ] && /etc/init.d/pbr enabled; then + logger -t "pbr" "Reloading pbr due to $ACTION of firewall" + /etc/init.d/pbr on_firewall_reload "$ACTION" +fi diff --git a/net/pbr/files/usr/share/pbr/pbr.user.aws b/net/pbr/files/usr/share/pbr/pbr.user.aws new file mode 100644 index 000000000..bf398dd66 --- /dev/null +++ b/net/pbr/files/usr/share/pbr/pbr.user.aws @@ -0,0 +1,33 @@ +#!/bin/sh +# This file is heavily based on code from https://github.com/Xentrk/netflix-vpn-bypass/blob/master/IPSET_Netflix.sh + +TARGET_SET='pbr_wan_4_dst_ip_user' +TARGET_IPSET='pbr_wan_4_dst_net_user' +TARGET_TABLE='inet fw4' +TARGET_URL="https://ip-ranges.amazonaws.com/ip-ranges.json" +TARGET_DL_FILE="/var/pbr_tmp_aws_ip_ranges" +TARGET_NFT_FILE="/var/pbr_tmp_aws_ip_ranges.nft" +[ -z "$nft" ] && nft="$(command -v nft)" +_ret=1 + +if [ ! -s "$TARGET_DL_FILE" ]; then + uclient-fetch --no-check-certificate -qO- "$TARGET_URL" 2>/dev/null | grep "ip_prefix" | sed 's/^.*\"ip_prefix\": \"//; s/\",//' > "$TARGET_DL_FILE" +fi + +if [ -s "$TARGET_DL_FILE" ]; then + if ipset -q list "$TARGET_IPSET" >/dev/null 2>&1; then + if awk -v ipset="$TARGET_IPSET" '{print "add " ipset " " $1}' "$TARGET_DL_FILE" | ipset restore -!; then + _ret=0 + fi + elif [ -n "$nft" ] && [ -x "$nft" ] && "$nft" list set "$TARGET_TABLE" "$TARGET_SET" >/dev/null 2>&1; then + printf "add element %s %s { " "$TARGET_TABLE" "$TARGET_SET" > "$TARGET_NFT_FILE" + awk '{printf $1 ", "}' "$TARGET_DL_FILE" >> "$TARGET_NFT_FILE" + printf " } " >> "$TARGET_NFT_FILE" + if "$nft" -f "$TARGET_NFT_FILE"; then + rm -f "$TARGET_NFT_FILE" + _ret=0 + fi + fi +fi + +return $_ret diff --git a/net/pbr/files/usr/share/pbr/pbr.user.netflix b/net/pbr/files/usr/share/pbr/pbr.user.netflix new file mode 100644 index 000000000..54f54e0d3 --- /dev/null +++ b/net/pbr/files/usr/share/pbr/pbr.user.netflix @@ -0,0 +1,49 @@ +#!/bin/sh +# This file is heavily based on code from https://github.com/Xentrk/netflix-vpn-bypass/blob/master/IPSET_Netflix.sh +# Credits to https://forum.openwrt.org/u/dscpl for api.hackertarget.com code. +# Credits to https://github.com/kkeker and https://github.com/tophirsch for api.bgpview.io code. + +TARGET_SET='pbr_wan_4_dst_ip_user' +TARGET_IPSET='pbr_wan_4_dst_net_user' +TARGET_TABLE='inet fw4' +TARGET_ASN='2906' +TARGET_DL_FILE="/var/pbr_tmp_AS${TARGET_ASN}" +TARGET_NFT_FILE="/var/pbr_tmp_AS${TARGET_ASN}.nft" +#DB_SOURCE='ipinfo.io' +#DB_SOURCE='api.hackertarget.com' +DB_SOURCE='api.bgpview.io' +[ -z "$nft" ] && nft="$(command -v nft)" +_ret=1 + +if [ ! -s "$TARGET_DL_FILE" ]; then + if [ "$DB_SOURCE" = "ipinfo.io" ]; then + TARGET_URL="https://ipinfo.io/AS${TARGET_ASN}" + uclient-fetch --no-check-certificate -qO- "$TARGET_URL" 2>/dev/null | grep -E "a href.*${TARGET_ASN}\/" | grep -v ":" | sed "s/^.*//" > "$TARGET_DL_FILE" + fi + if [ "$DB_SOURCE" = "api.hackertarget.com" ]; then + TARGET_URL="https://api.hackertarget.com/aslookup/?q=AS${TARGET_ASN}" + uclient-fetch --no-check-certificate -qO- "$TARGET_URL" 2>/dev/null | sed '1d' > "$TARGET_DL_FILE" + fi + if [ "$DB_SOURCE" = "api.bgpview.io" ]; then + TARGET_URL="https://api.bgpview.io/asn/${TARGET_ASN}/prefixes" + uclient-fetch --no-check-certificate -qO- "$TARGET_URL" 2>/dev/null | jsonfilter -e '@.data.ipv4_prefixes[*].prefix' > "$TARGET_DL_FILE" + fi +fi + +if [ -s "$TARGET_DL_FILE" ]; then + if ipset -q list "$TARGET_IPSET" >/dev/null 2>&1; then + if awk -v ipset="$TARGET_IPSET" '{print "add " ipset " " $1}' "$TARGET_DL_FILE" | ipset restore -!; then + _ret=0 + fi + elif [ -n "$nft" ] && [ -x "$nft" ] && "$nft" list set "$TARGET_TABLE" "$TARGET_SET" >/dev/null 2>&1; then + printf "add element %s %s { " "$TARGET_TABLE" "$TARGET_SET" > "$TARGET_NFT_FILE" + awk '{printf $1 ", "}' "$TARGET_DL_FILE" >> "$TARGET_NFT_FILE" + printf " } " >> "$TARGET_NFT_FILE" + if "$nft" -f "$TARGET_NFT_FILE"; then + rm -f "$TARGET_NFT_FILE" + _ret=0 + fi + fi +fi + +return $_ret diff --git a/net/vpn-policy-routing/test.sh b/net/pbr/test.sh similarity index 100% rename from net/vpn-policy-routing/test.sh rename to net/pbr/test.sh diff --git a/net/vpn-policy-routing/Makefile b/net/vpn-policy-routing/Makefile deleted file mode 100644 index 21c6b9339..000000000 --- a/net/vpn-policy-routing/Makefile +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright 2017-2018 Stan Grishin (stangri@melmac.net) -# This is free software, licensed under the GNU General Public License v3. - -include $(TOPDIR)/rules.mk - -PKG_NAME:=vpn-policy-routing -PKG_VERSION:=0.3.4 -PKG_RELEASE:=8 -PKG_LICENSE:=GPL-3.0-or-later -PKG_MAINTAINER:=Stan Grishin - -include $(INCLUDE_DIR)/package.mk - -define Package/vpn-policy-routing - SECTION:=net - CATEGORY:=Network - TITLE:=VPN Policy-Based Routing Service - URL:=https://docs.openwrt.melmac.net/vpn-policy-routing/ - DEPENDS:=+jshn +ipset +iptables +resolveip +kmod-ipt-ipset +iptables-mod-ipopt +ip-full - PKGARCH:=all -endef - -define Package/vpn-policy-routing/description -This service allows policy-based routing for L2TP, Openconnect, OpenVPN, PPTP and Wireguard tunnels and WAN interface. -Policies can specify domains, local IPs/subnets and ports, as well as remote IPs/subnets and ports. -endef - -define Package/vpn-policy-routing/conffiles -/etc/config/vpn-policy-routing -endef - -define Build/Configure -endef - -define Build/Compile -endef - -define Package/vpn-policy-routing/install - $(INSTALL_DIR) $(1)/etc/init.d $(1)/etc/config $(1)/etc/hotplug.d/firewall $(1)/etc/ - $(INSTALL_BIN) ./files/vpn-policy-routing.init $(1)/etc/init.d/vpn-policy-routing - $(SED) "s|^\(PKG_VERSION\).*|\1='$(PKG_VERSION)-$(PKG_RELEASE)'|" $(1)/etc/init.d/vpn-policy-routing - $(INSTALL_CONF) ./files/vpn-policy-routing.config $(1)/etc/config/vpn-policy-routing - $(INSTALL_DATA) ./files/vpn-policy-routing.firewall.hotplug $(1)/etc/hotplug.d/firewall/70-vpn-policy-routing - $(INSTALL_DATA) ./files/vpn-policy-routing.aws.user $(1)/etc/vpn-policy-routing.aws.user - $(INSTALL_DATA) ./files/vpn-policy-routing.netflix.user $(1)/etc/vpn-policy-routing.netflix.user -endef - -define Package/vpn-policy-routing/postinst - #!/bin/sh - # check if we are on real system - if [ -z "$${IPKG_INSTROOT}" ]; then - /etc/init.d/vpn-policy-routing enable - fi - exit 0 -endef - -define Package/vpn-policy-routing/prerm - #!/bin/sh - # check if we are on real system - if [ -z "$${IPKG_INSTROOT}" ]; then - echo "Stopping service and removing rc.d symlink for vpn-policy-routing" - /etc/init.d/vpn-policy-routing stop || true - /etc/init.d/vpn-policy-routing disable || true - fi - exit 0 -endef - -$(eval $(call BuildPackage,vpn-policy-routing)) diff --git a/net/vpn-policy-routing/files/README.md b/net/vpn-policy-routing/files/README.md deleted file mode 100644 index 98d7efc62..000000000 --- a/net/vpn-policy-routing/files/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# README - -README has been moved to [https://docs.openwrt.melmac.net/vpn-policy-routing/](https://docs.openwrt.melmac.net/vpn-policy-routing/). diff --git a/net/vpn-policy-routing/files/vpn-policy-routing.aws.user b/net/vpn-policy-routing/files/vpn-policy-routing.aws.user deleted file mode 100644 index a00770be7..000000000 --- a/net/vpn-policy-routing/files/vpn-policy-routing.aws.user +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -# This file is heavily based on code from https://github.com/Xentrk/netflix-vpn-bypass/blob/master/IPSET_Netflix.sh - -TARGET_IPSET='wan' - -TARGET_URL="https://ip-ranges.amazonaws.com/ip-ranges.json" -TARGET_FNAME="/var/vpn-policy-routing_tmp_aws_ip_ranges" - -_ret=1 - -if [ ! -s "$TARGET_FNAME" ]; then - curl "$TARGET_URL" 2>/dev/null | grep "ip_prefix" | sed 's/^.*\"ip_prefix\": \"//; s/\",//' > "$TARGET_FNAME" -fi -if [ -s "$TARGET_FNAME" ]; then - awk -v ipset="$TARGET_IPSET" '{print "add " ipset " " $1}' "$TARGET_FNAME" | ipset restore -! && _ret=0 -fi -rm -f "$TARGET_FNAME" - -return $_ret diff --git a/net/vpn-policy-routing/files/vpn-policy-routing.config b/net/vpn-policy-routing/files/vpn-policy-routing.config deleted file mode 100644 index ed6f01cdd..000000000 --- a/net/vpn-policy-routing/files/vpn-policy-routing.config +++ /dev/null @@ -1,30 +0,0 @@ -config vpn-policy-routing 'config' - option enabled '0' - option verbosity '2' - option strict_enforcement '1' - option src_ipset '0' - option dest_ipset '0' - option resolver_ipset 'dnsmasq.ipset' - option ipv6_enabled '0' - list ignored_interface 'vpnserver wgserver' - option boot_timeout '30' - option iptables_rule_option 'append' - option procd_reload_delay '1' - option webui_enable_column '0' - option webui_protocol_column '0' - option webui_chain_column '0' - option webui_show_ignore_target '0' - option webui_sorting '1' - list webui_supported_protocol 'tcp' - list webui_supported_protocol 'udp' - list webui_supported_protocol 'tcp udp' - list webui_supported_protocol 'icmp' - list webui_supported_protocol 'all' - -config include - option path '/etc/vpn-policy-routing.netflix.user' - option enabled 0 - -config include - option path '/etc/vpn-policy-routing.aws.user' - option enabled 0 diff --git a/net/vpn-policy-routing/files/vpn-policy-routing.firewall.hotplug b/net/vpn-policy-routing/files/vpn-policy-routing.firewall.hotplug deleted file mode 100755 index 3932b2b62..000000000 --- a/net/vpn-policy-routing/files/vpn-policy-routing.firewall.hotplug +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -[ "$ACTION" = "reload" ] || exit 0 - -logger -t "vpn-policy-routing" "Reloading vpn-policy-routing due to $ACTION of firewall" -/etc/init.d/vpn-policy-routing reload diff --git a/net/vpn-policy-routing/files/vpn-policy-routing.init b/net/vpn-policy-routing/files/vpn-policy-routing.init deleted file mode 100755 index 1962ed529..000000000 --- a/net/vpn-policy-routing/files/vpn-policy-routing.init +++ /dev/null @@ -1,1322 +0,0 @@ -#!/bin/sh /etc/rc.common -# Copyright 2017-2020 Stan Grishin (stangri@melmac.net) -# shellcheck disable=SC2039,SC1091,SC2018,SC2019,SC3043,SC3057,SC3060 -PKG_VERSION='dev-test' - -# sysctl net.ipv4.conf.default.rp_filter=1 -# sysctl net.ipv4.conf.all.rp_filter=1 - -# shellcheck disable=SC2034 -START=94 -# shellcheck disable=SC2034 -USE_PROCD=1 - -if type extra_command 1>/dev/null 2>&1; then - extra_command 'support' "Generates output required to troubleshoot routing issues - Use '-d' option for more detailed output - Use '-p' option to automatically upload data under VPR paste.ee account - WARNING: while paste.ee uploads are unlisted, they are still publicly available - List domain names after options to include their lookup in report" - extra_command 'version' 'Show version information' - extra_command 'reload_interface' 'Reload specific interface only' -else -# shellcheck disable=SC2034 - EXTRA_COMMANDS='support version' -# shellcheck disable=SC2034 - EXTRA_HELP=" support Generates output required to troubleshoot routing issues - Use '-d' option for more detailed output - Use '-p' option to automatically upload data under VPR paste.ee account - WARNING: while paste.ee uploads are unlisted, they are still publicly available - List domain names after options to include their lookup in report" -fi - -readonly packageName='vpn-policy-routing' -readonly serviceName="$packageName $PKG_VERSION" -readonly PIDFile="/var/run/${packageName}.pid" -readonly jsonFile="/var/run/${packageName}.json" -readonly dnsmasqFile="/var/dnsmasq.d/${packageName}" -readonly sharedMemoryOutput="/dev/shm/$packageName-output" -readonly _OK_='\033[0;32m\xe2\x9c\x93\033[0m' -readonly _FAIL_='\033[0;31m\xe2\x9c\x97\033[0m' -readonly __OK__='\033[0;32m[\xe2\x9c\x93]\033[0m' -readonly __FAIL__='\033[0;31m[\xe2\x9c\x97]\033[0m' -readonly _ERROR_='\033[0;31mERROR\033[0m' -readonly _WARNING_='\033[0;33mWARNING\033[0m' - -gatewaySummary=''; errorSummary=''; warningSummary=''; -serviceEnabled=''; verbosity=''; strictMode=''; -wanTableID=''; wanMark=''; fwMask=''; -ipv6Enabled=''; srcIpset=''; destIpset=''; resolverIpset=''; -wanIface4=''; wanIface6=''; ifaceMark=''; ifaceTableID=''; -ifAll=''; ifSupported=''; ignoredIfaces=''; supportedIfaces=''; icmpIface=''; -wanGW4=''; wanGW6=''; bootTimeout=''; insertOption=''; -webuiChainColumn=''; webuiShowIgnore=''; dnsmasqIpsetSupported=''; -procdReloadDelay=''; -usedChainsList='PREROUTING' -ipsetSupported='true' -configLoaded='false' - -version() { echo "$PKG_VERSION"; } -output_ok() { output 1 "$_OK_"; output 2 "$__OK__\\n"; } -output_okn() { output 1 "$_OK_\\n"; output 2 "$__OK__\\n"; } -output_fail() { s=1; output 1 "$_FAIL_"; output 2 "$__FAIL__\\n"; } -output_failn() { output 1 "$_FAIL_\\n"; output 2 "$__FAIL__\\n"; } -str_replace() { printf "%b" "$1" | sed -e "s/$(printf "%b" "$2")/$(printf "%b" "$3")/g"; } -str_replace() { echo "${1//$2/$3}"; } -str_contains() { [ -n "$2" ] && [ "${1//$2}" != "$1" ]; } -str_contains_word() { echo "$1" | grep -q -w "$2"; } -str_to_lower() { echo "$1" | tr 'A-Z' 'a-z'; } -str_extras_to_underscore() { echo "$1" | tr '[\. ~`!@#$%^&*()\+/,<>?//;:]' '_'; } -str_extras_to_space() { echo "$1" | tr ';{}' ' '; } - -output() { -# Can take a single parameter (text) to be output at any verbosity -# Or target verbosity level and text to be output at specifc verbosity - local msg memmsg logmsg - if [ $# -ne 1 ]; then - if [ $((verbosity & $1)) -gt 0 ] || [ "$verbosity" = "$1" ]; then shift; else return 0; fi - fi - [ -t 1 ] && printf "%b" "$1" - msg="${1//$serviceName /service }"; - if [ "$(printf "%b" "$msg" | wc -l)" -gt 0 ]; then - [ -s "$sharedMemoryOutput" ] && memmsg="$(cat "$sharedMemoryOutput")" - logmsg="$(printf "%b" "${memmsg}${msg}" | sed 's/\x1b\[[0-9;]*m//g')" - logger -t "${packageName:-service} [$$]" "$(printf "%b" "$logmsg")" - rm -f "$sharedMemoryOutput" - else - printf "%b" "$msg" >> "$sharedMemoryOutput" - fi -} -is_present() { command -v "$1" >/dev/null 2>&1; } -is_installed() { [ -s "/usr/lib/opkg/info/${1}.control" ]; } -is_variant_installed() { [ "$(echo /usr/lib/opkg/info/"${1}"*.control)" != "/usr/lib/opkg/info/${1}*.control" ]; } - -build_ifAll() { ifAll="${ifAll}${1} "; } -build_ifSupported() { is_supported_interface "$1" && ifSupported="${ifSupported}${1} "; } -vpr_find_iface() { - local iface i param="$2" - [ "$param" = 'wan6' ] || param='wan' - "network_find_${param}" iface - is_tunnel "$iface" && unset iface - if [ -z "$iface" ]; then - for i in $ifAll; do - if "is_${param}" "$i"; then break; else unset i; fi - done - fi - eval "$1"='${iface:-$i}' -} -vpr_get_gateway() { - local iface="$2" dev="$3" gw - network_get_gateway gw "$iface" - if [ -z "$gw" ] || [ "$gw" = '0.0.0.0' ]; then - gw="$(ip -4 a list dev "$dev" 2>/dev/null | grep inet | awk '{print $2}' | awk -F "/" '{print $1}')" - fi - eval "$1"='$gw' -} -vpr_get_gateway6() { - local iface="$2" dev="$3" gw - network_get_gateway6 gw "$iface" - if [ -z "$gw" ] || [ "$gw" = '::/0' ] || [ "$gw" = '::0/0' ] || [ "$gw" = '::' ]; then - gw="$(ip -6 a list dev "$dev" 2>/dev/null | grep inet6 | awk '{print $2}')" - fi - eval "$1"='$gw' -} -is_l2tp() { local proto; proto=$(uci -q get network."$1".proto); [ "${proto:0:4}" = "l2tp" ]; } -is_oc() { local proto; proto=$(uci -q get network."$1".proto); [ "${proto:0:11}" = "openconnect" ]; } -is_ovpn() { local dev i; for i in ifname device; do [ -z "$dev" ] && dev="$(uci -q get "network.${1}.${i}")"; done; [ "${dev:0:3}" = "tun" ] || [ "${dev:0:3}" = "tap" ] || [ -f "/sys/devices/virtual/net/${dev}/tun_flags" ]; } -is_pptp() { local proto; proto=$(uci -q get network."$1".proto); [ "${proto:0:4}" = "pptp" ]; } -is_tor() { [ "$(str_to_lower "$1")" = "tor" ]; } -is_tor_running() { - local ret=0 - if [ -s "/etc/tor/torrc" ]; then - json_load "$(ubus call service list "{ 'name': 'tor' }")" - json_select 'tor'; json_select 'instances'; json_select 'instance1'; - json_get_var ret 'running'; json_cleanup - fi - if [ "$ret" = "0" ]; then return 1; else return 0; fi -} -is_wg() { local proto; proto=$(uci -q get network."$1".proto); [ "${proto:0:9}" = "wireguard" ]; } -is_tunnel() { is_l2tp "$1" || is_oc "$1" || is_ovpn "$1" || is_pptp "$1" || is_tor "$1" || is_wg "$1"; } -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_ignored_interface() { str_contains_word "$ignoredIfaces" "$1"; } -is_supported_interface() { str_contains_word "$supportedIfaces" "$1" || { ! is_ignored_interface "$1" && { is_wan "$1" || is_wan6 "$1" || is_tunnel "$1"; }; }; } -is_mac_address() { expr "$1" : '[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]$' >/dev/null; } -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_family_mismatch() { ( is_netmask "${1//!}" && is_ipv6 "${2//!}" ) || ( is_ipv6 "${1//!}" && is_netmask "${2//!}" ); } -is_ipv6_link_local() { [ "${1:0:4}" = "fe80" ]; } -is_ipv6_unique_local() { [ "${1:0:2}" = "fc" ] || [ "${1:0:2}" = "fd" ]; } -is_ipv6_global() { [ "${1:0:4}" = "2001" ]; } -# is_ipv6_global() { is_ipv6 "$1" && ! is_ipv6_link_local "$1" && ! is_ipv6_link_local "$1"; } -is_netmask() { local ip="${1%/*}"; [ "$ip" != "$1" ] && is_ipv4 "$ip"; } -is_domain() { str_contains "$1" '[a-zA-Z]'; } -is_phys_dev() { [ "${1:0:1}" = "@" ] && ip l show | grep -E -q "^\\d+\\W+${1:1}"; } -is_turris() { /bin/ubus -S call system board | /bin/grep 'Turris' | /bin/grep -q '15.05'; } -is_chaos_calmer() { ubus -S call system board | grep -q 'Chaos Calmer'; } -dnsmasq_kill() { killall -q -s HUP dnsmasq; } -dnsmasq_restart() { output 3 'Restarting DNSMASQ '; if /etc/init.d/dnsmasq restart >/dev/null 2>&1; then output_okn; else output_failn; fi; } -is_default_dev() { [ "$1" = "$(ip -4 r | grep -m1 'dev' | grep -Eso 'dev [^ ]*' | awk '{print $2}')" ]; } -is_supported_iface_dev() { - for n in $ifSupported; do - if [ "$1" = "$(uci -q get "network.${n}.ifname" || echo "$n")" ] || \ - [ "$1" = "$(uci -q get "network.${n}.device" || echo "$n")" ] || \ - [ "$1" = "$(uci -q get "network.${n}.proto")-${n}" ] ; then return 0; fi - done - return 1 -} -is_supported_protocol () { grep -o '^[^#]*' /etc/protocols | grep -w -v '0' | grep . | awk '{print $1}' | grep -q "$1"; } -append_chains_targets() { - local chain iface name - config_get name "$1" 'name' 'blank' - config_get chain "$1" 'chain' 'PREROUTING' - config_get iface "$1" 'interface' - if ! str_contains_word "$usedChainsList" "$chain"; then - usedChainsList="$usedChainsList $chain" - if [ "$chain" != 'PREROUTING' ] && [ "$webuiChainColumn" != '1' ]; then - warningSummary="${warningSummary}$_WARNING_: Chain '$chain' is used by a policy '$name', but a WebUI setting to show chains column (webui_chain_column) is disabled!\\n" - fi - fi - if [ "$iface" = 'ignore' ] && ! str_contains_word "$supportedIfaces" 'ignore'; then - supportedIfaces="$supportedIfaces ignore" - if [ "$webuiShowIgnore" != '1' ]; then - warningSummary="${warningSummary}$_WARNING_: The 'ignore' target is used by a policy '$name', but a WebUI setting to show 'ignore' target (webui_show_ignore_target) is disabled!\\n" - fi - fi -} - -load_package_config() { - [ "$configLoaded" = 'false' ] || return 0 - - config_load "$packageName" - config_get_bool serviceEnabled 'config' 'enabled' 0 - config_get_bool strictMode 'config' 'strict_enforcement' 1 - config_get_bool ipv6Enabled 'config' 'ipv6_enabled' 0 - config_get_bool srcIpset 'config' 'src_ipset' 0 - config_get_bool destIpset 'config' 'dest_ipset' 0 - config_get resolverIpset 'config' 'resolver_ipset' 'dnsmasq.ipset' - config_get verbosity 'config' 'verbosity' '2' - config_get wanTableID 'config' 'wan_tid' '201' - config_get wanMark 'config' 'wan_mark' '0x010000' - config_get fwMask 'config' 'fw_mask' '0xff0000' - config_get icmpIface 'config' 'icmp_interface' - config_get ignoredIfaces 'config' 'ignored_interface' - config_get supportedIfaces 'config' 'supported_interface' - config_get bootTimeout 'config' 'boot_timeout' '30' - config_get insertOption 'config' 'iptables_rule_option' 'append' - config_get procdReloadDelay 'config' 'procd_reload_delay' '0' - config_get_bool webuiChainColumn 'config' 'webui_chain_column' '0' - config_get_bool webuiShowIgnore 'config' 'webui_show_ignore_target' '0' - config_foreach append_chains_targets 'policy' - - if [ -z "${verbosity##*[!0-9]*}" ] || [ "$verbosity" -lt 0 ] || [ "$verbosity" -gt 2 ]; then - verbosity=2 - fi - - . /lib/functions/network.sh - . /usr/share/libubox/jshn.sh - mkdir -p "${PIDFile%/*}" - mkdir -p "${jsonFile%/*}" - mkdir -p "${dnsmasqFile%/*}" - - if [ -n "$icmpIface" ] && ! str_contains_word "$usedChainsList" 'OUTPUT'; then - usedChainsList="$usedChainsList OUTPUT" - fi - - case $insertOption in - insert|-i|-I) insertOption='-I';; - append|-a|-A|*) insertOption='-A';; - esac - - [ "$resolverIpset" = 'dnsmasq.ipset' ] && dnsmasqIpsetSupported='true' - if dnsmasq -v 2>/dev/null | grep -q 'no-ipset' || ! dnsmasq -v 2>/dev/null | grep -q -w 'ipset'; then - unset dnsmasqIpsetSupported - if [ -n "$dnsmasqIpsetSupported" ]; then - errorSummary="${errorSummary}${_ERROR_}: Resolver ipset support (dnsmasq.ipset) is enabled in $packageName, but DNSMASQ ipsets are not supported on this system!\\n" - fi - fi - if ! ipset help hash:net >/dev/null 2>&1; then - unset ipsetSupported - if [ -n "$dnsmasqIpsetSupported" ]; then - errorSummary="${errorSummary}${_ERROR_}: DNSMASQ ipsets are supported, but ipset is either not installed or installed ipset does not support 'hash:net' type!\\n" - unset dnsmasqIpsetSupported - fi - if [ "$destIpset" -ne 0 ]; then - errorSummary="${errorSummary}${_ERROR_}: Destination ipset support is enabled in $packageName, but ipset is either not installed or installed ipset does not support 'hash:net' type!\\n" - destIpset=0 - fi - if [ "$srcIpset" -ne 0 ]; then - errorSummary="${errorSummary}${_ERROR_}: Source ipset support is enabled in $packageName, but ipset is either not installed or installed ipset does not support 'hash:net' type!\\n" - srcIpset=0 - fi - fi - if ! ipset help hash:mac >/dev/null 2>&1; then - if [ "$srcIpset" -ne 0 ]; then - errorSummary="${errorSummary}${_ERROR_}: Source ipset support is enabled in $packageName, but ipset is either not installed or installed ipset does not support 'hash:mac' type!\\n" - srcIpset=0 - fi - fi - - configLoaded='true' -} - -is_enabled() { - load_package_config - if [ "$serviceEnabled" -eq 0 ]; then - if [ "$1" = 'on_start' ]; then - errorSummary="${errorSummary}${_ERROR_}: ${packageName} is currently disabled.\\n" - errorSummary="${errorSummary}Enable ${packageName} from WebUI or run the following commands:\\n" - errorSummary="${errorSummary}uci set $packageName.config.enabled='1'; uci commit $packageName;\\n" - fi - return 1 - fi -} - -load_network() { - if [ -z "$ifAll" ]; then - config_load 'network' - config_foreach build_ifAll 'interface' - fi - vpr_find_iface wanIface4 'wan' - [ "$ipv6Enabled" -ne 0 ] && vpr_find_iface wanIface6 'wan6' - [ -n "$wanIface4" ] && network_get_gateway wanGW4 "$wanIface4" - [ -n "$wanIface6" ] && network_get_gateway6 wanGW6 "$wanIface6" - wanGW="${wanGW4:-$wanGW6}" - unset ifSupported - config_load 'network' - config_foreach build_ifSupported 'interface' -} - -is_wan_up() { - local sleepCount=1 - load_network - while [ -z "$wanGW" ] ; do - load_network - if [ $((sleepCount)) -gt $((bootTimeout)) ] || [ -n "$wanGW" ]; then break; fi - output "$serviceName waiting for wan gateway...\\n" - sleep 1 - network_flush_cache - sleepCount=$((sleepCount+1)) - done - if [ -n "$wanGW" ]; then - return 0 - else - errorSummary="${errorSummary}${_ERROR_}: ${serviceName} failed to discover WAN gateway!\\n" - return 1 - fi -} - -ipt_cleanup() { - local i - for i in PREROUTING FORWARD INPUT OUTPUT; do - while iptables -t mangle -D $i -m mark --mark 0x0/0xff0000 -j VPR_${i} >/dev/null 2>&1; do : ; done - done - for i in PREROUTING FORWARD INPUT OUTPUT; do - while iptables -t mangle -D $i -j VPR_${i} >/dev/null 2>&1; do : ; done - done -} - -# shellcheck disable=SC2086 -ipt() { - local d failFlagIpv4=1 failFlagIpv6=1 - for d in "${*//-A/-D}" "${*//-I/-D}" "${*//-N/-F}" "${*//-N/-X}"; do - [ "$d" != "$*" ] && { iptables $d >/dev/null 2>&1; ip6tables $d >/dev/null 2>&1; } - done - - d="$*"; iptables $d >/dev/null 2>&1 && failFlagIpv4=0; - if [ "$ipv6Enabled" -gt 0 ]; then ip6tables $d >/dev/null 2>&1 && failFlagIpv6=0; fi - - [ "$failFlagIpv4" -eq 0 ] || [ "$failFlagIpv6" -eq 0 ] -} - -# shellcheck disable=SC2086 -ips() { - local command="$1" ipset="${2//-/_}" param="$3" comment="$4" appendix failFlag=0 - if str_contains "$ipset" '_ip'; then - ipset="${ipset//_ip}"; appendix='_ip'; - elif str_contains "$ipset" '_mac'; then - ipset="${ipset//_mac}"; appendix='_mac'; - fi - - case "$command" in - add_dnsmasq) - [ "$resolverIpset" = "dnsmasq.ipset" ] || return 1 - if [ -z "$dnsmasqIpsetSupported" ]; then - warningSummary="${warningSummary}${_WARNING_}: The 'resolver_ipset' is set to 'dnsmasq.ipset', but DNSMASQ ipsets are not supported on this system!\\n" - failFlag=1 - elif [ "$ipv6Enabled" -ne 0 ]; then - echo "ipset=/${param}/${ipset},${ipset}6 # $comment" >> "$dnsmasqFile" || failFlag=1 - else - echo "ipset=/${param}/${ipset} # $comment" >> "$dnsmasqFile" || failFlag=1 - fi - ;; - add) - if [ -z "$appendix" ] && [ "$destIpset" -eq 0 ]; then return 1; fi - if [ -n "$appendix" ] && [ "$srcIpset" -eq 0 ]; then return 1; fi - if [ "$ipv6Enabled" -ne 0 ] && [ "$appendix" != "_mac" ]; then - ipset -q -! $command "${ipset}6${appendix}" $param comment "$comment" || failFlag=1 - fi - ipset -q -! $command "${ipset}${appendix}" $param comment "$comment" || failFlag=1 - ;; - create) - if [ "$ipv6Enabled" -ne 0 ] && [ "$appendix" != "_mac" ]; then - ipset -q -! "$command" "${ipset}6${appendix}" $param family inet6 || failFlag=1 - fi - ipset -q -! "$command" "${ipset}${appendix}" $param || failFlag=1 - ;; - destroy|flush) - ipset -q -! "$command" "${ipset}6${appendix}" 2>/dev/null || failFlag=1 - ipset -q -! "$command" "${ipset}${appendix}" 2>/dev/null || failFlag=1 - return 0 - ;; - esac - return $failFlag -} - -insert_tor_policy() { - local comment="$1" iface="$2" laddr="$3" lport="$4" raddr="$5" rport="$6" proto chain - proto="$(str_to_lower "$7")" - chain="${8:-PREROUTING}" - if [ -n "${laddr}${lport}${rport}" ]; then - processPolicyWarning="${processPolicyWarning}${_WARNING_}: Please unset 'src_addr', 'src_port' and 'dest_port' for policy '$comment'\\n" - fi - if [ -n "$proto" ] && [ "$proto" != "all" ]; then - processPolicyWarning="${processPolicyWarning}${_WARNING_}: Please unset 'proto' or set 'proto' to 'all' for policy '$comment'\\n" - fi - if [ "$chain" != "PREROUTING" ]; then - processPolicyWarning="${processPolicyWarning}${_WARNING_}: Please unset 'chain' or set 'chain' to 'PREROUTING' for policy '$comment'\\n" - fi - ips 'add' "${iface}" "$raddr" "${comment}: $raddr" || processPolicyError="${processPolicyError}${_ERROR_}: ipset 'add' $iface $raddr\\n" - return 0 -} - -insert_policy() { - local comment="$1" iface="$2" laddr="$3" lport="$4" raddr="$5" rport="$6" proto chain - local mark param i valueNeg value dest ipInsertOption="-A" - proto="$(str_to_lower "$7")" - chain="${8:-PREROUTING}" - mark=$(eval echo "\$mark_${iface//-/_}") - if [ "$ipv6Enabled" -eq 0 ] && ( is_ipv6 "$laddr" || is_ipv6 "$raddr" ); then - processPolicyError="${processPolicyError}${_ERROR_}: Skipping IPv6 policy '$comment' as IPv6 support is disabled\\n" - return 1 - fi - - if [ -n "$mark" ]; then - dest="-g VPR_MARK${mark}" - elif [ "$iface" = "ignore" ]; then - dest="-j RETURN" - else - processPolicyError="${processPolicyError}${_ERROR_}: Unknown fw_mark for ${iface}\\n" - return 0 - fi - - if [ -z "$proto" ]; then - if [ -n "$lport" ] || [ -n "$rport" ]; then - proto='tcp udp' - else - proto='all' - fi - fi - - if is_family_mismatch "$laddr" "$raddr"; then - processPolicyError="${processPolicyError}${_ERROR_}: Mismatched IP family between '$laddr' and '$raddr' in policy '$comment'\\n" - return 0 - fi - - for i in $proto; do - if [ "$i" = 'all' ]; then - param="-t mangle ${ipInsertOption} VPR_${chain} $dest" - elif ! is_supported_protocol "$i"; then - processPolicyError="${processPolicyError}${_ERROR_}: Unknown protocol '$i' in policy '$comment'\\n" - return 0 - else - param="-t mangle ${ipInsertOption} VPR_${chain} $dest -p $i" - fi - - if [ -n "$laddr" ]; then - if [ "${laddr:0:1}" = "!" ]; then - valueNeg='!'; value="${laddr:1}" - else - unset valueNeg; value="$laddr"; - fi - if is_phys_dev "$value"; then - param="$param $valueNeg -m physdev --physdev-in ${value:1}" - elif is_mac_address "$value"; then - param="$param -m mac $valueNeg --mac-source $value" - else - param="$param $valueNeg -s $value" - fi - fi - - if [ -n "$lport" ]; then - if [ "${lport:0:1}" = "!" ]; then - valueNeg='!'; value="${lport:1}" - else - unset valueNeg; value="$lport"; - fi - param="$param -m multiport $valueNeg --sport ${value//-/:}" - fi - - if [ -n "$raddr" ]; then - if [ "${raddr:0:1}" = "!" ]; then - valueNeg='!'; value="${raddr:1}" - else - unset valueNeg; value="$raddr"; - fi - param="$param $valueNeg -d $value" - fi - - if [ -n "$rport" ]; then - if [ "${rport:0:1}" = "!" ]; then - valueNeg='!'; value="${rport:1}" - else - unset valueNeg; value="$rport"; - fi - param="$param -m multiport $valueNeg --dport ${value//-/:}" - fi - - [ -n "$comment" ] && param="$param -m comment --comment $(str_extras_to_underscore "$comment")" - ipt "$param" || processPolicyError="${processPolicyError}${_ERROR_}: iptables $param\\n" - done - return 0 -} - -r_process_policy(){ - local comment="$1" iface="$2" laddr="$3" lport="$4" raddr="$5" rport="$6" proto="$7" chain="$8" resolved_laddr resolved_raddr i ipsFailFlag - if str_contains "$laddr" '[ ;\{\}]'; then - for i in $(str_extras_to_space "$laddr"); do [ -n "$i" ] && r_process_policy "$comment" "$iface" "$i" "$lport" "$raddr" "$rport" "$proto" "$chain"; done - return 0 - elif str_contains "$lport" '[ ;\{\}]'; then - for i in $(str_extras_to_space "$lport"); do [ -n "$i" ] && r_process_policy "$comment" "$iface" "$laddr" "$i" "$raddr" "$rport" "$proto" "$chain"; done - return 0 - elif str_contains "$raddr" '[ ;\{\}]'; then - for i in $(str_extras_to_space "$raddr"); do [ -n "$i" ] && r_process_policy "$comment" "$iface" "$laddr" "$lport" "$i" "$rport" "$proto" "$chain"; done - return 0 - elif str_contains "$rport" '[ ;\{\}]'; then - for i in $(str_extras_to_space "$rport"); do [ -n "$i" ] && r_process_policy "$comment" "$iface" "$laddr" "$lport" "$raddr" "$i" "$proto" "$chain"; done - return 0 - fi - - # start non-recursive processing - # process TOR, netmask, physical device and mac-address separately, so we don't send them to resolveip - if is_tor "$iface"; then - insert_tor_policy "$comment" "$iface" "$laddr" "$lport" "$raddr" "$rport" "$proto" "$chain" - elif is_phys_dev "$laddr"; then - insert_policy "$comment" "$iface" "$laddr" "$lport" "$raddr" "$rport" "$proto" "$chain" - elif [ -n "$laddr" ] && [ -z "${lport}${raddr}${rport}" ] && [ "$chain" = 'PREROUTING' ]; then - if is_mac_address "$laddr"; then - if [ -n "$proto" ] && [ "$proto" != 'all' ] && [ "$srcIpset" -ne 0 ]; then - processPolicyWarning="${processPolicyWarning}${_WARNING_}: Please unset 'proto' or set 'proto' to 'all' for policy: '$comment', mac-address: '$laddr'\\n" - fi - ips 'add' "${iface}_mac" "$laddr" "${comment}: $laddr" || ipsFailFlag=1 - else - if [ -n "$proto" ] && [ "$proto" != "all" ] && [ "$srcIpset" -ne 0 ]; then - processPolicyWarning="${processPolicyWarning}${_WARNING_}: Please unset 'proto' or set 'proto' to 'all' for policy: '$comment', source: '$laddr'\\n" - fi - ips 'add' "${iface}_ip" "$laddr" "${comment}: $laddr" || ipsFailFlag=1 - fi - elif [ -n "$raddr" ] && [ -z "${laddr}${lport}${rport}" ] && [ "$chain" = 'PREROUTING' ]; then - if [ -n "$proto" ] && [ "$proto" != 'all' ]; then - processPolicyWarning="${processPolicyWarning}${_WARNING_}: Please unset 'proto' or set 'proto' to 'all' for policy: '$comment', destination: '$raddr'\\n" - fi - if is_domain "$raddr"; then - ips 'add_dnsmasq' "${iface}" "$raddr" "${comment}" || ipsFailFlag=1 - else - ips 'add' "${iface}" "$raddr" "${comment}: $raddr" || ipsFailFlag=1 - fi - else - ipsFailFlag=1 - fi - [ -n "$ipsFailFlag" ] || return 0; - if is_mac_address "$laddr"; then - insert_policy "$comment" "$iface" "$laddr" "$lport" "$raddr" "$rport" "$proto" "$chain" - elif is_netmask "$laddr" || is_netmask "$raddr"; then - insert_policy "$comment" "$iface" "$laddr" "$lport" "$raddr" "$rport" "$proto" "$chain" - else - [ -n "$laddr" ] && resolved_laddr="$(resolveip "$laddr")" - [ -n "$raddr" ] && resolved_raddr="$(resolveip "$raddr")" - if [ -n "$resolved_laddr" ] && [ "$resolved_laddr" != "$laddr" ]; then - for i in $resolved_laddr; do [ -n "$i" ] && r_process_policy "$comment $laddr" "$iface" "$i" "$lport" "$raddr" "$rport" "$proto" "$chain"; done - elif [ -n "$resolved_raddr" ] && [ "$resolved_raddr" != "$raddr" ]; then - for i in $resolved_raddr; do [ -n "$i" ] && r_process_policy "$comment $raddr" "$iface" "$laddr" "$lport" "$i" "$rport" "$proto" "$chain"; done - else - insert_policy "$comment" "$iface" "$laddr" "$lport" "$raddr" "$rport" "$proto" "$chain" - fi - fi -} - -process_policy(){ - local name comment iface laddr lport raddr rport param mark processPolicyError processPolicyWarning proto chain enabled - config_get comment "$1" 'comment' - config_get name "$1" 'name' 'blank' - config_get iface "$1" 'interface' - config_get laddr "$1" 'src_addr' - config_get lport "$1" 'src_port' - config_get raddr "$1" 'dest_addr' - config_get rport "$1" 'dest_port' - config_get proto "$1" 'proto' - config_get chain "$1" 'chain' 'PREROUTING' - config_get_bool enabled "$1" 'enabled' 1 - - [ "$enabled" -gt 0 ] || return 0 - proto="$(str_to_lower "$proto")" - [ "$proto" = 'auto' ] && unset proto - - comment="${comment:-$name}" - output 2 "Routing '$comment' via $iface " - - if [ -z "$comment" ]; then - errorSummary="${errorSummary}${_ERROR_}: Policy name is empty\\n" - output_fail; return 1; - fi - if [ -z "${laddr}${lport}${raddr}${rport}" ]; then - errorSummary="${errorSummary}${_ERROR_}: Policy '$comment' missing all IPs/ports\\n" - output_fail; return 1; - fi - if [ -z "$iface" ]; then - errorSummary="${errorSummary}${_ERROR_}: Policy '$comment' has no assigned interface\\n" - output_fail; return 1; - fi - if ! is_supported_interface "$iface"; then - errorSummary="${errorSummary}${_ERROR_}: Policy '$comment' has unknown interface: '${iface}'\\n" - output_fail; return 1; - fi - - lport="${lport// / }"; lport="${lport// /,}"; lport="${lport//,\!/ !}"; - rport="${rport// / }"; rport="${rport// /,}"; rport="${rport//,\!/ !}"; - r_process_policy "$comment" "$iface" "$laddr" "$lport" "$raddr" "$rport" "$proto" "$chain" - if [ -n "$processPolicyWarning" ]; then - warningSummary="${warningSummary}${processPolicyWarning}\\n" - fi - if [ -n "$processPolicyError" ]; then - output_fail - errorSummary="${errorSummary}${processPolicyError}\\n" - else - output_ok - fi -} - -table_destroy(){ - local tid="$1" iface="$2" mark="$3" - if [ -n "$tid" ] && [ -n "$iface" ] && [ -n "$mark" ]; then - ipt -t mangle -F "VPR_MARK${mark}" - ipt -t mangle -X "VPR_MARK${mark}" - ip -4 rule del fwmark "$mark" table "$tid" >/dev/null 2>&1 - ip -6 rule del fwmark "$mark" table "$tid" >/dev/null 2>&1 - ip -4 rule del table "$tid" >/dev/null 2>&1 - ip -6 rule del table "$tid" >/dev/null 2>&1 - ip -4 route flush table "$tid" >/dev/null 2>&1 - ip -6 route flush table "$tid" >/dev/null 2>&1 - ips 'flush' "${iface}"; ips 'destroy' "${iface}"; - ips 'flush' "${iface}_ip"; ips 'destroy' "${iface}_ip"; - ips 'flush' "${iface}_mac"; ips 'destroy' "${iface}_mac"; - ip -4 route flush cache - ip -6 route flush cache - sed -i "/$iface/d" /etc/iproute2/rt_tables - return 0 - else - return 1 - fi -} - -# shellcheck disable=SC2086 -table_create(){ - local tid="$1" mark="$2" iface="$3" gw4="$4" dev="$5" gw6="$6" dev6="$7" match="$8" dscp s=0 i ipv4_error=0 ipv6_error=1 - - if [ -z "$tid" ] || [ -z "$mark" ] || [ -z "$iface" ]; then - return 1 - fi - - table_destroy "$tid" "$iface" "$mark" - - if [ -n "$gw4" ] || [ "$strictMode" -ne 0 ]; then - echo "$tid" "$iface" >> /etc/iproute2/rt_tables - if [ -z "$gw4" ]; then - ip -4 route add unreachable default table "$tid" >/dev/null 2>&1 || ipv4_error=1 - else - ip -4 route add default via "$gw4" dev "$dev" table "$tid" >/dev/null 2>&1 || ipv4_error=1 - fi -# ip -4 route list table main | grep -v 'br-lan' | while read -r i; do - ip -4 route list table main | while read -r i; do - idev="$(echo "$i" | grep -Eso 'dev [^ ]*' | awk '{print $2}')" - if ! is_supported_iface_dev "$idev"; then - ip -4 route add $i table "$tid" >/dev/null 2>&1 || ipv4_error=1 - fi - done - ip -4 route flush cache || ipv4_error=1 - ip -4 rule add fwmark "${mark}/${fwMask}" table "$tid" || ipv4_error=1 - ipt -t mangle -N "VPR_MARK${mark}" || ipv4_error=1 - ipt -t mangle -A "VPR_MARK${mark}" -j MARK --set-xmark "${mark}/${fwMask}" || ipv4_error=1 - ipt -t mangle -A "VPR_MARK${mark}" -j RETURN || ipv4_error=1 - fi - - if [ "$ipv6Enabled" -ne 0 ]; then - ipv6_error=0 - if { [ -n "$gw6" ] && [ "$gw6" != "::/0" ]; } || [ "$strictMode" -ne 0 ]; then - if [ -z "$gw6" ] || [ "$gw6" = "::/0" ]; then - ip -6 route add unreachable default table "$tid" || ipv6_error=1 - else - ip -6 route list table main | grep " dev $dev6 " | while read -r i; do - ip -6 route add $i table "$tid" >/dev/null 2>&1 || ipv6_error=1 - done - fi - ip -6 route flush cache || ipv6_error=1 - ip -6 rule add fwmark "${mark}/${fwMask}" table "$tid" || ipv6_error=1 - fi - fi - - if [ $ipv4_error -eq 0 ] || [ $ipv6_error -eq 0 ]; then - dscp="$(uci -q get "${packageName}".config."${iface}"_dscp)" - if [ "${dscp:-0}" -ge 1 ] && [ "${dscp:-0}" -le 63 ]; then - ipt -t mangle -I VPR_PREROUTING -m dscp --dscp "${dscp}" -g "VPR_MARK${mark}" || s=1 - fi - if [ -n "$ipsetSupported" ] && { [ -n "$dnsmasqIpsetSupported" ] || [ "$destIpset" -ne 0 ]; }; then - if ips 'create' "${iface}" 'hash:net comment' && ips 'flush' "${iface}"; then - for i in $usedChainsList; do - ipt -t mangle -I VPR_${i} -m set --match-set "${iface}" dst -g "VPR_MARK${mark}" || s=1 - if [ "$ipv6Enabled" -ne 0 ]; then ipt -t mangle -I VPR_${i} -m set --match-set "${iface}6" dst -g "VPR_MARK${mark}" || s=1; fi - done - else - s=1 - fi - fi - if [ -n "$ipsetSupported" ] && [ "$srcIpset" -ne 0 ]; then - if ips 'create' "${iface}_ip" 'hash:net comment' && ips 'flush' "${iface}_ip"; then - ipt -t mangle -I VPR_PREROUTING -m set --match-set "${iface}_ip" src -g "VPR_MARK${mark}" || s=1 - if [ "$ipv6Enabled" -ne 0 ]; then ipt -t mangle -I VPR_PREROUTING -m set --match-set "${iface}6_ip" src -g "VPR_MARK${mark}" || s=1; fi - else - s=1 - fi - if ips 'create' "${iface}_mac" 'hash:mac comment' && ips 'flush' "${iface}_mac"; then - ipt -t mangle -I VPR_PREROUTING -m set --match-set "${iface}_mac" src -g "VPR_MARK${mark}" || s=1 - else - s=1 - fi - fi - if [ "$iface" = "$icmpIface" ]; then - ipt -t mangle -I VPR_OUTPUT -p icmp -g "VPR_MARK${mark}" || s=1 - fi - else - s=1 - fi - - return $s -} - -table_reload() { - local tid="$1" mark="$2" iface="$3" gw4="$4" dev="$5" gw6="$6" dev6="$7" match="$8" dscp s=0 i ipv4_error=0 ipv6_error=1 - - if [ -z "$tid" ] || [ -z "$mark" ] || [ -z "$iface" ]; then - return 1 - fi - - ip -4 route del default table "$tid" >/dev/null 2>&1 - if [ -n "$gw4" ] || [ "$strictMode" -ne 0 ]; then - if [ -z "$gw4" ]; then - ip -4 route add unreachable default table "$tid" >/dev/null 2>&1 || ipv4_error=1 - else - ip -4 route add default via "$gw4" dev "$dev" table "$tid" >/dev/null 2>&1 || ipv4_error=1 - fi - ip -4 route flush cache || ipv4_error=1 - ip -4 rule del fwmark "${mark}/${fwMask}" table "$tid" >/dev/null 2>&1 - ip -4 rule add fwmark "${mark}/${fwMask}" table "$tid" || ipv4_error=1 - fi - - if [ "$ipv6Enabled" -ne 0 ]; then - ip -6 route del default table "$tid" >/dev/null 2>&1 - ipv6_error=0 - if { [ -n "$gw6" ] && [ "$gw6" != "::/0" ]; } || [ "$strictMode" -ne 0 ]; then - if [ -z "$gw6" ] || [ "$gw6" = "::/0" ]; then - ip -6 route add unreachable default table "$tid" || ipv6_error=1 - else - ip -6 route list table main | grep " dev $dev6 " | while read -r i; do - ip -6 route add "$i" table "$tid" >/dev/null 2>&1 || ipv6_error=1 - done - fi - ip -6 route flush cache || ipv6_error=1 - ip -6 rule del fwmark "${mark}/${fwMask}" table "$tid" >/dev/null 2>&1 - ip -6 rule add fwmark "${mark}/${fwMask}" table "$tid" || ipv6_error=1 - fi - fi - - if [ $ipv4_error -eq 0 ] || [ $ipv6_error -eq 0 ]; then - dscp="$(uci -q get "${packageName}".config."${iface}"_dscp)" - if [ "${dscp:-0}" -ge 1 ] && [ "${dscp:-0}" -le 63 ]; then - ipt -t mangle -I VPR_PREROUTING -m dscp --dscp "${dscp}" -g "VPR_MARK${mark}" || s=1 - fi - if [ "$iface" = "$icmpIface" ]; then - ipt -t mangle -I VPR_OUTPUT -p icmp -g "VPR_MARK${mark}" || s=1 - fi - else - s=1 - fi - - return $s -} - -process_interface(){ - local gw4 gw6 dev dev6 s=0 dscp iface="$1" action="$2" match="$3" displayText - - is_supported_interface "$iface" || return 0 - is_wan6 "$iface" && return 0 - [ $((ifaceMark)) -gt $((fwMask)) ] && return 1 - - network_get_device dev "$iface" - [ -z "$dev" ] && config_get dev "$iface" 'ifname' - [ -z "$dev" ] && config_get dev "$iface" 'device' - if is_wan "$iface" && [ -n "$wanIface6" ]; then - network_get_device dev6 "$wanIface6" - [ -z "$dev6" ] && config_get dev6 "$wanIface6" 'ifname' - [ -z "$dev6" ] && config_get dev6 "$wanIface6" 'device' - fi - [ -z "$dev6" ] && dev6="$dev" - - [ -z "$ifaceTableID" ] && ifaceTableID="$wanTableID"; [ -z "$ifaceMark" ] && ifaceMark="$wanMark"; - - case "$action" in - destroy) - table_destroy "${ifaceTableID}" "${iface}" "${ifaceMark}" - ifaceTableID="$((ifaceTableID + 1))"; ifaceMark="$(printf '0x%06x' $((ifaceMark + wanMark)))"; - ;; - create) - eval "mark_${iface//-/_}"='$ifaceMark' - eval "tid_${iface//-/_}"='$ifaceTableID' - if [ -z "$match" ]; then - table_destroy "$ifaceTableID" "$iface" - fi - vpr_get_gateway gw4 "$iface" "$dev" - vpr_get_gateway6 gw6 "$iface" "$dev6" - if [ "$iface" = "$dev" ]; then - displayText="${iface}/${gw4:-0.0.0.0}" - else - displayText="${iface}/${dev}/${gw4:-0.0.0.0}" - fi - [ "$ipv6Enabled" -ne 0 ] && displayText="${displayText}/${gw6:-::/0}" - if [ -z "$match" ]; then - output 2 "Creating table '$displayText' " - is_default_dev "$dev" && displayText="${displayText} ${__OK__}" - if table_create "$ifaceTableID" "$ifaceMark" "$iface" "$gw4" "$dev" "$gw6" "$dev6" "$match"; then - gatewaySummary="${gatewaySummary}${displayText}\\n" - output_ok - else - errorSummary="${errorSummary}${_ERROR_}: Failed to set up '$displayText'\\n" - output_fail - fi - elif [ "$iface" = "$match" ]; then - output 2 "Reloading table '$displayText' " - is_default_dev "$dev" && displayText="${displayText} ${__OK__}" - if table_reload "$ifaceTableID" "$ifaceMark" "$iface" "$gw4" "$dev" "$gw6" "$dev6" "$match"; then - gatewaySummary="${gatewaySummary}${displayText}\\n" - output_ok - else - errorSummary="${errorSummary}${_ERROR_}: Failed to reload '$displayText'\\n" - output_fail - fi - else - is_default_dev "$dev" && displayText="${displayText} ${__OK__}" - gatewaySummary="${gatewaySummary}${displayText}\\n" - fi - ifaceTableID="$((ifaceTableID + 1))"; ifaceMark="$(printf '0x%06x' $((ifaceMark + wanMark)))"; - ;; - esac - return $s -} - -process_tor_interface(){ - local s=0 iface="$1" action="$2" displayText - case "$action" in - destroy) - for i in PREROUTING FORWARD INPUT OUTPUT; do - ipt -t nat -D "${i}" -m mark --mark "0x0/${fwMask}" -j "VPR_${i}" - ipt -t nat -F "VPR_${i}"; ipt -t nat -X "VPR_${i}"; - done - ;; - create) - output 2 "Creating TOR redirects " - dnsPort="$(grep -m1 DNSPort /etc/tor/torrc | awk -F: '{print $2}')" - transPort="$(grep -m1 TransPort /etc/tor/torrc | awk -F: '{print $2}')" - dnsPort="${dnsPort:-9053}"; transPort="${transPort:-9040}"; - for i in $usedChainsList; do - ipt -t nat -N "VPR_${i}" - ipt -t nat "$insertOption" "$i" -m mark --mark "0x0/${fwMask}" -j "VPR_${i}" - done - if ips 'create' "${iface}" 'hash:net comment' && ips 'flush' "${iface}"; then - for i in $usedChainsList; do - ipt -t nat -I "VPR_${i}" -p udp -m udp --dport 53 -m set --match-set "${iface}" dst -j REDIRECT --to-ports "$dnsPort" -m comment --comment "TorDNS-UDP" || s=1 - ipt -t nat -I "VPR_${i}" -p tcp -m tcp --dport 80 -m set --match-set "${iface}" dst -j REDIRECT --to-ports "$transPort" -m comment --comment "TorHTTP-TCP" || s=1 - ipt -t nat -I "VPR_${i}" -p udp -m udp --dport 80 -m set --match-set "${iface}" dst -j REDIRECT --to-ports "$transPort" -m comment --comment "TorHTTP-UDP" || s=1 - ipt -t nat -I "VPR_${i}" -p tcp -m tcp --dport 443 -m set --match-set "${iface}" dst -j REDIRECT --to-ports "$transPort" -m comment --comment "TorHTTPS-TCP" || s=1 - ipt -t nat -I "VPR_${i}" -p udp -m udp --dport 443 -m set --match-set "${iface}" dst -j REDIRECT --to-ports "$transPort" -m comment --comment "TorHTTPS-UDP" || s=1 - done - else - s=1 - fi - displayText="${iface}/53->${dnsPort}/80,443->${transPort}" - if [ "$s" -eq "0" ]; then - gatewaySummary="${gatewaySummary}${displayText}\\n" - output_ok - else - errorSummary="${errorSummary}${_ERROR_}: Failed to set up '$displayText'\\n" - output_fail - fi - ;; - esac - return $s -} - -convert_config(){ - local i src_ipset dest_ipset resolver_ipset - [ -s "/etc/config/${packageName}" ] || return 0 - grep -q "ignored_interfaces" "/etc/config/${packageName}" && sed -i 's/ignored_interfaces/ignored_interface/g' "/etc/config/${packageName}" - grep -q "supported_interfaces" "/etc/config/${packageName}" && sed -i 's/supported_interfaces/supported_interface/g' "/etc/config/${packageName}" - grep -q "local_addresses" "/etc/config/${packageName}" && sed -i 's/local_addresses/local_address/g' "/etc/config/${packageName}" - grep -q "local_ports" "/etc/config/${packageName}" && sed -i 's/local_ports/local_port/g' "/etc/config/${packageName}" - grep -q "remote_addresses" "/etc/config/${packageName}" && sed -i 's/remote_addresses/remote_address/g' "/etc/config/${packageName}" - grep -q "remote_ports" "/etc/config/${packageName}" && sed -i 's/remote_ports/remote_port/g' "/etc/config/${packageName}" - grep -q "ipset_enabled" "/etc/config/${packageName}" && sed -i 's/ipset_enabled/dest_ipset/g' "/etc/config/${packageName}" - grep -q "dnsmasq_enabled" "/etc/config/${packageName}" && sed -i 's/dnsmasq_enabled/resolver_ipset/g' "/etc/config/${packageName}" - grep -q "enable_control" "/etc/config/${packageName}" && sed -i 's/enable_control/webui_enable_column/g' "/etc/config/${packageName}" - grep -q "proto_control" "/etc/config/${packageName}" && sed -i 's/proto_control/webui_protocol_column/g' "/etc/config/${packageName}" - grep -q "chain_control" "/etc/config/${packageName}" && sed -i 's/chain_control/webui_chain_column/g' "/etc/config/${packageName}" - grep -q "sort_control" "/etc/config/${packageName}" && sed -i 's/sort_control/webui_sorting/g' "/etc/config/${packageName}" - grep -q "local_address" "/etc/config/${packageName}" && sed -i 's/local_address/src_addr/g' "/etc/config/${packageName}" - grep -q "local_port" "/etc/config/${packageName}" && sed -i 's/local_port/src_port/g' "/etc/config/${packageName}" - grep -q "remote_address" "/etc/config/${packageName}" && sed -i 's/remote_address/dest_addr/g' "/etc/config/${packageName}" - grep -q "remote_port" "/etc/config/${packageName}" && sed -i 's/remote_port/dest_port/g' "/etc/config/${packageName}" - grep -q "local_ipset" "/etc/config/${packageName}" && sed -i 's/local_ipset/src_ipset/g' "/etc/config/${packageName}" - grep -q "remote_ipset" "/etc/config/${packageName}" && sed -i 's/remote_ipset/dest_ipset/g' "/etc/config/${packageName}" - dest_ipset="$(uci -q get $packageName.config.dest_ipset)" - src_ipset="$(uci -q get $packageName.config.src_ipset)" - resolver_ipset="$(uci -q get $packageName.config.resolver_ipset)" - - if [ -n "$dest_ipset" ] && [ "$dest_ipset" != "0" ] && [ "$dest_ipset" != "1" ]; then - uci set "$packageName".config.dest_ipset='0' - if [ -z "$resolver_ipset" ]; then - uci set "$packageName".config.resolver_ipset='dnsmasq.ipset' - fi - uci commit "$packageName" - fi - if [ -n "$src_ipset" ] && [ "$src_ipset" != "0" ] && [ "$src_ipset" != "1" ]; then - uci set "$packageName".config.src_ipset='1' - uci commit "$packageName" - fi - if [ -z "$(uci -q get $packageName.config.webui_supported_protocol)" ]; then - uci add_list "$packageName".config.webui_supported_protocol='tcp' - uci add_list "$packageName".config.webui_supported_protocol='udp' - uci add_list "$packageName".config.webui_supported_protocol='tcp udp' - uci add_list "$packageName".config.webui_supported_protocol='icmp' - uci add_list "$packageName".config.webui_supported_protocol='all' - uci commit "$packageName" - fi - for i in append_local_rules append_src_rules \ - append_remote_rules append_dest_rules; do - if [ -n "$(uci -q get $packageName.config.$i)" ]; then - warningSummary="${warningSummary}$_WARNING_: $i setting is not supported in ${serviceName}.\\n" - fi - done - for i in udp_proto_enabled forward_chain_enabled input_chain_enabled \ - output_chain_enabled iprule_enabled; do - if [ "$(uci -q get $packageName.config.$i)" = "1" ]; then - warningSummary="${warningSummary}$_WARNING_: $i setting is not supported in ${serviceName}.\\n" - fi - done -} - -check_config(){ local en; config_get_bool en "$1" 'enabled' 1; [ "$en" -gt 0 ] && _cfg_enabled=0; } -is_config_enabled(){ - local cfg="$1" _cfg_enabled=1 - [ -n "$1" ] || return 1 - config_load "$packageName" - config_foreach check_config "$cfg" - return "$_cfg_enabled" -} - -process_user_file(){ - local path enabled shellBin="${SHELL:-/bin/ash}" - config_get_bool enabled "$1" 'enabled' 1 - config_get path "$1" 'path' - [ "$enabled" -gt 0 ] || return 0 - if [ ! -s "$path" ]; then - errorSummary="${errorSummary}${_ERROR_}: Custom user file '$path' not found or empty!\\n" - output_fail - return 1 - fi - if ! $shellBin -n "$path"; then - errorSummary="${errorSummary}${_ERROR_}: Syntax error in custom user file '$path'!\\n" - output_fail - return 1 - fi - output 2 "Running $path " -# shellcheck disable=SC1090 - if ! . "$path"; then - errorSummary="${errorSummary}${_ERROR_}: Error running custom user file '$path'!\\n" - if grep -q -w 'curl' "$path" && ! is_present 'curl'; then - errorSummary="${errorSummary}${_ERROR_}: Use of 'curl' is detected in custom user file '$path', but 'curl' isn't installed!\\n" - errorSummary="${errorSummary}${_ERROR_}: If 'curl' is needed, install it with 'opkg update; opkg install curl;' command in CLI.\\n" - fi - output_fail - return 1 - else - output_ok - return 0 - fi -} - -boot() { rc_procd start_service && rc_procd service_triggers; } - -start_service() { - local dnsmasqStoredHash dnsmasqNewHash i modprobeStatus=0 reloadedIface="$1" - convert_config - is_enabled 'on_start' || return 1 - is_wan_up || return 1 - - iptables -t 'mangle' --list 'VPR_PREROUTING' >/dev/null 2>&1 || unset reloadedIface - [ -n "$(tmpfs get gateway)" ] || unset reloadedIface - - if [ -s "$dnsmasqFile" ]; then - dnsmasqStoredHash="$(md5sum $dnsmasqFile | awk '{ print $1; }')" - rm -f "$dnsmasqFile" - fi - - for i in xt_set ip_set ip_set_hash_ip; do - modprobe "$i" >/dev/null 2>/dev/null || modprobeStatus=$((modprobeStatus + 1)) - done - - if [ "$modprobeStatus" -gt 0 ] && ! is_chaos_calmer; then - errorSummary="${errorSummary}${_ERROR_}: Failed to load kernel modules\\n" - fi - - if [ -z "$reloadedIface" ]; then - for i in $usedChainsList; do - ipt -t mangle -N "VPR_${i}" - ipt -t mangle "$insertOption" "$i" -m mark --mark "0x0/${fwMask}" -j "VPR_${i}" - done - fi - - if [ -z "$reloadedIface" ]; then - output 1 'Processing Interfaces ' - config_load 'network'; config_foreach process_interface 'interface' 'create'; - process_tor_interface 'tor' 'destroy'; is_tor_running && process_tor_interface 'tor' 'create'; - output 1 '\n' - if is_config_enabled 'policy'; then - output 1 'Processing Policies ' - config_load "$packageName"; config_foreach process_policy 'policy' "$reloadedIface"; - output 1 '\n' - fi - if is_config_enabled 'include'; then - output 1 'Processing User File(s) ' - config_load "$packageName"; config_foreach process_user_file 'include'; - output 1 '\n' - fi - else - output 1 "Reloading Interface: $reloadedIface " - config_load 'network'; config_foreach process_interface 'interface' 'create' "$reloadedIface"; - output 1 '\n' - fi - - if [ -s "$dnsmasqFile" ]; then - dnsmasqNewHash="$(md5sum $dnsmasqFile | awk '{ print $1; }')" - fi - [ "$dnsmasqNewHash" != "$dnsmasqStoredHash" ] && dnsmasq_restart - - if [ -z "$gatewaySummary" ]; then - errorSummary="${errorSummary}${_ERROR_}: failed to set up any gateway!\\n" - fi - procd_open_instance "main" - procd_set_param command /bin/true - procd_set_param stdout 1 - procd_set_param stderr 1 - procd_open_data - json_add_array 'status' - json_add_object '' - [ -n "$gatewaySummary" ] && json_add_string gateway "$gatewaySummary" - [ -n "$errorSummary" ] && json_add_string error "$errorSummary" - [ -n "$warningSummary" ] && json_add_string warning "$warningSummary" - if [ "$strictMode" -ne 0 ] && str_contains "$gatewaySummary" '0.0.0.0'; then - json_add_string mode "strict" - fi - json_close_object - json_close_array - procd_close_data - procd_close_instance -} - -tmpfs() { - local action="$1" param="$2" value="$3" -# shellcheck disable=SC2034 - local gateway error warning mode i - if [ -s "$jsonFile" ]; then - json_load_file "$jsonFile" 2>/dev/null - json_select 'status' 2>/dev/null - for i in gateway error warning mode; do - json_get_var $i "$i" 2>/dev/null - done - fi - case "$action" in - get) - printf "%b" "$(eval echo "\$$param")"; return;; - add) - eval "$param"='$(eval echo "\$$param")${value}';; - del) - case "$param" in - all) - unset gateway error warning mode;; - *) - unset "$param";; - esac - ;; - set) - eval "$param"='$value';; - esac - json_init - json_add_object 'status' - json_add_string version "$PKG_VERSION" - for i in gateway error warning mode; do - json_add_string "$i" "$(eval echo "\$$i")" - done - json_close_object - json_dump > "$jsonFile" - sync -} - -service_started() { - tmpfs set 'gateway' "$gatewaySummary" - tmpfs set 'error' "$errorSummary" - tmpfs set 'warning' "$warningSummary" - if [ "$strictMode" -ne 0 ] && str_contains "$gatewaySummary" '0.0.0.0'; then - tmpfs set 'mode' 'strict' - fi - [ -n "$gatewaySummary" ] && output "$serviceName started with gateways:\\n${gatewaySummary}" - [ -n "$errorSummary" ] && output "${errorSummary}" - [ -n "$warningSummary" ] && output "${warningSummary}" - if [ -n "$errorSummary" ]; then - return 2 - elif [ -n "$warningSummary" ]; then - return 1 - else - return 0 - fi -} - -stop_service() { - local i - iptables -t mangle -L | grep -q VPR_PREROUTING || return 0 - load_package_config - for i in PREROUTING FORWARD INPUT OUTPUT; do - ipt -t mangle -D "${i}" -m mark --mark "0x0/${fwMask}" -j "VPR_${i}" - ipt -t mangle -F "VPR_${i}"; ipt -t mangle -X "VPR_${i}"; - done - config_load 'network'; config_foreach process_interface 'interface' 'destroy'; - process_tor_interface 'tor' 'destroy' - unset ifaceTableID; unset ifaceMark; - if [ -s "$dnsmasqFile" ]; then - rm -f "$dnsmasqFile" - dnsmasq_restart - fi - if [ "$serviceEnabled" -ne 0 ]; then - output "$serviceName stopped "; output_okn; - fi -} - -reload_interface() { rc_procd start_service "$1"; } - -service_triggers() { - local n - is_enabled || return 1 - - if [ "$procdReloadDelay" -gt 0 ] && [ "$procdReloadDelay" -lt 100 ]; then -# shellcheck disable=SC2034 - PROCD_RELOAD_DELAY=$(( procdReloadDelay * 1000 )) - fi - - procd_open_validate - validate_config - validate_policy - validate_include - procd_close_validate - - procd_open_trigger - procd_add_reload_trigger 'openvpn' - if type procd_add_service_trigger 1>/dev/null 2>&1; then - procd_add_service_trigger "service.restart" "firewall" /etc/init.d/${packageName} reload - fi - procd_add_config_trigger "config.change" "${packageName}" /etc/init.d/${packageName} reload - for n in $ifSupported; do - procd_add_interface_trigger "interface.*" "$n" /etc/init.d/${packageName} reload_interface "$n" - done - procd_close_trigger - - output 3 "$serviceName monitoring interfaces: $ifSupported"; output_okn; -} - -status_service() { support "$@"; } -support() { - local dist vers out id s param status set_d set_p tableCount i=0 dev dev6 j - readonly _SEPARATOR_='============================================================' - is_enabled - - json_load "$(ubus call system board)"; json_select release; json_get_var dist distribution; json_get_var vers version - if [ -n "$wanIface4" ]; then - network_get_gateway wanGW4 "$wanIface4" - [ -z "$dev" ] && dev="$(uci -q get network."${wanIface4}".ifname)" - [ -z "$dev" ] && dev="$(uci -q get network."${wanIface4}".device)" - fi - if [ -n "$wanIface6" ]; then - [ -z "$dev6" ] && dev6="$(uci -q get network."${wanIface6}".ifname)" - [ -z "$dev6" ] && dev6="$(uci -q get network."${wanIface6}".device)" - wanGW6=$(ip -6 route show | grep -m1 " dev $dev6 " | awk '{print $1}') - [ "$wanGW6" = "default" ] && wanGW6=$(ip -6 route show | grep -m1 " dev $dev6 " | awk '{print $3}') - fi - while [ "${1:0:1}" = "-" ]; do param="${1//-/}"; eval "set_$param=1"; shift; done - [ -e "/var/${packageName}-support" ] && rm -f "/var/${packageName}-support" - status="$serviceName running on $dist $vers." - [ -n "$wanIface4" ] && status="$status WAN (IPv4): ${wanIface4}/${dev}/${wanGW4:-0.0.0.0}." - [ -n "$wanIface6" ] && status="$status WAN (IPv6): ${wanIface6}/${dev6}/${wanGW6:-::/0}." - { - echo "$status" - echo "$_SEPARATOR_" - dnsmasq --version 2>/dev/null | sed '/^$/,$d' - if [ -n "$1" ]; then - echo "$_SEPARATOR_" - echo "Resolving domains" - for i in $1; do - echo "$i: $(resolveip "$i" | tr '\n' ' ')" - done - fi - - echo "$_SEPARATOR_" - echo "Routes/IP Rules" - tableCount=$(ip rule list | grep -c 'fwmark') || tableCount=0 - if [ -n "$set_d" ]; then route; else route | grep '^default'; fi - if [ -n "$set_d" ]; then ip rule list; fi - i=0; while [ $i -lt $tableCount ]; do - echo "" - echo "IPv4 Table $((wanTableID + i)): $(ip -4 route show table $((wanTableID + i)))" - echo "IPv4 Table $((wanTableID + i)) Rules:" - ip -4 rule list table "$((wanTableID + i))" - i=$((i + 1)) - done - - if [ "$ipv6Enabled" -ne 0 ]; then - i=0; while [ $i -lt $tableCount ]; do - ip -6 route show table $((wanTableID + i)) | while read -r param; do - echo "IPv6 Table $((wanTableID + i)): $param" - done - i=$((i + 1)) - done - fi - - for j in Mangle NAT; do - if [ -z "$set_d" ]; then - for i in $usedChainsList; do - if iptables -v -t "$(str_to_lower $j)" -S "VPR_${i}" 1>/dev/null 2>&1; then - echo "$_SEPARATOR_" - echo "$j IP Table: $i" - iptables -v -t "$(str_to_lower $j)" -S "VPR_${i}" - if [ "$ipv6Enabled" -ne 0 ]; then - echo "$_SEPARATOR_" - echo "$j IPv6 Table: $i" - ip6tables -v -t "$(str_to_lower $j)" -S "VPR_${i}" - fi - fi - done - else - echo "$_SEPARATOR_" - echo "$j IP Table" - iptables -L -t "$(str_to_lower $j)" - if [ "$ipv6Enabled" -ne 0 ]; then - echo "$_SEPARATOR_" - echo "$j IPv6 Table" - ip6tables -L -t "$(str_to_lower $j)" - fi - fi - i=0; ifaceMark="$wanMark"; - while [ $i -lt $tableCount ]; do - if iptables -v -t "$(str_to_lower $j)" -S "VPR_MARK${ifaceMark}" 1>/dev/null 2>&1; then - echo "$_SEPARATOR_" - echo "$j IP Table MARK Chain: VPR_MARK${ifaceMark}" - iptables -v -t "$(str_to_lower $j)" -S "VPR_MARK${ifaceMark}" - ifaceMark="$(printf '0x%06x' $((ifaceMark + wanMark)))"; - fi - i=$((i + 1)) - done - done - - echo "$_SEPARATOR_" - echo "Current ipsets" - ipset save - if [ -s "$dnsmasqFile" ]; then - echo "$_SEPARATOR_" - echo "DNSMASQ ipsets" - cat "$dnsmasqFile" - fi - echo "$_SEPARATOR_" - } | tee -a /var/${packageName}-support - if [ -n "$set_p" ]; then - printf "%b" "Pasting to paste.ee... " - if is_present 'curl' && is_variant_installed 'libopenssl' && is_installed 'ca-bundle'; then - json_init; json_add_string "description" "${packageName}-support" - json_add_array "sections"; json_add_object '0' - json_add_string "name" "$(uci -q get system.@system[0].hostname)" - json_add_string "contents" "$(cat /var/${packageName}-support)" - json_close_object; json_close_array; payload=$(json_dump) - out=$(curl -s -k "https://api.paste.ee/v1/pastes" -X "POST" -H "Content-Type: application/json" -H "X-Auth-Token:uVOJt6pNqjcEWu7qiuUuuxWQafpHhwMvNEBviRV2B" -d "$payload") - json_load "$out"; json_get_var id id; json_get_var s success - [ "$s" = "1" ] && printf "%b" "https://paste.ee/p/$id $__OK__\\n" || printf "%b" "$__FAIL__\\n" - [ -e "/var/${packageName}-support" ] && rm -f "/var/${packageName}-support" - else - printf "%b" "$__FAIL__\\n" - printf "%b" "$_ERROR_: curl, libopenssl or ca-bundle were not found!\\nRun 'opkg update; opkg install curl libopenssl ca-bundle' to install them.\\n" - fi - else - printf "%b" "Your support details have been logged to '/var/${packageName}-support'. $__OK__\\n" - fi -} - -# shellcheck disable=SC2120 -validate_config() { - uci_validate_section "${packageName}" config "${1}" \ - 'enabled:bool:0' \ - 'strict_enforcement:bool:1' \ - 'ipv6_enabled:bool:0' \ - 'src_ipset:bool:0' \ - 'dest_ipset:bool:0' \ - 'resolver_ipset::or("", "none", "dnsmasq.ipset")' \ - 'verbosity:range(0,2):1' \ - 'wan_tid:integer:201' \ - 'wan_fw_mark:hex(8)' \ - 'fw_mask:hex(8)' \ - 'icmp_interface:string' \ - 'ignored_interface:list(string)' \ - 'supported_interface:list(string)' \ - 'boot_timeout:integer:30' \ - 'iptables_rule_option:or("", "append", "insert")' \ - 'procd_reload_delay:integer:0' \ - 'webui_enable_column:bool:0' \ - 'webui_protocol_column:bool:0' \ - 'webui_supported_protocol:list(string)' \ - 'webui_chain_column:bool:0' \ - 'webui_sorting:bool:1' \ - 'webui_show_ignore_target:bool:0' -} - -# shellcheck disable=SC2120 -validate_policy() { - uci_validate_section "${packageName}" policy "${1}" \ - 'name:string' \ - 'enabled:bool:0' \ - 'interface:network' \ - 'proto:or(string)' \ - 'chain:or("", "PREROUTING", "FORWARD", "INPUT", "OUTPUT")' \ - 'src_addr:list(neg(or(host,network,macaddr)))' \ - 'src_port:list(neg(or(portrange, string)))' \ - 'dest_addr:list(neg(host))' \ - 'dest_port:list(neg(or(portrange, string)))' -} - -# shellcheck disable=SC2120 -validate_include() { - uci_validate_section "${packageName}" include "${1}" \ - 'path:string' \ - 'enabled:bool:0' -} diff --git a/net/vpn-policy-routing/files/vpn-policy-routing.netflix.user b/net/vpn-policy-routing/files/vpn-policy-routing.netflix.user deleted file mode 100644 index 02335c4b3..000000000 --- a/net/vpn-policy-routing/files/vpn-policy-routing.netflix.user +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh -# This file is heavily based on code from https://github.com/Xentrk/netflix-vpn-bypass/blob/master/IPSET_Netflix.sh -# Credits to https://forum.openwrt.org/u/dscpl for api.hackertarget.com code. -# Credits to https://github.com/kkeker and https://github.com/tophirsch for api.bgpview.io code. - -TARGET_IPSET='wan' -TARGET_ASN='2906' -TARGET_FNAME="/var/vpn-policy-routing_tmp_AS${TARGET_ASN}" -#DB_SOURCE='ipinfo.io' -#DB_SOURCE='api.hackertarget.com' -DB_SOURCE='api.bgpview.io' - -_ret=1 - -if [ ! -s "$TARGET_FNAME" ]; then - if [ "$DB_SOURCE" = "ipinfo.io" ]; then - TARGET_URL="https://ipinfo.io/AS${TARGET_ASN}" - curl "$TARGET_URL" 2>/dev/null | grep -E "a href.*${TARGET_ASN}\/" | grep -v ":" | sed "s/^.*//" > "$TARGET_FNAME" - fi - - if [ "$DB_SOURCE" = "api.hackertarget.com" ]; then - TARGET_URL="https://api.hackertarget.com/aslookup/?q=AS${TARGET_ASN}" - curl "$TARGET_URL" 2>/dev/null | sed '1d' > "$TARGET_FNAME" - fi - - if [ "$DB_SOURCE" = "api.bgpview.io" ]; then - TARGET_URL="https://api.bgpview.io/asn/${TARGET_ASN}/prefixes" - curl -s "$TARGET_URL" 2>/dev/null | jsonfilter -e '@.data.ipv4_prefixes[*].prefix' > "$TARGET_FNAME" - fi -fi - -if [ -s "$TARGET_FNAME" ]; then - awk -v ipset="$TARGET_IPSET" '{print "add " ipset " " $1}' "$TARGET_FNAME" | ipset restore -! && _ret=0 -fi -rm -f "$TARGET_FNAME" - -return $_ret diff --git a/net/vpnbypass/Makefile b/net/vpnbypass/Makefile deleted file mode 100644 index 83a4786ba..000000000 --- a/net/vpnbypass/Makefile +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright 2017-2018 Stan Grishin (stangri@melmac.net) -# This is free software, licensed under the GNU General Public License v3. - -include $(TOPDIR)/rules.mk - -PKG_NAME:=vpnbypass -PKG_VERSION:=1.3.2 -PKG_RELEASE:=1 -PKG_LICENSE:=GPL-3.0-or-later -PKG_MAINTAINER:=Stan Grishin - -include $(INCLUDE_DIR)/package.mk - -define Package/vpnbypass - SECTION:=net - CATEGORY:=Network - TITLE:=VPN Bypass Service - URL:=https://docs.openwrt.melmac.net/vpnbypass/ - DEPENDS:=+ipset +iptables - PKGARCH:=all -endef - -define Package/vpnbypass/description -This service can be used to enable simple VPN split tunnelling. -Supports accessing domains, IP ranges outside of your VPN tunnel. -Also supports dedicating local ports/IP ranges for direct -internet access (outside of your VPN tunnel). -Please see the README for further information. -endef - -define Package/vpnbypass/conffiles -/etc/config/vpnbypass -endef - -define Build/Configure -endef - -define Build/Compile -endef - -define Package/vpnbypass/install - $(INSTALL_DIR) $(1)/etc/init.d $(1)/etc/config $(1)/etc/hotplug.d/firewall - $(INSTALL_BIN) ./files/vpnbypass.init $(1)/etc/init.d/vpnbypass - $(SED) "s|^\(PKG_VERSION\).*|\1='$(PKG_VERSION)-$(PKG_RELEASE)'|" $(1)/etc/init.d/vpnbypass - $(INSTALL_CONF) ./files/vpnbypass.config $(1)/etc/config/vpnbypass - $(INSTALL_DATA) ./files/vpnbypass.hotplug $(1)/etc/hotplug.d/firewall/94-vpnbypass -endef - -define Package/vpnbypass/postinst - #!/bin/sh - # check if we are on real system - if [ -z "$${IPKG_INSTROOT}" ]; then - /etc/init.d/vpnbypass enable - fi - exit 0 -endef - -define Package/vpnbypass/prerm - #!/bin/sh - # check if we are on real system - if [ -z "$${IPKG_INSTROOT}" ]; then - echo "Stopping service and removing rc.d symlink for vpnbypass" - /etc/init.d/vpnbypass stop || true - /etc/init.d/vpnbypass disable || true - fi - exit 0 -endef - -$(eval $(call BuildPackage,vpnbypass)) diff --git a/net/vpnbypass/files/README.md b/net/vpnbypass/files/README.md deleted file mode 100644 index 886ac7c55..000000000 --- a/net/vpnbypass/files/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# README - -README has been moved to [https://docs.openwrt.melmac.net/vpnbypass/](https://docs.openwrt.melmac.net/vpnbypass/). diff --git a/net/vpnbypass/files/vpnbypass.config b/net/vpnbypass/files/vpnbypass.config deleted file mode 100644 index 0768e865c..000000000 --- a/net/vpnbypass/files/vpnbypass.config +++ /dev/null @@ -1,5 +0,0 @@ -config vpnbypass 'config' - option enabled '0' - list localport '32400' - list localsubnet '192.168.1.81/29' - list remotesubnet '25.0.0.0/8' diff --git a/net/vpnbypass/files/vpnbypass.hotplug b/net/vpnbypass/files/vpnbypass.hotplug deleted file mode 100644 index a2874f97e..000000000 --- a/net/vpnbypass/files/vpnbypass.hotplug +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -[ "$ACTION" = "reload" ] && /etc/init.d/vpnbypass reload diff --git a/net/vpnbypass/files/vpnbypass.init b/net/vpnbypass/files/vpnbypass.init deleted file mode 100644 index 03a95ae68..000000000 --- a/net/vpnbypass/files/vpnbypass.init +++ /dev/null @@ -1,146 +0,0 @@ -#!/bin/sh /etc/rc.common -# Copyright 2017-2020 Stan Grishin (stangri@melmac.net) -# shellcheck disable=SC2039,SC1091,SC2086,SC3043,SC3057,SC3060 -PKG_VERSION='dev-test' - -# shellcheck disable=SC2034 -START=94 -# shellcheck disable=SC2034 -USE_PROCD=1 - -if type extra_command 1>/dev/null 2>&1; then - extra_command 'version' 'Show version information' -else -# shellcheck disable=SC2034 - EXTRA_COMMANDS='version' -fi - -version() { echo "$PKG_VERSION"; } - -readonly __ERROR__='\033[0;31mERROR\033[0m' - -# shellcheck disable=SC2034 -serviceEnabled=0 -verbosity=2 -TID='200' -IPSET='vpnbypass' -FW_MARK='0x010000' -FW_MASK='0xff0000' -wan_if4='' -wan_gw='' - -readonly packageName='vpnbypass' -readonly serviceName="$packageName $PKG_VERSION" -readonly sharedMemoryOutput="/dev/shm/$packageName-output" - -output() { -# Can take a single parameter (text) to be output at any verbosity -# Or target verbosity level and text to be output at specifc verbosity - local msg memmsg logmsg - if [ $# -ne 1 ]; then - if [ $((verbosity & $1)) -gt 0 ] || [ "$verbosity" = "$1" ]; then shift; else return 0; fi - fi - [ -t 1 ] && printf "%b" "$1" - msg="${1//$serviceName /service }"; - if [ "$(printf "%b" "$msg" | wc -l)" -gt 0 ]; then - [ -s "$sharedMemoryOutput" ] && memmsg="$(cat "$sharedMemoryOutput")" - logmsg="$(printf "%b" "${memmsg}${msg}" | sed 's/\x1b\[[0-9;]*m//g')" - logger -t "${packageName:-service} [$$]" "$(printf "%b" "$logmsg")" - rm -f "$sharedMemoryOutput" - else - printf "%b" "$msg" >> "$sharedMemoryOutput" - fi -} -load_package_config() { - config_load "$packageName" - config_get_bool serviceEnabled 'config' 'enabled' 1 - config_get verbosity 'config' 'verbosity' '2' - if [ -z "${verbosity##*[!0-9]*}" ] || [ "$verbosity" -lt 0 ] || [ "$verbosity" -gt 2 ]; then - verbosity=1 - fi - . /lib/functions/network.sh -} - -is_enabled() { - local sleepCount=1 - load_package_config - while : ; do - network_find_wan wan_if4 - [ "$serviceEnabled" -gt 0 ] || return 1 - [ -n "$wan_if4" ] && network_get_gateway wan_gw "$wan_if4" - if [ $sleepCount -ge 25 ] || [ -n "$wan_gw" ]; then break; fi - output "$serviceName waiting for wan gateway...\\n" - sleep 2; network_flush_cache; sleepCount=$((sleepCount+1)); - done - [ -n "$wan_gw" ] && return 0 - output "$__ERROR__: $serviceName failed to discover WAN gateway.\\n"; return 1; -} - -is_ovpn() { local dev i; for i in ifname device; do [ -z "$dev" ] && dev="$(uci -q get "network.${1}.${i}")"; done; if [ "${dev:0:3}" = "tun" ] || [ "${dev:0:3}" = "tap" ] || [ -f "/sys/devices/virtual/net/${dev}/tun_flags" ]; then return 0; else return 1; fi; } -is_wan() { if [ -n "$wan_if4" ] && [ "$1" = "$wan_if4" ]; then return 0; else return 1; fi; } -is_supported_interface() { if is_wan "$1" || is_ovpn "$1"; then return 0; else return 1; fi; } - -ipt() { - local d; - d="${*//-A/-D}"; [ "$d" != "$*" ] && iptables $d >/dev/null 2>&1 - d="${*//-I/-D}"; [ "$d" != "$*" ] && iptables $d >/dev/null 2>&1 - d="${*//-N/-F}"; [ "$d" != "$*" ] && iptables $d >/dev/null 2>&1 - d="${*//-N/-X}"; [ "$d" != "$*" ] && iptables $d >/dev/null 2>&1 - d="$*"; iptables $d >/dev/null 2>&1 || output "\\n$__ERROR__: iptables $d\\n" -} - -start_service() { - local ll lports rports routes ranges - is_enabled || return 1 - config_get lports 'config' 'localport' - config_get rports 'config' 'remoteport' - config_get routes 'config' 'remotesubnet' - config_get ranges 'config' 'localsubnet' - - procd_open_instance "main" - procd_set_param command /bin/true - procd_set_param stdout 1 - procd_set_param stderr 1 - procd_close_instance - - ip rule del fwmark "$FW_MARK" table "$TID" >/dev/null 2>&1; - ipset -q flush "$IPSET"; ipset -q destroy "$IPSET"; - ip route flush table "$TID"; ip route flush cache; - ip route add default via "$wan_gw" table "$TID"; ip route flush cache; - ip rule add fwmark "$FW_MARK" table "$TID" - ipset -q -exist create "$IPSET" hash:ip; ipset -q flush "$IPSET" - { modprobe xt_set; modprobe ip_set; modprobe ip_set_hash_ip; } >/dev/null 2>&1 - ipt -t mangle -D PREROUTING -m mark --mark 0x00/${FW_MASK} -g VPNBYPASS >/dev/null 2>&1 - { ipt -t mangle -N VPNBYPASS; ipt -t mangle -A PREROUTING -m mark --mark 0x00/${FW_MASK} -g VPNBYPASS; } >/dev/null 2>&1 - ipt -t mangle -A VPNBYPASS -m set --match-set $IPSET dst -j MARK --set-mark ${FW_MARK}/${FW_MASK} >/dev/null 2>&1 - for ll in ${ranges}; do ipt -t mangle -A VPNBYPASS -j MARK --set-mark ${FW_MARK}/${FW_MASK} -s "$ll"; done - for ll in ${lports}; do ipt -t mangle -A VPNBYPASS -j MARK --set-mark ${FW_MARK}/${FW_MASK} -p tcp -m multiport --sport "${ll//-/:}"; done - for ll in ${routes}; do ipt -t mangle -A VPNBYPASS -j MARK --set-mark ${FW_MARK}/${FW_MASK} -d "$ll"; done - for ll in ${rports}; do ipt -t mangle -A VPNBYPASS -j MARK --set-mark ${FW_MARK}/${FW_MASK} -p tcp -m multiport --dport "${ll//-/:}"; done - output "$serviceName started with TID: $TID; FW_MARK: $FW_MARK\\n" -} - -stop_service() { - load_package_config - ip rule del fwmark "$FW_MARK" table "$TID" >/dev/null 2>&1; - ipset -q flush "$IPSET"; ipset -q destroy "$IPSET"; - ip route flush table "$TID"; ip route flush cache; - ipt -t mangle -D PREROUTING -m mark --mark 0x00/${FW_MASK} -g VPNBYPASS >/dev/null 2>&1 - { ipt -t mangle -F VPNBYPASS; ipt -t mangle -X VPNBYPASS; } >/dev/null 2>&1 - output "$serviceName stopped\\n" -} - -service_triggers_load_interface() { is_supported_interface "$1" && ifaces="${ifaces}${1} "; } -service_triggers() { - local ifaces n - config_load network; config_foreach service_triggers_load_interface 'interface'; - procd_open_trigger - procd_add_reload_trigger 'openvpn' - if type procd_add_service_trigger 1>/dev/null 2>&1; then - procd_add_service_trigger "service.restart" "firewall" /etc/init.d/${packageName} reload - fi - procd_add_config_trigger "config.change" "${packageName}" /etc/init.d/${packageName} reload - for n in $ifaces; do procd_add_reload_interface_trigger "$n"; procd_add_interface_trigger "interface.*" "$n" /etc/init.d/vpnbypass reload; done; - output "$serviceName monitoring interfaces: $ifaces\\n" - procd_close_trigger -} diff --git a/net/vpnbypass/test.sh b/net/vpnbypass/test.sh deleted file mode 100644 index 45469ed96..000000000 --- a/net/vpnbypass/test.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -/etc/init.d/"$1" version 2>&1 | grep "$2" From 9434a2dfb2f8d6efa3df4dea46b35eaa423de83a Mon Sep 17 00:00:00 2001 From: Stanislav Petrashov Date: Sun, 16 Oct 2022 18:11:11 +0200 Subject: [PATCH 10/39] tailscale: update to v1.32.0 Signed-off-by: Stanislav Petrashov --- net/tailscale/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/tailscale/Makefile b/net/tailscale/Makefile index e74854d16..460a345b8 100644 --- a/net/tailscale/Makefile +++ b/net/tailscale/Makefile @@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=tailscale -PKG_VERSION:=1.24.2 +PKG_VERSION:=1.32.0 PKG_RELEASE:=$(AUTORELEASE) PKG_SOURCE:=tailscale-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/tailscale/tailscale/tar.gz/v$(PKG_VERSION)? -PKG_HASH:=f1fe7770b4e372ace47c5b0ac4cbe21af95c3a6fb1828ee4f407fcfe35b7958f +PKG_HASH:=2085bbb34415e0480f118390026c7466f296b3a8851604378a82439b5b69df69 PKG_MAINTAINER:=Jan Pavlinec PKG_LICENSE:=BSD-3-Clause From 1ffe60bc859db3b6b900a9fd6950d53ee1184aa1 Mon Sep 17 00:00:00 2001 From: Stanislav Petrashov Date: Sat, 3 Dec 2022 19:49:08 +0100 Subject: [PATCH 11/39] tailscale: Update to version 1.32.3 Signed-off-by: Stanislav Petrashov --- net/tailscale/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/tailscale/Makefile b/net/tailscale/Makefile index 460a345b8..8f979aede 100644 --- a/net/tailscale/Makefile +++ b/net/tailscale/Makefile @@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=tailscale -PKG_VERSION:=1.32.0 -PKG_RELEASE:=$(AUTORELEASE) +PKG_VERSION:=1.32.3 +PKG_RELEASE:=1 PKG_SOURCE:=tailscale-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/tailscale/tailscale/tar.gz/v$(PKG_VERSION)? -PKG_HASH:=2085bbb34415e0480f118390026c7466f296b3a8851604378a82439b5b69df69 +PKG_HASH:=4cf88a1d754240ce71b29d3a65ca480091ad9c614ac99c541cef6fdaf0585dd4 PKG_MAINTAINER:=Jan Pavlinec PKG_LICENSE:=BSD-3-Clause From 149053198146a8821e8c12d7c7fce8c3a175c5b7 Mon Sep 17 00:00:00 2001 From: Marius Dinu Date: Wed, 30 Nov 2022 11:21:39 +0200 Subject: [PATCH 12/39] tvheadend: add conditions for -O3 and LTO optimizations Building for arc, mips and powerpc platforms fails if -O3 and LTO optimizations are enabled. This patch removes that option for everything other than arm and x86_64. These are known to work. Fixes issue #19923. Also fixes a typo in the description. Signed-off-by: Marius Dinu --- multimedia/tvheadend/Config.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/multimedia/tvheadend/Config.in b/multimedia/tvheadend/Config.in index 741ae8ffa..de689fd33 100644 --- a/multimedia/tvheadend/Config.in +++ b/multimedia/tvheadend/Config.in @@ -3,10 +3,10 @@ comment "Generic options" config TVHEADEND_OPTIMIZE_SPEED bool "Optimize for speed" - depends on PACKAGE_tvheadend + depends on PACKAGE_tvheadend && (arm || aarch64 || x86_64) default n help - Optimize tvheadend for speed instead of size. This option adds -O2 and LTO (Link Time Optimization). + Optimize tvheadend for speed instead of size. This option adds -O3 and LTO (Link Time Optimization). Note: No benchmarks were performed when this option was added. Speed improvements (if any) are not known. config TVHEADEND_TRACE From 091681e1523d2943e665c392b09f79d6959fe632 Mon Sep 17 00:00:00 2001 From: Marius Dinu Date: Wed, 30 Nov 2022 11:45:13 +0200 Subject: [PATCH 13/39] tvheadend: Fix github warning about AUTORELEASE Signed-off-by: Marius Dinu --- multimedia/tvheadend/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/multimedia/tvheadend/Makefile b/multimedia/tvheadend/Makefile index c6a01e203..4db9918c7 100644 --- a/multimedia/tvheadend/Makefile +++ b/multimedia/tvheadend/Makefile @@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=tvheadend PKG_VERSION:=2022-11-20 -PKG_RELEASE:=$(AUTORELEASE) +PKG_RELEASE:=3 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/tvheadend/tvheadend.git From c1222365526e1fab7f021f2b3a629e859be6b489 Mon Sep 17 00:00:00 2001 From: Hannu Nyman Date: Sun, 4 Dec 2022 11:32:37 +0200 Subject: [PATCH 14/39] xz: update to 5.2.9 Update xz to version 5.2.9. Switch back to .bz2 sources, as we already download .bz2 for tools/ No sense to re-download sources as a .xz file. Signed-off-by: Hannu Nyman --- utils/xz/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/utils/xz/Makefile b/utils/xz/Makefile index 7aa49ad98..e8d01626e 100644 --- a/utils/xz/Makefile +++ b/utils/xz/Makefile @@ -9,12 +9,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=xz -PKG_VERSION:=5.2.7 +PKG_VERSION:=5.2.9 PKG_RELEASE:=1 -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:=@SF/lzmautils -PKG_HASH:=8712e9acb0b6b49a97d443458a3067dc5c08a025e02dc5f773176c51dd7cfc69 +PKG_HASH:=b194507fba3a462a753c553149ccdaa168337bcb7deefddd067ba987c83dfce6 PKG_MAINTAINER:= PKG_LICENSE:=Public-Domain LGPL-2.1-or-later GPL-2.0-or-later GPL-3.0-or-later From 37a86626e05b8324e0d6234cf4f3a3f65c88c0a4 Mon Sep 17 00:00:00 2001 From: Javier Marcet Date: Fri, 2 Dec 2022 21:43:36 +0100 Subject: [PATCH 15/39] docker-compose: Update to version 2.14.0 Signed-off-by: Javier Marcet --- utils/docker-compose/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/utils/docker-compose/Makefile b/utils/docker-compose/Makefile index 46f174359..c62132da1 100644 --- a/utils/docker-compose/Makefile +++ b/utils/docker-compose/Makefile @@ -1,14 +1,14 @@ include $(TOPDIR)/rules.mk PKG_NAME:=compose -PKG_VERSION:=2.12.2 -PKG_RELEASE:=$(AUTORELEASE) +PKG_VERSION:=2.14.0 +PKG_RELEASE:=1 PKG_LICENSE:=Apache-2.0 PKG_LICENSE_FILES:=LICENSE PKG_SOURCE:=v$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/docker/compose/tar.gz/v${PKG_VERSION}? -PKG_HASH:=311131c5d930fdb1f5e86de19ea2ad1705d23e5745b780c0b10b2eb3f964fc69 +PKG_HASH:=003efb3139298aa4795f7a9fa4723ef43c12b401c235fe0c93dd23cc2c6b5f2e PKG_MAINTAINER:=Javier Marcet From f60f11f9277ee30fa0699cdf1aded5a0bc50aac6 Mon Sep 17 00:00:00 2001 From: Daniel Golle Date: Mon, 5 Dec 2022 01:18:43 +0000 Subject: [PATCH 16/39] snowflake: update to version 2.4.1 Changes in version v2.4.1 - 2022-12-01 - Issue 40224: Bug fix in utls roundtripper Changes in version v2.4.0 - 2022-11-29 - Fix proxy command line help output - Issue 40123: Reduce multicast DNS candidates - Add ICE ephemeral ports range setting - Reformat using Go 1.19 - Update CI tests to include latest and minimum Go versions - Issue 40184: Use fixed unit for bandwidth logging - Update gorilla/websocket to v1.5.0 - Issue 40175: Server performance improvements - Issue 40183: Change snowflake proxy log verbosity - Issue 40117: Display proxy NAT type in logs - Issue 40198: Add a `orport-srcaddr` server transport option - Add gofmt output to CI test - Issue 40185: Change bandwidth type from int to int64 to prevent overflow - Add version output support to snowflake - Issue 40229: Change regexes for ipv6 addresses to catch url-encoded addresses - Issue 40220: Close stale connections in standalone proxy Signed-off-by: Daniel Golle --- net/snowflake/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/snowflake/Makefile b/net/snowflake/Makefile index 5e9cadb34..2b4685d56 100644 --- a/net/snowflake/Makefile +++ b/net/snowflake/Makefile @@ -1,13 +1,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=snowflake -PKG_VERSION:=2.3.1 +PKG_VERSION:=2.4.1 PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=https://git.torproject.org/pluggable-transports/snowflake.git PKG_SOURCE_VERSION:=v$(PKG_VERSION) -PKG_MIRROR_HASH:=f83d48ebdbb3966856fdd1016a2ff4e57e63598182ad5e53ab5c31a7100ce6ee +PKG_MIRROR_HASH:=91f32c3f56718ae35641c734aa061be138eb7c0d1bc88596b42e731e30aaa27a PKG_LICENSE:=BSD-3-Clause PKG_LICENSE_FILES:=LICENSE From e691a25cb3398b83bedc9581ef119382760cfacc Mon Sep 17 00:00:00 2001 From: Richard Yu Date: Mon, 5 Dec 2022 16:03:51 +0800 Subject: [PATCH 17/39] natmap: add new package NATMap is a program for opening port behind full cone NAT (NAT-1), without the need for using UPnP or another port forward settings. More details can be found at original repo: https://github.com/heiher/natmap Signed-off-by: Richard Yu --- net/natmap/Makefile | 40 +++++++++++ net/natmap/files/natmap-update.sh | 17 +++++ net/natmap/files/natmap.config | 13 ++++ net/natmap/files/natmap.init | 113 ++++++++++++++++++++++++++++++ net/natmap/test.sh | 3 + 5 files changed, 186 insertions(+) create mode 100644 net/natmap/Makefile create mode 100644 net/natmap/files/natmap-update.sh create mode 100644 net/natmap/files/natmap.config create mode 100644 net/natmap/files/natmap.init create mode 100755 net/natmap/test.sh diff --git a/net/natmap/Makefile b/net/natmap/Makefile new file mode 100644 index 000000000..7c09f1716 --- /dev/null +++ b/net/natmap/Makefile @@ -0,0 +1,40 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=natmap +PKG_VERSION:=20221203 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://github.com/heiher/natmap/releases/download/$(PKG_VERSION) +PKG_HASH:=c7aa0bb1f3e057bf1fa987ad6166ba7c2e80510a89593e04f4fe0f36f1873338 + +PKG_MAINTAINER:=Richard Yu +PKG_LICENSE:=MIT +PKG_LICENSE_FILES:=License + +PKG_USE_MIPS16:=0 +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/natmap + SECTION:=net + CATEGORY:=Network + TITLE:=TCP/UDP port mapping tool for full cone NAT + URL:=https://github.com/heiher/natmap +endef + +MAKE_FLAGS += REV_ID="$(PKG_VERSION)" + +define Package/natmap/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/natmap $(1)/usr/bin/ + $(INSTALL_DIR) $(1)/usr/lib/natmap/ + $(INSTALL_BIN) ./files/natmap-update.sh $(1)/usr/lib/natmap/update.sh + $(INSTALL_DIR) $(1)/etc/config/ + $(INSTALL_CONF) ./files/natmap.config $(1)/etc/config/natmap + $(INSTALL_DIR) $(1)/etc/init.d/ + $(INSTALL_BIN) ./files/natmap.init $(1)/etc/init.d/natmap +endef + +$(eval $(call BuildPackage,natmap)) diff --git a/net/natmap/files/natmap-update.sh b/net/natmap/files/natmap-update.sh new file mode 100644 index 000000000..72afb94b8 --- /dev/null +++ b/net/natmap/files/natmap-update.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +. /usr/share/libubox/jshn.sh + +( + json_init + json_add_string ip "$1" + json_add_int port "$2" + json_add_int inner_port "$4" + json_add_string protocol "$5" + json_dump > /var/run/natmap/$PPID.json +) + +[ -n "${NOTIFY_SCRIPT}" ] && { + export -n NOTIFY_SCRIPT + exec "${NOTIFY_SCRIPT}" "$@" +} diff --git a/net/natmap/files/natmap.config b/net/natmap/files/natmap.config new file mode 100644 index 000000000..519cea052 --- /dev/null +++ b/net/natmap/files/natmap.config @@ -0,0 +1,13 @@ +config natmap + option enable '0' + option ipv4 '0' + option ipv6 '0' + option udp_mode '1' + option interface '' + option interval '' + option stun_server 'stun.stunprotocol.org' + option http_server 'example.com' + option port '8080' + option forward_target '' + option notify_script '' + diff --git a/net/natmap/files/natmap.init b/net/natmap/files/natmap.init new file mode 100644 index 000000000..e729e7275 --- /dev/null +++ b/net/natmap/files/natmap.init @@ -0,0 +1,113 @@ +#!/bin/sh /etc/rc.common + +START=99 +USE_PROCD=1 + +NAME=natmap +PROG=/usr/bin/$NAME + +STATUS_PATH=/var/run/natmap + +load_interfaces() { + config_get interface "$1" interface + config_get enable "$1" enable 1 + + [ "${enable}" = "1" ] && interfaces=" ${interface} ${interfaces}" +} + +validate_section_natmap() { + uci_load_validate "${NAME}" natmap "$1" "$2" \ + 'enable:bool:1' \ + 'ipv4:bool:0' \ + 'ipv6:bool:0' \ + 'udp_mode:bool:0' \ + 'interface:string' \ + 'interval:uinteger' \ + 'stun_server:host' \ + 'http_server:host' \ + 'port:port' \ + 'forward_target:host' \ + 'notify_script:file' +} + +natmap_instance() { + [ "$2" = 0 ] || { + echo "validation failed" + return 1 + } + + [ "${enable}" = 0 ] && return 1 + + procd_open_instance "$1" + procd_set_param command "$PROG" \ + ${interval:+-k $interval} \ + ${stun_server:+-s "$stun_server"} \ + ${http_server:+-h "$http_server"} + + [ "${ipv4}" = 1 ] && procd_append_param command -4 + [ "${ipv6}" = 1 ] && procd_append_param command -6 + [ "${udp_mode}" = 1 ] && procd_append_param command -u + + [ -n "$interface" ] && { + local ifname + + network_get_device ifname "$interface" || ifname="$interface" + procd_append_param command -i "$ifname" + procd_append_param netdev "$ifname" + } + + if [ -n "$forward_target" ]; then + procd_append_param command -t "$forward_target" -p $port + else + procd_append_param command -b $port + fi + + [ -n "${notify_script}" ] && procd_set_param env "NOTIFY_SCRIPT=${notify_script}" + procd_append_param command -e /usr/lib/natmap/update.sh + + procd_set_param respawn + procd_set_param stdout 1 + procd_set_param stderr 1 + + procd_close_instance +} + +clear_status_files() { + find "${STATUS_PATH}" -type f -print0 | xargs -0 rm -f -- +} + +service_triggers() { + local interfaces + + procd_add_reload_trigger "${NAME}" + + config_load "${NAME}" + config_foreach load_interfaces natmap + + [ -n "${interfaces}" ] && { + for n in $interfaces ; do + procd_add_reload_interface_trigger $n + done + } + + procd_add_validation validate_section_natmap +} + +start_service() { + . /lib/functions/network.sh + + mkdir -p "${STATUS_PATH}" + clear_status_files + + config_load "${NAME}" + config_foreach validate_section_natmap natmap natmap_instance +} + +reload_service() { + stop + start +} + +service_stopped() { + clear_status_files +} diff --git a/net/natmap/test.sh b/net/natmap/test.sh new file mode 100755 index 000000000..9ae615ccd --- /dev/null +++ b/net/natmap/test.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +"$1" 2>&1 | grep "$2" From eb251c50bbc58ae656c72f8ec718b44ea8913583 Mon Sep 17 00:00:00 2001 From: John Audia Date: Thu, 1 Dec 2022 10:07:00 -0500 Subject: [PATCH 18/39] snort3: update to 3.1.48.0-1 Had to add a patch to allow builds of targets containing '+' in their dir name Build system: x86_64 Build-tested: bcm2711/RPi4B Run-tested: bcm2711/RPi4B Signed-off-by: John Audia --- net/snort3/Makefile | 4 ++-- .../900-fix_build_for_archs_contain_plus.patch | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 net/snort3/patches/900-fix_build_for_archs_contain_plus.patch diff --git a/net/snort3/Makefile b/net/snort3/Makefile index fd2f76bd8..925005814 100644 --- a/net/snort3/Makefile +++ b/net/snort3/Makefile @@ -6,12 +6,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=snort3 -PKG_VERSION:=3.1.47.0 +PKG_VERSION:=3.1.48.0 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://github.com/snort3/snort3/archive/refs/tags/ -PKG_HASH:=7565411db11b453a98f8bd88eeef0fa9f2e85416a8f595e710aa19c430228b8c +PKG_HASH:=65df088a8cac11e59f0b71a7f98fc9d21eeb0e31d35280c470c985172947ebfe PKG_MAINTAINER:=W. Michael Petullo PKG_LICENSE:=GPL-2.0-only diff --git a/net/snort3/patches/900-fix_build_for_archs_contain_plus.patch b/net/snort3/patches/900-fix_build_for_archs_contain_plus.patch new file mode 100644 index 000000000..163a7a069 --- /dev/null +++ b/net/snort3/patches/900-fix_build_for_archs_contain_plus.patch @@ -0,0 +1,16 @@ +--- a/cmake/FindFlexLexer.cmake ++++ b/cmake/FindFlexLexer.cmake +@@ -16,11 +16,11 @@ macro(FLEX NAME LEXER_IN LEXER_OUT) + COMPILE_FLAGS ${FLEX_FLAGS} + ) + +- # we use '+' as a separator for 'sed' to avoid conflicts with '/' in paths from LEXER_OUT ++ # we use '|' as a separator for 'sed' to avoid conflicts with '/' in paths from LEXER_OUT + add_custom_command( + OUTPUT ${LEXER_OUT} + COMMAND sed -e +- "s+void yyFlexLexer::LexerError+yynoreturn void yyFlexLexer::LexerError+;s+${LEXER_OUT}.tmp+${LEXER_OUT}+" ++ "s|void yyFlexLexer::LexerError|yynoreturn void yyFlexLexer::LexerError|;s|${LEXER_OUT}.tmp|${LEXER_OUT}|" + ${FLEX_${NAME}_OUTPUTS} > ${LEXER_OUT} + DEPENDS ${FLEX_${NAME}_OUTPUTS} + VERBATIM From a1a14c1103e83ec31d437c0893833026d211805d Mon Sep 17 00:00:00 2001 From: Tianling Shen Date: Wed, 7 Dec 2022 06:58:35 +0800 Subject: [PATCH 19/39] cloudflared: Update to 2022.11.1 Signed-off-by: Tianling Shen --- net/cloudflared/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/cloudflared/Makefile b/net/cloudflared/Makefile index 5ec60b03e..cfe971f9b 100644 --- a/net/cloudflared/Makefile +++ b/net/cloudflared/Makefile @@ -5,12 +5,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=cloudflared -PKG_VERSION:=2022.11.0 +PKG_VERSION:=2022.11.1 PKG_RELEASE:=$(AUTORELEASE) PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/cloudflare/cloudflared/tar.gz/$(PKG_VERSION)? -PKG_HASH:=01478108dc4a4a74b2a9eecda35b1b7cc69ce33f45fe0c94edf598b90154fda0 +PKG_HASH:=d4b1133057a721087a0a5387ea6d4d1ebf3b1f5135396da25a1e88e873cd5203 PKG_LICENSE:=Apache-2.0 PKG_LICENSE_FILES:=LICENSE From 88d33fef91e6bdeb195bf40b80ceb4644334a00b Mon Sep 17 00:00:00 2001 From: Tianling Shen Date: Wed, 7 Dec 2022 06:58:42 +0800 Subject: [PATCH 20/39] dnsproxy: Update to 0.46.4 Signed-off-by: Tianling Shen --- net/dnsproxy/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/dnsproxy/Makefile b/net/dnsproxy/Makefile index f8227ced1..a02447e8f 100644 --- a/net/dnsproxy/Makefile +++ b/net/dnsproxy/Makefile @@ -5,12 +5,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=dnsproxy -PKG_VERSION:=0.46.2 +PKG_VERSION:=0.46.4 PKG_RELEASE:=$(AUTORELEASE) PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/AdguardTeam/dnsproxy/tar.gz/v$(PKG_VERSION)? -PKG_HASH:=8ce720f258747b0ff74b9889c93c616efe3b7267d04283a1338d2ff1e24d661e +PKG_HASH:=5c959bd2f08b2304306b8f0b933b20d31a3a3d1ebeb0f349740799e5089fd4ae PKG_MAINTAINER:=Tianling Shen PKG_LICENSE:=Apache-2.0 From 190e04caf69746b862dafdff7b16f539f86a7544 Mon Sep 17 00:00:00 2001 From: Richard Yu Date: Wed, 7 Dec 2022 15:18:09 +0800 Subject: [PATCH 21/39] natmap: merge "ipv4" and "ipv6" options into single "family" option Signed-off-by: Richard Yu --- net/natmap/files/natmap.config | 3 +-- net/natmap/files/natmap.init | 7 +++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/net/natmap/files/natmap.config b/net/natmap/files/natmap.config index 519cea052..71931f6c5 100644 --- a/net/natmap/files/natmap.config +++ b/net/natmap/files/natmap.config @@ -1,7 +1,6 @@ config natmap option enable '0' - option ipv4 '0' - option ipv6 '0' + option family '' option udp_mode '1' option interface '' option interval '' diff --git a/net/natmap/files/natmap.init b/net/natmap/files/natmap.init index e729e7275..a9ff90539 100644 --- a/net/natmap/files/natmap.init +++ b/net/natmap/files/natmap.init @@ -18,8 +18,7 @@ load_interfaces() { validate_section_natmap() { uci_load_validate "${NAME}" natmap "$1" "$2" \ 'enable:bool:1' \ - 'ipv4:bool:0' \ - 'ipv6:bool:0' \ + 'family:string' \ 'udp_mode:bool:0' \ 'interface:string' \ 'interval:uinteger' \ @@ -44,8 +43,8 @@ natmap_instance() { ${stun_server:+-s "$stun_server"} \ ${http_server:+-h "$http_server"} - [ "${ipv4}" = 1 ] && procd_append_param command -4 - [ "${ipv6}" = 1 ] && procd_append_param command -6 + [ "${family}" = ipv4 ] && procd_append_param command -4 + [ "${family}" = ipv6 ] && procd_append_param command -6 [ "${udp_mode}" = 1 ] && procd_append_param command -u [ -n "$interface" ] && { From f22370b1b7bbfc8c87e73c9e637cb9b896eb111e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20L=C3=BCssing?= Date: Mon, 5 Dec 2022 16:03:02 +0100 Subject: [PATCH 22/39] bpfcountd: remove incomplete/broken namespace feature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The original idea of the extra namespace variable was to set up bpfcountd from other daemons etc. independent of what a user configured in /etc/config/bpfcountd for instance. Like: $ UCI_CONFIG_DIR=/var/run/bpfcountd/gluon-config \ /etc/init.d/bpfcountd start "" gluon However there are still issues with this approach: 1) Instance specific stop calls like: $ /etc/init.d/bpfcountd stop " will not stop the according namespaced instance, as the stop() in /etc/rc.common will call procd_kill() without the namespace prefix. And we can't overwrite that behaviour. And asking a user to use "... start " and "... stop ." is confusing. (and currently "... stop ." would not remove the correct unix socket). 2) A stop call without an instance/config name would always stop all instances. So the namespace variable would be ignored. While start without an instance "works", but: 3) It would stop any process that is not in the currently selected UCI_CONFIG_DIR. As all this is not easily fixable without changing OpenWrt internals, just remove the whole namespace idea for now. Signed-off-by: Linus Lüssing --- net/bpfcountd/files/etc/init.d/bpfcountd | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/net/bpfcountd/files/etc/init.d/bpfcountd b/net/bpfcountd/files/etc/init.d/bpfcountd index 1639da720..2db2a4bac 100755 --- a/net/bpfcountd/files/etc/init.d/bpfcountd +++ b/net/bpfcountd/files/etc/init.d/bpfcountd @@ -10,7 +10,6 @@ UNIXSOCKDIR=/var/run/bpfcountd bpfcountd_start() { local cfg="$1" - local namespace="$2" local disabled local ifname @@ -37,14 +36,12 @@ bpfcountd_start() { return 0 } - [ -z "$namespace" ] && namespace="bpfcountd" - - procd_open_instance "$namespace.$cfg" + procd_open_instance "$cfg" procd_set_param command /usr/sbin/bpfcountd procd_append_param command -i "$ifname" procd_append_param command -f "$filterfile" - procd_append_param command -u $UNIXSOCKDIR/"$namespace.$cfg".sock + procd_append_param command -u $UNIXSOCKDIR/"$cfg".sock [ -n "$prefilter" ] && procd_append_param command -F "$prefilter" [ -n "$buffersize" ] && procd_append_param command -b "$buffersize" @@ -56,7 +53,6 @@ bpfcountd_start() { start_service() { local cfg="$1" - local namespace="$2" local instance_found=0 . /lib/functions/network.sh @@ -75,22 +71,19 @@ start_service() { if [ -n "$cfg" ]; then [ "$instance_found" -gt 0 ] || return - bpfcountd_start "$cfg" "$namespace" + bpfcountd_start "$cfg" else - config_foreach bpfcountd_start bpfcountd "$namespace" + config_foreach bpfcountd_start bpfcountd fi } stop_service() { local cfg="$1" - local namespace="$2" - - [ -z "$namespace" ] && namespace="bpfcountd" if [ -n "$cfg" ]; then - rm $UNIXSOCKDIR/$namespace.$cfg.sock + rm $UNIXSOCKDIR/$cfg.sock else - rm $UNIXSOCKDIR/$namespace.*.sock + rm $UNIXSOCKDIR/*.sock fi } From 6a0ee524b14f5f2390dbf4414b5980add7aa95ed Mon Sep 17 00:00:00 2001 From: Tianling Shen Date: Thu, 8 Dec 2022 00:43:34 +0800 Subject: [PATCH 23/39] golang: Update to 1.19.4 go1.19.4 (released 2022-12-06) includes security fixes to the net/http and os packages, as well as bug fixes to the compiler, the runtime, and the crypto/x509, os/exec, and sync/atomic packages. Signed-off-by: Tianling Shen --- lang/golang/golang/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lang/golang/golang/Makefile b/lang/golang/golang/Makefile index 38b7b2430..4377965c2 100644 --- a/lang/golang/golang/Makefile +++ b/lang/golang/golang/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk GO_VERSION_MAJOR_MINOR:=1.19 -GO_VERSION_PATCH:=3 +GO_VERSION_PATCH:=4 PKG_NAME:=golang PKG_VERSION:=$(GO_VERSION_MAJOR_MINOR)$(if $(GO_VERSION_PATCH),.$(GO_VERSION_PATCH)) @@ -20,7 +20,7 @@ GO_SOURCE_URLS:=https://dl.google.com/go/ \ PKG_SOURCE:=go$(PKG_VERSION).src.tar.gz PKG_SOURCE_URL:=$(GO_SOURCE_URLS) -PKG_HASH:=18ac263e39210bcf68d85f4370e97fb1734166995a1f63fb38b4f6e07d90d212 +PKG_HASH:=eda74db4ac494800a3e66ee784e495bfbb9b8e535df924a8b01b1a8028b7f368 PKG_MAINTAINER:=Jeffery To PKG_LICENSE:=BSD-3-Clause From d6b712cde6c3094562e143df69a8cd600af52be1 Mon Sep 17 00:00:00 2001 From: John Audia Date: Tue, 29 Nov 2022 05:50:45 -0500 Subject: [PATCH 24/39] snort3: unified configs: local.lua and homenet.lua This commit adds /etc/snort/local.lua and /etc/snort/homenet.lua for user defined config options which is more simplistic than modifying upstream files directly. That can be tedious and decisive to maintain in sync with upstream changes. The init script has been adjusted accordingly. Acknowledgment to amish who maintains the Arch Linux snort-nfqueue package[1] for these ideas and initial code. Another modification is dropping the following args in the call to /usr/bin/snort by the init system as these options are provided in /etc/snort/local.lua: * --daq-dir /usr/lib/daq/ * -A "$alert_module" Instructions to configure snort3: 1. Edit /etc/snort/homenet.lua and redefine HOME_NET and EXTERNAL_NET, for example: HOME_NET = [[ 10.9.8.0/24 192.168.1.0/24 ]] EXTERNAL_NET = "!$HOME_NET" 2. Edit /etc/snort/local.lua to setup options unique to your use case of snort. The default ones I included should be sane for the role of IDS (alert only), but users may easily uncomment some options therein to use IPS (drop) mode. 3. Install or symlink rules to /etc/snort/rules/snort.rules and optionally edit /etc/snort/local.lua to define extra rules files if not using a unified 'snort.rules' References: 1. https://aur.archlinux.org/packages/snort-nfqueue Signed-off-by: John Audia --- net/snort3/Makefile | 24 ++++++++++++++-- net/snort3/files/homenet.lua | 3 ++ net/snort3/files/local.lua | 52 +++++++++++++++++++++++++++++++++++ net/snort3/files/snort.config | 1 - net/snort3/files/snort.init | 3 +- 5 files changed, 78 insertions(+), 5 deletions(-) create mode 100644 net/snort3/files/homenet.lua create mode 100644 net/snort3/files/local.lua diff --git a/net/snort3/Makefile b/net/snort3/Makefile index 925005814..b91ebc6bd 100644 --- a/net/snort3/Makefile +++ b/net/snort3/Makefile @@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=snort3 PKG_VERSION:=3.1.48.0 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://github.com/snort3/snort3/archive/refs/tags/ @@ -90,7 +90,8 @@ define Package/snort3/install $(PKG_INSTALL_DIR)/usr/include/snort/lua/snort_plugin.lua \ $(1)/usr/share/lua/ - $(INSTALL_DIR) $(1)/etc/snort + $(INSTALL_DIR) $(1)/etc/snort/{rules,lists,builtin_rules,so_rules} + $(INSTALL_CONF) \ $(PKG_INSTALL_DIR)/usr/etc/snort/*.lua \ $(1)/etc/snort @@ -107,6 +108,25 @@ define Package/snort3/install $(INSTALL_CONF) \ ./files/snort.config \ $(1)/etc/config/snort + $(INSTALL_CONF) \ + ./files/local.lua \ + $(1)/etc/snort + $(INSTALL_CONF) \ + ./files/homenet.lua \ + $(1)/etc/snort + sed \ + -i -e "/^EXTERNAL_NET\\s\\+=/ a include 'homenet.lua'" \ + -e "/^HOME_NET\\s\\+=/ i -- we set HOME_NET and EXTERNAL_NET here or via an included file" \ + -e 's/^\(HOME_NET\s\+=\)/--\1/g' \ + -e 's/^\(EXTERNAL_NET\s\+=\)/--\1/g' \ + $(1)/etc/snort/snort.lua + sed \ + -i -e "s/^\\(RULE_PATH\\s\\+=\\).*/\\1 'rules'/g" \ + -e "s/^\\(BUILTIN_RULE_PATH\\s\\+=\\).*/\\1 'builtin_rules'/g" \ + -e "s/^\\(PLUGIN_RULE_PATH\\s\\+=\\).*/\\1 'so_rules'/g" \ + -e "s/^\\(WHITE_LIST_PATH\\s\\+=\\).*/\\1 'lists'/g" \ + -e "s/^\\(BLACK_LIST_PATH\\s\\+=\\).*/\\1 'lists'/g" \ + $(1)/etc/snort/snort_defaults.lua endef $(eval $(call BuildPackage,snort3)) diff --git a/net/snort3/files/homenet.lua b/net/snort3/files/homenet.lua new file mode 100644 index 000000000..975f70254 --- /dev/null +++ b/net/snort3/files/homenet.lua @@ -0,0 +1,3 @@ +-- setup HOME_NET below with your IP range/ranges to protect +HOME_NET = [[ 192.168.1.0/24 10.1.0.1/24 ]] +EXTERNAL_NET = "!$HOME_NET" diff --git a/net/snort3/files/local.lua b/net/snort3/files/local.lua new file mode 100644 index 000000000..7929388ba --- /dev/null +++ b/net/snort3/files/local.lua @@ -0,0 +1,52 @@ +-- use ths file to customize any functions defined in /etc/snort/snort.lua + +-- switch tap to inline in ips and uncomment the below to run snort in inline mode +--snort = {} +--snort["-Q"] = '' + +ips = { + mode = tap, + -- mode = inline, + variables = default_variables, + -- uncomment and change the below to reflect rules or symlinks to rules on your filesystem + -- include = RULE_PATH .. '/snort.rules', +} + +daq = { + module_dirs = { + '/usr/lib/daq', + }, + modules = { + { + name = 'afpacket', + mode = 'inline', + } + } +} + +alert_syslog = { + level = 'info', +} + +-- To log to a file, uncomment the below and manually create the dir defined in output.logdir +--output.logdir = '/var/log/snort' +--alert_fast = { +-- file = true, +-- packet = false, +--} + +normalizer = { + tcp = { + ips = true, + } +} + +file_policy = { + enable_type = true, + enable_signature = true, + rules = { + use = { + verdict = 'log', enable_file_type = true, enable_file_signature = true + } + } +} diff --git a/net/snort3/files/snort.config b/net/snort3/files/snort.config index 92e42959d..84f5e96d9 100644 --- a/net/snort3/files/snort.config +++ b/net/snort3/files/snort.config @@ -1,4 +1,3 @@ config snort 'snort' option config_dir '/etc/snort/' - option alert_module 'alert_syslog' option interface 'eth0' diff --git a/net/snort3/files/snort.init b/net/snort3/files/snort.init index 4549e26ea..ff864e02b 100644 --- a/net/snort3/files/snort.init +++ b/net/snort3/files/snort.init @@ -9,7 +9,6 @@ PROG=/usr/bin/snort validate_snort_section() { uci_validate_section snort snort "${1}" \ 'config_dir:string' \ - 'alert_module:string' \ 'interface:string' } @@ -22,7 +21,7 @@ start_service() { } procd_open_instance - procd_set_param command $PROG -q --daq-dir /usr/lib/daq/ -i "$interface" -c "$config_dir/snort.lua" -A "$alert_module" + procd_set_param command $PROG -q -i "$interface" -c "${config_dir%/}/snort.lua" --tweaks local procd_set_param env SNORT_LUA_PATH="$config_dir" procd_set_param file $CONFIGFILE procd_set_param respawn From ee37d0ec863a2254c4bfecd7bb65155e276fed88 Mon Sep 17 00:00:00 2001 From: Stan Grishin Date: Wed, 7 Dec 2022 20:59:28 +0000 Subject: [PATCH 25/39] https-dns-proxy: add mdns service records * add mdns records for started instances * Makefile: use $(PKG_VERSION) as a value for PKG_SOURCE_DATE instead of hard-coding it Signed-off-by: Stan Grishin --- net/https-dns-proxy/Makefile | 4 ++-- net/https-dns-proxy/files/https-dns-proxy.init | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/net/https-dns-proxy/Makefile b/net/https-dns-proxy/Makefile index 81b01e5b9..a91a3d1cd 100644 --- a/net/https-dns-proxy/Makefile +++ b/net/https-dns-proxy/Makefile @@ -2,11 +2,11 @@ include $(TOPDIR)/rules.mk PKG_NAME:=https-dns-proxy PKG_VERSION:=2022-10-15 -PKG_RELEASE:=8 +PKG_RELEASE:=9 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/aarond10/https_dns_proxy/ -PKG_SOURCE_DATE:=2022-10-15 +PKG_SOURCE_DATE:=$(PKG_VERSION) PKG_SOURCE_VERSION:=f52a85f3edabecfbab41d9244c63a1c6b8aaf49b PKG_MIRROR_HASH:=dd8a55255e8859a462fcfd736577fec40731b39a4783325640518745009b0dee PKG_MAINTAINER:=Stan Grishin diff --git a/net/https-dns-proxy/files/https-dns-proxy.init b/net/https-dns-proxy/files/https-dns-proxy.init index cae80f161..201ddadc7 100755 --- a/net/https-dns-proxy/files/https-dns-proxy.init +++ b/net/https-dns-proxy/files/https-dns-proxy.init @@ -153,6 +153,7 @@ start_instance() { procd_set_param stdout 1 procd_set_param respawn procd_open_data + procd_add_mdns_service "$packageName" 'udp' "$port" "DNS over HTTPS proxy" json_add_string url "$url" if [ "$force_dns" -ne 0 ]; then json_add_array firewall From d321db64098d12ef3f8c465eba2b47f77f2d7af3 Mon Sep 17 00:00:00 2001 From: Peter Stadler Date: Fri, 2 Dec 2022 22:26:34 +0100 Subject: [PATCH 26/39] django: bump version 4.1.3 fix CVE-2022-41323 Signed-off-by: Peter Stadler --- lang/python/django/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lang/python/django/Makefile b/lang/python/django/Makefile index 4578076a1..5d34a6cbd 100644 --- a/lang/python/django/Makefile +++ b/lang/python/django/Makefile @@ -8,11 +8,11 @@ include $(TOPDIR)/rules.mk PKG_NAME:=django -PKG_VERSION:=4.1.1 -PKG_RELEASE:=$(AUTORELEASE) +PKG_VERSION:=4.1.3 +PKG_RELEASE:=1 PYPI_NAME:=Django -PKG_HASH:=a153ffd5143bf26a877bfae2f4ec736ebd8924a46600ca089ad96b54a1d4e28e +PKG_HASH:=678bbfc8604eb246ed54e2063f0765f13b321a50526bdc8cb1f943eda7fa31f1 PKG_MAINTAINER:=Alexandru Ardelean , Peter Stadler PKG_LICENSE:=BSD-3-Clause From 6703d7623097b591ea08c12e66351eed884e1005 Mon Sep 17 00:00:00 2001 From: Alois Klink Date: Wed, 23 Nov 2022 23:32:14 +0000 Subject: [PATCH 27/39] privoxy: fix preinst/postinst script indentation Fix the indentation of the preinst/postinst scripts for the privoxy package. Because these scripts didn't start with `#!/bin/sh` (they instead started with the TAB character), `/bin/sh` was not used to start them. On x86_64 and i386_pentium-mmx, this seems to be fine, but on arm_cortex-a15_neon-vfpv4 and aarch64_cortex-a53, running these scripts fails with a: ``` Installing privoxy (3.0.33-3) to root... Collected errors: * pkg_run_script: package "privoxy" preinst script returned status 1. * preinst_configure: Aborting installation of privoxy. * opkg_install_cmd: Cannot install package privoxy. ``` Reported-by: Marius Dinu Signed-off-by: Alois Klink --- net/privoxy/Makefile | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/net/privoxy/Makefile b/net/privoxy/Makefile index 9f859c4eb..a7f5227b8 100644 --- a/net/privoxy/Makefile +++ b/net/privoxy/Makefile @@ -118,13 +118,13 @@ define Package/privoxy/conffiles endef define Package/privoxy/preinst - #!/bin/sh - [ -n "$${IPKG_INSTROOT}" ] && exit 0 # if run within buildroot exit +#!/bin/sh +[ -n "$${IPKG_INSTROOT}" ] && exit 0 # if run within buildroot exit - # stop service if PKG_UPGRADE - [ "$${PKG_UPGRADE}" = "1" ] && /etc/init.d/privoxy stop >/dev/null 2>&1 - - exit 0 # suppress errors from stop command +# stop service if PKG_UPGRADE +[ "$${PKG_UPGRADE}" = "1" ] && /etc/init.d/privoxy stop >/dev/null 2>&1 + +exit 0 # suppress errors from stop command endef define Package/privoxy/install @@ -156,16 +156,16 @@ define Package/privoxy/install endef define Package/privoxy/postinst - #!/bin/sh - # if exists, update previous version entry missing protocol - (grep -E "privoxy.*8118$$" $${IPKG_INSTROOT}/etc/services) > /dev/null \ - && sed -i "s/privoxy.*8118/privoxy\t\t8118\/tcp/" $${IPKG_INSTROOT}/etc/services +#!/bin/sh +# if exists, update previous version entry missing protocol +(grep -E "privoxy.*8118$$" $${IPKG_INSTROOT}/etc/services) > /dev/null \ + && sed -i "s/privoxy.*8118/privoxy\t\t8118\/tcp/" $${IPKG_INSTROOT}/etc/services - # add missing tcp and udp entries - (grep -E "privoxy.*8118\/tcp" $${IPKG_INSTROOT}/etc/services) > /dev/null \ - || echo -e "privoxy\t\t8118/tcp" >> $${IPKG_INSTROOT}/etc/services - (grep -E "privoxy.*8118\/udp" $${IPKG_INSTROOT}/etc/services) > /dev/null \ - || echo -e "privoxy\t\t8118/udp" >> $${IPKG_INSTROOT}/etc/services +# add missing tcp and udp entries +(grep -E "privoxy.*8118\/tcp" $${IPKG_INSTROOT}/etc/services) > /dev/null \ + || echo -e "privoxy\t\t8118/tcp" >> $${IPKG_INSTROOT}/etc/services +(grep -E "privoxy.*8118\/udp" $${IPKG_INSTROOT}/etc/services) > /dev/null \ + || echo -e "privoxy\t\t8118/udp" >> $${IPKG_INSTROOT}/etc/services endef $(eval $(call BuildPackage,privoxy)) From 18d3c529fa4ab8dafcf6c147cf3cb55792d8ca10 Mon Sep 17 00:00:00 2001 From: Alois Klink Date: Wed, 23 Nov 2022 18:37:01 +0000 Subject: [PATCH 28/39] github-ci: error on any shell errors Enable `errexit` and `nounset` [POSIX shell options][1] in `.github/workflows/entrypoint.sh` so that the script fails if any command within the script fails. [1]: https://pubs.opengroup.org/onlinepubs/9699919799//utilities/V3_chap02.html#set Reported-by: Marius Dinu Fixes: https://github.com/openwrt/packages/issues/19953 Signed-off-by: Alois Klink --- .github/workflows/entrypoint.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/entrypoint.sh b/.github/workflows/entrypoint.sh index 760410547..6af84b8e7 100755 --- a/.github/workflows/entrypoint.sh +++ b/.github/workflows/entrypoint.sh @@ -1,10 +1,14 @@ #!/bin/sh +# not enabling `errtrace` and `pipefail` since those are bash specific +set -o errexit # failing commands causes script to fail +set -o nounset # undefined variables causes script to fail + mkdir -p /var/lock/ opkg update -[ -n "$CI_HELPER" ] || CI_HELPER="/ci/.github/workflows/ci_helpers.sh" +[ -n "${CI_HELPER:=''}" ] || CI_HELPER="/ci/.github/workflows/ci_helpers.sh" for PKG in /ci/*.ipk; do tar -xzOf "$PKG" ./control.tar.gz | tar xzf - ./control From f141e794552bfb6351d61c3a1389160466059add Mon Sep 17 00:00:00 2001 From: Hirokazu MORIKAWA Date: Tue, 6 Dec 2022 15:05:07 +0900 Subject: [PATCH 29/39] swig: bump to 4.1.1 update summary * Add Javascript Node v12-v18 support, remove support prior to v6. * Octave 6.0 to 6.4 support added. * Add PHP 8 support. * PHP wrapping is now done entirely via PHP's C API - no more .php wrapper. * Perl 5.8.0 is now the oldest version SWIG supports. * Python 3.3 is now the oldest Python 3 version SWIG supports. * Python 3.9-3.11 support added. * Various memory leak fixes in Python generated code. * Scilab 5.5-6.1 support improved. * Many improvements for each and every target language. * Various preprocessor expression handling improvements. * Improved C99, C++11, C++14, C++17 support. Start adding C++20 standard. * Make SWIG much more move semantics friendly. * Add C++ std::unique_ptr support. * Few minor C++ template handling improvements. * Various C++ using declaration fixes. * Few fixes for handling Doxygen comments. * GitHub Actions is now used instead of Travis CI for continuous integration. * Add building SWIG using CMake as a secondary build system. * Update optional SWIG build dependency for regex support from PCRE to PCRE2. * Couple of stability fixes. * Stability fix in ccache-swig when calculating hashes of inputs. * Some template handling improvements. * R - minor fixes plus deprecation for rtypecheck typemaps being optional. Signed-off-by: Hirokazu MORIKAWA --- utils/swig/Makefile | 6 +- utils/swig/patches/000-support_v12.patch | 1854 ---------------------- 2 files changed, 3 insertions(+), 1857 deletions(-) delete mode 100644 utils/swig/patches/000-support_v12.patch diff --git a/utils/swig/Makefile b/utils/swig/Makefile index 2a3c16cd0..03378e196 100644 --- a/utils/swig/Makefile +++ b/utils/swig/Makefile @@ -7,12 +7,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=swig -PKG_VERSION:=4.0.2 -PKG_RELEASE:=2 +PKG_VERSION:=4.1.1 +PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=@SF/$(PKG_NAME) -PKG_HASH:=d53be9730d8d58a16bf0cbd1f8ac0c0c3e1090573168bfa151b01eb47fa906fc +PKG_HASH:=2af08aced8fcd65cdb5cc62426768914bedc735b1c250325203716f78e39ac9b PKG_MAINTAINER:=John Crispin , Hirokazu MORIKAWA PKG_LICENSE:=GPL-3.0-or-later diff --git a/utils/swig/patches/000-support_v12.patch b/utils/swig/patches/000-support_v12.patch deleted file mode 100644 index 6ac90a836..000000000 --- a/utils/swig/patches/000-support_v12.patch +++ /dev/null @@ -1,1854 +0,0 @@ -diff --git a/.travis.yml b/.travis.yml -index 32c6656dd2..6530d2cb5f 100644 ---- a/.travis.yml -+++ b/.travis.yml -@@ -89,27 +89,17 @@ matrix: - dist: xenial - - compiler: gcc - os: linux -- env: SWIGLANG=javascript ENGINE=node VER=0.10 -- sudo: required -- dist: xenial -- - compiler: gcc -- os: linux -- env: SWIGLANG=javascript ENGINE=node VER=4 CPP11=1 -- sudo: required -- dist: xenial -- - compiler: gcc -- os: linux -- env: SWIGLANG=javascript ENGINE=node VER=6 CPP11=1 -+ env: SWIGLANG=javascript ENGINE=node VER=10 CPP11=1 - sudo: required - dist: xenial - - compiler: gcc - os: linux -- env: SWIGLANG=javascript ENGINE=node VER=8 CPP11=1 -+ env: SWIGLANG=javascript ENGINE=node VER=12 CPP11=1 - sudo: required - dist: xenial - - compiler: gcc - os: linux -- env: SWIGLANG=javascript ENGINE=node VER=10 CPP11=1 -+ env: SWIGLANG=javascript ENGINE=node VER=13 CPP11=1 - sudo: required - dist: xenial - - compiler: gcc -@@ -117,11 +107,6 @@ matrix: - env: SWIGLANG=javascript ENGINE=jsc - sudo: required - dist: xenial -- - compiler: gcc -- os: linux -- env: SWIGLANG=javascript ENGINE=v8 -- sudo: required -- dist: xenial - - compiler: gcc - os: linux - env: SWIGLANG=lua -diff --git a/Examples/Makefile.in b/Examples/Makefile.in -index 6fbca29db5..dadb012bf9 100644 ---- a/Examples/Makefile.in -+++ b/Examples/Makefile.in -@@ -674,8 +674,8 @@ java_clean: - # create a configuration for a new example. - - ROOT_DIR = @ROOT_DIR@ --JSINCLUDES = @JSCOREINC@ @JSV8INC@ --JSDYNAMICLINKING = @JSCOREDYNAMICLINKING@ @JSV8DYNAMICLINKING@ -+JSINCLUDES = @JSCOREINC@ -+JSDYNAMICLINKING = @JSCOREDYNAMICLINKING@ - NODEJS = @NODEJS@ - NODEGYP = @NODEGYP@ - -@@ -710,7 +710,7 @@ javascript: $(SRCDIR_SRCS) javascript_custom_interpreter - ifeq (jsc, $(ENGINE)) - $(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) $(JSINCLUDES) - $(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO) --else # (v8 | node) # v8 and node must be compiled as c++ -+else # (node) # node must be compiled as c++ - $(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ISRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) $(JSINCLUDES) - $(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO) - endif -@@ -759,9 +759,6 @@ ifeq (jsc, $(ENGINE)) - echo "Unknown JavascriptCore version."; \ - fi - endif --ifeq (v8, $(ENGINE)) -- echo "Unknown v8 version." --endif - - # ----------------------------------------------------------------- - # Cleaning the Javascript examples -diff --git a/Examples/javascript/example.mk b/Examples/javascript/example.mk -index 3ef012aa82..beafd6f3fb 100644 ---- a/Examples/javascript/example.mk -+++ b/Examples/javascript/example.mk -@@ -7,19 +7,13 @@ else - JSENGINE=node - endif - --ifneq (, $(V8_VERSION)) -- JSV8_VERSION=$(V8_VERSION) --else -- JSV8_VERSION=0x031110 --endif -- - EXAMPLES_TOP = ../.. - SWIG_TOP = ../../.. - SWIGEXE = $(SWIG_TOP)/swig - SWIG_LIB_DIR = $(SWIG_TOP)/$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib - TARGET = example - INTERFACE = example.i --SWIGOPT = -$(JSENGINE) -DV8_VERSION=$(JSV8_VERSION) -+SWIGOPT = -$(JSENGINE) - - check: build - $(MAKE) -f $(EXAMPLES_TOP)/Makefile SRCDIR='$(SRCDIR)' JSENGINE='$(JSENGINE)' TARGET='$(TARGET)' javascript_run -diff --git a/Examples/javascript/native/example.i b/Examples/javascript/native/example.i -index 8c61600606..e94f18118b 100644 ---- a/Examples/javascript/native/example.i -+++ b/Examples/javascript/native/example.i -@@ -15,7 +15,7 @@ int placeholder() { return 0; } - static SwigV8ReturnValue JavaScript_do_work(const SwigV8Arguments &args) { - SWIGV8_HANDLESCOPE(); - const int MY_MAGIC_NUMBER = 5; -- v8::Handle jsresult = -+ v8::Local jsresult = - SWIG_From_int(static_cast< int >(MY_MAGIC_NUMBER)); - if (args.Length() != 0) - SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments."); -diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in -index 8127415f12..ce16f2ec0d 100644 ---- a/Examples/test-suite/javascript/Makefile.in -+++ b/Examples/test-suite/javascript/Makefile.in -@@ -22,16 +22,8 @@ else - JSENGINE=node - endif - --ifneq (, $(V8_VERSION)) -- JSV8_VERSION=$(V8_VERSION) --else -- JSV8_VERSION=0x031110 --endif -- - include $(srcdir)/../common.mk - --SWIGOPT += -DV8_VERSION=$(JSV8_VERSION) -- - _setup = \ - if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \ - echo "$(ACTION)ing $(LANGUAGE) ($(JSENGINE)) testcase $* (with run test)" ; \ -diff --git a/Examples/test-suite/native_directive.i b/Examples/test-suite/native_directive.i -index 9ae76e0b7f..99089af507 100644 ---- a/Examples/test-suite/native_directive.i -+++ b/Examples/test-suite/native_directive.i -@@ -53,7 +53,7 @@ extern "C" JNIEXPORT jint JNICALL Java_native_1directive_native_1directiveJNI_Co - - static SwigV8ReturnValue JavaScript_alpha_count(const SwigV8Arguments &args) { - SWIGV8_HANDLESCOPE(); -- v8::Handle jsresult; -+ v8::Local jsresult; - char *arg1 = (char *)0; - int res1; - char *buf1 = 0; -diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg -index c4aaf3db0c..b470e2aeeb 100644 ---- a/Lib/javascript/v8/javascriptcode.swg -+++ b/Lib/javascript/v8/javascriptcode.swg -@@ -11,7 +11,7 @@ - static SwigV8ReturnValue $jswrapper(const SwigV8Arguments &args) { - SWIGV8_HANDLESCOPE(); - -- v8::Handle self = args.Holder(); -+ v8::Local self = args.Holder(); - $jslocals - if(args.Length() != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); - $jscode -@@ -53,7 +53,7 @@ static SwigV8ReturnValue $jswrapper(const SwigV8Arguments &args) { - SWIGV8_HANDLESCOPE(); - - OverloadErrorHandler errorHandler; -- v8::Handle self; -+ v8::Local self; - - // switch all cases by means of series of if-returns. - $jsdispatchcases -@@ -78,7 +78,7 @@ fail: - static SwigV8ReturnValue $jswrapper(const SwigV8Arguments &args, V8ErrorHandler &SWIGV8_ErrorHandler) { - SWIGV8_HANDLESCOPE(); - -- v8::Handle self = args.Holder(); -+ v8::Local self = args.Holder(); - $jslocals - if(args.Length() != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); - $jscode -@@ -103,17 +103,10 @@ fail: - %{ - if(args.Length() == $jsargcount) { - errorHandler.err.Clear(); --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903) -- self = $jswrapper(args, errorHandler); -- if(errorHandler.err.IsEmpty()) { -- SWIGV8_ESCAPE(self); -- } --#else - $jswrapper(args, errorHandler); - if(errorHandler.err.IsEmpty()) { - return; - } --#endif - } - %} - -@@ -124,23 +117,8 @@ fail: - * ----------------------------------------------------------------------------- */ - %fragment ("js_dtor", "templates") - %{ -- --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710) --static void $jswrapper(v8::Persistent< v8::Value > object, void *parameter) { -- SWIGV8_Proxy *proxy = static_cast(parameter); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900) --static void $jswrapper(v8::Isolate *isolate, v8::Persistent object, void *parameter) { -- SWIGV8_Proxy *proxy = static_cast(parameter); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION) --static void $jswrapper(v8::Isolate *isolate, v8::Persistent *object, SWIGV8_Proxy *proxy) { --#elif (V8_MAJOR_VERSION-0) < 5 --static void $jswrapper(const v8::WeakCallbackData &data) { -- v8::Local object = data.GetValue(); -- SWIGV8_Proxy *proxy = data.GetParameter(); --#else - static void $jswrapper(const v8::WeakCallbackInfo &data) { - SWIGV8_Proxy *proxy = data.GetParameter(); --#endif - - if(proxy->swigCMemOwn && proxy->swigCObject) { - #ifdef SWIGRUNTIME_DEBUG -@@ -149,20 +127,6 @@ static void $jswrapper(const v8::WeakCallbackData &dat - $jsfree proxy->swigCObject; - } - delete proxy; -- --#if (V8_MAJOR_VERSION-0) < 5 -- object.Clear(); --#endif -- --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710) -- object.Dispose(); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900) -- object.Dispose(isolate); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032100) -- object->Dispose(isolate); --#elif (V8_MAJOR_VERSION-0) < 5 -- object->Dispose(); --#endif - } - %} - -@@ -174,40 +138,14 @@ static void $jswrapper(const v8::WeakCallbackData &dat - * ----------------------------------------------------------------------------- */ - %fragment ("js_dtoroverride", "templates") - %{ --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710) --static void $jswrapper(v8::Persistent object, void *parameter) { -- SWIGV8_Proxy *proxy = static_cast(parameter); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900) --static void $jswrapper(v8::Isolate *isolate, v8::Persistent object, void *parameter) { -- SWIGV8_Proxy *proxy = static_cast(parameter); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION) --static void $jswrapper(v8::Isolate *isolate, v8::Persistent< v8::Object> *object, SWIGV8_Proxy *proxy) { --#elif (V8_MAJOR_VERSION-0) < 5 --static void $jswrapper(const v8::WeakCallbackData &data) { -- v8::Local object = data.GetValue(); -- SWIGV8_Proxy *proxy = data.GetParameter(); --#else - static void $jswrapper(const v8::WeakCallbackInfo &data) { - SWIGV8_Proxy *proxy = data.GetParameter(); --#endif - - if(proxy->swigCMemOwn && proxy->swigCObject) { - $jstype arg1 = ($jstype)proxy->swigCObject; - ${destructor_action} - } - delete proxy; -- --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710) -- object.Dispose(); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900) -- object.Dispose(isolate); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032100) -- object->Dispose(isolate); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION) -- object->Dispose(); --#elif (V8_MAJOR_VERSION-0) < 5 -- object.Clear(); --#endif - } - %} - -@@ -219,14 +157,10 @@ static void $jswrapper(const v8::WeakCallbackInfo &data) { - * ----------------------------------------------------------------------------- */ - %fragment("js_getter", "templates") - %{ --#if (V8_MAJOR_VERSION-0) < 5 --static SwigV8ReturnValue $jswrapper(v8::Local property, const SwigV8PropertyCallbackInfo &info) { --#else - static SwigV8ReturnValue $jswrapper(v8::Local property, const SwigV8PropertyCallbackInfo &info) { --#endif - SWIGV8_HANDLESCOPE(); - -- v8::Handle jsresult; -+ v8::Local jsresult; - $jslocals - $jscode - SWIGV8_RETURN_INFO(jsresult, info); -@@ -245,11 +179,7 @@ fail: - * ----------------------------------------------------------------------------- */ - %fragment("js_setter", "templates") - %{ --#if (V8_MAJOR_VERSION-0) < 5 --static void $jswrapper(v8::Local property, v8::Local value, const SwigV8PropertyCallbackInfoVoid &info) { --#else - static void $jswrapper(v8::Local property, v8::Local value, const SwigV8PropertyCallbackInfoVoid &info) { --#endif - SWIGV8_HANDLESCOPE(); - - $jslocals -@@ -271,7 +201,7 @@ fail: - static SwigV8ReturnValue $jswrapper(const SwigV8Arguments &args) { - SWIGV8_HANDLESCOPE(); - -- v8::Handle jsresult; -+ v8::Local jsresult; - $jslocals - if(args.Length() != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); - -@@ -296,7 +226,7 @@ fail: - static SwigV8ReturnValue $jswrapper(const SwigV8Arguments &args) { - SWIGV8_HANDLESCOPE(); - -- v8::Handle jsresult; -+ v8::Local jsresult; - OverloadErrorHandler errorHandler; - $jscode - -@@ -320,7 +250,7 @@ static SwigV8ReturnValue $jswrapper(const SwigV8Arguments &args, V8ErrorHandler - { - SWIGV8_HANDLESCOPE(); - -- v8::Handle jsresult; -+ v8::Local jsresult; - $jslocals - $jscode - SWIGV8_RETURN(jsresult); -@@ -342,17 +272,10 @@ fail: - - if(args.Length() == $jsargcount) { - errorHandler.err.Clear(); --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903) -- jsresult = $jswrapper(args, errorHandler); -- if(errorHandler.err.IsEmpty()) { -- SWIGV8_ESCAPE(jsresult); -- } --#else - $jswrapper(args, errorHandler); - if(errorHandler.err.IsEmpty()) { - return; - } --#endif - } - %} - -@@ -374,7 +297,7 @@ fail: - %fragment("jsv8_define_class_template", "templates") - %{ - /* Name: $jsmangledname, Type: $jsmangledtype, Dtor: $jsdtor */ -- v8::Handle $jsmangledname_class = SWIGV8_CreateClassTemplate("$jsmangledname"); -+ v8::Local $jsmangledname_class = SWIGV8_CreateClassTemplate("$jsmangledname"); - SWIGV8_SET_CLASS_TEMPL($jsmangledname_clientData.class_templ, $jsmangledname_class); - $jsmangledname_clientData.dtor = $jsdtor; - if (SWIGTYPE_$jsmangledtype->clientdata == 0) { -@@ -392,15 +315,11 @@ fail: - %{ - if (SWIGTYPE_p$jsbaseclass->clientdata && !(static_cast(SWIGTYPE_p$jsbaseclass->clientdata)->class_templ.IsEmpty())) - { --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903) -- $jsmangledname_class->Inherit(static_cast(SWIGTYPE_p$jsbaseclass->clientdata)->class_templ); --#else - $jsmangledname_class->Inherit( - v8::Local::New( - v8::Isolate::GetCurrent(), - static_cast(SWIGTYPE_p$jsbaseclass->clientdata)->class_templ) - ); --#endif - - #ifdef SWIGRUNTIME_DEBUG - printf("Inheritance successful $jsmangledname $jsbaseclass\n"); -@@ -420,11 +339,10 @@ fail: - %fragment("jsv8_create_class_instance", "templates") - %{ - /* Class: $jsname ($jsmangledname) */ -- v8::Handle $jsmangledname_class_0 = SWIGV8_CreateClassTemplate("$jsname"); -+ v8::Local $jsmangledname_class_0 = SWIGV8_CreateClassTemplate("$jsname"); - $jsmangledname_class_0->SetCallHandler($jsctor); - $jsmangledname_class_0->Inherit($jsmangledname_class); -- $jsmangledname_class_0->SetHiddenPrototype(true); -- v8::Handle $jsmangledname_obj = $jsmangledname_class_0->GetFunction(); -+ v8::Local $jsmangledname_obj = $jsmangledname_class_0->GetFunction(SWIGV8_CURRENT_CONTEXT()).ToLocalChecked(); - %} - - /* ----------------------------------------------------------------------------- -@@ -435,7 +353,7 @@ fail: - * ----------------------------------------------------------------------------- */ - %fragment("jsv8_register_class", "templates") - %{ -- $jsparent_obj->Set(SWIGV8_SYMBOL_NEW("$jsname"), $jsmangledname_obj); -+ $jsparent_obj->Set(SWIGV8_CURRENT_CONTEXT(), SWIGV8_SYMBOL_NEW("$jsname"), $jsmangledname_obj); - %} - - /* ----------------------------------------------------------------------------- -@@ -444,7 +362,7 @@ fail: - * ----------------------------------------------------------------------------- */ - %fragment("jsv8_create_namespace", "templates") - %{ -- v8::Handle $jsmangledname_obj = SWIGV8_OBJECT_NEW(); -+ v8::Local $jsmangledname_obj = SWIGV8_OBJECT_NEW(); - %} - - /* ----------------------------------------------------------------------------- -@@ -455,7 +373,7 @@ fail: - * ----------------------------------------------------------------------------- */ - %fragment("jsv8_register_namespace", "templates") - %{ -- $jsparent_obj->Set(SWIGV8_SYMBOL_NEW("$jsname"), $jsmangledname_obj); -+ $jsparent_obj->Set(SWIGV8_CURRENT_CONTEXT(), SWIGV8_SYMBOL_NEW("$jsname"), $jsmangledname_obj); - %} - - /* ----------------------------------------------------------------------------- -diff --git a/Lib/javascript/v8/javascriptcomplex.swg b/Lib/javascript/v8/javascriptcomplex.swg -index d3b4aaffa6..533e548131 100644 ---- a/Lib/javascript/v8/javascriptcomplex.swg -+++ b/Lib/javascript/v8/javascriptcomplex.swg -@@ -12,7 +12,7 @@ - %fragment(SWIG_From_frag(Type),"header", - fragment=SWIG_From_frag(double)) - { --SWIGINTERNINLINE v8::Handle -+SWIGINTERNINLINE v8::Local - SWIG_From_dec(Type)(%ifcplusplus(const Type&, Type) c) - { - SWIGV8_HANDLESCOPE_ESC(); -@@ -32,12 +32,12 @@ SWIG_From_dec(Type)(%ifcplusplus(const Type&, Type) c) - fragment=SWIG_AsVal_frag(double)) - { - SWIGINTERN int --SWIG_AsVal_dec(Type) (v8::Handle o, Type* val) -+SWIG_AsVal_dec(Type) (v8::Local o, Type* val) - { - SWIGV8_HANDLESCOPE(); - - if (o->IsArray()) { -- v8::Handle array = v8::Handle::Cast(o); -+ v8::Local array = v8::Local::Cast(o); - - if(array->Length() != 2) SWIG_Error(SWIG_TypeError, "Illegal argument for complex: must be array[2]."); - double re, im; -@@ -74,12 +74,12 @@ SWIG_AsVal_dec(Type) (v8::Handle o, Type* val) - %fragment(SWIG_AsVal_frag(Type),"header", - fragment=SWIG_AsVal_frag(float)) { - SWIGINTERN int --SWIG_AsVal_dec(Type) (v8::Handle o, Type* val) -+SWIG_AsVal_dec(Type) (v8::Local o, Type* val) - { - SWIGV8_HANDLESCOPE(); - - if (o->IsArray()) { -- v8::Handle array = v8::Handle::Cast(o); -+ v8::Local array = v8::Local::Cast(o); - - if(array->Length() != 2) SWIG_Error(SWIG_TypeError, "Illegal argument for complex: must be array[2]."); - double re, im; -diff --git a/Lib/javascript/v8/javascripthelpers.swg b/Lib/javascript/v8/javascripthelpers.swg -index 80fbd7aa1a..d722581552 100644 ---- a/Lib/javascript/v8/javascripthelpers.swg -+++ b/Lib/javascript/v8/javascripthelpers.swg -@@ -1,39 +1,26 @@ - %insert(runtime) %{ - --// Note: since 3.19 there are new CallBack types, since 03.21.9 the old ones have been removed --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903) --typedef v8::InvocationCallback SwigV8FunctionCallback; --typedef v8::AccessorGetter SwigV8AccessorGetterCallback; --typedef v8::AccessorSetter SwigV8AccessorSetterCallback; --typedef v8::AccessorInfo SwigV8PropertyCallbackInfoVoid; --#elif (V8_MAJOR_VERSION-0) < 5 --typedef v8::FunctionCallback SwigV8FunctionCallback; --typedef v8::AccessorGetterCallback SwigV8AccessorGetterCallback; --typedef v8::AccessorSetterCallback SwigV8AccessorSetterCallback; --typedef v8::PropertyCallbackInfo SwigV8PropertyCallbackInfoVoid; --#else - typedef v8::FunctionCallback SwigV8FunctionCallback; - typedef v8::AccessorNameGetterCallback SwigV8AccessorGetterCallback; - typedef v8::AccessorNameSetterCallback SwigV8AccessorSetterCallback; - typedef v8::PropertyCallbackInfo SwigV8PropertyCallbackInfoVoid; --#endif - - /** - * Creates a class template for a class with specified initialization function. - */ --SWIGRUNTIME v8::Handle SWIGV8_CreateClassTemplate(const char* symbol) { -+SWIGRUNTIME v8::Local SWIGV8_CreateClassTemplate(const char* symbol) { - SWIGV8_HANDLESCOPE_ESC(); - - v8::Local class_templ = SWIGV8_FUNCTEMPLATE_NEW_VOID(); - class_templ->SetClassName(SWIGV8_SYMBOL_NEW(symbol)); - -- v8::Handle inst_templ = class_templ->InstanceTemplate(); -+ v8::Local inst_templ = class_templ->InstanceTemplate(); - inst_templ->SetInternalFieldCount(1); - -- v8::Handle equals_templ = class_templ->PrototypeTemplate(); -+ v8::Local equals_templ = class_templ->PrototypeTemplate(); - equals_templ->Set(SWIGV8_SYMBOL_NEW("equals"), SWIGV8_FUNCTEMPLATE_NEW(_SWIGV8_wrap_equals)); - -- v8::Handle cptr_templ = class_templ->PrototypeTemplate(); -+ v8::Local cptr_templ = class_templ->PrototypeTemplate(); - cptr_templ->Set(SWIGV8_SYMBOL_NEW("getCPtr"), SWIGV8_FUNCTEMPLATE_NEW(_wrap_getCPtr)); - - SWIGV8_ESCAPE(class_templ); -@@ -42,55 +29,47 @@ SWIGRUNTIME v8::Handle SWIGV8_CreateClassTemplate(const ch - /** - * Registers a class method with given name for a given class template. - */ --SWIGRUNTIME void SWIGV8_AddMemberFunction(v8::Handle class_templ, const char* symbol, -+SWIGRUNTIME void SWIGV8_AddMemberFunction(v8::Local class_templ, const char* symbol, - SwigV8FunctionCallback _func) { -- v8::Handle proto_templ = class_templ->PrototypeTemplate(); -+ v8::Local proto_templ = class_templ->PrototypeTemplate(); - proto_templ->Set(SWIGV8_SYMBOL_NEW(symbol), SWIGV8_FUNCTEMPLATE_NEW(_func)); - } - - /** - * Registers a class property with given name for a given class template. - */ --SWIGRUNTIME void SWIGV8_AddMemberVariable(v8::Handle class_templ, const char* symbol, -+SWIGRUNTIME void SWIGV8_AddMemberVariable(v8::Local class_templ, const char* symbol, - SwigV8AccessorGetterCallback getter, SwigV8AccessorSetterCallback setter) { -- v8::Handle proto_templ = class_templ->InstanceTemplate(); -+ v8::Local proto_templ = class_templ->InstanceTemplate(); - proto_templ->SetAccessor(SWIGV8_SYMBOL_NEW(symbol), getter, setter); - } - - /** - * Registers a class method with given name for a given object. - */ --SWIGRUNTIME void SWIGV8_AddStaticFunction(v8::Handle obj, const char* symbol, -+SWIGRUNTIME void SWIGV8_AddStaticFunction(v8::Local obj, const char* symbol, - const SwigV8FunctionCallback& _func) { -- obj->Set(SWIGV8_SYMBOL_NEW(symbol), SWIGV8_FUNCTEMPLATE_NEW(_func)->GetFunction()); -+#if (NODE_MODULE_VERSION < 72) -+ obj->Set(SWIGV8_SYMBOL_NEW(symbol), SWIGV8_FUNCTEMPLATE_NEW(_func)->GetFunction(SWIGV8_CURRENT_CONTEXT()).ToLocalChecked()); -+#else -+ obj->Set(SWIGV8_CURRENT_CONTEXT(), SWIGV8_SYMBOL_NEW(symbol), SWIGV8_FUNCTEMPLATE_NEW(_func)->GetFunction(SWIGV8_CURRENT_CONTEXT()).ToLocalChecked()); -+#endif - } - - /** - * Registers a class method with given name for a given object. - */ --SWIGRUNTIME void SWIGV8_AddStaticVariable(v8::Handle obj, const char* symbol, -+SWIGRUNTIME void SWIGV8_AddStaticVariable(v8::Local obj, const char* symbol, - SwigV8AccessorGetterCallback getter, SwigV8AccessorSetterCallback setter) { --#if (V8_MAJOR_VERSION-0) < 5 -- obj->SetAccessor(SWIGV8_SYMBOL_NEW(symbol), getter, setter); --#else - obj->SetAccessor(SWIGV8_CURRENT_CONTEXT(), SWIGV8_SYMBOL_NEW(symbol), getter, setter); --#endif - } - --#if (V8_MAJOR_VERSION-0) < 5 --SWIGRUNTIME void JS_veto_set_variable(v8::Local property, v8::Local value, const SwigV8PropertyCallbackInfoVoid& info) --#else - SWIGRUNTIME void JS_veto_set_variable(v8::Local property, v8::Local value, const SwigV8PropertyCallbackInfoVoid& info) --#endif - { - char buffer[256]; - char msg[512]; - int res; - --#if (V8_MAJOR_VERSION-0) < 5 -- property->WriteUtf8(buffer, 256); -- res = sprintf(msg, "Tried to write read-only variable: %s.", buffer); --#else - v8::Local sproperty; - if (property->ToString(SWIGV8_CURRENT_CONTEXT()).ToLocal(&sproperty)) { - SWIGV8_WRITE_UTF8(sproperty, buffer, 256); -@@ -99,7 +78,6 @@ SWIGRUNTIME void JS_veto_set_variable(v8::Local property, v8::Local exports) -+void SWIGV8_INIT (v8::Local exports) - #else --void SWIGV8_INIT (v8::Handle exports, v8::Handle /*module*/) -+void SWIGV8_INIT (v8::Local exports, v8::Local /*module*/) - #endif - { - SWIG_InitializeModule(static_cast(&exports)); - - SWIGV8_HANDLESCOPE(); - -- v8::Handle exports_obj = exports; -+ v8::Local exports_obj = exports; - %} - - -diff --git a/Lib/javascript/v8/javascriptprimtypes.swg b/Lib/javascript/v8/javascriptprimtypes.swg -index f76be983b1..41635e9d2d 100644 ---- a/Lib/javascript/v8/javascriptprimtypes.swg -+++ b/Lib/javascript/v8/javascriptprimtypes.swg -@@ -6,7 +6,7 @@ - - %fragment(SWIG_From_frag(bool),"header") { - SWIGINTERNINLINE --v8::Handle -+v8::Local - SWIG_From_dec(bool)(bool value) - { - return SWIGV8_BOOLEAN_NEW(value); -@@ -16,7 +16,7 @@ SWIG_From_dec(bool)(bool value) - %fragment(SWIG_AsVal_frag(bool),"header", - fragment=SWIG_AsVal_frag(long)) { - SWIGINTERN --int SWIG_AsVal_dec(bool)(v8::Handle obj, bool *val) -+int SWIG_AsVal_dec(bool)(v8::Local obj, bool *val) - { - if(!obj->IsBoolean()) { - return SWIG_ERROR; -@@ -31,7 +31,7 @@ int SWIG_AsVal_dec(bool)(v8::Handle obj, bool *val) - - %fragment(SWIG_From_frag(int),"header") { - SWIGINTERNINLINE --v8::Handle SWIG_From_dec(int)(int value) -+v8::Local SWIG_From_dec(int)(int value) - { - return SWIGV8_INT32_NEW(value); - } -@@ -39,7 +39,7 @@ v8::Handle SWIG_From_dec(int)(int value) - - %fragment(SWIG_AsVal_frag(int),"header") { - SWIGINTERN --int SWIG_AsVal_dec(int)(v8::Handle valRef, int* val) -+int SWIG_AsVal_dec(int)(v8::Local valRef, int* val) - { - if (!valRef->IsNumber()) { - return SWIG_TypeError; -@@ -54,7 +54,7 @@ int SWIG_AsVal_dec(int)(v8::Handle valRef, int* val) - - %fragment(SWIG_From_frag(long),"header") { - SWIGINTERNINLINE --v8::Handle SWIG_From_dec(long)(long value) -+v8::Local SWIG_From_dec(long)(long value) - { - return SWIGV8_NUMBER_NEW(value); - } -@@ -63,7 +63,7 @@ v8::Handle SWIG_From_dec(long)(long value) - %fragment(SWIG_AsVal_frag(long),"header", - fragment="SWIG_CanCastAsInteger") { - SWIGINTERN --int SWIG_AsVal_dec(long)(v8::Handle obj, long* val) -+int SWIG_AsVal_dec(long)(v8::Local obj, long* val) - { - if (!obj->IsNumber()) { - return SWIG_TypeError; -@@ -79,7 +79,7 @@ int SWIG_AsVal_dec(long)(v8::Handle obj, long* val) - %fragment(SWIG_From_frag(unsigned long),"header", - fragment=SWIG_From_frag(long)) { - SWIGINTERNINLINE --v8::Handle SWIG_From_dec(unsigned long)(unsigned long value) -+v8::Local SWIG_From_dec(unsigned long)(unsigned long value) - { - return (value > LONG_MAX) ? - SWIGV8_INTEGER_NEW_UNS(value) : SWIGV8_INTEGER_NEW(%numeric_cast(value,long)); -@@ -89,7 +89,7 @@ v8::Handle SWIG_From_dec(unsigned long)(unsigned long value) - %fragment(SWIG_AsVal_frag(unsigned long),"header", - fragment="SWIG_CanCastAsInteger") { - SWIGINTERN --int SWIG_AsVal_dec(unsigned long)(v8::Handle obj, unsigned long *val) -+int SWIG_AsVal_dec(unsigned long)(v8::Local obj, unsigned long *val) - { - if(!obj->IsNumber()) { - return SWIG_TypeError; -@@ -115,7 +115,7 @@ int SWIG_AsVal_dec(unsigned long)(v8::Handle obj, unsigned long *val) - fragment="SWIG_LongLongAvailable") { - %#ifdef SWIG_LONG_LONG_AVAILABLE - SWIGINTERNINLINE --v8::Handle SWIG_From_dec(long long)(long long value) -+v8::Local SWIG_From_dec(long long)(long long value) - { - return SWIGV8_NUMBER_NEW(value); - } -@@ -128,7 +128,7 @@ v8::Handle SWIG_From_dec(long long)(long long value) - fragment="SWIG_LongLongAvailable") { - %#ifdef SWIG_LONG_LONG_AVAILABLE - SWIGINTERN --int SWIG_AsVal_dec(long long)(v8::Handle obj, long long* val) -+int SWIG_AsVal_dec(long long)(v8::Local obj, long long* val) - { - if (!obj->IsNumber()) { - return SWIG_TypeError; -@@ -148,7 +148,7 @@ int SWIG_AsVal_dec(long long)(v8::Handle obj, long long* val) - fragment="SWIG_LongLongAvailable") { - %#ifdef SWIG_LONG_LONG_AVAILABLE - SWIGINTERNINLINE --v8::Handle SWIG_From_dec(unsigned long long)(unsigned long long value) -+v8::Local SWIG_From_dec(unsigned long long)(unsigned long long value) - { - return (value > LONG_MAX) ? - SWIGV8_INTEGER_NEW_UNS(value) : SWIGV8_INTEGER_NEW(%numeric_cast(value,long)); -@@ -162,7 +162,7 @@ v8::Handle SWIG_From_dec(unsigned long long)(unsigned long long value - fragment="SWIG_LongLongAvailable") { - %#ifdef SWIG_LONG_LONG_AVAILABLE - SWIGINTERN --int SWIG_AsVal_dec(unsigned long long)(v8::Handle obj, unsigned long long *val) -+int SWIG_AsVal_dec(unsigned long long)(v8::Local obj, unsigned long long *val) - { - if(!obj->IsNumber()) { - return SWIG_TypeError; -@@ -185,7 +185,7 @@ int SWIG_AsVal_dec(unsigned long long)(v8::Handle obj, unsigned long - - %fragment(SWIG_From_frag(double),"header") { - SWIGINTERN --v8::Handle SWIG_From_dec(double) (double val) -+v8::Local SWIG_From_dec(double) (double val) - { - return SWIGV8_NUMBER_NEW(val); - } -@@ -193,7 +193,7 @@ v8::Handle SWIG_From_dec(double) (double val) - - %fragment(SWIG_AsVal_frag(double),"header") { - SWIGINTERN --int SWIG_AsVal_dec(double)(v8::Handle obj, double *val) -+int SWIG_AsVal_dec(double)(v8::Local obj, double *val) - { - if(!obj->IsNumber()) { - return SWIG_TypeError; -@@ -203,4 +203,3 @@ int SWIG_AsVal_dec(double)(v8::Handle obj, double *val) - return SWIG_OK; - } - } -- -diff --git a/Lib/javascript/v8/javascriptrun.swg b/Lib/javascript/v8/javascriptrun.swg -index 2452f4040d..2023d023da 100644 ---- a/Lib/javascript/v8/javascriptrun.swg -+++ b/Lib/javascript/v8/javascriptrun.swg -@@ -5,70 +5,37 @@ - - // First v8 version that uses "SetWeak" and not "MakeWeak" - --#define SWIGV8_SETWEAK_VERSION 0x032224 -- --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031803) --#define SWIGV8_STRING_NEW2(cstr, len) v8::String::New(cstr, len) --#else -+#if (NODE_MODULE_VERSION < 72) - #define SWIGV8_STRING_NEW2(cstr, len) v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), cstr, v8::String::kNormalString, len) -+#else -+#define SWIGV8_STRING_NEW2(cstr, len) (v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), cstr, v8::NewStringType::kNormal, len)).ToLocalChecked() - #endif - --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903) --typedef v8::Handle SwigV8ReturnValue; --typedef v8::Arguments SwigV8Arguments; --typedef v8::AccessorInfo SwigV8PropertyCallbackInfo; --#define SWIGV8_RETURN(val) return scope.Close(val) --#define SWIGV8_RETURN_INFO(val, info) return scope.Close(val) --#else - typedef void SwigV8ReturnValue; - typedef v8::FunctionCallbackInfo SwigV8Arguments; - typedef v8::PropertyCallbackInfo SwigV8PropertyCallbackInfo; - #define SWIGV8_RETURN(val) args.GetReturnValue().Set(val); return - #define SWIGV8_RETURN_INFO(val, info) info.GetReturnValue().Set(val); return --#endif - --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032117) --#define SWIGV8_HANDLESCOPE() v8::HandleScope scope --#define SWIGV8_HANDLESCOPE_ESC() v8::HandleScope scope --#define SWIGV8_ESCAPE(val) return scope.Close(val) --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032224) --#define SWIGV8_HANDLESCOPE() v8::HandleScope scope(v8::Isolate::GetCurrent()); --#define SWIGV8_HANDLESCOPE_ESC() v8::HandleScope scope(v8::Isolate::GetCurrent()); --#define SWIGV8_ESCAPE(val) return scope.Close(val) --#else - #define SWIGV8_HANDLESCOPE() v8::HandleScope scope(v8::Isolate::GetCurrent()); - #define SWIGV8_HANDLESCOPE_ESC() v8::EscapableHandleScope scope(v8::Isolate::GetCurrent()); - #define SWIGV8_ESCAPE(val) return scope.Escape(val) --#endif - --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032224) --#define SWIGV8_ADJUST_MEMORY(size) v8::V8::AdjustAmountOfExternalAllocatedMemory(size) --#define SWIGV8_CURRENT_CONTEXT() v8::Context::GetCurrent() --#define SWIGV8_THROW_EXCEPTION(err) v8::ThrowException(err) --#define SWIGV8_STRING_NEW(str) v8::String::New(str) --#define SWIGV8_SYMBOL_NEW(sym) v8::String::NewSymbol(sym) -+#if (NODE_MODULE_VERSION < 72) -+#define SWIGV8_ADJUST_MEMORY(size) v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(size) -+#define SWIGV8_CURRENT_CONTEXT() v8::Isolate::GetCurrent()->GetCurrentContext() -+#define SWIGV8_THROW_EXCEPTION(err) v8::Isolate::GetCurrent()->ThrowException(err) -+#define SWIGV8_STRING_NEW(str) v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), str, v8::String::kNormalString) -+#define SWIGV8_SYMBOL_NEW(sym) v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), sym, v8::String::kNormalString) - #else - #define SWIGV8_ADJUST_MEMORY(size) v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(size) - #define SWIGV8_CURRENT_CONTEXT() v8::Isolate::GetCurrent()->GetCurrentContext() - #define SWIGV8_THROW_EXCEPTION(err) v8::Isolate::GetCurrent()->ThrowException(err) --#define SWIGV8_STRING_NEW(str) v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), str) --#define SWIGV8_SYMBOL_NEW(sym) v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), sym) -+#define SWIGV8_STRING_NEW(str) (v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), str, v8::NewStringType::kNormal)).ToLocalChecked() -+#define SWIGV8_SYMBOL_NEW(sym) (v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), sym, v8::NewStringType::kNormal)).ToLocalChecked() - #endif - --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032318) --#define SWIGV8_ARRAY_NEW() v8::Array::New() --#define SWIGV8_BOOLEAN_NEW(bool) v8::Boolean::New(bool) --#define SWIGV8_EXTERNAL_NEW(val) v8::External::New(val) --#define SWIGV8_FUNCTEMPLATE_NEW(func) v8::FunctionTemplate::New(func) --#define SWIGV8_FUNCTEMPLATE_NEW_VOID() v8::FunctionTemplate::New() --#define SWIGV8_INT32_NEW(num) v8::Int32::New(num) --#define SWIGV8_INTEGER_NEW(num) v8::Integer::New(num) --#define SWIGV8_INTEGER_NEW_UNS(num) v8::Integer::NewFromUnsigned(num) --#define SWIGV8_NUMBER_NEW(num) v8::Number::New(num) --#define SWIGV8_OBJECT_NEW() v8::Object::New() --#define SWIGV8_UNDEFINED() v8::Undefined() --#define SWIGV8_NULL() v8::Null() --#else -+ - #define SWIGV8_ARRAY_NEW() v8::Array::New(v8::Isolate::GetCurrent()) - #define SWIGV8_BOOLEAN_NEW(bool) v8::Boolean::New(v8::Isolate::GetCurrent(), bool) - #define SWIGV8_EXTERNAL_NEW(val) v8::External::New(v8::Isolate::GetCurrent(), val) -@@ -81,15 +48,8 @@ typedef v8::PropertyCallbackInfo SwigV8PropertyCallbackInfo; - #define SWIGV8_OBJECT_NEW() v8::Object::New(v8::Isolate::GetCurrent()) - #define SWIGV8_UNDEFINED() v8::Undefined(v8::Isolate::GetCurrent()) - #define SWIGV8_NULL() v8::Null(v8::Isolate::GetCurrent()) --#endif - --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710) --#define SWIGV8_SET_CLASS_TEMPL(class_templ, class) class_templ = v8::Persistent::New(class); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900) --#define SWIGV8_SET_CLASS_TEMPL(class_templ, class) class_templ = v8::Persistent::New(v8::Isolate::GetCurrent(), class); --#else - #define SWIGV8_SET_CLASS_TEMPL(class_templ, class) class_templ.Reset(v8::Isolate::GetCurrent(), class); --#endif - - #ifdef NODE_VERSION - #if NODE_VERSION_AT_LEAST(10, 12, 0) -@@ -98,23 +58,17 @@ typedef v8::PropertyCallbackInfo SwigV8PropertyCallbackInfo; - #endif - - //Necessary to check Node.js version because V8 API changes are backported in Node.js --#if (defined(NODE_VERSION) && !defined(SWIG_NODE_AT_LEAST_1012)) || \ -- (!defined(NODE_VERSION) && (V8_MAJOR_VERSION-0) < 7) --#define SWIGV8_TO_OBJECT(handle) (handle)->ToObject() --#define SWIGV8_TO_STRING(handle) (handle)->ToString() --#define SWIGV8_NUMBER_VALUE(handle) (handle)->NumberValue() --#define SWIGV8_INTEGER_VALUE(handle) (handle)->IntegerValue() --#define SWIGV8_BOOLEAN_VALUE(handle) (handle)->BooleanValue() --#define SWIGV8_WRITE_UTF8(handle, buffer, len) (handle)->WriteUtf8(buffer, len) --#define SWIGV8_UTF8_LENGTH(handle) (handle)->Utf8Length() --#else - #define SWIGV8_TO_OBJECT(handle) (handle)->ToObject(SWIGV8_CURRENT_CONTEXT()).ToLocalChecked() - #define SWIGV8_TO_STRING(handle) (handle)->ToString(SWIGV8_CURRENT_CONTEXT()).ToLocalChecked() - #define SWIGV8_NUMBER_VALUE(handle) (handle)->NumberValue(SWIGV8_CURRENT_CONTEXT()).ToChecked() - #define SWIGV8_INTEGER_VALUE(handle) (handle)->IntegerValue(SWIGV8_CURRENT_CONTEXT()).ToChecked() --#define SWIGV8_BOOLEAN_VALUE(handle) (handle)->BooleanValue(SWIGV8_CURRENT_CONTEXT()).ToChecked() - #define SWIGV8_WRITE_UTF8(handle, buffer, len) (handle)->WriteUtf8(v8::Isolate::GetCurrent(), buffer, len) - #define SWIGV8_UTF8_LENGTH(handle) (handle)->Utf8Length(v8::Isolate::GetCurrent()) -+ -+#if (NODE_MODULE_VERSION < 72) -+#define SWIGV8_BOOLEAN_VALUE(handle) (handle)->BooleanValue(SWIGV8_CURRENT_CONTEXT()).ToChecked() -+#else -+#define SWIGV8_BOOLEAN_VALUE(handle) (handle)->BooleanValue(v8::Isolate::GetCurrent()) - #endif - - /* --------------------------------------------------------------------------- -@@ -163,7 +117,7 @@ public: - SWIGV8_THROW_EXCEPTION(err); - } - } -- v8::Handle err; -+ v8::Local err; - }; - - /* --------------------------------------------------------------------------- -@@ -182,23 +136,8 @@ public: - }; - - ~SWIGV8_Proxy() { --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710) -- handle.ClearWeak(); -- handle.Dispose(); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032100) -- handle.ClearWeak(v8::Isolate::GetCurrent()); -- handle.Dispose(v8::Isolate::GetCurrent()); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION) -- handle.ClearWeak(); -- handle.Dispose(); --#else - handle.ClearWeak(); - handle.Reset(); --#endif -- --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION) -- handle.Clear(); --#endif - - SWIGV8_ADJUST_MEMORY(-SWIGV8_AVG_OBJ_SIZE); - } -@@ -213,32 +152,17 @@ class SWIGV8_ClientData { - public: - v8::Persistent class_templ; - --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710) -- void (*dtor) (v8::Persistent< v8::Value> object, void *parameter); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900) -- void (*dtor) (v8::Isolate *isolate, v8::Persistent< v8::Value> object, void *parameter); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION) -- void (*dtor) (v8::Isolate *isolate, v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy); --#elif (V8_MAJOR_VERSION-0) < 5 -- void (*dtor) (const v8::WeakCallbackData &data); --#else - void (*dtor) (const v8::WeakCallbackInfo &data); --#endif - }; - - SWIGRUNTIME v8::Persistent SWIGV8_SWIGTYPE_Proxy_class_templ; - --SWIGRUNTIME int SWIG_V8_ConvertInstancePtr(v8::Handle objRef, void **ptr, swig_type_info *info, int flags) { -+SWIGRUNTIME int SWIG_V8_ConvertInstancePtr(v8::Local objRef, void **ptr, swig_type_info *info, int flags) { - SWIGV8_HANDLESCOPE(); - - if(objRef->InternalFieldCount() < 1) return SWIG_ERROR; - --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031511) -- v8::Handle cdataRef = objRef->GetInternalField(0); -- SWIGV8_Proxy *cdata = static_cast(v8::External::Unwrap(cdataRef)); --#else - SWIGV8_Proxy *cdata = static_cast(objRef->GetAlignedPointerFromInternalField(0)); --#endif - - if(cdata == NULL) { - return SWIG_ERROR; -@@ -261,39 +185,21 @@ SWIGRUNTIME int SWIG_V8_ConvertInstancePtr(v8::Handle objRef, void * - } - - --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710) --SWIGRUNTIME void SWIGV8_Proxy_DefaultDtor(v8::Persistent< v8::Value > object, void *parameter) { -- SWIGV8_Proxy *proxy = static_cast(parameter); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900) --SWIGRUNTIME void SWIGV8_Proxy_DefaultDtor(v8::Isolate *, v8::Persistent< v8::Value > object, void *parameter) { -- SWIGV8_Proxy *proxy = static_cast(parameter); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION) --SWIGRUNTIME void SWIGV8_Proxy_DefaultDtor(v8::Isolate *, v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy) { --#elif (V8_MAJOR_VERSION-0) < 5 --SWIGRUNTIME void SWIGV8_Proxy_DefaultDtor(const v8::WeakCallbackData &data) { -- SWIGV8_Proxy *proxy = data.GetParameter(); --#else - SWIGRUNTIME void SWIGV8_Proxy_DefaultDtor(const v8::WeakCallbackInfo &data) { - SWIGV8_Proxy *proxy = data.GetParameter(); --#endif - - delete proxy; - } - --SWIGRUNTIME int SWIG_V8_GetInstancePtr(v8::Handle valRef, void **ptr) { -+SWIGRUNTIME int SWIG_V8_GetInstancePtr(v8::Local valRef, void **ptr) { - if(!valRef->IsObject()) { - return SWIG_TypeError; - } -- v8::Handle objRef = SWIGV8_TO_OBJECT(valRef); -+ v8::Local objRef = SWIGV8_TO_OBJECT(valRef); - - if(objRef->InternalFieldCount() < 1) return SWIG_ERROR; - --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031511) -- v8::Handle cdataRef = objRef->GetInternalField(0); -- SWIGV8_Proxy *cdata = static_cast(v8::External::Unwrap(cdataRef)); --#else - SWIGV8_Proxy *cdata = static_cast(objRef->GetAlignedPointerFromInternalField(0)); --#endif - - if(cdata == NULL) { - return SWIG_ERROR; -@@ -304,70 +210,31 @@ SWIGRUNTIME int SWIG_V8_GetInstancePtr(v8::Handle valRef, void **ptr) - return SWIG_OK; - } - --SWIGRUNTIME void SWIGV8_SetPrivateData(v8::Handle obj, void *ptr, swig_type_info *info, int flags) { -+SWIGRUNTIME void SWIGV8_SetPrivateData(v8::Local obj, void *ptr, swig_type_info *info, int flags) { - SWIGV8_Proxy *cdata = new SWIGV8_Proxy(); - cdata->swigCObject = ptr; - cdata->swigCMemOwn = (flags & SWIG_POINTER_OWN) ? 1 : 0; - cdata->info = info; - --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031511) -- obj->SetPointerInInternalField(0, cdata); --#else - obj->SetAlignedPointerInInternalField(0, cdata); --#endif - --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710) -- cdata->handle = v8::Persistent::New(obj); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900) -- cdata->handle = v8::Persistent::New(v8::Isolate::GetCurrent(), obj); --#else - cdata->handle.Reset(v8::Isolate::GetCurrent(), obj); --#endif - --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710) -- // clientdata must be set for owned data as we need to register the dtor -- if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) { -- cdata->handle.MakeWeak(cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor); -- } else { -- cdata->handle.MakeWeak(cdata, SWIGV8_Proxy_DefaultDtor); -- } --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031918) -- if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) { -- cdata->handle.MakeWeak(v8::Isolate::GetCurrent(), cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor); -- } else { -- cdata->handle.MakeWeak(v8::Isolate::GetCurrent(), cdata, SWIGV8_Proxy_DefaultDtor); -- } --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION) -- if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) { -- cdata->handle.MakeWeak(cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor); -- } else { -- cdata->handle.MakeWeak(cdata, SWIGV8_Proxy_DefaultDtor); -- } --#elif (V8_MAJOR_VERSION-0) < 5 -- if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) { -- cdata->handle.SetWeak(cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor); -- } else { -- cdata->handle.SetWeak(cdata, SWIGV8_Proxy_DefaultDtor); -- } --#else - if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) { - cdata->handle.SetWeak(cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor, v8::WeakCallbackType::kParameter); - } else { - cdata->handle.SetWeak(cdata, SWIGV8_Proxy_DefaultDtor, v8::WeakCallbackType::kParameter); - } --#endif - --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710) -- cdata->handle.MarkIndependent(); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032100) -- cdata->handle.MarkIndependent(v8::Isolate::GetCurrent()); --#else -+#if (NODE_MODULE_VERSION < 72) - cdata->handle.MarkIndependent(); -+// Looks like future versions do not require that anymore: -+// https://monorail-prod.appspot.com/p/chromium/issues/detail?id=923361#c11 - #endif - - } - --SWIGRUNTIME int SWIG_V8_ConvertPtr(v8::Handle valRef, void **ptr, swig_type_info *info, int flags) { -+SWIGRUNTIME int SWIG_V8_ConvertPtr(v8::Local valRef, void **ptr, swig_type_info *info, int flags) { - SWIGV8_HANDLESCOPE(); - - /* special case: JavaScript null => C NULL pointer */ -@@ -378,31 +245,20 @@ SWIGRUNTIME int SWIG_V8_ConvertPtr(v8::Handle valRef, void **ptr, swi - if(!valRef->IsObject()) { - return SWIG_TypeError; - } -- v8::Handle objRef = SWIGV8_TO_OBJECT(valRef); -+ v8::Local objRef = SWIGV8_TO_OBJECT(valRef); - return SWIG_V8_ConvertInstancePtr(objRef, ptr, info, flags); - } - --SWIGRUNTIME v8::Handle SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info, int flags) { -+SWIGRUNTIME v8::Local SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info, int flags) { - SWIGV8_HANDLESCOPE_ESC(); - -- v8::Handle class_templ; -+ v8::Local class_templ; - - if (ptr == NULL) { --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903) -- SWIGV8_ESCAPE(SWIGV8_NULL()); --#else - v8::Local result = SWIGV8_NULL(); - SWIGV8_ESCAPE(result); --#endif - } - --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903) -- if(info->clientdata != 0) { -- class_templ = ((SWIGV8_ClientData*) info->clientdata)->class_templ; -- } else { -- class_templ = SWIGV8_SWIGTYPE_Proxy_class_templ; -- } --#else - v8::Isolate *isolate = v8::Isolate::GetCurrent(); - - if(info->clientdata != 0) { -@@ -410,10 +266,13 @@ SWIGRUNTIME v8::Handle SWIG_V8_NewPointerObj(void *ptr, swig_type_inf - } else { - class_templ = v8::Local::New(isolate, SWIGV8_SWIGTYPE_Proxy_class_templ); - } --#endif - --// v8::Handle result = class_templ->InstanceTemplate()->NewInstance(); -+#if (NODE_MODULE_VERSION < 72) - v8::Local result = class_templ->InstanceTemplate()->NewInstance(); -+#else -+ v8::Local result = class_templ->InstanceTemplate()->NewInstance(SWIGV8_CURRENT_CONTEXT()).ToLocalChecked(); -+#endif -+ - SWIGV8_SetPrivateData(result, ptr, info, flags); - - SWIGV8_ESCAPE(result); -@@ -433,7 +292,7 @@ SWIGRUNTIME v8::Handle SWIG_V8_NewPointerObj(void *ptr, swig_type_inf - SWIGRUNTIME SwigV8ReturnValue _SWIGV8_wrap_equals(const SwigV8Arguments &args) { - SWIGV8_HANDLESCOPE(); - -- v8::Handle jsresult; -+ v8::Local jsresult; - void *arg1 = (void *) 0 ; - void *arg2 = (void *) 0 ; - bool result; -@@ -463,7 +322,7 @@ fail: - SWIGRUNTIME SwigV8ReturnValue _wrap_getCPtr(const SwigV8Arguments &args) { - SWIGV8_HANDLESCOPE(); - -- v8::Handle jsresult; -+ v8::Local jsresult; - void *arg1 = (void *) 0 ; - long result; - int res1; -@@ -502,37 +361,29 @@ public: - }; - - SWIGRUNTIMEINLINE --int SwigV8Packed_Check(v8::Handle valRef) { -+int SwigV8Packed_Check(v8::Local valRef) { - SWIGV8_HANDLESCOPE(); - -- v8::Handle objRef = SWIGV8_TO_OBJECT(valRef); -+ v8::Local objRef = SWIGV8_TO_OBJECT(valRef); - if(objRef->InternalFieldCount() < 1) return false; --#if (V8_MAJOR_VERSION-0) < 5 -- v8::Handle flag = objRef->GetHiddenValue(SWIGV8_STRING_NEW("__swig__packed_data__")); --#else - v8::Local privateKey = v8::Private::ForApi(v8::Isolate::GetCurrent(), SWIGV8_STRING_NEW("__swig__packed_data__")); - v8::Local flag; - if (!objRef->GetPrivate(SWIGV8_CURRENT_CONTEXT(), privateKey).ToLocal(&flag)) - return false; --#endif -+ - return (flag->IsBoolean() && SWIGV8_BOOLEAN_VALUE(flag)); - } - - SWIGRUNTIME --swig_type_info *SwigV8Packed_UnpackData(v8::Handle valRef, void *ptr, size_t size) { -+swig_type_info *SwigV8Packed_UnpackData(v8::Local valRef, void *ptr, size_t size) { - if (SwigV8Packed_Check(valRef)) { - SWIGV8_HANDLESCOPE(); - - SwigV8PackedData *sobj; - -- v8::Handle objRef = SWIGV8_TO_OBJECT(valRef); -+ v8::Local objRef = SWIGV8_TO_OBJECT(valRef); - --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031511) -- v8::Handle cdataRef = objRef->GetInternalField(0); -- sobj = static_cast(v8::External::Unwrap(cdataRef)); --#else - sobj = static_cast(objRef->GetAlignedPointerFromInternalField(0)); --#endif - if (sobj == NULL || sobj->size != size) return 0; - memcpy(ptr, sobj->data, size); - return sobj->type; -@@ -542,7 +393,7 @@ swig_type_info *SwigV8Packed_UnpackData(v8::Handle valRef, void *ptr, - } - - SWIGRUNTIME --int SWIGV8_ConvertPacked(v8::Handle valRef, void *ptr, size_t sz, swig_type_info *ty) { -+int SWIGV8_ConvertPacked(v8::Local valRef, void *ptr, size_t sz, swig_type_info *ty) { - swig_type_info *to = SwigV8Packed_UnpackData(valRef, ptr, sz); - if (!to) return SWIG_ERROR; - if (ty) { -@@ -555,89 +406,32 @@ int SWIGV8_ConvertPacked(v8::Handle valRef, void *ptr, size_t sz, swi - return SWIG_OK; - } - --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710) --SWIGRUNTIME void _wrap_SwigV8PackedData_delete(v8::Persistent< v8::Value > object, void *parameter) { -- SwigV8PackedData *cdata = static_cast(parameter); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900) --SWIGRUNTIME void _wrap_SwigV8PackedData_delete(v8::Isolate *isolate, v8::Persistent object, void *parameter) { -- SwigV8PackedData *cdata = static_cast(parameter); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION) --SWIGRUNTIME void _wrap_SwigV8PackedData_delete(v8::Isolate *isolate, v8::Persistent *object, SwigV8PackedData *cdata) { --#elif (V8_MAJOR_VERSION-0) < 5 --SWIGRUNTIME void _wrap_SwigV8PackedData_delete(const v8::WeakCallbackData &data) { -- v8::Local object = data.GetValue(); -- SwigV8PackedData *cdata = data.GetParameter(); --#else - SWIGRUNTIME void _wrap_SwigV8PackedData_delete(const v8::WeakCallbackInfo &data) { - SwigV8PackedData *cdata = data.GetParameter(); --#endif - - delete cdata; -- --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710) -- object.Clear(); -- object.Dispose(); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900) -- object.Clear(); -- object.Dispose(isolate); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032100) -- object->Dispose(isolate); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION) -- object->Dispose(); --#elif (V8_MAJOR_VERSION-0) < 5 -- object.Clear(); --#endif - } - - SWIGRUNTIME --v8::Handle SWIGV8_NewPackedObj(void *data, size_t size, swig_type_info *type) { -+v8::Local SWIGV8_NewPackedObj(void *data, size_t size, swig_type_info *type) { - SWIGV8_HANDLESCOPE_ESC(); - - SwigV8PackedData *cdata = new SwigV8PackedData(data, size, type); --// v8::Handle obj = SWIGV8_OBJECT_NEW(); - v8::Local obj = SWIGV8_OBJECT_NEW(); - --#if (V8_MAJOR_VERSION-0) < 5 -- obj->SetHiddenValue(SWIGV8_STRING_NEW("__swig__packed_data__"), SWIGV8_BOOLEAN_NEW(true)); --#else - v8::Local privateKey = v8::Private::ForApi(v8::Isolate::GetCurrent(), SWIGV8_STRING_NEW("__swig__packed_data__")); - obj->SetPrivate(SWIGV8_CURRENT_CONTEXT(), privateKey, SWIGV8_BOOLEAN_NEW(true)); --#endif - --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031511) -- obj->SetPointerInInternalField(0, cdata); --#else - obj->SetAlignedPointerInInternalField(0, cdata); --#endif - --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710) -- cdata->handle = v8::Persistent::New(obj); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900) -- cdata->handle = v8::Persistent::New(v8::Isolate::GetCurrent(), obj); --#else - cdata->handle.Reset(v8::Isolate::GetCurrent(), obj); --#endif -- - --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710) -- cdata->handle.MakeWeak(cdata, _wrap_SwigV8PackedData_delete); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031918) -- cdata->handle.MakeWeak(v8::Isolate::GetCurrent(), cdata, _wrap_SwigV8PackedData_delete); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION) -- cdata->handle.MakeWeak(cdata, _wrap_SwigV8PackedData_delete); --#elif (V8_MAJOR_VERSION-0) < 5 -- cdata->handle.SetWeak(cdata, _wrap_SwigV8PackedData_delete); --// v8::V8::SetWeak(&cdata->handle, cdata, _wrap_SwigV8PackedData_delete); --#else - cdata->handle.SetWeak(cdata, _wrap_SwigV8PackedData_delete, v8::WeakCallbackType::kParameter); --#endif - --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710) -- cdata->handle.MarkIndependent(); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032100) -- cdata->handle.MarkIndependent(v8::Isolate::GetCurrent()); --#else -+#if (NODE_MODULE_VERSION < 72) - cdata->handle.MarkIndependent(); -+// Looks like future versions do not require that anymore: -+// https://monorail-prod.appspot.com/p/chromium/issues/detail?id=923361#c11 - #endif - - SWIGV8_ESCAPE(obj); -@@ -654,22 +448,18 @@ v8::Handle SWIGV8_NewPackedObj(void *data, size_t size, swig_type_inf - - SWIGRUNTIME - --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903) --v8::Handle SWIGV8_AppendOutput(v8::Handle result, v8::Handle obj) { --#else --v8::Handle SWIGV8_AppendOutput(v8::Local result, v8::Handle obj) { --#endif -+v8::Local SWIGV8_AppendOutput(v8::Local result, v8::Local obj) { - SWIGV8_HANDLESCOPE_ESC(); - - if (result->IsUndefined()) { - result = SWIGV8_ARRAY_NEW(); - } --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903) -- v8::Handle arr = v8::Handle::Cast(result); --#else - v8::Local arr = v8::Local::Cast(result); --#endif -+#if (NODE_MODULE_VERSION < 72) - arr->Set(arr->Length(), obj); -+#else -+ arr->Set(SWIGV8_CURRENT_CONTEXT(), arr->Length(), obj); -+#endif - - SWIGV8_ESCAPE(arr); - } -diff --git a/Lib/javascript/v8/javascriptstrings.swg b/Lib/javascript/v8/javascriptstrings.swg -index e767a6d662..61a937fa52 100644 ---- a/Lib/javascript/v8/javascriptstrings.swg -+++ b/Lib/javascript/v8/javascriptstrings.swg -@@ -4,10 +4,10 @@ - * ------------------------------------------------------------ */ - %fragment("SWIG_AsCharPtrAndSize", "header", fragment="SWIG_pchar_descriptor") { - SWIGINTERN int --SWIG_AsCharPtrAndSize(v8::Handle valRef, char** cptr, size_t* psize, int *alloc) -+SWIG_AsCharPtrAndSize(v8::Local valRef, char** cptr, size_t* psize, int *alloc) - { - if(valRef->IsString()) { -- v8::Handle js_str = SWIGV8_TO_STRING(valRef); -+ v8::Local js_str = SWIGV8_TO_STRING(valRef); - - size_t len = SWIGV8_UTF8_LENGTH(js_str) + 1; - char* cstr = new char[len]; -@@ -20,7 +20,7 @@ SWIG_AsCharPtrAndSize(v8::Handle valRef, char** cptr, size_t* psize, - return SWIG_OK; - } else { - if(valRef->IsObject()) { -- v8::Handle obj = SWIGV8_TO_OBJECT(valRef); -+ v8::Local obj = SWIGV8_TO_OBJECT(valRef); - // try if the object is a wrapped char[] - swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); - if (pchar_descriptor) { -@@ -41,7 +41,7 @@ SWIG_AsCharPtrAndSize(v8::Handle valRef, char** cptr, size_t* psize, - } - - %fragment("SWIG_FromCharPtrAndSize","header",fragment="SWIG_pchar_descriptor") { --SWIGINTERNINLINE v8::Handle -+SWIGINTERNINLINE v8::Local - SWIG_FromCharPtrAndSize(const char* carray, size_t size) - { - if (carray) { -@@ -49,7 +49,7 @@ SWIG_FromCharPtrAndSize(const char* carray, size_t size) - // TODO: handle extra long strings - return SWIGV8_UNDEFINED(); - } else { -- v8::Handle js_str = SWIGV8_STRING_NEW2(carray, size); -+ v8::Local js_str = SWIGV8_STRING_NEW2(carray, size); - return js_str; - } - } else { -diff --git a/Lib/javascript/v8/javascripttypemaps.swg b/Lib/javascript/v8/javascripttypemaps.swg -index 4601698e03..fbe7849cd2 100644 ---- a/Lib/javascript/v8/javascripttypemaps.swg -+++ b/Lib/javascript/v8/javascripttypemaps.swg -@@ -25,7 +25,7 @@ - - /* Javascript types */ - --#define SWIG_Object v8::Handle -+#define SWIG_Object v8::Local - #define VOID_Object SWIGV8_UNDEFINED() - - /* Overload of the output/constant/exception/dirout handling */ -diff --git a/Tools/javascript/Makefile.in b/Tools/javascript/Makefile.in -index 5eeec07857..21088a8fad 100644 ---- a/Tools/javascript/Makefile.in -+++ b/Tools/javascript/Makefile.in -@@ -3,12 +3,9 @@ - # ---------------------------------------------------------------- - # - # Note: --# There is no common CLI Javascript interpreter. --# V8 comes with one 'd8' which however does not provide a means --# to load extensions. Therefore, by default we use nodejs as --# environment. --# For testing native v8 and jsc extensions we provide our own --# interpreter (see 'Tools/javascript'). -+# There is no common CLI Javascript interpreter. By default we -+# use nodejs as environment. For testing jsc extensions we -+# provide our own interpreter (see 'Tools/javascript'). - # - # ---------------------------------------------------------------- - all: javascript -@@ -24,37 +21,25 @@ LDFLAGS = - LINKFLAGS = @JSINTERPRETERLINKFLAGS@ - - ROOT_DIR = @ROOT_DIR@ --JSINCLUDES = @JSCOREINC@ @JSV8INC@ --JSDYNAMICLINKING = @JSCOREDYNAMICLINKING@ @JSV8DYNAMICLINKING@ --JSV8ENABLED = @JSV8ENABLED@ -+JSINCLUDES = @JSCOREINC@ -+JSDYNAMICLINKING = @JSCOREDYNAMICLINKING@ - JSCENABLED = @JSCENABLED@ - - srcdir = @srcdir@ - -- --ifneq (, $(V8_VERSION)) -- JSV8_VERSION=$(V8_VERSION) --else -- JSV8_VERSION=0x031110 --endif -- - # Regenerate Makefile if Makefile.in or config.status have changed. - Makefile: $(srcdir)/Makefile.in ../../config.status - cd ../.. && $(SHELL) ./config.status Tools/javascript/Makefile - - # These settings are provided by 'configure' (see '/configure.in') --ifeq (1, $(JSV8ENABLED)) --JS_INTERPRETER_SRC_V8 = v8_shell.cxx --JS_INTERPRETER_ENABLE_V8 = -DENABLE_V8 -DSWIG_V8_VERSION=$(JSV8_VERSION) -DV8_DEPRECATION_WARNINGS --endif - - ifeq (1, $(JSCENABLED)) - JS_INTERPRETER_SRC_JSC = jsc_shell.cxx - JS_INTERPRETER_ENABLE_JSC = -DENABLE_JSC - endif - --JS_INTERPRETER_DEFINES = $(JS_INTERPRETER_ENABLE_JSC) $(JS_INTERPRETER_ENABLE_V8) --JS_INTERPRETER_SRC = javascript.cxx js_shell.cxx $(JS_INTERPRETER_SRC_JSC) $(JS_INTERPRETER_SRC_V8) -+JS_INTERPRETER_DEFINES = $(JS_INTERPRETER_ENABLE_JSC) -+JS_INTERPRETER_SRC = javascript.cxx js_shell.cxx $(JS_INTERPRETER_SRC_JSC) - - JS_INTERPRETER_OBJS = $(JS_INTERPRETER_SRC:.cxx=.o) - -diff --git a/Tools/javascript/v8_shell.cxx b/Tools/javascript/v8_shell.cxx -deleted file mode 100644 -index 5001bc25a6..0000000000 ---- a/Tools/javascript/v8_shell.cxx -+++ /dev/null -@@ -1,388 +0,0 @@ --#include --#include --#include --#include --#include -- --#include --#include -- --#include "js_shell.h" -- --typedef int (*V8ExtensionInitializer) (v8::Handle module); -- --// Note: these typedefs and defines are used to deal with v8 API changes since version 3.19.00 -- --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903) --typedef v8::Handle SwigV8ReturnValue; --typedef v8::Arguments SwigV8Arguments; --typedef v8::AccessorInfo SwigV8PropertyCallbackInfo; --#define SWIGV8_RETURN(val) return scope.Close(val) --#define SWIGV8_RETURN_INFO(val, info) return scope.Close(val) --#else --typedef void SwigV8ReturnValue; --typedef v8::FunctionCallbackInfo SwigV8Arguments; --typedef v8::PropertyCallbackInfo SwigV8PropertyCallbackInfo; --#define SWIGV8_RETURN(val) args.GetReturnValue().Set(val); return --#define SWIGV8_RETURN_INFO(val, info) info.GetReturnValue().Set(val); return --#endif -- -- --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032117) --#define SWIGV8_HANDLESCOPE() v8::HandleScope scope --#define SWIGV8_HANDLESCOPE_ESC() v8::HandleScope scope --#define SWIGV8_ESCAPE(val) return scope.Close(val) --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032318) --#define SWIGV8_HANDLESCOPE() v8::HandleScope scope(v8::Isolate::GetCurrent()); --#define SWIGV8_HANDLESCOPE_ESC() v8::HandleScope scope(v8::Isolate::GetCurrent()); --#define SWIGV8_ESCAPE(val) return scope.Close(val) --#else --#define SWIGV8_HANDLESCOPE() v8::HandleScope scope(v8::Isolate::GetCurrent()); --#define SWIGV8_HANDLESCOPE_ESC() v8::EscapableHandleScope scope(v8::Isolate::GetCurrent()); --#define SWIGV8_ESCAPE(val) return scope.Escape(val) --#endif -- --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032318) --#define SWIGV8_CURRENT_CONTEXT() v8::Context::GetCurrent() --#define SWIGV8_STRING_NEW(str) v8::String::New(str) --#define SWIGV8_FUNCTEMPLATE_NEW(func) v8::FunctionTemplate::New(func) --#define SWIGV8_OBJECT_NEW() v8::Object::New() --#define SWIGV8_EXTERNAL_NEW(val) v8::External::New(val) --#define SWIGV8_UNDEFINED() v8::Undefined() --#else --#define SWIGV8_CURRENT_CONTEXT() v8::Isolate::GetCurrent()->GetCurrentContext() --#define SWIGV8_STRING_NEW(str) v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), str) --#define SWIGV8_FUNCTEMPLATE_NEW(func) v8::FunctionTemplate::New(v8::Isolate::GetCurrent(), func) --#define SWIGV8_OBJECT_NEW() v8::Object::New(v8::Isolate::GetCurrent()) --#define SWIGV8_EXTERNAL_NEW(val) v8::External::New(v8::Isolate::GetCurrent(), val) --#define SWIGV8_UNDEFINED() v8::Undefined(v8::Isolate::GetCurrent()) --#endif -- -- --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900) --typedef v8::Persistent SwigV8Context; --#else --typedef v8::Local SwigV8Context; --#endif -- --class V8Shell: public JSShell { -- --public: -- V8Shell(); -- -- virtual ~V8Shell(); -- -- virtual bool RunScript(const std::string &scriptPath); -- -- virtual bool RunShell(); -- -- --protected: -- -- virtual bool InitializeEngine(); -- -- virtual bool ExecuteScript(const std::string &source, const std::string &scriptPath); -- -- virtual bool DisposeEngine(); -- --private: -- -- v8::Handle Import(const std::string &moduleName); -- -- SwigV8Context CreateShellContext(); -- -- void ReportException(v8::TryCatch *handler); -- -- static SwigV8ReturnValue Print(const SwigV8Arguments &args); -- -- static SwigV8ReturnValue Require(const SwigV8Arguments &args); -- -- static SwigV8ReturnValue Quit(const SwigV8Arguments &args); -- -- static SwigV8ReturnValue Version(const SwigV8Arguments &args); -- -- static const char* ToCString(const v8::String::Utf8Value &value); -- --}; -- --#ifdef __GNUC__ --#include --#define LOAD_SYMBOL(handle, name) dlsym(handle, name) --#else --#error "implement dll loading" --#endif -- --V8Shell::V8Shell() {} -- --V8Shell::~V8Shell() {} -- --bool V8Shell::RunScript(const std::string &scriptPath) { -- std::string source = ReadFile(scriptPath); -- -- v8::Isolate *isolate = v8::Isolate::New(); -- v8::Isolate::Scope isolate_scope(isolate); -- -- SWIGV8_HANDLESCOPE(); -- -- SwigV8Context context = CreateShellContext(); -- -- if (context.IsEmpty()) { -- printf("Could not create context.\n"); -- return false; -- } -- -- context->Enter(); -- -- // Store a pointer to this shell for later use -- -- v8::Handle global = context->Global(); -- v8::Local __shell__ = SWIGV8_EXTERNAL_NEW((void*) (long) this); -- -- global->SetHiddenValue(SWIGV8_STRING_NEW("__shell__"), __shell__); -- -- // Node.js compatibility: make `print` available as `console.log()` -- ExecuteScript("var console = {}; console.log = print;", ""); -- -- bool success = ExecuteScript(source, scriptPath); -- -- // Cleanup -- -- context->Exit(); -- --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710) -- context.Dispose(); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900) -- context.Dispose(v8::Isolate::GetCurrent()); --#else --// context.Dispose(); --#endif -- --// v8::V8::Dispose(); -- -- return success; --} -- --bool V8Shell::RunShell() { -- SWIGV8_HANDLESCOPE(); -- -- SwigV8Context context = CreateShellContext(); -- -- if (context.IsEmpty()) { -- printf("Could not create context.\n"); -- return false; -- } -- -- context->Enter(); -- -- v8::Context::Scope context_scope(context); -- -- ExecuteScript("var console = {}; console.log = print;", ""); -- -- static const int kBufferSize = 1024; -- while (true) { -- char buffer[kBufferSize]; -- printf("> "); -- char *str = fgets(buffer, kBufferSize, stdin); -- if (str == NULL) break; -- std::string source(str); -- ExecuteScript(source, "(shell)"); -- } -- printf("\n"); -- -- // Cleanup -- -- context->Exit(); -- --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710) -- context.Dispose(); --#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900) -- context.Dispose(v8::Isolate::GetCurrent()); --#else --// context.Dispose(); --#endif -- --// v8::V8::Dispose(); -- -- return true; --} -- -- --bool V8Shell::InitializeEngine() { -- return true; --} -- --bool V8Shell::ExecuteScript(const std::string &source, const std::string &name) { -- SWIGV8_HANDLESCOPE(); -- -- v8::TryCatch try_catch; -- v8::Handle script = v8::Script::Compile(SWIGV8_STRING_NEW(source.c_str()), SWIGV8_STRING_NEW(name.c_str())); -- -- // Stop if script is empty -- if (script.IsEmpty()) { -- // Print errors that happened during compilation. -- ReportException(&try_catch); -- return false; -- } -- -- v8::Handle result = script->Run(); -- -- // Print errors that happened during execution. -- if (try_catch.HasCaught()) { -- ReportException(&try_catch); -- return false; -- } else { -- return true; -- } --} -- --bool V8Shell::DisposeEngine() { -- return true; --} -- --SwigV8Context V8Shell::CreateShellContext() { -- // Create a template for the global object. -- v8::Handle global = v8::ObjectTemplate::New(); -- -- // Bind global functions -- global->Set(SWIGV8_STRING_NEW("print"), SWIGV8_FUNCTEMPLATE_NEW(V8Shell::Print)); -- global->Set(SWIGV8_STRING_NEW("quit"), SWIGV8_FUNCTEMPLATE_NEW(V8Shell::Quit)); -- global->Set(SWIGV8_STRING_NEW("require"), SWIGV8_FUNCTEMPLATE_NEW(V8Shell::Require)); -- global->Set(SWIGV8_STRING_NEW("version"), SWIGV8_FUNCTEMPLATE_NEW(V8Shell::Version)); -- --#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900) -- SwigV8Context context = v8::Context::New(NULL, global); -- return context; --#else -- SwigV8Context context = v8::Context::New(v8::Isolate::GetCurrent(), NULL, global); -- return context; --#endif --} -- --v8::Handle V8Shell::Import(const std::string &module_path) --{ -- SWIGV8_HANDLESCOPE_ESC(); -- -- HANDLE library; -- std::string module_name = LoadModule(module_path, &library); -- -- std::string symname = std::string(module_name).append("_initialize"); -- -- V8ExtensionInitializer init_function = reinterpret_cast((long) LOAD_SYMBOL(library, symname.c_str())); -- -- if(init_function == 0) { -- printf("Could not find initializer function."); -- -- return SWIGV8_UNDEFINED(); -- } -- -- v8::Local module = SWIGV8_OBJECT_NEW(); -- init_function(module); -- -- SWIGV8_ESCAPE(module); --} -- --SwigV8ReturnValue V8Shell::Print(const SwigV8Arguments &args) { -- SWIGV8_HANDLESCOPE(); -- -- bool first = true; -- for (int i = 0; i < args.Length(); i++) { -- -- if (first) { -- first = false; -- } else { -- printf(" "); -- } -- v8::String::Utf8Value str(args[i]); -- const char *cstr = V8Shell::ToCString(str); -- printf("%s", cstr); -- } -- printf("\n"); -- fflush(stdout); -- -- SWIGV8_RETURN(SWIGV8_UNDEFINED()); --} -- --SwigV8ReturnValue V8Shell::Require(const SwigV8Arguments &args) { -- SWIGV8_HANDLESCOPE(); -- -- if (args.Length() != 1) { -- printf("Illegal arguments for `require`"); -- }; -- -- v8::String::Utf8Value str(args[0]); -- const char *cstr = V8Shell::ToCString(str); -- std::string moduleName(cstr); -- -- v8::Local global = SWIGV8_CURRENT_CONTEXT()->Global(); -- -- v8::Local hidden = global->GetHiddenValue(SWIGV8_STRING_NEW("__shell__")); -- v8::Local __shell__ = v8::Local::Cast(hidden); -- V8Shell *_this = (V8Shell *) (long) __shell__->Value(); -- -- v8::Handle module = _this->Import(moduleName); -- -- SWIGV8_RETURN(module); --} -- --SwigV8ReturnValue V8Shell::Quit(const SwigV8Arguments &args) { -- SWIGV8_HANDLESCOPE(); -- -- int exit_code = args[0]->Int32Value(); -- fflush(stdout); -- fflush(stderr); -- exit(exit_code); -- -- SWIGV8_RETURN(SWIGV8_UNDEFINED()); --} -- --SwigV8ReturnValue V8Shell::Version(const SwigV8Arguments &args) { -- SWIGV8_HANDLESCOPE(); -- SWIGV8_RETURN(SWIGV8_STRING_NEW(v8::V8::GetVersion())); --} -- --void V8Shell::ReportException(v8::TryCatch *try_catch) { -- SWIGV8_HANDLESCOPE(); -- -- v8::String::Utf8Value exception(try_catch->Exception()); -- const char *exception_string = V8Shell::ToCString(exception); -- v8::Handle message = try_catch->Message(); -- if (message.IsEmpty()) { -- // V8 didn't provide any extra information about this error; just -- // print the exception. -- printf("%s\n", exception_string); -- } else { -- // Print (filename):(line number): (message). -- v8::String::Utf8Value filename(message->GetScriptResourceName()); -- const char *filename_string = V8Shell::ToCString(filename); -- int linenum = message->GetLineNumber(); -- printf("%s:%i: %s\n", filename_string, linenum, exception_string); -- // Print line of source code. -- v8::String::Utf8Value sourceline(message->GetSourceLine()); -- const char *sourceline_string = V8Shell::ToCString(sourceline); -- printf("%s\n", sourceline_string); -- // Print wavy underline (GetUnderline is deprecated). -- int start = message->GetStartColumn(); -- for (int i = 0; i < start; i++) { -- printf(" "); -- } -- int end = message->GetEndColumn(); -- for (int i = start; i < end; i++) { -- printf("^"); -- } -- printf("\n"); -- v8::String::Utf8Value stack_trace(try_catch->StackTrace()); -- if (stack_trace.length() > 0) { -- const char *stack_trace_string = V8Shell::ToCString(stack_trace); -- printf("%s\n", stack_trace_string); -- } -- } --} -- --// Extracts a C string from a V8 Utf8Value. --const char *V8Shell::ToCString(const v8::String::Utf8Value &value) { -- return *value ? *value : ""; --} -- --JSShell *V8Shell_Create() { -- return new V8Shell(); --} -diff --git a/Tools/travis-linux-install.sh b/Tools/travis-linux-install.sh -index c8347d27a4..2427d08230 100755 ---- a/Tools/travis-linux-install.sh -+++ b/Tools/travis-linux-install.sh -@@ -39,22 +39,12 @@ - [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" - travis_retry nvm install ${VER} - nvm use ${VER} -- if [ "$VER" == "0.10" ] || [ "$VER" == "0.12" ] || [ "$VER" == "4" ] || [ "$VER" == "6" ] ; then --# travis_retry sudo apt-get install -qq nodejs node-gyp -- travis_retry npm install -g node-gyp@$VER -- elif [ "$VER" == "8" ] ; then -- travis_retry npm install -g node-gyp@6 -- else -- travis_retry npm install -g node-gyp -- fi -+ travis_retry npm install -g node-gyp - ;; - "jsc") - travis_retry sudo apt-get install -qq libwebkitgtk-dev - ;; -- "v8") -- travis_retry sudo apt-get install -qq libv8-dev -- ;; -- esac -+ - ;; - "guile") - travis_retry sudo apt-get -qq install guile-2.0-dev From e1a78f0033e0715b8ad3899257810502fd31691d Mon Sep 17 00:00:00 2001 From: Kuan-Yi Li Date: Tue, 29 Nov 2022 02:17:27 +0800 Subject: [PATCH 30/39] libqrtr-glib: drop deprecated AUTORELEASE Signed-off-by: Kuan-Yi Li --- libs/libqrtr-glib/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/libqrtr-glib/Makefile b/libs/libqrtr-glib/Makefile index f6eea539a..b5fabf31b 100644 --- a/libs/libqrtr-glib/Makefile +++ b/libs/libqrtr-glib/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=libqrtr-glib PKG_VERSION:=1.2.2 -PKG_RELEASE:=$(AUTORELEASE) +PKG_RELEASE:=3 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://gitlab.freedesktop.org/mobile-broadband/libqrtr-glib.git From b930149e5570f2d124103abc6d9a62394df8dc21 Mon Sep 17 00:00:00 2001 From: Kuan-Yi Li Date: Tue, 29 Nov 2022 02:17:51 +0800 Subject: [PATCH 31/39] libmbim: bump to 1.28.2 Drop deprecated AUTORELEASE. Signed-off-by: Kuan-Yi Li --- libs/libmbim/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/libmbim/Makefile b/libs/libmbim/Makefile index 4b70cf66c..abd94d617 100644 --- a/libs/libmbim/Makefile +++ b/libs/libmbim/Makefile @@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=libmbim -PKG_SOURCE_VERSION:=1.26.4 -PKG_RELEASE:=$(AUTORELEASE) +PKG_SOURCE_VERSION:=1.28.2 +PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://gitlab.freedesktop.org/mobile-broadband/libmbim.git -PKG_MIRROR_HASH:=4963f9135f8ad26165d969d0b2028b00d68243201113c94a2ebe22c4227058a4 +PKG_MIRROR_HASH:=0b0b46016738fc22355d5a58c8a2d1b2f04906c49c51a50b57a09640d13b00b7 PKG_MAINTAINER:=Nicholas Smith From 570c549bc686e71750b83cebce4e7162acef752a Mon Sep 17 00:00:00 2001 From: Kuan-Yi Li Date: Tue, 29 Nov 2022 02:18:11 +0800 Subject: [PATCH 32/39] libqmi: bump to 1.32.2 Drop deprecated AUTORELEASE. Signed-off-by: Kuan-Yi Li --- libs/libqmi/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/libqmi/Makefile b/libs/libqmi/Makefile index 2224a33c7..bfa3bab7c 100644 --- a/libs/libqmi/Makefile +++ b/libs/libqmi/Makefile @@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=libqmi -PKG_SOURCE_VERSION:=1.30.8 -PKG_RELEASE:=$(AUTORELEASE) +PKG_SOURCE_VERSION:=1.32.2 +PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://gitlab.freedesktop.org/mobile-broadband/libqmi.git -PKG_MIRROR_HASH:=a0fa33a89011bdb593f66fd0b674f2a7c31f87e43ffd7f3e9a515b00864c4a91 +PKG_MIRROR_HASH:=711d16d75a6a9afaefcf2be1bc845a4a6181dff786dfbd079e41e91279a0be91 PKG_MAINTAINER:=Nicholas Smith From cec29e91055c7e1722a99762fa1994198729d264 Mon Sep 17 00:00:00 2001 From: Kuan-Yi Li Date: Tue, 29 Nov 2022 02:34:28 +0800 Subject: [PATCH 33/39] modemmanager: bump to 1.20.2 Drop deprecated AUTORELEASE. Disable unused tests as its compilation is optional in 1.20. Signed-off-by: Kuan-Yi Li --- net/modemmanager/Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/modemmanager/Makefile b/net/modemmanager/Makefile index ae07e6107..6cbd6f738 100644 --- a/net/modemmanager/Makefile +++ b/net/modemmanager/Makefile @@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=modemmanager -PKG_SOURCE_VERSION:=1.18.12 -PKG_RELEASE:=$(AUTORELEASE) +PKG_SOURCE_VERSION:=1.20.2 +PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://gitlab.freedesktop.org/mobile-broadband/ModemManager.git -PKG_MIRROR_HASH:=5a32f90fc58345e2136f4196166a7a2b95a804a6b92adf1bfb5b7a1173a5b1a0 +PKG_MIRROR_HASH:=f138effc693456c5040ec22e17c0a8b41143c3b17b62437462995c297a9150dc PKG_MAINTAINER:=Nicholas Smith PKG_LICENSE:=GPL-2.0-or-later @@ -56,6 +56,7 @@ endef MESON_ARGS += \ -Dudev=false \ -Dudevdir=/lib/udev \ + -Dtests=false \ -Dsystemdsystemunitdir=no \ -Dsystemd_suspend_resume=false \ -Dsystemd_journal=false \ From 02e154d3e56bd35b2db345250c17e41da0edcfa9 Mon Sep 17 00:00:00 2001 From: Carlo Alberto Ferraris Date: Wed, 2 Nov 2022 22:14:01 +0900 Subject: [PATCH 34/39] tailscale: preserve tailscaled state file Fixes #19774 Signed-off-by: Carlo Alberto Ferraris --- net/tailscale/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/net/tailscale/Makefile b/net/tailscale/Makefile index 8f979aede..e15b54aa1 100644 --- a/net/tailscale/Makefile +++ b/net/tailscale/Makefile @@ -77,6 +77,7 @@ endef define Package/tailscaled/conffiles /etc/config/tailscale +/etc/tailscale/tailscaled.state endef $(eval $(call BuildPackage,tailscale)) From cbdc67bd107ac8c64f2dc20f742f7171a405e63d Mon Sep 17 00:00:00 2001 From: Chris Barrick Date: Sat, 3 Dec 2022 23:00:51 -0500 Subject: [PATCH 35/39] ddns-scripts: add support for Google Cloud DNS The implementation uses a GCP service account. The user is expected to create and secure a service account and generate a private key. The "password" field can contain the key inline or be a file path pointing to the key file on the router. The GCP project name and Cloud DNS ManagedZone must also be provided. These are taken as form-urlencoded key-value pairs in param_enc. The TTL can optionally be supplied in param_opt. Signed-off-by: Chris Barrick --- net/ddns-scripts/Makefile | 34 ++- .../files/usr/lib/ddns/update_gcp_v1.sh | 272 ++++++++++++++++++ .../ddns/default/cloud.google.com-v1.json | 10 + 3 files changed, 315 insertions(+), 1 deletion(-) create mode 100755 net/ddns-scripts/files/usr/lib/ddns/update_gcp_v1.sh create mode 100644 net/ddns-scripts/files/usr/share/ddns/default/cloud.google.com-v1.json diff --git a/net/ddns-scripts/Makefile b/net/ddns-scripts/Makefile index 8c51476c3..9e6e57ba7 100644 --- a/net/ddns-scripts/Makefile +++ b/net/ddns-scripts/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ddns-scripts PKG_VERSION:=2.8.2 -PKG_RELEASE:=29 +PKG_RELEASE:=30 PKG_LICENSE:=GPL-2.0 @@ -70,6 +70,17 @@ define Package/ddns-scripts-cloudflare/description endef +define Package/ddns-scripts-gcp + $(call Package/ddns-scripts/Default) + TITLE:=Extension for Google Cloud DNS API v1 + DEPENDS:=ddns-scripts +curl +openssl-util +endef + +define Package/ddns-scripts-gcp/description + Dynamic DNS Client scripts extension for Google Cloud DNS API v1 (requires curl) +endef + + define Package/ddns-scripts-freedns $(call Package/ddns-scripts/Default) TITLE:=Extension for freedns.42.pl @@ -323,6 +334,7 @@ define Package/ddns-scripts-services/install # Remove special services rm $(1)/usr/share/ddns/default/cloudflare.com-v4.json + rm $(1)/usr/share/ddns/default/cloud.google.com-v1.json rm $(1)/usr/share/ddns/default/freedns.42.pl.json rm $(1)/usr/share/ddns/default/godaddy.com-v1.json rm $(1)/usr/share/ddns/default/digitalocean.com-v2.json @@ -358,6 +370,25 @@ exit 0 endef +define Package/ddns-scripts-gcp/install + $(INSTALL_DIR) $(1)/usr/lib/ddns + $(INSTALL_BIN) ./files/usr/lib/ddns/update_gcp_v1.sh \ + $(1)/usr/lib/ddns + + $(INSTALL_DIR) $(1)/usr/share/ddns/default + $(INSTALL_DATA) ./files/usr/share/ddns/default/cloud.google.com-v1.json \ + $(1)/usr/share/ddns/default/ +endef + +define Package/ddns-scripts-gcp/prerm +#!/bin/sh +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/ddns stop +fi +exit 0 +endef + + define Package/ddns-scripts-freedns/install $(INSTALL_DIR) $(1)/usr/lib/ddns $(INSTALL_BIN) ./files/usr/lib/ddns/update_freedns_42_pl.sh \ @@ -608,6 +639,7 @@ endef $(eval $(call BuildPackage,ddns-scripts)) $(eval $(call BuildPackage,ddns-scripts-services)) $(eval $(call BuildPackage,ddns-scripts-cloudflare)) +$(eval $(call BuildPackage,ddns-scripts-gcp)) $(eval $(call BuildPackage,ddns-scripts-freedns)) $(eval $(call BuildPackage,ddns-scripts-godaddy)) $(eval $(call BuildPackage,ddns-scripts-digitalocean)) diff --git a/net/ddns-scripts/files/usr/lib/ddns/update_gcp_v1.sh b/net/ddns-scripts/files/usr/lib/ddns/update_gcp_v1.sh new file mode 100755 index 000000000..5bd096f46 --- /dev/null +++ b/net/ddns-scripts/files/usr/lib/ddns/update_gcp_v1.sh @@ -0,0 +1,272 @@ +#!/bin/sh +# +#.Distributed under the terms of the GNU General Public License (GPL) version 2.0 +#.2022 Chris Barrick +# +# This script sends DDNS updates using the Google Cloud DNS REST API. +# See: https://cloud.google.com/dns/docs/reference/v1 +# +# This script uses a GCP service account. The user is responsible for creating +# the service account, ensuring it has permission to update DNS records, and +# for generating a service account key to be used by this script. The records +# to be updated must already exist. +# +# Arguments: +# +# - $username: The service account name. +# Example: ddns-service-account@my-dns-project.iam.gserviceaccount.com +# +# - $password: The service account key. You can paste the key directly into the +# "password" field or upload the key file to the router and set the field +# equal to the file path. This script supports JSON keys or the raw private +# key as a PEM file. P12 keys are not supported. File names must end with +# `*.json` or `*.pem`. +# +# - $domain: The domain to update. +# +# - $param_enc: The additional required arguments, as form-urlencoded data, +# i.e. `key1=value1&key2=value2&...`. The required arguments are: +# - project: The name of the GCP project that owns the DNS records. +# - zone: The DNS zone in the GCP API. +# - Example: `project=my-dns-project&zone=my-dns-zone` +# +# - $param_opt: Optional TTL for the records, in seconds. Defaults to 3600 (1h). +# +# Dependencies: +# - ddns-scripts (for the base functionality) +# - openssl-util (for the authentication flow) +# - curl (for the GCP REST API) + +. /usr/share/libubox/jshn.sh + + +# Authentication +# --------------------------------------------------------------------------- +# The authentication flow works like this: +# +# 1. Construct a JWT claim for access to the DNS readwrite scope. +# 2. Sign the JWT with the service accout key, proving we have access. +# 3. Exchange the JWT for an access token, valid for 5m. +# 4. Use the access token for API calls. +# +# See https://developers.google.com/identity/protocols/oauth2/service-account + +# A URL-safe variant of base64 encoding, used by JWTs. +base64_urlencode() { + openssl base64 | tr '/+' '_-' | tr -d '=\n' +} + +# Prints the service account private key in PEM format. +get_service_account_key() { + # The "password" field provides us with the service account key. + # We allow the user to provide it to us in a few different formats. + # + # 1. If $password is a string ending in `*.json`, it is a file path, + # pointing to a JSON service account key as downloaded from GCP. + # + # 2. If $password is a string ending with `*.pem`, it is a PEM private + # key, extracted from the JSON service account key. + # + # 3. If $password starts with `{`, then the JSON service account key + # was pasted directly into the password field. + # + # 4. If $password starts with `---`, then the PEM private key was pasted + # directly into the password field. + # + # We do not support P12 service account keys. + case "${password}" in + (*".json") + jsonfilter -i "${password}" -e @.private_key + ;; + (*".pem") + cat "${password}" + ;; + ("{"*) + jsonfilter -s "${password}" -e @.private_key + ;; + ("---"*) + printf "%s" "${password}" + ;; + (*) + write_log 14 "Could not parse the service account key." + ;; + esac +} + +# Sign stdin using the service account key. Prints the signature. +# The input is the JWT header-payload. Used to construct a signed JWT. +sign() { + # Dump the private key to a tmp file so openssl can get to it. + local tmp_keyfile="$(mktemp -t gcp_dns_sak.pem.XXXXXX)" + chmod 600 ${tmp_keyfile} + get_service_account_key > ${tmp_keyfile} + openssl dgst -binary -sha256 -sign ${tmp_keyfile} + rm ${tmp_keyfile} +} + +# Print the JWT header in JSON format. +# Currently, Google only supports RS256. +jwt_header() { + json_init + json_add_string "alg" "RS256" + json_add_string "typ" "JWT" + json_dump +} + +# Prints the JWT claim-set in JSON format. +# The claim is for 5m of readwrite access to the Cloud DNS API. +jwt_claim_set() { + local iat=$(date -u +%s) # Current UNIX time, UTC. + local exp=$(( iat + 300 )) # Expiration is 5m in the future. + + json_init + json_add_string "iss" "${username}" + json_add_string "scope" "https://www.googleapis.com/auth/ndev.clouddns.readwrite" + json_add_string "aud" "https://oauth2.googleapis.com/token" + json_add_string "iat" "${iat}" + json_add_string "exp" "${exp}" + json_dump +} + +# Generate a JWT signed by the service account key, which can be exchanged for +# a Google Cloud access token, authorized for Cloud DNS. +get_jwt() { + local header=$(jwt_header | base64_urlencode) + local payload=$(jwt_claim_set | base64_urlencode) + local header_payload="${header}.${payload}" + local signature=$(printf "%s" ${header_payload} | sign | base64_urlencode) + echo "${header_payload}.${signature}" +} + +# Request an access token for the Google Cloud service account. +get_access_token_raw() { + local grant_type="urn:ietf:params:oauth:grant-type:jwt-bearer" + local assertion=$(get_jwt) + + ${CURL} -v https://oauth2.googleapis.com/token \ + --data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer' \ + --data-urlencode "assertion=${assertion}" \ + | jsonfilter -e @.access_token +} + +# Get the access token, stripping the trailing dots. +get_access_token() { + # Since tokens may contain internal dots, we only trim the suffix if it + # starts with at least 8 dots. (The access token has *many* trailing dots.) + local access_token="$(get_access_token_raw)" + echo "${access_token%%........*}" +} + + +# Google Cloud DNS API +# --------------------------------------------------------------------------- +# Cloud DNS offers a straight forward RESTful API. +# +# - The main class is a ResourceRecordSet. It's a collection of DNS records +# that share the same domain, type, TTL, etc. Within a record set, the only +# difference between the records are their values. +# +# - The record sets live under a ManagedZone, which in turn lives under a +# Project. All we need to know about these are their names. +# +# - This implementation only makes PATCH requests to update existing record +# sets. The user must have already created at least one A or AAAA record for +# the domain they are updating. It's fine to start with a dummy, like 0.0.0.0. +# +# - The API requires SSL, and this implementation uses curl. + +# Prints a ResourceRecordSet in JSON format. +format_record_set() { + local domain="$1" + local record_type="$2" + local ttl="$3" + shift 3 # The remaining arguments are the IP addresses for this record set. + + json_init + json_add_string "kind" "dns#resourceRecordSet" + json_add_string "name" "${domain}." # trailing dot on the domain + json_add_string "type" "${record_type}" + json_add_string "ttl" "${ttl}" + json_add_array "rrdatas" + for value in $@; do + json_add_string "" "${value}" + done + json_close_array + json_dump +} + +# Makes an HTTP PATCH request to the Cloud DNS API. +patch_record_set() { + local access_token="$1" + local project="$2" + local zone="$3" + local domain="$4" + local record_type="$5" + local ttl="$6" + shift 6 # The remaining arguments are the IP addresses for this record set. + + # Note the trailing dot after the domain name. It's fully qualified. + local url="https://dns.googleapis.com/dns/v1/projects/${project}/managedZones/${zone}/rrsets/${domain}./${record_type}" + local record_set=$(format_record_set ${domain} ${record_type} ${ttl} $@) + + ${CURL} -v ${url} \ + -X PATCH \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer ${access_token}" \ + -d "${record_set}" +} + + +# Main entrypoint +# --------------------------------------------------------------------------- + +# Parse the $param_enc into project and zone variables. +# The arguments are the names for those variables. +parse_project_zone() { + local project_var=$1 + local zone_var=$2 + + IFS='&' + for entry in $param_enc + do + case "${entry}" in + ('project='*) + local project_val=$(echo "${entry}" | cut -d'=' -f2) + eval "${project_var}=${project_val}" + ;; + ('zone='*) + local zone_val=$(echo "${entry}" | cut -d'=' -f2) + eval "${zone_var}=${zone_val}" + ;; + esac + done + unset IFS +} + +main() { + local access_token project zone ttl record_type + + # Dependency checking + [ -z "${CURL_SSL}" ] && write_log 14 "Google Cloud DNS requires cURL with SSL support" + [ -z "$(openssl version)" ] && write_log 14 "Google Cloud DNS update requires openssl-utils" + + # Argument parsing + [ -z ${param_opt} ] && ttl=3600 || ttl="${param_opt}" + [ $use_ipv6 -ne 0 ] && record_type="AAAA" || record_type="A" + parse_project_zone project zone + + # Sanity checks + [ -z "${username}" ] && write_log 14 "Config is missing 'username' (service account name)" + [ -z "${password}" ] && write_log 14 "Config is missing 'password' (service account key)" + [ -z "${domain}" ] && write_log 14 "Config is missing 'domain'" + [ -z "${project}" ] && write_log 14 "Could not parse project name from 'param_enc'" + [ -z "${zone}" ] && write_log 14 "Could not parse zone name from 'param_enc'" + [ -z "${ttl}" ] && write_log 14 "Could not parse TTL from 'param_opt'" + [ -z "${record_type}" ] && write_log 14 "Could not determine the record type" + + # Push the record! + access_token="$(get_access_token)" + patch_record_set "${access_token}" "${project}" "${zone}" "${domain}" "${record_type}" "${ttl}" "${__IP}" +} + +main $@ diff --git a/net/ddns-scripts/files/usr/share/ddns/default/cloud.google.com-v1.json b/net/ddns-scripts/files/usr/share/ddns/default/cloud.google.com-v1.json new file mode 100644 index 000000000..eee707b3e --- /dev/null +++ b/net/ddns-scripts/files/usr/share/ddns/default/cloud.google.com-v1.json @@ -0,0 +1,10 @@ +{ + "name": "cloud.google.com-v1", + "ipv4": { + "url": "update_gcp_v1.sh" + }, + "ipv6": { + "url": "update_gcp_v1.sh" + } +} + From 23e6200e4d0a435915ab4ef9700a7297e89b68b3 Mon Sep 17 00:00:00 2001 From: Vladimir Ulrich Date: Thu, 8 Dec 2022 17:28:30 +0300 Subject: [PATCH 36/39] zoneinfo: updated to the latest release Signed-off-by: Vladimir Ulrich --- utils/zoneinfo/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/utils/zoneinfo/Makefile b/utils/zoneinfo/Makefile index 9bf2dbce9..251a1cd08 100644 --- a/utils/zoneinfo/Makefile +++ b/utils/zoneinfo/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=zoneinfo -PKG_VERSION:=2022f +PKG_VERSION:=2022g PKG_RELEASE:=1 #As i couldn't find real license used "Public Domain" @@ -19,14 +19,14 @@ PKG_LICENSE:=Public Domain PKG_SOURCE:=tzdata$(PKG_VERSION).tar.gz PKG_SOURCE_CODE:=tzcode$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=http://www.iana.org/time-zones/repository/releases -PKG_HASH:=9990d71f675d212567b931fe8aae1cab7027f89fefb8a79d808a6933a67af000 +PKG_HASH:=4491db8281ae94a84d939e427bdd83dc389f26764d27d9a5c52d782c16764478 include $(INCLUDE_DIR)/package.mk define Download/tzcode FILE=$(PKG_SOURCE_CODE) URL=$(PKG_SOURCE_URL) - HASH:=e4543e90f84f91fa82809ea98930052fdbc13880c8a623ee3a4eaa42f8a64c15 + HASH:=9610bb0b9656ff404c361a41f3286da53064b5469d84f00c9cb2314c8614da74 endef $(eval $(call Download,tzcode)) From 3950f0ce99844425805887a8e312db6c911fe398 Mon Sep 17 00:00:00 2001 From: Stan Grishin Date: Sat, 10 Dec 2022 01:52:58 +0000 Subject: [PATCH 37/39] simple-adblock: support new OISD dnsmasq config * OISD dnsmasq config files switched from using address= to server= Signed-off-by: Stan Grishin --- net/simple-adblock/Makefile | 2 +- net/simple-adblock/files/simple-adblock.init | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/net/simple-adblock/Makefile b/net/simple-adblock/Makefile index d6fdd316f..ac2854e95 100644 --- a/net/simple-adblock/Makefile +++ b/net/simple-adblock/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=simple-adblock PKG_VERSION:=1.9.3 -PKG_RELEASE:=3 +PKG_RELEASE:=4 PKG_MAINTAINER:=Stan Grishin PKG_LICENSE:=GPL-3.0-or-later diff --git a/net/simple-adblock/files/simple-adblock.init b/net/simple-adblock/files/simple-adblock.init index 19a6b1fa2..cdd2dac36 100644 --- a/net/simple-adblock/files/simple-adblock.init +++ b/net/simple-adblock/files/simple-adblock.init @@ -62,7 +62,7 @@ readonly sharedMemoryError="/dev/shm/$packageName-error" readonly sharedMemoryOutput="/dev/shm/$packageName-output" readonly hostsFilter='/localhost/d;/^#/d;/^[^0-9]/d;s/^0\.0\.0\.0.//;s/^127\.0\.0\.1.//;s/[[:space:]]*#.*$//;s/[[:cntrl:]]$//;s/[[:space:]]//g;/[`~!@#\$%\^&\*()=+;:"'\'',<>?/\|[{}]/d;/]/d;/\./!d;/^$/d;/[^[:alnum:]_.-]/d;' readonly domainsFilter='/^#/d;s/[[:space:]]*#.*$//;s/[[:space:]]*$//;s/[[:cntrl:]]$//;/[[:space:]]/d;/[`~!@#\$%\^&\*()=+;:"'\'',<>?/\|[{}]/d;/]/d;/\./!d;/^$/d;/[^[:alnum:]_.-]/d;' -readonly dnsmasqAddressFilter='\|^address=/[[:alnum:]_.-].*/#|!d' +readonly dnsmasqOISDFilter='\|^server=/[[:alnum:]_.-].*/|!d' readonly _OK_='\033[0;32m\xe2\x9c\x93\033[0m' readonly _FAIL_='\033[0;31m\xe2\x9c\x97\033[0m' readonly __OK__='\033[0;32m[\xe2\x9c\x93]\033[0m' @@ -658,7 +658,7 @@ process_url() { if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then return 1; fi label="${1##*//}"; label="${label%%/*}"; case "$2" in - dnsmasq) label="Dnsmasq: $label"; filter="$dnsmasqAddressFilter";; + dnsmasq) label="Dnsmasq: $label"; filter="$dnsmasqOISDFilter";; domains) label="Domains: $label"; filter="$domainsFilter";; hosts) label="Hosts: $label"; filter="$hostsFilter";; esac From 75ac50ca895e9e042afe9c4a64a367e3863e471f Mon Sep 17 00:00:00 2001 From: Stan Grishin Date: Sat, 10 Dec 2022 05:32:20 +0000 Subject: [PATCH 38/39] https-dns-proxy: fix restart Signed-off-by: Stan Grishin --- net/https-dns-proxy/Makefile | 2 +- net/https-dns-proxy/files/https-dns-proxy.init | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/https-dns-proxy/Makefile b/net/https-dns-proxy/Makefile index a91a3d1cd..4b519a9b2 100644 --- a/net/https-dns-proxy/Makefile +++ b/net/https-dns-proxy/Makefile @@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=https-dns-proxy PKG_VERSION:=2022-10-15 -PKG_RELEASE:=9 +PKG_RELEASE:=10 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/aarond10/https_dns_proxy/ diff --git a/net/https-dns-proxy/files/https-dns-proxy.init b/net/https-dns-proxy/files/https-dns-proxy.init index 201ddadc7..0e75a14d7 100755 --- a/net/https-dns-proxy/files/https-dns-proxy.init +++ b/net/https-dns-proxy/files/https-dns-proxy.init @@ -280,7 +280,7 @@ service_triggers() { service_started() { procd_set_config_changed firewall; } service_stopped() { procd_set_config_changed firewall; } -restart() { procd_send_signal "$packageName"; } +restart() { procd_send_signal "$packageName"; rc_procd start_service; } dnsmasq_doh_server() { local cfg="$1" param="$2" address="${3:-127.0.0.1}" port="$4" i From fd7da3333e98c0d2ef1ed9d7997fe78000474caf Mon Sep 17 00:00:00 2001 From: Hannu Nyman Date: Sun, 11 Dec 2022 16:10:15 +0200 Subject: [PATCH 39/39] wget: apply upstream fix to avoid nettle linking in nossl Replace my own patch with the upstream solution, which they issued in response to my bug report. (Two patches as they overlooked something on the first try. Reference to https://savannah.gnu.org/bugs/index.php?63431 ) The nettle lib evaluation is now conditional to not having "--disable-ntlm". Signed-off-by: Hannu Nyman --- net/wget/Makefile | 2 +- net/wget/patches/001-fix-nettle-ntml.patch | 18 ----- .../001-upstream-fix-disable-ntlm-1.patch | 25 +++++++ .../002-upstream-fix-disable-ntlm-2.patch | 65 +++++++++++++++++++ 4 files changed, 91 insertions(+), 19 deletions(-) delete mode 100644 net/wget/patches/001-fix-nettle-ntml.patch create mode 100644 net/wget/patches/001-upstream-fix-disable-ntlm-1.patch create mode 100644 net/wget/patches/002-upstream-fix-disable-ntlm-2.patch diff --git a/net/wget/Makefile b/net/wget/Makefile index 7589ef1a8..006399312 100644 --- a/net/wget/Makefile +++ b/net/wget/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=wget PKG_VERSION:=1.21.3 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=@GNU/$(PKG_NAME) diff --git a/net/wget/patches/001-fix-nettle-ntml.patch b/net/wget/patches/001-fix-nettle-ntml.patch deleted file mode 100644 index 1cddf4070..000000000 --- a/net/wget/patches/001-fix-nettle-ntml.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- a/configure.ac -+++ b/configure.ac -@@ -630,6 +630,7 @@ then - AC_DEFINE([ENABLE_NTLM], 1, [Define if you want the NTLM authorization support compiled in.]) - fi - else -+ if test x"$ENABLE_NTLM" != xno; then - PKG_CHECK_MODULES([NETTLE], nettle, [ - HAVE_NETTLE=yes - LIBS="$NETTLE_LIBS $LIBS" -@@ -651,6 +652,7 @@ else - ENABLE_NTLM=yes - AC_DEFINE([ENABLE_NTLM], 1, [Define if you want the NTLM authorization support compiled in.]) - fi -+ fi - fi - - dnl ********************************************************************** diff --git a/net/wget/patches/001-upstream-fix-disable-ntlm-1.patch b/net/wget/patches/001-upstream-fix-disable-ntlm-1.patch new file mode 100644 index 000000000..5b3b1a64f --- /dev/null +++ b/net/wget/patches/001-upstream-fix-disable-ntlm-1.patch @@ -0,0 +1,25 @@ +From 485217d0ff8d0d17ea3815244b2bc2b747451e15 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tim=20R=C3=BChsen?= +Date: Sat, 10 Dec 2022 16:43:38 +0100 +Subject: [PATCH] * configure.ac: Allow disabling NTLM if nettle present (Savannah #63431) + +--- + configure.ac | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/configure.ac ++++ b/configure.ac +@@ -648,8 +648,11 @@ else + + if test x"$HAVE_NETTLE" = xyes; then + AC_DEFINE([HAVE_NETTLE], [1], [Use libnettle]) +- ENABLE_NTLM=yes +- AC_DEFINE([ENABLE_NTLM], 1, [Define if you want the NTLM authorization support compiled in.]) ++ if test x"$ENABLE_NTLM" != xno ++ then ++ ENABLE_NTLM=yes ++ AC_DEFINE([ENABLE_NTLM], 1, [Define if you want the NTLM authorization support compiled in.]) ++ fi + fi + fi + diff --git a/net/wget/patches/002-upstream-fix-disable-ntlm-2.patch b/net/wget/patches/002-upstream-fix-disable-ntlm-2.patch new file mode 100644 index 000000000..91fb52aa3 --- /dev/null +++ b/net/wget/patches/002-upstream-fix-disable-ntlm-2.patch @@ -0,0 +1,65 @@ +From c69030a904f8ab25b9ca2704c8a6dd03554e9503 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tim=20R=C3=BChsen?= +Date: Sun, 11 Dec 2022 13:31:38 +0100 +Subject: [PATCH] * configure.ac: Disable nettle if NTLM is explicitly disabled + +--- + configure.ac | 41 +++++++++++++++++++---------------------- + 1 file changed, 19 insertions(+), 22 deletions(-) + +--- a/configure.ac ++++ b/configure.ac +@@ -622,34 +622,31 @@ AS_IF([test x"$with_ssl" = xopenssl], [ + ]) # endif: --with-ssl == openssl? + + dnl Enable NTLM if requested and if SSL is available. +-if test x"$LIBSSL" != x || test "$ac_cv_lib_ssl32_SSL_connect" = yes ++if test x"$ENABLE_NTLM" != xno + then +- if test x"$ENABLE_NTLM" != xno ++ if test x"$LIBSSL" != x || test "$ac_cv_lib_ssl32_SSL_connect" = yes + then + ENABLE_NTLM=yes + AC_DEFINE([ENABLE_NTLM], 1, [Define if you want the NTLM authorization support compiled in.]) +- fi +-else +- PKG_CHECK_MODULES([NETTLE], nettle, [ +- HAVE_NETTLE=yes +- LIBS="$NETTLE_LIBS $LIBS" +- CFLAGS="$NETTLE_CFLAGS $CFLAGS" +- ], [ +- AC_CHECK_LIB(nettle, nettle_md4_init, [HAVE_NETTLE=yes], [HAVE_NETTLE=no; AC_MSG_WARN(*** libnettle was not found. You will not be able to use NTLM)]) +- if test x"$HAVE_NETTLE" != xyes; then +- if test x"$ENABLE_NTLM" = xyes; then +- AC_MSG_ERROR([NTLM authorization requested and SSL not enabled; aborting]) +- fi +- else +- AC_SUBST(NETTLE_LIBS, "-lnettle") ++ else ++ PKG_CHECK_MODULES([NETTLE], nettle, [ ++ HAVE_NETTLE=yes + LIBS="$NETTLE_LIBS $LIBS" +- fi +- ]) ++ CFLAGS="$NETTLE_CFLAGS $CFLAGS" ++ ], [ ++ AC_CHECK_LIB(nettle, nettle_md4_init, [HAVE_NETTLE=yes], [HAVE_NETTLE=no; AC_MSG_WARN(*** libnettle was not found. You will not be able to use NTLM)]) ++ if test x"$HAVE_NETTLE" != xyes; then ++ if test x"$ENABLE_NTLM" = xyes; then ++ AC_MSG_ERROR([NTLM authorization requested and SSL not enabled; aborting]) ++ fi ++ else ++ AC_SUBST(NETTLE_LIBS, "-lnettle") ++ LIBS="$NETTLE_LIBS $LIBS" ++ fi ++ ]) + +- if test x"$HAVE_NETTLE" = xyes; then +- AC_DEFINE([HAVE_NETTLE], [1], [Use libnettle]) +- if test x"$ENABLE_NTLM" != xno +- then ++ if test x"$HAVE_NETTLE" = xyes; then ++ AC_DEFINE([HAVE_NETTLE], [1], [Use libnettle]) + ENABLE_NTLM=yes + AC_DEFINE([ENABLE_NTLM], 1, [Define if you want the NTLM authorization support compiled in.]) + fi