diff --git a/netmode/Makefile b/netmode/Makefile index 68d229c1b..1509d6545 100644 --- a/netmode/Makefile +++ b/netmode/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=netmode -PKG_VERSION:=1.1.1 +PKG_VERSION:=1.1.2 PKG_RELEASE:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) PKG_LICENSE:=GPL-2.0-only diff --git a/netmode/files/datamodel.json b/netmode/files/datamodel.json index 7d1c3923c..2140471f8 100644 --- a/netmode/files/datamodel.json +++ b/netmode/files/datamodel.json @@ -3,7 +3,7 @@ "Device.{BBF_VENDOR_PREFIX}NetMode.": { "type": "object", "protocols": [ - "cwmp", + "cwmp", "usp" ], "description": "Datamodel vendor extension to support easy switching between wan types, a reboot is required in some cases after switching the mode", @@ -16,7 +16,7 @@ "write": true, "description": "Enable/Disable WAN switching using netmode", "protocols": [ - "cwmp", + "cwmp", "usp" ], "mapping": [ @@ -38,9 +38,9 @@ "type": "string", "read": true, "write": true, - "description": "Current applied netmode value", + "description": "Current configured netmode value", "protocols": [ - "cwmp", + "cwmp", "usp" ], "flags": [ @@ -68,6 +68,7 @@ "write": false, "description": "SupportedModes Number of entries in the current config", "protocols": [ + "cwmp", "usp" ], "mapping": [ @@ -88,10 +89,10 @@ "Device.{BBF_VENDOR_PREFIX}NetMode.SupportedModes.{i}.": { "type": "object", "protocols": [ - "cwmp", + "cwmp", "usp" ], - "access": true, + "access": false, "array": true, "description": "Object to list supported wan modes", "mapping": [ @@ -112,6 +113,7 @@ "write": false, "description": "Name of the wan mode, it has to be unique and in sync with /etc/netmodes/", "protocols": [ + "cwmp", "usp" ], "flags": [ @@ -132,6 +134,7 @@ "write": false, "description": "Human readable description for this mode", "protocols": [ + "cwmp", "usp" ], "mapping": [ @@ -142,25 +145,123 @@ } ] }, - "Args": { - "type": "string", + "SupportedArgumentsNumberOfEntries": { + "type": "unsignedInt", "read": true, - "write": true, - "description": "Input args for this mode", + "write": false, + "description": "SupportedModes Number of entries in the current config", "protocols": [ + "cwmp", "usp" ], - "flags": [ - "Secure" + "mapping": [ + { + "type": "uci", + "uci": { + "file": "netmode", + "section": { + "type": "supported_args" + }, + "option": { + "name": "@Count" + } + } + } + ] + }, + "Device.{BBF_VENDOR_PREFIX}NetMode.SupportedModes.{i}.SupportedArguments.{i}.": { + "type": "object", + "protocols": [ + "cwmp", + "usp" ], + "access": false, + "array": true, + "description": "Extra arguments for this Mode", "mapping": [ { - "type": "uci_sec", - "data": "@Parent", - "list": "args" + "type": "uci", + "uci": { + "file": "netmode", + "section": { + "type": "supported_args" + }, + "dmmapfile": "dmmap_netmode" + } } - ] + ], + "Name": { + "type": "string", + "read": true, + "write": false, + "description": "Name of the argument", + "protocols": [ + "cwmp", + "usp" + ], + "mapping": [ + { + "type": "uci_sec", + "data": "@Parent", + "key": "name" + } + ] + }, + "Description": { + "type": "string", + "read": true, + "write": false, + "description": "Human readable description for this Argument", + "protocols": [ + "cwmp", + "usp" + ], + "mapping": [ + { + "type": "uci_sec", + "data": "@Parent", + "key": "description" + } + ] + }, + "Required": { + "type": "boolean", + "read": true, + "write": false, + "description": "If Required is true, then Name and Value is mandatory for mode to apply", + "protocols": [ + "cwmp", + "usp" + ], + "mapping": [ + { + "type": "uci_sec", + "data": "@Parent", + "key": "required" + } + ] + }, + "Value": { + "type": "string", + "read": true, + "write": true, + "description": "Value for this SupportedArguments Name, get on this parameter result into empty output", + "protocols": [ + "cwmp", + "usp" + ], + "flags": [ + "Secure" + ], + "mapping": [ + { + "type": "uci_sec", + "data": "@Parent", + "key": "value" + } + ] + } } - } + } } } diff --git a/netmode/files/etc/init.d/netmode b/netmode/files/etc/init.d/netmode index ddd87a129..30878d038 100755 --- a/netmode/files/etc/init.d/netmode +++ b/netmode/files/etc/init.d/netmode @@ -6,18 +6,110 @@ USE_PROCD=1 . /lib/functions.sh MODEDIR="/etc/netmodes" +SUPP_MODES_SEC="" + +_log() { + logger -s -p user.info -t "netmode" "$*" +} libnetmode_exec() { when="$1" # Execute /lib/netmode scripts if [ -d /lib/netmode/$when ]; then - logger -s -p user.info -t "netmode" "Executing /lib/netmode/$when scripts" + _log "Executing /lib/netmode/$when scripts" for script in $(ls /lib/netmode/$when/); do sh /lib/netmode/$when/$script done fi } +_get_modes_sec_name() { + local sec mode name + + sec="${1}" + mode="${2}" + + config_get name ${1} name "" + if [ "${name}" = "${mode}" ]; then + SUPP_MODES_SEC="${sec}" + break; + fi +} + +_set_env_args() { + local sec name value required dm_parent + + sec="${1}" + + config_get_bool required ${sec} required "0" + config_get name ${sec} name "" + config_get value ${sec} value "" + config_get dm_parent ${sec} dm_parent "" + + if [ -z "${dm_parent}" ]; then + continue; + fi + + if [ "${dm_parent}" != "${SUPP_MODES_SEC}" ]; then + continue; + fi + + if [ "${required}" -eq "1" ]; then + if [ -z "${name}" -o -z "${value}" ]; then + _log "Can't apply mode, name[${name}] or value[${value}] is missing" + exit 0 + fi + fi + + if [ -n "${name}" -a -n "${value}" ]; then + export NETMODE_${name}="${value}" + fi +} + +configure_env_vars() { + local mode + + mode="${1}" + if [ -z "${mode}" ]; then + _log "mode info missing" + exit 0 + fi + + SUPP_MODES_SEC="" + config_load "netmode" + config_foreach _get_modes_sec_name supported_modes "${mode}" + + if [ -z "${SUPP_MODES_SEC}" ]; then + _log "mode ${mode} not found in uci" + exit 0 + fi + + config_foreach _set_env_args supported_args +} + +cleanup_arg_values() { + local dm_parent + + config_get dm_parent ${1} dm_parent "" + if [ "${dm_parent}" = "${SUPP_MODES_SEC}" ]; then + uci -q set netmode.${1}.value="" + fi +} + +cleanup_env_vars() { + for e in $(env); do + if echo ${e} |grep -q "^NETMODE_"; then + unset ${e} + fi + done + + if [ -n "${SUPP_MODES_SEC}" ]; then + config_load "netmode" + config_foreach cleanup_arg_values supported_args + uci commit netmode + fi +} + start_service() { [ -f /etc/config/netmode ] || return @@ -26,7 +118,7 @@ start_service() { [ $enabled -eq 0 ] && return # Get the desired netmode from config - config_get mode global mode + config_get mode global mode "" # Check if netmode is set as boot environment parameter [ -n "$mode" ] || mode="$(fw_printenv -n netmode 2>/dev/null)" # Return if mode is not set @@ -37,18 +129,16 @@ start_service() { # Return if desired mode is same as last saved mode [ "$mode" == "$lastmode" ] && return - # Save mode as last mode - [ -d $MODEDIR ] || mkdir -p $MODEDIR - echo "$mode" > $MODEDIR/.last_mode - - logger -s -p user.info -t "netmode" "Switching to $mode Mode" >/dev/console + _log "Switching to [${mode}] Mode" >/dev/console + # Configure env variables + configure_env_vars ${mode} # Execute netmode generic pre-mode-switch scripts libnetmode_exec "pre" # Copy netmode UCI config files if [ -d $MODEDIR/$mode/uci ]; then - logger -s -p user.info -t "netmode" "Copying $MODEDIR/$mode/uci/* to /etc/config/" + _log "Copying $MODEDIR/$mode/uci/* to /etc/config/" cp $MODEDIR/$mode/uci/* /etc/config/ 2>/dev/null fi @@ -57,7 +147,7 @@ start_service() { # Execute mode specific scripts if [ -d $MODEDIR/$mode/scripts ]; then - logger -s -p user.info -t "netmode" "Executing $MODEDIR/$mode/scripts/* scripts" + _log "Executing $MODEDIR/$mode/scripts/* scripts" for script in $(ls $MODEDIR/$mode/scripts/); do sh $MODEDIR/$mode/scripts/$script done @@ -65,6 +155,12 @@ start_service() { # 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() diff --git a/netmode/files/etc/netmodes/supported_modes.json b/netmode/files/etc/netmodes/supported_modes.json index 99bf07e4e..7323c4ce9 100644 --- a/netmode/files/etc/netmodes/supported_modes.json +++ b/netmode/files/etc/netmodes/supported_modes.json @@ -1,21 +1,31 @@ { - "mode": "routed-dhcp", - "supported_modes": [ - { - "name": "routed-dhcp", - "description": "WAN with DHCP proto (Layer 3)" - }, - { - "name": "routed-pppoe", - "description": "WAN with PPPoE (Layer 3)", - "args": [ - "username:test", - "password:testpass123" - ] - }, - { - "name": "bridged", - "description": "Bridged mode (Layer 2)" - } - ] + "#mode": "routed-pppoe", + "supported_modes": [ + { + "name": "routed-dhcp", + "description": "WAN with DHCP proto (Layer 3)" + }, + { + "name": "routed-pppoe", + "description": "WAN with PPPoE (Layer 3)", + "supported_args": [ + { + "name": "username", + "description": "PPoE username", + "required": true, + "#value": "TestUser" + }, + { + "name": "password", + "description": "PPoE password", + "required": true, + "#value": "TestPassword" + } + ] + }, + { + "name": "bridged", + "description": "Bridged mode (Layer 2)" + } + ] } diff --git a/netmode/files/etc/uci-defaults/40_supported_mode b/netmode/files/etc/uci-defaults/40_supported_mode index eca259077..e8daa31bd 100644 --- a/netmode/files/etc/uci-defaults/40_supported_mode +++ b/netmode/files/etc/uci-defaults/40_supported_mode @@ -4,6 +4,7 @@ . /usr/share/libubox/jshn.sh COUNT=1 +SUPP_ARGS=1 SUPPORTED_MODE="/etc/netmodes/supported_modes.json" if [ ! -f "/etc/config/netmode" ]; then @@ -14,6 +15,35 @@ if [ ! -f "${SUPPORTED_MODE}" ]; then exit 0 fi +configure_supp_modes_args() +{ + local obj inst name description required value parent + + obj="${1}" + inst="${2}" + parent="${3}" + + if [ -z "${inst}" ]; then + return 0 + fi + + json_select ${inst} + json_get_var name name + json_get_var description description + json_get_var value value + json_get_var required required + + uci -q set netmode.${parent}_supprted_args_${SUPP_ARGS}=supported_args + uci -q set netmode.${parent}_supprted_args_${SUPP_ARGS}.name="${name}" + uci -q set netmode.${parent}_supprted_args_${SUPP_ARGS}.description="${description}" + uci -q set netmode.${parent}_supprted_args_${SUPP_ARGS}.required="${required}" + uci -q set netmode.${parent}_supprted_args_${SUPP_ARGS}.value="${value}" + uci -q set netmode.${parent}_supprted_args_${SUPP_ARGS}.dm_parent="${parent}" + + json_select .. + SUPP_ARGS="$((SUPP_ARGS + 1))" +} + configure_supp_modes() { local obj inst name description args @@ -28,18 +58,16 @@ configure_supp_modes() json_select ${inst} json_get_var name name json_get_var description description - json_get_values args args if [ -d "/etc/netmodes/${name}" ]; then uci -q set netmode.mode_${COUNT}=supported_modes uci -q set netmode.mode_${COUNT}.name="${name}" uci -q set netmode.mode_${COUNT}.description="${description}" - - for arg in ${args}; do - uci -q add_list netmode.mode_${COUNT}.args="${arg}" - done fi + SUPP_ARGS=1 + json_for_each_item configure_supp_modes_args supported_args mode_${COUNT} + json_select .. COUNT="$((COUNT + 1))" }