diff --git a/Makefile b/Makefile
index d910e235..fbe8bbbd 100644
--- a/Makefile
+++ b/Makefile
@@ -1,12 +1,12 @@
 
 ROOT_DIR      := $(CURDIR)
-BR_VER        := 2020.02
+BR_VER        := 2020.02.12
 BR_DIR        := $(ROOT_DIR)/buildroot-$(BR_VER)
 BR_EXT_DIR    := $(ROOT_DIR)/br-ext-chip-$(PLATFORM)
 SCRIPTS_DIR   := $(ROOT_DIR)/scripts
 BOARDS        := $(shell ls -1 $(BR_EXT_DIR)/configs)
 
-.PHONY: usage help prepare install-deps all toolchain-params run-tests overlayed-rootfs-%
+.PHONY: usage help clean distclean prepare install-deps all toolchain-params run-tests overlayed-rootfs-%
 
 usage help:
 	@echo \
@@ -19,11 +19,18 @@ usage help:
 	  - make BOARD=<BOARD-ID> board-info - write to stdout information about selected board\n\
 	  - make BOARD=<BOARD-ID> all - build all needed for a board (toolchain, kernel and rootfs images)\n\
 	  - make overlayed-rootfs-<FS-TYPE> ROOTFS_OVERLAYS=... - create rootfs image that contains original\n\
+	  - make clean - cleaning before reassembly\n\
+	  - make distclean - switching to the factory state\n\
 	  Buildroot target dir overlayed by some custom layers.\n\
 	  Example:\n\
 	      make overlayed-rootfs-squashfs ROOTFS_OVERLAYS=./examples/echo_server/overlay\n\
 	"
 
+distclean:
+	@rm -rf output buildroot-$(BR_VER)
+
+clean:
+	@rm -rf output/target /output/.config
 
 prepare: $(BR_DIR)
 $(ROOT_DIR)/buildroot-$(BR_VER).tar.gz:
diff --git a/README.md b/README.md
index f1e4a51f..d5b66a99 100644
--- a/README.md
+++ b/README.md
@@ -34,3 +34,12 @@ If you like our work, please consider supporting us on [Opencollective](https://
 |![Image](https://github.com/OpenIPC/openipc-2.1/actions/workflows/hi3518ev300_images.yml/badge.svg)|Hi3518Ev300|[uImage + rootfs.squashfs](https://github.com/OpenIPC/openipc-2.1/releases/download/latest/openipc.hi3518ev300-br.tgz)|[zigfisher](https://github.com/ZigFisher), [widgetii](https://github.com/widgetii)| OK |
 |![Image](https://github.com/OpenIPC/openipc-2.1/actions/workflows/ssc335_images.yml/badge.svg)|SSC335|[uImage + rootfs.squashfs](https://github.com/OpenIPC/openipc-2.1/releases/download/latest/openipc.ssc335-br.tgz)|[zigfisher](https://github.com/ZigFisher)|no video |
 |![Image](https://github.com/OpenIPC/openipc-2.1/actions/workflows/xm530_images.yml/badge.svg)|XM530/XM550|[uImage + rootfs.squashfs](https://github.com/OpenIPC/openipc-2.1/releases/download/latest/openipc.xm530-br.tgz)|[zigfisher](https://github.com/ZigFisher)|no video |
+
+-----
+
+| Platform    | U-Boot | Kernel | Rootfs | Video | Audio | GPIO | WiFi |
+|-------------|--------|--------|--------|-------|-------|------|------|
+| hi3516ev200 |
+| ssc335      |
+| xm530/xm550 |
+
diff --git a/br-ext-chip-hisilicon/Config.in b/br-ext-chip-hisilicon/Config.in
index 0948fad0..92ab43de 100644
--- a/br-ext-chip-hisilicon/Config.in
+++ b/br-ext-chip-hisilicon/Config.in
@@ -4,5 +4,7 @@ source "$BR2_EXTERNAL_HISILICON_PATH/package/hisi_gpio_scanner/Config.in"
 source "$BR2_EXTERNAL_HISILICON_PATH/package/hisilicon-osdrv4/Config.in"
 source "$BR2_EXTERNAL_HISILICON_PATH/package/fwprintenv-ng/Config.in"
 source "$BR2_EXTERNAL_HISILICON_PATH/package/ipctool/Config.in"
-source "$BR2_EXTERNAL_HISILICON_PATH/package/majestic/Config.in"
 source "$BR2_EXTERNAL_HISILICON_PATH/package/libevent-mini/Config.in"
+source "$BR2_EXTERNAL_HISILICON_PATH/package/majestic/Config.in"
+source "$BR2_EXTERNAL_HISILICON_PATH/package/node-exporter/Config.in"
+source "$BR2_EXTERNAL_HISILICON_PATH/package/vtund-lite/Config.in"
diff --git a/br-ext-chip-hisilicon/configs/unknown_unknown_hi3516ev200_openipc_defconfig b/br-ext-chip-hisilicon/configs/unknown_unknown_hi3516ev200_openipc_defconfig
index f4c7b922..8e4ba32a 100644
--- a/br-ext-chip-hisilicon/configs/unknown_unknown_hi3516ev200_openipc_defconfig
+++ b/br-ext-chip-hisilicon/configs/unknown_unknown_hi3516ev200_openipc_defconfig
@@ -54,6 +54,19 @@ BR2_PACKAGE_LAME=y
 BR2_PACKAGE_LIBEVENT_MINI=y
 BR2_PACKAGE_MAJESTIC=y
 BR2_PACKAGE_MINI_SNMPD=y
+BR2_PACKAGE_VTUND_LITE=y
+
+# Experimental
+BR2_PER_PACKAGE_DIRECTORIES=y
+BR2_PACKAGE_WIRELESS_TOOLS=y
+BR2_PACKAGE_WPA_SUPPLICANT=y
+BR2_PACKAGE_WPA_SUPPLICANT_CLI=y
+BR2_PACKAGE_WPA_SUPPLICANT_NL80211=y
+BR2_PACKAGE_WPA_SUPPLICANT_PASSPHRASE=y
+
+# Firmware
+BR2_PACKAGE_LINUX_FIRMWARE=y
+BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7601U=y
 
 # Unused
 # BR2_SHARED_STATIC_LIBS is not set
@@ -63,8 +76,3 @@ BR2_PACKAGE_MINI_SNMPD=y
 # BR2_PACKAGE_SSHPASS is not set
 # BR2_PACKAGE_RTL8188EU is not set
 
-# Experimental
-BR2_PER_PACKAGE_DIRECTORIES=y
-BR2_PACKAGE_WIRELESS_TOOLS=y
-BR2_PACKAGE_WPA_SUPPLICANT=y
-BR2_PACKAGE_WPA_SUPPLICANT_NL80211=y
diff --git a/br-ext-chip-hisilicon/configs/unknown_unknown_hi3516ev300_dev_defconfig b/br-ext-chip-hisilicon/configs/unknown_unknown_hi3516ev300_dev_defconfig
index 2f4cf3c7..b6cc41b3 100644
--- a/br-ext-chip-hisilicon/configs/unknown_unknown_hi3516ev300_dev_defconfig
+++ b/br-ext-chip-hisilicon/configs/unknown_unknown_hi3516ev300_dev_defconfig
@@ -54,6 +54,7 @@ BR2_PACKAGE_LAME=y
 BR2_PACKAGE_LIBEVENT_MINI=y
 BR2_PACKAGE_MAJESTIC=y
 BR2_PACKAGE_MINI_SNMPD=y
+BR2_PACKAGE_VTUND_LITE=y
 
 # For @widgetii
 BR2_TOOLCHAIN_BUILDROOT_CXX=y
@@ -69,6 +70,29 @@ BR2_PACKAGE_NCURSES=y
 BR2_PACKAGE_NCURSES_ADDITIONAL_TERMINFO=""
 BR2_PACKAGE_STRACE=y
 
+# Experimental
+BR2_PER_PACKAGE_DIRECTORIES=y
+BR2_PACKAGE_WIRELESS_TOOLS=y
+BR2_PACKAGE_WPA_SUPPLICANT=y
+BR2_PACKAGE_WPA_SUPPLICANT_CLI=y
+BR2_PACKAGE_WPA_SUPPLICANT_NL80211=y
+BR2_PACKAGE_WPA_SUPPLICANT_PASSPHRASE=y
+
+# Firmware
+BR2_PACKAGE_LINUX_FIRMWARE=y
+BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7601U=y
+
+# Lua
+BR2_PACKAGE_LUA=y
+BR2_PACKAGE_PROVIDES_LUAINTERPRETER="lua"
+BR2_PACKAGE_LUA_5_1=y
+BR2_PACKAGE_LUAINTERPRETER_ABI_VERSION="5.1"
+BR2_PACKAGE_LUA_EDITING_NONE=y
+BR2_PACKAGE_HAS_LUAINTERPRETER=y
+BR2_PACKAGE_LUASOCKET=y
+BR2_PACKAGE_LUA_CJSON=y
+BR2_PACKAGE_NODE_EXPORTER=y
+
 # Unused
 # BR2_SHARED_STATIC_LIBS is not set
 # BR2_PACKAGE_JPEG_TURBO is not set
@@ -76,9 +100,3 @@ BR2_PACKAGE_STRACE=y
 # BR2_PACKAGE_MXML is not set
 # BR2_PACKAGE_SSHPASS is not set
 # BR2_PACKAGE_RTL8188EU is not set
-
-# Experimental
-BR2_PER_PACKAGE_DIRECTORIES=y
-BR2_PACKAGE_WIRELESS_TOOLS=y
-BR2_PACKAGE_WPA_SUPPLICANT=y
-BR2_PACKAGE_WPA_SUPPLICANT_NL80211=y
diff --git a/br-ext-chip-hisilicon/configs/unknown_unknown_hi3516ev300_openipc_defconfig b/br-ext-chip-hisilicon/configs/unknown_unknown_hi3516ev300_openipc_defconfig
index 5c6098f8..f8b9be6d 100644
--- a/br-ext-chip-hisilicon/configs/unknown_unknown_hi3516ev300_openipc_defconfig
+++ b/br-ext-chip-hisilicon/configs/unknown_unknown_hi3516ev300_openipc_defconfig
@@ -54,6 +54,19 @@ BR2_PACKAGE_LAME=y
 BR2_PACKAGE_LIBEVENT_MINI=y
 BR2_PACKAGE_MAJESTIC=y
 BR2_PACKAGE_MINI_SNMPD=y
+BR2_PACKAGE_VTUND_LITE=y
+
+# Experimental
+BR2_PER_PACKAGE_DIRECTORIES=y
+BR2_PACKAGE_WIRELESS_TOOLS=y
+BR2_PACKAGE_WPA_SUPPLICANT=y
+BR2_PACKAGE_WPA_SUPPLICANT_CLI=y
+BR2_PACKAGE_WPA_SUPPLICANT_NL80211=y
+BR2_PACKAGE_WPA_SUPPLICANT_PASSPHRASE=y
+
+# Firmware
+BR2_PACKAGE_LINUX_FIRMWARE=y
+BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7601U=y
 
 # Unused
 # BR2_SHARED_STATIC_LIBS is not set
@@ -62,9 +75,3 @@ BR2_PACKAGE_MINI_SNMPD=y
 # BR2_PACKAGE_MXML is not set
 # BR2_PACKAGE_SSHPASS is not set
 # BR2_PACKAGE_RTL8188EU is not set
-
-# Experimental
-BR2_PER_PACKAGE_DIRECTORIES=y
-BR2_PACKAGE_WIRELESS_TOOLS=y
-BR2_PACKAGE_WPA_SUPPLICANT=y
-BR2_PACKAGE_WPA_SUPPLICANT_NL80211=y
diff --git a/br-ext-chip-hisilicon/configs/unknown_unknown_hi3518ev300_openipc_defconfig b/br-ext-chip-hisilicon/configs/unknown_unknown_hi3518ev300_openipc_defconfig
index 9cb35ad0..e1eb65e4 100644
--- a/br-ext-chip-hisilicon/configs/unknown_unknown_hi3518ev300_openipc_defconfig
+++ b/br-ext-chip-hisilicon/configs/unknown_unknown_hi3518ev300_openipc_defconfig
@@ -9,7 +9,7 @@ BR2_DEFAULT_KERNEL_VERSION="4.9.37"
 BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_4_9=y
 
 # Toolchain
-# BR2_GCC_VERSION_7_X is not set
+BR2_GCC_VERSION_7_X=y
 # BR2_TOOLCHAIN_USES_UCLIBC is not set
 # BR2_TOOLCHAIN_BUILDROOT_UCLIBC is not set
 # BR2_TOOLCHAIN_BUILDROOT_LIBC="uclibc"
@@ -46,6 +46,7 @@ BR2_GLOBAL_PATCH_DIR="$(TOPDIR)/../general/package/all-patches"
 BR2_PACKAGE_BUSYBOX_CONFIG="$(TOPDIR)/../general/package/busybox/busybox.config"
 BR2_PACKAGE_DROPBEAR=y
 BR2_PACKAGE_FWPRINTENV_NG=y
+BR2_PACKAGE_HISI_GPIO_SCANNER=y
 BR2_PACKAGE_HISILICON_OSDRV4=y
 BR2_PACKAGE_IPCTOOL=y
 BR2_PACKAGE_JSON_C=y
@@ -53,6 +54,19 @@ BR2_PACKAGE_LAME=y
 BR2_PACKAGE_LIBEVENT_MINI=y
 BR2_PACKAGE_MAJESTIC=y
 BR2_PACKAGE_MINI_SNMPD=y
+BR2_PACKAGE_VTUND_LITE=y
+
+# Experimental
+BR2_PER_PACKAGE_DIRECTORIES=y
+BR2_PACKAGE_WIRELESS_TOOLS=y
+BR2_PACKAGE_WPA_SUPPLICANT=y
+BR2_PACKAGE_WPA_SUPPLICANT_CLI=y
+BR2_PACKAGE_WPA_SUPPLICANT_NL80211=y
+BR2_PACKAGE_WPA_SUPPLICANT_PASSPHRASE=y
+
+# Firmware
+BR2_PACKAGE_LINUX_FIRMWARE=y
+BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7601U=y
 
 # Unused
 # BR2_SHARED_STATIC_LIBS is not set
@@ -61,9 +75,3 @@ BR2_PACKAGE_MINI_SNMPD=y
 # BR2_PACKAGE_MXML is not set
 # BR2_PACKAGE_SSHPASS is not set
 # BR2_PACKAGE_RTL8188EU is not set
-
-# Experimental
-BR2_PER_PACKAGE_DIRECTORIES=y
-BR2_PACKAGE_WIRELESS_TOOLS=y
-BR2_PACKAGE_WPA_SUPPLICANT=y
-BR2_PACKAGE_WPA_SUPPLICANT_NL80211=y
diff --git a/br-ext-chip-hisilicon/external.mk b/br-ext-chip-hisilicon/external.mk
index 27d10e6f..35aaab54 100644
--- a/br-ext-chip-hisilicon/external.mk
+++ b/br-ext-chip-hisilicon/external.mk
@@ -6,3 +6,5 @@ include $(BR2_EXTERNAL_HISILICON_PATH)/package/hisilicon-osdrv4/hisilicon-osdrv4
 include $(BR2_EXTERNAL_HISILICON_PATH)/package/ipctool/ipctool.mk
 include $(BR2_EXTERNAL_HISILICON_PATH)/package/libevent-mini/libevent-mini.mk
 include $(BR2_EXTERNAL_HISILICON_PATH)/package/majestic/majestic.mk
+include $(BR2_EXTERNAL_HISILICON_PATH)/package/node-exporter/node-exporter.mk
+include $(BR2_EXTERNAL_HISILICON_PATH)/package/vtund-lite/vtund-lite.mk
diff --git a/br-ext-chip-hisilicon/package/hisilicon-osdrv4/files/script/S99hisilicon b/br-ext-chip-hisilicon/package/hisilicon-osdrv4/files/script/S99hisilicon
index c49c9ca6..c9dd0d37 100755
--- a/br-ext-chip-hisilicon/package/hisilicon-osdrv4/files/script/S99hisilicon
+++ b/br-ext-chip-hisilicon/package/hisilicon-osdrv4/files/script/S99hisilicon
@@ -11,6 +11,7 @@ MAJESTIC_ARGS=""
 # The majestic does not create a pidfile, and use "-m" to instruct start-stop-daemon to create one.
 start() {
 	logger -s -p daemon.info -t hisilicon "Loading of kernel modules and initialization of the video system has started"
+	export TZ=$(cat /etc/TZ)
 	load_hisilicon -i
 	#
 	printf 'Starting %s: ' "$DAEMON"
diff --git a/br-ext-chip-hisilicon/package/node-exporter b/br-ext-chip-hisilicon/package/node-exporter
new file mode 120000
index 00000000..4ef72307
--- /dev/null
+++ b/br-ext-chip-hisilicon/package/node-exporter
@@ -0,0 +1 @@
+../../general/package/node-exporter
\ No newline at end of file
diff --git a/br-ext-chip-sigmastar/Config.in b/br-ext-chip-sigmastar/Config.in
index d67506b4..718b2180 100644
--- a/br-ext-chip-sigmastar/Config.in
+++ b/br-ext-chip-sigmastar/Config.in
@@ -1,6 +1,8 @@
 source "$BR2_EXTERNAL_SIGMASTAR_PATH/linux/Config.ext.in"
 source "$BR2_EXTERNAL_SIGMASTAR_PATH/package/sigmastar_patcher/Config.in"
-#source "$BR2_EXTERNAL_SIGMASTAR_PATH/package/sigmastar-osdrv-ssc335/Config.in"
+source "$BR2_EXTERNAL_SIGMASTAR_PATH/package/sigmastar-osdrv-ssc335/Config.in"
 source "$BR2_EXTERNAL_SIGMASTAR_PATH/package/fwprintenv-ng/Config.in"
 source "$BR2_EXTERNAL_SIGMASTAR_PATH/package/ipctool/Config.in"
 source "$BR2_EXTERNAL_SIGMASTAR_PATH/package/libevent-mini/Config.in"
+source "$BR2_EXTERNAL_SIGMASTAR_PATH/package/node-exporter/Config.in"
+source "$BR2_EXTERNAL_SIGMASTAR_PATH/package/vtund-lite/Config.in"
diff --git a/br-ext-chip-sigmastar/board/infinity6b0/kernel/patches/infinity6b0_kernel_4.9.84_sdk-Ispahan-ILS00V020.patch b/br-ext-chip-sigmastar/board/infinity6b0/kernel/patches/00_infinity6b0_kernel_4.9.84_sdk-Ispahan-ILS00V020.patch
similarity index 100%
rename from br-ext-chip-sigmastar/board/infinity6b0/kernel/patches/infinity6b0_kernel_4.9.84_sdk-Ispahan-ILS00V020.patch
rename to br-ext-chip-sigmastar/board/infinity6b0/kernel/patches/00_infinity6b0_kernel_4.9.84_sdk-Ispahan-ILS00V020.patch
diff --git a/br-ext-chip-sigmastar/board/infinity6b0/kernel/patches/infinity6b0_kernel_4.9.84_sdk-Ispahan-ILS00V020_stupid1.patch b/br-ext-chip-sigmastar/board/infinity6b0/kernel/patches/01_infinity6b0_kernel_4.9.84_sdk-Ispahan-ILS00V020_stupid1.patch
similarity index 100%
rename from br-ext-chip-sigmastar/board/infinity6b0/kernel/patches/infinity6b0_kernel_4.9.84_sdk-Ispahan-ILS00V020_stupid1.patch
rename to br-ext-chip-sigmastar/board/infinity6b0/kernel/patches/01_infinity6b0_kernel_4.9.84_sdk-Ispahan-ILS00V020_stupid1.patch
diff --git a/br-ext-chip-sigmastar/board/infinity6b0/kernel/patches/11_fix_yylloc_for_modern_computers.patch b/br-ext-chip-sigmastar/board/infinity6b0/kernel/patches/11_fix_yylloc_for_modern_computers.patch
new file mode 100644
index 00000000..2a670230
--- /dev/null
+++ b/br-ext-chip-sigmastar/board/infinity6b0/kernel/patches/11_fix_yylloc_for_modern_computers.patch
@@ -0,0 +1,11 @@
+--- a/scripts/dtc/dtc-lexer.lex.c_shipped	2016-08-28 13:19:20.000000000 +0300
++++ b/scripts/dtc/dtc-lexer.lex.c_shipped	2021-04-02 00:06:02.972781070 +0300
+@@ -637,7 +637,7 @@
+ #include "srcpos.h"
+ #include "dtc-parser.tab.h"
+ 
+-YYLTYPE yylloc;
++extern YYLTYPE yylloc;
+ extern bool treesource_error;
+ 
+ /* CAUTION: this will stop working if we ever use yyless() or yyunput() */
diff --git a/br-ext-chip-sigmastar/board/infinity6b0/kernel/ssc335.generic.config b/br-ext-chip-sigmastar/board/infinity6b0/kernel/ssc335.generic.config
index 551135a2..c0ae0e95 100644
--- a/br-ext-chip-sigmastar/board/infinity6b0/kernel/ssc335.generic.config
+++ b/br-ext-chip-sigmastar/board/infinity6b0/kernel/ssc335.generic.config
@@ -1988,7 +1988,7 @@ CONFIG_AUTO_DETECT_WRITE=y
 CONFIG_MS_SPI_INFINITY=y
 # CONFIG_CAM_CLK is not set
 # CONFIG_MS_EMMC is not set
-# CONFIG_MS_SDMMC is not set
+CONFIG_MS_SDMMC=y
 CONFIG_MS_EMAC=y
 # CONFIG_EMAC_SUPPLY_RNG is not set
 # CONFIG_MSTAR_HW_TX_CHECKSUM is not set
diff --git a/br-ext-chip-sigmastar/configs/unknown_unknown_ssc335_dev_defconfig b/br-ext-chip-sigmastar/configs/unknown_unknown_ssc335_dev_defconfig
new file mode 100644
index 00000000..007121a9
--- /dev/null
+++ b/br-ext-chip-sigmastar/configs/unknown_unknown_ssc335_dev_defconfig
@@ -0,0 +1,85 @@
+# Architecture
+BR2_arm=y
+BR2_cortex_a7=y
+BR2_ARM_EABI=y
+BR2_ARM_FPU_NEON_VFPV4=y
+BR2_ARM_INSTRUCTIONS_THUMB2=y
+BR2_KERNEL_HEADERS_VERSION=y
+BR2_DEFAULT_KERNEL_VERSION="4.9.84"
+BR2_PACKAGE_HOST_LINUX_HEADERS_CUSTOM_4_9=y
+
+# Toolchain
+BR2_GCC_VERSION_7_X=y
+# BR2_TOOLCHAIN_USES_UCLIBC is not set
+# BR2_TOOLCHAIN_BUILDROOT_UCLIBC is not set
+# BR2_TOOLCHAIN_BUILDROOT_LIBC="uclibc"
+BR2_TOOLCHAIN_USES_MUSL=y
+BR2_TOOLCHAIN_BUILDROOT_MUSL=y
+BR2_TOOLCHAIN_BUILDROOT_LIBC="musl"
+BR2_TOOLCHAIN_BUILDROOT_LOCALE=y
+BR2_TOOLCHAIN_BUILDROOT_USE_SSP=y
+
+# U-Boot
+# BR2_TARGET_UBOOT=y
+# BR2_TARGET_UBOOT_BOARD_DEFCONFIG="x600"
+# BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y
+# #BR2_TARGET_UBOOT_CUSTOM_VERSION=y
+# BR2_TARGET_UBOOT_CUSTOM_VERSION_VALUE="2015.01"
+# BR2_TARGET_UBOOT_VERSION="2015.01"
+# BR2_TARGET_UBOOT_FORMAT_BIN=y
+
+# Kernel
+BR2_LINUX_KERNEL=y
+BR2_LINUX_KERNEL_CUSTOM_VERSION=y
+BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="4.9.84"
+BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
+BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_SIGMASTAR_PATH)/board/infinity6b0/kernel/ssc335.generic.config"
+BR2_LINUX_KERNEL_UIMAGE=y
+BR2_LINUX_KERNEL_XZ=y
+BR2_LINUX_KERNEL_EXT_SIGMASTAR_PATCHER=y
+BR2_LINUX_KERNEL_EXT_SIGMASTAR_PATCHER_LIST="$(BR2_EXTERNAL_SIGMASTAR_PATH)/board/infinity6b0/kernel/patches/ $(BR2_EXTERNAL_SIGMASTAR_PATH)/board/infinity6b0/kernel/overlay"
+
+# Filesystem
+# BR2_TARGET_TZ_INFO is not set
+BR2_TARGET_ROOTFS_SQUASHFS=y
+BR2_TARGET_ROOTFS_SQUASHFS4_XZ=y
+BR2_ROOTFS_OVERLAY="$(TOPDIR)/../general/overlay"
+
+# OpenIPC configuration
+BR2_TOOLCHAIN_BUILDROOT_VENDOR="openipc"
+BR2_TARGET_GENERIC_ISSUE="Welcome to OpenIPC v21.04.25.1"
+BR2_TARGET_GENERIC_HOSTNAME="ipcam"
+BR2_GLOBAL_PATCH_DIR="$(TOPDIR)/../general/package/all-patches"
+
+# Packages
+BR2_PACKAGE_BUSYBOX_CONFIG="$(TOPDIR)/../general/package/busybox/busybox.config"
+BR2_PACKAGE_DROPBEAR=y
+BR2_PACKAGE_FWPRINTENV_NG=y
+BR2_PACKAGE_SIGMASTAR_OSDRV_SSC335=y
+BR2_PACKAGE_IPCTOOL=y
+BR2_PACKAGE_JSON_C=y
+BR2_PACKAGE_LAME=y
+BR2_PACKAGE_LIBEVENT_MINI=y
+# BR2_PACKAGE_MAJESTIC is not set
+BR2_PACKAGE_MINI_SNMPD=y
+BR2_PACKAGE_VTUND_LITE=y
+
+# Unused
+# BR2_SHARED_STATIC_LIBS is not set
+# BR2_PACKAGE_JPEG_TURBO is not set
+# BR2_PACKAGE_MINIHTTP is not set
+# BR2_PACKAGE_MXML is not set
+# BR2_PACKAGE_SSHPASS is not set
+# BR2_PACKAGE_RTL8188EU is not set
+
+# Experimental
+BR2_PER_PACKAGE_DIRECTORIES=y
+BR2_PACKAGE_WIRELESS_TOOLS=y
+BR2_PACKAGE_WPA_SUPPLICANT=y
+BR2_PACKAGE_WPA_SUPPLICANT_CLI=y
+BR2_PACKAGE_WPA_SUPPLICANT_NL80211=y
+BR2_PACKAGE_WPA_SUPPLICANT_PASSPHRASE=y
+
+# Firmware
+BR2_PACKAGE_LINUX_FIRMWARE=y
+BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7601U=y
diff --git a/br-ext-chip-sigmastar/configs/unknown_unknown_ssc335_openipc_defconfig b/br-ext-chip-sigmastar/configs/unknown_unknown_ssc335_openipc_defconfig
index 12d7341a..2c360120 100644
--- a/br-ext-chip-sigmastar/configs/unknown_unknown_ssc335_openipc_defconfig
+++ b/br-ext-chip-sigmastar/configs/unknown_unknown_ssc335_openipc_defconfig
@@ -46,13 +46,14 @@ BR2_GLOBAL_PATCH_DIR="$(TOPDIR)/../general/package/all-patches"
 BR2_PACKAGE_BUSYBOX_CONFIG="$(TOPDIR)/../general/package/busybox/busybox.config"
 BR2_PACKAGE_DROPBEAR=y
 BR2_PACKAGE_FWPRINTENV_NG=y
-# BR2_PACKAGE_SIGMASTAR_OSDRV_SSC335 is not set
+BR2_PACKAGE_SIGMASTAR_OSDRV_SSC335=y
 BR2_PACKAGE_IPCTOOL=y
 BR2_PACKAGE_JSON_C=y
 BR2_PACKAGE_LAME=y
 BR2_PACKAGE_LIBEVENT_MINI=y
 # BR2_PACKAGE_MAJESTIC is not set
 BR2_PACKAGE_MINI_SNMPD=y
+BR2_PACKAGE_VTUND_LITE=y
 
 # Unused
 # BR2_SHARED_STATIC_LIBS is not set
@@ -66,4 +67,10 @@ BR2_PACKAGE_MINI_SNMPD=y
 BR2_PER_PACKAGE_DIRECTORIES=y
 BR2_PACKAGE_WIRELESS_TOOLS=y
 BR2_PACKAGE_WPA_SUPPLICANT=y
+BR2_PACKAGE_WPA_SUPPLICANT_CLI=y
 BR2_PACKAGE_WPA_SUPPLICANT_NL80211=y
+BR2_PACKAGE_WPA_SUPPLICANT_PASSPHRASE=y
+
+# Firmware
+BR2_PACKAGE_LINUX_FIRMWARE=y
+BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7601U=y
diff --git a/br-ext-chip-sigmastar/external.mk b/br-ext-chip-sigmastar/external.mk
index 22bcc1d4..74c178a4 100644
--- a/br-ext-chip-sigmastar/external.mk
+++ b/br-ext-chip-sigmastar/external.mk
@@ -1,7 +1,9 @@
 include $(BR2_EXTERNAL_SIGMASTAR_PATH)/linux/linux-ext-sigmastar_patcher.mk
 include $(BR2_EXTERNAL_SIGMASTAR_PATH)/package/sigmastar_patcher/sigmastar_patcher.mk
-#include $(BR2_EXTERNAL_SIGMASTAR_PATH)/package/sigmastar-osdrv-ssc335/sigmastar-osdrv-ssc335.mk
+include $(BR2_EXTERNAL_SIGMASTAR_PATH)/package/sigmastar-osdrv-ssc335/sigmastar-osdrv-ssc335.mk
 include $(BR2_EXTERNAL_SIGMASTAR_PATH)/package/fwprintenv-ng/fwprintenv-ng.mk
 include $(BR2_EXTERNAL_SIGMASTAR_PATH)/package/ipctool/ipctool.mk
 include $(BR2_EXTERNAL_SIGMASTAR_PATH)/package/libevent-mini/libevent-mini.mk
+include $(BR2_EXTERNAL_SIGMASTAR_PATH)/package/node-exporter/node-exporter.mk
+include $(BR2_EXTERNAL_SIGMASTAR_PATH)/package/vtund-lite/vtund-lite.mk
 
diff --git a/br-ext-chip-sigmastar/package/node-exporter b/br-ext-chip-sigmastar/package/node-exporter
new file mode 120000
index 00000000..4ef72307
--- /dev/null
+++ b/br-ext-chip-sigmastar/package/node-exporter
@@ -0,0 +1 @@
+../../general/package/node-exporter
\ No newline at end of file
diff --git a/br-ext-chip-sigmastar/package/sigmastar-osdrv-ssc335/Config.in b/br-ext-chip-sigmastar/package/sigmastar-osdrv-ssc335/Config.in
new file mode 100644
index 00000000..5dc07c85
--- /dev/null
+++ b/br-ext-chip-sigmastar/package/sigmastar-osdrv-ssc335/Config.in
@@ -0,0 +1,6 @@
+config BR2_PACKAGE_SIGMASTAR_OSDRV_SSC335
+	bool "sigmastar-osdrv-ssc335"
+	help
+	  sigmastar-osdrv-ssc335 - SigmaStar kernel modules and libs
+
+	  https://openipc.org
diff --git a/br-ext-chip-sigmastar/package/sigmastar-osdrv-ssc335/files/script/debug_level.sh b/br-ext-chip-sigmastar/package/sigmastar-osdrv-ssc335/files/script/debug_level.sh
new file mode 100755
index 00000000..845c159a
--- /dev/null
+++ b/br-ext-chip-sigmastar/package/sigmastar-osdrv-ssc335/files/script/debug_level.sh
@@ -0,0 +1,69 @@
+#!/bin/sh
+#
+# OpenIPC.org | 2021.04.26
+#
+
+if [ TEST$2 != "TEST" ];
+then
+    export level=$2
+else
+    export level=0
+fi
+
+echo "$0 $1 $level"
+
+
+set_level()
+{
+    export DEBUGLEVEL=$1
+    echo $DEBUGLEVEL > /proc/mi_modules/mi_ai/debug_level
+    echo $DEBUGLEVEL > /proc/mi_modules/mi_ao/debug_level
+    echo $DEBUGLEVEL > /proc/mi_modules/mi_divp/debug_level
+    echo $DEBUGLEVEL > /proc/mi_modules/mi_rgn/debug_level
+    echo $DEBUGLEVEL > /proc/mi_modules/mi_sensor/debug_level
+    echo $DEBUGLEVEL > /proc/mi_modules/mi_shadow/debug_level
+    echo $DEBUGLEVEL > /proc/mi_modules/mi_sys/debug_level
+    echo $DEBUGLEVEL > /proc/mi_modules/mi_venc/debug_level
+    echo $DEBUGLEVEL > /proc/mi_modules/mi_vif/debug_level
+    echo $DEBUGLEVEL > /proc/mi_modules/mi_vpe/debug_level
+}
+
+
+show_level()
+{
+    export SHELLCMD="cat /proc/mi_modules/mi_ai/debug_level   "
+    echo $SHELLCMD && $SHELLCMD
+    export SHELLCMD="cat /proc/mi_modules/mi_ao/debug_level   "
+    echo $SHELLCMD && $SHELLCMD
+    export SHELLCMD="cat /proc/mi_modules/mi_divp/debug_level   "
+    echo $SHELLCMD && $SHELLCMD
+    export SHELLCMD="cat /proc/mi_modules/mi_rgn/debug_level   "
+    echo $SHELLCMD && $SHELLCMD
+    export SHELLCMD="cat /proc/mi_modules/mi_sensor/debug_level   "
+    echo $SHELLCMD && $SHELLCMD
+    export SHELLCMD="cat /proc/mi_modules/mi_shadow/debug_level   "
+    echo $SHELLCMD && $SHELLCMD
+    export SHELLCMD="cat /proc/mi_modules/mi_sys/debug_level   "
+    echo $SHELLCMD && $SHELLCMD
+    export SHELLCMD="cat /proc/mi_modules/mi_venc/debug_level   "
+    echo $SHELLCMD && $SHELLCMD
+    export SHELLCMD="cat /proc/mi_modules/mi_vif/debug_level   "
+    echo $SHELLCMD && $SHELLCMD
+    export SHELLCMD="cat /proc/mi_modules/mi_vpe/debug_level   "
+    echo $SHELLCMD && $SHELLCMD
+}
+
+
+case "$1" in
+    set)
+        set_level $level
+        show_level
+        ;;
+    show)
+        show_level
+        ;;
+    *)
+        echo $"Usage: $0 {set|show}"
+        exit 1
+        ;;
+esac
diff --git a/br-ext-chip-sigmastar/package/sigmastar-osdrv-ssc335/files/script/load_modules.sh b/br-ext-chip-sigmastar/package/sigmastar-osdrv-ssc335/files/script/load_modules.sh
new file mode 100755
index 00000000..eeaa153a
--- /dev/null
+++ b/br-ext-chip-sigmastar/package/sigmastar-osdrv-ssc335/files/script/load_modules.sh
@@ -0,0 +1,71 @@
+#!/bin/sh
+#
+# OpenIPC.org | 2021.04.26
+#
+# Useage: ./load [ -r|-i|-a ]
+#         -r : rmmod all modules
+#         -i : insmod all modules
+#    default : rmmod all moules and then insmod them
+
+PATH_MODULE=/opt/lib/modules/
+
+insert_ko()
+{
+    insmod ${PATH_MODULE}/mhal.ko
+    insmod ${PATH_MODULE}/mi_common.ko
+    insmod ${PATH_MODULE}/mi_sys.ko cmdQBufSize=256 logBufSize=256
+    insmod ${PATH_MODULE}/mi_ai.ko
+    insmod ${PATH_MODULE}/mi_ao.ko
+    insmod ${PATH_MODULE}/mi_rgn.ko
+    insmod ${PATH_MODULE}/mi_divp.ko thread_priority=98
+    insmod ${PATH_MODULE}/mi_ipu.ko
+    insmod ${PATH_MODULE}/mi_vpe.ko thread_priority=98
+    insmod ${PATH_MODULE}/mi_sensor.ko
+    insmod ${PATH_MODULE}/mi_vif.ko thread_priority=98
+    insmod ${PATH_MODULE}/mi_venc.ko max_width=2304 max_height=1296  thread_priority=99
+    insmod ${PATH_MODULE}/mi_shadow.ko
+
+    major=$(awk '$2=="mi_poll" {print $1}' /proc/devices)
+    mknod /dev/mi_poll c $major 0
+    echo hvsp2 down /config/iqfile/filter.txt /config/iqfile/filter.txt > /sys/class/mstar/mscl/hvsp
+    #insmod ${PATH_MODULE}/imx307_MIPI.ko chmap=1 lane_num=2 hdr_lane_num=2
+    mdev -s
+}
+
+
+remove_ko()
+{
+    rmmod imx307_MIPI
+    rmmod mi_shadow
+    rmmod mi_venc
+    rmmod mi_vif
+    rmmod mi_sensor
+    rmmod mi_vpe
+    rmmod mi_ipu
+    rmmod mi_divp
+    rmmod mi_rgn
+    rmmod mi_ao
+    rmmod mi_ai
+    rmmod mi_sys
+    rmmod mi_common
+    rmmod mhal
+}
+
+
+if [ "$1" = "-i" ]
+then
+    insert_ko
+fi
+
+if [ "$1" = "-r" ]
+then
+    remove_ko
+fi
+
+if [ $# -eq 0 ] || [ "$1" = "-a" ]
+then
+    remove_ko
+    insert_ko
+fi
+
+exit 0
diff --git a/br-ext-chip-sigmastar/package/sigmastar-osdrv-ssc335/sigmastar-osdrv-ssc335.mk b/br-ext-chip-sigmastar/package/sigmastar-osdrv-ssc335/sigmastar-osdrv-ssc335.mk
new file mode 100644
index 00000000..285d8670
--- /dev/null
+++ b/br-ext-chip-sigmastar/package/sigmastar-osdrv-ssc335/sigmastar-osdrv-ssc335.mk
@@ -0,0 +1,56 @@
+################################################################################
+#
+# sigmastar-osdrv-ssc335
+#
+################################################################################
+
+SIGMASTAR_OSDRV_SSC335_VERSION =
+SIGMASTAR_OSDRV_SSC335_SITE =
+SIGMASTAR_OSDRV_SSC335_LICENSE = MIT
+SIGMASTAR_OSDRV_SSC335_LICENSE_FILES = LICENSE
+SIGMASTAR_OSDRV_SSC335_INSTALL_STAGING = YES
+
+
+define SIGMASTAR_OSDRV_SSC335_INSTALL_STAGING_CMDS
+	$(INSTALL) -m 755 -d $(STAGING_DIR)/usr/include/sigmastar
+	# $(INSTALL) -m 644 -t $(STAGING_DIR)/usr/include/sigmastar $(BR2_EXTERNAL_SIGMASTAR_PATH)/package/sigmastar-osdrv-ssc335/files/include/*
+
+	# $(INSTALL) -m 755 -d $(BUILD_DIR)/sigmastar-osdrv-ssc335/include
+	# $(INSTALL) -m 644 -t $(BUILD_DIR)/sigmastar-osdrv-ssc335/include $(BR2_EXTERNAL_SIGMASTAR_PATH)/package/sigmastar-osdrv-ssc335/files/include/*
+
+	# $(INSTALL) -m 755 -d $(BUILD_DIR)/sigmastar-osdrv-ssc335/kmod
+	# $(INSTALL) -m 644 -t $(BUILD_DIR)/sigmastar-osdrv-ssc335/kmod $(BR2_EXTERNAL_SIGMASTAR_PATH)/package/sigmastar-osdrv-ssc335/files/kmod/*.ko
+
+	# $(INSTALL) -m 755 -d $(BUILD_DIR)/sigmastar-osdrv-ssc335/lib
+	# $(INSTALL) -m 644 -t $(BUILD_DIR)/sigmastar-osdrv-ssc335/lib $(BR2_EXTERNAL_SIGMASTAR_PATH)/package/sigmastar-osdrv-ssc335/files/lib/*.so
+endef
+
+
+define SIGMASTAR_OSDRV_SSC335_INSTALL_TARGET_CMDS
+	# $(INSTALL) -m 755 -d $(TARGET_DIR)/etc/sensors
+	# $(INSTALL) -m 644 -t $(TARGET_DIR)/etc/sensors $(BR2_EXTERNAL_SIGMASTAR_PATH)/package/sigmastar-osdrv-ssc335/files/sensor/config/*.ini
+
+	# $(INSTALL) -m 755 -d $(TARGET_DIR)/lib/modules/4.9.x/sigmastar
+	# $(INSTALL) -m 644 -t $(TARGET_DIR)/lib/modules/4.9.x/sigmastar $(BR2_EXTERNAL_SIGMASTAR_PATH)/package/sigmastar-osdrv-ssc335/files/kmod/*.ko
+	# $(INSTALL) -m 644 -t $(TARGET_DIR)/lib/modules/4.9.x/sigmastar $(BR2_EXTERNAL_SIGMASTAR_PATH)/package/sigmastar-osdrv-ssc335/files/kmod/usb/*.ko
+
+	$(INSTALL) -m 755 -d $(TARGET_DIR)/usr/bin
+	$(INSTALL) -m 755 -t $(TARGET_DIR)/usr/bin $(BR2_EXTERNAL_SIGMASTAR_PATH)/package/sigmastar-osdrv-ssc335/files/script/*
+
+	# $(INSTALL) -m 755 -d $(TARGET_DIR)/usr/lib/fonts
+	# $(INSTALL) -m 644 -t $(TARGET_DIR)/usr/lib/fonts $(BR2_EXTERNAL_SIGMASTAR_PATH)/package/sigmastar-osdrv-ssc335/files/fonts/*.bin
+
+	# $(INSTALL) -m 755 -d $(TARGET_DIR)/usr/lib/sensors
+	# $(INSTALL) -m 644 -t $(TARGET_DIR)/usr/lib/sensors $(BR2_EXTERNAL_SIGMASTAR_PATH)/package/sigmastar-osdrv-ssc335/files/sensor/*.so
+
+	# $(INSTALL) -m 755 -d $(TARGET_DIR)/usr/lib
+	# $(INSTALL) -m 644 -t $(TARGET_DIR)/usr/lib/ $(BR2_EXTERNAL_SIGMASTAR_PATH)/package/sigmastar-osdrv-ssc335/files/lib/*.so
+endef
+
+$(eval $(generic-package))
+
+
+
+
+
+
diff --git a/br-ext-chip-xiongmai/Config.in b/br-ext-chip-xiongmai/Config.in
index 1364f8ac..8334540b 100644
--- a/br-ext-chip-xiongmai/Config.in
+++ b/br-ext-chip-xiongmai/Config.in
@@ -4,5 +4,7 @@ source "$BR2_EXTERNAL_XIONGMAI_PATH/package/xiongmai-osdrv-xm510/Config.in"
 source "$BR2_EXTERNAL_XIONGMAI_PATH/package/xiongmai-osdrv-xm530/Config.in"
 source "$BR2_EXTERNAL_XIONGMAI_PATH/package/fwprintenv-ng/Config.in"
 source "$BR2_EXTERNAL_XIONGMAI_PATH/package/ipctool/Config.in"
-source "$BR2_EXTERNAL_XIONGMAI_PATH/package/majestic/Config.in"
 source "$BR2_EXTERNAL_XIONGMAI_PATH/package/libevent-mini/Config.in"
+source "$BR2_EXTERNAL_XIONGMAI_PATH/package/majestic/Config.in"
+source "$BR2_EXTERNAL_XIONGMAI_PATH/package/node-exporter/Config.in"
+source "$BR2_EXTERNAL_XIONGMAI_PATH/package/vtund-lite/Config.in"
diff --git a/br-ext-chip-xiongmai/configs/unknown_unknown_xm510_openipc_defconfig b/br-ext-chip-xiongmai/configs/unknown_unknown_xm510_openipc_defconfig
index a4ff0c22..1e2c6995 100644
--- a/br-ext-chip-xiongmai/configs/unknown_unknown_xm510_openipc_defconfig
+++ b/br-ext-chip-xiongmai/configs/unknown_unknown_xm510_openipc_defconfig
@@ -51,6 +51,7 @@ BR2_PACKAGE_LAME=y
 BR2_PACKAGE_LIBEVENT_MINI=y
 # BR2_PACKAGE_MAJESTIC is not set
 BR2_PACKAGE_MINI_SNMPD=y
+BR2_PACKAGE_VTUND_LITE=y
 
 # Unused
 # BR2_SHARED_STATIC_LIBS is not set
@@ -64,4 +65,10 @@ BR2_PACKAGE_MINI_SNMPD=y
 BR2_PER_PACKAGE_DIRECTORIES=y
 BR2_PACKAGE_WIRELESS_TOOLS=y
 BR2_PACKAGE_WPA_SUPPLICANT=y
+BR2_PACKAGE_WPA_SUPPLICANT_CLI=y
 BR2_PACKAGE_WPA_SUPPLICANT_NL80211=y
+BR2_PACKAGE_WPA_SUPPLICANT_PASSPHRASE=y
+
+# Firmware
+BR2_PACKAGE_LINUX_FIRMWARE=y
+BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7601U=y
diff --git a/br-ext-chip-xiongmai/configs/unknown_unknown_xm530_openipc_defconfig b/br-ext-chip-xiongmai/configs/unknown_unknown_xm530_openipc_defconfig
index fe4b13ae..74993ef6 100644
--- a/br-ext-chip-xiongmai/configs/unknown_unknown_xm530_openipc_defconfig
+++ b/br-ext-chip-xiongmai/configs/unknown_unknown_xm530_openipc_defconfig
@@ -51,6 +51,7 @@ BR2_PACKAGE_LAME=y
 BR2_PACKAGE_LIBEVENT_MINI=y
 # BR2_PACKAGE_MAJESTIC is not set
 BR2_PACKAGE_MINI_SNMPD=y
+BR2_PACKAGE_VTUND_LITE=y
 
 # Unused
 # BR2_SHARED_STATIC_LIBS is not set
@@ -64,4 +65,10 @@ BR2_PACKAGE_MINI_SNMPD=y
 BR2_PER_PACKAGE_DIRECTORIES=y
 BR2_PACKAGE_WIRELESS_TOOLS=y
 BR2_PACKAGE_WPA_SUPPLICANT=y
+BR2_PACKAGE_WPA_SUPPLICANT_CLI=y
 BR2_PACKAGE_WPA_SUPPLICANT_NL80211=y
+BR2_PACKAGE_WPA_SUPPLICANT_PASSPHRASE=y
+
+# Firmware
+BR2_PACKAGE_LINUX_FIRMWARE=y
+BR2_PACKAGE_LINUX_FIRMWARE_MEDIATEK_MT7601U=y
diff --git a/br-ext-chip-xiongmai/external.mk b/br-ext-chip-xiongmai/external.mk
index f56daa79..bd993e01 100644
--- a/br-ext-chip-xiongmai/external.mk
+++ b/br-ext-chip-xiongmai/external.mk
@@ -6,4 +6,6 @@ include $(BR2_EXTERNAL_XIONGMAI_PATH)/package/fwprintenv-ng/fwprintenv-ng.mk
 include $(BR2_EXTERNAL_XIONGMAI_PATH)/package/ipctool/ipctool.mk
 include $(BR2_EXTERNAL_XIONGMAI_PATH)/package/libevent-mini/libevent-mini.mk
 include $(BR2_EXTERNAL_XIONGMAI_PATH)/package/majestic/majestic.mk
+include $(BR2_EXTERNAL_XIONGMAI_PATH)/package/node-exporter/node-exporter.mk
+include $(BR2_EXTERNAL_XIONGMAI_PATH)/package/vtund-lite/vtund-lite.mk
 
diff --git a/br-ext-chip-xiongmai/package/node-exporter b/br-ext-chip-xiongmai/package/node-exporter
new file mode 120000
index 00000000..4ef72307
--- /dev/null
+++ b/br-ext-chip-xiongmai/package/node-exporter
@@ -0,0 +1 @@
+../../general/package/node-exporter
\ No newline at end of file
diff --git a/general/package/busybox/0101-add-rnd-applet-for-openipc.patch b/general/package/busybox/0101-add-rnd-applet-for-openipc.patch
deleted file mode 100644
index 4dec818e..00000000
--- a/general/package/busybox/0101-add-rnd-applet-for-openipc.patch
+++ /dev/null
@@ -1,353 +0,0 @@
-diff -urn -- a/miscutils/rng_fips.h b/miscutils/rng_fips.h
---- a/miscutils/rng_fips.h	1970-01-01 00:00:00.000000000 +0000
-+++ b/miscutils/rng_fips.h	2008-08-17 13:28:27.000000000 +0000
-@@ -0,0 +1,152 @@
-+/* vi: set sw=4 ts=4: */
-+/* rng_fips.h
-+ *
-+ * Ported to busybox by Malek Degachi
-+ *
-+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
-+ */
-+
-+#ifndef _RNG_FIPS_H
-+#define _RNG_FIPS_H
-+
-+#include "libbb.h"
-+
-+/**********************************************
-+ * FIPS part
-+ *********************************************/
-+
-+/*  Size of a FIPS test buffer, do not change this */
-+#define FIPS_RNG_BUFFER_SIZE 2500
-+
-+/* Context for running FIPS tests */
-+typedef struct {
-+	int poker[16];
-+	int runs[12];
-+	int ones;
-+	int rlength;
-+	int current_bit;
-+	int last_bit;
-+	int longrun;
-+	unsigned int last32;
-+} fips_ctx_t;
-+
-+/*
-+ * Return values for fips_run_rng_test. These values are OR'ed together
-+ * for all tests that failed.
-+ */
-+#define FIPS_RNG_MONOBIT	0x0001 /* FIPS 140-2 2001-10-10 monobit */
-+#define FIPS_RNG_POKER		0x0002 /* FIPS 140-2 2001-10-10 poker */
-+#define FIPS_RNG_RUNS		0x0004 /* FIPS 140-2 2001-10-10 runs */
-+#define FIPS_RNG_LONGRUN	0x0008 /* FIPS 140-2 2001-10-10 long run */
-+#define FIPS_RNG_CONTINUOUS_RUN 0x0010 /* FIPS 140-2 continuous run */
-+
-+/*
-+ * fips_test_store - store 8 bits of entropy in FIPS
-+ * 			 internal test data pool
-+ */
-+static void fips_test_store(fips_ctx_t *ctx, unsigned int rng_data)
-+{
-+	int j;
-+
-+	ctx->poker[rng_data >> 4]++;
-+	ctx->poker[rng_data & 15]++;
-+
-+	/* Note in the loop below rlength is always one less than the actual
-+	   run length. This makes things easier. */
-+	for (j = 7; j >= 0; j--) {
-+		ctx->ones += ctx->current_bit = ((rng_data >> j) & 1);
-+		if (ctx->current_bit != ctx->last_bit) {
-+			/* If runlength is 1-6 count it in correct bucket. 0's go in
-+			   runs[0-5] 1's go in runs[6-11] hence the 6*current_bit below */
-+			if (ctx->rlength < 5) {
-+				ctx->runs[ctx->rlength +
-+				     (6 * ctx->current_bit)]++;
-+			} else {
-+				ctx->runs[5 + (6 * ctx->current_bit)]++;
-+			}
-+
-+			/* Check if we just failed longrun test */
-+			if (ctx->rlength >= 25)
-+				ctx->longrun = 1;
-+			ctx->rlength = 0;
-+			/* flip the current run type */
-+			ctx->last_bit = ctx->current_bit;
-+		} else {
-+			ctx->rlength++;
-+		}
-+	}
-+}
-+
-+static int fips_run_rng_test(fips_ctx_t *ctx, const void *buf)
-+{
-+	int i, j;
-+	int rng_test = 0;
-+	unsigned char *rngdatabuf;
-+
-+	if (!ctx) return -1;
-+	if (!buf) return -1;
-+	rngdatabuf = (unsigned char *)buf;
-+
-+	for (i=0; i<FIPS_RNG_BUFFER_SIZE; i += 4) {
-+		int new32 = rngdatabuf[i] | 
-+			    ( rngdatabuf[i+1] << 8 ) | 
-+			    ( rngdatabuf[i+2] << 16 ) | 
-+			    ( rngdatabuf[i+3] << 24 );
-+		if (new32 == ctx->last32) rng_test |= FIPS_RNG_CONTINUOUS_RUN;
-+		ctx->last32 = new32;
-+		fips_test_store(ctx, rngdatabuf[i]);
-+		fips_test_store(ctx, rngdatabuf[i+1]);
-+		fips_test_store(ctx, rngdatabuf[i+2]);
-+		fips_test_store(ctx, rngdatabuf[i+3]);
-+	}
-+
-+	/* add in the last (possibly incomplete) run */
-+	if (ctx->rlength < 5)
-+		ctx->runs[ctx->rlength + (6 * ctx->current_bit)]++;
-+	else {
-+		ctx->runs[5 + (6 * ctx->current_bit)]++;
-+		if (ctx->rlength >= 25)
-+			rng_test |= FIPS_RNG_LONGRUN;
-+	}
-+	
-+	if (ctx->longrun) {
-+		rng_test |= FIPS_RNG_LONGRUN;
-+		ctx->longrun = 0;
-+	}
-+
-+	/* Ones test */
-+	if ((ctx->ones >= 10275) || (ctx->ones <= 9725))
-+		rng_test |= FIPS_RNG_MONOBIT;
-+	/* Poker calcs */
-+	for (i = 0, j = 0; i < 16; i++)
-+		j += ctx->poker[i] * ctx->poker[i];
-+	/* 16/5000*1563176-5000 = 2.1632  */
-+	/* 16/5000*1576928-5000 = 46.1696 */
-+	if ((j > 1576928) || (j < 1563176))
-+		rng_test |= FIPS_RNG_POKER;
-+
-+	if ((ctx->runs[0] < 2315) || (ctx->runs[0] > 2685) ||
-+	    (ctx->runs[1] < 1114) || (ctx->runs[1] > 1386) ||
-+	    (ctx->runs[2] < 527) || (ctx->runs[2] > 723) ||
-+	    (ctx->runs[3] < 240) || (ctx->runs[3] > 384) ||
-+	    (ctx->runs[4] < 103) || (ctx->runs[4] > 209) ||
-+	    (ctx->runs[5] < 103) || (ctx->runs[5] > 209) ||
-+	    (ctx->runs[6] < 2315) || (ctx->runs[6] > 2685) ||
-+	    (ctx->runs[7] < 1114) || (ctx->runs[7] > 1386) ||
-+	    (ctx->runs[8] < 527) || (ctx->runs[8] > 723) ||
-+	    (ctx->runs[9] < 240) || (ctx->runs[9] > 384) ||
-+	    (ctx->runs[10] < 103) || (ctx->runs[10] > 209) ||
-+	    (ctx->runs[11] < 103) || (ctx->runs[11] > 209)) {
-+		rng_test |= FIPS_RNG_RUNS;
-+	}
-+	
-+	/* finally, clear out FIPS variables for start of next run */
-+	memset(ctx->poker, 0, sizeof (ctx->poker));
-+	memset(ctx->runs, 0, sizeof (ctx->runs));
-+	ctx->ones = 0;
-+	ctx->rlength = -1;
-+	ctx->current_bit = 0;
-+
-+	return rng_test;
-+}
-+#endif /* _RNG_FIPS_H */
-diff -urn -- a/miscutils/rngd.c b/miscutils/rngd.c
---- a/miscutils/rngd.c	2021-04-14 10:06:59.131381906 +0300
-+++ b/miscutils/rngd.c	2021-04-14 10:04:59.785401231 +0300
-@@ -0,0 +1,193 @@
-+/* vi: set sw=4 ts=4: */
-+/*
-+ * rngd implementation for busybox
-+ *
-+ * Ported to busybox by Malek Degachi
-+ *
-+ * Licensed under GPLv2 or later, see file License in this tarball for details.
-+ *
-+ */
-+
-+//config:config RNGD
-+//config:	bool "rngd"
-+//config:	default n
-+//config:	help
-+//config:	Hardware random number generation daemon.
-+//config:config FEATURE_RNGD_LONG_OPTIONS
-+//config:	bool "Enable long options"
-+//config:	default n
-+//config:	depends on RNGD && GETOPT_LONG
-+//config:	help
-+//config:	Support long options for the rngd applet.
-+
-+//applet:IF_RNGD(APPLET(rngd, BB_DIR_USR_SBIN, BB_SUID_DROP))
-+
-+//kbuild:lib-$(CONFIG_RNGD) += rngd.o
-+
-+//usage:#define rngd_trivial_usage
-+//usage:       "[-bf] [-o random file] [-r rng file] [-s step] [-t nnn] [-W n]"
-+//usage:#define rngd_full_usage "\n\n"
-+//usage:       "Check and feed random data from hardware device to kernel entropy pool.\n"
-+//usage:      "\nOptions:"
-+//usage:     "\n	-b,--background		Become a daemon (default)"
-+//usage:     "\n	-f,--foreground		Do not fork and become a daemon"
-+//usage:     "\n	-o,--rng-device=file	Kernel device used for random number output"
-+//usage:     "\n				(default: /dev/random)"
-+//usage:     "\n	-r,--random-step=nnn	Kernel device used for random number input"
-+//usage:     "\n				(default: /dev/hw_random)"
-+//usage:     "\n	-s,--random-step=nnn	Number of bytes written to random-device at a time"
-+//usage:     "\n				(default: 64)"
-+//usage:     "\n	-t,--timeout=nnn	Interval written to random-device when the entropy"
-+//usage:     "\n				pool is full, in seconds (default: 60)"
-+//usage:     "\n	-W,--fill-watermark=n	Do not stop feeding entropy to random-device until"
-+//usage:     "\n				at least n bits of entropy are available in the"
-+//usage:     "\n				pool (default: 2048), 0 <= n <= 4096"
-+
-+
-+#include "libbb.h"
-+#include "rng_fips.h"
-+#include <syslog.h>
-+
-+#ifndef __u32
-+typedef unsigned int __u32;
-+#endif
-+#include <linux/random.h>	/* struct rand_pool_info, RNDADDENTROPY and RNDGETENTCNT */
-+
-+enum {
-+	RNG_b	= (1 << 0),
-+	RNG_f	= (1 << 1),
-+	RNG_o	= (1 << 2),
-+	RNG_r	= (1 << 3),
-+	RNG_s	= (1 << 4),
-+	RNG_t	= (1 << 5),
-+	RNG_W	= (1 << 6),
-+};
-+
-+static void random_add_entropy(int random_fd, void *buf, size_t size)
-+{
-+	struct rand_pool_info *entropy;
-+
-+	entropy = xmalloc(sizeof(struct rand_pool_info) + size);
-+
-+	entropy->entropy_count = size * 8;
-+	entropy->buf_size = size;
-+	memcpy(entropy->buf, buf, size);
-+
-+	ioctl_or_perror_and_die(random_fd, RNDADDENTROPY, entropy, "RNDADDENTROPY failed: %s\n",
-+			strerror(errno));
-+}
-+
-+static void random_sleep(int random_fd, double timeout, unsigned fill_watermark)
-+{
-+	int ent_count;
-+	struct pollfd pfd[1];
-+
-+	pfd[0].fd = random_fd;
-+	pfd[0].events = POLLOUT;
-+
-+	ioctl_or_perror_and_die(random_fd, RNDGETENTCNT, &ent_count, "RNDGETENTCNT failed: %s\n",
-+			strerror(errno));
-+	if (ent_count < fill_watermark) return;
-+	
-+	safe_poll(pfd, 1, 1000.0 * timeout);
-+}
-+
-+/* Initialize entropy source */
-+static int discard_initial_data(int rng_fd)
-+{
-+	/* Trash 32 bits of what is probably stale (non-random)
-+	 * initial state from the RNG.  For Intel's, 8 bits would
-+	 * be enough, but since AMD's generates 32 bits at a time...
-+	 *
-+	 * The kernel drivers should be doing this at device powerup,
-+	 * but at least up to 2.4.24, it doesn't. */
-+	unsigned char tempbuf[4];
-+
-+	xread(rng_fd, tempbuf, sizeof tempbuf);
-+
-+	/* Return 32 bits of bootstrap data */
-+	xread(rng_fd, tempbuf, sizeof tempbuf);
-+
-+	return tempbuf[0] | (tempbuf[1] << 8) | 
-+		(tempbuf[2] << 16) | (tempbuf[3] << 24);
-+}
-+
-+
-+#if ENABLE_FEATURE_RNGD_LONG_OPTIONS
-+static const char rngd_longopts[] ALIGN1 =
-+	"background\0"		No_argument		"b"
-+	"foreground\0"		No_argument		"f"
-+	"random-device\0"	Required_argument	"o"
-+	"rng-device\0"		Required_argument	"r"
-+	"random-step\0"		Required_argument	"s"
-+	"timeout\0"		Required_argument	"t"
-+	"fill-watermark\0"	Required_argument	"W"
-+	;
-+#endif
-+
-+int rngd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
-+int rngd_main(int argc UNUSED_PARAM, char **argv)
-+{
-+	const char *random_name = "/dev/random";
-+	const char *rng_name = "/dev/hw_random";
-+	int random_step = 64;
-+	unsigned fill_watermark;
-+	double poll_timeout = 60;
-+
-+	const char *watermark = "2048";
-+	static int rng_fd;
-+	static int random_fd;
-+
-+	unsigned char buf[FIPS_RNG_BUFFER_SIZE];
-+	unsigned char *p;
-+	int fips;
-+	fips_ctx_t *fipsctx;
-+
-+#if ENABLE_FEATURE_RNGD_LONG_OPTIONS
-+	applet_long_options = rngd_longopts;
-+#endif
-+
-+
-+	getopt32(argv, "bfo:r:s:t:W:", &random_name, &rng_name, &random_step, &poll_timeout, &watermark);
-+	argv += optind;
-+
-+	fill_watermark = xatou_range(watermark, 0, 4096);
-+
-+	/* Init entropy source, and open hardware RNG device */
-+	rng_fd = xopen(rng_name, O_RDONLY);
-+
-+	/* Bootstrap FIPS tests */
-+	fipsctx = (fips_ctx_t *) xzalloc(sizeof(fips_ctx_t));
-+	fipsctx->rlength = -1;
-+	fipsctx->last32 = discard_initial_data(rng_fd);
-+
-+	/* Init entropy sink and open random device */
-+	random_fd = xopen(random_name, O_RDWR);
-+
-+	if (!(option_mask32 & RNG_f)) { /* no -f */
-+		bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv);
-+		openlog(applet_name, LOG_PID, LOG_DAEMON);
-+		logmode = LOGMODE_SYSLOG;
-+	}
-+
-+	write_pidfile("/var/run/rngd.pid");
-+	for (;;) {
-+		xread(rng_fd, buf, sizeof buf);
-+
-+		fips = fips_run_rng_test(fipsctx, buf);
-+
-+		if (fips) {
-+			bb_info_msg("failed fips test");
-+			sleep(1);
-+			continue;
-+		}
-+
-+		for (p = buf; p + random_step <= &buf[sizeof buf]; p += random_step) {
-+			random_add_entropy(random_fd, p, random_step);
-+			random_sleep(random_fd, poll_timeout ? : -1.0, fill_watermark);
-+		}
-+	}
-+
-+	return EXIT_SUCCESS;
-+}
-+
diff --git a/general/package/busybox/busybox.config b/general/package/busybox/busybox.config
index 2f9259e3..7856c186 100644
--- a/general/package/busybox/busybox.config
+++ b/general/package/busybox/busybox.config
@@ -937,7 +937,7 @@ CONFIG_TRACEROUTE=y
 # CONFIG_TRACEROUTE6 is not set
 # CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set
 # CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
-# CONFIG_TUNCTL is not set
+CONFIG_TUNCTL=y
 # CONFIG_FEATURE_TUNCTL_UG is not set
 CONFIG_VCONFIG=y
 CONFIG_WGET=y
diff --git a/general/package/node-exporter/Config.in b/general/package/node-exporter/Config.in
new file mode 100644
index 00000000..8717d1f3
--- /dev/null
+++ b/general/package/node-exporter/Config.in
@@ -0,0 +1,6 @@
+config BR2_PACKAGE_NODE_EXPORTER
+	bool "node-exporter"
+	help
+	  node-exporter - Monitoring Linux host metrics with Prometheus
+
+	  https://openipc.org
diff --git a/general/package/node-exporter/files/prometheus-collectors/conntrack.lua b/general/package/node-exporter/files/prometheus-collectors/conntrack.lua
new file mode 100644
index 00000000..1abb7a19
--- /dev/null
+++ b/general/package/node-exporter/files/prometheus-collectors/conntrack.lua
@@ -0,0 +1,12 @@
+local function scrape()
+  local count = get_contents("/proc/sys/net/netfilter/nf_conntrack_count")
+  local max = get_contents("/proc/sys/net/netfilter/nf_conntrack_max")
+  if count ~= "" then
+    metric("node_nf_conntrack_entries", "gauge", nil, string.sub(count, 1, -2))
+  end
+  if max ~= "" then
+    metric("node_nf_conntrack_entries_limit", "gauge", nil, string.sub(max, 1, -2))
+  end
+end
+
+return { scrape = scrape }
diff --git a/general/package/node-exporter/files/prometheus-collectors/cpu.lua b/general/package/node-exporter/files/prometheus-collectors/cpu.lua
new file mode 100644
index 00000000..17e35bf7
--- /dev/null
+++ b/general/package/node-exporter/files/prometheus-collectors/cpu.lua
@@ -0,0 +1,47 @@
+-- stat/cpu collector
+local function scrape()
+  local stat = get_contents("/proc/stat")
+
+  -- system boot time, seconds since epoch
+  metric("node_boot_time_seconds", "gauge", nil,
+    string.match(stat, "btime ([0-9]+)"))
+
+  -- context switches since boot (all CPUs)
+  metric("node_context_switches_total", "counter", nil,
+    string.match(stat, "ctxt ([0-9]+)"))
+
+  -- cpu times, per CPU, per mode
+  local cpu_mode = {"user", "nice", "system", "idle", "iowait", "irq",
+                    "softirq", "steal", "guest", "guest_nice"}
+  local i = 0
+  local cpu_metric = metric("node_cpu_seconds_total", "counter")
+  while true do
+    local cpu = {string.match(stat,
+      "cpu"..i.." (%d+) (%d+) (%d+) (%d+) (%d+) (%d+) (%d+) (%d+) (%d+) (%d+)")}
+    if #cpu ~= 10 then
+      break
+    end
+    for ii, mode in ipairs(cpu_mode) do
+      cpu_metric({cpu="cpu"..i, mode=mode}, cpu[ii] / 100)
+    end
+    i = i + 1
+  end
+
+  -- interrupts served
+  metric("node_intr_total", "counter", nil,
+    string.match(stat, "intr ([0-9]+)"))
+
+  -- processes forked
+  metric("node_forks_total", "counter", nil,
+    string.match(stat, "processes ([0-9]+)"))
+
+  -- processes running
+  metric("node_procs_running_total", "gauge", nil,
+    string.match(stat, "procs_running ([0-9]+)"))
+
+  -- processes blocked for I/O
+  metric("node_procs_blocked_total", "gauge", nil,
+    string.match(stat, "procs_blocked ([0-9]+)"))
+end
+
+return { scrape = scrape }
diff --git a/general/package/node-exporter/files/prometheus-collectors/filefd.lua b/general/package/node-exporter/files/prometheus-collectors/filefd.lua
new file mode 100644
index 00000000..7e2ff639
--- /dev/null
+++ b/general/package/node-exporter/files/prometheus-collectors/filefd.lua
@@ -0,0 +1,8 @@
+local function scrape()
+  local file_nr = space_split(get_contents("/proc/sys/fs/file-nr"))
+
+  metric("node_filefd_allocated", "gauge", nil, file_nr[1])
+  metric("node_filefd_maximum", "gauge", nil, file_nr[3])
+end
+
+return { scrape = scrape }
diff --git a/general/package/node-exporter/files/prometheus-collectors/loadavg.lua b/general/package/node-exporter/files/prometheus-collectors/loadavg.lua
new file mode 100644
index 00000000..6bfab89b
--- /dev/null
+++ b/general/package/node-exporter/files/prometheus-collectors/loadavg.lua
@@ -0,0 +1,9 @@
+local function scrape()
+  local loadavg = space_split(get_contents("/proc/loadavg"))
+
+  metric("node_load1", "gauge", nil, loadavg[1])
+  metric("node_load5", "gauge", nil, loadavg[2])
+  metric("node_load15", "gauge", nil, loadavg[3])
+end
+
+return { scrape = scrape }
diff --git a/general/package/node-exporter/files/prometheus-collectors/meminfo.lua b/general/package/node-exporter/files/prometheus-collectors/meminfo.lua
new file mode 100644
index 00000000..cf836e3e
--- /dev/null
+++ b/general/package/node-exporter/files/prometheus-collectors/meminfo.lua
@@ -0,0 +1,12 @@
+local function scrape()
+  for line in io.lines("/proc/meminfo") do
+    local name, size, unit = string.match(line, "([^:]+):%s+(%d+)%s?(k?B?)")
+    if unit == 'kB' then
+      size = size * 1024
+    end
+    metric("node_memory_"..name:gsub("[):]", ""):gsub("[(]", "_").."_bytes",
+        "gauge", nil, size)
+  end
+end
+
+return { scrape = scrape }
diff --git a/general/package/node-exporter/files/prometheus-collectors/netdev.lua b/general/package/node-exporter/files/prometheus-collectors/netdev.lua
new file mode 100644
index 00000000..679b2f37
--- /dev/null
+++ b/general/package/node-exporter/files/prometheus-collectors/netdev.lua
@@ -0,0 +1,39 @@
+
+local netdevsubstat = {
+    "receive_bytes_total",
+    "receive_packets_total",
+    "receive_errs_total",
+    "receive_drop_total",
+    "receive_fifo_total",
+    "receive_frame_total",
+    "receive_compressed_total",
+    "receive_multicast_total",
+    "transmit_bytes_total",
+    "transmit_packets_total",
+    "transmit_errs_total",
+    "transmit_drop_total",
+    "transmit_fifo_total",
+    "transmit_colls_total",
+    "transmit_carrier_total",
+    "transmit_compressed_total"
+}
+
+local pattern = "([^%s:]+):%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)%s+(%d+)"
+
+local function scrape()
+  local nds_table = {}
+  for line in io.lines("/proc/net/dev") do
+    local t = {string.match(line, pattern)}
+    if #t == 17 then
+      nds_table[t[1]] = t
+    end
+  end
+  for i, ndss in ipairs(netdevsubstat) do
+    netdev_metric = metric("node_network_" .. ndss, "counter")
+    for dev, nds_dev in pairs(nds_table) do
+      netdev_metric({device=dev}, nds_dev[i+1])
+    end
+  end
+end
+
+return { scrape = scrape }
diff --git a/general/package/node-exporter/files/prometheus-collectors/netstat.lua b/general/package/node-exporter/files/prometheus-collectors/netstat.lua
new file mode 100644
index 00000000..bd6b87c3
--- /dev/null
+++ b/general/package/node-exporter/files/prometheus-collectors/netstat.lua
@@ -0,0 +1,30 @@
+local netsubstat = {
+    "IcmpMsg",
+    "Icmp",
+    "IpExt",
+    "Ip",
+    "TcpExt",
+    "Tcp",
+    "UdpLite",
+    "Udp"
+}
+
+local function scrape()
+  -- NOTE: Both of these are missing in OpenWRT kernels.
+  --       See: https://dev.openwrt.org/ticket/15781
+  local netstat = get_contents("/proc/net/netstat") .. get_contents("/proc/net/snmp")
+
+  -- all devices
+  for i, nss in ipairs(netsubstat) do
+    local substat_s = string.match(netstat, nss .. ": ([A-Z][A-Za-z0-9 ]+)")
+    if substat_s then
+      local substat = space_split(substat_s)
+      local substatv = space_split(string.match(netstat, nss .. ": ([0-9 -]+)"))
+      for ii, ss in ipairs(substat) do
+        metric("node_netstat_" .. nss .. "_" .. ss, "gauge", nil, substatv[ii])
+      end
+    end
+  end
+end
+
+return { scrape = scrape }
diff --git a/general/package/node-exporter/files/prometheus-collectors/time.lua b/general/package/node-exporter/files/prometheus-collectors/time.lua
new file mode 100644
index 00000000..2cd68c02
--- /dev/null
+++ b/general/package/node-exporter/files/prometheus-collectors/time.lua
@@ -0,0 +1,6 @@
+local function scrape()
+  -- current time
+  metric("node_time_seconds", "gauge", nil, os.time())
+end
+
+return { scrape = scrape }
diff --git a/general/package/node-exporter/files/prometheus-collectors/uname.lua b/general/package/node-exporter/files/prometheus-collectors/uname.lua
new file mode 100644
index 00000000..75a366e3
--- /dev/null
+++ b/general/package/node-exporter/files/prometheus-collectors/uname.lua
@@ -0,0 +1,20 @@
+local uname_fd = io.popen("uname -m")
+
+local labels = {
+  domainname = "",
+  nodename = "",
+  release = string.sub(get_contents("/proc/sys/kernel/osrelease"), 1, -2),
+  sysname = string.sub(get_contents("/proc/sys/kernel/ostype"), 1, -2),
+  version = string.sub(get_contents("/proc/sys/kernel/version"), 1, -2),
+  machine = string.sub(uname_fd:read("*a"), 1, -2)
+}
+
+uname_fd:close()
+
+local function scrape()
+  labels["domainname"] = string.sub(get_contents("/proc/sys/kernel/domainname"), 1, -2)
+  labels["nodename"] = string.sub(get_contents("/proc/sys/kernel/hostname"), 1, -2)
+  metric("node_uname_info", "gauge", labels, 1)
+end
+
+return { scrape = scrape }
diff --git a/general/package/node-exporter/files/script/S99node-exporter b/general/package/node-exporter/files/script/S99node-exporter
new file mode 100755
index 00000000..be597a58
--- /dev/null
+++ b/general/package/node-exporter/files/script/S99node-exporter
@@ -0,0 +1,56 @@
+#!/bin/sh
+
+DAEMON="node-exporter"
+PIDFILE="/var/run/$DAEMON.pid"
+
+NODE_EXPORTER_ARGS="--bind 0.0.0.0 --port 9100"
+
+# shellcheck source=/dev/null
+[ -r "/etc/default/$DAEMON" ] && . "/etc/default/$DAEMON"
+
+# The node-exporter does not create a pidfile, and use "-m" to instruct start-stop-daemon to create one.
+start() {
+	logger -s -p daemon.info -t node-exporter "Start $DAEMON"
+	#
+	printf 'Starting %s: ' "$DAEMON"
+	# shellcheck disable=SC2086 # we need the word splitting
+	start-stop-daemon -b -m -S -q -p "$PIDFILE" -x "/usr/bin/$DAEMON" \
+		-- $NODE_EXPORTER_ARGS
+	status=$?
+	if [ "$status" -eq 0 ]; then
+		echo "OK"
+	else
+		echo "FAIL"
+	fi
+	return "$status"
+}
+
+stop() {
+	printf 'Stopping %s: ' "$DAEMON"
+	start-stop-daemon -K -q -p "$PIDFILE"
+	status=$?
+	if [ "$status" -eq 0 ]; then
+		rm -f "$PIDFILE"
+		echo "OK"
+	else
+		echo "FAIL"
+	fi
+	return "$status"
+}
+
+restart() {
+	stop
+	sleep 1
+	start
+}
+
+case "$1" in
+	start|stop|restart)
+		"$1";;
+	reload)
+		# Restart, since there is no true "reload" feature.
+		restart;;
+	*)
+		echo "Usage: $0 {start|stop|restart|reload}"
+		exit 1
+esac
diff --git a/general/package/node-exporter/files/script/node-exporter b/general/package/node-exporter/files/script/node-exporter
new file mode 100755
index 00000000..075d823e
--- /dev/null
+++ b/general/package/node-exporter/files/script/node-exporter
@@ -0,0 +1,148 @@
+#!/usr/bin/lua
+
+-- Metrics web server
+
+-- Copyright (c) 2016 Jeff Schornick <jeff@schornick.org>
+-- Copyright (c) 2015 Kevin Lyda
+-- Licensed under the Apache License, Version 2.0
+
+socket = require("socket")
+
+-- Parsing
+
+function space_split(s)
+  local elements = {}
+  for element in s:gmatch("%S+") do
+    table.insert(elements, element)
+  end
+  return elements
+end
+
+function get_contents(filename)
+  local f = io.open(filename, "rb")
+  local contents = ""
+  if f then
+    contents = f:read "*a"
+    f:close()
+  end
+
+  return contents
+end
+
+-- Metric printing
+
+function print_metric(metric, labels, value)
+  local label_string = ""
+  if labels then
+    for label,value in pairs(labels) do
+      label_string =  label_string .. label .. '="' .. value .. '",'
+    end
+    label_string = "{" .. string.sub(label_string, 1, -2) .. "}"
+  end
+  output(string.format("%s%s %s", metric, label_string, value))
+end
+
+function metric(name, mtype, labels, value)
+  output("# TYPE " .. name .. " " .. mtype)
+  local outputter = function(labels, value)
+    print_metric(name, labels, value)
+  end
+  if value then
+    outputter(labels, value)
+  end
+  return outputter
+end
+
+function timed_scrape(collector)
+  local start_time = socket.gettime()
+  local success = 1
+  local status, err = pcall(collector.scrape)
+  if not status then
+    success = 0
+    print(err)
+  end
+  return (socket.gettime() - start_time), success
+end
+
+function run_all_collectors(collectors)
+  local metric_duration = metric("node_scrape_collector_duration_seconds", "gauge")
+  local metric_success = metric("node_scrape_collector_success", "gauge")
+  for _,cname in pairs(collectors) do
+    if col_mods[cname] ~= nil then
+      local duration, success = timed_scrape(col_mods[cname])
+      local labels = {collector=cname}
+      metric_duration(labels, duration)
+      metric_success(labels, success)
+    end
+  end
+end
+
+-- Web server-specific functions
+
+function http_ok_header()
+  output("HTTP/1.0 200 OK\r\nServer: lua-metrics\r\nContent-Type: text/plain; version=0.0.4\r\n\r")
+end
+
+function http_not_found()
+  output("HTTP/1.0 404 Not Found\r\nServer: lua-metrics\r\nContent-Type: text/plain\r\n\r\nERROR: File Not Found.")
+end
+
+function serve(request)
+  local q = request:match("^GET /metrics%??([^ ]*) HTTP/1%.[01]$")
+  if q == nil then
+    http_not_found()
+  else
+    http_ok_header()
+    local cols = {}
+    for c in q:gmatch("collect[^=]*=([^&]+)") do
+      cols[#cols+1] = c
+    end
+    if #cols == 0 then
+      cols = col_names
+    end
+    run_all_collectors(cols)
+  end
+  client:close()
+  return true
+end
+
+-- Main program
+
+for k,v in ipairs(arg) do
+  if (v == "-p") or (v == "--port") then
+    port = arg[k+1]
+  end
+  if (v == "-b") or (v == "--bind") then
+    bind = arg[k+1]
+  end
+end
+
+col_mods = {}
+col_names = {}
+ls_fd = io.popen("ls -1 /usr/lib/lua/5.1/prometheus-collectors/*.lua")
+for c in ls_fd:lines() do
+  c = c:match("([^/]+)%.lua$")
+  col_mods[c] = require('prometheus-collectors.'..c)
+  col_names[#col_names+1] = c
+end
+ls_fd:close()
+
+if port then
+  server = assert(socket.bind(bind, port))
+
+  while 1 do
+    client = server:accept()
+    client:settimeout(60)
+    local request, err = client:receive()
+
+    if not err then
+      output = function (str) client:send(str.."\n") end
+      if not serve(request) then
+        break
+      end
+    end
+  end
+else
+  output = print
+  run_all_collectors(col_names)
+end
diff --git a/general/package/node-exporter/node-exporter.mk b/general/package/node-exporter/node-exporter.mk
new file mode 100644
index 00000000..4444d93b
--- /dev/null
+++ b/general/package/node-exporter/node-exporter.mk
@@ -0,0 +1,31 @@
+################################################################################
+#
+# node-exporter
+#
+################################################################################
+
+NODE_EXPORTER_VERSION =
+NODE_EXPORTER_SITE =
+NODE_EXPORTER_LICENSE = MIT
+NODE_EXPORTER_LICENSE_FILES = LICENSE
+NODE_EXPORTER_INSTALL_STAGING = YES
+
+
+define NODE_EXPORTER_INSTALL_TARGET_CMDS
+	$(INSTALL) -m 755 -d $(TARGET_DIR)/etc/init.d
+	$(INSTALL) -m 755 -t $(TARGET_DIR)/etc/init.d $(TOPDIR)/../general/package/node-exporter/files/script/S99node-exporter
+
+	$(INSTALL) -m 755 -d $(TARGET_DIR)/usr/bin
+	$(INSTALL) -m 755 -t $(TARGET_DIR)/usr/bin $(TOPDIR)/../general/package/node-exporter/files/script/node-exporter
+
+	$(INSTALL) -m 755 -d $(TARGET_DIR)/usr/lib/lua/5.1/prometheus-collectors
+	$(INSTALL) -m 644 -t $(TARGET_DIR)/usr/lib/lua/5.1/prometheus-collectors $(TOPDIR)/../general/package/node-exporter/files/prometheus-collectors/*.lua
+endef
+
+$(eval $(generic-package))
+
+
+
+
+
+
diff --git a/general/package/vtund-lite/0001-fix-installation.patch b/general/package/vtund-lite/0001-fix-installation.patch
deleted file mode 100644
index d9659fa8..00000000
--- a/general/package/vtund-lite/0001-fix-installation.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-Makefile.in: fix installation steps
-
-Not sure what the reason for that patch is, but originally added by Ulf
-Samuelsson <ulf.samuelsson@atmel.com>, when upgrading from 2.6.x to 3.0.2.
-
-yann.morin.1998@free.fr: the initial commit in the Buildroot tree had the
-SoB by Ulf, but it was not explicitly reproduced here in the patch; so I
-added it here directly in the patch.
-
-Somewhat-signed-off-by: Ulf Samuelsson <ulf.samuelsson@atmel.com>
-Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
-diff -durN vtun-3.0.3.orig/Makefile.in vtun-3.0.3/Makefile.in
---- vtun-3.0.3.orig/Makefile.in	2012-07-09 06:55:38.000000000 +0200
-+++ vtun-3.0.3/Makefile.in	2013-02-16 23:28:47.034036869 +0100
-@@ -28,7 +28,7 @@
- LEXFLAGS = -t 
- 
- INSTALL = @INSTALL@
--INSTALL_OWNER = -o root -g 0
-+INSTALL_OWNER =
- 
- prefix = @prefix@
- exec_prefix = @exec_prefix@
-@@ -89,16 +89,15 @@
- 
- install_config: 
- 	$(INSTALL) -d -m 755 $(INSTALL_OWNER) $(DESTDIR)$(ETC_DIR)
--	if [ ! -f $(ETC_DIR)/vtund.conf ]; then \
--	  $(INSTALL) -m 600 $(INSTALL_OWNER) vtund.conf $(DESTDIR)$(ETC_DIR); \
--	fi
-+	$(INSTALL) -m 600 $(INSTALL_OWNER) vtund.conf $(DESTDIR)$(ETC_DIR);
-+	$(INSTALL) -m 600 $(INSTALL_OWNER) scripts/vtund-start.conf $(DESTDIR)$(ETC_DIR);
- 
- install: vtund install_config install_man
--	$(INSTALL) -d -m 755 $(INSTALL_OWNER) $(DESTDIR)$(VAR_DIR)/run
- 	$(INSTALL) -d -m 755 $(INSTALL_OWNER) $(DESTDIR)$(STAT_DIR)
- 	$(INSTALL) -d -m 755 $(INSTALL_OWNER) $(DESTDIR)$(LOCK_DIR)
- 	$(INSTALL) -d -m 755 $(INSTALL_OWNER) $(DESTDIR)$(SBIN_DIR)
- 	$(INSTALL) -m 755 $(INSTALL_OWNER) vtund $(DESTDIR)$(SBIN_DIR)
--	$(BIN_DIR)/strip $(DESTDIR)$(SBIN_DIR)/vtund
-+	$(INSTALL) -m 755 -D $(INSTALL_OWNER) scripts/vtund.rc.debian \
-+		$(DESTDIR)$(ETC_DIR)/init.d/S90vtun
- 
- # DO NOT DELETE THIS LINE -- make depend depends on it.
diff --git a/general/package/vtund-lite/01_vtund-3.0.2_fix_makefile.patch b/general/package/vtund-lite/01_vtund-3.0.2_fix_makefile.patch
new file mode 100644
index 00000000..cd9bcf18
--- /dev/null
+++ b/general/package/vtund-lite/01_vtund-3.0.2_fix_makefile.patch
@@ -0,0 +1,43 @@
+--- a/Makefile.in	2008-01-08 01:35:55.000000000 +0300
++++ b/Makefile.in	2021-05-07 22:18:22.310801557 +0300
+@@ -74,27 +74,27 @@
+ 
+ distclean: clean
+ 	rm -f $(CONFIGURE_FILES)
+-	rm -f `cat vtun.drivers`	
++	rm -f `cat vtun.drivers`
+ 
+ install_man: 
+-	$(INSTALL) -d -m 755 $(INSTALL_OWNER) $(DESTDIR)$(MAN_DIR)/man8
+-	$(INSTALL) -m 644 $(INSTALL_OWNER) vtund.8 $(DESTDIR)$(MAN_DIR)/man8
+-	$(INSTALL) -d -m 755 $(INSTALL_OWNER) $(DESTDIR)$(MAN_DIR)/man5
+-	$(INSTALL) -m 644 $(INSTALL_OWNER) vtund.conf.5 $(DESTDIR)$(MAN_DIR)/man5
++	$(INSTALL) -d -m 755 $(DESTDIR)$(MAN_DIR)/man8
++	$(INSTALL) -m 644 vtund.8 $(DESTDIR)$(MAN_DIR)/man8
++	$(INSTALL) -d -m 755 $(DESTDIR)$(MAN_DIR)/man5
++	$(INSTALL) -m 644 $vtund.conf.5 $(DESTDIR)$(MAN_DIR)/man5
+ 	rm -f $(DESTDIR)$(MAN_DIR)/man8/vtun.8 
+ 	ln -s vtund.8 $(DESTDIR)$(MAN_DIR)/man8/vtun.8 
+ 
+ install_config: 
+-	$(INSTALL) -d -m 755 $(INSTALL_OWNER) $(DESTDIR)$(ETC_DIR)
++	$(INSTALL) -d -m 755 $(DESTDIR)$(ETC_DIR)
+ 	if [ ! -f $(ETC_DIR)/vtund.conf ]; then \
+-	  $(INSTALL) -m 600 $(INSTALL_OWNER) vtund.conf $(DESTDIR)$(ETC_DIR); \
++	  $(INSTALL) -m 600 vtund.conf $(DESTDIR)$(ETC_DIR); \
+ 	fi
+ 
+-install: vtund install_config install_man
+-	$(INSTALL) -d -m 755 $(INSTALL_OWNER) $(DESTDIR)$(VAR_DIR)/run
+-	$(INSTALL) -d -m 755 $(INSTALL_OWNER) $(DESTDIR)$(STAT_DIR)
+-	$(INSTALL) -d -m 755 $(INSTALL_OWNER) $(DESTDIR)$(LOCK_DIR)
+-	$(INSTALL) -d -m 755 $(INSTALL_OWNER) $(DESTDIR)$(SBIN_DIR)
+-	$(INSTALL) -m 755 $(INSTALL_OWNER) vtund $(DESTDIR)$(SBIN_DIR)
++install: vtund
++	$(INSTALL) -d -m 755 $(DESTDIR)$(VAR_DIR)/run
++	$(INSTALL) -d -m 755 $(DESTDIR)$(STAT_DIR)
++	$(INSTALL) -d -m 755 $(DESTDIR)$(LOCK_DIR)
++	$(INSTALL) -d -m 755 $(DESTDIR)$(SBIN_DIR)
++	$(INSTALL) -m 755 vtund $(DESTDIR)$(SBIN_DIR)
+ 
+ # DO NOT DELETE THIS LINE -- make depend depends on it.
diff --git a/general/package/vtund-lite/Config.in b/general/package/vtund-lite/Config.in
index 2cae104d..9ecee2c9 100644
--- a/general/package/vtund-lite/Config.in
+++ b/general/package/vtund-lite/Config.in
@@ -7,4 +7,6 @@ config BR2_PACKAGE_VTUND_LITE
 
 	  It supports IP, PPP, SLIP, Ethernet and other tunnel types.
 
+	  No LZO/SSL/ZLIB version
+
 	  http://vtun.sourceforge.net/
diff --git a/general/package/vtund-lite/files/S90vtun b/general/package/vtund-lite/files/S90vtun
new file mode 100644
index 00000000..5158663f
--- /dev/null
+++ b/general/package/vtund-lite/files/S90vtun
@@ -0,0 +1,61 @@
+#! /bin/sh
+#
+# submitted by Morgon Kanter
+# 
+
+PATH=/bin:/usr/bin:/sbin:/usr/sbin
+DAEMON=/usr/sbin/vtund
+CONFFILE=/etc/vtund-start.conf
+PIDPREFIX=/var/run/vtund
+  
+test -f $DAEMON || exit 0
+  
+case "$1" in 
+       start)
+      # find all the defined tunnels
+      egrep -v '^[:space:]*(#.*)?$' $CONFFILE | while true;
+      do
+          read i
+          # no more lines available? done, then.
+          if [ $? != 0 ] ; then break; fi
+              SARGS=`echo $i|sed -ne 's/--server--\s*/-s -P /p'`;
+              if [ -n "$SARGS" ];
+              then
+                 echo "Starting vtund server."
+                  start-stop-daemon --start --exec $DAEMON --pidfile $PIDPREFIX.pid -- $SARGS;
+              else
+                  # split args into host and rest
+                  HOST=`echo $i|cut -f 1 -d " "`;
+                  TARGET=`echo $i|cut -f 2 -d " "`;
+                  echo  "Starting vtund client $HOST to $TARGET.";
+                  start-stop-daemon --start --exec $DAEMON --pidfile $PIDPREFIX.$HOST.pid -- $i;
+ 
+              fi
+          done
+              ;;
+       stop) 
+          echo "Stopping vtund.";
+          for i in $PIDPREFIX*;
+          do
+              start-stop-daemon --stop --pidfile $i; 
+              rm -f $i;
+          done
+               ;;
+       reload|force-reload)
+          echo "Reloading vtund.";
+          for i in $PIDPREFIX*;
+          do
+              start-stop-daemon --stop --signal 1 --pidfile $i; 
+          done
+              ;;
+       restart) 
+          $0 stop
+          sleep 1;
+          $0 start
+          ;;
+   *)
+      echo "Usage: $0 {start|stop|restart|reload|force-reload}" >&2
+       exit 1
+               ;;
+esac
+exit 0
diff --git a/general/package/vtund-lite/vtund-lite.hash b/general/package/vtund-lite/vtund-lite.hash
deleted file mode 100644
index a13f4bd4..00000000
--- a/general/package/vtund-lite/vtund-lite.hash
+++ /dev/null
@@ -1,5 +0,0 @@
-# From https://sourceforge.net/projects/vtun/files/vtun/3.0.4/
-md5 f952c5895ae8f40235aaad9a8f41a4bd  vtun-3.0.4.tar.gz
-sha1 2335c21b56fadf9ce851dd7f342fb0ed4f522c47  vtun-3.0.4.tar.gz
-# Locally computed:
-sha256 abf8df6b15e3febeaaeae2ce24ead7105eb1537ad4ec0d830c83cbb684fd98b9  vtun-3.0.4.tar.gz
diff --git a/general/package/vtund-lite/vtund-lite.mk b/general/package/vtund-lite/vtund-lite.mk
index 2a409b4b..81f11b1f 100644
--- a/general/package/vtund-lite/vtund-lite.mk
+++ b/general/package/vtund-lite/vtund-lite.mk
@@ -4,23 +4,16 @@
 #
 ################################################################################
 
-VTUND_LITE_VERSION = 3.0.4
-VTUND_LITE_SITE = http://downloads.sourceforge.net/project/vtun/vtun/$(VTUND_LITE_VERSION)
-VTUND_LITE_LICENSE = GPL-2.0+ with OpenSSL exception
-VTUND_LITE_LICENSE_FILES = README.OpenSSL
+VTUND_LITE_VERSION = 3.0.2
+VTUND_LITE_SOURCE = vtun-$(VTUND_LITE_VERSION).tar.gz
+VTUND_LITE_SITE = http://prdownloads.sourceforge.net/vtun
+VTUND_LITE_LICENSE = GPL-2.0+
+VTUND_LITE_LICENSE_FILES = LICENSE
 VTUND_LITE_DEPENDENCIES = host-bison host-flex host-pkgconf
-VTUND_LITE_AUTORECONF = YES
 
-VTUND_LITE_CONF_OPTS = \
-	--without-ssl-headers=$(STAGING_DIR)/usr/include/openssl \
-	--without-lzo-headers=$(STAGING_DIR)/usr/include/lzo \
-	--without-lzo-lib=$(STAGING_DIR)/usr/lib
+VTUND_LITE_CONF_OPTS += --disable-lzo --disable-ssl --disable-zlib
 
 # Assumes old-style gcc inline symbol visibility rules
 VTUND_LITE_CONF_ENV = CFLAGS="$(TARGET_CFLAGS) -std=gnu89"
 
-# configure.in forgets to link to dependent libraries of openssl breaking static
-# linking
-VTUND_LITE_CONF_ENV += LIBS=`$(PKG_CONFIG_HOST_BINARY)`
-
 $(eval $(autotools-package))