Compare commits

..

1 Commits

Author SHA1 Message Date
Meng
6226c8045e quickjs-ng 2025-07-22 18:26:08 +02:00
223 changed files with 4299 additions and 9232 deletions

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=bbfdm
PKG_VERSION:=1.18.16
PKG_VERSION:=1.17.0
USE_LOCAL:=0
ifneq ($(USE_LOCAL),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/bbf/bbfdm.git
PKG_SOURCE_VERSION:=72c3307651cb583121fa5b4abcaad957ddc264bd
PKG_SOURCE_VERSION:=a4f61081381a35fc98fa1cec58e964c3e6db2c55
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif
@@ -55,7 +55,7 @@ define Package/dm-service
CATEGORY:=Utilities
SUBMENU:=TRx69
TITLE:=Datamodel ubus backend to expose micro-service tree
DEPENDS:=+libuci +libubox +libubus +libblobmsg-json +libjson-c +libbbfdm-api +libbbfdm-ubus +bbf_configmngr +libeasy
DEPENDS:=+libuci +libubox +libubus +libblobmsg-json +libjson-c +libbbfdm-api +libbbfdm-ubus +bbf_configmngr
endef
define Package/bbf_configmngr
@@ -107,7 +107,7 @@ endif
CMAKE_OPTIONS += \
-DBBF_VENDOR_PREFIX:String="$(CONFIG_BBF_VENDOR_PREFIX)" \
-DBBFDMD_MAX_MSG_LEN:Integer=20971520 \
-DBBFDMD_MAX_MSG_LEN:Integer=10485760 \
-DCMAKE_BUILD_TYPE:String="Debug" \
@@ -183,7 +183,6 @@ define Package/bbf_configmngr/install
$(INSTALL_BIN) ./files/etc/init.d/bbf_configd $(1)/etc/init.d/bbf_configd
$(INSTALL_BIN) $(PKG_BUILD_DIR)/utilities/files/usr/share/bbfdm/scripts/bbf_config_notify.sh $(1)/usr/share/bbfdm/scripts/
$(INSTALL_BIN) $(PKG_BUILD_DIR)/utilities/files/usr/share/bbfdm/scripts/bbf_default_reload.sh $(1)/etc/bbfdm/
$(INSTALL_DATA) ./files/etc/bbfdm/critical_services.json $(1)/etc/bbfdm/
endef

View File

@@ -1,47 +1,23 @@
{
"usp": [
"/etc/config/firewall",
"/etc/bbfdm/dmmap/dmmap_firewall",
"/etc/config/network",
"/etc/bbfdm/dmmap/IP",
"/etc/bbfdm/dmmap/Ethernet",
"/etc/bbfdm/dmmap/GRE",
"/etc/bbfdm/dmmap/IPv6rd",
"/etc/bbfdm/dmmap/PPP",
"/etc/bbfdm/dmmap/Routing",
"/etc/config/dhcp",
"/etc/bbfdm/dmmap/DHCPv4",
"/etc/bbfdm/dmmap/DHCPv6",
"/etc/config/time",
"/etc/bbfdm/dmmap/dmmap_time",
"/etc/config/mapcontroller",
"/etc/config/wireless",
"/etc/bbfdm/dmmap/WiFi",
"/etc/config/ieee1905",
"/etc/config/mosquitto",
"/etc/config/nginx",
"/etc/config/netmode",
"/etc/bbfdm/dmmap/dmmap_netmode"
"firewall",
"network",
"dhcp",
"time",
"wireless",
"ieee1905",
"mapcontroller",
"mosquitto",
"nginx",
"netmode"
],
"cwmp": [
"/etc/config/firewall",
"/etc/bbfdm/dmmap/dmmap_firewall",
"/etc/config/network",
"/etc/bbfdm/dmmap/IP",
"/etc/bbfdm/dmmap/Ethernet",
"/etc/bbfdm/dmmap/GRE",
"/etc/bbfdm/dmmap/IPv6rd",
"/etc/bbfdm/dmmap/PPP",
"/etc/bbfdm/dmmap/Routing",
"/etc/config/dhcp",
"/etc/bbfdm/dmmap/DHCPv4",
"/etc/bbfdm/dmmap/DHCPv6",
"/etc/config/mapcontroller",
"/etc/config/wireless",
"/etc/bbfdm/dmmap/WiFi",
"/etc/config/time",
"/etc/bbfdm/dmmap/dmmap_time",
"/etc/config/netmode",
"/etc/bbfdm/dmmap/dmmap_netmode"
"firewall",
"network",
"dhcp",
"mapcontroller",
"wireless",
"time",
"netmode"
]
}

View File

@@ -27,6 +27,6 @@ start_service()
service_triggers() {
for config_file in /etc/config/*; do
config_name=$(basename "$config_file")
procd_add_config_trigger "config.change" "$config_name" /usr/share/bbfdm/scripts/bbf_config_notify.sh "$config_name"
procd_add_config_trigger "config.change" "$config_name" /usr/share/bbfdm/scripts/bbf_config_notify.sh
done
}

View File

@@ -5,12 +5,6 @@ config BRIDGEMNGR_BRIDGE_VLAN
help
Set this option to use bridge-vlan as backend for VLAN objects.
config BRIDGEMNGR_COPY_PBITS
bool "Copy pbits from cvlan to svlan"
default y
help
Set this option to copy cvlan pbits to svlan pbits by default (driver vlan).
config BRIDGEMNGR_BRIDGE_VENDOR_EXT
bool "Use bridge BBF vendor extensions"
default y

View File

@@ -5,13 +5,14 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=bridgemngr
PKG_VERSION:=1.1.6
PKG_VERSION:=1.1.1
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/network/bridgemngr.git
PKG_SOURCE_VERSION:=882f8c8cc9a97372297d192cc916c4f8ffe7c25a
PKG_SOURCE_URL:=https://dev.iopsys.eu/network/bridgemngr
PKG_SOURCE_VERSION:=b6a657e1c83b49f09323b4012ef229c604b82854
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif
@@ -51,10 +52,6 @@ ifeq ($(CONFIG_BRIDGEMNGR_BRIDGE_VLAN),y)
TARGET_CFLAGS += -DBRIDGE_VLAN_BACKEND
endif
ifeq ($(CONFIG_BRIDGEMNGR_COPY_PBITS),y)
TARGET_CFLAGS+=-DBRIDGEMNGR_COPY_PBITS
endif
define Package/bridgemngr/install
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_DIR) $(1)/etc/config

View File

@@ -7,13 +7,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=bulkdata
PKG_VERSION:=2.1.23
PKG_VERSION:=2.1.20
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/bbf/bulkdata.git
PKG_SOURCE_VERSION:=f54550f2d587a701c0a8d5cac4a0910a99ce92cf
PKG_SOURCE_VERSION:=a5e57962938ca143ede65d92be90b6e9fce66e15
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif

View File

@@ -4,16 +4,4 @@ config DECOLLECTOR_EASYMESH_VERSION
int "Support Easymesh version"
default 6
config DECOLLECTOR_BUILD_TR181_PLUGIN
bool "Build TR-181 mapping module (responsible for Device.WiFi.DataElements.)"
default y
config DECOLLECTOR_VENDOR_EXTENSIONS
bool "Iopsys vendor extensions for Device.WiFi.DataElements."
default y
config DECOLLECTOR_VENDOR_PREFIX
string "Package specific datamodel Vendor Prefix for TR181 extensions"
default ""
endmenu

View File

@@ -6,12 +6,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=decollector
PKG_VERSION:=6.2.3.8
PKG_VERSION:=6.2.1.7
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=8396091a83aefaf8423dfd41a957b04f3ed821e7
PKG_SOURCE_VERSION:=ca92325ece080389ffb405c95048b64071eda653
PKG_SOURCE_URL:=https://dev.iopsys.eu/multi-ap/decollector.git
PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
@@ -24,7 +24,6 @@ PKG_LICENSE:=BSD-3-Clause
PKG_LICENSE_FILES:=LICENSE
include $(INCLUDE_DIR)/package.mk
include $(TOPDIR)/feeds/iopsys/bbfdm/bbfdm.mk
define Package/decollector
SECTION:=utils
@@ -67,18 +66,6 @@ MAKE_PATH:=src
TARGET_CFLAGS += -DEASYMESH_VERSION=$(CONFIG_DECOLLECTOR_EASYMESH_VERSION)
ifeq ($(CONFIG_DECOLLECTOR_BUILD_TR181_PLUGIN),y)
MAKE_FLAGS += DECOLLECTOR_BUILD_TR181_PLUGIN=y
ifeq ($(CONFIG_DECOLLECTOR_VENDOR_EXTENSIONS),y)
TARGET_CFLAGS += -DDECOLLECTOR_VENDOR_EXTENSIONS
ifeq ($(CONFIG_DECOLLECTOR_VENDOR_PREFIX),"")
TARGET_CFLAGS += -DCUSTOM_PREFIX=\\\"$(CONFIG_BBF_VENDOR_PREFIX)\\\"
else
TARGET_CFLAGS += -DCUSTOM_PREFIX=\\\"$(CONFIG_DECOLLECTOR_VENDOR_PREFIX)\\\"
endif
endif
endif
EXECS := \
$(if $(CONFIG_PACKAGE_decollector),decollector)
@@ -89,7 +76,6 @@ define Package/decollector/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) ./files/decollector.init $(1)/etc/init.d/decollector
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/decollector $(1)/usr/sbin/
$(BBFDM_REGISTER_SERVICES) ./bbfdm_service.json $(1) $(PKG_NAME)
endef
$(eval $(call BuildPackage,decollector))

View File

@@ -1,26 +0,0 @@
{
"daemon": {
"enable": "1",
"service_name": "decollector",
"unified_daemon": true,
"services": [
{
"parent_dm": "Device.WiFi.",
"object": "DataElements"
}
],
"config": {
"loglevel": "3"
},
"apply_handler": {
"uci": [
{
"file": [
"mapcontroller"
],
"external_handler": "/etc/wifidmd/bbf_config_reload.sh"
}
]
}
}
}

View File

@@ -2,13 +2,13 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=dectmngr
PKG_RELEASE:=3
PKG_VERSION:=3.7.13
PKG_VERSION:=3.7.10
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/dectmngr.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=5c2720563b3ed889e9d4de6fdb9b0f6a9d584094
PKG_SOURCE_VERSION:=1f851980a6ba616df54f79930225f8bcd563b711
PKG_MIRROR_HASH:=skip
endif

View File

@@ -1,12 +0,0 @@
if PACKAGE_dhcpmngr
config DHCPMNGR_ENABLE_VENDOR_EXT
bool "Use datamodel vendor extensions"
default y
help
Set this option to use bridge BBF vendor extensions.
config DHCPMNGR_VENDOR_PREFIX
string "Package specific datamodel Vendor Prefix for TR181 extensions"
default ""
endif

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=dhcpmngr
PKG_VERSION:=1.1.6
PKG_VERSION:=1.0.6
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/network/dhcpmngr.git
PKG_SOURCE_VERSION:=74d96cd70119e4ea08767d68b45b4922162d0328
PKG_SOURCE_VERSION:=986f66608959f4f589009d580b046e250d8c620d
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif
@@ -39,22 +39,6 @@ define Package/dhcpmngr/description
Package to add Device.DHCPv4. and Device.DHCPv6. data model support.
endef
define Package/$(PKG_NAME)/config
source "$(SOURCE)/Config.in"
endef
ifeq ($(CONFIG_DHCPMNGR_ENABLE_VENDOR_EXT),y)
MAKE_FLAGS += DHCPMNGR_ENABLE_VENDOR_EXT=y
endif
ifeq ($(CONFIG_DHCPMNGR_VENDOR_PREFIX),"")
VENDOR_PREFIX = $(CONFIG_BBF_VENDOR_PREFIX)
else
VENDOR_PREFIX = $(CONFIG_DHCPMNGR_VENDOR_PREFIX)
endif
TARGET_CFLAGS += -DBBF_VENDOR_PREFIX=\\\"$(VENDOR_PREFIX)\\\"
ifeq ($(LOCAL_DEV),1)
define Build/Prepare
$(CP) -rf ~/git/dhcpmngr/* $(PKG_BUILD_DIR)/

View File

@@ -1,48 +0,0 @@
#
# Copyright (c) 2023 Genexis Netherlands B.V. All rights reserved.
# This Software and its content are protected by the Dutch Copyright Act
# ('Auteurswet'). All and any copying and distribution of the software
# and its content without authorization by Genexis Netherlands B.V. is
# prohibited. The prohibition includes every form of reproduction and
# distribution.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=dmcli-plugins
PKG_LICENSE:=PROPRIETARY GENEXIS
PKG_VERSION:=2.2.6
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/gnx/dmcli-plugin-easydm.git
PKG_SOURCE_VERSION:=bc8b8527e8a41bdba73cb277a3c6c3b42b045153
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.xz
PKG_MIRROR_HASH:=skip
PKG_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/package.mk
define Package/dmcli-plugins
SECTION:=tools
CATEGORY:=Genexis
TITLE:=Easy-to-use data model on top of TR181
URL:=http://genexis.eu
DEPENDS:=+dmcli
endef
define Package/dmcli-plugins/description
EasyDM offers a user-friendly approach to configuring TR-181
simplifying the process with its intuitive interface.
endef
define Build/Compile
true
endef
define Package/dmcli-plugins/install
$(INSTALL_DIR) $(1)/usr/lib/dmcli/plugins
$(CP) $(PKG_BUILD_DIR)/src/*.js $(1)/usr/lib/dmcli/plugins/
endef
$(eval $(call BuildPackage,dmcli-plugins))

View File

@@ -1,9 +0,0 @@
if PACKAGE_dmcli
config DMCLI_REMOTE_CONNECTION
bool "Add dmcli remote controller configuration"
default n
help
This adds a usp controller configuration for dmcli remote connection from different machine/laptop/server.
endif

View File

@@ -1,76 +0,0 @@
#
# Copyright (c) 2021 Genexis Netherlands B.V. All rights reserved.
# This Software and its content are protected by the Dutch Copyright Act
# ('Auteurswet'). All and any copying and distribution of the software
# and its content without authorization by Genexis Netherlands B.V. is
# prohibited. The prohibition includes every form of reproduction and
# distribution.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=dmcli
PKG_LICENSE:=PROPRIETARY GENEXIS
PKG_VERSION:=1.9.6
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/gnx/dmcli.git
PKG_SOURCE_VERSION:=f03188eff6c2cab59e4c8f18a435c940ff5043f5
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.xz
PKG_MIRROR_HASH:=skip
PKG_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/package.mk
define Package/dmcli
SECTION:=tools
CATEGORY:=Genexis
TITLE:=DMCLI (datamodel-based CLI)
URL:=http://genexis.eu
DEPENDS:=+usp-js +DMCLI_REMOTE_CONNECTION:mosquitto-auth-plugin +shadow-utils +@BUSYBOX_CONFIG_ADDUSER
endef
define Package/dmcli/description
CLI to view and configure datamodels of CPE
endef
define Package/dmcli/conffiles
/etc/dmcli/dmcli.conf
endef
define Package/dmcli/config
source "$(SOURCE)/Config.in"
endef
define Package/dmcli/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/dmcli $(1)/usr/bin/
$(INSTALL_DIR) $(1)/usr/lib/dmcli
$(CP) $(PKG_BUILD_DIR)/common $(1)/usr/lib/dmcli/
mv $(1)/usr/lib/dmcli/common/os_qjs.js $(1)/usr/lib/dmcli/common/os.js
rm $(1)/usr/lib/dmcli/common/os_node.js
$(CP) $(PKG_BUILD_DIR)/core $(1)/usr/lib/dmcli/
$(CP) $(PKG_BUILD_DIR)/cli $(1)/usr/lib/dmcli/
$(CP) $(PKG_BUILD_DIR)/data $(1)/usr/lib/dmcli/
$(CP) $(PKG_BUILD_DIR)/plugins $(1)/usr/lib/dmcli/
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_DATA) ./files/etc/uci-defaults/36-dmcli $(1)/etc/uci-defaults/
ifeq ($(CONFIG_DMCLI_REMOTE_CONNECTION),y)
$(INSTALL_DATA) ./files/etc/uci-defaults/36-dmcli-remote $(1)/etc/uci-defaults/
else
$(INSTALL_DATA) ./files/etc/uci-defaults/36-dmcli-remote-remove $(1)/etc/uci-defaults/
endif
$(INSTALL_DIR) $(1)/etc/dmcli
$(CP) ./files/etc/dmcli/dmcli.acl $(1)/etc/dmcli/
$(CP) ./files/etc/dmcli/dmcli.conf $(1)/etc/dmcli/
$(INSTALL_DIR) $(1)/etc/users/roles/
$(INSTALL_DATA) ./files/etc/users/roles/operator.json $(1)/etc/users/roles/
endef
$(eval $(call BuildPackage,dmcli))

View File

@@ -1,4 +0,0 @@
user operator
topic read /usp/operator/controller/reply-to
topic read /usp/operator/controller
topic write /usp/operator/endpoint

View File

@@ -1,45 +0,0 @@
{
"Settings": {
"USP": {
"ActiveConnectionProfile": "local",
"ConnectionProfile": [
{
"Name": "local",
"Host": "127.0.0.1",
"Port": 9002,
"Username": "operator",
"Protocol": "ws",
"FromId": "oui:000F94:device-controller-operator",
"PublishEndpoint": "/usp/operator/endpoint",
"SubscribeEndpoint": "/usp/operator/controller"
}
],
"Session": {
"AutoStart": false
},
"Notification": {
"LogTo": "console",
"Format": "brief",
"LogFile": "usp-notification.log"
}
},
"CLI": {
"Home": "/",
"Color": "true",
"Mode": "Command",
"ShowCommandTime": false,
"SortDMTree": false
},
"Prompt": {
"Auto": true,
"Color": "default",
"SelectedBackgroundColor": "yellow",
"PageSize": "3",
"AutoPromptOnEmptyCommand": false,
"AutoPromptInstanceNumbers": false
},
"Log": {
"Level": "Error"
}
}
}

View File

@@ -1,120 +0,0 @@
#!/bin/sh
. /lib/functions.sh
. /lib/functions/iopsys-environment.sh
. /usr/share/libubox/jshn.sh
DMCLI_CONF="/etc/dmcli/dmcli.conf"
CONTROLLER_ID='oui:000F94:device-controller-operator'
DMCLI_RESP_TOPIC="/usp/operator/endpoint"
DMCLI_CTRL_TOPIC="/usp/operator/controller"
DMCLI_PORT="9002"
grep -q "^operator:" /etc/passwd || {
adduser -g 'Operator' -D -H -s /usr/bin/dmcli --home '/usr/lib/dmcli' 'operator'
hash=""
if type get_operator_password_hash > /dev/null 2>&1; then
hash=$(get_operator_password_hash)
fi
if [ -z "$hash" ]; then
hash='$6$zP4Wk/VQJOLwwofC$teuhnYFQBcA8YUZo/Q0quDMi4SsOHmfBcyvt5VNchPnzgwF1nfNNliC3yBVW22NwmwttPEWeBEBfnMTBB0rYs/'
fi
echo "operator:${hash}" | chpasswd -e
}
grep -q "^/usr/bin/dmcli$" /etc/shells || {
echo '/usr/bin/dmcli' >> /etc/shells
}
uci -q del_list sshd.@sshd[0].AllowUsers='operator'
uci -q add_list sshd.@sshd[0].AllowUsers='operator'
uci -q delete users.operator
uci -q set users.operator=user
uci -q set users.operator.enabled=1
uci -q set users.operator.shell='dmcli'
uci -q set users.operator.member_roles='operator'
if [ -f "/etc/config/mosquitto" ]; then
uci_add mosquitto listener dmcli_local
uci_set mosquitto dmcli_local enabled 1
uci_set mosquitto dmcli_local port "${DMCLI_PORT}"
uci_set mosquitto dmcli_local protocol 'websockets'
uci_set mosquitto dmcli_local acl_file '/etc/dmcli/dmcli.acl'
uci_set mosquitto dmcli_local no_remote_access '1'
uci_set mosquitto dmcli_local allow_anonymous '1'
fi
if [ -f "/etc/config/obuspa" ]; then
uci_add obuspa mqtt mqtt_operator
uci_set obuspa mqtt_operator BrokerAddress '127.0.0.1'
uci_set obuspa mqtt_operator BrokerPort '1883'
uci_set obuspa mqtt_operator TransportProtocol 'TCP/IP'
uci_add obuspa mtp mtp_operator
uci_set obuspa mtp_operator Protocol 'MQTT'
uci_set obuspa mtp_operator ResponseTopicConfigured "${DMCLI_RESP_TOPIC}"
uci_set obuspa mtp_operator mqtt 'mqtt_operator'
uci_add obuspa controller controller_operator
uci_set obuspa controller_operator EndpointID "${CONTROLLER_ID}"
uci_set obuspa controller_operator Protocol 'MQTT'
uci_set obuspa controller_operator Topic "${DMCLI_CTRL_TOPIC}"
uci_set obuspa controller_operator mqtt 'mqtt_operator'
uci_set obuspa controller_operator assigned_role_name 'operator'
fi
_get_endpoint_id() {
local id serial oui
id="$(uci -q get obuspa.localagent.EndpointID)"
if [ -n "${id}" ]; then
echo "${id}"
return 0
fi
serial="$(db -q get device.deviceinfo.SerialNumber)"
oui="$(db -q get device.deviceinfo.ManufacturerOUI)"
echo "os::${oui}-${serial//+/%2B}"
}
update_dmcli_conf() {
local endpointid confTmpFile
local port fromid publish subscribe toid
if [ -f "${DMCLI_CONF}" ]; then
endpointid="$(_get_endpoint_id)"
json_load_file "${DMCLI_CONF}" || return
json_select "Settings" || return
json_select "USP" || return
json_select "ConnectionProfile" || return
json_select "1" || return
json_get_var port "Port"
json_get_var fromid "FromId"
json_get_var publish "PublishEndpoint"
json_get_var subscribe "SubscribeEndpoint"
json_get_var toid "ToId"
json_add_int "Port" "${DMCLI_PORT}"
json_add_string "FromId" "${CONTROLLER_ID}"
json_add_string "PublishEndpoint" "${DMCLI_RESP_TOPIC}"
json_add_string "SubscribeEndpoint" "${DMCLI_CTRL_TOPIC}"
json_add_string "ToId" "${endpointid}"
json_select ..
json_select ..
json_select ..
json_select ..
if [ "${port}" != "${DMCLI_PORT}" ] || [ "${fromid}" != "${CONTROLLER_ID}" ] || \
[ "${publish}" != "${DMCLI_RESP_TOPIC}" ] || [ "${subscribe}" != "${DMCLI_CTRL_TOPIC}" ] || \
[ "${toid}" != "${endpointid}" ]; then
confTmpFile="$(mktemp -u -p "$(dirname "$DMCLI_CONF")" "$(basename "$DMCLI_CONF").XXXXXXX")"
json_pretty
json_dump > "${confTmpFile}" || return
mv -f "${confTmpFile}" "${DMCLI_CONF}" || return
fi
fi
}
update_dmcli_conf || exit

View File

@@ -1,14 +0,0 @@
#!/bin/sh
. /lib/functions.sh
if [ -f "/etc/config/mosquitto" ]; then
uci_add mosquitto listener dmcli
uci_set mosquitto dmcli enabled 1
uci_set mosquitto dmcli port '9003'
uci_set mosquitto dmcli protocol 'websockets'
uci_set mosquitto dmcli auth_plugin '/usr/lib/mosquitto_auth_plugin.so'
uci_set mosquitto dmcli acl_file '/etc/dmcli/dmcli.acl'
fi
exit 0

View File

@@ -1,9 +0,0 @@
#!/bin/sh
. /lib/functions.sh
if [ -f "/etc/config/mosquitto" ]; then
uci_remove mosquitto dmcli
fi
exit 0

View File

@@ -1,14 +0,0 @@
{
"tr181": {
"name": "operator",
"instance": 6,
"permission": [
{
"object": "Device.",
"perm": [
"PERMIT_ALL"
]
}
]
}
}

View File

@@ -1,7 +0,0 @@
all: dmcli
dmcli: main.c
$(CC) $(CFLAGS) -Wall -Werror -o $@ $^
clean:
rm -f dmcli

View File

@@ -1,32 +0,0 @@
/*
* Copyright (c) 2021 Genexis Netherlands B.V. All rights reserved.
* This Software and its content are protected by the Dutch Copyright Act
* ('Auteurswet'). All and any copying and distribution of the software
* and its content without authorization by Genexis Netherlands B.V. is
* prohibited. The prohibition includes every form of reproduction and
* distribution.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
/* C Wrapper for operator to login to the CLI via ssh: the shell in
* the passwd file cannot be a script that requires an interpreter. */
int main(int argc, char *argv[])
{
char *cmd[3 + (argc > 1 ? argc - 1 : 0)];
cmd[0] = "/usr/bin/qjs";
cmd[1] = "/usr/lib/dmcli/cli/main.js";
cmd[2] = NULL;
if (argc > 1) {
memcpy(&cmd[2], &argv[1], (argc - 1) * sizeof(char *));
cmd[2 + argc - 1] = NULL;
}
execv(cmd[0], cmd);
fprintf(stderr, "%s: command not found\n", cmd[0]);
return 127;
}

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=dnsmngr
PKG_VERSION:=1.0.20
PKG_VERSION:=1.0.18
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/network/dnsmngr.git
PKG_SOURCE_VERSION:=83e485fae8905f9061257264cf43ea41e47743a6
PKG_SOURCE_VERSION:=80fa147e6f1f0d9c1a62a62a693ff3adaef45363
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif

View File

@@ -5,8 +5,6 @@ source "/lib/functions/network.sh"
source "/lib/functions/system.sh"
PREVLINK=""
LINK=""
LINKSPEED=""
PREVWANMODE=""
WANMODE=""
CONFIGURED=0
@@ -62,7 +60,7 @@ create_atm_devices() {
}
configure_line() {
local mode profile bitswap sra us0 sesdrop sos roc ginp gvector mod prof
local mode profile bitswap sra us0 sesdrop sos ginp mod prof
local adsl1_flag=0 issue2_flag=0 Glite_flag=0 adsl2_flag=0 adsl2p_flag=0 vdsl2_flag=0
local pro_8a_flag=0 pro_8b_flag=0 pro_8c_flag=0 pro_8d_flag=0 pro_12a_flag=0 pro_12b_flag=0 pro_17a_flag=0 pro_30a_flag=0 pro_35b_flag=0
@@ -72,9 +70,8 @@ configure_line() {
config_get sra $1 sra "1"
config_get us0 $1 us0 "1"
config_get sos $1 sos "0"
config_get roc $1 roc "0"
config_get ginp $1 ginp "1"
config_get gvector $1 gvector "1"
config_get sos $1 roc "0"
config_get sos $1 ginp "0"
for mod in $mode; do
[ "$mod" = "gdmt" ] && adsl1_flag=1
@@ -99,7 +96,6 @@ configure_line() {
/userfs/bin/blapi_cmd xdsl set_adsl_profile "$pro_8a_flag" "$pro_8b_flag" "$pro_8c_flag" "$pro_8d_flag" "$pro_12a_flag" "$pro_12b_flag" "$pro_17a_flag" "$pro_30a_flag" "$pro_35b_flag"
/userfs/bin/blapi_cmd xdsl set_adsl_mode "$adsl1_flag" "$issue2_flag" "$Glite_flag" "$adsl2_flag" "$adsl2p_flag" "$vdsl2_flag"
/userfs/bin/blapi_cmd xdsl set_adsl_gvector "$((!gvector))"
/userfs/bin/blapi_cmd xdsl set_adsl_ginp "$((!ginp))"
/userfs/bin/blapi_cmd xdsl set_adsl_sos_roc "$((!sos))" "$((!roc))"
/userfs/bin/blapi_cmd xdsl set_adsl_us0 "$((!us0))"
@@ -152,12 +148,6 @@ while [ true ]; do
if [ "$LINK" != "$PREVLINK" -a \( "$LINK" = "down" -o "$LINK" = "up" \) ]; then
if [ "$LINK" = "down" ]; then
if [ ! -s /tmp/qos/wan_link_shape_rate ]; then
rm -rf /tmp/qos/wan_link_shape_rate
rm -rf /tmp/qos/wan_link_speed
/usr/sbin/qos-uplink-bandwidth
fi
[ "$CONFIGURED" -eq 0 ] && configure_lines # Needs to be done once the slave SoC is in down state and we've not been able to auto-sync.
if [ -n "$WANMODE" ]; then
if [ "$WANMODE" = "PTM" ]; then
@@ -234,26 +224,6 @@ while [ true ]; do
call_wan_hotplug "up" "$WANPORT"
PREVWANMODE="$WANMODE"
if [ ! -s /tmp/qos/wan_link_shape_rate ]; then
LINKSPEED="$(awk '/far-end interleaved channel bit rate/{print $6}' /proc/tc3162/adsl_stats)"
LINKSPEED=$((LINKSPEED))
if [ "$LINKSPEED" -eq 0 ]; then
LINKSPEED="$(awk '/far-end fast channel bit rate/{print $6}' /proc/tc3162/adsl_stats)"
LINKSPEED=$((LINKSPEED))
fi
if [ "$LINKSPEED" -ne 0 ]; then
mkdir -p /tmp/qos
touch /tmp/qos/wan_link_shape_rate
/userfs/bin/qosrule discpline Rate uplink-bandwidth ${LINKSPEED}
hw_nat -! > /dev/null 2>&1
else
rm -rf /tmp/qos/wan_link_speed
/usr/sbin/qos-uplink-bandwidth
fi
fi
fi
# Toggle link state

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=ethmngr
PKG_VERSION:=3.1.4
PKG_VERSION:=3.0.8
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/hal/ethmngr.git
PKG_SOURCE_VERSION:=0283fb5cb74a7baca46c4360da680757c57c86ac
PKG_SOURCE_VERSION:=c73e5b15718ca40b2740bbe6151dfbb2bcca16df
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz
PKG_MIRROR_HASH:=skip
endif

View File

@@ -10,14 +10,19 @@ PKG_NAME:=fdtextract
PKG_RELEASE:=1
PKG_VERSION:=1.0
PKG_SOURCE_URL:=https://dev.iopsys.eu/system/fdtextract.git
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/fdtextract.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=7917dbcb29724476cd46164eec29848df1e5fb67
PKG_SOURCE_VERSION:=e3cefda3b26c9aea3021b20725ce7b31b33eebc4
PKG_MIRROR_HASH:=skip
PKG_LICENSE:=GPLv2
PKG_LICENSE_FILES:=LICENSE
RSTRIP:=true
export BUILD_DIR
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_BUILD_PARALLEL:=1
@@ -35,7 +40,9 @@ endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/fdtextract $(1)/usr/sbin/
$(STRIP) $(1)/usr/sbin/fdtextract
endef
$(eval $(call BuildPackage,$(PKG_NAME)))

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=firewallmngr
PKG_VERSION:=1.0.12
PKG_VERSION:=1.0.10
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/network/firewallmngr.git
PKG_SOURCE_VERSION:=30319c67fb4db285a2bcd272b1c10bc040eecf19
PKG_SOURCE_VERSION:=05ad0d6f7f21520eecd05429c14d1963de2a8463
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif

View File

@@ -0,0 +1,45 @@
diff --git a/plugins/out_file/file.c b/plugins/out_file/file.c
index 2e47c9666..95d28e438 100644
--- a/plugins/out_file/file.c
+++ b/plugins/out_file/file.c
@@ -27,6 +27,7 @@
#include <msgpack.h>
#include <stdio.h>
+#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -55,6 +56,7 @@ struct flb_file_conf {
int csv_column_names;
int mkdir;
struct flb_output_instance *ins;
+ char hostname[256];
};
static char *check_delimiter(const char *str)
@@ -141,6 +143,9 @@ static int cb_file_init(struct flb_output_instance *ins,
}
}
+ if (gethostname(ctx->hostname, sizeof(ctx->hostname)) != 0)
+ snprintf(ctx->hostname, sizeof(ctx->hostname), "%s", "localhost");
+
tmp = flb_output_get_property("delimiter", ins);
ret_str = check_delimiter(tmp);
if (ret_str != NULL) {
@@ -233,12 +238,8 @@ static int template_output_write(struct flb_file_conf *ctx,
int i;
msgpack_object_kv *kv;
- /*
- * Right now we treat "{time}" specially and fill the placeholder
- * with the metadata timestamp (formatted as float).
- */
- if (!strncmp(key, "time", size)) {
- fprintf(fp, "%f", flb_time_to_double(tm));
+ if (!strncmp(key, "hostname", size)) {
+ fprintf(fp, "%s", ctx->hostname);
return 0;
}

View File

@@ -1,27 +0,0 @@
diff --git a/plugins/out_file/file.c b/plugins/out_file/file.c
index 77baf6be8..04c519d5a 100644
--- a/plugins/out_file/file.c
+++ b/plugins/out_file/file.c
@@ -238,10 +238,20 @@ static int template_output_write(struct flb_file_conf *ctx,
/*
* Right now we treat "{time}" specially and fill the placeholder
- * with the metadata timestamp (formatted as float).
+ * with the metadata timestamp.
*/
if (!strncmp(key, "time", size)) {
- fprintf(fp, "%f", flb_time_to_double(tm));
+ struct tm tm_local;
+ char buf[32];
+ if (localtime_r(&tm->tm.tv_sec, &tm_local) == NULL) {
+ flb_plg_error(ctx->ins, "localtime_r failed");
+ return -1;
+ }
+ if (strftime(buf, sizeof(buf), "%b %d %H:%M:%S", &tm_local) == 0) {
+ flb_plg_error(ctx->ins, "strftime failed");
+ return -1;
+ }
+ fputs(buf, fp);
return 0;
}

View File

@@ -0,0 +1,32 @@
diff --git a/plugins/in_kmsg/in_kmsg.c b/plugins/in_kmsg/in_kmsg.c
index cd5c4cd17..9524cf194 100644
--- a/plugins/in_kmsg/in_kmsg.c
+++ b/plugins/in_kmsg/in_kmsg.c
@@ -165,6 +165,15 @@ static inline int process_line(const char *line,
flb_time_set(&ts, ctx->boot_time.tv_sec + tv.tv_sec, tv.tv_usec * 1000);
+ /* Format syslog timestamp: "Jul 03 10:31:53" */
+ time_t real_time = ctx->boot_time.tv_sec + tv.tv_sec;
+ struct tm tm_info;
+ char syslog_ts[32];
+
+ localtime_r(&real_time, &tm_info);
+ strftime(syslog_ts, sizeof(syslog_ts), "%b %d %H:%M:%S", &tm_info);
+ int syslog_ts_len = strlen(syslog_ts);
+
/* Now process the human readable message */
p = strchr(p, ';');
if (!p) {
@@ -198,7 +207,10 @@ static inline int process_line(const char *line,
FLB_LOG_EVENT_UINT64_VALUE(tv.tv_usec),
FLB_LOG_EVENT_CSTRING_VALUE("msg"),
- FLB_LOG_EVENT_STRING_VALUE((char *) p, line_len - 1));
+ FLB_LOG_EVENT_STRING_VALUE((char *) p, line_len - 1),
+
+ FLB_LOG_EVENT_CSTRING_VALUE("syslog_ts"),
+ FLB_LOG_EVENT_STRING_VALUE(syslog_ts, syslog_ts_len));
}
if (ret == FLB_EVENT_ENCODER_SUCCESS) {

View File

@@ -1,73 +0,0 @@
diff --git a/plugins/in_kmsg/in_kmsg.c b/plugins/in_kmsg/in_kmsg.c
index cd5c4cd17..15f105451 100644
--- a/plugins/in_kmsg/in_kmsg.c
+++ b/plugins/in_kmsg/in_kmsg.c
@@ -36,7 +36,6 @@
#include <sys/stat.h>
#include <sys/time.h>
#include <inttypes.h>
-#include <time.h>
#include "in_kmsg.h"
@@ -123,12 +122,17 @@ static inline int process_line(const char *line,
ctx->buffer_id++;
errno = 0;
- val = strtol(p, &end, 10);
- if ((errno == ERANGE && (val == INT_MAX || val == INT_MIN))
+ val = strtoul(p, &end, 10);
+ if ((errno == ERANGE && val == ULONG_MAX)
|| (errno != 0 && val == 0)) {
goto fail;
}
+ /* ensure something was consumed */
+ if (end == p) {
+ goto fail;
+ }
+
/* Priority */
priority = FLB_KLOG_PRI(val);
@@ -144,24 +148,35 @@ static inline int process_line(const char *line,
}
p++;
- val = strtoul(p, &end, 10);
- if ((errno == ERANGE && (val == INT_MAX || val == INT_MIN))
+ val = strtoull(p, &end, 10);
+ if ((errno == ERANGE && val == ULLONG_MAX)
|| (errno != 0 && val == 0)) {
goto fail;
}
+ /* make sure strtoull consumed something */
+ /* after the sequence number, the next char must be ',' */
+ if (end == p || *end != ',') {
+ goto fail;
+ }
+
sequence = val;
p = ++end;
/* Timestamp */
- val = strtoul(p, &end, 10);
- if ((errno == ERANGE && (val == INT_MAX || val == INT_MIN))
+ val = strtoull(p, &end, 10);
+ if ((errno == ERANGE && val == ULLONG_MAX)
|| (errno != 0 && val == 0)) {
goto fail;
}
+ /* ensure something was consumed */
+ if (end == p) {
+ goto fail;
+ }
+
tv.tv_sec = val/1000000;
- tv.tv_usec = val - (tv.tv_sec * 1000000);
+ tv.tv_usec = val - ((uint64_t)tv.tv_sec * 1000000);
flb_time_set(&ts, ctx->boot_time.tv_sec + tv.tv_sec, tv.tv_usec * 1000);

View File

@@ -110,7 +110,7 @@ configure_send_op125() {
if [ "${uci}" = "network" ]; then
[ -n "${sendopt}" ] && new_send_opt="$sendopt $opt125" || new_send_opt="$opt125"
new_send_opt="$sendopt $opt125"
uci -q set network."${intf}".sendopts="$new_send_opt"
else
new_send_opt="$sendopt$opt125"
@@ -228,7 +228,7 @@ enable_dhcp_option125() {
if [ "${proto}" = "dhcp" ]; then
if [ ${req125_present} -eq 0 ]; then
[ -n "${reqopts}" ] && newreqopts="$reqopts 125" || newreqopts="125"
newreqopts="$reqopts 125"
uci -q set network."${wan}".reqopts="$newreqopts"
fi

View File

@@ -40,22 +40,22 @@ get_vivsoi() {
#hex-string 2 character=1 Byte
# length in hex string will be twice of actual Byte length
[ "${len}" -gt 8 ] || return
[ "$len" -gt "8" ] || return
data="${opt125}"
rem_len="${len}"
while [ "${rem_len}" -gt 0 ]; do
while [ $rem_len -gt 0 ]; do
ent_id=${data:0:8}
ent_id=$(printf "%d\n" "0x$ent_id")
if [ "${ent_id}" -ne 3561 ]; then
if [ $ent_id -ne 3561 ]; then
len_val=${data:8:2}
data_len=$(printf "%d\n" "0x$len_val")
# add 4 byte for ent_id and 1 byte for len
data_len=$(( data_len * 2 + 10 ))
# move ahead data to next enterprise id
data=${data:"${data_len}":"${rem_len}"}
rem_len=$(( rem_len - data_len ))
rem_len=$(( rem_len - $data_len ))
continue
fi
@@ -66,7 +66,7 @@ get_vivsoi() {
data_len=$(( data_len * 2 + 10 ))
opt_len=$(printf "%d\n" "0x$len_val")
[ "${opt_len}" -eq 0 ] && return
[ $opt_len -eq 0 ] && return
# populate the option data of enterprise id
sub_data_len=$(( opt_len * 2))
@@ -74,7 +74,7 @@ get_vivsoi() {
sub_data=${data:10:"${sub_data_len}"}
# parsing of suboption of option 125
while [ "${sub_data_len}" -gt 0 ]; do
while [ $sub_data_len -gt 0 ]; do
# get the suboption id
sub_opt_id=${sub_data:0:2}
sub_opt_id=$(printf "%d\n" "0x$sub_opt_id")
@@ -85,20 +85,20 @@ get_vivsoi() {
sub_opt_len=$(( sub_opt_len * 2 ))
# get the value of sub option starting 4 means starting after length
sub_opt_val=${sub_data:4:"${sub_opt_len}"}
sub_opt_val=${sub_data:4:${sub_opt_len}}
# assign the value found in sub option
case "${sub_opt_id}" in
"4")
OUI=$(echo -n "${sub_opt_val}" | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
OUI=$(echo -n $sub_opt_val | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
GW_DISCOVERED=1
;;
"5")
SERIAL=$(echo -n "${sub_opt_val}" | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
SERIAL=$(echo -n $sub_opt_val | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
GW_DISCOVERED=1
;;
"6")
CLASS=$(echo -n "${sub_opt_val}" | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
CLASS=$(echo -n $sub_opt_val | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
GW_DISCOVERED=1
;;
esac
@@ -110,7 +110,7 @@ get_vivsoi() {
sub_data_len=$((sub_data_len - sub_opt_end))
# fetch next sub option hex string
sub_data=${sub_data:"${sub_opt_end}":"${sub_data_len}"}
sub_data=${sub_data:${sub_opt_end}:${sub_data_len}}
done
# move ahead data to next enterprise id
@@ -131,13 +131,15 @@ send_host_query() {
sleep 5
json_load "$(ubus call umdns browse)"
if ! json_select discovered_services; then
json_select discovered_services
if [ "${?}" -ne 0 ]; then
json_cleanup
loop=$(( loop - 1 ))
continue
fi
if ! json_select _usp-agt-mqtt._tcp; then
json_select _usp-agt-mqtt._tcp
if [ "${?}" -ne 0 ]; then
json_cleanup
loop=$(( loop - 1 ))
continue
@@ -154,7 +156,7 @@ send_host_query() {
json_get_keys keys
for key in $keys; do
json_select "${key}"
json_select $key
json_get_var _host host ""
if [ -z "${_host}" ] || [[ "${sent_host}" =~ " ${_host}" ]]; then
@@ -164,10 +166,9 @@ send_host_query() {
sent_host="${sent_host} ${_host}"
cmd="ubus call umdns query '{\"question\":\"$_host\",\"interface\":\"$intf\"}'"
sh -c "${cmd}"
eval $cmd
resp=0
json_select ..
sleep 2 # umdns query sometime takes time to resolve so adding some sleep
done
json_cleanup
@@ -184,29 +185,32 @@ get_usp_agent_id() {
fi
json_load "$(ubus call umdns browse)"
if ! json_select discovered_services; then
json_select discovered_services
if [ "${?}" -ne 0 ]; then
json_cleanup
echo "${ID}"
echo ${ID}
return 0
fi
if ! json_select _usp-agt-mqtt._tcp; then
json_select _usp-agt-mqtt._tcp
if [ "${?}" -ne 0 ]; then
json_cleanup
echo "${ID}"
echo ${ID}
return 0
fi
json_get_keys keys
for key in $keys; do
json_select "${key}"
if ! json_select "${family}"; then
json_select $key
json_select $family
if [ "${?}" -ne 0 ]; then
json_select ..
continue
fi
json_get_keys ips
for ip in $ips; do
json_get_var ip_val "${ip}"
json_get_var ip_val $ip
if [ "${ip_val}" != "${dhcp_ip}" ]; then
continue
fi
@@ -215,8 +219,8 @@ get_usp_agent_id() {
json_select txt
json_get_keys txts
for _txt in $txts; do
json_get_var text_val "${_txt}"
if [[ "${text_val:0:3}" = "ID=" ]]; then
json_get_var text_val $_txt
if [[ "${text_val:0:3}" == "ID=" ]]; then
ID="${text_val:3}"
break
fi
@@ -234,16 +238,16 @@ get_usp_agent_id() {
done
json_cleanup
echo "${ID}"
echo ${ID}
}
get_mac_address() {
ip="${1}"
device="${2}"
mac=$(grep "${ip}" /proc/net/arp | awk '{print $4}')
mac="$(cat /proc/net/arp | grep $ip | awk '{print $4}')"
if [ -z "${mac}" ]; then
arp_resp=$(arping -b -f -c 5 -I "${device}" "${ip}" | grep 'Unicast reply from' | awk '{print $5}')
arp_resp="$(arping -b -f -c 5 -I $device $ip | grep 'Unicast reply from' | awk '{print $5}')"
if [ -n "${arp_resp}" ]; then
mac=${arp_resp:1:-1}
fi
@@ -256,7 +260,7 @@ send_unknown_gw_event() {
mac="${1}"
cmd="ubus -t 5 send gateway-info.gateway.unknown '{\"hwaddr\":\"$mac\"}'"
sh -c "${cmd}"
eval $cmd
}
send_cwmp_gw_event() {
@@ -265,14 +269,14 @@ send_cwmp_gw_event() {
serial="${3}"
cmd="ubus -t 5 send gateway-info.gateway.cwmp '{\"oui\":\"$oui\",\"class\":\"$class\",\"serial\":\"$serial\"}'"
sh -c "${cmd}"
eval $cmd
}
send_usp_gw_event() {
endpoint="${1}"
cmd="ubus -t 5 send gateway-info.gateway.usp '{\"endpoint\":\"$endpoint\"}'"
sh -c "${cmd}"
eval $cmd
}
config_load gateway
@@ -283,13 +287,13 @@ if [ "${enable}" -eq 0 ]; then
return 0
fi
if [ "${wan_intf}" = "${INTERFACE}" ]; then
if [ "${1}" = "deconfig" ]; then
if [ "${wan_intf}" == "${INTERFACE}" ]; then
if [ "${1}" == "deconfig" ]; then
rm -rf /var/state/gwinfo
return 0
fi
json_load "$(ifstatus "${INTERFACE}")"
json_load "$(ifstatus ${INTERFACE})"
json_get_var dev_name device ""
json_select data
json_get_var dhcp_ip dhcpserver ""
@@ -299,7 +303,7 @@ if [ "${wan_intf}" = "${INTERFACE}" ]; then
return 0
fi
MAC=$(get_mac_address "${dhcp_ip}" "${dev_name}")
MAC="$(get_mac_address $dhcp_ip $dev_name)"
mkdir -p /var/state
touch /var/state/gwinfo
@@ -322,8 +326,8 @@ if [ "${wan_intf}" = "${INTERFACE}" ]; then
return 0
fi
len=$(echo -n "${opt125}" | wc -c)
get_vivsoi "${opt125}" "${len}"
len=$(printf "$opt125"|wc -c)
get_vivsoi "$opt125" "$len"
if [ "${GW_DISCOVERED}" -eq 0 ]; then
send_unknown_gw_event "${MAC}"
@@ -337,18 +341,19 @@ if [ "${wan_intf}" = "${INTERFACE}" ]; then
uci -q -c /var/state commit gwinfo
# Check for USP parameters
if ! ubus -t 15 wait_for umdns; then
ubus -t 15 wait_for umdns
if [ "${?}" -ne 0 ]; then
send_cwmp_gw_event "${OUI}" "${CLASS}" "${SERIAL}"
return 0
fi
resp=$(send_host_query "${dev_name}")
resp=$(send_host_query $dev_name)
if [ "${resp}" -ne 0 ]; then
send_cwmp_gw_event "${OUI}" "${CLASS}" "${SERIAL}"
return 0
fi
ID=$(get_usp_agent_id "${dhcp_ip}")
ID="$(get_usp_agent_id $dhcp_ip)"
if [ -z "${ID}" ]; then
send_cwmp_gw_event "${OUI}" "${CLASS}" "${SERIAL}"
return 0

View File

@@ -5,12 +5,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=hostmngr
PKG_VERSION:=1.4.3
PKG_VERSION:=1.3.1
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=667866b8149d3df83a05536319eac02aee0b6d75
PKG_SOURCE_VERSION:=3663ca4d001508509774115d6797b932f9ed4f69
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/hostmngr.git
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz
PKG_MIRROR_HASH:=skip

View File

@@ -8,13 +8,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=icwmp
PKG_VERSION:=9.10.10
PKG_VERSION:=9.9.10
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/bbf/icwmp.git
PKG_SOURCE_VERSION:=63251b6c9789b1428604af0a5c1d23d32d14a8b8
PKG_SOURCE_VERSION:=1a842e0a3836f616973e6a92f0b0b6ca82ec39bb
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif
@@ -84,7 +84,6 @@ define Package/icwmp/install
$(INSTALL_BIN) $(PKG_BUILD_DIR)/icwmpd $(1)/usr/sbin/icwmpd
$(INSTALL_DATA) ./files/etc/config/cwmp $(1)/etc/config/cwmp
$(INSTALL_BIN) ./files/etc/init.d/icwmpd $(1)/etc/init.d/icwmpd
$(INSTALL_BIN) ./files/etc/uci-defaults/50-cwmp-align-keep-config $(1)/etc/uci-defaults/
$(INSTALL_BIN) ./files/etc/uci-defaults/85-cwmp-set-userid $(1)/etc/uci-defaults/
$(INSTALL_BIN) ./files/etc/uci-defaults/90-cwmpfirewall $(1)/etc/uci-defaults/
$(INSTALL_BIN) ./files/etc/uci-defaults/95-set-random-inform-time $(1)/etc/uci-defaults/

View File

@@ -28,9 +28,9 @@ config cpe 'cpe'
option log_severity 'WARNING'
option log_file_name '/var/log/icwmpd.log'
option log_max_size '102400'
option bind_retries '5'
option userid '' #$OUI-$SER
option passwd ''
option port '7547'
option provisioning_code ''
option amd_version '5'
# compression possible configs: InstanceNumber, InstanceAlias
@@ -42,9 +42,7 @@ config cpe 'cpe'
option periodic_notify_interval '10'
option incoming_rule 'Port_Only'
option active_notif_throttle '0'
#option KeepConfig '1'
#option KeepOpConf '1'
#option ConfigScope 'UserOnly'
option fw_upgrade_keep_settings '1'
option clock_sync_timeout '128'
option disable_datatype_check '0'
#list allowed_cr_ip '10.5.1.0/24'

View File

@@ -133,56 +133,9 @@ add_firewall_rule() {
fi
}
remove_port_protection() {
local enabled chain rule rule_num
config_get enabled "${1}" "${2}"
if [ "${enabled}" -eq 1 ]; then
config_get zonename "$1" name
[ -n "$zonename" ] || return 0
chain='prerouting_'$zonename'_rule'
while rule=$(iptables -w -t nat -nL "$chain" --line-numbers | grep -m 1 -w CWMP_Port_protection); do
rule_num=${rule%%[$' \t']*}
iptables -w -t nat -D "$chain" "$rule_num"
done
fi
}
cleanup_port_protection() {
config_load firewall
config_foreach remove_port_protection zone masq
}
install_port_protection() {
local PORT="${3}"
local enabled zonename chain
config_get enabled "${1}" "${2}"
if [ "${enabled}" -eq 1 ]; then
config_get zonename "${1}" name
[ -n "$zonename" ] || return 0
chain='prerouting_'$zonename'_rule'
iptables -w -t nat -I "$chain" -p tcp --dport "$PORT" -j ACCEPT -m comment --comment=CWMP_Port_protection
iptables -w -t nat -I "$chain" -p udp --dport "$PORT" -j ACCEPT -m comment --comment=CWMP_Port_protection
fi
}
add_port_protection() {
config_load firewall
config_foreach install_port_protection zone masq "${1}"
}
configure_connection_req_rules() {
app="${1}"
cleanup_port_protection
wan="$(uci -q get cwmp.cpe.default_wan_interface)"
wan="${wan:-wan}"
@@ -222,11 +175,8 @@ configure_connection_req_rules() {
fi
fi
port=$(uci -q -c /var/state get icwmp.cpe.port)
if [ -z "${port}" ]; then
log "cwmp cpe port not configured"
exit 0
fi
port=$(uci -q get cwmp.cpe.port)
port="${port:-7547}"
ipaddr=$(uci -q get cwmp.cpe.allowed_cr_ip)
if [ -n "${ipaddr}" ]; then
@@ -247,8 +197,6 @@ configure_connection_req_rules() {
# Close the ACS port at Lan side
close_downstream_acs_port "${lan}" "${port}"
fi
add_port_protection "${port}"
}
load_zone_names

View File

@@ -97,9 +97,7 @@ validate_cpe_section()
'periodic_notify_enable:bool' \
'enable:bool:1' \
'periodic_notify_interval:uinteger' \
'KeepConfig:bool' \
'KeepOpConf:bool' \
'ConfigScope:string'
'fw_upgrade_keep_settings:bool'
}
validate_defaults() {
@@ -170,21 +168,13 @@ start_service() {
stop_service()
{
local switch_bank KeepConfig KeepOpConf ConfigScope
local switch_bank
copy_cwmp_varstate_files_to_etc
switch_bank=$(uci -q -c /var/state/ get icwmp.cpe.switch_bank)
if [ "$switch_bank" = "1" ] && [ -x /etc/sysmngr/fwbank ]; then
KeepConfig="$(uci -q get cwmp.cpe.KeepConfig)"
KeepOpConf="$(uci -q get cwmp.cpe.KeepOpConf)"
ConfigScope="$(uci -q get cwmp.cpe.ConfigScope)"
json_init
[ -n "${KeepConfig}" ] && json_add_boolean "keep_config" "${KeepConfig}"
[ -n "${KeepOpConf}" ] && json_add_boolean "keep_opconf" "${KeepOpConf}"
[ -n "${ConfigScope}" ] && json_add_string "config_scope" "${ConfigScope}"
json_dump| /etc/sysmngr/fwbank call copy_config
if [ -n "$switch_bank" ] && [ "$switch_bank" = "1" ]; then
[ -x /etc/sysmngr/fwbank ] && /etc/sysmngr/fwbank call copy_config
fi
}

View File

@@ -1,7 +0,0 @@
#!/bin/sh
keep_settings="$(uci -q get cwmp.cpe.fw_upgrade_keep_settings)"
if [ -n "${keep_settings}" ]; then
uci -q delete cwmp.cpe.fw_upgrade_keep_settings
uci -q set cwmp.cpe.KeepConfig="${keep_settings}"
fi

View File

@@ -5,6 +5,7 @@ uci -q batch <<-EOT
set firewall.cwmp=include
set firewall.cwmp.path=/etc/icwmpd/firewall.cwmp
set firewall.cwmp.reload=1
commit firewall
EOT
exit 0

View File

@@ -16,12 +16,12 @@ get_opt43() {
local opt43="$1"
local len="$2"
[ "${len}" -gt 2 ] || return
[ "$len" -gt "2" ] || return
first_byte=${opt43:0:2}
first_byte=$(printf "%d\n" "0x$first_byte")
if [ "${len}" -ge 4 ] && [ "${first_byte}" -ge 1 ] && [ "${first_byte}" -le 4 ]; then
if [ $len -ge 4 ] && [ $first_byte -ge 1 ] && [ $first_byte -le 4 ]; then
# it is in encapsulated form
# opt43 encapsulated vendor-specific option has data in below format
# Code Len Data item Code Len Data item Code
@@ -35,7 +35,7 @@ get_opt43() {
data="${opt43}"
rem_len="${len}"
# parsing of suboption of option 43
while [ "${rem_len}" -gt 0 ]; do
while [ $rem_len -gt 0 ]; do
# get the suboption id
sub_opt_id=${data:0:2}
sub_opt_id=$(printf "%d\n" "0x$sub_opt_id")
@@ -50,13 +50,13 @@ get_opt43() {
# assign the value found in sub option
case "${sub_opt_id}" in
"1") DHCP_ACS_URL=$(echo -n "${sub_opt_val}" | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
"1") DHCP_ACS_URL=$(echo -n $sub_opt_val | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
;;
"2") DHCP_PROV_CODE=$(echo -n "${sub_opt_val}" | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
"2") DHCP_PROV_CODE=$(echo -n $sub_opt_val | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
;;
"3") MIN_WAIT_INVL=$(echo -n "${sub_opt_val}" | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
"3") MIN_WAIT_INVL=$(echo -n $sub_opt_val | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
;;
"4") INVL_MULTIPLIER=$(echo -n "${sub_opt_val}" | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
"4") INVL_MULTIPLIER=$(echo -n $sub_opt_val | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
;;
esac
@@ -70,14 +70,13 @@ get_opt43() {
rem_len=$((rem_len - sub_opt_end))
done
else
DHCP_ACS_URL=$(echo -n "${opt43}" | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
DHCP_ACS_URL=$(echo -n $opt43 | sed 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI' | xargs printf && echo '')
fi
}
config_load cwmp
config_get wan_intf cpe default_wan_interface "wan"
config_get dhcp_discovery acs dhcp_discovery "0"
config_get_bool insecure_enable acs insecure_enable "0"
config_get dhcp_url acs dhcp_url ""
config_get min_wait_intvl acs dhcp_retry_min_wait_interval "0"
config_get intvl_multi acs dhcp_retry_interval_multiplier "0"
@@ -93,9 +92,9 @@ if [ "$discovery_enable" = "0" ]; then
return 0
fi
if [ "${wan_intf}" = "${INTERFACE}" ]; then
if [ "${wan_intf}" == "${INTERFACE}" ]; then
if [ -n "$opt43" ]; then
len=$(echo -n "$opt43"|wc -c)
len=$(printf "$opt43"|wc -c)
get_opt43 "$opt43" "$len"
fi
@@ -103,17 +102,6 @@ if [ "${wan_intf}" = "${INTERFACE}" ]; then
return 0
fi
if [ "${insecure_enable}" -eq "0" ]; then
case $DHCP_ACS_URL in
https://*)
log "ACS url $DHCP_ACS_URL has https"
;;
*)
return 0
;;
esac
fi
sec=$(uci -q get cwmp.acs)
if [ -z "${sec}" ]; then

View File

@@ -6,12 +6,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=ieee1905
PKG_VERSION:=8.7.44
PKG_VERSION:=8.7.33
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=29ba8f04dc6bd7e77683352c0c71988f51fbadf8
PKG_SOURCE_VERSION:=cb5b8f76c854b89607cd1750d3a4052ecd71ac9d
PKG_SOURCE_URL:=https://dev.iopsys.eu/multi-ap/ieee1905.git
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz
PKG_MIRROR_HASH:=skip

View File

@@ -4,7 +4,7 @@ PKG_NAME:=iopsys-analytics
PKG_RELEASE:=$(COMMITCOUNT)
PKG_LICENSE:=PROPRIETARY
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=5ad41ca8eb5de887487feb7148b5dce44943218c
PKG_SOURCE_VERSION:=25e32ac5a860aec6e53e3449565b71595073e014
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/iopsys-analytics.git
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz
PKG_MIRROR_HASH:=skip
@@ -33,10 +33,6 @@ define Package/$(PKG_NAME)
DEPENDS+= \
+@PACKAGE_syslog-ng:SYSLOGNG_LOGROTATE \
+PACKAGE_fluent-bit:logrotate \
+@DMCLI_REMOTE_CONNECTION
# tools used in development/testing
DEPENDS+= \
+iperf3
endef

View File

@@ -5,12 +5,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=libdpp
PKG_VERSION:=2.1.3
PKG_VERSION:=2.1.1
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=fdfe23e51ff77ca6d2661ad6208d097758524147
PKG_SOURCE_VERSION:=6024efd3db9dd490c07465ea9b0c15120063165c
PKG_SOURCE_URL:=https://dev.iopsys.eu/multi-ap/libdpp.git
PKG_MAINTAINER:=Jakob Olsson <jakob.olsson@iopsys.eu>
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=libdsl
PKG_VERSION:=7.3.2
PKG_VERSION:=7.3.0
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/hal/libdsl.git
PKG_SOURCE_VERSION:=1aa9c40f9503311652e562617b1e15533257adcc
PKG_SOURCE_VERSION:=2a7a49fac35c3d8078ffe051594c0425d355cacd
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz
PKG_MIRROR_HASH:=skip
endif

View File

@@ -1,28 +1,32 @@
#
# Copyright (C) 2025 Genexis Sweden AB
# Copyright (C) 2020-2023 Iopsys
#
include $(TOPDIR)/rules.mk
PKG_NAME:=libeasy
PKG_VERSION:=7.5.1
PKG_VERSION:=7.4.6
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=b981f7e1bd51f66041cd0c25d15af74ae1e3bc75
PKG_SOURCE_URL:=https://dev.iopsys.eu/hal/libeasy.git
PKG_SOURCE_VERSION:=ca7b20068c9d373e41045a2e899a9c697576262c
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/libeasy.git
PKG_MAINTAINER:=Anjan Chanda <anjan.chanda@iopsys.eu>
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz
PKG_MIRROR_HASH:=skip
endif
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_LICENSE:=LGPL-2.1-only
PKG_LICENSE_FILES:=
PKG_MAINTAINER:=Anjan Chanda <anjan.chanda@genexis.eu>
PKG_LICENSE_FILES:=LICENSE
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/cmake.mk
TARGET_CFLAGS += \
-I$(STAGING_DIR)/usr/include \
-I$(STAGING_DIR)/usr/include/openssl \
-I$(STAGING_DIR)/usr/include/libnl3
ifeq ($(LOCAL_DEV),1)
define Build/Prepare
@@ -30,6 +34,9 @@ define Build/Prepare
endef
endif
MAKE_FLAGS += \
CFLAGS="$(TARGET_CFLAGS) -Wall"
define Package/libeasy
SECTION:=libs
CATEGORY:=Libraries
@@ -40,7 +47,7 @@ define Package/libeasy
endef
define Package/libeasy/description
This package provides libeasy.so for common utility functions.
Library provides common utility functions
endef
define Build/InstallDev/libeasy
@@ -60,7 +67,6 @@ define Build/InstallDev/libeasy
endef
define Build/InstallDev
$(call Build/InstallDev/cmake,$(1))
$(call Build/InstallDev/libeasy,$(1),$(2))
endef

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=libqos
PKG_VERSION:=7.2.111
PKG_VERSION:=7.2.109
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/libqos.git
PKG_SOURCE_VERSION:=2e4c6a9c27e0f4f68dfe7a5c930afefd8dc7119a
PKG_SOURCE_VERSION:=4948d372c3d7e43a0ba9aee517dbb83b94bba3dc
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz
PKG_MIRROR_HASH:=skip
endif
@@ -65,7 +65,7 @@ define Package/libqos
SUBMENU:=IOPSYS HAL libs
MENU:=1
TITLE:= QoS library (libqos)
DEPENDS+=+libnl +libnl-route +libeasy +TARGET_brcmbca:bcm963xx-bsp +TARGET_airoha:libuci
DEPENDS+=+libnl +libnl-route +libeasy +TARGET_brcmbca:bcm963xx-bsp
endef
define Package/libqos/config

View File

@@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=libvoice-airoha
PKG_RELEASE:=1
PKG_VERSION:=1.1.8
PKG_VERSION:=1.1.7
PKG_LICENSE:=PROPRIETARY
PKG_LICENSE_FILES:=LICENSE
@@ -17,7 +17,7 @@ LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/$(PKG_NAME).git
PKG_SOURCE_VERSION:=9763c574ec69e2aa492db4f1296d4bcd53776fba
PKG_SOURCE_VERSION:=3a30086a68a3409f0396acb01380f91daabf7a2f
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif

View File

@@ -25,5 +25,6 @@ db commit
# configure the PCM for DECT/DCX81
[ -f "/proc/device-tree/aliases/dcx81-uart" ] && {
uci set dect.global.pcm_fsync='SHORT_LF'
uci set dect.global.pcm_slot_start='8'
uci set dect.global.dect_channel_start='3'
}

View File

@@ -1,32 +1,27 @@
#
# Copyright (C) 2019-2024 Iopsys
# Copyright (C) 2025 Genexis Sweden AB
# Copyright (C) 2020-2023 Iopsys
#
include $(TOPDIR)/rules.mk
PKG_NAME:=libwifi
PKG_VERSION:=7.22.10
PKG_VERSION:=7.13.7
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=4759a74db66dd0b4bfa6707683129a317ae42779
PKG_SOURCE_URL:=https://dev.iopsys.eu/hal/libwifi.git
PKG_SOURCE_VERSION:=65a7cd643c07e3f0a11d5b20225d4d87b8646513
PKG_SOURCE_URL:=https://dev.iopsys.eu/iopsys/libwifi.git
PKG_MAINTAINER:=Anjan Chanda <anjan.chanda@iopsys.eu>
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz
PKG_MIRROR_HASH:=skip
endif
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_LICENSE:=LGPL-2.1-only
PKG_LICENSE_FILES:=
PKG_MAINTAINER:=Anjan Chanda <anjan.chanda@genexis.eu>
MAKE_VERBOSE := 1
PKG_LICENSE_FILES:=LICENSE
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/kernel.mk
include $(INCLUDE_DIR)/cmake.mk
ifeq ($(CONFIG_TARGET_brcmbca),y)
TARGET_PLATFORM=BROADCOM
@@ -47,20 +42,10 @@ else ifeq ($(CONFIG_TARGET_armvirt),y)
else ifeq ($(CONFIG_TARGET_airoha),y)
TARGET_PLATFORM=ECONET
TARGET_WIFI_TYPE=MEDIATEK
TARGET_CFLAGS +=-DIOPSYS_ECONET -I$(LINUX_DIR)/include/uapi/linux/mtk_nl80211_inc
TARGET_CFLAGS +=-DIOPSYS_ECONET
ifeq ($(CONFIG_TARGET_airoha_an7581),y)
TARGET_CFLAGS +=-DCONFIG_MTK
endif
else ifeq ($(CONFIG_TARGET_mediatek),y)
TARGET_PLATFORM=MEDIATEK
TARGET_WIFI_TYPE=MAC80211
ifeq ($(CONFIG_TARGET_DEVICE_mediatek_filogic_DEVICE_cx750),y)
TARGET_WIFI_TYPE=MEDIATEK
TARGET_CFLAGS +=-DCONFIG_MTK -I$(LINUX_DIR)/include/uapi/linux/mtk_nl80211_inc
else ifeq ($(CONFIG_TARGET_DEVICE_mediatek_filogic_DEVICE_mediatek_mt7987a-spim-nand-an8801sb),y)
TARGET_WIFI_TYPE=MEDIATEK
TARGET_CFLAGS +=-DCONFIG_MTK -I$(LINUX_DIR)/include/uapi/linux/mtk_nl80211_inc
endif
else ifeq ($(CONFIG_TARGET_ipq95xx),y)
TARGET_PLATFORM=IPQ95XX
TARGET_WIFI_TYPE=QUALCOMM
@@ -76,13 +61,13 @@ else
endif
ifneq ($(CONFIG_PACKAGE_kmod-mt7915e_en7523),)
TARGET_CFLAGS +=-DMT7915_VENDOR_EXT
TARGET_CFLAGS=-DMT7915_VENDOR_EXT
endif
PKG_BUILD_DEPENDS:=PACKAGE_kmod-mt7915e_en7523:mt76_en7523
ifneq ($(CONFIG_PACKAGE_libwifi),)
CMAKE_OPTIONS +=-DHAS_WIFI=ON
TARGET_CFLAGS +=-DHAS_WIFI
endif
ifeq ($(CONFIG_LIBWIFI_USE_CTRL_IFACE),y)
@@ -93,8 +78,18 @@ ifeq ($(CONFIG_LIBWIFI_SKIP_PROBES),y)
TARGET_CFLAGS +=-DLIBWIFI_BRCM_SKIP_PROBES
endif
TARGET_CFLAGS += \
-I$(STAGING_DIR)/usr/include \
-I$(STAGING_DIR)/usr/include/openssl \
-I$(STAGING_DIR)/usr/include/libnl3
CMAKE_OPTIONS += -DPLATFORM=$(TARGET_PLATFORM) -DWIFI_TYPE=$(TARGET_WIFI_TYPE)
MAKE_FLAGS += \
CFLAGS="$(TARGET_CFLAGS) -Wall -I./" \
LDFLAGS="$(TARGET_LDFLAGS)" \
FPIC="$(FPIC)" \
PLATFORM="$(TARGET_PLATFORM)" \
WIFI_TYPE="$(TARGET_WIFI_TYPE)" \
subdirs="$(subdirs)"
ifeq ($(LOCAL_DEV),1)
define Build/Prepare
@@ -102,39 +97,43 @@ define Build/Prepare
endef
endif
define Package/libwifiutils
SECTION:=libs
CATEGORY:=Libraries
TITLE:= WiFi utility library (libwifiutils.so)
DEPENDS+=+libnl +libnl-route +libeasy +libopenssl
endef
define Package/libwifiutils/description
Library provides WiFi utility functions
endef
define Package/libwifi
SECTION:=libs
CATEGORY:=Libraries
TITLE:= WiFi HAL library (libwifi-7.so.m)
DEPENDS+=+libnl +libnl-route +libeasy +libwifiutils +TARGET_brcmbca:bcm963xx-bsp
define Package/libwifi-common
SECTION:=libs
CATEGORY:=Libraries
TITLE:=libwifi
SUBMENU:=IOPSYS HAL libs
DEPENDS:=+libopenssl
MENU:=1
endef
define Package/libwifi/description
Library provides WiFi HAL APIs
Library provides WiFi HAL APIs and WiFi common utility functions
endef
define Package/libwifiutils
$(call Package/libwifi-common)
TITLE:= WiFi utility library (libwifiutils.so)
DEPENDS+=+libnl +libnl-route +libeasy
endef
define Build/InstallDev/libwifiutils
$(INSTALL_DIR) $(1)/usr/include
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_BUILD_DIR)/libwifiutils/wifidefs.h $(1)/usr/include/
$(CP) $(PKG_BUILD_DIR)/libwifiutils/wifiutils.h $(1)/usr/include/
$(CP) $(PKG_BUILD_DIR)/libwifiutils/libwifiutils*.so* $(1)/usr/lib/
$(CP) $(PKG_BUILD_DIR)/wifidefs.h $(1)/usr/include/
$(CP) $(PKG_BUILD_DIR)/wifiutils.h $(1)/usr/include/
$(CP) $(PKG_BUILD_DIR)/libwifiutils*.so* $(1)/usr/lib/
endef
define Package/libwifiutils/install
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_BUILD_DIR)/libwifiutils/libwifiutils*.so* $(1)/usr/lib/
$(CP) $(PKG_BUILD_DIR)/libwifiutils*.so* $(1)/usr/lib/
endef
define Package/libwifi
$(call Package/libwifi-common)
TITLE:= WiFi library (libwifi)
DEPENDS+=+libnl +libnl-route +libeasy +libwifiutils +TARGET_brcmbca:bcm963xx-bsp
endef
define Package/libwifi/config
@@ -155,12 +154,13 @@ define Package/libwifi/config
endif
endef
define Build/InstallDev/libwifi
$(INSTALL_DIR) $(1)/usr/include
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_BUILD_DIR)/libwifi/wifiops.h $(1)/usr/include/
$(CP) $(PKG_BUILD_DIR)/libwifi/wifi.h $(1)/usr/include/
$(CP) $(PKG_BUILD_DIR)/libwifi/libwifi-7*.so* $(1)/usr/lib/
$(CP) $(PKG_BUILD_DIR)/wifiops.h $(1)/usr/include/
$(CP) $(PKG_BUILD_DIR)/wifi.h $(1)/usr/include/
$(CP) $(PKG_BUILD_DIR)/libwifi-7*.so* $(1)/usr/lib/
endef
@@ -173,7 +173,7 @@ endef
define Package/libwifi/install
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_BUILD_DIR)/libwifi/libwifi-7*.so* $(1)/usr/lib/
$(CP) $(PKG_BUILD_DIR)/libwifi-7*.so* $(1)/usr/lib/
endef
$(eval $(call BuildPackage,libwifiutils))

View File

@@ -31,8 +31,8 @@ MESON_ARGS += \
define Package/linux-pam/install
$(INSTALL_DIR) $(1)/usr/lib/security
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./linux_pam.init $(1)/etc/init.d/linux_pam
$(INSTALL_DIR) $(1)/etc/uci-defaults/
$(INSTALL_BIN) ./files/pam_faillock.uci_default $(1)/etc/uci-defaults/99-add_pam_faillock
endef
$(eval $(call BuildPackage,linux-pam))

View File

@@ -0,0 +1,43 @@
#!/bin/sh
create_faillock_files()
{
# also create files needed by pam_faillock
touch /var/log/faillock
chmod 700 /var/log/faillock
touch /var/log/btmp
chmod 700 /var/log/btmp
}
update_pam_common_auth()
{
local file="/etc/pam.d/common-auth"
local deny=6
local unlock_time=300
# update pam_unix.so line
sed -i -E 's|^.*pam_unix\.so.*|auth\t sufficient\tpam_unix.so nullok_secure|' "$file"
# Insert pam_faillock lines before and after pam_unix.so
sed -i -E "/pam_unix.so nullok_secure/i auth required pam_faillock.so preauth deny=$deny even_deny_root unlock_time=$unlock_time" "$file"
sed -i -E "/pam_unix.so nullok_secure/a auth [default=die] pam_faillock.so authfail audit deny=$deny even_deny_root unlock_time=$unlock_time" "$file"
}
update_pam_common_account()
{
# update account file
sed -i "/pam_unix.so/ i account required pam_faillock.so" /etc/pam.d/common-account
}
if [ -f "/usr/lib/security/pam_faillock.so" ]; then
update_pam_common_auth
update_pam_common_account
create_faillock_files
fi
if [ -f /etc/config/sshd ]; then
uci -q set sshd.@sshd[0].UsePAM=1
uci commit sshd
fi
exit 0

View File

@@ -1,18 +0,0 @@
#!/bin/sh /etc/rc.common
START=11
STOP=90
USE_PROCD=1
create_faillock_files()
{
# also create files needed by pam_faillock
touch /var/log/faillock
chmod 700 /var/log/faillock
touch /var/log/btmp
chmod 700 /var/log/btmp
}
boot() {
create_faillock_files
}

View File

@@ -1,5 +1,4 @@
if PACKAGE_logmngr
choice
prompt "Select backend for syslog management"
default LOGMNGR_BACKEND_FLUENTBIT
@@ -32,5 +31,4 @@ config LOGMNGR_VENDOR_LOG_FILE
default y
help
It adds support for Device.DeviceInfo.VendorLogFile. Object.
endif

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=logmngr
PKG_VERSION:=1.1.4
PKG_VERSION:=1.0.17
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/system/logmngr.git
PKG_SOURCE_VERSION:=62441fdfe14a39bff8fff7c62307bd7b54d7240f
PKG_SOURCE_VERSION:=ad2636c642d56967e78c0c84bf82cb0e2b6311f2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif
@@ -52,37 +52,29 @@ endif
define Package/logmngr/install
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_BIN) ./files/logmngr.init $(1)/etc/init.d/logmngr
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/10-logmngr_config_generate $(1)/etc/uci-defaults/
$(INSTALL_BIN) ./files/etc/init.d/logmngr $(1)/etc/init.d/
$(INSTALL_DATA) ./files/etc/config/logmngr $(1)/etc/config/
$(INSTALL_DATA) ./files/etc/uci-defaults/10-logmngr_config_migrate $(1)/etc/uci-defaults/
$(BBFDM_INSTALL_MS_PLUGIN) $(PKG_BUILD_DIR)/bbf_plugin/libbbfsyslog.so $(1) core 10
# Install logmngr service backend
$(INSTALL_DIR) $(1)/lib/logmngr
ifeq ($(CONFIG_LOGMNGR_BACKEND_FLUENTBIT),y)
$(INSTALL_DIR) $(1)/sbin
$(INSTALL_DIR) $(1)/etc/hotplug.d/ntp/
$(INSTALL_BIN) ./files/logread $(1)/sbin/
$(INSTALL_DATA) ./files/lib/logmngr/fluent-bit.sh $(1)/lib/logmngr/
$(INSTALL_BIN) ./files/etc/hotplug.d/ntp/20-reload_fluent_bit $(1)/etc/hotplug.d/ntp/
else ifeq ($(CONFIG_LOGMNGR_BACKEND_SYSLOG_NG),y)
$(INSTALL_DIR) $(1)/sbin
$(INSTALL_BIN) ./files/logread $(1)/sbin/
endif
ifeq ($(CONFIG_LOGMNGR_BACKEND_SYSLOG_NG),y)
$(INSTALL_DATA) ./files/lib/logmngr/syslog-ng.sh $(1)/lib/logmngr/
endif
$(BBFDM_INSTALL_MS_PLUGIN) $(PKG_BUILD_DIR)/bbf_plugin/libbbfsyslog.so $(1) core 10
ifeq ($(CONFIG_LOGMNGR_LOGROTATE),y)
$(INSTALL_BIN) ./files/11-logmngr_logrotate_config_generate $(1)/etc/uci-defaults/
$(INSTALL_DATA) ./files/lib/logmngr/logrotate.sh $(1)/lib/logmngr/
$(INSTALL_DATA) ./files/etc/uci-defaults/11-logmngr_logrotate_syslog $(1)/etc/uci-defaults/
$(BBFDM_INSTALL_MS_PLUGIN) $(PKG_BUILD_DIR)/bbf_plugin/libbbflogrotate.so $(1) sysmngr 11
endif
ifeq ($(CONFIG_LOGMNGR_VENDOR_LOG_FILE),y)
$(BBFDM_INSTALL_MS_PLUGIN) $(PKG_BUILD_DIR)/bbf_plugin/libbbfvendorlog.so $(1) sysmngr 12
endif
endef
$(eval $(call BuildPackage,logmngr))

View File

@@ -0,0 +1,26 @@
#!/bin/sh
if uci -q get logmngr.@globals[0] >/dev/null; then
# return if there is any valid content
exit 0
else
rm -f /etc/config/logmngr
fi
touch /etc/config/logmngr
uci set logmngr.globals=globals
uci set logmngr.globals.enable=1
uci set logmngr.a1=action
uci set logmngr.a1.name="ac1"
uci set logmngr.lf1=log_file
uci set logmngr.lf1.enable=1
uci set logmngr.lf1.action="ac1"
uci set logmngr.lf1.file="/var/log/messages"
uci set logmngr.lr1=log_remote
uci set logmngr.lr1.enable=0
uci set logmngr.lr1.action="ac1"
uci set logmngr.lr1.port="514"

View File

@@ -1,7 +1,7 @@
#!/bin/sh
# Adds a default log rotate policy if none exists
if uci -q get logmngr.lro1 >/dev/null; then
if uci -q get logmngr.@log_rotate[0] >/dev/null; then
# return if there is any valid content
exit 0
fi

View File

@@ -1,26 +0,0 @@
config globals 'globals'
option enable '1'
config source 'default_source'
option name 'default_source'
option system_messages '1'
option kernel_messages '1'
config template 'default_template'
option name 'default_template'
option expression '{time} {hostname} {ident}[{pid}]: {message}'
config action 'default_action'
option name 'default_action'
list source 'default_source'
option template 'default_template'
config log_file 'lf1'
option enable '1'
option action 'default_action'
option file '/var/log/messages'
config log_remote 'lr1'
option enable '0'
option action 'default_action'
option port '514'

View File

@@ -1,14 +0,0 @@
#!/bin/sh
# This hotplug script reloads fluent-bit, so that kmsg logs' timestamp gets in sync
[ "$ACTION" = stratum ] || exit 0
# only once
if ! uci -q get time.global.first_use_date > /dev/null 2>&1; then
flb_pid="$(pidof fluent-bit)"
if [ -n "$flb_pid" ]; then
logger -t "logmngr.hotplug" -p info "reload fluent-bit due to ntp sync"
kill -SIGHUP "$flb_pid"
fi
fi

View File

@@ -1,36 +0,0 @@
#!/bin/sh
# check if this is a new type UCI or old type UCI
if ! uci -q get logmngr.default_source > /dev/null; then
uci -q set logmngr.default_source=source
uci -q set logmngr.default_source.name='default_source'
uci -q set logmngr.default_source.system_messages='1'
uci -q set logmngr.default_source.kernel_messages='1'
fi
if ! uci -q get logmngr.default_template > /dev/null; then
uci -q set logmngr.default_template=template
uci -q set logmngr.default_template.name='default_template'
uci -q set logmngr.default_template.expression='{time} {hostname} {ident}[{pid}]: {message}'
fi
if uci -q get logmngr.a1 >/dev/null; then
uci -q rename logmngr.a1='default_action'
uci -q set logmngr.default_action.name='default_action'
uci -q set logmngr.default_action.template='default_template'
uci -q delete logmngr.default_action.source
uci -q add_list logmngr.default_action.source='default_source'
fi
if uci -q get logmngr.lf1 >/dev/null; then
uci -q rename logmngr.lf1='default_logfile'
uci -q set logmngr.default_logfile.action='default_action'
fi
if uci -q get logmngr.lr1 >/dev/null; then
uci -q rename logmngr.lr1='default_logremote'
uci -q set logmngr.default_logremote.action='default_action'
fi
exit 0

View File

@@ -6,37 +6,6 @@
CONF_FILE=/etc/fluent-bit/fluent-bit.conf
TMP_CONF_FILE=/tmp/fluent-bit/fluent-bit.conf
FLUENT_BIT_CONF_DIR=/etc/fluent-bit/conf.d
PROCESSED_SYSLOG_TAGS=""
PROCESSED_KMSG_TAGS=""
# check if syslog source section is already processed
# and add it to the list of processed source sections
syslog_tag_already_processed() {
local tag="$1"
for t in $PROCESSED_SYSLOG_TAGS; do
[ "$t" = "$tag" ] && return 0
done
PROCESSED_SYSLOG_TAGS="$tag $PROCESSED_SYSLOG_TAGS"
return 1
}
# check if kmsg source section is already processed
# and add it to the list of processed source sections
# two separate functions used because we want to populate
# appropriate PROCESSED variable
kmsg_tag_already_processed() {
local tag="$1"
for t in $PROCESSED_KMSG_TAGS; do
[ "$t" = "$tag" ] && return 0
done
PROCESSED_KMSG_TAGS="$tag $PROCESSED_KMSG_TAGS"
return 1
}
append_conf() {
echo "$*" >> ${TMP_CONF_FILE}
@@ -51,282 +20,219 @@ create_config_file() {
# also, if no file is found then fluent-bit aborts
# so only add include if any file is present in the FLUENT_BIT_CONF_DIR
if [ -d "$FLUENT_BIT_CONF_DIR" ] && [ "$(ls -A "$FLUENT_BIT_CONF_DIR")" ]; then
append_conf "@INCLUDE ${FLUENT_BIT_CONF_DIR}/*"
echo "@INCLUDE ${FLUENT_BIT_CONF_DIR}/*" >> ${TMP_CONF_FILE}
fi
append_conf ""
echo "" >> ${TMP_CONF_FILE}
}
create_service_section() {
# the service section of the fluent-bit.conf file has hardcoded values,
# no need to lookup any uci section to configure this section
append_conf "[SERVICE]"
append_conf " flush 1"
append_conf " daemon off"
append_conf " log_level info"
append_conf " coro_stack_size 1048576"
append_conf " parsers_file /etc/fluent-bit/parsers.conf"
append_conf " hot_reload on"
append_conf ""
}
echo "[SERVICE]" >> ${TMP_CONF_FILE}
echo " flush 1" >> ${TMP_CONF_FILE}
echo " daemon off" >> ${TMP_CONF_FILE}
echo " log_level info" >> ${TMP_CONF_FILE}
echo " coro_stack_size 24576" >> ${TMP_CONF_FILE}
echo " parsers_file /etc/fluent-bit/parsers.conf" >> ${TMP_CONF_FILE}
echo " hot_reload on" >> ${TMP_CONF_FILE}
echo "" >> ${TMP_CONF_FILE}
create_default_filters() {
append_conf "[FILTER]"
append_conf " name modify"
append_conf " match KM*"
append_conf " add ident kernel"
append_conf " rename msg message"
append_conf ""
# Generate default input for kmsg
echo "[INPUT]" >> ${TMP_CONF_FILE}
echo " name kmsg" >> ${TMP_CONF_FILE}
echo " Tag KMSG" >> ${TMP_CONF_FILE}
echo "" >> ${TMP_CONF_FILE}
append_conf "[FILTER]"
append_conf " name modify"
append_conf " match *"
append_conf " add pid 0"
append_conf ""
append_conf "[FILTER]"
append_conf " name sysinfo"
append_conf " match *"
append_conf " hostname_key hostname"
append_conf ""
echo "[OUTPUT]" >> ${TMP_CONF_FILE}
echo " name file" >> ${TMP_CONF_FILE}
echo " match KMSG" >> ${TMP_CONF_FILE}
echo " file /var/log/messages" >> ${TMP_CONF_FILE}
echo " format template" >> ${TMP_CONF_FILE}
echo " template {syslog_ts} {hostname} kernel: {msg}" >> ${TMP_CONF_FILE}
echo "" >> ${TMP_CONF_FILE}
}
create_input_section() {
local tag="$1"
[ -z "$tag" ] && return
# check if this source section has already been processed
syslog_tag_already_processed "$tag" && return
append_conf "[INPUT]"
append_conf " name syslog"
append_conf " unix_perm 0666"
append_conf " tag $tag"
append_conf " path /dev/log"
append_conf ""
# the input in our case is always syslog, hence, this section of the
# fluent-bit.conf file has hardcoded values as well that do not depend
# on any uci value
echo "[INPUT]" >> ${TMP_CONF_FILE}
echo " name syslog" >> ${TMP_CONF_FILE}
echo " tag $tag" >> ${TMP_CONF_FILE}
echo " path /dev/log" >> ${TMP_CONF_FILE}
echo "" >> ${TMP_CONF_FILE}
}
populate_allowed_logs() {
local facility_level sev_level
local section="$1"
generate_facility_regex() {
local facility_level=$1
local pri=0
[ -z "$section" ] && return
# reset
match_pattern=""
facilities=""
all_facilities=0
kern_facility=0
severities=""
sev_compare=1
sev_action=0
# read config
config_get match_pattern $section pattern_match
config_get facility_level $section facility_level
config_get sev_level $section severity_level
config_get sev_compare $section severity_compare 1
config_get sev_action $section severity_action 0
# normalize facilities
if [ -n "$facility_level" ]; then
for f in $facility_level; do
if [ "$f" = "24" ]; then
all_facilities=1
# xargs is used to convert from new line separated numbers to space separated numbers
facilities="$(seq 0 23 | xargs)"
break
fi
if [ "$f" = "0" ]; then
kern_facility=1
fi
done
if [ "$all_facilities" -eq 0 ]; then
facilities="$facility_level"
fi
else
# default to "all facilities" when unset
all_facilities=1
facilities="$(seq 0 23 | xargs)"
fi
# normalize severities
case "$sev_level" in
8) # all severities
severities="$(seq 0 7 | xargs)"
;;
9) # none
severities="none"
;;
"") # unset, treat as "all"
severities="$(seq 0 7 | xargs)"
;;
*)
if [ "$sev_compare" = "0" ]; then
# equal
severities="$sev_level"
else
# equl or higher
severities="$(seq 0 $sev_level | xargs)"
fi
;;
esac
}
create_filter_section() {
local match_regex="$1"
local pattern="$2"
[ -z "$match_regex" ] && return
append_conf "[FILTER]"
append_conf " name grep"
append_conf " match_regex $match_regex"
# we need "logical_op or" only in non-pattern sections
if [ "$pattern" = "0" ]; then
append_conf " logical_op or" # handle multiple filters
fi
}
create_kmsg_input_section() {
local tag="$1"
local max_sev=7
[ -z "$tag" ] && return
kmsg_tag_already_processed "$tag" && return
if [ -c "/dev/kmsg" ]; then
append_conf "[INPUT]"
append_conf " name kmsg"
append_conf " tag $tag"
# check kern facility (0)
if [ "$all_facilities" -eq 1 ] || [ "$kern_facility" -eq 1 ]; then
if [ "$severities" != "none" ]; then
# severity filtering
# only EqualOrHigher is supported by Prio_Level
# and only Log action is supported
# so set Prio_Level = max severity
if [ "$sev_action" = "0" ] && [ "$sev_compare" = "1" ]; then
if [ -n "$severities" ]; then
max_sev=$(echo $severities | tr ' ' '\n' | sort -n | tail -1)
fi
append_conf " prio_level $max_sev"
fi
fi
fi
append_conf ""
# if severities is none, or
# if kern facility has been excluded
# then we need to stop kernel logs
# sev_action and sev_compare is being checked because we don't want to work with rules that exclude logs
if [ "$severities" = "none" ] || { [ "$kern_facility" -eq 0 ] && [ "$all_facilities" -eq 0 ] && [ "$sev_action" = "0" ] && [ "$sev_compare" = "1" ]; }; then
# block all
# create a filter section that matches on KM* tag
# and excludes all messages
create_filter_section "KM*" "0"
append_conf " exclude message ^.*$"
append_conf ""
fi
fi
}
generate_syslog_filter() {
local param="regex"
[ "$sev_action" = "1" ] && param="exclude"
# start adding the fluent-bit filter section
create_filter_section "SL*" "0"
if [ "$severities" = "none" ]; then
append_conf " exclude pri ^.*$"
if [ "$facility_level" == "24" ]; then
# value 24 means all facility level, which is as good as not
# generating a filter section, so return
return
fi
for fval in $facilities; do
for sval in $severities; do
local pri=$((fval * 8 + sval))
append_conf " $param pri ^${pri}$"
# facility_level is a list value, hence, generate regex for
# each value
IFS=" "
for val in $facility_level; do
# as per rfc 5424 and 3164, pri in syslog msg is
# facility*8+severity. Severity value can range from 0-7 hence
# generate regex for each.
for sval in 0 1 2 3 4 5 6 7; do
pri=`expr $val \* 8 + $sval`
echo " regex pri $pri" >> ${TMP_CONF_FILE}
done
done
append_conf ""
}
generate_pattern_filter() {
local match_regex="$1"
local match_pattern="$2"
generate_severity_regex() {
local sev_level="$1"
local sev_compare="$2"
local sev_action="$3"
[ -z "$match_regex" ] && return
[ -z "$match_pattern" ] && return
local pri=0
local param="exclude"
# start adding the fluent-bit filter section
create_filter_section "$match_regex" "1"
append_conf " regex message $match_pattern"
append_conf ""
if [ "$sev_action" == "0" ]; then
param="regex"
fi
local fval=0
if [ "$sev_compare" == "0" ]; then
# generate regex for all facility values, with severity=sev_level
while [ $fval -le 23 ] ; do
pri=`expr $fval \* 8 + $sev_level`
echo " $param pri $pri" >> ${TMP_CONF_FILE}
fval=$((fval + 1))
done
elif [ "$sev_compare" == "1" ]; then
# generate regex for all severity value greater than or equal to
# sev_level. please, lower value have higher precedence, so sev_level
# 0 which is emergency has higher precedence than error which is 3
while [ $fval -le 23 ] ; do
sval=0
while [ $sev_level -ge $sval ]; do
pri=`expr $fval \* 8 + $sval`
echo " $param pri $pri" >> ${TMP_CONF_FILE}
sval=$((sval + 1))
done
fval=$((fval + 1))
done
fi
}
handle_filter_conf() {
local section="$1" # config filter
local filter_name="$2"
local name
# no need to proceed if name of filter section is not one of the values
# listed in option filter in config action section
config_get name $section name
if [ "$name" != "$filter_name" ]; then
return
fi
# as per data model, at a time either facility_level or severity_level can
# be specified along with pattern_match. hence, first process and generate
# regex for pattern_match which is common in both condition. Next, we will
# process facility_level and return if facility level is defined and not
# process severity related params at all.
local pattern_match
config_get pattern_match $section pattern_match
if [ -n "$pattern_match" ]; then
echo " regex $pattern_match" >> ${TMP_CONF_FILE}
fi
local facility_level
config_get facility_level $section facility_level
if [ -n "$facility_level" ]; then
generate_facility_regex $facility_level
# return from here since if facility_level is defined, then no
# need to process severity_level
return
fi
local sev_level
local sev_compare
local sev_action
config_get sev_level $section severity_level
if [ -n "$sev_level" ]; then
# value 1 of severity compare corresponds to data model
# and system default which is EqualorHigher
config_get sev_compare $section severity_compare 1
# value 0 of severity action corresponds to data model
# and system default that is log
config_get sev_action $section severity_action 0
generate_severity_regex $sev_level $sev_compare $sev_action
fi
}
create_filter_section() {
local match="$1"
echo "[FILTER]" >> ${TMP_CONF_FILE}
echo " name grep" >> ${TMP_CONF_FILE}
echo " match $match" >> ${TMP_CONF_FILE}
echo " logical_op or" >> ${TMP_CONF_FILE} # handle multiple filters
}
handle_filter_ref() {
local filter_name="$1"
config_foreach handle_filter_conf filter "$filter_name"
}
handle_log_file() {
local section="$1" # out_file section
local linker="$2"
local match_regex="$3"
local template="$4"
local match="$2"
local action_ref
config_get action_ref $section action
if [ "$action_ref" != "$linker" ]; then
if [ "$action_ref" != "$match" ]; then
return
fi
local enabled
config_get_bool enabled $section enable
if [ "$enabled" = "0" ]; then
config_get enabled $section enable
if [ "$enabled" == 0 ]; then
return
fi
local file
config_get file $section file
if [ -z "$file" ] || [ -z "$match_regex" ]; then
if [ -z "$file" ]; then
return
fi
append_conf "[OUTPUT]"
append_conf " name file"
append_conf " workers 2"
append_conf " match_regex $match_regex"
append_conf " file $file"
if [ -n "$template" ]; then
append_conf " format template"
append_conf " template ${template}"
fi
append_conf ""
echo "[OUTPUT]" >> ${TMP_CONF_FILE}
echo " name file" >> ${TMP_CONF_FILE}
echo " match $match" >> ${TMP_CONF_FILE}
echo " file $file" >> ${TMP_CONF_FILE}
echo " format template" >> ${TMP_CONF_FILE}
echo " template {time} {hostname} {ident}: {message}" >> ${TMP_CONF_FILE}
}
handle_log_remote() {
local section="$1"
local linker="$2"
local match_regex="$3"
local match="$2"
local action_ref
config_get action_ref $section action
if [ "$action_ref" != "$linker" ]; then
if [ "$action_ref" != "$match" ]; then
return
fi
local enabled
config_get_bool enabled $section enable
if [ "$enabled" = "0" ]; then
config_get enabled $section enable
if [ "$enabled" == 0 ]; then
return
fi
@@ -336,167 +242,83 @@ handle_log_remote() {
return
fi
append_conf "[OUTPUT]"
append_conf " name syslog"
append_conf " match_regex $match_regex"
append_conf " host $address"
echo "[OUTPUT]" >> ${TMP_CONF_FILE}
echo " name syslog" >> ${TMP_CONF_FILE}
echo " match $match" >> ${TMP_CONF_FILE}
echo " host $address" >> ${TMP_CONF_FILE}
append_conf " syslog_appname_key ident"
append_conf " syslog_procid_key pid"
append_conf " syslog_message_key message"
append_conf " syslog_hostname_key hostname"
local hostname="$(uci -q get 'system.@system[0].hostname')"
if [ -n "${hostname}" ]; then
append_conf " syslog_hostname_preset ${hostname}"
fi
local proto # holds value tcp or udp
config_get proto ${section} proto
if [ -n "$proto" ]; then
if [ "$proto" == "tls" ]; then
append_conf " mode tcp"
append_conf " tls on"
echo " mode tcp" >> ${TMP_CONF_FILE}
echo " tls on" >> ${TMP_CONF_FILE}
else
append_conf " mode $proto"
echo " mode $proto" >> ${TMP_CONF_FILE}
fi
fi
local port
config_get port $section port
if [ -n "$port" ]; then
append_conf " port $port"
echo " port $port" >> ${TMP_CONF_FILE}
fi
local cert
local peer_verify
config_get cert $section cert
if [ -n "$cert" ]; then
append_conf " tls.crt_file $cert"
echo " tls.crt_file $cert" >> ${TMP_CONF_FILE}
config_get_bool peer_verify $section peer_verify
if [ "$peer_verify" = "1" ]; then
append_conf " tls.verify on"
config_get peer_verify $section peer_verify
if [ "$peer_verify" == "1" ]; then
echo " tls.verify on" >> ${TMP_CONF_FILE}
fi
fi
append_conf ""
}
resolve_source_section() {
local src_section="$1"
local linker="$2"
local src_name syslog_en kernel_en
config_get src_name "$src_section" name
[ "$src_name" = "$linker" ] || return
config_get_bool syslog_en "$src_section" system_messages 1
config_get_bool kernel_en "$src_section" kernel_messages 1
# create an input section using /dev/log or kmsg
# and store the tag in a variable
# so that later a regex can be made to match this tag
# which will be used in output section
if [ "$syslog_en" = "1" ]; then
source_tag_syslog="SL$src_name"
create_input_section "$source_tag_syslog"
fi
if [ "$kernel_en" = "1" ]; then
source_tag_kmsg="KM$src_name"
create_kmsg_input_section "$source_tag_kmsg"
fi
}
# get the value of option expression from the relevant section
resolve_template_section() {
local tmpl_section="$1"
local tmpl_name
config_get tmpl_name "$tmpl_section" name
[ "$tmpl_name" = "$template_ref" ] || return
config_get template_expr "$tmpl_section" expression
[ -n "$template_expr" ] && echo "$template_expr"
}
# loop over template sections and get the value of option expression from the relevant section
get_template_expression() {
local template_ref="$1"
[ -n "$template_ref" ] && config_foreach resolve_template_section template
}
# build a regex that will match all the tags supplied to this function
build_match_regex() {
local tags="$1"
local first=1
local regex="^("
for tag in $tags; do
[ "$first" -eq 1 ] && first=0 || regex="$regex|"
regex="$regex$tag"
done
regex="$regex)\$"
echo "$regex"
}
handle_filter_conf() {
local section="$1" # config filter
local filter_name="$2"
local name
config_get name $section name
[ "$name" = "$filter_name" ] || return
populate_allowed_logs "$filter_name"
}
handle_action() {
local tag_regex filter source_ref template_ref source_sec log_template finst
local action_section="$1"
local source_tag_syslog source_tag_kmsg
local section="$1"
# shared variables set by populate_allowed_logs
match_pattern=""
facilities=""
all_facilities=0
kern_facility=1
severities=""
sev_compare=1
sev_action=0
local filter
config_get filter $section filter
config_get action_name "$action_section" name
config_get filter "$action_section" filter
config_get source_ref "$action_section" source
config_get template_ref "$action_section" template
# use config action option name as tag for input
local tag
config_get tag $section name
if [ -z "$tag" ]; then
return
fi
[ -z "$action_name" ] && return
[ -z "$source_ref" ] && return
# read filter section and populate relevant variables
# these variables will be used by create_kmsg_input_section
# generate_syslog_filter, and generate_pattern_filter functions
create_input_section $tag
if [ -n "$filter" ]; then
# the only fluentbit filter that is useful for the datamodel is
# grep. Also, fluentbit does not seem to handle multiple instances
# of FILTER of same kind. Hence, each filter section corresponding
# to an action entry in the uci would translate for us into a set of
# regex/exclude values instead of individual FILTER section per uci
# section filter is a list, treat according
create_filter_section $tag
IFS=" "
for finst in $filter; do
config_foreach handle_filter_conf filter "$finst"
handle_filter_ref $finst
done
fi
# Resolve referenced source sections
for source_sec in $source_ref; do
config_foreach resolve_source_section source "$source_sec"
done
# build a regex that will match all the sources for this action
tag_regex=$(build_match_regex "$source_tag_syslog $source_tag_kmsg")
if [ -n "$filter" ]; then
generate_pattern_filter "$tag_regex" "$match_pattern"
generate_syslog_filter
fi
# get the template expression if any is present
log_template="$(get_template_expression "$template_ref")"
# handle output, each action can be associated with an out_log and out_syslog
# handle output, each action can be associated with a out_log and out_syslog
# section so figure out if any out_log or out_syslog section is associated
# with this and action and setup output accordingly.
config_foreach handle_log_file log_file "$action_name" "$tag_regex" "$log_template"
config_foreach handle_log_remote log_remote "$action_name" "$tag_regex"
config_foreach handle_log_file log_file "$tag"
config_foreach handle_log_remote log_remote "$tag"
}
handle_action_section() {
@@ -512,14 +334,13 @@ logmngr_init() {
create_config_file
create_service_section
create_default_filters
handle_action_section
if [ -f /lib/logmngr/logrotate.sh ]; then
logrotate_init
fi
if [ "$enabled" = "0" ]; then
if [ "$enabled" == "0" ]; then
return
fi

View File

@@ -1,6 +1,6 @@
#!/bin/sh /etc/rc.common
START=09
START=12
USE_PROCD=1

View File

@@ -55,20 +55,12 @@ config AGENT_OPER_CHANNEL_CHANGE_RELAY_MCAST
config AGENT_USE_LIBDPP
bool "Depend on libdpp for DPP EasyConnect"
config AGENT_ZEROTOUCH_DPP
bool "Enable Zero-touch DPP bootstrapping. Depends on libztdpp.so"
default n
config AGENT_CHECK_PARTIAL_WIFI_RELOAD
bool "Option that allow SSID/PSK simple reload"
default y
config DYNBH
bool "Enable map-agent dynamic Ethernet backhaul management"
default n
config DYNBH_DYNAMICALLY_PERSIST_CONTROLLER
bool "Let map-agent through AP-Autoconfiguration Search and DHCP Discovery determine the controller or agent role"
config DYNBHD_DYNAMICALLY_PERSIST_CONTROLLER
bool "Let dynbhd through AP-Autoconfiguration Search and DHCP Discovery determine the controller or agent role"
config AGENT_UNASSOC_STA_CONT_MONITOR
bool "Enable continuos monitoring of unassociated clients"

View File

@@ -1,14 +1,13 @@
#
# Copyright (C) 2020-2024 IOPSYS Software Solutions AB
# Copyright (C) 2025 Genexis Sweden AB
# Copyright (C) 2020-2023 IOPSYS Software Solutions AB
#
include $(TOPDIR)/rules.mk
PKG_NAME:=map-agent
PKG_VERSION:=6.5.0.9
PKG_VERSION:=6.3.6.7
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_SOURCE_VERSION:=f4d201acde3320b1019c1831315e58a8ecb0290c
PKG_SOURCE_VERSION:=f611be0c05e3f4fb3d35a5a1ad51f5a4ad6406ca
PKG_MAINTAINER:=Jakob Olsson <jakob.olsson@iopsys.eu>
PKG_LICENSE:=BSD-3-Clause
@@ -27,7 +26,7 @@ include $(INCLUDE_DIR)/package.mk
define Package/map-agent
SECTION:=utils
CATEGORY:=Utilities
TITLE:=Wi-Fi Multi-AP Agent (EasyMesh R6)
TITLE:=WiFi multi-AP Agent (EasyMesh R2)
DEPENDS:=+libwifi +libuci +libubox +ubus +libeasy +libieee1905 +ieee1905 \
+ieee1905-map-plugin +ip-bridge +AGENT_USE_LIBDPP:libdpp \
+uuidgen +openssl-util +!TARGET_brcmbca:ebtables-legacy \
@@ -38,12 +37,21 @@ ifeq ($(CONFIG_AGENT_USE_LIBDPP),y)
TARGET_CFLAGS += -DUSE_LIBDPP
endif
ifeq ($(CONFIG_AGENT_ZEROTOUCH_DPP),y)
TARGET_CFLAGS += -DZEROTOUCH_DPP
endif
define Package/dynbhd
SECTION:=utils
CATEGORY:=Utilities
TITLE:=Dynamic Backhaul Daemon
DEPENDS:=+libwifi +libuci +libubox +ubus +libeasy +libieee1905 +ieee1905 \
+ieee1905-map-plugin +map-agent
endef
define Package/map-agent/description
This package provides EasyMesh R6 compliant Wi-Fi Multi-AP Agent.
This package implements EasyMesh R2 compliant WiFi Agent.
endef
define Package/dynbhd/description
Dyanmic LAN/WAN port detection and loop avoidance.
endef
define Package/map-agent/config
@@ -103,11 +111,7 @@ ifeq ($(CONFIG_AGENT_CHECK_PARTIAL_WIFI_RELOAD),y)
TARGET_CFLAGS += -DCHECK_PARTIAL_WIFI_RELOAD
endif
ifeq ($(CONFIG_DYNBH),y)
TARGET_CFLAGS += -DDYNBH
endif
ifeq ($(CONFIG_DYNBH_DYNAMICALLY_PERSIST_CONTROLLER),y)
ifeq ($(CONFIG_DYNBHD_DYNAMICALLY_PERSIST_CONTROLLER),y)
TARGET_CFLAGS += -DPERSIST_CONTROLLER
endif
@@ -120,10 +124,6 @@ MAKE_PATH:=src
define Package/map-agent/install
$(INSTALL_DIR) $(1)/etc
$(CP) ./files/* $(1)/
ifeq ($(CONFIG_DYNBH),y)
$(RM) $(1)/etc/hotplug.d/ethernet/map-dynamic-backhaul
$(RM) $(1)/etc/hotplug.d/ethernet/map-topology-discovery
endif
$(INSTALL_DIR) $(1)/usr/lib
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_DIR) $(1)/lib/wifi
@@ -131,6 +131,15 @@ endif
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/mapagent $(1)/usr/sbin/
endef
define Package/dynbhd/install
$(INSTALL_DIR) $(1)/etc
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_DIR) $(1)/lib/wifi/dynbhd
$(INSTALL_DIR) $(1)/etc/hotplug.d/ethernet
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/dynbh/dynbhd $(1)/usr/sbin/dynbhd
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/dynbh/api $(1)/lib/wifi/dynbhd/api
# $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/dynbh/map-dynamic-backhaul $(1)/etc/hotplug.d/ethernet/map-dynamic-backhaul
endef
ifeq ($(LOCAL_DEV),1)
define Build/Prepare
@@ -139,3 +148,4 @@ endef
endif
$(eval $(call BuildPackage,map-agent))
$(eval $(call BuildPackage,dynbhd))

View File

@@ -17,7 +17,7 @@ config dynamic_backhaul
option missing_bh_reconfig_timer '1800'
config controller_select
option mode 'auto'
option id 'auto'
option probe_int '20'
option retry_int '9'
option autostart '1'

View File

@@ -27,6 +27,11 @@ done
al_brnet="${al_bridge:3}"
[ "$(uci -q get network.${al_brnet}.proto)" == "dhcp" ] || exit 0
############## Dynamic Backhaul Daemon ##############
if [ -n "$(which dynbhd)" ]; then
exit 0
fi
########################################################
################ Dedicated ETH WAN Port ################
wanport="$(jsonfilter -i /etc/board.json -e @.network.wan.device)"
@@ -90,8 +95,7 @@ if [ "$LINK" = "up" ]; then
config_foreach remove_from_bridge bsta
config_foreach update_bstas bsta down
hwaddr="$(ifconfig $PORT | grep -i hwaddr | awk '{print $5}' | awk '{print tolower($0)}')"
/lib/wifi/multiap set_uplink "eth" "$PORT" "$hwaddr"
/lib/wifi/multiap set_uplink "eth" "$PORT"
else
/lib/wifi/multiap unset_uplink "eth"
#rm -f "$map_bh_file"

View File

@@ -1,12 +1,26 @@
#!/bin/sh /etc/rc.common
START=97
START=98
STOP=20
USE_PROCD=1
IS_CFG_VALID=1
MAP_DEV="map_dev"
MAP_IF="map"
start_dynbhd_service() {
rm -f /var/run/multiap/multiap.backhaul
procd_open_instance
procd_set_param command "/usr/sbin/dynbhd"
procd_set_param respawn
# procd_set_param stdout 1
# procd_set_param stderr 1
procd_close_instance
}
validate_agent_section() {
uci_validate_section mapagent agent "agent" \
'enabled:bool:true' \
@@ -37,7 +51,7 @@ validate_cs_section() {
uci_validate_section mapagent $section "${section}" \
'local:bool:false' \
'mode:string' \
'id:string' \
'probe_int:range(0,1000):20' \
'retry_int:range(0,255):3' \
'autostart:bool:false'
@@ -165,6 +179,17 @@ create_dir() {
}
start_service() {
if [ -f /usr/sbin/dynbhd ]; then
# Start dynbhd only if the device is operating in extender/repeater mode
al_bridge="$(uci -q get mapagent.agent.al_bridge)"
if [ "${al_bridge:0:3}" = "br-" ]; then
al_brnet="${al_bridge:3}"
if [ "$(uci -q get network.${al_brnet}.proto)" == "dhcp" ]; then
start_dynbhd_service
fi
fi
fi
config_load "mapagent"
validate_agent_config || return 1;

View File

@@ -1,15 +0,0 @@
#!/bin/sh
. /lib/functions.sh
adapt_cntlr_sel() {
local section=$1
id=$(uci -q get mapagent.@controller_select[0].id)
uci -q del mapagent.@controller_select[0].id
# re-apply any custom value
[ -z "${id}" ] || uci -q set mapagent.@controller_select[0].mode="${id}"
}
adapt_cntlr_sel

View File

@@ -10,11 +10,6 @@ network_mode="$(fw_printenv -n netmode)" # default is layer3
multiap_mode="$(fw_printenv -n multiap_mode)" # default is full
disable_mlo="$(fw_printenv -n disable_mlo)"
is_logan() {
[ -d /sys/module/mt_wifi ] && return 0
return 1
}
is_airoha() {
[ -f /proc/device-tree/compatible ] || return
strings /proc/device-tree/compatible | grep -qE '^(econet,|airoha,)'; return
@@ -49,16 +44,19 @@ generate_multiap_config() {
2g)
mode_band=2
priority=2
dpp_chan="81/1"
channels="1 6 11"
;;
5g)
mode_band=5
priority=1
dpp_chan="128/36"
channels="36-64 100-112"
;;
6g)
mode_band=6
priority=0
dpp_chan="133/49"
;;
esac
@@ -69,45 +67,45 @@ generate_multiap_config() {
device="$dev"
ifprefix_radio=""
if is_logan; then
uci set mapagent.agent.mld_ap_prefix="bss"
uci set mapagent.agent.mld_sta_prefix="sta"
ifname_sta=""
case "$band" in
2g)
ifprefix="ra%"
ifname="ra0"
ifname_bh="ra1"
ifname_sta="apcli0"
;;
5g)
ifprefix="rai%"
ifname="rai0"
ifname_bh="rai1"
ifname_sta="apclii0"
;;
6g)
ifprefix="rax%"
ifname="rax0"
ifname_bh="rax1"
ifname_sta="apclix0"
;;
esac
ifprefix_radio="${ifprefix}"
if [ "${network_mode}" == "extender" ]; then
ifname="${ifname_sta}"
fi
[ "$disable_mlo" == "1" ] || {
uci set wireless.$dev.mlo="1"
uci set wireless.$dev.mlo_capable="1"
}
elif is_airoha; then
if is_airoha; then
if [ -d "/sys/module/mt76" ]; then
ifprefix="wlan%_%"
ifname="wlan${devidx}_0"
ifname_bh="wlan${devidx}_1"
else
uci set mapagent.agent.mld_prefix="bss"
ifname_sta=""
case "$band" in
2g)
ifprefix="ra%"
ifname="ra0"
ifname_bh="ra1"
ifname_sta="apcli0"
;;
5g)
ifprefix="rai%"
ifname="rai0"
ifname_bh="rai1"
ifname_sta="apclii0"
;;
6g)
ifprefix="rax%"
ifname="rax0"
ifname_bh="rax1"
ifname_sta="apclix0"
;;
esac
ifprefix_radio="${ifprefix}"
if [ "${network_mode}" == "extender" ]; then
ifname="${ifname_sta}"
fi
[ "$disable_mlo" == "1" ] || {
uci set wireless.$dev.mlo="1"
uci set wireless.$dev.mlo_capable="1"
}
fi
uci set wireless.$dev.channels="$channels"
uci commit wireless
elif is_broadcom; then
@@ -160,17 +158,13 @@ generate_multiap_config() {
uci set mapagent.@bsta[-1].band="$mode_band"
uci set mapagent.@bsta[-1].priority="$priority"
# add dpp_chirp section for 2.4GHz bSTA
if [ $mode_band -eq 2 ]; then
uci add mapagent dpp_chirp
uci set mapagent.@dpp_chirp[-1].type="qrcode"
uci set mapagent.@dpp_chirp[-1].device="$device"
uci set mapagent.@dpp_chirp[-1].ifname="$ifname"
uci set mapagent.@dpp_chirp[-1].band="$mode_band"
for channel in $channels; do
uci add_list mapagent.@dpp_chirp[-1].channel="$channel"
done
fi
#uci add mapagent dpp_uri
#uci set mapagent.@dpp_uri[-1].type="qrcode"
#uci set mapagent.@dpp_uri[-1].device="$device"
#uci set mapagent.@dpp_uri[-1].ifname="$ifname"
#uci set mapagent.@dpp_uri[-1].band="$mode_band"
#uci set mapagent.@dpp_uri[-1].chirp_interval="10"
#uci add_list mapagent.@dpp_uri[-1].dpp_chan="$dpp_chan"
if [ $generate_wireless_sta_config -eq 1 ]; then
secname="default_sta_${device}"
@@ -264,6 +258,7 @@ map_genconf () {
config_foreach mapcontroller_remove_mld_id ap
}
fi
ubus -t 5 call uci commit '{"config":"mapcontroller"}'
uci -q commit mapcontroller
ubus send bbfdm.wifidmd.reload
fi
}

View File

@@ -39,10 +39,6 @@ config CONTROLLER_EASYMESH_VENDOR_EXT_OUI
config CONTROLLER_USE_LIBDPP
bool "Depend on libdpp for DPP EasyConnect"
config CONTROLLER_ZEROTOUCH_DPP
bool "Enable Zero-touch DPP bootstrapping via passphrase."
default n
config CONTROLLER_PROPAGATE_PROBE_REQ
depends on CONTROLLER_EASYMESH_VENDOR_EXT
bool "Enable publishing probe requests vendor specific messages as UBUS events"

View File

@@ -6,9 +6,9 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=map-controller
PKG_VERSION:=6.4.4.16
PKG_VERSION:=6.4.0.12
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_SOURCE_VERSION:=2f8d2afc604c090637acdb01e630e233cd9aceff
PKG_SOURCE_VERSION:=ae10f447f8d83ed6b98d2b82da2dda64be2c3183
PKG_MAINTAINER:=Jakob Olsson <jakob.olsson@genexis.eu>
LOCAL_DEV=0
@@ -36,9 +36,6 @@ ifeq ($(CONFIG_CONTROLLER_USE_LIBDPP),y)
TARGET_CFLAGS += -DUSE_LIBDPP
endif
ifeq ($(CONFIG_CONTROLLER_ZEROTOUCH_DPP),y)
TARGET_CFLAGS += -DZEROTOUCH_DPP
endif
define Package/map-controller/description
This package provides WiFi MultiAP Controller as per the EasyMesh-R2 specs.
@@ -84,7 +81,6 @@ define Build/InstallDev
$(CP) $(PKG_BUILD_DIR)/src/cntlr_commands_impl.h $(1)/usr/include/map-controller
$(CP) $(PKG_BUILD_DIR)/src/cntlr_commands.h $(1)/usr/include/map-controller
$(CP) $(PKG_BUILD_DIR)/src/cntlr_apis.h $(1)/usr/include/map-controller
$(CP) $(PKG_BUILD_DIR)/src/cntlr_plugin.h $(1)/usr/include/map-controller
$(CP) $(PKG_BUILD_DIR)/src/wifi_opclass.h $(1)/usr/include/map-controller
$(CP) $(PKG_BUILD_DIR)/src/steer_module.h $(1)/usr/include/map-controller
$(CP) $(PKG_BUILD_DIR)/src/timer.h $(1)/usr/include/map-controller

View File

@@ -2,18 +2,18 @@ config controller 'controller'
option enabled '1' # may be modified by other package start-up scripts (i.e. map-agent)
option profile '3'
option registrar '2 5 6'
option debug '2'
option debug '0'
option bcn_metrics_max_num '10'
option initial_channel_scan '0'
option enable_ts '0'
option primary_vid '1'
option primary_pcp '0'
option stale_sta_timeout '20d'
option stale_sta_timeout '30d'
option de_collect_interval '60'
list plugin 'zerotouch'
config sta_steering 'sta_steering'
config sta_steering
option enable_sta_steer '1'
option enable_bsta_steer '1'
option enable_bsta_steer '0'
option rcpi_threshold_2g '70'
option rcpi_threshold_5g '86'
option rcpi_threshold_6g '86'
@@ -23,10 +23,8 @@ config sta_steering 'sta_steering'
option plugins_enabled '1'
option plugins_policy 'any'
list plugins 'rcpi'
list plugins 'rate'
list plugins 'bsteer'
config channel_plan 'channel_plan'
config channel_plan
option preclear_dfs '0'
option acs '0'

View File

@@ -20,6 +20,7 @@ validate_controller_section() {
'registrar:string' \
'debug:range(0,16)' \
'bcn_metrics_max_num:range(1,256)' \
'initial_channel_scan:bool:true' \
'resend_num:uinteger:0' \
'allow_bgdfs:range(0,2629744)' \
'stale_sta_timeout:string' \

View File

@@ -1,66 +0,0 @@
#!/bin/sh
. /lib/functions.sh
cfg="mapcontroller"
config_load "$cfg"
used_ids=""
collect_used_ids() {
local section="$1"
local id
id=$(uci -q get ${cfg}.${section}.id)
if [ -n "$id" ] && printf "%s" "$id" | grep -qE '^[0-9]+$'; then
used_ids="$used_ids $id"
fi
}
# Find first available ID from 0 to INT32_MAX
find_first_available_id() {
local max_int=2147483647
local expected=0
local id
# Convert list to sorted unique list
sorted_ids=$(printf "%s\n" $used_ids | sort -n | uniq)
for id in $sorted_ids; do
if [ "$id" -eq "$expected" ]; then
expected=$((expected + 1))
elif [ "$id" -gt "$expected" ]; then
# Found a gap -> return the gap
echo "$expected"
return
fi
done
# If no gaps, next available is `expected`
if [ "$expected" -le "$max_int" ]; then
echo "$expected"
else
echo -1
fi
}
# Assign ID if missing
add_qos_rule_id() {
local section="$1"
local id
id=$(uci -q get ${cfg}.${section}.id)
if [ -z "$id" ]; then
new_id=$(find_first_available_id)
[ "$new_id" -ge 0 ] || return # No available ID
uci -q set ${cfg}.${section}.id="$new_id"
used_ids="$used_ids $new_id"
fi
}
# Step 1: Collect all existing IDs
config_foreach collect_used_ids qos_rule
# Step 2: Assign IDs to rules missing them
config_foreach add_qos_rule_id qos_rule

View File

@@ -1,16 +0,0 @@
#!/bin/sh
. /lib/functions.sh
cfg=mapcontroller
# singleton sections
sections="channel_plan sta_steering"
for sec in $sections; do
# find unnamed section of given type, only index 0
s=$(uci show $cfg | grep -oE "@${sec}\[0\]" | sort -u)
[ "$s" = "" ] && continue
uci rename $cfg.$s=$sec
done

View File

@@ -5,12 +5,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=map-plugins
PKG_VERSION:=1.2.7
PKG_VERSION:=0.0.4
LOCAL_DEV=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=dd873ca4e2cb321302dae1955da24d1be271b2b1
PKG_SOURCE_VERSION:=74bf151851112ecee731d447af016c8dc668adcf
PKG_SOURCE_URL:=https://dev.iopsys.eu/multi-ap/map-plugins.git
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)_$(PKG_SOURCE_VERSION).tar.xz
PKG_MIRROR_HASH:=skip
@@ -27,18 +27,11 @@ include $(INCLUDE_DIR)/package.mk
include $(wildcard plugins/*.mk)
TARGET_CFLAGS += \
-I$(STAGING_DIR)/usr/include \
-I$(STAGING_DIR)/usr/include/libnl3 \
-D_GNU_SOURCE
MAKE_FLAGS += \
CFLAGS="$(TARGET_CFLAGS) -Wall"
plugins := \
$(if $(CONFIG_PACKAGE_map-plugins-steer-rate),steer-rate) \
$(if $(CONFIG_PACKAGE_map-plugins-bsteer),bsteer) \
$(if $(CONFIG_PACKAGE_map-plugins-zero-touch),zero-touch)
$(if $(CONFIG_PACKAGE_map-plugins-steer-rate),steer-rate)
ppkg:=$(patsubst plugins/%.mk,map-plugins-%,$(wildcard plugins/*.mk))
@@ -59,8 +52,7 @@ define Package/map-plugins
endef
define Package/map-plugins/description
Provides extra Multi-AP services viz. steering, channel-planning,
self-organizing network, zero-touch onboarding etc.
Provides extra Multi-AP services viz. steering, channel-planning etc.
endef
define Package/map-plugins/install
@@ -68,14 +60,9 @@ define Package/map-plugins/install
endef
define Build/Compile
$(foreach p,$(plugins),$(call Build/Compile/map-plugins-$(p), $(1)))
$(foreach p,$(ppkg),$(call Build/Compile/$(p),$(1)))
endef
ifeq ($(LOCAL_DEV),1)
define Build/Prepare
rsync -r --exclude=.* ~/git/map-plugins/ $(PKG_BUILD_DIR)/
endef
endif
$(eval $(call BuildPackage,map-plugins))
$(eval $(foreach p,$(ppkg),$(call BuildPackage,$(p))))

View File

@@ -1,20 +0,0 @@
define Package/map-plugins-bsteer
$(call Package/map-plugins/Default)
TITLE:=Wi-Fi backhaul steering plugin based on maximizing backhaul throughput
DEPENDS= +libubox +libuci +libubus +libeasy +libnl-genl \
+libjson-c +libblobmsg-json +map-controller \
+map-plugins
endef
define Package/map-plugins-bsteer/install
$(INSTALL_DIR) $(1)/usr/lib
$(INSTALL_DIR) $(1)/usr/lib/mapcontroller
$(CP) $(PKG_BUILD_DIR)/steer/bsteer/bsteer.so $(1)/usr/lib/mapcontroller/bsteer.so
endef
define Build/Compile/map-plugins-bsteer
$(MAKE) -C $(PKG_BUILD_DIR)/steer/bsteer \
CC="$(TARGET_CC)" \
CFLAGS="$(TARGET_CFLAGS)" \
LDFLAGS="$(TARGET_LDFLAGS)";
endef

View File

@@ -16,5 +16,5 @@ define Build/Compile/map-plugins-steer-rate
$(MAKE) -C $(PKG_BUILD_DIR)/steer/rate \
CC="$(TARGET_CC)" \
CFLAGS="$(TARGET_CFLAGS)" \
LDFLAGS="$(TARGET_LDFLAGS)";
LDFLAGS="$(TARGET_LDFLAGS)"
endef

View File

@@ -1,22 +0,0 @@
define Package/map-plugins-zero-touch
$(call Package/map-plugins/Default)
TITLE:=Full Zero-touch bootstrapping of Wi-Fi Repeater device(s)
DEPENDS= +libubox +libuci +libubus +libeasy +libnl-genl \
+libjson-c +libblobmsg-json +map-controller \
+map-plugins
endef
define Package/map-plugins-zero-touch/install
$(INSTALL_DIR) $(1)/usr/lib
$(INSTALL_DIR) $(1)/usr/lib/mapcontroller
$(CP) $(PKG_BUILD_DIR)/zero-touch/zerotouch.so $(1)/usr/lib/mapcontroller/zerotouch.so
$(CP) $(PKG_BUILD_DIR)/zero-touch/libztdpp.so $(1)/usr/lib/libztdpp.so
endef
define Build/Compile/map-plugins-zero-touch
$(MAKE) -C $(PKG_BUILD_DIR)/zero-touch \
CC="$(TARGET_CC)" \
CFLAGS="$(TARGET_CFLAGS)" \
LDFLAGS="$(TARGET_LDFLAGS)";
endef

View File

@@ -1,7 +0,0 @@
if PACKAGE_mosquitto-auth-plugin
config MOSQUITTO_AUTH_PAM_SUPPORT
bool "Enable support of Linux PAM module for Authentication"
default y
endif

View File

@@ -1,670 +0,0 @@
/*
* Copyright (c) 2022 Genexis B.V.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Erik Karlsson - initial implementation
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <shadow.h>
#include <crypt.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <mosquitto.h>
#include <mosquitto_broker.h>
#include <mosquitto_plugin.h>
#ifdef ENABLE_PAM_SUPPORT
#include <security/pam_appl.h>
#endif
#define MAX_USERS 256
#define MAX_SUBNETS_PER_USER 32
typedef struct {
union {
uint32_t ipv4_network;
uint8_t ipv6_network[16];
};
union {
uint32_t ipv4_netmask;
uint8_t ipv6_netmask[16];
};
int is_ipv6;
} subnet_t;
typedef struct {
char username[64];
subnet_t allow_subnets[MAX_SUBNETS_PER_USER];
int allow_count;
subnet_t deny_subnets[MAX_SUBNETS_PER_USER];
int deny_count;
} user_acl_t;
typedef struct {
user_acl_t users[MAX_USERS];
int user_count;
mosquitto_plugin_id_t *identifier;
char *config_file;
} plugin_data_t;
/* Parse CIDR notation for IPv4 or IPv6 (e.g., "192.168.1.0/24" or "2001:db8::/32") */
static int parse_subnet(const char *cidr, subnet_t *subnet)
{
char ip_str[128];
char *slash;
int prefix_len;
struct in_addr addr4;
struct in6_addr addr6;
strncpy(ip_str, cidr, sizeof(ip_str) - 1);
ip_str[sizeof(ip_str) - 1] = '\0';
slash = strchr(ip_str, '/');
if (slash != NULL) {
*slash = '\0';
prefix_len = atoi(slash + 1);
}
/* Try IPv4 first */
if (inet_pton(AF_INET, ip_str, &addr4) == 1) {
subnet->is_ipv6 = 0;
if (slash == NULL)
prefix_len = 32;
if (prefix_len < 0 || prefix_len > 32)
return -1;
subnet->ipv4_network = ntohl(addr4.s_addr);
subnet->ipv4_netmask = prefix_len == 0 ? 0 : (~0U << (32 - prefix_len));
subnet->ipv4_network &= subnet->ipv4_netmask;
return 0;
}
/* Try IPv6 */
if (inet_pton(AF_INET6, ip_str, &addr6) == 1) {
subnet->is_ipv6 = 1;
if (slash == NULL)
prefix_len = 128;
if (prefix_len < 0 || prefix_len > 128)
return -1;
/* Copy network address */
memcpy(subnet->ipv6_network, addr6.s6_addr, 16);
/* Generate netmask */
memset(subnet->ipv6_netmask, 0, 16);
for (int i = 0; i < prefix_len / 8; i++)
subnet->ipv6_netmask[i] = 0xff;
if (prefix_len % 8)
subnet->ipv6_netmask[prefix_len / 8] = ~((1 << (8 - (prefix_len % 8))) - 1);
/* Apply netmask to network address */
for (int i = 0; i < 16; i++)
subnet->ipv6_network[i] &= subnet->ipv6_netmask[i];
return 0;
}
return -1;
}
/* Check if IPv4 address is in subnet */
static int ipv4_in_subnet(uint32_t ip, const subnet_t *subnet)
{
if (subnet->is_ipv6)
return 0;
return (ip & subnet->ipv4_netmask) == subnet->ipv4_network;
}
/* Check if IPv6 address is in subnet */
static int ipv6_in_subnet(const uint8_t *ip, const subnet_t *subnet)
{
if (!subnet->is_ipv6)
return 0;
for (int i = 0; i < 16; i++) {
if ((ip[i] & subnet->ipv6_netmask[i]) != subnet->ipv6_network[i])
return 0;
}
return 1;
}
/* Check if IP is in any subnet in the list */
static int ip_in_subnet_list(const char *client_address, const subnet_t *subnets, int count)
{
struct in_addr addr4;
struct in6_addr addr6;
uint32_t ipv4;
/* Try IPv4 */
if (inet_pton(AF_INET, client_address, &addr4) == 1) {
ipv4 = ntohl(addr4.s_addr);
for (int i = 0; i < count; i++) {
if (ipv4_in_subnet(ipv4, &subnets[i]))
return 1;
}
return 0;
}
/* Try IPv6 */
if (inet_pton(AF_INET6, client_address, &addr6) == 1) {
for (int i = 0; i < count; i++) {
if (ipv6_in_subnet(addr6.s6_addr, &subnets[i]))
return 1;
}
return 0;
}
return 0;
}
/* Find or create user ACL entry */
static user_acl_t* find_or_create_user_acl(plugin_data_t *pdata, const char *username)
{
user_acl_t *user;
/* Find existing user */
for (int i = 0; i < pdata->user_count; i++) {
if (strcmp(pdata->users[i].username, username) == 0)
return &pdata->users[i];
}
/* Create new user if not found */
if (pdata->user_count >= MAX_USERS) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Max users exceeded");
return NULL;
}
user = &pdata->users[pdata->user_count];
strncpy(user->username, username, sizeof(user->username) - 1);
user->username[sizeof(user->username) - 1] = '\0';
user->allow_count = 0;
user->deny_count = 0;
pdata->user_count++;
return user;
}
/* Parse subnet ACL file with simplified format
* Format:
* # Comment lines
* subnet allow <username> <cidr>
* subnet deny <username> <cidr>
*/
static int load_subnet_acl_config(plugin_data_t *pdata, const char *config_file)
{
FILE *fp;
char line[512];
int line_num = 0;
/* Initialize user count */
pdata->user_count = 0;
/* Config file is optional - if not provided, no subnet filtering */
if (config_file == NULL) {
mosquitto_log_printf(MOSQ_LOG_INFO,
"subnet_acl: No subnet ACL file specified, subnet filtering disabled");
return 0;
}
/* If config file is specified but cannot be opened, this is a fatal error */
fp = fopen(config_file, "r");
if (fp == NULL) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Failed to open subnet ACL file '%s'", config_file);
return -1;
}
while (fgets(line, sizeof(line), fp) != NULL) {
char *token, *saveptr;
char *action, *username, *cidr;
user_acl_t *user;
subnet_t subnet;
line_num++;
/* Remove newline and comments */
line[strcspn(line, "\r\n")] = '\0';
char *comment = strchr(line, '#');
if (comment)
*comment = '\0';
/* Trim leading whitespace */
char *line_start = line;
while (*line_start == ' ' || *line_start == '\t')
line_start++;
/* Skip empty lines */
if (*line_start == '\0')
continue;
/* Parse: subnet allow|deny <username> <cidr> */
token = strtok_r(line_start, " \t", &saveptr);
if (token == NULL)
continue;
/* Must start with "subnet" */
if (strcmp(token, "subnet") != 0) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Invalid directive '%s' at line %d (expected 'subnet')",
token, line_num);
fclose(fp);
return -1;
}
/* Get allow/deny */
action = strtok_r(NULL, " \t", &saveptr);
if (action == NULL) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Missing allow/deny at line %d", line_num);
fclose(fp);
return -1;
}
if (strcmp(action, "allow") != 0 && strcmp(action, "deny") != 0) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Invalid action '%s' at line %d (use 'allow' or 'deny')",
action, line_num);
fclose(fp);
return -1;
}
/* Get username */
username = strtok_r(NULL, " \t", &saveptr);
if (username == NULL) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Missing username at line %d", line_num);
fclose(fp);
return -1;
}
/* Get CIDR */
cidr = strtok_r(NULL, " \t", &saveptr);
if (cidr == NULL) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Missing CIDR at line %d", line_num);
fclose(fp);
return -1;
}
/* Parse subnet */
if (parse_subnet(cidr, &subnet) != 0) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Invalid CIDR '%s' at line %d", cidr, line_num);
fclose(fp);
return -1;
}
/* Find or create user */
user = find_or_create_user_acl(pdata, username);
if (user == NULL) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Max users (%d) exceeded at line %d", MAX_USERS, line_num);
fclose(fp);
return -1;
}
/* Add to appropriate list */
if (strcmp(action, "allow") == 0) {
if (user->allow_count >= MAX_SUBNETS_PER_USER) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Max allow subnets (%d) exceeded for user '%s' at line %d",
MAX_SUBNETS_PER_USER, user->username, line_num);
fclose(fp);
return -1;
}
user->allow_subnets[user->allow_count] = subnet;
user->allow_count++;
mosquitto_log_printf(MOSQ_LOG_DEBUG,
"subnet_acl: User '%s' allow subnet %s",
user->username, cidr);
} else { /* deny */
if (user->deny_count >= MAX_SUBNETS_PER_USER) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Max deny subnets (%d) exceeded for user '%s' at line %d",
MAX_SUBNETS_PER_USER, user->username, line_num);
fclose(fp);
return -1;
}
user->deny_subnets[user->deny_count] = subnet;
user->deny_count++;
mosquitto_log_printf(MOSQ_LOG_DEBUG,
"subnet_acl: User '%s' deny subnet %s",
user->username, cidr);
}
}
fclose(fp);
/* Log summary */
for (int i = 0; i < pdata->user_count; i++) {
user_acl_t *user = &pdata->users[i];
if (user->allow_count > 0 || user->deny_count > 0) {
mosquitto_log_printf(MOSQ_LOG_INFO,
"subnet_acl: User '%s' has %d allow and %d deny subnet rules",
user->username, user->allow_count, user->deny_count);
}
}
mosquitto_log_printf(MOSQ_LOG_NOTICE,
"subnet_acl: Loaded subnet restrictions for %d user(s)", pdata->user_count);
return 0;
}
/* Find user ACL entry */
static const user_acl_t* find_user_acl(const plugin_data_t *pdata, const char *username)
{
for (int i = 0; i < pdata->user_count; i++) {
if (strcmp(pdata->users[i].username, username) == 0)
return &pdata->users[i];
}
return NULL;
}
/* Check subnet access on authentication (connection time)
* Returns: MOSQ_ERR_SUCCESS if allowed, MOSQ_ERR_AUTH if denied
*/
static int check_subnet_on_auth(plugin_data_t *pdata, struct mosquitto_evt_basic_auth *ed)
{
const user_acl_t *user_acl;
const char *client_address;
/* Skip if no subnet config loaded */
if (pdata == NULL || pdata->user_count == 0)
return MOSQ_ERR_SUCCESS;
/* Skip anonymous users */
if (ed->username == NULL)
return MOSQ_ERR_SUCCESS;
/* Find user's subnet ACL */
user_acl = find_user_acl(pdata, ed->username);
/* If user not in config or has no subnet rules, allow */
if (user_acl == NULL || (user_acl->allow_count == 0 && user_acl->deny_count == 0))
return MOSQ_ERR_SUCCESS;
/* Get client IP address */
client_address = mosquitto_client_address(ed->client);
if (client_address == NULL) {
mosquitto_log_printf(MOSQ_LOG_WARNING,
"subnet_acl: Could not get client address for user '%s', denying connection",
ed->username);
return MOSQ_ERR_AUTH;
}
/* Check deny list first - deny takes precedence */
if (user_acl->deny_count > 0) {
if (ip_in_subnet_list(client_address, user_acl->deny_subnets, user_acl->deny_count)) {
mosquitto_log_printf(MOSQ_LOG_NOTICE,
"subnet_acl: User '%s' from %s DENIED by deny rule",
ed->username, client_address);
return MOSQ_ERR_AUTH;
}
}
/* If there are allow rules, IP must match one of them */
if (user_acl->allow_count > 0) {
if (ip_in_subnet_list(client_address, user_acl->allow_subnets, user_acl->allow_count)) {
mosquitto_log_printf(MOSQ_LOG_DEBUG,
"subnet_acl: User '%s' from %s allowed by allow rule",
ed->username, client_address);
return MOSQ_ERR_SUCCESS;
} else {
mosquitto_log_printf(MOSQ_LOG_NOTICE,
"subnet_acl: User '%s' from %s DENIED (not in allowed subnets)",
ed->username, client_address);
return MOSQ_ERR_AUTH;
}
}
/* No subnet rules for this user - allow */
return MOSQ_ERR_SUCCESS;
}
#ifdef ENABLE_PAM_SUPPORT
static int pam_conversation(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr)
{
int i;
const char *pass = (const char *)appdata_ptr;
*resp = calloc(num_msg, sizeof(struct pam_response));
if (*resp == NULL) {
mosquitto_log_printf(MOSQ_LOG_ERR, "pam failed to allocate buffer for validation");
return PAM_BUF_ERR;
}
if (pass == NULL)
return PAM_SUCCESS;
for (i = 0; i < num_msg; ++i) {
if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF) {
(*resp)[i].resp = strdup(pass);
if ((*resp)[i].resp == NULL) {
for (int j = 0; j < i ; j++)
free((*resp)[j].resp);
free(*resp);
*resp = NULL;
mosquitto_log_printf(MOSQ_LOG_ERR, "pam failed in strdup");
return PAM_BUF_ERR;
}
}
}
return PAM_SUCCESS;
}
static int process_pam_auth_callback(struct mosquitto_evt_basic_auth *ed)
{
struct pam_conv conv;
int retval;
pam_handle_t *pamh = NULL;
conv.conv = pam_conversation;
conv.appdata_ptr = (void *)ed->password;
retval = pam_start("mosquitto", ed->username, &conv, &pamh);
if (retval != PAM_SUCCESS) {
mosquitto_log_printf(MOSQ_LOG_ERR, "pam start failed: %s", pam_strerror(pamh, retval));
return MOSQ_ERR_AUTH;
}
retval = pam_authenticate(pamh, 0);
pam_end(pamh, retval);
if (retval == PAM_SUCCESS) {
mosquitto_log_printf(MOSQ_LOG_NOTICE, "pam user [%s] logged in", ed->username);
return MOSQ_ERR_SUCCESS;
}
mosquitto_log_printf(MOSQ_LOG_NOTICE, "pam user [%s] failed authentication, err [%s]", ed->username, pam_strerror(pamh, retval));
return MOSQ_ERR_AUTH;
}
#else
static int process_shadow_auth_callback(struct mosquitto_evt_basic_auth *ed)
{
struct spwd spbuf, *sp = NULL;
char buf[256];
struct crypt_data data;
char *hash;
getspnam_r(ed->username, &spbuf, buf, sizeof(buf), &sp);
if (sp == NULL || sp->sp_pwdp == NULL)
return MOSQ_ERR_AUTH;
/* Empty string as hash means password is not required */
if (sp->sp_pwdp[0] == 0)
return MOSQ_ERR_SUCCESS;
if (ed->password == NULL)
return MOSQ_ERR_AUTH;
memset(&data, 0, sizeof(data));
hash = crypt_r(ed->password, sp->sp_pwdp, &data);
if (hash == NULL)
return MOSQ_ERR_AUTH;
if (strcmp(hash, sp->sp_pwdp) == 0)
return MOSQ_ERR_SUCCESS;
return MOSQ_ERR_AUTH;
}
#endif
static int basic_auth_callback(int event, void *event_data, void *userdata)
{
struct mosquitto_evt_basic_auth *ed = event_data;
plugin_data_t *pdata = userdata;
int auth_result;
/* Let other plugins or broker decide about anonymous login */
if (ed->username == NULL)
return MOSQ_ERR_PLUGIN_DEFER;
/* First check username/password authentication */
#ifdef ENABLE_PAM_SUPPORT
auth_result = process_pam_auth_callback(ed);
#else
auth_result = process_shadow_auth_callback(ed);
#endif
/* If authentication failed, reject immediately */
if (auth_result != MOSQ_ERR_SUCCESS)
return auth_result;
/* Authentication succeeded, now check subnet restrictions */
return check_subnet_on_auth(pdata, ed);
}
static int reload_callback(int event, void *event_data, void *userdata)
{
plugin_data_t *pdata = userdata;
if (pdata == NULL)
return MOSQ_ERR_SUCCESS;
mosquitto_log_printf(MOSQ_LOG_NOTICE,
"subnet_acl: Reloading subnet ACL configuration from '%s'",
pdata->config_file ? pdata->config_file : "(none)");
/* Reload subnet ACL configuration */
if (load_subnet_acl_config(pdata, pdata->config_file) != 0) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Failed to reload subnet ACL configuration, keeping old config");
return MOSQ_ERR_UNKNOWN;
}
mosquitto_log_printf(MOSQ_LOG_NOTICE,
"subnet_acl: Reload complete, now tracking %d user(s)", pdata->user_count);
return MOSQ_ERR_SUCCESS;
}
int mosquitto_plugin_version(int supported_version_count,
const int *supported_versions)
{
return 5;
}
int mosquitto_plugin_init(mosquitto_plugin_id_t *identifier,
void **user_data,
struct mosquitto_opt *opts, int opt_count)
{
plugin_data_t *pdata;
const char *config_file = NULL;
int rc;
/* Find subnet config file option */
for (int i = 0; i < opt_count; i++) {
if (strcmp(opts[i].key, "subnet_acl_file") == 0) {
config_file = opts[i].value;
break;
}
}
pdata = calloc(1, sizeof(plugin_data_t));
if (pdata == NULL)
return MOSQ_ERR_NOMEM;
pdata->identifier = identifier;
/* Store config file path for reload */
if (config_file != NULL) {
pdata->config_file = strdup(config_file);
if (pdata->config_file == NULL) {
free(pdata);
return MOSQ_ERR_NOMEM;
}
} else {
pdata->config_file = NULL;
}
/* Load subnet ACL configuration */
if (load_subnet_acl_config(pdata, config_file) != 0) {
free(pdata->config_file);
free(pdata);
return MOSQ_ERR_UNKNOWN;
}
/* Register authentication callback only - subnet check is done during auth */
rc = mosquitto_callback_register(identifier, MOSQ_EVT_BASIC_AUTH,
basic_auth_callback, NULL, pdata);
if (rc != MOSQ_ERR_SUCCESS) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Failed to register authentication callback");
free(pdata->config_file);
free(pdata);
return rc;
}
/* Register reload callback to handle SIGHUP */
rc = mosquitto_callback_register(identifier, MOSQ_EVT_RELOAD,
reload_callback, NULL, pdata);
if (rc != MOSQ_ERR_SUCCESS) {
mosquitto_log_printf(MOSQ_LOG_ERR,
"subnet_acl: Failed to register reload callback");
mosquitto_callback_unregister(identifier, MOSQ_EVT_BASIC_AUTH,
basic_auth_callback, NULL);
free(pdata->config_file);
free(pdata);
return rc;
}
mosquitto_log_printf(MOSQ_LOG_INFO,
"subnet_acl: Plugin initialized with %d user(s)", pdata->user_count);
/* Only assign user_data after all possible error paths */
*user_data = pdata;
return MOSQ_ERR_SUCCESS;
}
int mosquitto_plugin_cleanup(void *user_data,
struct mosquitto_opt *opts, int opt_count)
{
plugin_data_t *pdata = user_data;
if (pdata) {
mosquitto_callback_unregister(pdata->identifier, MOSQ_EVT_BASIC_AUTH,
basic_auth_callback, NULL);
mosquitto_callback_unregister(pdata->identifier, MOSQ_EVT_RELOAD,
reload_callback, NULL);
free(pdata->config_file);
free(pdata);
}
return MOSQ_ERR_SUCCESS;
}

View File

@@ -13,42 +13,33 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=mosquitto-auth-plugin
PKG_VERSION:=1.2.1
PKG_NAME:=mosquitto-auth-shadow
PKG_VERSION:=1.0.1
PKG_MAINTAINER:=Erik Karlsson <erik.karlsson@genexis.eu>
PKG_LICENSE:=EPL-2.0
PKG_BUILD_PARALLEL:=1
PKG_CONFIG_DEPENDS:=CONFIG_MOSQUITTO_AUTH_PAM_SUPPORT
include $(INCLUDE_DIR)/package.mk
define Package/mosquitto-auth-plugin
define Package/mosquitto-auth-shadow
SECTION:=net
CATEGORY:=Network
TITLE:=mosquitto - /etc/shadow authentication plugin
DEPENDS:=+mosquitto-ssl +MOSQUITTO_AUTH_PAM_SUPPORT:libpam
DEPENDS:=+mosquitto-ssl
USERID:=mosquitto=200:mosquitto=200 mosquitto=200:shadow=11
endef
define Package/mosquitto-auth-plugin/description
define Package/mosquitto-auth-shadow/description
Plugin for the mosquitto MQTT message broker that authenticates
users using /etc/shadow
endef
define Package/mosquitto-auth-plugin/config
source "$(SOURCE)/Config.in"
endef
ifeq ($(CONFIG_MOSQUITTO_AUTH_PAM_SUPPORT),y)
TARGET_CFLAGS+=-DENABLE_PAM_SUPPORT
endif
define Package/mosquitto-auth-plugin/install
define Package/mosquitto-auth-shadow/install
$(INSTALL_DIR) $(1)/usr/lib
$(INSTALL_BIN) $(PKG_BUILD_DIR)/mosquitto_auth_plugin.so $(1)/usr/lib/
$(INSTALL_BIN) $(PKG_BUILD_DIR)/mosquitto_auth_shadow.so $(1)/usr/lib/
$(CP) ./files/* $(1)/
endef
$(eval $(call BuildPackage,mosquitto-auth-plugin))
$(eval $(call BuildPackage,mosquitto-auth-shadow))

View File

@@ -11,15 +11,15 @@
# Erik Karlsson - initial implementation
#
TARGETS = mosquitto_auth_plugin.so
TARGETS = mosquitto_auth_shadow.so
all: $(TARGETS)
%.pic.o: %.c
$(CC) $(CFLAGS) -Wall -Werror -fPIC -c -o $@ $<
mosquitto_auth_plugin.so: mosquitto_auth_plugin.pic.o
$(CC) $(LDFLAGS) -shared -o $@ $^ $(if $(filter -DENABLE_PAM_SUPPORT,$(CFLAGS)),-lpam)
mosquitto_auth_shadow.so: mosquitto_auth_shadow.pic.o
$(CC) $(LDFLAGS) -shared -o $@ $^
clean:
rm -f *.o $(TARGETS)

View File

@@ -0,0 +1,81 @@
/*
* Copyright (c) 2022 Genexis B.V.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Erik Karlsson - initial implementation
*/
#define _GNU_SOURCE
#include <string.h>
#include <shadow.h>
#include <crypt.h>
#include <mosquitto.h>
#include <mosquitto_broker.h>
#include <mosquitto_plugin.h>
static int basic_auth_callback(int event, void *event_data, void *userdata)
{
struct mosquitto_evt_basic_auth *ed = event_data;
struct spwd spbuf, *sp = NULL;
char buf[256];
struct crypt_data data;
char *hash;
/* Let other plugins or broker decide about anonymous login */
if (ed->username == NULL)
return MOSQ_ERR_PLUGIN_DEFER;
getspnam_r(ed->username, &spbuf, buf, sizeof(buf), &sp);
if (sp == NULL || sp->sp_pwdp == NULL)
return MOSQ_ERR_AUTH;
/* Empty string as hash means password is not required */
if (sp->sp_pwdp[0] == 0)
return MOSQ_ERR_SUCCESS;
if (ed->password == NULL)
return MOSQ_ERR_AUTH;
memset(&data, 0, sizeof(data));
hash = crypt_r(ed->password, sp->sp_pwdp, &data);
if (hash == NULL)
return MOSQ_ERR_AUTH;
if (strcmp(hash, sp->sp_pwdp) == 0)
return MOSQ_ERR_SUCCESS;
return MOSQ_ERR_AUTH;
}
int mosquitto_plugin_version(int supported_version_count,
const int *supported_versions)
{
return 5;
}
int mosquitto_plugin_init(mosquitto_plugin_id_t *identifier,
void **user_data,
struct mosquitto_opt *opts, int opt_count)
{
*user_data = identifier;
return mosquitto_callback_register(identifier, MOSQ_EVT_BASIC_AUTH,
basic_auth_callback, NULL, NULL);
}
int mosquitto_plugin_cleanup(void *user_data,
struct mosquitto_opt *opts, int opt_count)
{
mosquitto_plugin_id_t *identifier = user_data;
return mosquitto_callback_unregister(identifier, MOSQ_EVT_BASIC_AUTH,
basic_auth_callback, NULL);
}

View File

@@ -5,13 +5,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=netmngr
PKG_VERSION:=1.2.4
PKG_VERSION:=1.1.8
LOCAL_DEV:=0
ifneq ($(LOCAL_DEV),1)
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://dev.iopsys.eu/network/netmngr.git
PKG_SOURCE_VERSION:=8240c6089cdd44f268db135920800b8fc1d65ca9
PKG_SOURCE_VERSION:=6310f32b80f8abeccbf99ad55ce88792b19342d6
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
PKG_MIRROR_HASH:=skip
endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=netmode
PKG_VERSION:=1.1.11
PKG_VERSION:=1.1.6
PKG_RELEASE:=1
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_LICENSE:=GPL-2.0-only
@@ -18,7 +18,6 @@ include $(TOPDIR)/feeds/iopsys/bbfdm/bbfdm.mk
define Package/netmode
CATEGORY:=Utilities
TITLE:=Network Modes and Utils
DEPENDS:=+dm-service
endef
define Package/netmode/description

View File

@@ -1,380 +1,109 @@
# Netmode - Network Mode Switching for OpenWrt/iopsys
# Creating Custom Netmodes in IOWRT
**Version**: 1.1.11
**License**: GPL-2.0-only
**Maintainer**: iopsys
## Overview
Netmode is a network configuration management package for OpenWrt/iopsys-based routers that enables seamless switching between different WAN connection types. It provides a unified interface for managing network modes including DHCP, PPPoE, Static IP, and Bridge configurations.
### Key Features
- **Simple Mode Switching**: Change WAN connection type with a single command
- **Multiple Mode Support**: DHCP, PPPoE, Static IP, and Bridged mode
- **Automatic Configuration**: Handles network, firewall, DHCP, and multicast settings
- **TR-069/USP Integration**: Remote management via BBF data model
- **Extensible Architecture**: Easy to add custom network modes
- **Safe Transitions**: Proper cleanup and validation during mode switches
## Quick Start
### Installation
```bash
# Install via opkg
opkg update
opkg install netmode
# Or build from source
make package/feeds/iopsys/netmode/compile
```
### Basic Usage
```bash
# Check current mode
cat /etc/netmodes/.last_mode
# Switch to DHCP mode
uci set netmode.global.mode='routed-dhcp'
uci commit netmode
service netmode restart
# Switch to PPPoE mode
uci set netmode.global.mode='routed-pppoe'
uci set netmode.@supported_args[2].value='username@isp.com'
uci set netmode.@supported_args[3].value='password'
uci commit netmode
service netmode restart
```
## Supported Modes
| Mode | Description | Use Case |
|------|-------------|----------|
| **routed-dhcp** | Router with DHCP WAN | Cable/Fiber internet with automatic IP |
| **routed-pppoe** | Router with PPPoE WAN | DSL internet with authentication |
| **routed-static** | Router with Static IP WAN | Business connections with fixed IP |
| **bridged** | L2 Bridge Mode | Transparent bridge, no routing |
## Documentation
Comprehensive documentation is available in the following guides:
### For Users
- **[USER_GUIDE.md](USER_GUIDE.md)** - Complete user guide with configuration examples
- Getting started
- Mode descriptions
- Common use cases
- Troubleshooting
- FAQ
### For Developers
- **[DEVELOPER_GUIDE.md](DEVELOPER_GUIDE.md)** - Developer documentation
- Development environment setup
- Code organization
- API reference
- Testing framework
- Contributing guidelines
### For Implementers
- **[IMPLEMENTATION_GUIDE.md](IMPLEMENTATION_GUIDE.md)** - Implementation details
- Architecture overview
- Creating custom modes
- Environment variables
- Hook system
- Data model integration
## Architecture
```
┌─────────────────────────────────────────┐
│ Netmode System │
├─────────────────────────────────────────┤
│ UCI Config → Init Service → Mode Scripts│
│ ↓ ↓ ↓ │
│ Environment Pre-hooks UCI Copy │
│ Variables ↓ ↓ │
│ ↓ Mode Scripts Post-hooks │
│ └──────────┴────────────┘ │
│ Network Reconfiguration │
└─────────────────────────────────────────┘
```
### Components
- **Init Service** (`/etc/init.d/netmode`): Orchestrates mode switching
- **Mode Scripts** (`/etc/netmodes/<mode>/scripts/`): Mode-specific configuration
- **UCI Config** (`/etc/config/netmode`): Mode definitions and parameters
- **Data Model** (`datamodel.json`): BBF TR-181 integration
- **Hooks** (`/lib/netmode/{pre,post}/`): Pre/post mode switch scripts
## Configuration Examples
### DHCP with VLAN
```bash
uci set netmode.global.mode='routed-dhcp'
uci set netmode.@supported_args[0].value='100' # VLAN ID
uci commit netmode
service netmode restart
```
### PPPoE with Custom DNS
```bash
uci set netmode.global.mode='routed-pppoe'
uci set netmode.@supported_args[2].value='user@isp.com'
uci set netmode.@supported_args[3].value='password123'
uci set netmode.@supported_args[6].value='8.8.8.8,8.8.4.4'
uci commit netmode
service netmode restart
```
### Static IP Business Connection
```bash
uci set netmode.global.mode='routed-static'
uci set netmode.@supported_args[6].value='203.0.113.10'
uci set netmode.@supported_args[7].value='255.255.255.0'
uci set netmode.@supported_args[8].value='203.0.113.1'
uci commit netmode
service netmode restart
```
## Creating Custom Modes
Custom network modes can be added by following these steps:
1. **Create mode directory structure**:
```bash
mkdir -p /etc/netmodes/my-mode/scripts
```
2. **Define mode in supported_modes.json**:
```json
{
"name": "my-mode",
"description": "My Custom Mode",
"supported_args": [...]
}
```
3. **Create mode script**:
```bash
cat > /etc/netmodes/my-mode/scripts/10-my-mode << 'EOF'
#!/bin/sh
# Configuration logic here
EOF
chmod +x /etc/netmodes/my-mode/scripts/10-my-mode
```
4. **Import to UCI and test**:
```bash
sh /etc/uci-defaults/40_netmode_populated_supported_modes
uci set netmode.global.mode='my-mode'
service netmode restart
```
See [IMPLEMENTATION_GUIDE.md](IMPLEMENTATION_GUIDE.md#creating-a-new-network-mode) for detailed instructions.
## TR-069/USP Integration
Netmode exposes a BBF TR-181 data model for remote management:
**Data Model Path**: `Device.X_IOPSYS_EU_NetMode.`
```
Device.X_IOPSYS_EU_NetMode.
├── Enable (boolean, r/w)
├── Mode (string, r/w)
├── SupportedModesNumberOfEntries (unsignedInt, r)
└── SupportedModes.{i}.
├── Name (string, r)
├── Description (string, r)
└── SupportedArguments.{i}.
├── Name (string, r)
├── Type (string, r)
├── Required (boolean, r)
└── Value (string, r/w)
```
Example TR-069 operation:
```xml
<SetParameterValues>
<ParameterList>
<ParameterValueStruct>
<Name>Device.X_IOPSYS_EU_NetMode.Mode</Name>
<Value>routed-dhcp</Value>
</ParameterValueStruct>
</ParameterList>
</SetParameterValues>
```
## System Requirements
- **Platform**: OpenWrt/iopsys
- **Dependencies**:
- `dm-service` (BBF data model service)
- `uci`
- `procd`
- `libubox` (jshn)
- **Recommended**:
- `logread` for monitoring
- `firewall`, `odhcpd`, `mcast` for full functionality
## File Structure
```
netmode/
├── Makefile # Package build definition
├── README.md # This file
├── IMPLEMENTATION_GUIDE.md # Implementation guide
├── DEVELOPER_GUIDE.md # Developer documentation
├── USER_GUIDE.md # User documentation
├── bbfdm_service.json # BBF service registration
└── files/
├── etc/
│ ├── config/netmode # UCI configuration
│ ├── init.d/netmode # Init script (START=11)
│ ├── uci-defaults/ # First-boot scripts
│ └── netmodes/
│ ├── supported_modes.json # Mode definitions
│ ├── routed-dhcp/scripts/
│ ├── routed-pppoe/scripts/
│ ├── routed-static/scripts/
│ └── bridged/scripts/
└── lib/
├── netmode/
│ ├── pre/ # Pre-switch hooks
│ └── post/ # Post-switch hooks
└── upgrade/keep.d/netmode # Sysupgrade preservation
```
## Troubleshooting
### Mode Not Switching
```bash
# Check if enabled
uci get netmode.global.enabled
# Check logs
logread | grep netmode
# Force mode change
rm /etc/netmodes/.last_mode
service netmode restart
```
### No Internet After Switch
```bash
# Verify mode applied
cat /etc/netmodes/.last_mode
# Check WAN status
ifconfig wan
ip route
# Restart network
/etc/init.d/network restart
```
### PPPoE Authentication Failed
```bash
# Check credentials
uci show network.wan | grep -E "username|password"
# Check logs
logread | grep ppp
# Verify VLAN if required
uci get network.wan.device
```
See [USER_GUIDE.md](USER_GUIDE.md#troubleshooting) for comprehensive troubleshooting.
## Development
### Building
```bash
# Clone repository
cd feeds/iopsys/netmode
# Build package
make package/feeds/iopsys/netmode/compile V=s
# Install on device
scp bin/packages/*/iopsys/netmode_*.ipk root@192.168.1.1:/tmp/
ssh root@192.168.1.1 "opkg install /tmp/netmode_*.ipk"
```
### Testing
```bash
# Run mode switch test
./test-mode-switch.sh routed-dhcp
# Monitor logs
logread -f | grep netmode
# Verify configuration
uci show network
cat /etc/netmodes/.last_mode
```
### Contributing
Contributions are welcome! Please follow these steps:
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Test thoroughly on target hardware
5. Update documentation
6. Submit a pull request
See [DEVELOPER_GUIDE.md](DEVELOPER_GUIDE.md#contributing-guidelines) for detailed guidelines.
## License
This project is licensed under the GNU General Public License v2.0 only.
See `/LICENSE` for more information.
## Support
- **Documentation**: See guides in this repository
- **Issues**: Contact iopsys development team
- **Community**: OpenWrt and iopsys forums
## Changelog
### Version 1.1.11
- Current stable release
- Support for DHCP, PPPoE, Static IP, and Bridge modes
- BBF TR-181 data model integration
- Comprehensive documentation
## Acknowledgments
- OpenWrt project for the underlying platform
- iopsys for development and maintenance
- Contributors and testers
## Related Projects
- [OpenWrt](https://openwrt.org/) - Linux operating system for embedded devices
- [iopsys](https://www.iopsys.eu/) - Broadband device management
- [BBF](https://www.broadband-forum.org/) - Broadband Forum standards
---
**For detailed information, please refer to the specific guides:**
- Users: [USER_GUIDE.md](USER_GUIDE.md)
- Developers: [DEVELOPER_GUIDE.md](DEVELOPER_GUIDE.md)
- Implementers: [IMPLEMENTATION_GUIDE.md](IMPLEMENTATION_GUIDE.md)
This guide provides developers with detailed instructions on how to create and manage custom network modes (netmodes) in IOWRT. The `netmode` script allows for flexible network configuration, and developers can define their own modes by structuring the necessary files and scripts within the `/etc/netmodes/` directory.
## Table of Contents
1. [Overview of Netmodes](#overview-of-netmodes)
2. [Directory Structure](#directory-structure)
3. [Creating a Custom Netmode](#creating-a-custom-netmode)
- [Step 1: Pre-Execution Scripts](#step-1-pre-execution-scripts)
- [Step 2: UCI Configuration Files](#step-2-uci-configuration-files)
- [Step 3: Custom Execution Scripts](#step-3-custom-execution-scripts)
- [Step 4: Post-Execution Scripts](#step-4-post-execution-scripts)
4. [Enabling and Switching Netmodes](#enabling-and-switching-netmodes)
## Overview of Netmodes
Netmodes in IOWRT provide a way to switch between different network configurations based on the needs of the environment. Developers can create custom netmodes by organizing scripts and configuration files in specific directories under `/etc/netmodes/<NETMODE_NAME>`.
## Directory Structure
A custom netmode is defined within the `/etc/netmodes/<NETMODE_NAME>` directory, which should contain the following subdirectories:
- **/lib/netmode/pre/**: Generic scripts executed before the netmode-specific configurations are applied.
- **/etc/netmodes/<NETMODE_NAME>/uci/**: Contains UCI configuration files that will be copied to `/etc/config/` during the application of the netmode.
- **/etc/netmodes/<NETMODE_NAME>/scripts/**: Custom scripts specific to the netmode that are executed after the UCI configurations are applied.
- **/lib/netmode/post/**: Generic scripts executed after the netmode-specific configurations are completed.
## Creating a Custom Netmode
To create a new netmode, follow these steps:
### Step 1: Pre-Execution Scripts
Scripts located in `/lib/netmode/pre/` are executed before any mode-specific actions. These are typically used for preparing the system or cleaning up configurations from the previous netmode.
- **Create Pre-Execution Scripts**:
- Place your generic pre-execution scripts in `/lib/netmode/pre/`.
- Example script (`/lib/netmode/pre/cleanup.sh`):
```bash
#!/bin/sh
echo "Cleaning up old network configurations..."
# Add commands here
```
### Step 2: UCI Configuration Files
The UCI configuration files stored in `/etc/netmodes/<NETMODE_NAME>/uci/` will be copied to `/etc/config/`, effectively applying the desired network configuration.
- **Place UCI Config Files**:
- Create UCI configuration files under `/etc/netmodes/<NETMODE_NAME>/uci/`.
- Example (`/etc/netmodes/bridge/uci/network`):
````bash
config device 'br_lan'
option name 'br-lan'
option type 'bridge'
option multicast_to_unicast '0'
option bridge_empty '1'
list ports 'eth1'
list ports 'eth3'
list ports 'eth4'
config interface 'lan'
option proto 'dhcp'
option device 'br-lan'
option force_link '1'
option reqopts '43 125'
````
### Step 3: Custom Execution Scripts
After the UCI files are applied, any scripts in `/etc/netmodes/<NETMODE_NAME>/scripts/` are executed. These can be used to perform additional configuration tasks that are specific to the netmode.
- **Create Custom Scripts**:
- Add scripts to `/etc/netmodes/<NETMODE_NAME>/scripts/`.
- Example (`/etc/netmodes/bridge/scripts/setup_bridge.sh`):
```bash
#!/bin/sh
echo "Setting up bridge mode..."
# Additional configuration commands here
```
### Step 4: Post-Execution Scripts
Finally, the generic scripts in `/lib/netmode/post/` are executed. These scripts typically finalize the setup or perform any necessary cleanups.
- **Create Post-Execution Scripts**:
- Place scripts in `/lib/netmode/post/`.
- Example script (`/lib/netmode/post/restart_services.sh`):
```bash
#!/bin/sh
echo "Restarting network services..."
# Add commands here
```
## Enabling and Switching Netmodes
The netmode mechanism can be enabled or disabled via the UCI configuration, and you can switch between netmodes using UCI commands.
- **Enable Netmode**:
```bash
uci set netmode.global.enabled=1
uci commit netmode
```
- **Switch Netmode**:
```bash
uci set netmode.global.mode='<NETMODE_NAME>'
uci commit netmode
```

View File

@@ -1,857 +0,0 @@
# Netmode User Guide
## Table of Contents
1. [Introduction](#introduction)
2. [Getting Started](#getting-started)
3. [Available Network Modes](#available-network-modes)
4. [Configuration Methods](#configuration-methods)
5. [Common Use Cases](#common-use-cases)
6. [Troubleshooting](#troubleshooting)
7. [FAQ](#faq)
8. [Glossary](#glossary)
---
## Introduction
### What is Netmode?
Netmode is a network configuration management system for iopsys-based routers that allows you to easily switch between different WAN (Wide Area Network) connection types without manual configuration.
### Why Use Netmode?
- **Simplicity**: Switch network modes with a single command
- **Flexibility**: Support for multiple WAN connection types
- **Consistency**: Ensures proper configuration of all related network services
- **Remote Management**: Can be controlled via TR-069/USP protocols
- **Safety**: Automatically handles complex network reconfigurations
### Supported Connection Types
- **DHCP**: Automatic IP configuration (most common for cable/fiber connections)
- **PPPoE**: Username/password authentication (common for DSL connections)
- **Static IP**: Manual IP configuration (business connections)
- **Bridged Mode**: Bridge/modem mode (disable routing)
---
## Getting Started
### Checking if Netmode is Installed
```bash
# Check if netmode package is installed
opkg list-installed | grep netmode
# Check netmode service status
service netmode status
```
Expected output:
```
netmode - 1.1.11-1 - Network Modes and Utils
```
### Checking Current Mode
```bash
# View current configuration
uci show netmode.global
# Check active mode
cat /etc/netmodes/.last_mode
```
Example output:
```
netmode.global=netmode
netmode.global.enabled='1'
netmode.global.mode='routed-dhcp'
```
### Viewing Available Modes
```bash
# List all supported modes
uci show netmode | grep "supported_modes.*name"
```
Example output:
```
netmode.@supported_modes[0].name='routed-dhcp'
netmode.@supported_modes[1].name='routed-pppoe'
netmode.@supported_modes[2].name='routed-static'
netmode.@supported_modes[3].name='bridged'
```
---
## Available Network Modes
### 1. Routed DHCP Mode
**Mode Name**: `routed-dhcp`
**When to Use**:
- Cable internet connection
- Fiber internet connection
- Any ISP that automatically provides IP configuration
**Features**:
- Automatic IP address assignment
- Built-in router (NAT)
- Firewall enabled
- DHCP server for local devices
- IPv4 and IPv6 support
**Configuration Parameters**:
- `vlanid` (optional): VLAN ID if required by ISP
- `dns_servers` (optional): Custom DNS servers (comma-separated)
**Example Configuration**:
```bash
# Basic DHCP mode
uci set netmode.global.mode='routed-dhcp'
uci commit netmode
service netmode restart
# DHCP with VLAN ID 100
uci set netmode.global.mode='routed-dhcp'
# Find VLAN argument and set value
uci set netmode.@supported_args[0].value='100'
uci commit netmode
service netmode restart
```
---
### 2. Routed PPPoE Mode
**Mode Name**: `routed-pppoe`
**When to Use**:
- DSL internet connection
- ISP requires username and password authentication
- Connection uses PPPoE protocol
**Features**:
- Username/password authentication
- Built-in router (NAT)
- Firewall enabled
- DHCP server for local devices
- Automatic MTU optimization
**Required Parameters**:
- `username`: PPPoE username (provided by ISP)
- `password`: PPPoE password (provided by ISP)
**Optional Parameters**:
- `vlanid`: VLAN ID if required by ISP
- `mtu`: Maximum transmission unit (default: 1492 for PPPoE)
- `dns_servers`: Custom DNS servers (comma-separated)
**Example Configuration**:
```bash
# Set mode
uci set netmode.global.mode='routed-pppoe'
# Set username (find correct argument index)
uci set netmode.@supported_args[2].value='myuser@isp.com'
# Set password
uci set netmode.@supported_args[3].value='mypassword'
# Optional: Set VLAN
uci set netmode.@supported_args[4].value='100'
# Optional: Set MTU
uci set netmode.@supported_args[5].value='1492'
# Apply configuration
uci commit netmode
service netmode restart
```
**Important Notes**:
- Device will reboot after configuration
- Keep ISP credentials safe
- Most DSL connections use VLAN ID 7 or 100 (check with ISP)
- MTU typically 1492 for PPPoE (auto-configured)
---
### 3. Routed Static IP Mode
**Mode Name**: `routed-static`
**When to Use**:
- Business internet connection with static IP
- ISP provided specific IP address, subnet mask, and gateway
- Fixed IP address required for services (web server, VPN, etc.)
**Features**:
- Manual IP configuration
- Built-in router (NAT)
- Firewall enabled
- DHCP server for local devices
- Fixed WAN IP address
**Required Parameters**:
- `ipaddr`: Static IP address (e.g., 93.21.0.104)
- `netmask`: Subnet mask (e.g., 255.255.255.0)
- `gateway`: Default gateway IP (e.g., 93.21.0.1)
**Optional Parameters**:
- `vlanid`: VLAN ID if required
- `dns_servers`: DNS servers (comma-separated, e.g., 8.8.8.8,8.8.4.4)
**Example Configuration**:
```bash
# Set mode
uci set netmode.global.mode='routed-static'
# Set IP address
uci set netmode.@supported_args[6].value='93.21.0.104'
# Set subnet mask
uci set netmode.@supported_args[7].value='255.255.255.0'
# Set gateway
uci set netmode.@supported_args[8].value='93.21.0.1'
# Optional: Set DNS servers
uci set netmode.@supported_args[9].value='8.8.8.8,8.8.4.4'
# Apply configuration
uci commit netmode
service netmode restart
```
**Important Notes**:
- Use exact IP settings provided by ISP
- Incorrect settings will result in no internet connectivity
- DNS servers are optional but recommended
- Device will reboot after configuration
---
### 4. Bridged Mode
**Mode Name**: `bridged`
**When to Use**:
- Using router as a bridge/modem only
- Another router handles routing and DHCP
- ISP requires bridge mode
- Cascading routers (not recommended, prefer this mode on upstream device)
**Features**:
- All LAN and WAN ports bridged together
- No routing (NAT disabled)
- Firewall disabled
- DHCP server disabled
- Device acts as transparent bridge
**Configuration Parameters**:
- No parameters required
**Example Configuration**:
```bash
# Set mode
uci set netmode.global.mode='bridged'
uci commit netmode
service netmode restart
```
**Important Notes**:
- Device will obtain IP from upstream router/ISP
- Web interface may be inaccessible until device gets IP
- To access device: connect directly and check DHCP leases on upstream router
- Device will reboot after configuration
- Use this mode carefully - you may lose access to the device
**Reverting from Bridge Mode**:
If you lose access, connect via serial console or perform factory reset.
---
## Configuration Methods
### Method 1: UCI Command Line (SSH/Console)
**Step-by-step procedure**:
```bash
# 1. Connect to device
ssh root@192.168.1.1
# 2. View current configuration
uci show netmode
# 3. Set desired mode
uci set netmode.global.mode='routed-dhcp'
# 4. Set any required parameters (example for PPPoE)
uci set netmode.@supported_args[2].value='username@isp.com'
uci set netmode.@supported_args[3].value='password123'
# 5. Save configuration
uci commit netmode
# 6. Apply changes
service netmode restart
# 7. Monitor logs (optional)
logread -f | grep netmode
```
### Method 2: TR-069/CWMP (Remote Management)
If your device is managed by an ACS (Auto Configuration Server):
**Get current mode**:
```xml
GetParameterValues
Device.X_IOPSYS_EU_NetMode.Mode
```
**Set PPPoE mode**:
```xml
SetParameterValues
Device.X_IOPSYS_EU_NetMode.Mode = "routed-pppoe"
Device.X_IOPSYS_EU_NetMode.SupportedModes.2.SupportedArguments.1.Value = "username@isp.com"
Device.X_IOPSYS_EU_NetMode.SupportedModes.2.SupportedArguments.2.Value = "password123"
```
**Trigger mode change**:
```bash
# On device (via TR-069 script)
service netmode restart
```
### Method 3: Web Interface (if available)
Some firmware may provide a web interface for netmode configuration.
Typical location: **Network → WAN → Connection Type**
---
## Common Use Cases
### Use Case 1: Switching from DHCP to PPPoE
**Scenario**: ISP changed from cable to DSL connection
```bash
# 1. Connect to router
ssh root@192.168.1.1
# 2. Find username and password argument indices
uci show netmode | grep -A3 "name='username'"
# Note the index numbers
# 3. Set mode and credentials
uci set netmode.global.mode='routed-pppoe'
uci set netmode.@supported_args[2].value='newuser@dsl-isp.com'
uci set netmode.@supported_args[3].value='newpassword'
# 4. If ISP requires VLAN (e.g., VLAN 7)
uci set netmode.@supported_args[4].value='7'
# 5. Apply
uci commit netmode
service netmode restart
# Device will reboot
```
### Use Case 2: Adding Custom DNS Servers
**Scenario**: Want to use Google DNS or Cloudflare DNS
```bash
# For DHCP mode
uci set netmode.global.mode='routed-dhcp'
# Find dns_servers argument index
uci show netmode | grep -B2 "name='dns_servers'"
# Set custom DNS (Google DNS example)
uci set netmode.@supported_args[1].value='8.8.8.8,8.8.4.4'
# Or Cloudflare DNS
uci set netmode.@supported_args[1].value='1.1.1.1,1.0.0.1'
# Apply
uci commit netmode
service netmode restart
```
### Use Case 3: Configuring VLAN for ISP
**Scenario**: ISP requires VLAN tagging (common for fiber)
```bash
# Identify your mode (example: DHCP)
uci set netmode.global.mode='routed-dhcp'
# Find VLAN argument
uci show netmode | grep -B2 "name='vlanid'"
# Set VLAN ID (ISP will provide this, commonly 100, 7, or other)
uci set netmode.@supported_args[0].value='100'
# Apply
uci commit netmode
service netmode restart
```
### Use Case 4: Setting Up Bridge Mode for Secondary Router
**Scenario**: Using dedicated router behind ISP modem
```bash
# Configure device as bridge
uci set netmode.global.mode='bridged'
uci commit netmode
service netmode restart
# After reboot, device will be in bridge mode
# Connect to it via the IP it receives from upstream
```
### Use Case 5: Business Static IP Setup
**Scenario**: ISP provided static IP configuration
**ISP Information**:
- IP Address: 203.0.113.10
- Subnet Mask: 255.255.255.248
- Gateway: 203.0.113.9
- DNS: 203.0.113.1, 203.0.113.2
```bash
# Set mode
uci set netmode.global.mode='routed-static'
# Configure IP settings (find argument indices first)
uci show netmode | grep -B2 "name='ipaddr'"
uci show netmode | grep -B2 "name='netmask'"
uci show netmode | grep -B2 "name='gateway'"
# Set values
uci set netmode.@supported_args[6].value='203.0.113.10'
uci set netmode.@supported_args[7].value='255.255.255.248'
uci set netmode.@supported_args[8].value='203.0.113.9'
uci set netmode.@supported_args[9].value='203.0.113.1,203.0.113.2'
# Apply
uci commit netmode
service netmode restart
```
---
## Troubleshooting
### Problem: No Internet After Mode Switch
**Symptoms**:
- Cannot access websites
- No WAN IP address
- Local network works but no internet
**Diagnosis**:
```bash
# Check WAN interface status
ifconfig wan
# Check if WAN has IP
ip addr show wan
# Check routing table
ip route
# Check DNS resolution
nslookup google.com
# Check mode applied correctly
cat /etc/netmodes/.last_mode
uci show netmode.global.mode
```
**Solutions**:
1. **For DHCP mode**:
```bash
# Restart network
/etc/init.d/network restart
# Release and renew DHCP
udhcpc -i wan -n
```
2. **For PPPoE mode**:
```bash
# Check credentials
uci show network.wan.username
uci show network.wan.password
# Check PPPoE connection
logread | grep pppd
# Restart PPPoE
ifdown wan
ifup wan
```
3. **For Static IP mode**:
```bash
# Verify settings
uci show network.wan
# Check if gateway is reachable
ping -c 3 $(uci get network.wan.gateway)
```
### Problem: Cannot Access Router After Mode Change
**Symptoms**:
- Cannot reach router web interface
- Cannot SSH to router
- Router appears offline
**Solutions**:
1. **Check router IP address**:
- Routed modes: Router should be at `192.168.1.1`
- Bridged mode: Router gets IP from upstream device
2. **For bridged mode**:
```bash
# Connect to upstream router
# Check DHCP leases for your device MAC address
# Or connect via serial console
```
3. **Factory reset** (last resort):
- Hold reset button for 10 seconds
- Device will reset to default configuration
### Problem: Mode Not Switching
**Symptoms**:
- `.last_mode` not updated
- Old configuration still active
- No changes after restart
**Diagnosis**:
```bash
# Check if netmode is enabled
uci get netmode.global.enabled
# Check logs
logread | grep netmode
# Check if mode exists
ls /etc/netmodes/*/scripts/
```
**Solutions**:
```bash
# Enable netmode if disabled
uci set netmode.global.enabled='1'
uci commit netmode
# Force mode change by removing last_mode
rm /etc/netmodes/.last_mode
service netmode restart
```
### Problem: PPPoE Authentication Failure
**Symptoms**:
- WAN interface shows "connecting" but never connects
- Logs show authentication errors
**Diagnosis**:
```bash
# Check PPPoE logs
logread | grep ppp
# Common errors:
# - "authentication failed"
# - "LCP timeout"
# - "CHAP authentication failed"
```
**Solutions**:
```bash
# Verify credentials (double-check with ISP)
uci show network.wan.username
uci show network.wan.password
# Some ISPs require VLAN tagging
uci set netmode.@supported_args[4].value='7' # or ISP-specific VLAN
uci commit netmode
service netmode restart
# Check if service name is required (rare)
uci set network.wan.service='ISP-SERVICE-NAME'
uci commit network
```
### Problem: Slow Internet After Mode Switch
**Symptoms**:
- Internet works but very slow
- High latency
**Solutions**:
1. **Check MTU settings** (especially for PPPoE):
```bash
# Set MTU for PPPoE
uci set netmode.@supported_args[5].value='1492'
uci commit netmode
service netmode restart
```
2. **Check for DNS issues**:
```bash
# Test DNS resolution speed
time nslookup google.com
# Use faster DNS
uci set netmode.@supported_args[X].value='1.1.1.1,1.0.0.1'
uci commit netmode
service netmode restart
```
3. **Check WAN speed**:
```bash
# Install iperf3 and test
opkg update
opkg install iperf3
```
---
## FAQ
### General Questions
**Q: Will I lose my configuration when switching modes?**
A: Netmode preserves most router settings (WiFi, firewall rules, etc.), but WAN-specific settings are reconfigured. Local network settings remain unchanged.
**Q: How long does a mode switch take?**
A: The mode switch itself takes a few seconds, but the device will reboot, which takes 1-2 minutes total.
**Q: Can I switch modes remotely?**
A: Yes, via SSH or TR-069/USP if configured. However, be careful with bridge mode as you may lose connectivity.
**Q: Do I need to reboot manually?**
A: No, the system automatically reboots after applying a new mode.
**Q: Can I schedule a mode switch?**
A: Yes, using cron:
```bash
# Switch to bridged mode at 2 AM
echo "0 2 * * * uci set netmode.global.mode='bridged' && uci commit && service netmode restart" | crontab -
```
### Mode-Specific Questions
**Q: Which mode should I use?**
A: Depends on your ISP:
- Cable/Fiber without login: **routed-dhcp**
- DSL with username/password: **routed-pppoe**
- Static IP business connection: **routed-static**
- Using as bridge only: **bridged**
**Q: Can I use PPPoE with VLAN?**
A: Yes, set both the mode and VLAN ID:
```bash
uci set netmode.global.mode='routed-pppoe'
uci set netmode.@supported_args[4].value='100'
```
**Q: What's the difference between routed and bridged mode?**
A:
- **Routed modes**: Router performs NAT, runs firewall, provides DHCP to local network
- **Bridged mode**: Router acts as transparent bridge, no NAT, no firewall, no DHCP
**Q: Can I customize the LAN IP in routed modes?**
A: Yes, but not through netmode. After mode switch, manually configure:
```bash
uci set network.lan.ipaddr='192.168.2.1'
uci commit network
/etc/init.d/network restart
```
### Technical Questions
**Q: Where are my credentials stored?**
A: In `/etc/config/netmode` (UCI configuration). They are cleared from memory after mode application for security.
**Q: Can I create custom modes?**
A: Yes, advanced users can create custom modes. See the IMPLEMENTATION_GUIDE.md and DEVELOPER_GUIDE.md.
**Q: Does netmode support IPv6?**
A: Yes, routed-dhcp and routed-pppoe modes support IPv6 (DHCPv6).
**Q: What happens to firewall rules?**
A: Firewall is enabled for routed modes and disabled for bridged mode. Custom rules are preserved.
**Q: Can I use multiple WAN connections?**
A: Netmode manages the primary WAN. For multi-WAN setups, configure secondary WANs manually after netmode configuration.
---
## Glossary
**Bridge Mode**: Operating mode where the router acts as a transparent network bridge without routing or NAT.
**DHCP (Dynamic Host Configuration Protocol)**: Automatic IP address assignment protocol.
**DMZ (Demilitarized Zone)**: Network segment that sits between internal network and external network.
**DNS (Domain Name System)**: Service that translates domain names to IP addresses.
**Gateway**: Router IP address that connects local network to the internet.
**ISP (Internet Service Provider)**: Company providing internet access.
**LAN (Local Area Network)**: Internal network (devices in your home/office).
**MTU (Maximum Transmission Unit)**: Largest packet size that can be transmitted. PPPoE typically uses 1492.
**NAT (Network Address Translation)**: Technology allowing multiple devices to share one public IP address.
**PPPoE (Point-to-Point Protocol over Ethernet)**: Authentication protocol commonly used for DSL connections.
**Static IP**: Fixed IP address that doesn't change (opposite of DHCP).
**Subnet Mask**: Defines the network portion of an IP address (e.g., 255.255.255.0).
**TR-069/CWMP**: Remote management protocol for network devices.
**UCI (Unified Configuration Interface)**: OpenWrt configuration system.
**USP (User Services Platform)**: Next-generation device management protocol.
**VLAN (Virtual LAN)**: Network segmentation using VLAN tags (802.1Q).
**WAN (Wide Area Network)**: External network connection (internet).
---
## Getting Help
### Log Collection
When reporting issues, collect these logs:
```bash
# System logs
logread > /tmp/system.log
# Network configuration
uci export network > /tmp/network.conf
uci export netmode > /tmp/netmode.conf
# Interface status
ifconfig > /tmp/interfaces.txt
ip route > /tmp/routes.txt
# Copy to external system
scp /tmp/*.{log,conf,txt} user@external-host:/path/
```
### Support Resources
- **Documentation**: Check IMPLEMENTATION_GUIDE.md and DEVELOPER_GUIDE.md
- **Community Forums**: OpenWrt and iopsys community forums
- **Issue Tracker**: Report bugs to iopsys development team
- **ISP Support**: Contact ISP for connection-specific parameters (VLAN, credentials, etc.)
### Before Contacting Support
Please have ready:
1. Current mode: `cat /etc/netmodes/.last_mode`
2. Netmode version: `opkg info netmode | grep Version`
3. Error logs: `logread | grep netmode`
4. Network configuration: `uci export netmode`
5. What you're trying to achieve
6. What you've already tried
---
## Quick Reference Card
### Common Commands
```bash
# View current mode
cat /etc/netmodes/.last_mode
# List available modes
uci show netmode | grep "supported_modes.*name"
# Switch to DHCP
uci set netmode.global.mode='routed-dhcp'
uci commit netmode && service netmode restart
# Switch to PPPoE
uci set netmode.global.mode='routed-pppoe'
uci set netmode.@supported_args[2].value='username'
uci set netmode.@supported_args[3].value='password'
uci commit netmode && service netmode restart
# Switch to Bridge
uci set netmode.global.mode='bridged'
uci commit netmode && service netmode restart
# View logs
logread | grep netmode
# Reset to last mode
rm /etc/netmodes/.last_mode
service netmode restart
```
### Emergency Recovery
```bash
# If locked out after bridge mode
# Connect via serial console and run:
uci set netmode.global.mode='routed-dhcp'
uci commit netmode
service netmode restart
# Factory reset (hold reset button 10 seconds)
# Or via console:
firstboot -y && reboot
```
---
**Document Version**: 1.0
**Package Version**: 1.1.11
**Last Updated**: 2024
**License**: GPL-2.0-only

View File

@@ -1,2 +1,2 @@
config netmode global
option enabled 1
option enabled 0

View File

@@ -1,6 +1,6 @@
#!/bin/sh /etc/rc.common
START=11
START=10
USE_PROCD=1
. /lib/functions.sh
@@ -117,7 +117,6 @@ start_service() {
config_get_bool enabled global enabled '0'
[ $enabled -eq 0 ] && return
[ -d $MODEDIR ] || mkdir -p $MODEDIR
# Get the desired netmode from config
config_get mode global mode ""
# Check if netmode is set as boot environment parameter
@@ -128,12 +127,9 @@ start_service() {
# Get the last saved mode
lastmode="$(cat $MODEDIR/.last_mode 2>/dev/null)"
# Return if desired mode is same as last saved mode
if [ "$mode" = "$lastmode" ]; then
_log "Not switching mode[${mode}], lastmode[${lastmode}]"
return
fi
[ "$mode" == "$lastmode" ] && return
_log "Switching to [${mode}] Mode"
_log "Switching to [${mode}] Mode" >/dev/console
# Configure env variables
configure_env_vars ${mode}
@@ -151,19 +147,20 @@ start_service() {
# Execute mode specific scripts
if [ -d $MODEDIR/$mode/scripts ]; then
_log "Executing $MODEDIR/$mode/scripts/* scripts"
for script in $(ls $MODEDIR/$mode/scripts/); do
_log "Executing [${mode}], script [${script}]"
sh $MODEDIR/$mode/scripts/$script
done
fi
# Save mode as last mode
echo "$mode" > $MODEDIR/.last_mode
_log "Switching to Mode [${mode}] done, last mode updated"
# Execute netmode generic post-mode-switch scripts
libnetmode_exec "post"
cleanup_env_vars "${mode}"
# Save mode as last mode
[ -d $MODEDIR ] || mkdir -p $MODEDIR
echo "$mode" > $MODEDIR/.last_mode
_log "Switching to Mode [${mode}] done, last mode updated" >/dev/console
}
service_triggers()

View File

@@ -61,8 +61,8 @@ l2_network_config() {
uci -q set network.lan6.device='@lan'
uci -q set network.lan6.reqprefix='no'
uci -q delete network.wan
uci -q delete network.wan6
uci -q set network.wan.disabled='1'
uci -q set network.wan6.disabled='1'
uci -q delete network.br_lan.ports
uci -q set network.br_lan.bridge_empty='1'
@@ -116,3 +116,12 @@ l2_network_config() {
l2_network_config
l2_mcast_config
# If device is already boot-up, assume netmode changed during runtime
if [ -f /var/run/boot_complete ]; then
/etc/init.d/odhcpd stop 2>/dev/null
for config in network dhcp ssdpd cwmp gateway firewall mcast; do
ubus call uci commit "{\"config\":\"$config\"}"
sleep 1
done
fi

View File

@@ -17,8 +17,6 @@ l3_mcast_config() {
l3_network_config() {
logger -s -p user.info -t "netmode" "Generating L3 network configuration"
wandev="$(uci -q get network.WAN.ifname)"
# Configure L3 Network Mode
uci -q set network.lan=interface
uci -q set network.lan.device='br-lan'
@@ -38,44 +36,11 @@ l3_network_config() {
uci -q delete network.wan.disabled
uci -q delete network.wan.username
uci -q delete network.wan.password
uci -q delete network.wan.ipaddr
uci -q delete network.wan.gateway
uci -q delete network.wan.netmask
uci -q set network.wan6=interface
uci -q set network.wan6.proto="dhcpv6"
uci -q set network.wan6.proto='dhcpv6'
uci -q delete network.wan6.disabled
# Delete all VLAN sections; new ones will be created in next function if required
for vlandev_sec in $(uci show network | grep "type=.*8021q" | cut -d'.' -f1,2); do
uci -q delete $vlandev_sec
done
if [ -n "$wandev" ] && echo "$NETMODE_vlanid" | grep -Eq '^[0-9]+$' && [ "$NETMODE_vlanid" -ge 1 ]; then
vlandev="$wandev.$NETMODE_vlanid"
vlandev_sec=$(echo $vlandev | tr '.' '_')
uci -q set network.${vlandev_sec}=device
uci -q set network.${vlandev_sec}.type="8021q"
uci -q set network.${vlandev_sec}.name="$vlandev"
uci -q set network.${vlandev_sec}.ifname="$wandev"
uci -q set network.${vlandev_sec}.vid=$NETMODE_vlanid
wandev="$vlandev"
fi
uci -q set network.wan.device="$wandev"
uci -q set network.wan6.device="$wandev"
uci -q set network.WAN.mtu="$NETMODE_mtu"
uci -q delete network.wan.dns
if [ -n "$NETMODE_dns_servers" ]; then
dns_servers="$(echo $NETMODE_dns_servers | tr ',' ' ')"
for server in $dns_servers; do
uci -q add_list network.wan.dns=$server
done
fi
uci -q delete network.br_lan.ports
uci -q set network.br_lan.bridge_empty='1'
@@ -96,6 +61,12 @@ l3_network_config() {
[ -n "$device" ] && uci add_list network.br_lan.ports="$device"
fi
json_select ..
json_select wan 2>/dev/null
json_get_var device device
if [ -n "$device" ]; then
uci -q set network.wan.device="$device"
uci -q set network.wan6.device="$device"
fi
json_cleanup
fi
@@ -126,3 +97,12 @@ l3_network_config() {
l3_network_config
l3_mcast_config
# If device is already boot-up, assume netmode changed during runtime
if [ -f /var/run/boot_complete ]; then
/etc/init.d/odhcpd restart 2>/dev/null
for config in network dhcp ssdpd cwmp gateway firewall mcast; do
ubus call uci commit "{\"config\":\"$config\"}"
sleep 1
done
fi

View File

@@ -17,8 +17,6 @@ l3_mcast_config() {
l3_network_pppoe_config() {
logger -s -p user.info -t "netmode" "Generating L3 network configuration"
wandev="$(uci -q get network.WAN.ifname)"
# Configure L3 Network Mode
uci -q set network.lan=interface
uci -q set network.lan.device='br-lan'
@@ -38,40 +36,8 @@ l3_network_pppoe_config() {
uci -q set network.wan.username="$NETMODE_username"
uci -q set network.wan.password="$NETMODE_password"
uci -q delete network.wan.disabled
uci -q delete network.wan.ipaddr
uci -q delete network.wan.gateway
uci -q delete network.wan.netmask
uci -q delete network.wan6
# Delete all VLAN sections; new ones will be created in next function if required
for vlandev_sec in $(uci show network | grep "type=.*8021q" | cut -d'.' -f1,2); do
uci -q delete $vlandev_sec
done
if [ -n "$wandev" ] && echo "$NETMODE_vlanid" | grep -Eq '^[0-9]+$' && [ "$NETMODE_vlanid" -ge 1 ]; then
vlandev="$wandev.$NETMODE_vlanid"
vlandev_sec=$(echo $vlandev | tr '.' '_')
uci -q set network.${vlandev_sec}=device
uci -q set network.${vlandev_sec}.type="8021q"
uci -q set network.${vlandev_sec}.name="$vlandev"
uci -q set network.${vlandev_sec}.ifname="$wandev"
uci -q set network.${vlandev_sec}.vid=$NETMODE_vlanid
wandev="$vlandev"
fi
uci -q set network.wan.device="$wandev"
uci -q set network.WAN.mtu="$NETMODE_mtu"
uci -q delete network.wan.dns
if [ -n "$NETMODE_dns_servers" ]; then
dns_servers="$(echo $NETMODE_dns_servers | tr ',' ' ')"
for server in $dns_servers; do
uci -q add_list network.wan.dns=$server
done
fi
uci -q set network.wan6.disabled='1'
uci -q delete network.br_lan.ports
uci -q set network.br_lan.bridge_empty='1'
@@ -93,6 +59,12 @@ l3_network_pppoe_config() {
[ -n "$device" ] && uci add_list network.br_lan.ports="$device"
fi
json_select ..
json_select wan 2>/dev/null
json_get_var device device
if [ -n "$device" ]; then
uci -q set network.wan.device="$device"
uci -q set network.wan6.device="$device"
fi
json_cleanup
fi
@@ -123,3 +95,12 @@ l3_network_pppoe_config() {
l3_network_pppoe_config
l3_mcast_config
# If device is already boot-up, assume netmode changed during runtime
if [ -f /var/run/boot_complete ]; then
/etc/init.d/odhcpd restart 2>/dev/null
for config in network dhcp ssdpd cwmp gateway firewall mcast; do
ubus call uci commit "{\"config\":\"$config\"}"
sleep 1
done
fi

View File

@@ -1,126 +0,0 @@
#!/bin/sh
. /lib/functions.sh
. /usr/share/libubox/jshn.sh
source "/etc/device_info"
l3_mcast_config() {
# configure L3 mcast config
logger -s -p user.info -t "netmode" "Generating L3 mcast configuration"
rm -f /etc/config/mcast
sh /rom/etc/uci-defaults/61-mcast_config_generate
uci -q commit mcast
}
l3_network_config() {
logger -s -p user.info -t "netmode" "Generating L3 network configuration"
wandev="$(uci -q get network.WAN.ifname)"
# Configure L3 Network Mode
uci -q set network.lan=interface
uci -q set network.lan.device='br-lan'
uci -q set network.lan.proto='static'
uci -q set network.lan.ipaddr='192.168.1.1'
uci -q set network.lan.netmask='255.255.255.0'
uci -q set network.lan.ip6assign='60'
uci -q delete network.lan.vendorid
uci -q delete network.lan.clientid
uci -q delete network.lan.reqopts
uci -q delete network.lan.sendopts
uci -q delete network.lan6
uci -q set network.wan=interface
uci -q set network.wan.device="$wandev"
uci -q set network.wan.proto='static'
uci -q set network.wan.ipaddr="$NETMODE_ipaddr"
uci -q set network.wan.gateway="$NETMODE_gateway"
uci -q set network.wan.netmask="$NETMODE_netmask"
uci -q delete network.wan.disabled
uci -q delete network.wan.username
uci -q delete network.wan.password
uci -q delete network.wan6
# Delete all VLAN sections; new ones will be created in next function if required
for vlandev_sec in $(uci show network | grep "type=.*8021q" | cut -d'.' -f1,2); do
uci -q delete $vlandev_sec
done
if [ -n "$wandev" ] && echo "$NETMODE_vlanid" | grep -Eq '^[0-9]+$' && [ "$NETMODE_vlanid" -ge 1 ]; then
vlandev="$wandev.$NETMODE_vlanid"
vlandev_sec=$(echo $vlandev | tr '.' '_')
uci -q set network.${vlandev_sec}=device
uci -q set network.${vlandev_sec}.type="8021q"
uci -q set network.${vlandev_sec}.name="$vlandev"
uci -q set network.${vlandev_sec}.ifname="$wandev"
uci -q set network.${vlandev_sec}.vid=$NETMODE_vlanid
wandev="$vlandev"
fi
uci -q set network.wan.device="$wandev"
uci -q set network.WAN.mtu="$NETMODE_mtu"
uci -q delete network.wan.dns
if [ -n "$NETMODE_dns_servers" ]; then
dns_servers="$(echo $NETMODE_dns_servers | tr ',' ' ')"
for server in $dns_servers; do
uci -q add_list network.wan.dns=$server
done
fi
uci -q delete network.br_lan.ports
uci -q set network.br_lan.bridge_empty='1'
add_port_to_br_lan() {
port="$1"
[ -n "$port" -a -d /sys/class/net/$port ] || continue
uci add_list network.br_lan.ports="$port"
}
if [ -f /etc/board.json ]; then
json_load_file /etc/board.json
json_select network
json_select lan
if json_is_a ports array; then
json_for_each_item add_port_to_br_lan ports
else
json_get_var device device
[ -n "$device" ] && uci add_list network.br_lan.ports="$device"
fi
json_select ..
json_cleanup
fi
uci -q commit network
# Enable DHCP Server
uci -q set dhcp.lan.ignore=0
uci -q set dhcp.wan.ignore=1
uci -q commit dhcp
/etc/init.d/odhcpd enable
# Enable SSDPD
uci -q set ssdpd.ssdp.enabled="1"
uci -q commit ssdpd
# Update CWMP Agent WAN Interface
uci -q set cwmp.cpe.default_wan_interface="wan"
uci -q commit cwmp
# Update gateway WAN Interface
uci -q set gateway.global.wan_interface="wan"
uci -q commit gateway
# Enable firewall
uci -q set firewall.globals.enabled="1"
uci -q commit firewall
}
l3_network_config
l3_mcast_config

View File

@@ -3,96 +3,25 @@
"supported_modes": [
{
"name": "routed-dhcp",
"description": "DHCP",
"supported_args": [
{
"name": "vlanid",
"description": "VLAN ID",
"required": false,
"type": "integer"
},
{
"name": "dns_servers",
"description": "DNS Servers",
"required": false,
"type": "string"
}
]
"description": "WAN with DHCP proto (Layer 3)"
},
{
"name": "routed-pppoe",
"description": "PPPoE",
"description": "WAN with PPPoE (Layer 3)",
"supported_args": [
{
"name": "username",
"description": "PPPoE Username",
"description": "PPPoE username",
"required": true,
"type": "string",
"type": "string",
"#value": "TestUser"
},
{
"name": "password",
"description": "PPPoE Password",
"description": "PPPoE password",
"required": true,
"type": "string",
"type": "string",
"#value": "TestPassword"
},
{
"name": "vlanid",
"description": "VLAN ID",
"required": false,
"type": "integer"
},
{
"name": "mtu",
"description": "MTU",
"required": false,
"type": "integer"
},
{
"name": "dns_servers",
"description": "DNS Servers",
"required": false,
"type": "string"
}
]
},
{
"name": "routed-static",
"description": "Static",
"supported_args": [
{
"name": "ipaddr",
"description": "IP Address",
"required": true,
"type": "string",
"#value": "93.21.0.104"
},
{
"name": "netmask",
"description": "Subnet Mask",
"required": true,
"type": "string",
"#value": "255.255.255.0"
},
{
"name": "gateway",
"description": "Default Gateway",
"required": true,
"type": "string",
"#value": "93.21.0.1"
},
{
"name": "vlanid",
"description": "VLAN ID",
"required": false,
"type": "integer"
},
{
"name": "dns_servers",
"description": "DNS Servers",
"required": false,
"type": "string"
}
]
}

View File

@@ -1,60 +0,0 @@
#!/bin/sh
enabled="$(uci -q get netmode.global.enabled)"
if [ "$enabled" != "1" ]; then
exit 0
fi
opconf_file="/opconf/opconf.json"
[ -f $opconf_file ] || opconf_file="/usr_data/opconf/opconf.json"
# Check if netmode getting provisioned from opconf, in case of opconf
# provisioning, mode setting not required
mode="$(jsonfilter -i $opconf_file -e @.netmode.mode 2>/dev/null)"
if [ -n "${mode}" ]; then
exit 0
fi
# Check if opconf has wan provisioning enabled, if yes, get the proto/mode from opconf
proto="$(jsonfilter -i $opconf_file -e '@.network.wan[@.name="wan"].proto' 2>/dev/null)"
if [ -n "${proto}" ]; then
mode="routed-${proto}"
uci -q set netmode.global.mode="${mode}"
echo "${mode}" > /etc/netmodes/.last_mode
exit 0
fi
mode="$(uci -q get netmode.global.mode)"
wanproto=$(uci -q get network.wan.proto)
if [ -n "$mode" ]; then
# check if wanproto and mode aligned
if [ "${mode}" = "routed-${wanproto}" ]; then
exit 0
fi
fi
if [ ! -f "/etc/netmodes/supported_modes.json" ]; then
exit 0
fi
# NetMode is enabled without a Mode being set
# Figure out the current mode from network config
curmode=""
case "$wanproto" in
dhcp) curmode="routed-dhcp" ;;
pppoe) curmode="routed-pppoe" ;;
static) curmode="routed-static" ;;
esac
found=0
for md in $(jsonfilter -i /etc/netmodes/supported_modes.json -e "@.supported_modes.*.name"); do
[ "$md" = "$curmode" ] && found=1
done
if [ $found -eq 1 ]; then
uci -q set netmode.global.mode="$curmode"
echo "$curmode" > /etc/netmodes/.last_mode
else
exit 1
fi

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