1
0
Fork 0
mirror of https://github.com/Ysurac/openmptcprouter-feeds.git synced 2025-03-09 15:40:03 +00:00

Compare commits

..

No commits in common. "develop" and "v0.62-snapshot" have entirely different histories.

360 changed files with 31228 additions and 86665 deletions

View file

@ -8,8 +8,8 @@ jobs:
build: build:
strategy: strategy:
matrix: matrix:
OMR_TARGET: [bpi-r1, bpi-r2, bpi-r3, bpi-r4, bpi-r4-poe, bpi-r64, rpi2, rpi4, wrt32x, espressobin, r2s, rpi3, wrt3200acm, x86, x86_64, ubnt-erx, r4s, r7800, rutx12, rutx50, r5s, qnap-301w, rpi5, z8102ax_128m, z8102ax_64m, z8102ax-emmc, gl-mt6000, gl-mt3000, gl-mt2500, r5c, z8109ax_128m] OMR_TARGET: [bpi-r1, bpi-r2, bpi-r64, rpi2, rpi4, wrt32x, espressobin, r2s, rpi3, wrt3200acm, x86, x86_64, ubnt-erx, r4s, r7800, rutx12, rutx50, r5s, qnap-301w, rpi5, z8102ax_128m, z8102ax_64m]
OMR_KERNEL: [6.6, 6.12] OMR_KERNEL: [5.4, 6.6]
runs-on: ubuntu-latest runs-on: ubuntu-latest
continue-on-error: true continue-on-error: true

View file

@ -5,9 +5,9 @@ PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/raspberrypi/rpi-eeprom PKG_SOURCE_URL:=https://github.com/raspberrypi/rpi-eeprom
PKG_SOURCE_DATE:=2024-09-23 PKG_SOURCE_DATE:=2024-06-05
PKG_SOURCE_VERSION:=c8fffcda5ae0f923857a73fedbeb07e81d2eb813 PKG_SOURCE_VERSION:=e430a41e7323a1e28fb42b53cf79e5ba9b5ee975
PKG_MIRROR_HASH:=68d0eedd1aff573c2ea7071f89a5898292061ced96d7f98ea4a347dc16c8102c PKG_MIRROR_HASH:=6c9a45d4ea0f33a9dc18f11b6cdeb425f0682dc41099df3a1f350939aecce353
PKG_LICENSE:=BSD-3-Clause Custom PKG_LICENSE:=BSD-3-Clause Custom
PKG_LICENSE_FILES:=LICENSE PKG_LICENSE_FILES:=LICENSE
@ -74,21 +74,21 @@ endef
define Package/bcm2711-eeprom/install define Package/bcm2711-eeprom/install
$(INSTALL_DIR) $(1)/lib/firmware/raspberrypi/bootloader-2711 $(INSTALL_DIR) $(1)/lib/firmware/raspberrypi/bootloader-2711
$(INSTALL_DIR) $(1)/lib/firmware/raspberrypi/bootloader-2711/latest $(INSTALL_DIR) $(1)/lib/firmware/raspberrypi/bootloader-2711/default
$(CP) $(PKG_BUILD_DIR)/firmware-2711/release-notes.md $(1)/lib/firmware/raspberrypi/bootloader-2711 $(CP) $(PKG_BUILD_DIR)/firmware-2711/release-notes.md $(1)/lib/firmware/raspberrypi/bootloader-2711
$(CP) $(PKG_BUILD_DIR)/firmware-2711/latest/pieeprom-2024-09-05.bin $(1)/lib/firmware/raspberrypi/bootloader-2711/latest $(CP) $(PKG_BUILD_DIR)/firmware-2711/default/pieeprom-2024-04-15.bin $(1)/lib/firmware/raspberrypi/bootloader-2711/default
$(CP) $(PKG_BUILD_DIR)/firmware-2711/latest/recovery.bin $(1)/lib/firmware/raspberrypi/bootloader-2711/latest $(CP) $(PKG_BUILD_DIR)/firmware-2711/default/recovery.bin $(1)/lib/firmware/raspberrypi/bootloader-2711/default
$(CP) $(PKG_BUILD_DIR)/firmware-2711/latest/vl805-000138c0.bin $(1)/lib/firmware/raspberrypi/bootloader-2711/latest $(CP) $(PKG_BUILD_DIR)/firmware-2711/default/vl805-000138c0.bin $(1)/lib/firmware/raspberrypi/bootloader-2711/default
endef endef
define Package/bcm2712-eeprom/install define Package/bcm2712-eeprom/install
$(INSTALL_DIR) $(1)/lib/firmware/raspberrypi/bootloader-2712 $(INSTALL_DIR) $(1)/lib/firmware/raspberrypi/bootloader-2712
$(INSTALL_DIR) $(1)/lib/firmware/raspberrypi/bootloader-2712/latest $(INSTALL_DIR) $(1)/lib/firmware/raspberrypi/bootloader-2712/default
$(CP) $(PKG_BUILD_DIR)/firmware-2712/release-notes.md $(1)/lib/firmware/raspberrypi/bootloader-2712 $(CP) $(PKG_BUILD_DIR)/firmware-2712/release-notes.md $(1)/lib/firmware/raspberrypi/bootloader-2712
$(CP) $(PKG_BUILD_DIR)/firmware-2712/latest/pieeprom-2024-09-23.bin $(1)/lib/firmware/raspberrypi/bootloader-2712/latest $(CP) $(PKG_BUILD_DIR)/firmware-2712/default/pieeprom-2024-04-20.bin $(1)/lib/firmware/raspberrypi/bootloader-2712/default
$(CP) $(PKG_BUILD_DIR)/firmware-2712/latest/recovery.bin $(1)/lib/firmware/raspberrypi/bootloader-2712/latest $(CP) $(PKG_BUILD_DIR)/firmware-2712/default/recovery.bin $(1)/lib/firmware/raspberrypi/bootloader-2712/default
endef endef
$(eval $(call BuildPackage,bcm27xx-eeprom)) $(eval $(call BuildPackage,bcm27xx-eeprom))

View file

@ -28,9 +28,8 @@ Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
@@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
FIRMWARE_ROOT=/lib/firmware/raspberrypi/bootloader FIRMWARE_ROOT=/lib/firmware/raspberrypi/bootloader
-FIRMWARE_RELEASE_STATUS="default" FIRMWARE_RELEASE_STATUS="default"
-FIRMWARE_BACKUP_DIR="/var/lib/raspberrypi/bootloader/backup" -FIRMWARE_BACKUP_DIR="/var/lib/raspberrypi/bootloader/backup"
+FIRMWARE_RELEASE_STATUS="latest"
+FIRMWARE_BACKUP_DIR="${FIRMWARE_ROOT}/backup" +FIRMWARE_BACKUP_DIR="${FIRMWARE_ROOT}/backup"
EEPROM_CONFIG_HOOK= EEPROM_CONFIG_HOOK=

View file

@ -24,7 +24,7 @@ Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
fi fi
LOCAL_MODE=0 LOCAL_MODE=0
@@ -439,7 +439,7 @@ checkDependencies() { @@ -423,7 +423,7 @@ checkDependencies() {
echo "Run with -h for more information." echo "Run with -h for more information."
echo echo
echo "To enable flashrom programming of the EEPROM" echo "To enable flashrom programming of the EEPROM"
@ -33,7 +33,7 @@ Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
echo "RPI_EEPROM_USE_FLASHROM=1" echo "RPI_EEPROM_USE_FLASHROM=1"
echo "CM4_ENABLE_RPI_EEPROM_UPDATE=1" echo "CM4_ENABLE_RPI_EEPROM_UPDATE=1"
echo echo
@@ -526,7 +526,7 @@ The system should then boot normally. @@ -514,7 +514,7 @@ The system should then boot normally.
If /boot does not correspond to the boot partition and this If /boot does not correspond to the boot partition and this
is not a NOOBS system, then the mount point for BOOTFS should be defined is not a NOOBS system, then the mount point for BOOTFS should be defined
@ -42,7 +42,7 @@ Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
A backup of the current EEPROM config file is written to ${FIRMWARE_BACKUP_DIR} A backup of the current EEPROM config file is written to ${FIRMWARE_BACKUP_DIR}
before applying the update. before applying the update.
@@ -558,7 +558,7 @@ Options: @@ -546,7 +546,7 @@ Options:
-u Install the specified VL805 (USB EEPROM) image file. -u Install the specified VL805 (USB EEPROM) image file.
Environment: Environment:
@ -51,7 +51,7 @@ Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
EEPROM_CONFIG_HOOK EEPROM_CONFIG_HOOK
@@ -630,7 +630,7 @@ must first be enabled by removing ENABLE @@ -618,7 +618,7 @@ must first be enabled by removing ENABLE
via usbboot. via usbboot.
After enabling self-update set the CM4_ENABLE_RPI_EEPROM_UPDATE=1 environment After enabling self-update set the CM4_ENABLE_RPI_EEPROM_UPDATE=1 environment

View file

@ -13,7 +13,7 @@ Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
--- a/rpi-eeprom-update --- a/rpi-eeprom-update
+++ b/rpi-eeprom-update +++ b/rpi-eeprom-update
@@ -220,7 +220,7 @@ applyRecoveryUpdate() @@ -216,7 +216,7 @@ applyRecoveryUpdate()
|| die "Failed to copy ${TMP_EEPROM_IMAGE} to ${BOOTFS}" || die "Failed to copy ${TMP_EEPROM_IMAGE} to ${BOOTFS}"
# For NFS mounts ensure that the files are readable to the TFTP user # For NFS mounts ensure that the files are readable to the TFTP user
@ -22,7 +22,7 @@ Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
|| die "Failed to set permissions on eeprom update files" || die "Failed to set permissions on eeprom update files"
fi fi
@@ -231,7 +231,7 @@ applyRecoveryUpdate() @@ -227,7 +227,7 @@ applyRecoveryUpdate()
|| die "Failed to copy ${VL805_UPDATE_IMAGE} to ${BOOTFS}/vl805.bin" || die "Failed to copy ${VL805_UPDATE_IMAGE} to ${BOOTFS}/vl805.bin"
# For NFS mounts ensure that the files are readable to the TFTP user # For NFS mounts ensure that the files are readable to the TFTP user

View file

@ -13,7 +13,7 @@ Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
--- a/rpi-eeprom-config --- a/rpi-eeprom-config
+++ b/rpi-eeprom-config +++ b/rpi-eeprom-config
@@ -186,8 +186,8 @@ def edit_config(eeprom=None): @@ -184,8 +184,8 @@ def edit_config(eeprom=None):
""" """
Implements something like 'git commit' for editing EEPROM configs. Implements something like 'git commit' for editing EEPROM configs.
""" """
@ -24,7 +24,7 @@ Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
if 'EDITOR' in os.environ: if 'EDITOR' in os.environ:
editor = os.environ['EDITOR'] editor = os.environ['EDITOR']
@@ -517,7 +517,7 @@ Operating modes: @@ -484,7 +484,7 @@ Operating modes:
To cancel the pending update run 'sudo rpi-eeprom-update -r' To cancel the pending update run 'sudo rpi-eeprom-update -r'

View file

@ -3,13 +3,13 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=bcm27xx-utils PKG_NAME:=bcm27xx-utils
PKG_VERSION:=2024.10.25 PKG_VERSION:=2024-04-24
PKG_RELEASE:=1 PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/raspberrypi/utils.git PKG_SOURCE_URL:=https://github.com/raspberrypi/utils.git
PKG_SOURCE_VERSION:=6a2a6becebbc38fde34a94386457ac8210f9119b PKG_SOURCE_VERSION:=451b9881b72cb994c102724b5a7d9b93f97dc315
PKG_MIRROR_HASH:=a775c7ffb9fac2d798ec8e0a4c7707eb7133cbc9c4418a1cf9434f87c42c01bb PKG_MIRROR_HASH:=b453976171187e0ffe7cacfdcab36cec6b5d02db8b6d978cb9afbbcafcfcff9d
PKG_FLAGS:=nonshared PKG_FLAGS:=nonshared
PKG_BUILD_FLAGS:=no-lto PKG_BUILD_FLAGS:=no-lto
@ -46,8 +46,6 @@ define Package/bcm27xx-utils/install
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/eepflash.sh $(1)/usr/bin $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/eepflash.sh $(1)/usr/bin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/eepmake $(1)/usr/bin $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/eepmake $(1)/usr/bin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/kdtc $(1)/usr/bin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/otpset $(1)/usr/bin $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/otpset $(1)/usr/bin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/overlaycheck $(1)/usr/bin $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/overlaycheck $(1)/usr/bin

View file

@ -15,8 +15,8 @@ PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/$(PKG_NAME)/$(PKG_NAME).git PKG_SOURCE_URL:=https://github.com/$(PKG_NAME)/$(PKG_NAME).git
PKG_SOURCE_VERSION:=277d4574c10bb8e16ab6ab3f38b8e1cb6cd6c678 PKG_SOURCE_VERSION:=5e7121e45ff283d30097da381fd7e97c4bb61364
PKG_VERSION:=1.14.20241010 PKG_VERSION:=1.13-$(PKG_SOURCE_VERSION)
PKG_LICENSE:=GPL-2.0 PKG_LICENSE:=GPL-2.0
PKG_LICENSE_FILES:=COPYING PKG_LICENSE_FILES:=COPYING
@ -29,6 +29,7 @@ define KernelPackage/cryptodev
SUBMENU:=Cryptographic API modules SUBMENU:=Cryptographic API modules
TITLE:=Driver for cryptographic acceleration TITLE:=Driver for cryptographic acceleration
URL:=http://cryptodev-linux.org/ URL:=http://cryptodev-linux.org/
VERSION:=$(LINUX_VERSION)+$(PKG_VERSION)-$(BOARD)-$(PKG_RELEASE)
DEPENDS:=+kmod-crypto-authenc +kmod-crypto-hash DEPENDS:=+kmod-crypto-authenc +kmod-crypto-hash
FILES:=$(PKG_BUILD_DIR)/cryptodev.$(LINUX_KMOD_SUFFIX) FILES:=$(PKG_BUILD_DIR)/cryptodev.$(LINUX_KMOD_SUFFIX)
AUTOLOAD:=$(call AutoLoad,50,cryptodev) AUTOLOAD:=$(call AutoLoad,50,cryptodev)

View file

@ -13,7 +13,7 @@ PKG_SOURCE_URL:=https://github.com/Ysurac/dsvpn.git
#PKG_SOURCE_VERSION:=3b99d2ef6c02b2ef68b5784bec8adfdd55b29b1a #PKG_SOURCE_VERSION:=3b99d2ef6c02b2ef68b5784bec8adfdd55b29b1a
PKG_SOURCE_VERSION:=4333aa705efd9c86c76809614d20dc5ebf43da7f PKG_SOURCE_VERSION:=4333aa705efd9c86c76809614d20dc5ebf43da7f
PKG_NAME:=dsvpn PKG_NAME:=dsvpn
PKG_VERSION:=0.1.5 PKG_VERSION:=0.1.5-$(PKG_SOURCE_VERSION)
PKG_RELEASE:=1 PKG_RELEASE:=1
PKG_LICENSE:=MIT PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE PKG_LICENSE_FILES:=LICENSE

View file

@ -31,7 +31,7 @@ validate_section() {
version_over_5_4() { version_over_5_4() {
MAJOR_VERSION=$(uname -r | awk -F '.' '{print $1}') MAJOR_VERSION=$(uname -r | awk -F '.' '{print $1}')
MINOR_VERSION=$(uname -r | awk -F '.' '{print $2}' | awk -F '-' '{print $1}') MINOR_VERSION=$(uname -r | awk -F '.' '{print $2}')
if [ $MAJOR_VERSION -ge 5 ] && [ $MINOR_VERSION -gt 13 ] || [ $MAJOR_VERSION -gt 5 ] ; then if [ $MAJOR_VERSION -ge 5 ] && [ $MINOR_VERSION -gt 13 ] || [ $MAJOR_VERSION -gt 5 ] ; then
return 0 return 0
else else

View file

@ -12,8 +12,8 @@ PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/angt/glorytun.git PKG_SOURCE_URL:=https://github.com/angt/glorytun.git
PKG_SOURCE_VERSION:=32267e86a6da05b285bb3bf2b136c105dc0af4bb PKG_SOURCE_VERSION:=32267e86a6da05b285bb3bf2b136c105dc0af4bb
PKG_NAME:=glorytun-udp PKG_NAME:=glorytun-udp
PKG_VERSION:=0.3.4 PKG_VERSION:=0.3.4-$(PKG_SOURCE_VERSION)
PKG_RELEASE:=24 PKG_RELEASE:=23
PKG_LICENSE:=BSD-2-Clause PKG_LICENSE:=BSD-2-Clause
PKG_LICENSE_FILES:=LICENSE PKG_LICENSE_FILES:=LICENSE
@ -48,7 +48,7 @@ define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/etc/init.d $(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) init $(1)/etc/init.d/$(PKG_NAME) $(INSTALL_BIN) init $(1)/etc/init.d/$(PKG_NAME)
$(INSTALL_DIR) $(1)/etc/config $(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DATA) glorytun-udp.config $(1)/etc/config/glorytun-udp touch $(1)/etc/config/glorytun
endef endef
$(eval $(call BuildPackage,$(PKG_NAME))) $(eval $(call BuildPackage,$(PKG_NAME)))

View file

@ -9,12 +9,12 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=glorytun PKG_NAME:=glorytun
PKG_RELEASE:=8 PKG_RELEASE:=6
PKG_SOURCE_PROTO:=git PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=8aebb3efb3b108b1276aa74679e200e003f298de PKG_SOURCE_VERSION:=0c3b03cf0215e0896fd8e7e91be92efa77f6a2d1
PKG_SOURCE:=glorytun-$(PKG_VERSION).tar.gz PKG_SOURCE:=glorytun-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/Ysurac/glorytun.git PKG_SOURCE_URL:=https://github.com/Ysurac/glorytun.git
PKG_VERSION:=0.0.35 PKG_VERSION:=0.0.35-$(PKG_SOURCE_VERSION)
PKG_LICENSE:=BSD-2-Clause PKG_LICENSE:=BSD-2-Clause
PKG_LICENSE_FILES:=LICENSE PKG_LICENSE_FILES:=LICENSE
PKG_FIXUP:=autoreconf PKG_FIXUP:=autoreconf

View file

@ -120,7 +120,7 @@ build() {
if [ "$GO_GO_GENERATE" = 1 ]; then if [ "$GO_GO_GENERATE" = 1 ]; then
log "Calling go generate" log "Calling go generate"
# shellcheck disable=SC2086 # shellcheck disable=SC2086
GOOS='' GOARCH='' GO386='' GOARM='' GOARM64='' GOMIPS='' GOMIPS64='' GORISCV64=''\ GOOS='' GOARCH='' GO386='' GOARM='' GOMIPS='' GOMIPS64='' \
go generate -v $targets go generate -v $targets
log log
fi fi

View file

@ -19,11 +19,14 @@ define GoCompiler/Default/CheckHost
endef endef
# $(1) source go root # $(1) source go root
# $(2) additional environment variables (optional) # $(2) destination prefix
# $(3) go version id
# $(4) additional environment variables (optional)
define GoCompiler/Default/Make define GoCompiler/Default/Make
( \ ( \
cd "$(1)/src" ; \ cd "$(1)/src" ; \
$(2) \ $(if $(2),GOROOT_FINAL="$(2)/lib/go-$(3)") \
$(4) \
$(BASH) make.bash \ $(BASH) make.bash \
$(if $(findstring s,$(OPENWRT_VERBOSE)),-v) \ $(if $(findstring s,$(OPENWRT_VERBOSE)),-v) \
--no-banner \ --no-banner \
@ -153,7 +156,7 @@ define GoCompiler/AddProfile
# $$(1) additional environment variables (optional) # $$(1) additional environment variables (optional)
define GoCompiler/$(1)/Make define GoCompiler/$(1)/Make
$$(call GoCompiler/Default/Make,$(2),$$(1)) $$(call GoCompiler/Default/Make,$(2),$(3),$(4),$$(1))
endef endef
# $$(1) override install prefix (optional) # $$(1) override install prefix (optional)

View file

@ -59,13 +59,11 @@ unexport \
# Architecture-specific environment variables: # Architecture-specific environment variables:
unexport \ unexport \
GOARM \ GOARM \
GOARM64 \
GO386 \ GO386 \
GOAMD64 \ GOAMD64 \
GOMIPS \ GOMIPS \
GOMIPS64 \ GOMIPS64 \
GOPPC64 \ GOPPC64 \
GORISCV64 \
GOWASM GOWASM
# Environment variables for use with code coverage: # Environment variables for use with code coverage:

View file

@ -7,8 +7,8 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
GO_VERSION_MAJOR_MINOR:=1.23 GO_VERSION_MAJOR_MINOR:=1.22
GO_VERSION_PATCH:=4 GO_VERSION_PATCH:=0
PKG_NAME:=golang PKG_NAME:=golang
PKG_VERSION:=$(GO_VERSION_MAJOR_MINOR)$(if $(GO_VERSION_PATCH),.$(GO_VERSION_PATCH)) 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:=go$(PKG_VERSION).src.tar.gz
PKG_SOURCE_URL:=$(GO_SOURCE_URLS) PKG_SOURCE_URL:=$(GO_SOURCE_URLS)
PKG_HASH:=ad345ac421e90814293a9699cca19dd5238251c3f687980bbcae28495b263531 PKG_HASH:=4d196c3d41a0d6c1dfc64d04e3cc1f608b0c436bd87b7060ce3e23234e1f4d5c
PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com> PKG_MAINTAINER:=Jeffery To <jeffery.to@gmail.com>
PKG_LICENSE:=BSD-3-Clause PKG_LICENSE:=BSD-3-Clause
@ -34,6 +34,7 @@ PKG_BUILD_FLAGS:=no-mips16
PKG_GO_PREFIX:=/usr PKG_GO_PREFIX:=/usr
PKG_GO_VERSION_ID:=$(GO_VERSION_MAJOR_MINOR) PKG_GO_VERSION_ID:=$(GO_VERSION_MAJOR_MINOR)
PKG_GO_ROOT:=$(PKG_GO_PREFIX)/lib/go-$(PKG_GO_VERSION_ID)
HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/go-$(PKG_VERSION) HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/go-$(PKG_VERSION)
HOST_BUILD_PARALLEL:=1 HOST_BUILD_PARALLEL:=1
@ -64,7 +65,6 @@ HOST_GO_VALID_OS_ARCH:= \
wasip1_wasm \ wasip1_wasm \
\ \
freebsd_riscv64 \ freebsd_riscv64 \
openbsd_riscv64 \
\ \
linux_ppc64 linux_ppc64le \ linux_ppc64 linux_ppc64le \
linux_mips linux_mipsle linux_mips64 linux_mips64le \ linux_mips linux_mipsle linux_mips64 linux_mips64le \
@ -394,6 +394,7 @@ define Build/Compile
cd "$(PKG_BUILD_DIR)/bin" ; \ cd "$(PKG_BUILD_DIR)/bin" ; \
export $(GO_PKG_TARGET_VARS) ; \ export $(GO_PKG_TARGET_VARS) ; \
$(CP) go go-host ; \ $(CP) go go-host ; \
GOROOT_FINAL="$(PKG_GO_ROOT)" \
GO_GCC_HELPER_CC="$(TARGET_CC)" \ GO_GCC_HELPER_CC="$(TARGET_CC)" \
GO_GCC_HELPER_CXX="$(TARGET_CXX)" \ GO_GCC_HELPER_CXX="$(TARGET_CXX)" \
$(PKG_GO_VARS) \ $(PKG_GO_VARS) \

48
https-dns-proxy/Makefile Normal file
View file

@ -0,0 +1,48 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=https-dns-proxy
PKG_VERSION:=2021-06-03
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/aarond10/https_dns_proxy
PKG_SOURCE_DATE:=2021-06-03
PKG_SOURCE_VERSION:=5651b984f770a8bcecb14aeffc224703f8f82586
PKG_MIRROR_HASH:=b65161936269aa3117debad0fcfce157024726b78d7e7da77c226f7aa8da5b4d
PKG_MAINTAINER:=Stan Grishin <stangri@melmac.net>
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/cmake.mk
CMAKE_OPTIONS += -DCLANG_TIDY_EXE=
define Package/https-dns-proxy
SECTION:=net
CATEGORY:=Network
TITLE:=DNS Over HTTPS Proxy
URL:=https://docs.openwrt.melmac.net/https-dns-proxy/
DEPENDS:=+libcares +libcurl +libev +ca-bundle
CONFLICTS:=https_dns_proxy
endef
define Package/https-dns-proxy/description
https-dns-proxy is a light-weight DNS<-->HTTPS, non-caching translation proxy for the RFC 8484 DoH standard.
It receives regular (UDP) DNS requests and issues them via DoH.
Please see https://docs.openwrt.melmac.net/https-dns-proxy/ for more information.
endef
define Package/https-dns-proxy/conffiles
/etc/config/https-dns-proxy
endef
define Package/https-dns-proxy/install
$(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/init.d ${1}/etc/config
$(INSTALL_BIN) $(PKG_BUILD_DIR)/https_dns_proxy $(1)/usr/sbin/https-dns-proxy
$(INSTALL_BIN) ./files/https-dns-proxy.init $(1)/etc/init.d/https-dns-proxy
$(SED) "s|^\(PKG_VERSION\).*|\1='$(PKG_VERSION)-$(PKG_RELEASE)'|" $(1)/etc/init.d/https-dns-proxy
$(INSTALL_CONF) ./files/https-dns-proxy.config $(1)/etc/config/https-dns-proxy
endef
$(eval $(call BuildPackage,https-dns-proxy))

View file

@ -0,0 +1,3 @@
# README
README has been moved to [https://docs.openwrt.melmac.net/https-dns-proxy/](https://docs.openwrt.melmac.net/https-dns-proxy/).

View file

@ -0,0 +1,18 @@
config main 'config'
option update_dnsmasq_config '*'
config https-dns-proxy
option bootstrap_dns '8.8.8.8,8.8.4.4'
option resolver_url 'https://dns.google/dns-query'
option listen_addr '127.0.0.1'
option listen_port '5053'
option user 'nobody'
option group 'nogroup'
config https-dns-proxy
option bootstrap_dns '1.1.1.1,1.0.0.1'
option resolver_url 'https://cloudflare-dns.com/dns-query'
option listen_addr '127.0.0.1'
option listen_port '5054'
option user 'nobody'
option group 'nogroup'

View file

@ -0,0 +1,238 @@
#!/bin/sh /etc/rc.common
# Copyright 2019-2020 Stan Grishin (stangri@melmac.net)
# shellcheck disable=SC2039,SC3043,SC3060
PKG_VERSION='dev-test'
# shellcheck disable=SC2034
START=80
# 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
readonly PROG=/usr/sbin/https-dns-proxy
dnsmasqConfig=''; forceDNS=''; forceDNSPorts='';
version() { echo "$PKG_VERSION"; }
xappend() { param="$param $1"; }
append_bool() {
local section="$1"
local option="$2"
local value="$3"
local default="$4"
local _loctmp
[ -z "$default" ] && default="0"
config_get_bool _loctmp "$section" "$option" "$default"
[ "$_loctmp" != "0" ] && xappend "$value"
}
append_parm() {
local section="$1"
local option="$2"
local switch="$3"
local default="$4"
local _loctmp
config_get _loctmp "$section" "$option" "$default"
[ -z "$_loctmp" ] && return 0
xappend "$switch $_loctmp"
}
start_instance() {
local cfg="$1" param listen_addr listen_port i
append_parm "$cfg" 'resolver_url' '-r'
append_parm "$cfg" 'polling_interval' '-i'
append_parm "$cfg" 'listen_addr' '-a' '127.0.0.1'
append_parm "$cfg" 'listen_port' '-p' "$p"
append_parm "$cfg" 'dscp_codepoint' '-c'
append_parm "$cfg" 'bootstrap_dns' '-b'
append_parm "$cfg" 'user' '-u' 'nobody'
append_parm "$cfg" 'group' '-g' 'nogroup'
append_parm "$cfg" 'proxy_server' '-t'
append_parm "$cfg" 'logfile' '-l'
append_bool "$cfg" 'use_http1' '-x'
config_get_bool ipv6_resolvers_only "$cfg" 'use_ipv6_resolvers_only' '0'
config_get verbosity "$cfg" 'verbosity' '0'
# shellcheck disable=SC2086,SC2154
for i in $(seq 1 $verbosity); do
xappend '-v'
done
# shellcheck disable=SC2154
if [ "$ipv6_resolvers_only" = 0 ]; then
xappend '-4'
fi
procd_open_instance
# shellcheck disable=SC2086
procd_set_param command ${PROG} ${param}
procd_set_param stderr 1
procd_set_param stdout 1
procd_set_param respawn
procd_close_instance
config_get listen_addr "$cfg" 'listen_addr' '127.0.0.1'
config_get listen_port "$cfg" 'listen_port' "$p"
if [ "$dnsmasqConfig" = "*" ]; then
config_load 'dhcp'
config_foreach dnsmasq_add_doh_server 'dnsmasq' "${listen_addr}" "${listen_port}"
elif [ -n "$dnsmasqConfig" ]; then
for i in $dnsmasqConfig; do
dnsmasq_add_doh_server "@dnsmasq[${i}]" "${listen_addr}" "${listen_port}"
done
fi
p="$((p+1))"
}
is_force_dns_active() { iptables-save 2>/dev/null | grep -q -w -- '--dport 53'; }
start_service() {
local p=5053 c
config_load 'https-dns-proxy'
config_get dnsmasqConfig 'config' 'update_dnsmasq_config' '*'
config_get_bool forceDNS 'config' 'force_dns' '1'
config_get forceDNSPorts 'config' 'force_dns_port' '53 853'
dhcp_backup 'create'
config_load 'https-dns-proxy'
config_foreach start_instance 'https-dns-proxy'
if [ "$forceDNS" -ne 0 ]; then
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 firewall
for c in $forceDNSPorts; do
if netstat -tuln | grep 'LISTEN' | grep ":${c}" >/dev/null 2>&1 || [ "$c" = "53" ]; then
json_add_object ""
json_add_string type redirect
json_add_string target DNAT
json_add_string src lan
json_add_string proto "tcp udp"
json_add_string src_dport "$c"
json_add_string dest_port "$c"
json_add_boolean reflection 0
json_close_object
else
json_add_object ""
json_add_string type rule
json_add_string src lan
json_add_string dest "*"
json_add_string proto "tcp udp"
json_add_string dest_port "$c"
json_add_string target REJECT
json_close_object
fi
done
json_close_array
procd_close_data
procd_close_instance
fi
if [ -n "$(uci -q changes dhcp)" ]; then
uci -q commit dhcp
[ -x /etc/init.d/dnsmasq ] && /etc/init.d/dnsmasq restart >/dev/null 2>&1
fi
}
stop_service() {
config_load 'https-dns-proxy'
config_get dnsmasqConfig 'config' 'update_dnsmasq_config' '*'
dhcp_backup 'restore'
if [ -n "$(uci -q changes dhcp)" ]; then
uci -q commit dhcp
[ -x /etc/init.d/dnsmasq ] && /etc/init.d/dnsmasq restart >/dev/null 2>&1
fi
}
service_triggers() {
procd_add_config_trigger "config.change" "https-dns-proxy" /etc/init.d/https-dns-proxy reload
}
service_started() { procd_set_config_changed firewall; }
service_stopped() { procd_set_config_changed firewall; }
dnsmasq_add_doh_server() {
local cfg="$1" address="$2" port="$3"
case $address in
0.0.0.0|::ffff:0.0.0.0) address='127.0.0.1';;
::) address='::1';;
esac
uci -q del_list "dhcp.${cfg}.server=${address}#${port}"
uci -q add_list "dhcp.${cfg}.server=${address}#${port}"
}
dnsmasq_create_server_backup() {
local cfg="$1"
local i
uci -q get "dhcp.${cfg}" >/dev/null || return 1
if ! uci -q get "dhcp.${cfg}.doh_backup_noresolv" >/dev/null; then
if [ -z "$(uci -q get "dhcp.${cfg}.noresolv")" ]; then
uci -q set "dhcp.${cfg}.noresolv=1"
uci -q set "dhcp.${cfg}.doh_backup_noresolv=-1"
elif [ "$(uci -q get "dhcp.${cfg}.noresolv")" != "1" ]; then
uci -q set "dhcp.${cfg}.noresolv=1"
uci -q set "dhcp.${cfg}.doh_backup_noresolv=0"
fi
fi
if ! uci -q get "dhcp.${cfg}.doh_backup_server" >/dev/null; then
if [ -z "$(uci -q get "dhcp.${cfg}.server")" ]; then
uci -q add_list "dhcp.${cfg}.doh_backup_server="
fi
for i in $(uci -q get "dhcp.${cfg}.server"); do
uci -q add_list "dhcp.${cfg}.doh_backup_server=$i"
if [ "$i" = "$(echo "$i" | tr -d /\#)" ]; then
uci -q del_list "dhcp.${cfg}.server=$i"
fi
done
uci -q del_list "dhcp.${cfg}.server=127.0.0.1#5353"
fi
return 0
}
dnsmasq_restore_server_backup() {
local cfg="$1"
local i
uci -q get "dhcp.${cfg}" >/dev/null || return 0
if uci -q get "dhcp.${cfg}.doh_backup_noresolv" >/dev/null; then
if [ "$(uci -q get "dhcp.${cfg}.doh_backup_noresolv")" = "0" ]; then
uci -q set "dhcp.${cfg}.noresolv=0"
else
uci -q del "dhcp.${cfg}.noresolv"
fi
uci -q del "dhcp.${cfg}.doh_backup_noresolv"
fi
if uci -q get "dhcp.${cfg}.doh_backup_server" >/dev/null; then
uci -q del "dhcp.${cfg}.server"
for i in $(uci -q get "dhcp.${cfg}.doh_backup_server"); do
uci -q add_list "dhcp.${cfg}.server=$i"
done
uci -q del "dhcp.${cfg}.doh_backup_server"
fi
}
dhcp_backup() {
local i
config_load 'dhcp'
case "$1" in
create)
if [ "$dnsmasqConfig" = "*" ]; then
config_foreach dnsmasq_create_server_backup 'dnsmasq'
elif [ -n "$dnsmasqConfig" ]; then
for i in $dnsmasqConfig; do
dnsmasq_create_server_backup "@dnsmasq[${i}]" || \
dnsmasq_create_server_backup "$i"
done
fi
;;
restore)
config_foreach dnsmasq_restore_server_backup 'dnsmasq'
;;
esac
}

3
https-dns-proxy/test.sh Normal file
View file

@ -0,0 +1,3 @@
#!/bin/sh
/etc/init.d/"$1" version 2>&1 | grep "$2"

View file

@ -8,16 +8,15 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=iperf PKG_NAME:=iperf
PKG_VERSION:=3.18 PKG_VERSION:=3.17.1
PKG_RELEASE:=1 PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE:=$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://downloads.es.net/pub/iperf PKG_SOURCE_URL:=https://github.com/esnet/iperf/archive/refs/tags/
PKG_HASH:=c0618175514331e766522500e20c94bfb293b4424eb27d7207fb427b88d20bab PKG_HASH:=105b4fe7fbce31c9b94a3fec10c46e3b4b298adc076e1e3af52b990e1faf2db9
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name> PKG_MAINTAINER:=Yannick Chabanois <ycarus@zugaina.org>
PKG_LICENSE:=BSD-3-Clause PKG_LICENSE:=BSD-3-Clause
PKG_CPE_ID:=cpe:/a:es:iperf3
PKG_BUILD_PARALLEL:=1 PKG_BUILD_PARALLEL:=1
PKG_INSTALL:=1 PKG_INSTALL:=1
@ -38,36 +37,24 @@ endef
define Package/iperf3 define Package/iperf3
$(call Package/iperf3/default) $(call Package/iperf3/default)
VARIANT:=nossl VARIANT:=nossl
DEPENDS:=+libiperf3
endef endef
define Package/iperf3-ssl define Package/iperf3-ssl
$(call Package/iperf3/default) $(call Package/iperf3/default)
TITLE+= with iperf_auth support TITLE+= with iperf_auth support
VARIANT:=ssl VARIANT:=ssl
DEPENDS:=+libopenssl +libatomic DEPENDS:= +libopenssl
CONFLICTS:=iperf3
endef
define Package/libiperf3
SECTION:=libs
CATEGORY:=Libraries
TITLE:=Internet Protocol bandwidth measuring library
URL:=https://github.com/esnet/iperf
DEPENDS+=+libatomic
endef endef
TARGET_CFLAGS += -D_GNU_SOURCE TARGET_CFLAGS += -D_GNU_SOURCE
TARGET_LDFLAGS += -latomic CONFIGURE_ARGS += --disable-shared
ifeq ($(BUILD_VARIANT),ssl) ifeq ($(BUILD_VARIANT),ssl)
CONFIGURE_ARGS += --with-openssl="$(STAGING_DIR)/usr" --disable-shared CONFIGURE_ARGS += --with-openssl="$(STAGING_DIR)/usr"
else else
CONFIGURE_ARGS += --without-openssl CONFIGURE_ARGS += --without-openssl
endif endif
CONFIGURE_ARGS += --without-sctp
MAKE_FLAGS += noinst_PROGRAMS= MAKE_FLAGS += noinst_PROGRAMS=
define Package/iperf3/description define Package/iperf3/description
@ -76,17 +63,6 @@ define Package/iperf3/description
characteristics. characteristics.
endef endef
define Package/libiperf3/description
Libiperf is a library providing an API for iperf3 functionality.
endef
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/lib
$(INSTALL_DIR) $(1)/usr/include
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libiperf.* $(1)/usr/lib/
$(CP) $(PKG_INSTALL_DIR)/usr/include/* $(1)/usr/include/
endef
# autoreconf fails if the README file isn't present # autoreconf fails if the README file isn't present
define Build/Prepare define Build/Prepare
$(call Build/Prepare/Default) $(call Build/Prepare/Default)
@ -103,11 +79,5 @@ define Package/iperf3-ssl/install
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/iperf3 $(1)/usr/bin/ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/iperf3 $(1)/usr/bin/
endef endef
define Package/libiperf3/install
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libiperf.so.* $(1)/usr/lib
endef
$(eval $(call BuildPackage,iperf3)) $(eval $(call BuildPackage,iperf3))
$(eval $(call BuildPackage,iperf3-ssl)) $(eval $(call BuildPackage,iperf3-ssl))
$(eval $(call BuildPackage,libiperf3))

View file

@ -1,21 +0,0 @@
From fe09305eb6f907e4eb637b8edd0c8a986187d1dd Mon Sep 17 00:00:00 2001
From: Rosen Penev <rosenp@gmail.com>
Date: Sat, 8 Jun 2024 15:23:51 -0700
Subject: [PATCH] fix crash under big endian musl
iperf_printf is using an int format here but an int64_t variable. The format only needs the first 3 digits. Cast to int to fix it.
---
src/iperf_api.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/src/iperf_api.c
+++ b/src/iperf_api.c
@@ -4137,7 +4137,7 @@ iperf_print_results(struct iperf_test *t
iperf_printf(test, report_sender_not_available_summary_format, "SUM");
}
else {
- iperf_printf(test, report_sum_bw_retrans_format, mbuf, start_time, sender_time, ubuf, nbuf, total_retransmits, report_sender);
+ iperf_printf(test, report_sum_bw_retrans_format, mbuf, start_time, sender_time, ubuf, nbuf, (int)total_retransmits, report_sender);
}
} else {
/* Summary sum, TCP without retransmits. */

View file

@ -1,4 +1,4 @@
From cf75cf46785871330717a6d2c889abeb7bbd7bfd Mon Sep 17 00:00:00 2001 From 5f71968be8e8809e4e7b876ff04b4ef3f22eb141 Mon Sep 17 00:00:00 2001
From: Geliang Tang <geliang@kernel.org> From: Geliang Tang <geliang@kernel.org>
Date: Wed, 6 Mar 2024 11:23:33 +0800 Date: Wed, 6 Mar 2024 11:23:33 +0800
Subject: [PATCH] add MPTCPv1 support Subject: [PATCH] add MPTCPv1 support
@ -17,6 +17,10 @@ be used like this:
> iperf3 -m -s > iperf3 -m -s
> iperf3 -m -c 127.0.0.1 > iperf3 -m -c 127.0.0.1
There is no need to check for IPPROTO_MPTCP support in configure.ac
at build time, it is at runtime we will see if the kernel being use
supports or not MPTCP.
If IPPROTO_MPTCP is not supported by the kernel being tested, it is If IPPROTO_MPTCP is not supported by the kernel being tested, it is
normal to fail because the feature is not available and the user normal to fail because the feature is not available and the user
explicitly asked to use MPTCP. explicitly asked to use MPTCP.
@ -25,44 +29,20 @@ Closes: https://github.com/esnet/iperf/pull/1659
Co-developed-by: Paolo Abeni <pabeni@redhat.com> Co-developed-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Geliang Tang <geliang@kernel.org> Signed-off-by: Geliang Tang <geliang@kernel.org>
--- ---
configure.ac | 12 ++++++++++++
src/iperf.h | 1 + src/iperf.h | 1 +
src/iperf3.1 | 4 ++++ src/iperf3.1 | 4 ++++
src/iperf_api.c | 19 ++++++++++++++++++- src/iperf_api.c | 19 ++++++++++++++++++-
src/iperf_locale.c | 3 +++ src/iperf_locale.c | 3 +++
src/iperf_tcp.c | 18 +++++++++++++++--- src/iperf_tcp.c | 22 +++++++++++++++++++---
src/net.c | 10 +++++----- src/net.c | 10 +++++-----
src/net.h | 2 +- src/net.h | 2 +-
8 files changed, 59 insertions(+), 10 deletions(-) 7 files changed, 51 insertions(+), 10 deletions(-)
diff --git a/configure.ac b/configure.ac
index 66c1e97a5..22c2a95cf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -337,6 +337,18 @@ if test "x$iperf3_cv_header_tcp_info_snd_wnd" = "xyes"; then
AC_DEFINE([HAVE_TCP_INFO_SND_WND], [1], [Have tcpi_snd_wnd field in tcp_info.])
fi
+# Check for IPPROTO_MPTCP (Linux)
+AC_CACHE_CHECK([MPTCP protocol],
+[iperf3_cv_header_ipproto_mptcp],
+AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[#include <netinet/in.h>]],
+ [[int foo = IPPROTO_MPTCP;]])],
+ iperf3_cv_header_ipproto_mptcp=yes,
+ iperf3_cv_header_ipproto_mptcp=no))
+if test "x$iperf3_cv_header_ipproto_mptcp" = "xyes"; then
+ AC_DEFINE([HAVE_IPPROTO_MPTCP], [1], [Have MPTCP protocol.])
+fi
+
# Check if we need -lrt for clock_gettime
AC_SEARCH_LIBS(clock_gettime, [rt posix4])
# Check for clock_gettime support
diff --git a/src/iperf.h b/src/iperf.h diff --git a/src/iperf.h b/src/iperf.h
index 202d3016f..4043031b3 100644 index dc3c0d1df..cb821e1f7 100644
--- a/src/iperf.h --- a/src/iperf.h
+++ b/src/iperf.h +++ b/src/iperf.h
@@ -353,6 +353,7 @@ struct iperf_test @@ -342,6 +342,7 @@ struct iperf_test
int repeating_payload; /* --repeating-payload */ int repeating_payload; /* --repeating-payload */
int timestamps; /* --timestamps */ int timestamps; /* --timestamps */
char *timestamp_format; char *timestamp_format;
@ -71,12 +51,12 @@ index 202d3016f..4043031b3 100644
char *json_output_string; /* rendered JSON output if json_output is set */ char *json_output_string; /* rendered JSON output if json_output is set */
/* Select related parameters */ /* Select related parameters */
diff --git a/src/iperf3.1 b/src/iperf3.1 diff --git a/src/iperf3.1 b/src/iperf3.1
index f8eff48d2..9e425cabc 100644 index 2efd53dea..ebc603408 100644
--- a/src/iperf3.1 --- a/src/iperf3.1
+++ b/src/iperf3.1 +++ b/src/iperf3.1
@@ -202,6 +202,10 @@ iperf-3.17, OAEP padding is used, however this is a breaking change @@ -193,6 +193,10 @@ parameter is specified in ms, and defaults to the system settings.
that is not compatible with older iperf3 versions. Use this option to This functionality depends on the TCP_USER_TIMEOUT socket option, and
preserve the less secure, but more compatible, behavior. will not work on systems that do not support it.
.TP .TP
+.BR -m ", " --mptcp " " +.BR -m ", " --mptcp " "
+use mptcp variant for the current protocol. This only applies to +use mptcp variant for the current protocol. This only applies to
@ -86,33 +66,33 @@ index f8eff48d2..9e425cabc 100644
emit debugging output. emit debugging output.
Primarily (perhaps exclusively) of use to developers. Primarily (perhaps exclusively) of use to developers.
diff --git a/src/iperf_api.c b/src/iperf_api.c diff --git a/src/iperf_api.c b/src/iperf_api.c
index fa06dc830..419b48657 100644 index 1dcfaabf5..f7f1fbfb8 100644
--- a/src/iperf_api.c --- a/src/iperf_api.c
+++ b/src/iperf_api.c +++ b/src/iperf_api.c
@@ -1149,6 +1149,9 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) @@ -1144,6 +1144,9 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
{"idle-timeout", required_argument, NULL, OPT_IDLE_TIMEOUT}, {"idle-timeout", required_argument, NULL, OPT_IDLE_TIMEOUT},
{"rcv-timeout", required_argument, NULL, OPT_RCV_TIMEOUT}, {"rcv-timeout", required_argument, NULL, OPT_RCV_TIMEOUT},
{"snd-timeout", required_argument, NULL, OPT_SND_TIMEOUT}, {"snd-timeout", required_argument, NULL, OPT_SND_TIMEOUT},
+#if defined(HAVE_IPPROTO_MPTCP) +#if defined(linux)
+ {"mptcp", no_argument, NULL, 'm'}, + {"mptcp", no_argument, NULL, 'm'},
+#endif +#endif
{"debug", optional_argument, NULL, 'd'}, {"debug", optional_argument, NULL, 'd'},
{"help", no_argument, NULL, 'h'}, {"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0} {NULL, 0, NULL, 0}
@@ -1174,7 +1177,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) @@ -1169,7 +1172,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
FILE *ptr_file; FILE *ptr_file;
#endif /* HAVE_SSL */ #endif /* HAVE_SSL */
- while ((flag = getopt_long(argc, argv, "p:f:i:D1VJvsc:ub:t:n:k:l:P:Rw:B:M:N46S:L:ZO:F:A:T:C:dI:hX:", longopts, NULL)) != -1) { - while ((flag = getopt_long(argc, argv, "p:f:i:D1VJvsc:ub:t:n:k:l:P:Rw:B:M:N46S:L:ZO:F:A:T:C:dI:hX:", longopts, NULL)) != -1) {
+ while ((flag = getopt_long(argc, argv, "p:f:i:D1VJvsc:ub:t:n:k:l:P:Rw:B:M:N46S:L:ZO:F:A:T:C:dI:mhX:", longopts, NULL)) != -1) { + while ((flag = getopt_long(argc, argv, "p:f:i:D1VJvsc:ub:t:n:k:l:P:Rw:B:mM:N46S:L:ZO:F:A:T:C:dI:hX:", longopts, NULL)) != -1) {
switch (flag) { switch (flag) {
case 'p': case 'p':
portno = atoi(optarg); portno = atoi(optarg);
@@ -1647,6 +1650,12 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) @@ -1639,6 +1642,12 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
test->settings->connect_timeout = unit_atoi(optarg); test->settings->connect_timeout = unit_atoi(optarg);
client_flag = 1; client_flag = 1;
break; break;
+#if defined(HAVE_IPPROTO_MPTCP) +#if defined(linux)
+ case 'm': + case 'm':
+ set_protocol(test, Ptcp); + set_protocol(test, Ptcp);
+ test->mptcp = 1; + test->mptcp = 1;
@ -121,47 +101,58 @@ index fa06dc830..419b48657 100644
case 'h': case 'h':
usage_long(stdout); usage_long(stdout);
exit(0); exit(0);
@@ -2259,6 +2268,10 @@ send_parameters(struct iperf_test *test) @@ -2216,6 +2225,10 @@ send_parameters(struct iperf_test *test)
cJSON_AddTrueToObject(j, "reverse"); cJSON_AddTrueToObject(j, "reverse");
if (test->bidirectional) if (test->bidirectional)
cJSON_AddTrueToObject(j, "bidirectional"); cJSON_AddTrueToObject(j, "bidirectional");
+#if defined(HAVE_IPPROTO_MPTCP) +#if defined(linux)
+ if (test->mptcp) + if (test->mptcp)
+ cJSON_AddTrueToObject(j, "mptcp"); + cJSON_AddTrueToObject(j, "mptcp");
+#endif +#endif
if (test->settings->socket_bufsize) if (test->settings->socket_bufsize)
cJSON_AddNumberToObject(j, "window", test->settings->socket_bufsize); cJSON_AddNumberToObject(j, "window", test->settings->socket_bufsize);
if (test->settings->blksize) if (test->settings->blksize)
@@ -2375,6 +2388,10 @@ get_parameters(struct iperf_test *test) @@ -2332,6 +2345,10 @@ get_parameters(struct iperf_test *test)
iperf_set_test_reverse(test, 1); iperf_set_test_reverse(test, 1);
if ((j_p = iperf_cJSON_GetObjectItemType(j, "bidirectional", cJSON_True)) != NULL) if ((j_p = cJSON_GetObjectItem(j, "bidirectional")) != NULL)
iperf_set_test_bidirectional(test, 1); iperf_set_test_bidirectional(test, 1);
+#if defined(HAVE_IPPROTO_MPTCP) +#if defined(linux)
+ if ((j_p = iperf_cJSON_GetObjectItemType(j, "mptcp", cJSON_True)) != NULL) + if ((j_p = cJSON_GetObjectItem(j, "mptcp")) != NULL)
+ test->mptcp = 1; + test->mptcp = 1;
+#endif +#endif
if ((j_p = iperf_cJSON_GetObjectItemType(j, "window", cJSON_Number)) != NULL) if ((j_p = cJSON_GetObjectItem(j, "window")) != NULL)
test->settings->socket_bufsize = j_p->valueint; test->settings->socket_bufsize = j_p->valueint;
if ((j_p = iperf_cJSON_GetObjectItemType(j, "len", cJSON_Number)) != NULL) if ((j_p = cJSON_GetObjectItem(j, "len")) != NULL)
diff --git a/src/iperf_locale.c b/src/iperf_locale.c diff --git a/src/iperf_locale.c b/src/iperf_locale.c
index 32883da84..f1d89e298 100644 index ae0f63a41..d454af4f0 100644
--- a/src/iperf_locale.c --- a/src/iperf_locale.c
+++ b/src/iperf_locale.c +++ b/src/iperf_locale.c
@@ -128,6 +128,9 @@ const char usage_longstr[] = "Usage: iperf3 [-s|-c host] [options]\n" @@ -128,6 +128,9 @@ const char usage_longstr[] = "Usage: iperf3 [-s|-c host] [options]\n"
" --snd-timeout # timeout for unacknowledged TCP data\n" " --snd-timeout # timeout for unacknowledged TCP data\n"
" (in ms, default is system settings)\n" " (in ms, default is system settings)\n"
#endif /* HAVE_TCP_USER_TIMEOUT */ #endif /* HAVE_TCP_USER_TIMEOUT */
+#if defined(HAVE_IPPROTO_MPTCP) +#if defined(linux)
+ " -m, --mptcp use MPTCP rather than plain TCP\n" + " -m, --mptcp use MPTCP rather than plain TCP\n"
+#endif +#endif
" -d, --debug[=#] emit debugging output\n" " -d, --debug[=#] emit debugging output\n"
" (optional optional \"=\" and debug level: 1-4. Default is 4 - all messages)\n" " (optional optional \"=\" and debug level: 1-4. Default is 4 - all messages)\n"
" -v, --version show version information and quit\n" " -v, --version show version information and quit\n"
diff --git a/src/iperf_tcp.c b/src/iperf_tcp.c diff --git a/src/iperf_tcp.c b/src/iperf_tcp.c
index 481c09dc8..2c10d7df5 100644 index 184a1955e..a10322b75 100644
--- a/src/iperf_tcp.c --- a/src/iperf_tcp.c
+++ b/src/iperf_tcp.c +++ b/src/iperf_tcp.c
@@ -184,9 +184,10 @@ iperf_tcp_listen(struct iperf_test *test) @@ -44,6 +44,10 @@
#include "net.h"
#include "cjson.h"
+#ifndef IPPROTO_MPTCP
+#define IPPROTO_MPTCP 262
+#endif
+
#if defined(HAVE_FLOWLABEL)
#include "flowlabel.h"
#endif /* HAVE_FLOWLABEL */
@@ -182,9 +186,10 @@ iperf_tcp_listen(struct iperf_test *test)
* *
* It's not clear whether this is a requirement or a convenience. * It's not clear whether this is a requirement or a convenience.
*/ */
@ -173,12 +164,12 @@ index 481c09dc8..2c10d7df5 100644
FD_CLR(s, &test->read_set); FD_CLR(s, &test->read_set);
close(s); close(s);
@@ -212,7 +213,12 @@ iperf_tcp_listen(struct iperf_test *test) @@ -210,7 +215,12 @@ iperf_tcp_listen(struct iperf_test *test)
return -1; return -1;
} }
- if ((s = socket(res->ai_family, SOCK_STREAM, 0)) < 0) { - if ((s = socket(res->ai_family, SOCK_STREAM, 0)) < 0) {
+#if defined(HAVE_IPPROTO_MPTCP) +#if defined(linux)
+ if (test->mptcp) + if (test->mptcp)
+ proto = IPPROTO_MPTCP; + proto = IPPROTO_MPTCP;
+#endif +#endif
@ -187,13 +178,13 @@ index 481c09dc8..2c10d7df5 100644
freeaddrinfo(res); freeaddrinfo(res);
i_errno = IESTREAMLISTEN; i_errno = IESTREAMLISTEN;
return -1; return -1;
@@ -380,8 +386,14 @@ iperf_tcp_connect(struct iperf_test *test) @@ -375,8 +385,14 @@ iperf_tcp_connect(struct iperf_test *test)
socklen_t optlen; socklen_t optlen;
int saved_errno; int saved_errno;
int rcvbuf_actual, sndbuf_actual; int rcvbuf_actual, sndbuf_actual;
+ int proto = 0; + int proto = 0;
+ +
+#if defined(HAVE_IPPROTO_MPTCP) +#if defined(linux)
+ if (test->mptcp) + if (test->mptcp)
+ proto = IPPROTO_MPTCP; + proto = IPPROTO_MPTCP;
+#endif +#endif
@ -204,7 +195,7 @@ index 481c09dc8..2c10d7df5 100644
i_errno = IESTREAMCONNECT; i_errno = IESTREAMCONNECT;
return -1; return -1;
diff --git a/src/net.c b/src/net.c diff --git a/src/net.c b/src/net.c
index b693ea7fb..febf20885 100644 index c82caff1b..849e919f2 100644
--- a/src/net.c --- a/src/net.c
+++ b/src/net.c +++ b/src/net.c
@@ -124,7 +124,7 @@ timeout_connect(int s, const struct sockaddr *name, socklen_t namelen, @@ -124,7 +124,7 @@ timeout_connect(int s, const struct sockaddr *name, socklen_t namelen,
@ -252,7 +243,7 @@ index b693ea7fb..febf20885 100644
return -1; return -1;
} }
diff --git a/src/net.h b/src/net.h diff --git a/src/net.h b/src/net.h
index 859c52cef..fb78d289b 100644 index f0e1b4f98..1f5cc4d34 100644
--- a/src/net.h --- a/src/net.h
+++ b/src/net.h +++ b/src/net.h
@@ -28,7 +28,7 @@ @@ -28,7 +28,7 @@

View file

@ -1,552 +0,0 @@
From 197d8ba733f0502985abb5b0a22bf9f71c2596a7 Mon Sep 17 00:00:00 2001
From: David Bar-On <david.cdb004@gmail.com>
Date: Mon, 25 Mar 2024 22:11:49 +0200
Subject: [PATCH] Add SOCKS5 Proxy support for TCP
---
src/iperf.h | 8 ++
src/iperf_api.c | 250 ++++++++++++++++++++++++++++++++++++++++-
src/iperf_api.h | 13 ++-
src/iperf_client_api.c | 27 ++++-
src/iperf_error.c | 10 ++
src/iperf_locale.c | 2 +
src/iperf_tcp.c | 22 +++-
7 files changed, 323 insertions(+), 9 deletions(-)
diff --git a/src/iperf.h b/src/iperf.h
index dc3c0d1df..9823dc180 100644
--- a/src/iperf.h
+++ b/src/iperf.h
@@ -343,6 +343,14 @@ struct iperf_test
int timestamps; /* --timestamps */
char *timestamp_format;
+ char *socks5_host; /* --socks5 option */
+ uint16_t socks5_port; /* --socks5 option optional value */
+ char *socks5_username; /* --socks5 option optional value */
+ char *socks5_password; /* --socks5 option optional value */
+ char socks5_bind_atyp; /* from socks5 CONNECT response ATYP */
+ char *socks5_bind_host; /* from socks5 CONNECT response BIND.ADDR*/
+ uint16_t socks5_bind_port; /* from socks5 CONNECT response BIND.PORT */
+
char *json_output_string; /* rendered JSON output if json_output is set */
/* Select related parameters */
int max_fd;
diff --git a/src/iperf_api.c b/src/iperf_api.c
index 4765d4e97..ca47f708d 100644
--- a/src/iperf_api.c
+++ b/src/iperf_api.c
@@ -115,7 +115,7 @@ usage()
void
usage_long(FILE *f)
{
- fprintf(f, usage_longstr, DEFAULT_NO_MSG_RCVD_TIMEOUT, UDP_RATE / (1024*1024), DEFAULT_PACING_TIMER, DURATION, DEFAULT_TCP_BLKSIZE / 1024, DEFAULT_UDP_BLKSIZE);
+ fprintf(f, usage_longstr, DEFAULT_NO_MSG_RCVD_TIMEOUT, UDP_RATE / (1024*1024), DEFAULT_PACING_TIMER, DURATION, DEFAULT_TCP_BLKSIZE / 1024, DEFAULT_UDP_BLKSIZE, SOCKS5_DEFAULT_PORT);
}
@@ -1100,6 +1100,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
{"version6", no_argument, NULL, '6'},
{"tos", required_argument, NULL, 'S'},
{"dscp", required_argument, NULL, OPT_DSCP},
+ {"socks5", required_argument, NULL, OPT_SOCKS5},
{"extra-data", required_argument, NULL, OPT_EXTRA_DATA},
#if defined(HAVE_FLOWLABEL)
{"flowlabel", required_argument, NULL, 'L'},
@@ -1157,7 +1158,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
char* comma;
#endif /* HAVE_CPU_AFFINITY */
char* slash;
- char *p, *p1;
+ char *p, *p1, *p2;
struct xbind_entry *xbe;
double farg;
int rcv_timeout_in = 0;
@@ -1433,6 +1434,47 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
}
client_flag = 1;
break;
+ case OPT_SOCKS5: // Format: "[username:password@]<host addr/fqdn>[:port]"
+ if (strlen(optarg) <= 0) {
+ i_errno = IESOCKS5HOST;
+ return -1;
+ }
+ p1 = strtok(optarg, "@"); // p1 -> user:password
+ if (p1 == NULL) {
+ i_errno = IESOCKS5HOST;
+ return -1;
+ }
+ p = strtok(NULL, "@"); // p -> host[:port]
+ if (p == NULL) {
+ p = p1;
+ p1 = NULL;
+ }
+ p2 = strtok(p, ":"); // parse host[:port]
+ if (strlen(p2) <= 0) {
+ i_errno = IESOCKS5HOST;
+ return -1;
+ }
+ test->socks5_host = strdup(p2);
+ p2 = strtok(NULL, ":");
+ if (p2 && strlen(p2) > 0) {
+ test->socks5_port = atoi(p2);
+ }
+ if (p1) { // parse user:password
+ p2 = strtok(p1, ":");
+ if (strlen(p2) <= 0 || strlen(p2) > 255) {
+ i_errno = IESOCKS5HOST;
+ return -1;
+ }
+ test->socks5_username = strdup(p2);
+ p2 = strtok(NULL, ":");
+ if (!p2 || strlen(p2) <= 0 || strlen(p2) > 255) {
+ i_errno = IESOCKS5HOST;
+ return -1;
+ }
+ test->socks5_password = strdup(p2);
+ }
+ client_flag = 1;
+ break;
case OPT_EXTRA_DATA:
test->extra_data = strdup(optarg);
client_flag = 1;
@@ -1740,6 +1782,12 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
return -1;
}
+ // SOCKS5 Proxy is supported only for TCP
+ if(test->role == 'c' && test->socks5_host && test->protocol->id != Ptcp) {
+ i_errno = IESOCKS5RTCPONLY;
+ return -1;
+ }
+
if (blksize == 0) {
if (test->protocol->id == Pudp)
blksize = 0; /* try to dynamically determine from MSS */
@@ -2943,6 +2991,12 @@ iperf_defaults(struct iperf_test *testp)
testp->stats_interval = testp->reporter_interval = 1;
testp->num_streams = 1;
+ testp->socks5_host = NULL;
+ testp->socks5_port = SOCKS5_DEFAULT_PORT;
+ testp->socks5_username = NULL;
+ testp->socks5_password = NULL;
+ testp->socks5_bind_host = NULL;
+
testp->settings->domain = AF_UNSPEC;
testp->settings->unit_format = 'a';
testp->settings->socket_bufsize = 0; /* use autotuning */
@@ -3100,6 +3154,14 @@ iperf_free_test(struct iperf_test *test)
free(test->remote_congestion_used);
if (test->timestamp_format)
free(test->timestamp_format);
+ if (test->socks5_host)
+ free(test->socks5_host);
+ if (test->socks5_username)
+ free(test->socks5_username);
+ if (test->socks5_password)
+ free(test->socks5_password);
+ if (test->socks5_bind_host)
+ free(test->socks5_bind_host);
if (test->omit_timer != NULL)
tmr_cancel(test->omit_timer);
if (test->timer != NULL)
@@ -3289,6 +3351,23 @@ iperf_reset_test(struct iperf_test *test)
free(test->extra_data);
test->extra_data = NULL;
}
+ if (test->socks5_host) {
+ free(test->socks5_host);
+ test->socks5_host = NULL;
+ }
+ test->socks5_port = SOCKS5_DEFAULT_PORT;
+ if (test->socks5_username) {
+ free(test->socks5_username);
+ test->socks5_username = NULL;
+ }
+ if (test->socks5_password) {
+ free(test->socks5_password);
+ test->socks5_password = NULL;
+ }
+ if (test->socks5_bind_host) {
+ free(test->socks5_bind_host);
+ test->socks5_bind_host = NULL;
+ }
/* Free output line buffers, if any (on the server only) */
struct iperf_textline *t;
@@ -4614,6 +4693,173 @@ iperf_add_stream(struct iperf_test *test, struct iperf_stream *sp)
}
}
+/**************************************************************************/
+
+/* iperf_socks5_handshake
+ *
+ * Handshake with a SOCKS5 Proxy per RFC1928, RFC1929
+ */
+int
+iperf_socks5_handshake(struct iperf_test *test, int s) {
+ char req[1024];
+ char res[1024];
+ char selected_mthod;
+ char *p, *p1;
+ size_t len;
+ int ret;
+ uint16_t net_order_short;
+
+ // Send method selection request [RFC1928]
+ p = req;
+ *p++ = 5; // VERSION
+ if (test->socks5_username) // Number of METHODs supported
+ *p++ = 2;
+ else
+ *p++ = 1;
+ *p++ = 0; // NO AUTHENTICATION REQUIRED
+ if (test->socks5_username) *p++ = 2; // USERNAME/PASSWORD
+ if (Nwrite(s, req, p - req, Ptcp) < 0) {
+ i_errno = IESOCKS5HANDSHAKE;
+ iperf_err(test, "Writing SOCKS5 auth methods message failed\n");
+ return -1;
+ }
+
+ // Receive selected method
+ if (Nread(s, res, 2, Ptcp) != 2) {
+ i_errno = IESOCKS5HANDSHAKE;
+ iperf_err(test, "Reading selected SOCKS5 method message failed\n");
+ return -1;
+ }
+
+ selected_mthod = res[1];
+ if (res[0] != 5 || (selected_mthod != 0 && selected_mthod != 2)) {
+ i_errno = IESOCKS5HANDSHAKE;
+ iperf_err(test, "Ilegal SOCKS5 method selection response: version=%d, auth method=%d\n", res[0], selected_mthod);
+ return -1;
+ }
+ if (test->debug) {
+ iperf_printf(test, "SOCKS5 server selected authentication method %d\n", selected_mthod);
+ }
+
+ // Send Username/Password request and receive the auth response [RFC1929]
+ if (selected_mthod == 2) {
+ p = req;
+ *p++ = 1; // VERSION
+ len = strlen(test->socks5_username);
+ *p++ = len;
+ memcpy(p, test->socks5_username, len); // USERNAME
+ p += len;
+ len = strlen(test->socks5_password);
+ *p++ = len;
+ memcpy(p, test->socks5_password, len); // PASSWORD
+ p += len;
+
+ if (Nwrite(s, req, p - req, Ptcp) < 0) {
+ i_errno = IESOCKS5HANDSHAKE;
+ iperf_err(test, "Writing SOCKS5 Username/Password request message failed\n");
+ return -1;
+ }
+
+ if ((ret = Nread(s, res, 2, Ptcp)) != 2) {
+ i_errno = IESOCKS5HANDSHAKE;
+ iperf_err(test, "Reading SOCKS5 Username/Password response failed; Returned %d\n", ret);
+ return -1;
+ }
+ if (res[1] != 0) {
+ i_errno = IESOCKS5HANDSHAKE;
+ iperf_err(test, "SOCKS5 Username/Password failed with error %d\n", res[1]);
+ return -1;
+ }
+ }
+
+ // Send CONNECT request [RFC1928]
+ p = req;
+ *p++ = 5; // VERSION
+ *p++ = 1; // CMD = CONNECT
+ *p++ = 0; // RESERVED
+ *p++ = 3; // ATYPE = DOMAINNAME:
+ len = strlen(test->server_hostname);
+ if (len > 255) {
+ i_errno = IESOCKS5HANDSHAKE;
+ iperf_err(test, "iperf3 host option length is limited to 255 chars when SOCKS5 is used\n");
+ return -1;
+ }
+ *p++ = len;
+ memcpy(p, test->server_hostname, len); // ADDR
+ p += len;
+ net_order_short = htons(test->server_port);
+ p1 = (char *)&net_order_short;
+ *p++ = *p1++; // PORT
+ *p++ = *p1;
+ if (Nwrite(s, req, p - req, Ptcp) < 0) {
+ i_errno = IESOCKS5HANDSHAKE;
+ iperf_err(test, "Writing SOCKS5 CONNECT message failed\n");
+ return -1;
+ }
+
+ // Read CONNECT response [RFC1928]
+ if ((ret = Nread(s, res, 4, Ptcp)) != 4) {
+ i_errno = IESOCKS5HANDSHAKE;
+ iperf_err(test, "Reading SOCKS5 CONNECT response failed; Returned %d\n", ret);
+ return -1;
+ }
+
+ if (res[0] != 5 || res[1] != 0 || res[2] != 0) {
+ i_errno = IESOCKS5HANDSHAKE;
+ iperf_err(test, "SOCKS5 CONNECT failed with error %d\n", res[1]);
+ return -1;
+ }
+
+ // Get BND.ADDR length
+ test->socks5_bind_atyp = res[3]; // ATYP
+ switch (test->socks5_bind_atyp) {
+ case 1: // IP V4 address
+ len = 4;
+ break;
+ case 3: // DOMAINNAME:
+ if ((ret = read(s, res, 1)) != 1) {
+ i_errno = IESOCKS5HANDSHAKE;
+ iperf_err(test, "Failed to read SOCKS5 CONNECT response BND.ADDR length; Returned %d\n", ret);
+ return -1;
+ }
+ len = (unsigned char)res[0];
+ break;
+ case 4: // IP V6 address
+ len = 16;
+ break;
+ default:
+ i_errno = IESOCKS5HANDSHAKE;
+ iperf_err(test, "Illegal SOCKS5 CONNECT response ATYP %d\n", res[3]);
+ return -1;
+ }
+ // Read BND.ADDR
+ if ((ret = Nread(s, res, len, Ptcp)) != len) {
+ i_errno = IESOCKS5HANDSHAKE;
+ iperf_err(test, "Failed to read SOCKS5 detailes BND.ADDR; Returned %d\n", ret);
+ return -1;
+ }
+ res[len] = '\0';
+ test->socks5_bind_host = strdup(res);
+ // Read BND.PORT
+ if ((ret = Nread(s, res, 2, Ptcp)) != 2) {
+ i_errno = IESOCKS5HANDSHAKE;
+ iperf_err(test, "Failed to read SOCKS5 detailes BND.PORT; Returned %d\n", ret);
+ return -1;
+ }
+ p1 = (char *)&net_order_short;
+ *p1++ = res[0];
+ *p1 = res[1];
+ test->socks5_bind_port = ntohs(net_order_short);
+ if (test->debug) {
+ iperf_printf(test, "SOCKS5 server BIND ADDR type=%d, PORT=%d\n", test->socks5_bind_atyp, test->socks5_bind_port);
+ }
+
+ return 0;
+}
+
+/**************************************************************************/
+
+
/* This pair of routines gets inserted into the snd/rcv function pointers
** when there's a -F flag. They handle the file stuff and call the real
** snd/rcv functions, which have been saved in snd2/rcv2.
diff --git a/src/iperf_api.h b/src/iperf_api.h
index d2bbdfe96..01d63bf5e 100644
--- a/src/iperf_api.h
+++ b/src/iperf_api.h
@@ -68,6 +68,7 @@ typedef atomic_uint_fast64_t atomic_iperf_size_t;
#define DEFAULT_PACING_TIMER 1000
#define DEFAULT_NO_MSG_RCVD_TIMEOUT 120000
#define MIN_NO_MSG_RCVD_TIMEOUT 100
+#define SOCKS5_DEFAULT_PORT 1080
#define WARN_STR_LEN 128
@@ -100,7 +101,8 @@ typedef atomic_uint_fast64_t atomic_iperf_size_t;
#define OPT_RCV_TIMEOUT 27
#define OPT_JSON_STREAM 28
#define OPT_SND_TIMEOUT 29
#define OPT_USE_PKCS1_PADDING 30
+#define OPT_SOCKS5 31
/* states */
#define TEST_START 1
@@ -308,6 +310,12 @@ void iperf_free_stream(struct iperf_stream * sp);
*/
int iperf_common_sockopts(struct iperf_test *, int s);
+/**
+ * iperf_socks5_handshake - handshake with a SOCKS5 Proxy per RFC1928, RFC1929
+ *
+ */
+int iperf_socks5_handshake(struct iperf_test *test, int s);
+
int has_tcpinfo(void);
int has_tcpinfo_retransmits(void);
void save_tcpinfo(struct iperf_stream *sp, struct iperf_interval_results *irp);
@@ -419,6 +427,8 @@ enum {
IESNDTIMEOUT = 33, // Illegal message send timeout
IEUDPFILETRANSFER = 34, // Cannot transfer file using UDP
IESERVERAUTHUSERS = 35, // Cannot access authorized users file
+ IESOCKS5HOST = 36, // Illegal SOCKS5 host / creadentials
+ IESOCKS5RTCPONLY = 37, // SOCKS5 Proxy is supported only for TCP
/* Test errors */
IENEWTEST = 100, // Unable to create a new test (check perror)
IEINITTEST = 101, // Test initialization failed (check perror)
@@ -473,8 +483,9 @@ enum {
IEPTHREADCANCEL=151, // Unable to cancel thread (check perror)
IEPTHREADJOIN=152, // Unable to join thread (check perror)
IEPTHREADATTRINIT=153, // Unable to initialize thread attribute (check perror)
IEPTHREADATTRDESTROY=154, // Unable to destroy thread attribute (check perror)
IEPTHREADSIGMASK=155, // Unable to initialize sub thread signal mask (check perror)
+ IESOCKS5HANDSHAKE = 156, // SOCKS5 Handshake with the server failed
/* Stream errors */
IECREATESTREAM = 200, // Unable to create a new stream (check herror/perror)
IEINITSTREAM = 201, // Unable to initialize stream (check herror/perror)
diff --git a/src/iperf_client_api.c b/src/iperf_client_api.c
index 7ad4c939b..670e3521d 100644
--- a/src/iperf_client_api.c
+++ b/src/iperf_client_api.c
@@ -385,6 +385,8 @@ iperf_connect(struct iperf_test *test)
{
int opt;
socklen_t len;
+ const char *connect_server;
+ int connect_port;
if (NULL == test)
{
@@ -397,12 +399,20 @@ iperf_connect(struct iperf_test *test)
make_cookie(test->cookie);
/* Create and connect the control channel */
- if (test->ctrl_sck < 0)
- // Create the control channel using an ephemeral port
- test->ctrl_sck = netdial(test->settings->domain, Ptcp, test->bind_address, test->bind_dev, 0, test->server_hostname, test->server_port, test->settings->connect_timeout);
if (test->ctrl_sck < 0) {
- i_errno = IECONNECT;
- return -1;
+ if (test->socks5_host) {
+ connect_server = test->socks5_host;
+ connect_port = test->socks5_port;
+ } else {
+ connect_server = test->server_hostname;
+ connect_port = test->server_port;
+ }
+ // Create the control channel using an ephemeral port
+ test->ctrl_sck = netdial(test->settings->domain, Ptcp, test->bind_address, test->bind_dev, 0, connect_server, connect_port, test->settings->connect_timeout);
+ if (test->ctrl_sck < 0) {
+ i_errno = IECONNECT;
+ return -1;
+ }
}
// set TCP_NODELAY for lower latency on control messages
@@ -421,6 +431,13 @@ iperf_connect(struct iperf_test *test)
}
#endif /* HAVE_TCP_USER_TIMEOUT */
+ /* socks5 proxy handshake */
+ if (test->socks5_host) {
+ if (0 != iperf_socks5_handshake(test, test->ctrl_sck)) {
+ return -1;
+ }
+ }
+
if (Nwrite(test->ctrl_sck, test->cookie, COOKIE_SIZE, Ptcp) < 0) {
i_errno = IESENDCOOKIE;
return -1;
diff --git a/src/iperf_error.c b/src/iperf_error.c
index 6426554cf..a0bbb6844 100644
--- a/src/iperf_error.c
+++ b/src/iperf_error.c
@@ -216,6 +216,9 @@ iperf_strerror(int int_errno)
case IEUNIMP:
snprintf(errstr, len, "an option you are trying to set is not implemented yet");
break;
+ case IESOCKS5HOST:
+ snprintf(errstr, len, "ilegal SOCKS5 host / creadentials");
+ break;
case IEFILE:
snprintf(errstr, len, "unable to open -F file");
perr = 1;
@@ -375,6 +378,9 @@ iperf_strerror(int int_errno)
case IEUDPFILETRANSFER:
snprintf(errstr, len, "cannot transfer file using UDP");
break;
+ case IESOCKS5RTCPONLY:
+ snprintf(errstr, len, "SOCKS5 Proxy is supported only for TCP");
+ break;
case IERVRSONLYRCVTIMEOUT:
snprintf(errstr, len, "client receive timeout is valid only in receiving mode");
perr = 1;
@@ -507,6 +513,10 @@ iperf_strerror(int int_errno)
snprintf(errstr, len, "unable to destroy thread attributes");
perr = 1;
break;
+ case IESOCKS5HANDSHAKE:
+ snprintf(errstr, len, "socks5 Handshake with the server failed");
+ perr = 1;
+ break;
default:
snprintf(errstr, len, "int_errno=%d", int_errno);
perr = 1;
diff --git a/src/iperf_locale.c b/src/iperf_locale.c
index ae0f63a41..c8b9a71d1 100644
--- a/src/iperf_locale.c
+++ b/src/iperf_locale.c
@@ -194,6 +194,8 @@ const char usage_longstr[] = "Usage: iperf3 [-s|-c host] [options]\n"
" --dscp N or --dscp val set the IP dscp value, either 0-63 or symbolic.\n"
" Numeric values can be specified in decimal,\n"
" octal and hex (see --tos above).\n"
+ " --socks5 [user:password@]<proxy-host>[:port] use SOCKS5 Proxy for TCP connections,\n"
+ " using no auth or user:password. Default Proxy port is %d \n"
#if defined(HAVE_FLOWLABEL)
" -L, --flowlabel N set the IPv6 flow label (only supported on Linux)\n"
#endif /* HAVE_FLOWLABEL */
diff --git a/src/iperf_tcp.c b/src/iperf_tcp.c
index 184a1955e..515913581 100644
--- a/src/iperf_tcp.c
+++ b/src/iperf_tcp.c
@@ -375,14 +375,24 @@ iperf_tcp_connect(struct iperf_test *test)
socklen_t optlen;
int saved_errno;
int rcvbuf_actual, sndbuf_actual;
int proto = 0;
+ const char *connect_server;
+ int connect_port;
#if defined(HAVE_IPPROTO_MPTCP)
if (test->mptcp)
proto = IPPROTO_MPTCP;
#endif
- s = create_socket(test->settings->domain, SOCK_STREAM, proto, test->bind_address, test->bind_dev, test->bind_port, test->server_hostname, test->server_port, &server_res);
+ if (test->socks5_host) {
+ connect_server = test->socks5_host;
+ connect_port = test->socks5_port;
+ } else {
+ connect_server = test->server_hostname;
+ connect_port = test->server_port;
+ }
+
+ s = create_socket(test->settings->domain, SOCK_STREAM, proto, test->bind_address, test->bind_dev, test->bind_port, connect_server, connect_port, &server_res);
if (s < 0) {
i_errno = IESTREAMCONNECT;
return -1;
@@ -571,6 +581,16 @@ iperf_tcp_connect(struct iperf_test *test)
freeaddrinfo(server_res);
+ /* socks5 proxy handshake */
+ if (test->socks5_host) {
+ if (0 != iperf_socks5_handshake(test, s)) {
+ saved_errno = errno;
+ close(s);
+ errno = saved_errno;
+ return -1;
+ }
+ }
+
/* Send cookie for verification */
if (Nwrite(s, test->cookie, COOKIE_SIZE, Ptcp) < 0) {
saved_errno = errno;

View file

@ -8,12 +8,12 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=iproute2 PKG_NAME:=iproute2
PKG_VERSION:=6.12.0 PKG_VERSION:=6.9.0
PKG_RELEASE:=2 PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=@KERNEL/linux/utils/net/iproute2 PKG_SOURCE_URL:=@KERNEL/linux/utils/net/iproute2
PKG_HASH:=bbd141ef7b5d0127cc2152843ba61f274dc32814fa3e0f13e7d07a080bef53d9 PKG_HASH:=2f643d09ea11a4a2a043c92e2b469b5f73228cbf241ae806760296ed0ec413d0
PKG_BUILD_PARALLEL:=1 PKG_BUILD_PARALLEL:=1
PKG_BUILD_DEPENDS:=iptables PKG_BUILD_DEPENDS:=iptables
PKG_LICENSE:=GPL-2.0 PKG_LICENSE:=GPL-2.0
@ -77,7 +77,14 @@ $(call Package/iproute2/Default)
VARIANT:=tcfull VARIANT:=tcfull
PROVIDES:=tc PROVIDES:=tc
ALTERNATIVES:=400:/sbin/tc:/usr/libexec/tc-full ALTERNATIVES:=400:/sbin/tc:/usr/libexec/tc-full
DEPENDS:=+kmod-sched-core +(PACKAGE_devlink||PACKAGE_rdma):libmnl +libbpf +libxtables DEPENDS:=+kmod-sched-core +(PACKAGE_devlink||PACKAGE_rdma):libmnl +libbpf +libxtables +tc-mod-iptables
endef
define Package/tc-mod-iptables
$(call Package/iproute2/Default)
TITLE:=Traffic control module - iptables action
VARIANT:=tcfull
DEPENDS:=+libxtables +libbpf
endef endef
define Package/genl define Package/genl
@ -95,7 +102,7 @@ endef
define Package/ss define Package/ss
$(call Package/iproute2/Default) $(call Package/iproute2/Default)
TITLE:=Socket statistics utility TITLE:=Socket statistics utility
DEPENDS:=+libnl-tiny +(PACKAGE_devlink||PACKAGE_rdma):libmnl +libbpf +kmod-netlink-diag DEPENDS:=+libnl-tiny +(PACKAGE_devlink||PACKAGE_rdma):libmnl +kmod-netlink-diag
endef endef
define Package/nstat define Package/nstat
@ -225,6 +232,11 @@ define Package/tc-full/install
$(INSTALL_BIN) $(PKG_BUILD_DIR)/tc/tc $(1)/usr/libexec/tc-full $(INSTALL_BIN) $(PKG_BUILD_DIR)/tc/tc $(1)/usr/libexec/tc-full
endef endef
define Package/tc-mod-iptables/install
$(INSTALL_DIR) $(1)/usr/lib/tc
$(CP) $(PKG_BUILD_DIR)/tc/m_xt.so $(1)/usr/lib/tc
endef
define Package/genl/install define Package/genl/install
$(INSTALL_DIR) $(1)/usr/sbin $(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/genl/genl $(1)/usr/sbin/ $(INSTALL_BIN) $(PKG_BUILD_DIR)/genl/genl $(1)/usr/sbin/
@ -257,6 +269,9 @@ endef
$(eval $(call BuildPackage,ip-tiny)) $(eval $(call BuildPackage,ip-tiny))
$(eval $(call BuildPackage,ip-full)) $(eval $(call BuildPackage,ip-full))
# build tc-mod-iptables before its dependents, to avoid
# spurious rebuilds when building multiple variants.
$(eval $(call BuildPackage,tc-mod-iptables))
$(eval $(call BuildPackage,tc-tiny)) $(eval $(call BuildPackage,tc-tiny))
$(eval $(call BuildPackage,tc-bpf)) $(eval $(call BuildPackage,tc-bpf))
$(eval $(call BuildPackage,tc-full)) $(eval $(call BuildPackage,tc-full))

View file

@ -1,22 +0,0 @@
From c8b3ecc22ed0edaf0259eaf7d1a5c04f300ad6e4 Mon Sep 17 00:00:00 2001
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Thu, 12 Dec 2024 11:24:18 -0800
Subject: [PATCH] libnetlink: add missing endian.h
Need endian.h to get htobe64 with musl.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
include/libnetlink.h | 1 +
1 file changed, 1 insertion(+)
--- a/include/libnetlink.h
+++ b/include/libnetlink.h
@@ -4,6 +4,7 @@
#include <stdio.h>
#include <string.h>
+#include <endian.h>
#include <asm/types.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>

View file

@ -1,29 +0,0 @@
From fa3949b792e275f75d7d6200dc2036ef7fff8816 Mon Sep 17 00:00:00 2001
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Thu, 12 Dec 2024 11:21:56 -0800
Subject: [PATCH] rdma: add missing header for basename
The function basename prototype is in libgen.h
Fixes build on musl
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
rdma/rdma.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/rdma/rdma.h
+++ b/rdma/rdma.h
@@ -10,11 +10,12 @@
#include <string.h>
#include <errno.h>
#include <getopt.h>
+#include <time.h>
+#include <libgen.h>
#include <netinet/in.h>
#include <libmnl/libmnl.h>
#include <rdma/rdma_netlink.h>
#include <rdma/rdma_user_cm.h>
-#include <time.h>
#include <net/if_arp.h>
#include "list.h"

View file

@ -1,84 +0,0 @@
From 7e23da91fca6e5dedeb32a7d308cf20982e897c3 Mon Sep 17 00:00:00 2001
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Tue, 10 Dec 2024 13:38:08 -0800
Subject: [PATCH] ip: rearrange and prune header files
The recent report of issues with missing limits.h impacting musl
suggested looking at what files are and are not included in ip code.
The standard practice is to put standard headers first, then system,
then local headers. Used iwyu to get suggestions about missing
and extraneous headers.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
ip/iplink.c | 13 +++++--------
ip/ipnetns.c | 19 +++++++++----------
2 files changed, 14 insertions(+), 18 deletions(-)
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -11,17 +11,14 @@
#include <fcntl.h>
#include <dlfcn.h>
#include <errno.h>
+#include <string.h>
+#include <strings.h>
+#include <limits.h>
+
#include <sys/socket.h>
+#include <arpa/inet.h>
#include <linux/if.h>
-#include <linux/if_packet.h>
#include <linux/if_ether.h>
-#include <linux/sockios.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <stdbool.h>
-#include <linux/mpls.h>
#include "rt_names.h"
#include "utils.h"
--- a/ip/ipnetns.c
+++ b/ip/ipnetns.c
@@ -1,21 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0 */
#define _ATFILE_SOURCE
-#include <sys/file.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <sys/inotify.h>
-#include <sys/mount.h>
-#include <sys/syscall.h>
+
#include <stdio.h>
+#include <stdint.h>
#include <string.h>
-#include <sched.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
#include <unistd.h>
#include <ctype.h>
-#include <linux/limits.h>
+#include <limits.h>
+
+#include <sys/file.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/inotify.h>
+#include <sys/mount.h>
#include <linux/net_namespace.h>
@@ -23,7 +23,6 @@
#include "list.h"
#include "ip_common.h"
#include "namespace.h"
-#include "json_print.h"
static int usage(void)
{

View file

@ -1,26 +0,0 @@
From f982f30e166a02e09097de05129449031ba51f76 Mon Sep 17 00:00:00 2001
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Thu, 12 Dec 2024 11:29:44 -0800
Subject: [PATCH] cg_map: use limits.h
Prefer limits.h from system headers over linux/limits.h
Fixes build with musl.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/cg_map.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/lib/cg_map.c
+++ b/lib/cg_map.c
@@ -9,8 +9,9 @@
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
+#include <limits.h>
+
#include <linux/types.h>
-#include <linux/limits.h>
#include <ftw.h>
#include "cg_map.h"

View file

@ -1,178 +0,0 @@
From ac547ad027e3d4e283202ecb487cf54707234491 Mon Sep 17 00:00:00 2001
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Thu, 12 Dec 2024 14:15:59 -0800
Subject: [PATCH] flower: replace XATTR_SIZE_MAX
The flower tc parser was using XATTR_SIZE_MAX from linux/limits.h,
but this constant is intended to before extended filesystem attributes
not for TC. Replace it with a local define.
This fixes issue on systems with musl and XATTR_SIZE_MAX is not
defined in limits.h there.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
tc/f_flower.c | 37 ++++++++++++++++++++-----------------
1 file changed, 20 insertions(+), 17 deletions(-)
--- a/tc/f_flower.c
+++ b/tc/f_flower.c
@@ -10,7 +10,7 @@
#include <unistd.h>
#include <string.h>
#include <net/if.h>
-#include <linux/limits.h>
+
#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
@@ -22,6 +22,9 @@
#include "tc_util.h"
#include "rt_names.h"
+/* maximum length of options string */
+#define FLOWER_OPTS_MAX 4096
+
#ifndef IPPROTO_L2TP
#define IPPROTO_L2TP 115
#endif
@@ -1252,7 +1255,7 @@ static int flower_check_enc_opt_key(char
static int flower_parse_enc_opts_geneve(char *str, struct nlmsghdr *n)
{
- char key[XATTR_SIZE_MAX], mask[XATTR_SIZE_MAX];
+ char key[FLOWER_OPTS_MAX], mask[FLOWER_OPTS_MAX];
int data_len, key_len, mask_len, err;
char *token, *slash;
struct rtattr *nest;
@@ -1265,7 +1268,7 @@ static int flower_parse_enc_opts_geneve(
if (slash)
*slash = '\0';
- if ((key_len + strlen(token) > XATTR_SIZE_MAX) ||
+ if ((key_len + strlen(token) > FLOWER_OPTS_MAX) ||
flower_check_enc_opt_key(token))
return -1;
@@ -1275,7 +1278,7 @@ static int flower_parse_enc_opts_geneve(
if (!slash) {
/* Pad out mask when not provided */
- if (mask_len + strlen(token) > XATTR_SIZE_MAX)
+ if (mask_len + strlen(token) > FLOWER_OPTS_MAX)
return -1;
data_len = strlen(rindex(token, ':'));
@@ -1288,7 +1291,7 @@ static int flower_parse_enc_opts_geneve(
continue;
}
- if (mask_len + strlen(slash + 1) > XATTR_SIZE_MAX)
+ if (mask_len + strlen(slash + 1) > FLOWER_OPTS_MAX)
return -1;
strcpy(&mask[mask_len], slash + 1);
@@ -1318,7 +1321,7 @@ static int flower_parse_enc_opts_geneve(
static int flower_parse_enc_opts_vxlan(char *str, struct nlmsghdr *n)
{
- char key[XATTR_SIZE_MAX], mask[XATTR_SIZE_MAX];
+ char key[FLOWER_OPTS_MAX], mask[FLOWER_OPTS_MAX];
struct rtattr *nest;
char *slash;
int err;
@@ -1326,14 +1329,14 @@ static int flower_parse_enc_opts_vxlan(c
slash = strchr(str, '/');
if (slash) {
*slash++ = '\0';
- if (strlen(slash) > XATTR_SIZE_MAX)
+ if (strlen(slash) > FLOWER_OPTS_MAX)
return -1;
strcpy(mask, slash);
} else {
strcpy(mask, "0xffffffff");
}
- if (strlen(str) > XATTR_SIZE_MAX)
+ if (strlen(str) > FLOWER_OPTS_MAX)
return -1;
strcpy(key, str);
@@ -1355,7 +1358,7 @@ static int flower_parse_enc_opts_vxlan(c
static int flower_parse_enc_opts_erspan(char *str, struct nlmsghdr *n)
{
- char key[XATTR_SIZE_MAX], mask[XATTR_SIZE_MAX];
+ char key[FLOWER_OPTS_MAX], mask[FLOWER_OPTS_MAX];
struct rtattr *nest;
char *slash;
int err;
@@ -1364,7 +1367,7 @@ static int flower_parse_enc_opts_erspan(
slash = strchr(str, '/');
if (slash) {
*slash++ = '\0';
- if (strlen(slash) > XATTR_SIZE_MAX)
+ if (strlen(slash) > FLOWER_OPTS_MAX)
return -1;
strcpy(mask, slash);
} else {
@@ -1376,7 +1379,7 @@ static int flower_parse_enc_opts_erspan(
strcpy(mask + index, ":0xffffffff:0xff:0xff");
}
- if (strlen(str) > XATTR_SIZE_MAX)
+ if (strlen(str) > FLOWER_OPTS_MAX)
return -1;
strcpy(key, str);
@@ -1398,7 +1401,7 @@ static int flower_parse_enc_opts_erspan(
static int flower_parse_enc_opts_gtp(char *str, struct nlmsghdr *n)
{
- char key[XATTR_SIZE_MAX], mask[XATTR_SIZE_MAX];
+ char key[FLOWER_OPTS_MAX], mask[FLOWER_OPTS_MAX];
struct rtattr *nest;
char *slash;
int err;
@@ -1406,13 +1409,13 @@ static int flower_parse_enc_opts_gtp(cha
slash = strchr(str, '/');
if (slash) {
*slash++ = '\0';
- if (strlen(slash) > XATTR_SIZE_MAX)
+ if (strlen(slash) > FLOWER_OPTS_MAX)
return -1;
strcpy(mask, slash);
} else
strcpy(mask, "ff:ff");
- if (strlen(str) > XATTR_SIZE_MAX)
+ if (strlen(str) > FLOWER_OPTS_MAX)
return -1;
strcpy(key, str);
@@ -1433,7 +1436,7 @@ static int flower_parse_enc_opts_gtp(cha
static int flower_parse_enc_opts_pfcp(char *str, struct nlmsghdr *n)
{
- char key[XATTR_SIZE_MAX], mask[XATTR_SIZE_MAX];
+ char key[FLOWER_OPTS_MAX], mask[FLOWER_OPTS_MAX];
struct rtattr *nest;
char *slash;
int err;
@@ -1442,14 +1445,14 @@ static int flower_parse_enc_opts_pfcp(ch
slash = strchr(str, '/');
if (slash) {
*slash++ = '\0';
- if (strlen(slash) > XATTR_SIZE_MAX)
+ if (strlen(slash) > FLOWER_OPTS_MAX)
return -1;
strcpy(mask, slash);
} else {
strcpy(mask, "ff:ffffffffffffffff");
}
- if (strlen(str) > XATTR_SIZE_MAX)
+ if (strlen(str) > FLOWER_OPTS_MAX)
return -1;
strcpy(key, str);

View file

@ -1,37 +0,0 @@
From 458dce5d0431f0589aca1bc841904b5d1db3bbce Mon Sep 17 00:00:00 2001
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Thu, 12 Dec 2024 14:18:35 -0800
Subject: [PATCH] uapi: remove no longer used linux/limits.h
Code is now using limits.h instead.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
include/uapi/linux/limits.h | 21 ---------------------
1 file changed, 21 deletions(-)
delete mode 100644 include/uapi/linux/limits.h
--- a/include/uapi/linux/limits.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-#ifndef _LINUX_LIMITS_H
-#define _LINUX_LIMITS_H
-
-#define NR_OPEN 1024
-
-#define NGROUPS_MAX 65536 /* supplemental group IDs are available */
-#define ARG_MAX 131072 /* # bytes of args + environ for exec() */
-#define LINK_MAX 127 /* # links a file may have */
-#define MAX_CANON 255 /* size of the canonical input queue */
-#define MAX_INPUT 255 /* size of the type-ahead buffer */
-#define NAME_MAX 255 /* # chars in a file name */
-#define PATH_MAX 4096 /* # chars in a path name including nul */
-#define PIPE_BUF 4096 /* # bytes in atomic write to a pipe */
-#define XATTR_NAME_MAX 255 /* # chars in an extended attribute name */
-#define XATTR_SIZE_MAX 65536 /* size of an extended attribute value (64k) */
-#define XATTR_LIST_MAX 65536 /* size of extended attribute namelist (64k) */
-
-#define RTSIG_MAX 32
-
-#endif

View file

@ -1,6 +1,6 @@
--- a/netem/maketable.c --- a/netem/maketable.c
+++ b/netem/maketable.c +++ b/netem/maketable.c
@@ -11,7 +11,9 @@ @@ -10,7 +10,9 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
@ -12,7 +12,7 @@
#include <sys/stat.h> #include <sys/stat.h>
--- a/netem/normal.c --- a/netem/normal.c
+++ b/netem/normal.c +++ b/netem/normal.c
@@ -9,8 +9,12 @@ @@ -8,8 +8,12 @@
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
@ -27,7 +27,7 @@
#define TABLEFACTOR NETEM_DIST_SCALE #define TABLEFACTOR NETEM_DIST_SCALE
--- a/netem/pareto.c --- a/netem/pareto.c
+++ b/netem/pareto.c +++ b/netem/pareto.c
@@ -8,8 +8,12 @@ @@ -7,8 +7,12 @@
#include <math.h> #include <math.h>
#include <limits.h> #include <limits.h>
@ -42,7 +42,7 @@
#define TABLESIZE 16384 #define TABLESIZE 16384
--- a/netem/paretonormal.c --- a/netem/paretonormal.c
+++ b/netem/paretonormal.c +++ b/netem/paretonormal.c
@@ -15,10 +15,13 @@ @@ -14,10 +14,13 @@
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
#include <limits.h> #include <limits.h>

View file

@ -1,6 +1,6 @@
--- a/tc/Makefile --- a/tc/Makefile
+++ b/tc/Makefile +++ b/tc/Makefile
@@ -107,6 +107,9 @@ CFLAGS += -DCONFIG_GACT -DCONFIG_GACT_PR @@ -128,6 +128,9 @@ CFLAGS += -DCONFIG_GACT -DCONFIG_GACT_PR
ifneq ($(IPT_LIB_DIR),) ifneq ($(IPT_LIB_DIR),)
CFLAGS += -DIPT_LIB_DIR=\"$(IPT_LIB_DIR)\" CFLAGS += -DIPT_LIB_DIR=\"$(IPT_LIB_DIR)\"
endif endif

View file

@ -1,6 +1,6 @@
--- a/Makefile --- a/Makefile
+++ b/Makefile +++ b/Makefile
@@ -69,9 +69,9 @@ WFLAGS += -Wmissing-declarations -Wold-s @@ -65,9 +65,9 @@ WFLAGS += -Wmissing-declarations -Wold-s
CFLAGS := $(WFLAGS) $(CCOPTS) -I../include -I../include/uapi $(DEFINES) $(CFLAGS) CFLAGS := $(WFLAGS) $(CCOPTS) -I../include -I../include/uapi $(DEFINES) $(CFLAGS)
YACCFLAGS = -d -t -v YACCFLAGS = -d -t -v

View file

@ -1,6 +1,6 @@
--- a/tc/q_fifo.c --- a/tc/q_fifo.c
+++ b/tc/q_fifo.c +++ b/tc/q_fifo.c
@@ -90,5 +90,6 @@ struct qdisc_util pfifo_head_drop_qdisc_ @@ -95,5 +95,6 @@ struct qdisc_util pfifo_head_drop_qdisc_
struct qdisc_util pfifo_fast_qdisc_util = { struct qdisc_util pfifo_fast_qdisc_util = {
.id = "pfifo_fast", .id = "pfifo_fast",

View file

@ -1,6 +1,6 @@
--- a/configure --- a/configure
+++ b/configure +++ b/configure
@@ -368,7 +368,7 @@ check_tirpc() @@ -387,7 +387,7 @@ check_selinux()
check_mnl() check_mnl()
{ {

View file

@ -1,6 +1,6 @@
--- a/configure --- a/configure
+++ b/configure +++ b/configure
@@ -217,7 +217,7 @@ EOF @@ -255,7 +255,7 @@ EOF
check_elf() check_elf()
{ {

View file

@ -1,6 +1,6 @@
--- a/configure --- a/configure
+++ b/configure +++ b/configure
@@ -427,7 +427,7 @@ EOF @@ -445,7 +445,7 @@ EOF
check_cap() check_cap()
{ {

View file

@ -1,6 +1,6 @@
--- a/configure --- a/configure
+++ b/configure +++ b/configure
@@ -355,7 +355,7 @@ check_selinux() @@ -398,7 +398,7 @@ check_selinux()
check_tirpc() check_tirpc()
{ {

View file

@ -1,108 +0,0 @@
--- a/ip/Makefile
+++ b/ip/Makefile
@@ -19,6 +19,13 @@ RTMONOBJ=rtmon.o
include ../config.mk
+STATIC_SYM_FILTER:=
+ifeq ($(IP_CONFIG_TINY),y)
+ STATIC_SYM_FILTER:=iplink_can.c iplink_ipoib.c iplink_vxlan.c
+ CFLAGS += -DIPROUTE2_TINY
+endif
+STATIC_SYM_SOURCES:=$(filter-out $(STATIC_SYM_FILTER),$(wildcard *.c))
+
ALLOBJ=$(IPOBJ) $(RTMONOBJ)
SCRIPTS=routel
TARGETS=ip rtmon
@@ -48,7 +55,7 @@ else
ip: static-syms.o
static-syms.o: static-syms.h
-static-syms.h: $(wildcard *.c)
+static-syms.h: $(STATIC_SYM_SOURCES)
files="$^" ; \
for s in `grep -B 3 '\<dlsym' $$files | sed -n '/snprintf/{s:.*"\([^"]*\)".*:\1:;s:%s::;p}'` ; do \
sed -n '/'$$s'[^ ]* =/{s:.* \([^ ]*'$$s'[^ ]*\) .*:extern char \1[] __attribute__((weak)); if (!strcmp(sym, "\1")) return \1;:;p}' $$files ; \
--- a/ip/ip.c
+++ b/ip/ip.c
@@ -61,11 +61,17 @@ static void usage(void)
fprintf(stderr,
"Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }\n"
" ip [ -force ] -batch filename\n"
+#ifndef IPROUTE2_TINY
"where OBJECT := { address | addrlabel | fou | help | ila | ioam | l2tp | link |\n"
" macsec | maddress | monitor | mptcp | mroute | mrule |\n"
" neighbor | neighbour | netconf | netns | nexthop | ntable |\n"
" ntbl | route | rule | sr | stats | tap | tcpmetrics |\n"
" token | tunnel | tuntap | vrf | xfrm }\n"
+#else
+ "where OBJECT := { address | help | link | maddress | monitor |\n"
+ " neighbor | neighbour | netns | route |\n"
+ " rule | stats | token | tunnel }\n"
+#endif
" OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |\n"
" -h[uman-readable] | -iec | -j[son] | -p[retty] |\n"
" -f[amily] { inet | inet6 | mpls | bridge | link } |\n"
@@ -88,37 +94,49 @@ static const struct cmd {
int (*func)(int argc, char **argv);
} cmds[] = {
{ "address", do_ipaddr },
+#ifndef IPROUTE2_TINY
{ "addrlabel", do_ipaddrlabel },
+#endif
{ "maddress", do_multiaddr },
{ "route", do_iproute },
{ "rule", do_iprule },
{ "neighbor", do_ipneigh },
{ "neighbour", do_ipneigh },
+#ifndef IPROUTE2_TINY
{ "ntable", do_ipntable },
{ "ntbl", do_ipntable },
+#endif
{ "link", do_iplink },
+#ifndef IPROUTE2_TINY
{ "l2tp", do_ipl2tp },
{ "fou", do_ipfou },
{ "ila", do_ipila },
{ "macsec", do_ipmacsec },
+#endif
{ "tunnel", do_iptunnel },
{ "tunl", do_iptunnel },
+#ifndef IPROUTE2_TINY
{ "tuntap", do_iptuntap },
{ "tap", do_iptuntap },
{ "token", do_iptoken },
{ "tcpmetrics", do_tcp_metrics },
{ "tcp_metrics", do_tcp_metrics },
+#endif
{ "monitor", do_ipmonitor },
+#ifndef IPROUTE2_TINY
{ "xfrm", do_xfrm },
{ "mroute", do_multiroute },
{ "mrule", do_multirule },
+#endif
{ "netns", do_netns },
+#ifndef IPROUTE2_TINY
{ "netconf", do_ipnetconf },
{ "vrf", do_ipvrf},
{ "sr", do_seg6 },
{ "nexthop", do_ipnh },
{ "mptcp", do_mptcp },
{ "ioam", do_ioam6 },
+#endif
{ "help", do_help },
{ "stats", do_ipstats },
{ 0 }
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -3,6 +3,10 @@ include ../config.mk
CFLAGS += $(FPIC)
+ifeq ($(IP_CONFIG_TINY),y)
+ CFLAGS += -DIPROUTE2_TINY
+endif
+
UTILOBJ = utils.o utils_math.o rt_names.o ll_map.o ll_types.o ll_proto.o ll_addr.o \
inet_proto.o namespace.o json_writer.o json_print.o json_print_math.o \
names.o color.o bpf_legacy.o bpf_glue.o exec.o fs.o cg_map.o ppp_proto.o

View file

@ -0,0 +1,45 @@
--- a/tc/Makefile
+++ b/tc/Makefile
@@ -114,7 +114,7 @@ LDLIBS += -L. -lm
ifeq ($(SHARED_LIBS),y)
LDLIBS += -ldl
-LDFLAGS += -Wl,-export-dynamic
+LDFLAGS += -Wl,--dynamic-list=dynsyms.list
endif
TCLIB := tc_core.o
@@ -144,7 +144,7 @@ MODDESTDIR := $(DESTDIR)$(LIBDIR)/tc
all: tc $(TCSO)
tc: $(TCOBJ) $(LIBNETLINK) libtc.a
- $(QUIET_LINK)$(CC) $^ $(LDFLAGS) $(LDLIBS) -o $@
+ $(QUIET_LINK)$(CC) $(filter-out dynsyms.list, $^) $(LDFLAGS) $(LDLIBS) -o $@
libtc.a: $(TCLIB)
$(QUIET_AR)$(AR) rcs $@ $^
@@ -166,6 +166,7 @@ install: all
clean:
rm -f $(TCOBJ) $(TCLIB) libtc.a tc *.so emp_ematch.tab.h; \
rm -f emp_ematch.tab.*
+ rm -f dynsyms.list
q_atm.so: q_atm.c
$(QUIET_CC)$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -shared -fpic -o q_atm.so q_atm.c -latm
@@ -205,4 +206,16 @@ static-syms.h: $(wildcard *.c)
sed -n '/'$$s'[^ ]* =/{s:.* \([^ ]*'$$s'[^ ]*\) .*:extern char \1[] __attribute__((weak)); if (!strcmp(sym, "\1")) return \1;:;p}' $$files ; \
done > $@
+else
+
+tc: dynsyms.list
+m_xt.so: dynsyms.list
+dynsyms.list: $(wildcard *.c)
+ files="$(filter-out $(patsubst %.so,%.c,$(TCSO)), $^)" ; \
+ echo "{" > $@ ; \
+ for s in `grep -B 3 '\<dlsym' $$files | sed -n '/snprintf/{s:.*"\([^"]*\)".*:\1:;s:%s::;p}'` ; do \
+ sed -n '/'$$s'[^ ]* =/{s:.* \([^ ]*'$$s'[^ ]*\) .*:\1;:;p}' $$files ; \
+ done >> $@ ; \
+ echo "show_stats; print_nl; print_tm; parse_rtattr; parse_rtattr_flags; get_u32; matches; addattr_l; addattr_nest; addattr_nest_end; };" >> $@
+
endif

View file

@ -11,7 +11,7 @@ Subject: [PATCH] add support for dropping with FAILED_POLICY
--- a/ip/rtm_map.c --- a/ip/rtm_map.c
+++ b/ip/rtm_map.c +++ b/ip/rtm_map.c
@@ -49,6 +49,8 @@ char *rtnl_rtntype_n2a(int id, char *buf @@ -54,6 +54,8 @@ char *rtnl_rtntype_n2a(int id, char *buf
return "nat"; return "nat";
case RTN_XRESOLVE: case RTN_XRESOLVE:
return "xresolve"; return "xresolve";
@ -20,7 +20,7 @@ Subject: [PATCH] add support for dropping with FAILED_POLICY
default: default:
snprintf(buf, len, "%d", id); snprintf(buf, len, "%d", id);
return buf; return buf;
@@ -84,6 +86,8 @@ int rtnl_rtntype_a2n(int *id, char *arg) @@ -89,6 +91,8 @@ int rtnl_rtntype_a2n(int *id, char *arg)
res = RTN_UNICAST; res = RTN_UNICAST;
else if (strcmp(arg, "throw") == 0) else if (strcmp(arg, "throw") == 0)
res = RTN_THROW; res = RTN_THROW;
@ -31,7 +31,7 @@ Subject: [PATCH] add support for dropping with FAILED_POLICY
if (!end || end == arg || *end || res > 255) if (!end || end == arg || *end || res > 255)
--- a/include/uapi/linux/rtnetlink.h --- a/include/uapi/linux/rtnetlink.h
+++ b/include/uapi/linux/rtnetlink.h +++ b/include/uapi/linux/rtnetlink.h
@@ -265,6 +265,7 @@ enum { @@ -256,6 +256,7 @@ enum {
RTN_THROW, /* Not in this table */ RTN_THROW, /* Not in this table */
RTN_NAT, /* Translate this address */ RTN_NAT, /* Translate this address */
RTN_XRESOLVE, /* Use external resolver */ RTN_XRESOLVE, /* Use external resolver */

View file

@ -1,6 +1,6 @@
--- a/configure --- a/configure
+++ b/configure +++ b/configure
@@ -241,7 +241,7 @@ int main(int argc, char **argv) { @@ -279,7 +279,7 @@ int main(int argc, char **argv) {
} }
EOF EOF
@ -9,7 +9,7 @@
local ret=$? local ret=$?
rm -f $TMPDIR/libbpf_test.c $TMPDIR/libbpf_test rm -f $TMPDIR/libbpf_test.c $TMPDIR/libbpf_test
@@ -259,7 +259,7 @@ int main(int argc, char **argv) { @@ -297,7 +297,7 @@ int main(int argc, char **argv) {
} }
EOF EOF

View file

@ -11,7 +11,7 @@
--- a/tc/Makefile --- a/tc/Makefile
+++ b/tc/Makefile +++ b/tc/Makefile
@@ -120,7 +120,7 @@ MODDESTDIR := $(DESTDIR)$(LIBDIR)/tc @@ -140,7 +140,7 @@ MODDESTDIR := $(DESTDIR)$(LIBDIR)/tc
$(QUIET_CC)$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -shared -fpic $< -o $@ $(QUIET_CC)$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -shared -fpic $< -o $@
@ -19,4 +19,4 @@
+all: $(findstring tc,$(BUILD_VARIANT)) $(TCSO) +all: $(findstring tc,$(BUILD_VARIANT)) $(TCSO)
tc: $(TCOBJ) $(LIBNETLINK) libtc.a tc: $(TCOBJ) $(LIBNETLINK) libtc.a
$(QUIET_LINK)$(CC) $^ $(LDFLAGS) $(LDLIBS) -o $@ $(QUIET_LINK)$(CC) $(filter-out dynsyms.list, $^) $(LDFLAGS) $(LDLIBS) -o $@

View file

@ -1,19 +0,0 @@
--- a/configure
+++ b/configure
@@ -413,14 +413,8 @@ EOF
if $CC -I$INCLUDE -o $TMPDIR/strtest $TMPDIR/strtest.c >/dev/null 2>&1; then
echo "no"
else
- if ${PKG_CONFIG} libbsd --exists; then
- echo 'CFLAGS += -DHAVE_LIBBSD' "$(${PKG_CONFIG} libbsd --cflags)" >>$CONFIG
- echo 'LDLIBS +=' "$(${PKG_CONFIG} libbsd --libs)" >> $CONFIG
- echo "no"
- else
- echo 'CFLAGS += -DNEED_STRLCPY' >>$CONFIG
- echo "yes"
- fi
+ echo 'CFLAGS += -DNEED_STRLCPY' >>$CONFIG
+ echo "yes"
fi
rm -f $TMPDIR/strtest.c $TMPDIR/strtest
}

View file

@ -1,6 +1,6 @@
--- a/configure --- a/configure
+++ b/configure +++ b/configure
@@ -342,7 +342,7 @@ check_libbpf() @@ -374,7 +374,7 @@ check_libbpf()
check_selinux() check_selinux()
# SELinux is a compile time option in the ss utility # SELinux is a compile time option in the ss utility
{ {

View file

@ -8,7 +8,6 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=libmbim PKG_NAME:=libmbim
PKG_VERSION:=1.31.6
PKG_SOURCE_VERSION:=1.31.6-dev PKG_SOURCE_VERSION:=1.31.6-dev
#PKG_SOURCE_VERSION:=1866ed53c05916c66c5d52682778a6078e5221d3 #PKG_SOURCE_VERSION:=1866ed53c05916c66c5d52682778a6078e5221d3
PKG_RELEASE:=1 PKG_RELEASE:=1

View file

@ -8,7 +8,7 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=libqmi PKG_NAME:=libqmi
PKG_VERSION:=1.35.6 #PKG_SOURCE_VERSION:=1.34.0
PKG_SOURCE_VERSION:=1.35.6-dev PKG_SOURCE_VERSION:=1.35.6-dev
PKG_RELEASE:=1 PKG_RELEASE:=1

View file

@ -6,11 +6,11 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
LUCI_TITLE:=Firewall and port forwarding application LUCI_TITLE:=Firewall and Portforwarding application
LUCI_DEPENDS:=+luci-base +uci-firewall LUCI_DEPENDS:=+@LINUX_5_4:firewall +@(LINUX_5_15||LINUX_6_1||LINUX_6_6||LINUX_6_7):uci-firewall
PKG_LICENSE:=Apache-2.0 PKG_LICENSE:=Apache-2.0
PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io> PKG_VERSION:=omr-202103
include $(TOPDIR)/feeds/luci/luci.mk include $(TOPDIR)/feeds/luci/luci.mk

View file

@ -6,7 +6,6 @@
'require form'; 'require form';
'require network'; 'require network';
'require firewall'; 'require firewall';
'require validation';
'require tools.prng as random'; 'require tools.prng as random';
var protocols = [ var protocols = [
@ -393,25 +392,12 @@ return baseclass.extend({
}, },
transformHostHints: function(family, hosts) { transformHostHints: function(family, hosts) {
var choice_values = [], var choice_values = [], choice_labels = {};
choice_labels = {},
ip6addrs = {},
ipaddrs = {};
for (var mac in hosts) {
L.toArray(hosts[mac].ipaddrs || hosts[mac].ipv4).forEach(function(ip) {
ipaddrs[ip] = mac;
});
L.toArray(hosts[mac].ip6addrs || hosts[mac].ipv6).forEach(function(ip) {
ip6addrs[ip] = mac;
});
}
if (!family || family == 'ipv4') { if (!family || family == 'ipv4') {
L.sortedKeys(ipaddrs, null, 'addr').forEach(function(ip) { L.sortedKeys(hosts, 'ipv4', 'addr').forEach(function(mac) {
var val = ip, var val = hosts[mac].ipv4,
txt = hosts[ipaddrs[ip]].name || ipaddrs[ip]; txt = hosts[mac].name || mac;
choice_values.push(val); choice_values.push(val);
choice_labels[val] = E([], [ val, ' (', E('strong', {}, [txt]), ')' ]); choice_labels[val] = E([], [ val, ' (', E('strong', {}, [txt]), ')' ]);
@ -419,9 +405,9 @@ return baseclass.extend({
} }
if (!family || family == 'ipv6') { if (!family || family == 'ipv6') {
L.sortedKeys(ip6addrs, null, 'addr').forEach(function(ip) { L.sortedKeys(hosts, 'ipv6', 'addr').forEach(function(mac) {
var val = ip, var val = hosts[mac].ipv6,
txt = hosts[ip6addrs[ip]].name || ip6addrs[ip]; txt = hosts[mac].name || mac;
choice_values.push(val); choice_values.push(val);
choice_labels[val] = E([], [ val, ' (', E('strong', {}, [txt]), ')' ]); choice_labels[val] = E([], [ val, ' (', E('strong', {}, [txt]), ')' ]);
@ -439,27 +425,11 @@ return baseclass.extend({
opt.addChoices(choices[0], choices[1]); opt.addChoices(choices[0], choices[1]);
}, },
CBIDynamicMultiValueList: form.DynamicList.extend({
renderWidget: function(/* ... */) {
var dl = form.DynamicList.prototype.renderWidget.apply(this, arguments),
inst = dom.findClassInstance(dl);
inst.addItem = function(dl, value, text, flash) {
var values = L.toArray(value);
for (var i = 0; i < values.length; i++)
ui.DynamicList.prototype.addItem.call(this, dl, values[i], null, true);
};
return dl;
}
}),
addIPOption: function(s, tab, name, label, description, family, hosts, multiple) { addIPOption: function(s, tab, name, label, description, family, hosts, multiple) {
var o = s.taboption(tab, multiple ? this.CBIDynamicMultiValueList : form.Value, name, label, description); var o = s.taboption(tab, multiple ? form.DynamicList : form.Value, name, label, description);
var fw4 = L.hasSystemFeature('firewall4');
o.modalonly = true; o.modalonly = true;
o.datatype = (fw4 && validation.types.iprange) ? 'list(neg(or(ipmask("true"),iprange)))' : 'list(neg(ipmask("true")))'; o.datatype = 'list(neg(ipmask))';
o.placeholder = multiple ? _('-- add IP --') : _('any'); o.placeholder = multiple ? _('-- add IP --') : _('any');
if (family != null) { if (family != null) {
@ -479,20 +449,18 @@ return baseclass.extend({
addLocalIPOption: function(s, tab, name, label, description, devices) { addLocalIPOption: function(s, tab, name, label, description, devices) {
var o = s.taboption(tab, form.Value, name, label, description); var o = s.taboption(tab, form.Value, name, label, description);
var fw4 = L.hasSystemFeature('firewall4');
o.modalonly = true; o.modalonly = true;
o.datatype = !fw4?'ip4addr("nomask")':'ipaddr("nomask")'; o.datatype = 'ip4addr("nomask")';
o.placeholder = _('any'); o.placeholder = _('any');
L.sortedKeys(devices, 'name').forEach(function(dev) { L.sortedKeys(devices, 'name').forEach(function(dev) {
var ip4addrs = devices[dev].ipaddrs; var ip4addrs = devices[dev].ipaddrs;
var ip6addrs = devices[dev].ip6addrs;
if (!L.isObject(devices[dev].flags) || devices[dev].flags.loopback) if (!L.isObject(devices[dev].flags) || !Array.isArray(ip4addrs) || devices[dev].flags.loopback)
return; return;
for (var i = 0; Array.isArray(ip4addrs) && i < ip4addrs.length; i++) { for (var i = 0; i < ip4addrs.length; i++) {
if (!L.isObject(ip4addrs[i]) || !ip4addrs[i].address) if (!L.isObject(ip4addrs[i]) || !ip4addrs[i].address)
continue; continue;
@ -500,21 +468,13 @@ return baseclass.extend({
ip4addrs[i].address, ' (', E('strong', {}, [dev]), ')' ip4addrs[i].address, ' (', E('strong', {}, [dev]), ')'
])); ]));
} }
for (var i = 0; fw4 && Array.isArray(ip6addrs) && i < ip6addrs.length; i++) {
if (!L.isObject(ip6addrs[i]) || !ip6addrs[i].address)
continue;
o.value(ip6addrs[i].address, E([], [
ip6addrs[i].address, ' (', E('strong', {}, [dev]), ')'
]));
}
}); });
return o; return o;
}, },
addMACOption: function(s, tab, name, label, description, hosts) { addMACOption: function(s, tab, name, label, description, hosts) {
var o = s.taboption(tab, this.CBIDynamicMultiValueList, name, label, description); var o = s.taboption(tab, form.DynamicList, name, label, description);
o.modalonly = true; o.modalonly = true;
o.datatype = 'list(macaddr)'; o.datatype = 'list(macaddr)';
@ -522,10 +482,7 @@ return baseclass.extend({
L.sortedKeys(hosts).forEach(function(mac) { L.sortedKeys(hosts).forEach(function(mac) {
o.value(mac, E([], [ mac, ' (', E('strong', {}, [ o.value(mac, E([], [ mac, ' (', E('strong', {}, [
hosts[mac].name || hosts[mac].name || hosts[mac].ipv4 || hosts[mac].ipv6 || '?'
L.toArray(hosts[mac].ipaddrs || hosts[mac].ipv4)[0] ||
L.toArray(hosts[mac].ip6addrs || hosts[mac].ipv6)[0] ||
'?'
]), ')' ])); ]), ')' ]));
}); });
@ -565,9 +522,6 @@ return baseclass.extend({
} }
}, this)); }, this));
if (cfgvalue == '*' || cfgvalue == 'any' || cfgvalue == 'all')
cfgvalue = 'all';
return cfgvalue; return cfgvalue;
}, },
@ -583,7 +537,6 @@ return baseclass.extend({
display_items: 10, display_items: 10,
dropdown_items: -1, dropdown_items: -1,
create: true, create: true,
disabled: (this.readonly != null) ? this.readonly : this.map.readonly,
validate: function(value) { validate: function(value) {
var v = L.toArray(value); var v = L.toArray(value);
@ -602,7 +555,8 @@ return baseclass.extend({
}); });
widget.createChoiceElement = function(sb, value) { widget.createChoiceElement = function(sb, value) {
var p = lookupProto(value); var m = value.match(/^(0x[0-9a-f]{1,2}|[0-9]{1,3})$/),
p = lookupProto(lookupProto(m ? +m[1] : value)[0]);
return ui.Dropdown.prototype.createChoiceElement.call(this, sb, p[2], p[1]); return ui.Dropdown.prototype.createChoiceElement.call(this, sb, p[2], p[1]);
}; };
@ -612,11 +566,9 @@ return baseclass.extend({
var m = value.match(/^(0x[0-9a-f]{1,2}|[0-9]{1,3})$/), var m = value.match(/^(0x[0-9a-f]{1,2}|[0-9]{1,3})$/),
p = lookupProto(m ? +m[1] : value); p = lookupProto(m ? +m[1] : value);
return (p[0] > -1) ? p[2] : p[1]; return (p[0] > -1) ? p[2] : value;
}); });
values.sort();
return ui.Dropdown.prototype.createItems.call(this, sb, values.join(' ')); return ui.Dropdown.prototype.createItems.call(this, sb, values.join(' '));
}; };

View file

@ -24,7 +24,7 @@ return view.extend({
return E([ return E([
E('h2', _('Firewall - Custom Rules')), E('h2', _('Firewall - Custom Rules')),
E('p', {}, _('Custom rules allow you to execute arbitrary iptables commands which are not otherwise covered by the firewall framework. The commands are executed after each firewall restart, right after the default ruleset has been loaded.')), E('p', {}, _('Custom rules allow you to execute arbitrary iptables commands which are not otherwise covered by the firewall framework. The commands are executed after each firewall restart, right after the default ruleset has been loaded.')),
E('p', {}, E('textarea', { 'style': 'width:100%', 'rows': 25 }, [ fwuser != null ? fwuser : '' ])) E('p', {}, E('textarea', { 'style': 'width:100%', 'rows': 10 }, [ fwuser != null ? fwuser : '' ]))
]); ]);
}, },

View file

@ -9,8 +9,6 @@
'require tools.widgets as widgets'; 'require tools.widgets as widgets';
function rule_proto_txt(s, ctHelpers) { function rule_proto_txt(s, ctHelpers) {
var family = (uci.get('firewall', s, 'family') || '').toLowerCase().replace(/^(?:all|\*)$/, 'any');
var dip = uci.get('firewall', s, 'dest_ip') || '';
var proto = L.toArray(uci.get('firewall', s, 'proto')).filter(function(p) { var proto = L.toArray(uci.get('firewall', s, 'proto')).filter(function(p) {
return (p != '*' && p != 'any' && p != 'all'); return (p != '*' && p != 'any' && p != 'all');
}).map(function(p) { }).map(function(p) {
@ -22,7 +20,7 @@ function rule_proto_txt(s, ctHelpers) {
}; };
}); });
var m = String(uci.get('firewall', s, 'helper') || '').match(/^(!\s*)?(\S+)$/); m = String(uci.get('firewall', s, 'helper') || '').match(/^(!\s*)?(\S+)$/);
var h = m ? { var h = m ? {
val: m[0].toUpperCase(), val: m[0].toUpperCase(),
inv: m[1], inv: m[1],
@ -37,9 +35,7 @@ function rule_proto_txt(s, ctHelpers) {
mask: m[3] ? '0x%02X'.format(+m[3]) : null mask: m[3] ? '0x%02X'.format(+m[3]) : null
} : null; } : null;
return fwtool.fmt(_('Incoming %{ipv6?%{ipv4?<var>IPv4</var> and <var>IPv6</var>:<var>IPv6</var>}:<var>IPv4</var>}%{proto?, protocol %{proto#%{next?, }%{item.types?<var class="cbi-tooltip-container">%{item.name}<span class="cbi-tooltip">ICMP with types %{item.types#%{next?, }<var>%{item}</var>}</span></var>:<var>%{item.name}</var>}}}%{mark?, mark <var%{mark.inv? data-tooltip="Match fwmarks except %{mark.num}%{mark.mask? with mask %{mark.mask}}.":%{mark.mask? data-tooltip="Mask fwmark value with %{mark.mask} before compare."}}>%{mark.val}</var>}%{helper?, helper %{helper.inv?<var data-tooltip="Match any helper except &quot;%{helper.name}&quot;">%{helper.val}</var>:<var data-tooltip="%{helper.name}">%{helper.val}</var>}}'), { return fwtool.fmt(_('Incoming IPv4%{proto?, protocol %{proto#%{next?, }%{item.types?<var class="cbi-tooltip-container">%{item.name}<span class="cbi-tooltip">ICMP with types %{item.types#%{next?, }<var>%{item}</var>}</span></var>:<var>%{item.name}</var>}}}%{mark?, mark <var%{mark.inv? data-tooltip="Match fwmarks except %{mark.num}%{mark.mask? with mask %{mark.mask}}.":%{mark.mask? data-tooltip="Mask fwmark value with %{mark.mask} before compare."}}>%{mark.val}</var>}%{helper?, helper %{helper.inv?<var data-tooltip="Match any helper except &quot;%{helper.name}&quot;">%{helper.val}</var>:<var data-tooltip="%{helper.name}">%{helper.val}</var>}}'), {
ipv4: ((!family && dip.indexOf(':') == -1) || family == 'any' || (!family && !dip) || family == 'ipv4'),
ipv6: ((!family && dip.indexOf(':') != -1) || family == 'any' || family == 'ipv6'),
proto: proto, proto: proto,
helper: h, helper: h,
mark: f mark: f
@ -50,7 +46,7 @@ function rule_src_txt(s, hosts) {
var z = uci.get('firewall', s, 'src'); var z = uci.get('firewall', s, 'src');
return fwtool.fmt(_('From %{src}%{src_ip?, IP %{src_ip#%{next?, }<var%{item.inv? data-tooltip="Match IP addresses except %{item.val}."}>%{item.ival}</var>}}%{src_port?, port %{src_port#%{next?, }<var%{item.inv? data-tooltip="Match ports except %{item.val}."}>%{item.ival}</var>}}%{src_mac?, MAC %{src_mac#%{next?, }<var%{item.inv? data-tooltip="Match MACs except %{item.val}%{item.hint.name? a.k.a. %{item.hint.name}}.":%{item.hint.name? data-tooltip="%{item.hint.name}"}}>%{item.ival}</var>}}'), { return fwtool.fmt(_('From %{src}%{src_ip?, IP %{src_ip#%{next?, }<var%{item.inv? data-tooltip="Match IP addresses except %{item.val}."}>%{item.ival}</var>}}%{src_port?, port %{src_port#%{next?, }<var%{item.inv? data-tooltip="Match ports except %{item.val}."}>%{item.ival}</var>}}%{src_mac?, MAC %{src_mac#%{next?, }<var%{item.inv? data-tooltip="Match MACs except %{item.val}%{item.hint.name? a.k.a. %{item.hint.name}}.":%{item.hint.name? data-tooltip="%{item.hint.name}"}}>%{item.ival}</var>}}'), {
src: E('span', { 'class': 'zonebadge', 'style': fwmodel.getZoneColorStyle(z) }, [(z == '*') ? E('em', _('any zone')) : (z ? E('strong', z) : E('em', _('this device')))]), src: E('span', { 'class': 'zonebadge', 'style': 'background-color:' + fwmodel.getColorForName((z && z != '*') ? z : null) }, [(z == '*') ? E('em', _('any zone')) : (z || E('em', _('this device')))]),
src_ip: fwtool.map_invert(uci.get('firewall', s, 'src_ip'), 'toLowerCase'), src_ip: fwtool.map_invert(uci.get('firewall', s, 'src_ip'), 'toLowerCase'),
src_mac: fwtool.map_invert(uci.get('firewall', s, 'src_mac'), 'toUpperCase').map(function(v) { return Object.assign(v, { hint: hosts[v.val] }) }), src_mac: fwtool.map_invert(uci.get('firewall', s, 'src_mac'), 'toUpperCase').map(function(v) { return Object.assign(v, { hint: hosts[v.val] }) }),
src_port: fwtool.map_invert(uci.get('firewall', s, 'src_port')) src_port: fwtool.map_invert(uci.get('firewall', s, 'src_port'))
@ -59,7 +55,7 @@ function rule_src_txt(s, hosts) {
function rule_dest_txt(s) { function rule_dest_txt(s) {
return fwtool.fmt(_('To %{dest}%{dest_ip?, IP %{dest_ip#%{next?, }<var%{item.inv? data-tooltip="Match IP addresses except %{item.val}."}>%{item.ival}</var>}}%{dest_port?, port %{dest_port#%{next?, }<var%{item.inv? data-tooltip="Match ports except %{item.val}."}>%{item.ival}</var>}}'), { return fwtool.fmt(_('To %{dest}%{dest_ip?, IP %{dest_ip#%{next?, }<var%{item.inv? data-tooltip="Match IP addresses except %{item.val}."}>%{item.ival}</var>}}%{dest_port?, port %{dest_port#%{next?, }<var%{item.inv? data-tooltip="Match ports except %{item.val}."}>%{item.ival}</var>}}'), {
dest: E('span', { 'class': 'zonebadge', 'style': fwmodel.getZoneColorStyle(null) }, [E('em', _('this device'))]), dest: E('span', { 'class': 'zonebadge', 'style': 'background-color:' + fwmodel.getColorForName(null) }, [E('em', _('this device'))]),
dest_ip: fwtool.map_invert(uci.get('firewall', s, 'src_dip'), 'toLowerCase'), dest_ip: fwtool.map_invert(uci.get('firewall', s, 'src_dip'), 'toLowerCase'),
dest_port: fwtool.map_invert(uci.get('firewall', s, 'src_dport')) dest_port: fwtool.map_invert(uci.get('firewall', s, 'src_dport'))
}); });
@ -83,30 +79,12 @@ function rule_target_txt(s) {
var z = uci.get('firewall', s, 'dest'); var z = uci.get('firewall', s, 'dest');
return fwtool.fmt(_('<var data-tooltip="DNAT">Forward</var> to %{dest}%{dest_ip? IP <var>%{dest_ip}</var>}%{dest_port? port <var>%{dest_port}</var>}'), { return fwtool.fmt(_('<var data-tooltip="DNAT">Forward</var> to %{dest}%{dest_ip? IP <var>%{dest_ip}</var>}%{dest_port? port <var>%{dest_port}</var>}'), {
dest: E('span', { 'class': 'zonebadge', 'style': 'background-color:' + fwmodel.getColorForName((z && z != '*') ? z : null) }, [(z == '*') ? E('em', _('any zone')) : (z ? E('strong', z) : E('em', _('this device')))]), dest: E('span', { 'class': 'zonebadge', 'style': 'background-color:' + fwmodel.getColorForName((z && z != '*') ? z : null) }, [(z == '*') ? E('em', _('any zone')) : (z || E('em', _('this device')))]),
dest_ip: (uci.get('firewall', s, 'dest_ip') || '').toLowerCase(), dest_ip: (uci.get('firewall', s, 'dest_ip') || '').toLowerCase(),
dest_port: uci.get('firewall', s, 'dest_port') dest_port: uci.get('firewall', s, 'dest_port')
}); });
} }
function validate_opt_family(m, section_id, opt) {
var dopt = m.section.getOption('dest_ip'),
fmopt = m.section.getOption('family');
if (!dopt.isValid(section_id) && opt != 'dest_ip')
return true;
if (!fmopt.isValid(section_id) && opt != 'family')
return true;
var dip = dopt.formvalue(section_id) || '',
fm = fmopt.formvalue(section_id) || '';
if (fm == '' || (fm == 'any' && dip == '') || (fm == 'ipv6' && (dip.indexOf(':') != -1 || dip == '')) || (fm == 'ipv4' && dip.indexOf(':') == -1))
return true;
return _('Address family, Internal IP address must match');
}
return view.extend({ return view.extend({
callHostHints: rpc.declare({ callHostHints: rpc.declare({
object: 'luci-rpc', object: 'luci-rpc',
@ -147,7 +125,6 @@ return view.extend({
ctHelpers = data[1], ctHelpers = data[1],
devs = data[2], devs = data[2],
m, s, o; m, s, o;
var fw4 = L.hasSystemFeature('firewall4');
m = new form.Map('firewall', _('Firewall - Port Forwards'), m = new form.Map('firewall', _('Firewall - Port Forwards'),
_('Port forwarding allows remote computers on the Internet to connect to a specific computer or service within the private LAN.')); _('Port forwarding allows remote computers on the Internet to connect to a specific computer or service within the private LAN.'));
@ -156,7 +133,6 @@ return view.extend({
s.addremove = true; s.addremove = true;
s.anonymous = true; s.anonymous = true;
s.sortable = true; s.sortable = true;
s.cloneable = true;
s.tab('general', _('General Settings')); s.tab('general', _('General Settings'));
s.tab('advanced', _('Advanced Settings')); s.tab('advanced', _('Advanced Settings'));
@ -173,10 +149,9 @@ return view.extend({
var config_name = this.uciconfig || this.map.config, var config_name = this.uciconfig || this.map.config,
section_id = uci.add(config_name, this.sectiontype); section_id = uci.add(config_name, this.sectiontype);
uci.set(config_name, section_id, 'dest', 'lan');
uci.set(config_name, section_id, 'target', 'DNAT'); uci.set(config_name, section_id, 'target', 'DNAT');
m.addedSection = section_id; this.addedSection = section_id;
this.renderMoreOptionsModal(section_id); this.renderMoreOptionsModal(section_id);
}; };
@ -184,32 +159,6 @@ return view.extend({
o.placeholder = _('Unnamed forward'); o.placeholder = _('Unnamed forward');
o.modalonly = true; o.modalonly = true;
if (fw4) {
o = s.taboption('general', form.ListValue, 'family', _('Restrict to address family'));
o.modalonly = true;
o.rmempty = true;
o.value('any', _('IPv4 and IPv6'));
o.value('ipv4', _('IPv4 only'));
o.value('ipv6', _('IPv6 only'));
o.value('', _('automatic')); // infer from zone or used IP addresses
o.cfgvalue = function(section_id) {
var val = this.map.data.get(this.map.config, section_id, 'family');
if (!val)
return '';
else if (val == 'any' || val == 'all' || val == '*')
return 'any';
else if (val == 'inet' || String(val).indexOf('4') != -1)
return 'ipv4';
else if (String(val).indexOf('6') != -1)
return 'ipv6';
};
o.validate = function(section_id, value) {
fwtool.updateHostHints(this.map, section_id, 'dest_ip', value, hosts);
return !fw4?true:validate_opt_family(this, section_id, 'family');
};
}
o = s.option(form.DummyValue, '_match', _('Match')); o = s.option(form.DummyValue, '_match', _('Match'));
o.modalonly = false; o.modalonly = false;
o.textvalue = function(s) { o.textvalue = function(s) {
@ -244,23 +193,15 @@ return view.extend({
o.nocreate = true; o.nocreate = true;
o.default = 'wan'; o.default = 'wan';
o = s.taboption('advanced', form.Value, 'ipset', _('Use ipset'));
uci.sections('firewall', 'ipset', function(s) {
if (typeof(s.name) == 'string')
o.value(s.name, s.comment ? '%s (%s)'.format(s.name, s.comment) : s.name);
});
o.modalonly = true;
o.rmempty = true;
o = fwtool.addMACOption(s, 'advanced', 'src_mac', _('Source MAC address'), o = fwtool.addMACOption(s, 'advanced', 'src_mac', _('Source MAC address'),
_('Only match incoming traffic from these MACs.'), hosts); _('Only match incoming traffic from these MACs.'), hosts);
o.rmempty = true; o.rmempty = true;
o.datatype = 'list(neg(macaddr))'; o.datatype = 'list(neg(macaddr))';
o = fwtool.addIPOption(s, 'advanced', 'src_ip', _('Source IP address'), o = fwtool.addIPOption(s, 'advanced', 'src_ip', _('Source IP address'),
_('Only match incoming traffic from this IP or range.'), !fw4?'ipv4':'', hosts); _('Only match incoming traffic from this IP or range.'), 'ipv4', hosts);
o.rmempty = true; o.rmempty = true;
o.datatype = !fw4?'neg(ipmask4("true"))':'neg(ipmask("true"))'; o.datatype = 'neg(ipmask4)';
o = s.taboption('advanced', form.Value, 'src_port', _('Source port'), o = s.taboption('advanced', form.Value, 'src_port', _('Source port'),
_('Only match incoming traffic originating from the given source port or port range on the client host')); _('Only match incoming traffic originating from the given source port or port range on the client host'));
@ -273,7 +214,7 @@ return view.extend({
o = fwtool.addLocalIPOption(s, 'advanced', 'src_dip', _('External IP address'), o = fwtool.addLocalIPOption(s, 'advanced', 'src_dip', _('External IP address'),
_('Only match incoming traffic directed at the given IP address.'), devs); _('Only match incoming traffic directed at the given IP address.'), devs);
o.datatype = !fw4?'neg(ipmask4("true"))':'neg(ipmask("true"))'; o.datatype = 'neg(ipmask4)';
o.rmempty = true; o.rmempty = true;
o = s.taboption('general', form.Value, 'src_dport', _('External port'), o = s.taboption('general', form.Value, 'src_dport', _('External port'),
@ -288,11 +229,12 @@ return view.extend({
o.modalonly = true; o.modalonly = true;
o.rmempty = true; o.rmempty = true;
o.nocreate = true; o.nocreate = true;
o.default = 'lan';
o = fwtool.addIPOption(s, 'general', 'dest_ip', _('Internal IP address'), o = fwtool.addIPOption(s, 'general', 'dest_ip', _('Internal IP address'),
_('Redirect matched incoming traffic to the specified internal host'), !fw4?'ipv4':'', hosts); _('Redirect matched incoming traffic to the specified internal host'), 'ipv4', hosts);
o.rmempty = true; o.rmempty = true;
o.datatype = !fw4?'ipmask4':'ipmask'; o.datatype = 'ipmask4';
o = s.taboption('general', form.Value, 'dest_port', _('Internal port'), o = s.taboption('general', form.Value, 'dest_port', _('Internal port'),
_('Redirect matched incoming traffic to the given port on the internal host')); _('Redirect matched incoming traffic to the given port on the internal host'));
@ -317,12 +259,6 @@ return view.extend({
uci.set('firewall', section_id, 'reflection_src', (value != 'internal') ? value : null); uci.set('firewall', section_id, 'reflection_src', (value != 'internal') ? value : null);
}; };
o = s.taboption('advanced', widgets.ZoneSelect, 'reflection_zone', _('Reflection zones'), _('Zones from which reflection rules shall be created. If unset, only the destination zone is used.'));
o.nocreate = true;
o.multiple = true;
o.modalonly = true;
o.depends('reflection', '1');
o = s.taboption('advanced', form.Value, 'helper', _('Match helper'), _('Match traffic using the specified connection tracking helper.')); o = s.taboption('advanced', form.Value, 'helper', _('Match helper'), _('Match traffic using the specified connection tracking helper.'));
o.modalonly = true; o.modalonly = true;
o.placeholder = _('any'); o.placeholder = _('any');
@ -348,13 +284,13 @@ return view.extend({
o = s.taboption('advanced', form.Flag, 'v2ray', _('Use V2Ray/XRay'), o = s.taboption('advanced', form.Flag, 'v2ray', _('Use V2Ray/XRay'),
_('Forward a port (not a range) from server using V2Ray/XRay proxy (if enabled) instead of VPN')); _('Forward a port (not a range) from server using V2Ray/XRay proxy (if enabled) instead of VPN'));
o.modalonly = true; o.modalonly = true;
o.editable = true;
o.depends({ src: 'vpn', '!contains': true });
if (!L.hasSystemFeature('firewall4')) {
o = s.taboption('advanced', form.Value, 'extra', _('Extra arguments'), o = s.taboption('advanced', form.Value, 'extra', _('Extra arguments'),
_('Passes additional arguments to iptables. Use with care!')); _('Passes additional arguments to iptables. Use with care!'));
o.modalonly = true; o.modalonly = true;
o.rmempty = true; o.rmempty = true;
}
return m.render(); return m.render();
} }

View file

@ -1,222 +0,0 @@
'use strict';
'require view';
'require uci';
'require form';
'require firewall';
'require tools.firewall as fwtool';
return view.extend({
load: function() {
return Promise.all([
uci.load('firewall')
]);
},
render: function(data) {
let m, s, o;
m = new form.Map('firewall', _('Firewall - IP sets'),
_('firewall4 supports referencing and creating IP sets to simplify matching of large address lists without the need to create one rule per item to match. Port ranges in ipsets are unsupported by firewall4.<br />'));
var have_fw4 = L.hasSystemFeature('firewall4');
if (have_fw4) {
s = m.section(form.NamedSection, 'fwver', 'fwver', '', _('Your device runs firewall4.'));
} else {
s = m.section(form.NamedSection, 'fwver', 'fwver', '', _('Your device does not run firewall4.'));
}
s = m.section(form.GridSection, 'ipset', _('IP Sets'));
s.addremove = true;
s.anonymous = true;
s.sortable = true;
s.cloneable = true;
s.nodescriptions = true;
s.filter = function(section_id) {
return (section_id.startsWith('bypass') == false && section_id.startsWith('omr_dst') == false && section_id.startsWith('omr_dscp') == false);
};
/* refer to: https://ipset.netfilter.org/ipset.man.html */
if (have_fw4) {
o = s.option(form.Value, 'name', _('Name'));
o.optional = false;
o.rmempty = false;
o.validate = function (section_id, value) {
if (!/^[a-zA-Z_.][a-zA-Z0-9\/_.-]*$/.test(value))
return _('Invalid set name');
return true;
};
} else {
o = s.option(form.Value, 'name', _('Name'));
o.depends({ external: '' });
/* Default: (none) if external is unset
value of external if external is set */
}
o.placeholder = _('Unnamed set');
/* comment requires https://git.openwrt.org/?p=project/firewall4.git;a=commitdiff;h=39e8c70957c795bf0c12f04299170ae86c6efdf8 */
o = s.option(form.Value, 'comment', _('Comment'));
o.placeholder = _('Comment');
o.modalonly = true;
o.rmempty = true;
o = s.option(form.ListValue, 'family', _('Family'));
o.value('ipv4', _('IPv4'));
o.value('ipv6', _('IPv6'));
o.default = _('ipv4');
/* Direction src, dst; (Data)Types: ip, port, mac, net or set
Tuples: direction_datatype e.g. src_port, dest_net */
o = s.option(form.DynamicList, 'match', _('Packet Field Match'),
_('Packet fields to match upon.<br />' +
'Syntax: <em>direction_datatype</em>. e.g.: <code>src_port, dest_net</code>.<br />' +
'Directions: <code>src, dst</code>. Datatypes: <code>ip, port, mac, net, set</code>.<br />' +
'Direction prefixes are optional.<br />' +
'*Note: datatype <code>set</code> is unsupported in fw4.'));
o.value('ip', _('ip: IP addr'));
o.value('port', _('port: Port'));
o.value('mac', _('mac: MAC addr'));
o.value('net', _('net: (sub)net'));
if (!have_fw4)
o.value('set', _('set: ipset*'));
o.value('src_ip', _('src_ip: Source IP'));
o.value('src_port', _('src_port: Source Port'));
o.value('src_mac', _('src_mac: Source MAC addr'));
o.value('src_net', _('src_net: Source (sub)net'));
if (!have_fw4)
o.value('src_set', _('src_Set: Source ipset*')); // fw4 unsupported
o.value('dest_ip', _('dest_ip: Destination IP'));
o.value('dest_port', _('dest_port: Destination Port'));
o.value('dest_mac', _('dest_mac: Destination MAC addr'));
o.value('dest_net', _('dest_net: Destination (sub)net'));
if (!have_fw4)
o.value('dest_set', _('dest_set: Destination ipset*')); // fw4 unsupported
o.optional = false;
o.rmempty = false;
// TODO: if/when firewall5 arrives, this 'else' check must change.
if (have_fw4) {
//we have fw4
o = s.option(form.DynamicList, 'entry', _('IPs/Networks/MACs'),
_('macaddr|ip[/cidr]<br />'));
o.datatype = 'or(ipaddr,macaddr)';
o.rmempty = true;
o = s.option(form.Value, 'maxelem', _('Max Entries'),
_('up to 65536 entries.'));
o.datatype = 'port'; //covers 16 bit size
o.modalonly = true;
o.rmempty = true;
} else {
// this else section is intended to handle firewall3
o = s.option(form.Value, 'external', _('Refer To External Set'));
/* Todo: loop to fill o.values with all other ipset names except itself */
o.rmempty = true;
o.optional = true;
/* 'storage' depends on fw3. It must be removed for fw4 */
//aka 'method' in netfilter terminology.
o = s.option(form.ListValue, 'storage', _('Storage Method'));
o.value('bitmap', _('bitmap')); //ipv4 only
o.value('hash', _('hash'));
o.value('list', _('list'));
o.validate = function(section_id, value) {
var family = this.section.formvalue(section_id, 'family');
if (value.match(/bitmap/) && !family.match(/ipv4/))
return _('bitmap is ipv4 only');
return true;
}
/* this iprange differs from netfilters range fromip-toip|ip/cidr:
uci enforces a datatype = cidr in order to be able to enter
an IP for all storage/data types. */
o = s.option(form.Value, 'iprange', _('IP (range)'),
_('ip[/cidr]<br />'+
'For use with Match datatypes: <code>*_ip</code>.'));
o.datatype = 'ipaddr';
o.depends({family: 'ipv4', storage: 'bitmap', match: /_ip|_mac/ });
o.depends({storage: 'hash', match: /_ip/ });
o = s.option(form.DynamicList, 'entry', _('IPs/Networks'),
_('ip[/cidr]<br />'));
o.datatype = 'or(ipaddr,macaddr)';
o.depends({storage: 'hash', match: /_ip|_net|_mac/ });
o = s.option(form.Value, 'portrange', _('Port range'),
_('fromport-toport'));
o.datatype = 'neg(portrange)';
o.depends({family: 'ipv4', storage: 'bitmap', match: /_port/ });
o.depends({family: 'ipv4', storage: 'hash', match: /_port/ });
o.depends({family: 'ipv6', storage: 'hash', match: /_port/ });
o = s.option(form.Value, 'netmask', _('Netmask'));
o.datatype = 'or(ip4prefix,ip6prefix)';
o.depends({family: 'ipv4', storage: 'bitmap', match: /_ip/ });
o.depends({storage: 'hash', match: /_ip/});
o = s.option(form.Value, 'maxelem', _('Max Length'),
_('up to 65536 entries.'));
o.datatype = 'port'; //covers 16 bit size
o.depends('storage', 'hash');
o.depends('storage', 'list');
o.modalonly = true;
o = s.option(form.Value, 'hashsize', _('Initial Hash Size'));
o.depends('storage', 'hash');
o.placeholder = _('1024');
o.modalonly = true;
}
o = s.option(form.FileUpload, 'loadfile', _('Include File'),
_('Path to file of CIDRs, subnets, host IPs, etc.<br />'));
o.root_directory = '/etc/luci-uploads';
o.enable_delete = true;
o.enable_upload = true;
o.datatype = 'file';
o.rmempty = true;
o = s.option(form.Value, 'timeout', _('Timeout'),
_('Unit: seconds. Default <code>0</code> means the entry is added permanently to the set.<br />' +
'Max: 2147483 seconds.'));
o.placeholder = _('0');
o.modalonly = true;
o.rmempty = true;
o = s.option(form.Flag, 'counters', _('Counters'),
_('Enables packet and byte count tracking for the set.'));
o.modalonly = true;
o.rmempty = true;
o.default = false;
o = s.option(form.Flag, 'enabled', _('Enabled'));
o.default = true;
o.editable = true;
o.modalonly = false;
return m.render();
}
});

View file

@ -22,7 +22,7 @@ function rule_proto_txt(s, ctHelpers) {
}; };
}); });
var m = String(uci.get('firewall', s, 'helper') || '').match(/^(!\s*)?(\S+)$/); m = String(uci.get('firewall', s, 'helper') || '').match(/^(!\s*)?(\S+)$/);
var h = m ? { var h = m ? {
val: m[0].toUpperCase(), val: m[0].toUpperCase(),
inv: m[1], inv: m[1],
@ -62,7 +62,7 @@ function rule_src_txt(s, hosts) {
d = (uci.get('firewall', s, 'direction') == 'in') ? uci.get('firewall', s, 'device') : null; d = (uci.get('firewall', s, 'direction') == 'in') ? uci.get('firewall', s, 'device') : null;
return fwtool.fmt(_('From %{src}%{src_device?, interface <var>%{src_device}</var>}%{src_ip?, IP %{src_ip#%{next?, }<var%{item.inv? data-tooltip="Match IP addresses except %{item.val}."}>%{item.ival}</var>}}%{src_port?, port %{src_port#%{next?, }<var%{item.inv? data-tooltip="Match ports except %{item.val}."}>%{item.ival}</var>}}%{src_mac?, MAC %{src_mac#%{next?, }<var%{item.inv? data-tooltip="Match MACs except %{item.val}%{item.hint.name? a.k.a. %{item.hint.name}}.":%{item.hint.name? data-tooltip="%{item.hint.name}"}}>%{item.ival}</var>}}'), { return fwtool.fmt(_('From %{src}%{src_device?, interface <var>%{src_device}</var>}%{src_ip?, IP %{src_ip#%{next?, }<var%{item.inv? data-tooltip="Match IP addresses except %{item.val}."}>%{item.ival}</var>}}%{src_port?, port %{src_port#%{next?, }<var%{item.inv? data-tooltip="Match ports except %{item.val}."}>%{item.ival}</var>}}%{src_mac?, MAC %{src_mac#%{next?, }<var%{item.inv? data-tooltip="Match MACs except %{item.val}%{item.hint.name? a.k.a. %{item.hint.name}}.":%{item.hint.name? data-tooltip="%{item.hint.name}"}}>%{item.ival}</var>}}'), {
src: E('span', { 'class': 'zonebadge', 'style': fwmodel.getZoneColorStyle(z) }, [(z == '*') ? E('em', _('any zone')) : (z ? E('strong', z) : E('em', _('this device')))]), src: E('span', { 'class': 'zonebadge', 'style': 'background-color:' + fwmodel.getColorForName((z && z != '*') ? z : null) }, [(z == '*') ? E('em', _('any zone')) : (z || E('em', _('this device')))]),
src_ip: fwtool.map_invert(uci.get('firewall', s, 'src_ip'), 'toLowerCase'), src_ip: fwtool.map_invert(uci.get('firewall', s, 'src_ip'), 'toLowerCase'),
src_mac: fwtool.map_invert(uci.get('firewall', s, 'src_mac'), 'toUpperCase').map(function(v) { return Object.assign(v, { hint: hosts[v.val] }) }), src_mac: fwtool.map_invert(uci.get('firewall', s, 'src_mac'), 'toUpperCase').map(function(v) { return Object.assign(v, { hint: hosts[v.val] }) }),
src_port: fwtool.map_invert(uci.get('firewall', s, 'src_port')), src_port: fwtool.map_invert(uci.get('firewall', s, 'src_port')),
@ -75,7 +75,7 @@ function rule_dest_txt(s) {
d = (uci.get('firewall', s, 'direction') == 'out') ? uci.get('firewall', s, 'device') : null; d = (uci.get('firewall', s, 'direction') == 'out') ? uci.get('firewall', s, 'device') : null;
return fwtool.fmt(_('To %{dest}%{dest_device?, interface <var>%{dest_device}</var>}%{dest_ip?, IP %{dest_ip#%{next?, }<var%{item.inv? data-tooltip="Match IP addresses except %{item.val}."}>%{item.ival}</var>}}%{dest_port?, port %{dest_port#%{next?, }<var%{item.inv? data-tooltip="Match ports except %{item.val}."}>%{item.ival}</var>}}'), { return fwtool.fmt(_('To %{dest}%{dest_device?, interface <var>%{dest_device}</var>}%{dest_ip?, IP %{dest_ip#%{next?, }<var%{item.inv? data-tooltip="Match IP addresses except %{item.val}."}>%{item.ival}</var>}}%{dest_port?, port %{dest_port#%{next?, }<var%{item.inv? data-tooltip="Match ports except %{item.val}."}>%{item.ival}</var>}}'), {
dest: E('span', { 'class': 'zonebadge', 'style': fwmodel.getZoneColorStyle(z) }, [(z == '*') ? E('em', _('any zone')) : (z ? E('strong', z) : E('em', _('this device')))]), dest: E('span', { 'class': 'zonebadge', 'style': 'background-color:' + fwmodel.getColorForName((z && z != '*') ? z : null) }, [(z == '*') ? E('em', _('any zone')) : (z || E('em', _('this device')))]),
dest_ip: fwtool.map_invert(uci.get('firewall', s, 'dest_ip'), 'toLowerCase'), dest_ip: fwtool.map_invert(uci.get('firewall', s, 'dest_ip'), 'toLowerCase'),
dest_port: fwtool.map_invert(uci.get('firewall', s, 'dest_port')), dest_port: fwtool.map_invert(uci.get('firewall', s, 'dest_port')),
dest_device: d dest_device: d
@ -171,13 +171,12 @@ return view.extend({
m, s, o; m, s, o;
m = new form.Map('firewall', _('Firewall - Traffic Rules'), m = new form.Map('firewall', _('Firewall - Traffic Rules'),
_('Traffic rules define policies for packets travelling between different zones, for example to reject traffic between certain hosts or to open WAN ports on the router.')); _('Traffic rules define policies for packets traveling between different zones, for example to reject traffic between certain hosts or to open WAN ports on the router.'));
s = m.section(form.GridSection, 'rule', _('Traffic Rules')); s = m.section(form.GridSection, 'rule', _('Traffic Rules'));
s.addremove = true; s.addremove = true;
s.anonymous = true; s.anonymous = true;
s.sortable = true; s.sortable = true;
s.cloneable = true;
s.tab('general', _('General Settings')); s.tab('general', _('General Settings'));
s.tab('advanced', _('Advanced Settings')); s.tab('advanced', _('Advanced Settings'));
@ -195,8 +194,13 @@ return view.extend({
s.handleAdd = function(ev) { s.handleAdd = function(ev) {
var config_name = this.uciconfig || this.map.config, var config_name = this.uciconfig || this.map.config,
section_id = uci.add(config_name, this.sectiontype), section_id = uci.add(config_name, this.sectiontype),
opt1 = this.getOption('src'), opt1, opt2;
opt2 = this.getOption('dest');
for (var i = 0; i < this.children.length; i++)
if (this.children[i].option == 'src')
opt1 = this.children[i];
else if (this.children[i].option == 'dest')
opt2 = this.children[i];
opt1.default = 'wan'; opt1.default = 'wan';
opt2.default = 'lan'; opt2.default = 'lan';
@ -233,19 +237,7 @@ return view.extend({
o.modalonly = false; o.modalonly = false;
o.default = o.enabled; o.default = o.enabled;
o.editable = true; o.editable = true;
o.tooltip = function(section_id) {
var weekdays = uci.get('firewall', section_id, 'weekdays');
var monthdays = uci.get('firewall', section_id, 'monthdays');
var start_time = uci.get('firewall', section_id, 'start_time');
var stop_time = uci.get('firewall', section_id, 'stop_time');
var start_date = uci.get('firewall', section_id, 'start_date');
var stop_date = uci.get('firewall', section_id, 'stop_date');
if (weekdays || monthdays || start_time || stop_time || start_date || stop_date )
return _('Time restrictions are enabled for this rule');
return null;
};
o = s.taboption('advanced', form.ListValue, 'direction', _('Match device')); o = s.taboption('advanced', form.ListValue, 'direction', _('Match device'));
o.modalonly = true; o.modalonly = true;
@ -296,52 +288,27 @@ return view.extend({
o.multiple = true; o.multiple = true;
o.custom = true; o.custom = true;
o.cast = 'table'; o.cast = 'table';
o.placeholder = _('any/all'); o.placeholder = _('any');
o.value('', 'any');
o.value('address-mask-reply'); o.value('address-mask-reply');
o.value('address-mask-request'); o.value('address-mask-request');
o.value('address-unreachable'); /* icmpv6 1:3 */
o.value('bad-header'); /* icmpv6 4:0 */
o.value('certification-path-solicitation-message'); /* icmpv6 148 */
o.value('certification-path-advertisement-message'); /* icmpv6 149 */
o.value('communication-prohibited'); o.value('communication-prohibited');
o.value('destination-unreachable'); o.value('destination-unreachable');
o.value('duplicate-address-request'); /* icmpv6 157 */
o.value('duplicate-address-confirmation'); /* icmpv6 158 */
o.value('echo-reply'); o.value('echo-reply');
o.value('echo-request'); o.value('echo-request');
o.value('extended-echo-request'); /* icmpv6 160 */
o.value('extended-echo-reply'); /* icmpv6 161 */
o.value('fmipv6-message'); /* icmpv6 154 */
o.value('fragmentation-needed'); o.value('fragmentation-needed');
o.value('home-agent-address-discovery-reply-message'); /* icmpv6 145 */
o.value('home-agent-address-discovery-request-message'); /* icmpv6 144 */
o.value('host-precedence-violation'); o.value('host-precedence-violation');
o.value('host-prohibited'); o.value('host-prohibited');
o.value('host-redirect'); o.value('host-redirect');
o.value('host-unknown'); o.value('host-unknown');
o.value('host-unreachable'); o.value('host-unreachable');
o.value('ilnpv6-locator-update-message'); /* icmpv6 156 */
o.value('inverse-neighbour-discovery-advertisement-message'); /* icmpv6 142 */
o.value('inverse-neighbour-discovery-solicitation-message'); /* icmpv6 141 */
o.value('ip-header-bad'); o.value('ip-header-bad');
o.value('mobile-prefix-advertisement'); /* icmpv6 147 */
o.value('mobile-prefix-solicitation'); /* icmpv6 146 */
o.value('mpl-control-message'); /* icmpv6 159 */
o.value('multicast-listener-query'); /* icmpv6 130 */
o.value('multicast-listener-report'); /* icmpv6 131 */
o.value('multicast-listener-done'); /* icmpv6 132 */
o.value('multicast-router-advertisement'); /* icmpv6 151 */
o.value('multicast-router-solicitation'); /* icmpv6 152 */
o.value('multicast-router-termination'); /* icmpv6 153 */
o.value('neighbour-advertisement'); o.value('neighbour-advertisement');
o.value('neighbour-solicitation'); o.value('neighbour-solicitation');
o.value('network-prohibited'); o.value('network-prohibited');
o.value('network-redirect'); o.value('network-redirect');
o.value('network-unknown'); o.value('network-unknown');
o.value('network-unreachable'); o.value('network-unreachable');
o.value('no-route'); /* icmpv6 1:0 */
o.value('node-info-query'); /* icmpv6 139 */
o.value('node-info-response'); /* icmpv6 140 */
o.value('packet-too-big'); o.value('packet-too-big');
o.value('parameter-problem'); o.value('parameter-problem');
o.value('port-unreachable'); o.value('port-unreachable');
@ -350,9 +317,7 @@ return view.extend({
o.value('redirect'); o.value('redirect');
o.value('required-option-missing'); o.value('required-option-missing');
o.value('router-advertisement'); o.value('router-advertisement');
o.value('router-renumbering'); /* icmpv6 138 */
o.value('router-solicitation'); o.value('router-solicitation');
o.value('rpl-control-message'); /* icmpv6 155 */
o.value('source-quench'); o.value('source-quench');
o.value('source-route-failed'); o.value('source-route-failed');
o.value('time-exceeded'); o.value('time-exceeded');
@ -364,9 +329,6 @@ return view.extend({
o.value('TOS-network-unreachable'); o.value('TOS-network-unreachable');
o.value('ttl-zero-during-reassembly'); o.value('ttl-zero-during-reassembly');
o.value('ttl-zero-during-transit'); o.value('ttl-zero-during-transit');
o.value('v2-multicast-listener-report'); /* icmpv6 143 */
o.value('unknown-header-type'); /* icmpv6 4:1 */
o.value('unknown-option'); /* icmpv6 4:2 */
o.depends({ proto: 'icmp', '!contains': true }); o.depends({ proto: 'icmp', '!contains': true });
o.depends({ proto: 'icmpv6', '!contains': true }); o.depends({ proto: 'icmpv6', '!contains': true });
@ -376,14 +338,6 @@ return view.extend({
o.allowany = true; o.allowany = true;
o.allowlocal = 'src'; o.allowlocal = 'src';
o = s.taboption('advanced', form.Value, 'ipset', _('Use ipset'));
uci.sections('firewall', 'ipset', function(s) {
if (typeof(s.name) == 'string')
o.value(s.name, s.comment ? '%s (%s)'.format(s.name, s.comment) : s.name);
});
o.modalonly = true;
o.rmempty = true;
fwtool.addMACOption(s, 'advanced', 'src_mac', _('Source MAC address'), null, hosts); fwtool.addMACOption(s, 'advanced', 'src_mac', _('Source MAC address'), null, hosts);
fwtool.addIPOption(s, 'general', 'src_ip', _('Source address'), null, '', hosts, true); fwtool.addIPOption(s, 'general', 'src_ip', _('Source address'), null, '', hosts, true);
@ -467,11 +421,9 @@ return view.extend({
fwtool.addLimitOption(s); fwtool.addLimitOption(s);
fwtool.addLimitBurstOption(s); fwtool.addLimitBurstOption(s);
if (!L.hasSystemFeature('firewall4')) {
o = s.taboption('advanced', form.Value, 'extra', _('Extra arguments'), o = s.taboption('advanced', form.Value, 'extra', _('Extra arguments'),
_('Passes additional arguments to iptables. Use with care!')); _('Passes additional arguments to iptables. Use with care!'));
o.modalonly = true; o.modalonly = true;
}
o = s.taboption('timed', form.MultiValue, 'weekdays', _('Week Days')); o = s.taboption('timed', form.MultiValue, 'weekdays', _('Week Days'));
o.modalonly = true; o.modalonly = true;
@ -500,11 +452,11 @@ return view.extend({
for (var i = 1; i <= 31; i++) for (var i = 1; i <= 31; i++)
o.value(i); o.value(i);
o = s.taboption('timed', form.Value, 'start_time', _('Start Time (hh:mm:ss)')); o = s.taboption('timed', form.Value, 'start_time', _('Start Time (hh.mm.ss)'));
o.modalonly = true; o.modalonly = true;
o.datatype = 'timehhmmss'; o.datatype = 'timehhmmss';
o = s.taboption('timed', form.Value, 'stop_time', _('Stop Time (hh:mm:ss)')); o = s.taboption('timed', form.Value, 'stop_time', _('Stop Time (hh.mm.ss)'));
o.modalonly = true; o.modalonly = true;
o.datatype = 'timehhmmss'; o.datatype = 'timehhmmss';

View file

@ -9,10 +9,6 @@
'require tools.widgets as widgets'; 'require tools.widgets as widgets';
function rule_proto_txt(s) { function rule_proto_txt(s) {
var family = (uci.get('firewall', s, 'family') || '').toLowerCase().replace(/^(?:all|\*)$/, 'any');
var sip = uci.get('firewall', s, 'src_ip') || '';
var dip = uci.get('firewall', s, 'dest_ip') || '';
var rwip = uci.get('firewall', s, 'snat_ip') || '';
var proto = L.toArray(uci.get('firewall', s, 'proto')).filter(function(p) { var proto = L.toArray(uci.get('firewall', s, 'proto')).filter(function(p) {
return (p != '*' && p != 'any' && p != 'all'); return (p != '*' && p != 'any' && p != 'all');
}).map(function(p) { }).map(function(p) {
@ -23,7 +19,7 @@ function rule_proto_txt(s) {
}; };
}); });
var m = String(uci.get('firewall', s, 'mark')).match(/^(!\s*)?(0x[0-9a-f]{1,8}|[0-9]{1,10})(?:\/(0x[0-9a-f]{1,8}|[0-9]{1,10}))?$/i); m = String(uci.get('firewall', s, 'mark')).match(/^(!\s*)?(0x[0-9a-f]{1,8}|[0-9]{1,10})(?:\/(0x[0-9a-f]{1,8}|[0-9]{1,10}))?$/i);
var f = m ? { var f = m ? {
val: m[0].toUpperCase().replace(/X/g, 'x'), val: m[0].toUpperCase().replace(/X/g, 'x'),
inv: m[1], inv: m[1],
@ -31,9 +27,7 @@ function rule_proto_txt(s) {
mask: m[3] ? '0x%02X'.format(+m[3]) : null mask: m[3] ? '0x%02X'.format(+m[3]) : null
} : null; } : null;
return fwtool.fmt(_('Forwarded %{ipv6?%{ipv4?<var>IPv4</var> and <var>IPv6</var>:<var>IPv6</var>}:<var>IPv4</var>}%{proto?, protocol %{proto#%{next?, }<var>%{item.name}</var>}}%{mark?, mark <var%{mark.inv? data-tooltip="Match fwmarks except %{mark.num}%{mark.mask? with mask %{mark.mask}}.":%{mark.mask? data-tooltip="Mask fwmark value with %{mark.mask} before compare."}}>%{mark.val}</var>}'), { return fwtool.fmt(_('Forwarded IPv4%{proto?, protocol %{proto#%{next?, }<var>%{item.name}</var>}}%{mark?, mark <var%{mark.inv? data-tooltip="Match fwmarks except %{mark.num}%{mark.mask? with mask %{mark.mask}}.":%{mark.mask? data-tooltip="Mask fwmark value with %{mark.mask} before compare."}}>%{mark.val}</var>}'), {
ipv4: (family == 'ipv4' || family == 'any' || (!family && sip.indexOf(':') == -1 && dip.indexOf(':') == -1 && rwip.indexOf(':') == -1)),
ipv6: (family == 'ipv6' || family == 'any' || (!family && (sip.indexOf(':') != -1 || dip.indexOf(':') != -1 || rwip.indexOf(':') != -1))),
proto: proto, proto: proto,
mark: f mark: f
}); });
@ -43,7 +37,7 @@ function rule_src_txt(s, hosts) {
var z = uci.get('firewall', s, 'src'); var z = uci.get('firewall', s, 'src');
return fwtool.fmt(_('From %{src}%{src_device?, interface <var>%{src_device}</var>}%{src_ip?, IP %{src_ip#%{next?, }<var%{item.inv? data-tooltip="Match IP addresses except %{item.val}."}>%{item.ival}</var>}}%{src_port?, port %{src_port#%{next?, }<var%{item.inv? data-tooltip="Match ports except %{item.val}."}>%{item.ival}</var>}}'), { return fwtool.fmt(_('From %{src}%{src_device?, interface <var>%{src_device}</var>}%{src_ip?, IP %{src_ip#%{next?, }<var%{item.inv? data-tooltip="Match IP addresses except %{item.val}."}>%{item.ival}</var>}}%{src_port?, port %{src_port#%{next?, }<var%{item.inv? data-tooltip="Match ports except %{item.val}."}>%{item.ival}</var>}}'), {
src: E('span', { 'class': 'zonebadge', 'style': fwmodel.getZoneColorStyle(null) }, [E('em', _('any zone'))]), src: E('span', { 'class': 'zonebadge', 'style': 'background-color:' + fwmodel.getColorForName(null) }, [E('em', _('any zone'))]),
src_ip: fwtool.map_invert(uci.get('firewall', s, 'src_ip'), 'toLowerCase'), src_ip: fwtool.map_invert(uci.get('firewall', s, 'src_ip'), 'toLowerCase'),
src_port: fwtool.map_invert(uci.get('firewall', s, 'src_port')) src_port: fwtool.map_invert(uci.get('firewall', s, 'src_port'))
}); });
@ -53,7 +47,7 @@ function rule_dest_txt(s) {
var z = uci.get('firewall', s, 'src'); var z = uci.get('firewall', s, 'src');
return fwtool.fmt(_('To %{dest}%{dest_device?, via interface <var>%{dest_device}</var>}%{dest_ip?, IP %{dest_ip#%{next?, }<var%{item.inv? data-tooltip="Match IP addresses except %{item.val}."}>%{item.ival}</var>}}%{dest_port?, port %{dest_port#%{next?, }<var%{item.inv? data-tooltip="Match ports except %{item.val}."}>%{item.ival}</var>}}'), { return fwtool.fmt(_('To %{dest}%{dest_device?, via interface <var>%{dest_device}</var>}%{dest_ip?, IP %{dest_ip#%{next?, }<var%{item.inv? data-tooltip="Match IP addresses except %{item.val}."}>%{item.ival}</var>}}%{dest_port?, port %{dest_port#%{next?, }<var%{item.inv? data-tooltip="Match ports except %{item.val}."}>%{item.ival}</var>}}'), {
dest: E('span', { 'class': 'zonebadge', 'style': fwmodel.getZoneColorStyle(z) }, [(z == '*') ? E('em', _('any zone')) : (z ? E('strong', z) : E('em', _('this device')))]), dest: E('span', { 'class': 'zonebadge', 'style': 'background-color:' + fwmodel.getColorForName((z && z != '*') ? z : null) }, [(z == '*') ? E('em', _('any zone')) : (z || E('em', _('this device')))]),
dest_ip: fwtool.map_invert(uci.get('firewall', s, 'dest_ip'), 'toLowerCase'), dest_ip: fwtool.map_invert(uci.get('firewall', s, 'dest_ip'), 'toLowerCase'),
dest_port: fwtool.map_invert(uci.get('firewall', s, 'dest_port')), dest_port: fwtool.map_invert(uci.get('firewall', s, 'dest_port')),
dest_device: uci.get('firewall', s, 'device') dest_device: uci.get('firewall', s, 'device')
@ -97,44 +91,6 @@ function rule_target_txt(s) {
} }
} }
function validate_opt_family(m, section_id, opt) {
var sopt = m.section.getOption('src_ip'),
dopt = m.section.getOption('dest_ip'),
rwopt = m.section.getOption('snat_ip'),
fmopt = m.section.getOption('family'),
tgopt = m.section.getOption('target');
if (!sopt.isValid(section_id) && opt != 'src_ip')
return true;
if (!dopt.isValid(section_id) && opt != 'dest_ip')
return true;
if (!rwopt.isValid(section_id) && opt != 'snat_ip')
return true;
if (!fmopt.isValid(section_id) && opt != 'family')
return true;
if (!tgopt.isValid(section_id) && opt != 'target')
return true;
var sip = sopt.formvalue(section_id) || '',
dip = dopt.formvalue(section_id) || '',
rwip = rwopt.formvalue(section_id) || '',
fm = fmopt.formvalue(section_id) || '',
tg = tgopt.formvalue(section_id);
if (fm == 'ipv6' && (sip.indexOf(':') != -1 || sip == '') && (dip.indexOf(':') != -1 || dip == '') && ((rwip.indexOf(':') != -1 && tg == 'SNAT') || rwip == ''))
return true;
if (fm == 'ipv4' && (sip.indexOf(':') == -1) && (dip.indexOf(':') == -1) && ((rwip.indexOf(':') == -1 && tg == 'SNAT') || rwip == ''))
return true;
if (fm == '' || fm == 'any') {
if ((sip.indexOf(':') != -1 || sip == '') && (dip.indexOf(':') != -1 || dip == '') && ((rwip.indexOf(':') != -1 && tg == 'SNAT') || rwip == ''))
return true;
if ((sip.indexOf(':') == -1) && (dip.indexOf(':') == -1) && ((rwip.indexOf(':') == -1 && tg == 'SNAT') || rwip == ''))
return true;
}
return _('Address family, source address, destination address, rewrite IP address must match');
}
return view.extend({ return view.extend({
callHostHints: rpc.declare({ callHostHints: rpc.declare({
object: 'luci-rpc', object: 'luci-rpc',
@ -167,7 +123,6 @@ return view.extend({
var hosts = data[0], var hosts = data[0],
devs = data[1], devs = data[1],
m, s, o; m, s, o;
var fw4 = L.hasSystemFeature('firewall4');
m = new form.Map('firewall', _('Firewall - NAT Rules'), m = new form.Map('firewall', _('Firewall - NAT Rules'),
_('NAT rules allow fine grained control over the source IP to use for outbound or forwarded traffic.')); _('NAT rules allow fine grained control over the source IP to use for outbound or forwarded traffic.'));
@ -176,7 +131,6 @@ return view.extend({
s.addremove = true; s.addremove = true;
s.anonymous = true; s.anonymous = true;
s.sortable = true; s.sortable = true;
s.cloneable = true;
s.tab('general', _('General Settings')); s.tab('general', _('General Settings'));
s.tab('advanced', _('Advanced Settings')); s.tab('advanced', _('Advanced Settings'));
@ -212,33 +166,6 @@ return view.extend({
o.default = o.enabled; o.default = o.enabled;
o.editable = true; o.editable = true;
if (fw4) {
o = s.taboption('general', form.ListValue, 'family', _('Restrict to address family'));
o.modalonly = true;
o.rmempty = true;
o.value('any', _('IPv4 and IPv6'));
o.value('ipv4', _('IPv4 only'));
o.value('ipv6', _('IPv6 only'));
o.value('', _('automatic')); // infer from zone or used IP addresses
o.cfgvalue = function(section_id) {
var val = this.map.data.get(this.map.config, section_id, 'family');
if (!val)
return '';
else if (val == 'any' || val == 'all' || val == '*')
return 'any';
else if (val == 'inet' || String(val).indexOf('4') != -1)
return 'ipv4';
else if (String(val).indexOf('6') != -1)
return 'ipv6';
};
o.validate = function(section_id, value) {
fwtool.updateHostHints(this.map, section_id, 'src_ip', value, hosts);
fwtool.updateHostHints(this.map, section_id, 'dest_ip', value, hosts);
return !fw4?true:validate_opt_family(this, section_id, 'family');
};
}
o = s.taboption('general', fwtool.CBIProtocolSelect, 'proto', _('Protocol')); o = s.taboption('general', fwtool.CBIProtocolSelect, 'proto', _('Protocol'));
o.modalonly = true; o.modalonly = true;
o.default = 'all'; o.default = 'all';
@ -251,12 +178,9 @@ return view.extend({
o.default = 'lan'; o.default = 'lan';
o = fwtool.addIPOption(s, 'general', 'src_ip', _('Source address'), o = fwtool.addIPOption(s, 'general', 'src_ip', _('Source address'),
_('Match forwarded traffic from this IP or range.'), !fw4?'ipv4':'', hosts); _('Match forwarded traffic from this IP or range.'), 'ipv4', hosts);
o.rmempty = true; o.rmempty = true;
o.datatype = !fw4?'neg(ipmask4("true"))':'neg(ipmask("true"))'; o.datatype = 'neg(ipmask4)';
o.validate = function(section_id, value) {
return !fw4?true:validate_opt_family(this, section_id, 'src_ip');
};
o = s.taboption('general', form.Value, 'src_port', _('Source port'), o = s.taboption('general', form.Value, 'src_port', _('Source port'),
_('Match forwarded traffic originating from the given source port or port range.')); _('Match forwarded traffic originating from the given source port or port range.'));
@ -268,12 +192,9 @@ return view.extend({
o.depends({ proto: 'udp', '!contains': true }); o.depends({ proto: 'udp', '!contains': true });
o = fwtool.addIPOption(s, 'general', 'dest_ip', _('Destination address'), o = fwtool.addIPOption(s, 'general', 'dest_ip', _('Destination address'),
_('Match forwarded traffic directed at the given IP address.'), !fw4?'ipv4':'', hosts); _('Match forwarded traffic directed at the given IP address.'), 'ipv4', hosts);
o.rmempty = true; o.rmempty = true;
o.datatype = !fw4?'neg(ipmask4("true"))':'neg(ipmask("true"))'; o.datatype = 'neg(ipmask4)';
o.validate = function(section_id, value) {
return !fw4?true:validate_opt_family(this, section_id, 'dest_ip');
};
o = s.taboption('general', form.Value, 'dest_port', _('Destination port'), o = s.taboption('general', form.Value, 'dest_port', _('Destination port'),
_('Match forwarded traffic directed at the given destination port or port range.')); _('Match forwarded traffic directed at the given destination port or port range.'));
@ -290,22 +211,20 @@ return view.extend({
o.value('SNAT', _('SNAT - Rewrite to specific source IP or port')); o.value('SNAT', _('SNAT - Rewrite to specific source IP or port'));
o.value('MASQUERADE', _('MASQUERADE - Automatically rewrite to outbound interface IP')); o.value('MASQUERADE', _('MASQUERADE - Automatically rewrite to outbound interface IP'));
o.value('ACCEPT', _('ACCEPT - Disable address rewriting')); o.value('ACCEPT', _('ACCEPT - Disable address rewriting'));
o.validate = function(section_id, value) {
return !fw4?true:validate_opt_family(this, section_id, 'target');
};
o = fwtool.addLocalIPOption(s, 'general', 'snat_ip', _('Rewrite IP address'), o = fwtool.addLocalIPOption(s, 'general', 'snat_ip', _('Rewrite IP address'),
_('Rewrite matched traffic to the specified source IP address.'), devs); _('Rewrite matched traffic to the specified source IP address.'), devs);
o.placeholder = null; o.placeholder = null;
o.depends('target', 'SNAT'); o.depends('target', 'SNAT');
o.validate = function(section_id, value) { o.validate = function(section_id, value) {
var a = this.formvalue(section_id), var port = this.map.lookupOption('snat_port', section_id),
p = this.section.formvalue(section_id, 'snat_port'); a = this.formvalue(section_id),
p = port ? port[0].formvalue(section_id) : null;
if ((a == null || a == '') && (p == null || p == '') && value == '') if ((a == null || a == '') && (p == null || p == '') && value == '')
return _('A rewrite IP must be specified!'); return _('A rewrite IP must be specified!');
return !fw4?true:validate_opt_family(this, section_id, 'snat_ip'); return true;
}; };
o = s.taboption('general', form.Value, 'snat_port', _('Rewrite port'), o = s.taboption('general', form.Value, 'snat_port', _('Rewrite port'),
@ -317,17 +236,6 @@ return view.extend({
o.depends({ proto: 'tcp', '!contains': true }); o.depends({ proto: 'tcp', '!contains': true });
o.depends({ proto: 'udp', '!contains': true }); o.depends({ proto: 'udp', '!contains': true });
var have_fw4 = L.hasSystemFeature('firewall4')
if (!have_fw4) {
o = s.taboption('advanced', form.Value, 'ipset', _('Use ipset'));
uci.sections('firewall', 'ipset', function(s) {
if (typeof(s.name) == 'string')
o.value(s.name, s.comment ? '%s (%s)'.format(s.name, s.comment) : s.name);
});
o.modalonly = true;
o.rmempty = true;
}
o = s.taboption('advanced', widgets.DeviceSelect, 'device', _('Outbound device'), o = s.taboption('advanced', widgets.DeviceSelect, 'device', _('Outbound device'),
_('Matches forwarded traffic using the specified outbound network device.')); _('Matches forwarded traffic using the specified outbound network device.'));
o.noaliases = true; o.noaliases = true;
@ -338,12 +246,10 @@ return view.extend({
fwtool.addLimitOption(s); fwtool.addLimitOption(s);
fwtool.addLimitBurstOption(s); fwtool.addLimitBurstOption(s);
if (!have_fw4) {
o = s.taboption('advanced', form.Value, 'extra', _('Extra arguments'), o = s.taboption('advanced', form.Value, 'extra', _('Extra arguments'),
_('Passes additional arguments to iptables. Use with care!')); _('Passes additional arguments to iptables. Use with care!'));
o.modalonly = true; o.modalonly = true;
o.rmempty = true; o.rmempty = true;
}
o = s.taboption('timed', form.MultiValue, 'weekdays', _('Week Days')); o = s.taboption('timed', form.MultiValue, 'weekdays', _('Week Days'));
o.modalonly = true; o.modalonly = true;
@ -372,11 +278,11 @@ return view.extend({
for (var i = 1; i <= 31; i++) for (var i = 1; i <= 31; i++)
o.value(i); o.value(i);
o = s.taboption('timed', form.Value, 'start_time', _('Start Time (hh:mm:ss)')); o = s.taboption('timed', form.Value, 'start_time', _('Start Time (hh.mm.ss)'));
o.modalonly = true; o.modalonly = true;
o.datatype = 'timehhmmss'; o.datatype = 'timehhmmss';
o = s.taboption('timed', form.Value, 'stop_time', _('Stop Time (hh:mm:ss)')); o = s.taboption('timed', form.Value, 'stop_time', _('Stop Time (hh.mm.ss)'));
o.modalonly = true; o.modalonly = true;
o.datatype = 'timehhmmss'; o.datatype = 'timehhmmss';

View file

@ -33,7 +33,6 @@ return view.extend({
var ctHelpers = data[0], var ctHelpers = data[0],
fwDefaults = data[1], fwDefaults = data[1],
m, s, o, inp, out; m, s, o, inp, out;
var fw4 = L.hasSystemFeature('firewall4');
m = new form.Map('firewall', _('Firewall - Zone Settings'), m = new form.Map('firewall', _('Firewall - Zone Settings'),
_('The firewall creates zones over your network interfaces to control network traffic flow.')); _('The firewall creates zones over your network interfaces to control network traffic flow.'));
@ -42,20 +41,7 @@ return view.extend({
s.anonymous = true; s.anonymous = true;
s.addremove = false; s.addremove = false;
o = s.option(form.Flag, 'synflood_protect', _('Enable SYN-flood protection')); o = s.option(form.Flag, 'syn_flood', _('Enable SYN-flood protection'));
o.cfgvalue = function(section_id) {
var val = uci.get('firewall', section_id, 'synflood_protect');
return (val != null) ? val : uci.get('firewall', section_id, 'syn_flood');
};
o.write = function(section_id, value) {
uci.unset('firewall', section_id, 'syn_flood');
uci.set('firewall', section_id, 'synflood_protect', value);
};
o.remove = function(section_id) {
uci.unset('firewall', section_id, 'syn_flood');
uci.unset('firewall', section_id, 'synflood_protect');
};
o = s.option(form.Flag, 'drop_invalid', _('Drop invalid packets')); o = s.option(form.Flag, 'drop_invalid', _('Drop invalid packets'));
var p = [ var p = [
@ -74,27 +60,21 @@ return view.extend({
if (L.hasSystemFeature('offloading')) { if (L.hasSystemFeature('offloading')) {
s = m.section(form.TypedSection, 'defaults', _('Routing/NAT Offloading'), s = m.section(form.TypedSection, 'defaults', _('Routing/NAT Offloading'),
_('Not fully compatible with QoS/SQM.')); _('Experimental feature. Not fully compatible with QoS/SQM.'));
s.anonymous = true; s.anonymous = true;
s.addremove = false; s.addremove = false;
o = s.option(form.RichListValue, "offloading_type", _("Flow offloading type")); o = s.option(form.Flag, 'flow_offloading',
o.value('0', _("None")); _('Software flow offloading'),
o.value('1', _("Software flow offloading"), _('Software based offloading for routing/NAT.')); _('Software based offloading for routing/NAT'));
o.value('2', _("Hardware flow offloading"), _('Hardware based offloading for routing with/without NAT.') + ' ' + _(' Requires hardware NAT support.')); o.optional = true;
o.optional = false;
o.load = function (section_id) { o = s.option(form.Flag, 'flow_offloading_hw',
var flow_offloading = uci.get('firewall', section_id, 'flow_offloading'); _('Hardware flow offloading'),
var flow_offloading_hw = uci.get('firewall', section_id, 'flow_offloading_hw'); _('Requires hardware NAT support. Implemented at least for mt7621'));
return (flow_offloading === '1') o.optional = true;
? (flow_offloading_hw === '1' ? '2' : '1') o.depends('flow_offloading', '1');
: '0';
};
o.write = function(section_id, value) {
uci.set('firewall', section_id, 'flow_offloading', value === '0' ? null : '1');
uci.set('firewall', section_id, 'flow_offloading_hw', value === '2' ? '1' : null);
};
} }
@ -102,7 +82,6 @@ return view.extend({
s.addremove = true; s.addremove = true;
s.anonymous = true; s.anonymous = true;
s.sortable = true; s.sortable = true;
s.nodescriptions = true;
s.handleRemove = function(section_id, ev) { s.handleRemove = function(section_id, ev) {
return firewall.deleteZone(section_id).then(L.bind(function() { return firewall.deleteZone(section_id).then(L.bind(function() {
@ -150,7 +129,7 @@ return view.extend({
var p = [ var p = [
s.taboption('general', form.ListValue, 'input', _('Input')), s.taboption('general', form.ListValue, 'input', _('Input')),
s.taboption('general', form.ListValue, 'output', _('Output')), s.taboption('general', form.ListValue, 'output', _('Output')),
s.taboption('general', form.ListValue, 'forward', _('Intra zone forward')) s.taboption('general', form.ListValue, 'forward', _('Forward'))
]; ];
for (var i = 0; i < p.length; i++) { for (var i = 0; i < p.length; i++) {
@ -164,20 +143,9 @@ return view.extend({
p[1].default = fwDefaults.getOutput(); p[1].default = fwDefaults.getOutput();
p[2].default = fwDefaults.getForward(); p[2].default = fwDefaults.getForward();
o = s.taboption('general', form.Flag, 'masq', _('Masquerading'), o = s.taboption('general', form.Flag, 'masq', _('Masquerading'));
_('Enable network address and port translation IPv4 (NAT4 or NAPT4) for outbound traffic on this zone. This is typically enabled on the <em>wan</em> zone.'));
o.editable = true; o.editable = true;
o.tooltip = function(section_id) {
var family = uci.get('firewall', section_id, 'family')
var masq_src = uci.get('firewall', section_id, 'masq_src')
var masq_dest = uci.get('firewall', section_id, 'masq_dest')
if ((!family || family.indexOf('6') == -1) && (masq_src || masq_dest))
return _('Limited masquerading enabled');
return null;
};
/*
o = s.taboption('general', form.Flag, 'fullcone', _('Full Cone')); o = s.taboption('general', form.Flag, 'fullcone', _('Full Cone'));
o.editable = true; o.editable = true;
o.depends('masq', '1'); o.depends('masq', '1');
@ -185,7 +153,6 @@ return view.extend({
o = s.taboption('general', form.Flag, 'fullcone6', _('Full Cone IPv6')); o = s.taboption('general', form.Flag, 'fullcone6', _('Full Cone IPv6'));
o.editable = true; o.editable = true;
o.depends('masq', '1'); o.depends('masq', '1');
*/
o = s.taboption('general', form.Flag, 'mtu_fix', _('MSS clamping')); o = s.taboption('general', form.Flag, 'mtu_fix', _('MSS clamping'));
o.modalonly = true; o.modalonly = true;
@ -198,24 +165,21 @@ return view.extend({
}; };
o.write = function(section_id, formvalue) { o.write = function(section_id, formvalue) {
var name = uci.get('firewall', section_id, 'name'), var name = uci.get('firewall', section_id, 'name'),
cfgvalue = this.cfgvalue(section_id), cfgvalue = this.cfgvalue(section_id);
oldNetworks = L.toArray(cfgvalue),
newNetworks = L.toArray(formvalue);
oldNetworks.sort(); /*
newNetworks.sort(); if (typeof(cfgvalue) == 'string' && Array.isArray(formvalue) && (cfgvalue == formvalue.join(' ')))
if (oldNetworks.join(' ') == newNetworks.join(' '))
return; return;
*/
var tasks = [ firewall.getZone(name) ]; var tasks = [ firewall.getZone(name) ];
if (Array.isArray(formvalue)) if (Array.isArray(formvalue))
for (var i = 0; i < newNetworks.length; i++) { for (var i = 0; i < formvalue.length; i++) {
var netname = newNetworks[i]; var netname = formvalue[i];
tasks.push(network.getNetwork(netname).then(L.bind(function(netname, net) { tasks.push(network.getNetwork(netname).then(function(net) {
return net || network.addNetwork(netname, { 'proto': 'none' }); return net || network.addNetwork(netname, { 'proto': 'none' });
}, this, netname))); }));
} }
return Promise.all(tasks).then(function(zone_networks) { return Promise.all(tasks).then(function(zone_networks) {
@ -244,24 +208,10 @@ return view.extend({
o.multiple = true; o.multiple = true;
o = s.taboption('advanced', form.DynamicList, 'subnet', _('Covered subnets'), _('Use this option to classify zone traffic by source or destination subnet instead of networks or devices.')); o = s.taboption('advanced', form.DynamicList, 'subnet', _('Covered subnets'), _('Use this option to classify zone traffic by source or destination subnet instead of networks or devices.'));
o.datatype = 'neg(cidr("true"))'; o.datatype = 'neg(cidr)';
o.modalonly = true; o.modalonly = true;
o.multiple = true; o.multiple = true;
if (fw4) {
o = s.taboption('advanced', form.Flag, 'masq6', _('IPv6 Masquerading'),
_('Enable network address and port translation IPv6 (NAT6 or NAPT6) for outbound traffic on this zone.'));
o.modalonly = true;
o.tooltip = function(section_id) {
var family = uci.get('firewall', section_id, 'family')
var masq_src = uci.get('firewall', section_id, 'masq_src')
var masq_dest = uci.get('firewall', section_id, 'masq_dest')
if ((!family || family.indexOf('6') >= 0) && (masq_src || masq_dest))
return _('Limited masquerading enabled');
return null;
};
}
o = s.taboption('advanced', form.ListValue, 'family', _('Restrict to address family')); o = s.taboption('advanced', form.ListValue, 'family', _('Restrict to address family'));
o.value('', _('IPv4 and IPv6')); o.value('', _('IPv4 and IPv6'));
o.value('ipv4', _('IPv4 only')); o.value('ipv4', _('IPv4 only'));
@ -269,24 +219,16 @@ return view.extend({
o.modalonly = true; o.modalonly = true;
o = s.taboption('advanced', form.DynamicList, 'masq_src', _('Restrict Masquerading to given source subnets')); o = s.taboption('advanced', form.DynamicList, 'masq_src', _('Restrict Masquerading to given source subnets'));
if (fw4) {
o.datatype = 'list(neg(or(uciname,hostname,ipmask)))';
} else {
o.depends('family', ''); o.depends('family', '');
o.depends('family', 'ipv4'); o.depends('family', 'ipv4');
o.datatype = 'list(neg(or(uciname,hostname,ipmask4)))'; o.datatype = 'list(neg(or(uciname,hostname,ipmask4)))';
}
o.placeholder = '0.0.0.0/0'; o.placeholder = '0.0.0.0/0';
o.modalonly = true; o.modalonly = true;
o = s.taboption('advanced', form.DynamicList, 'masq_dest', _('Restrict Masquerading to given destination subnets')); o = s.taboption('advanced', form.DynamicList, 'masq_dest', _('Restrict Masquerading to given destination subnets'));
if (fw4) {
o.datatype = 'list(neg(or(uciname,hostname,ipmask)))';
} else {
o.depends('family', ''); o.depends('family', '');
o.depends('family', 'ipv4'); o.depends('family', 'ipv4');
o.datatype = 'list(neg(or(uciname,hostname,ipmask4)))'; o.datatype = 'list(neg(or(uciname,hostname,ipmask4)))';
}
o.placeholder = '0.0.0.0/0'; o.placeholder = '0.0.0.0/0';
o.modalonly = true; o.modalonly = true;
@ -301,7 +243,8 @@ return view.extend({
o.depends('auto_helper', '0'); o.depends('auto_helper', '0');
o.modalonly = true; o.modalonly = true;
for (var i = 0; i < ctHelpers.length; i++) for (var i = 0; i < ctHelpers.length; i++)
o.value(ctHelpers[i].name, E('<span><span class="hide-close">%s (%s)</span><span class="hide-open">%s</span></span>'.format(ctHelpers[i].description, ctHelpers[i].name.toUpperCase(), ctHelpers[i].name.toUpperCase()))); //o.value(ctHelpers[i].name, '<span class="hide-close">%s (%s)</span><span class="hide-open">%s</span>'.format(ctHelpers[i].description, ctHelpers[i].name.toUpperCase(), ctHelpers[i].name.toUpperCase()));
o.value(ctHelpers[i].name, '%s (%s)'.format(ctHelpers[i].description, ctHelpers[i].name.toUpperCase()));
o = s.taboption('advanced', form.Flag, 'log', _('Enable logging on this zone')); o = s.taboption('advanced', form.Flag, 'log', _('Enable logging on this zone'));
o.modalonly = true; o.modalonly = true;
@ -311,7 +254,6 @@ return view.extend({
o.placeholder = '10/minute'; o.placeholder = '10/minute';
o.modalonly = true; o.modalonly = true;
if (!L.hasSystemFeature('firewall4')) {
o = s.taboption('extra', form.DummyValue, '_extrainfo'); o = s.taboption('extra', form.DummyValue, '_extrainfo');
o.rawhtml = true; o.rawhtml = true;
o.modalonly = true; o.modalonly = true;
@ -338,7 +280,6 @@ return view.extend({
uci.unset('firewall', section_id, 'extra'); uci.unset('firewall', section_id, 'extra');
uci.set('firewall', section_id, 'extra_dest', value); uci.set('firewall', section_id, 'extra_dest', value);
}; };
}
o = s.taboption('general', form.DummyValue, '_forwardinfo'); o = s.taboption('general', form.DummyValue, '_forwardinfo');
o.rawhtml = true; o.rawhtml = true;

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Some files were not shown because too many files have changed in this diff Show more