You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3658 lines
128 KiB
Bash

#!/bin/sh /etc/rc.common
# Copyright (c) 2015, 2017-2018 Qualcomm Technologies, Inc.
#
# All Rights Reserved.
# Confidential and Proprietary - Qualcomm Technologies, Inc.
#
# 2015 Qualcomm Atheros, Inc.
#
# All Rights Reserved.
# Qualcomm Atheros Confidential and Proprietary.
# shellcheck disable=SC2034
START=97 # needs to be after LED init
# shellcheck disable=SC2034
SERVICE_WRITE_PID=1
# shellcheck disable=SC2034
SERVICE_DAEMONIZE=1
#SERVICE_DEBUG=1
NETWORK_RESTART=0
SERVICE_DEBUG_OUTPUT=0
REPACD_DEBUG_OUTOUT=0
# These restart_in_*_mode commands are only intended to be used by
# repacd-run.sh.
#
# - restart_in_cap_mode is used when the device has a direct connection to the
# the gateway via ethernet. This will result in only the AP interfaces being
# enabled.
# - restart_in_noncap_mode is used when the device no longer has a direct
# connection to the gateway via ethernet. When this is done, the device will
# either have both its AP and STA interfaces enabled (if its primary purpose
# is as a standalone RE) or just its STA interface enabled (if its primary
# purpose is as a client device).
# - restart_in_re_mode is used when a device that is intended to primarily
# act as a client actually has sufficient link quality to act as a range
# extender. It will enable both the STA and AP interfaces.
EXTRA_COMMANDS="restart_in_cap_mode restart_in_noncap_mode restart_in_re_mode"
EXTRA_HELP=<<EOF
restart_in_cap_mode Reconfigure the system into Central AP mode
restart_in_noncap_mode Reconfigure the system into Non Central AP mode
restart_in_re_mode Reconfigure the system into Range Extender mode
EOF
WSPLCD_INIT='/etc/init.d/wsplcd'
HYFI_BRIDGING_INIT='/etc/init.d/hyfi-bridging'
HYD_INIT='/etc/init.d/hyd'
LBD_INIT='/etc/init.d/lbd'
MCSD_INIT='/etc/init.d/mcsd'
#check repacd config to enable/disable cfg80211
config_load 'repacd'
config_get_bool repacd_cfg config 'cfg80211_enable' '0'
if [ "$repacd_cfg" == "1" ]; then
REPACD_CFG80211=-cfg80211
else
REPACD_CFG80211=
fi
WSPLCD_MAP_DIR='/etc/wsplcd/map'
WSPLCD_MAP_BSS_POLICY_PATH="${WSPLCD_MAP_DIR}/bss-policy.conf"
WSPLCD_MAP_TEMPLATE_DIR="${WSPLCD_MAP_DIR}/templates"
. /lib/functions/whc-debug.sh
. /lib/functions/whc-iface.sh
. /lib/functions/whc-network.sh
. /lib/functions/repacd-netdet.sh
RE_DEFAULT_RATE_ESTIMATE_SCALING_FACTOR='70'
RE_ROOT_AP_DISTANCE_INVALID='255'
managed_network='' config_changed=0 map_bsta_max_preference=0
vap_defconf=1
config_re_mode='' resolved_re_mode='' resolved_re_submode=''
wsplcd_enabled=0 wsplcd_start=0 wsplcd_stop=0 wsplcd_restart=0
hyd_start=0 hyd_stop=0
resolved_ssid='' resolved_enc='' resolved_key=''
network_guest=
guest_backhaul_iface=
network_backhaul="backhaul"
backhaul_ssid='' backhaul_key='' backhaul_enc=''
def_backhaul_ssid="Backhaul" def_backhaul_key="1234567890" def_backhaul_enc="psk2+ccmp"
guest_ssid='' guest_enc='' guest_key=''
def_guest_ssid="Guest" def_guest_enc="none" def_guest_key=""
traffic_separation_enabled='' traffic_separation_active='' create_sta=0
daisy_chain=0 manage_vap_ind=0
bssid_resolve_state="resolving"
net_config_changed=0
lan_vid=100 guest_vid=102
eth_iface_wan="eth0"
eth_iface_lan="eth1"
eth_iface_wan_port=5
eth_iface_lan_port1=4
eth_iface_lan_port2=3
capsnr=0
Manage_front_and_back_hauls_ind=0
# Write the provided log message to the correct output stream.
# If REPACD_DEBUG_OUTOUT is non-zero, it will be written to the console.
# Otherwise, it will be written to stdout.
__repacd_echo() {
if [ "$REPACD_DEBUG_OUTOUT" -gt 0 ]; then
echo "whc (repacd): $*" > /dev/console
else
echo "whc (repacd): $*"
fi
}
# Determine if the device is configured in gateway mode or not.
# Note that a device can still act as a CAP even if it is not in gateway
# mode, but this is detected later by the repacd-run.sh script.
#
# return: 0 if in gateway mode; otherwise non-zero
__repacd_gw_mode() {
local wan_iface
config_load network
config_get wan_iface wan ifname
[ -n "$wan_iface" ] && return 0
return 1
}
# Determine if the network is configured or not.
#
# input: $1 network name
# return: 0 if network exist; otherwise non-zero
__repacd_network_exist() {
local lan_name=$1
local no_network
no_network=$(uci show "network.$lan_name" 2>&1 | grep 'Entry not found')
[ -n "$no_network" ] && return 1
return 0
}
# Set bridge_empty option for the given network.
# This option allows to create empty_bridge.
#
# input: $1 network name
__repacd_set_bridge_empty() {
local name="$1"
local bridge_empty
config_load network
config_get bridge_empty "$name" 'bridge_empty' 0
if [ "$bridge_empty" -eq 0 ]; then
uci_set network "$name" bridge_empty '1'
fi
uci_commit network
}
# Determine if additional network exist.
# Currently looking out for only guest network.
#
# input: $1 network name
# return: 0 if exist; otherwise non-zero
__repacd_check_additional_network_exist() {
config_load network
if [ -n "$network_guest" ]; then
if __repacd_network_exist $network_guest; then
return 0
fi
fi
return 1
}
# Add the given interface to the given network.
# input: $1 network name
# input: $2 interface name
__repacd_add_interface() {
local name=$1 new_if="$2"
local if_name
if __repacd_network_exist "$name"; then
if [ -n "$new_if" ]; then
if_name=$(uci get "network.$name.ifname")
if [ -n "$if_name" ]; then
if_name="$if_name $new_if"
else
if_name="$new_if"
fi
if_name=$(echo "$if_name" | xargs -n1 | sort -u | xargs)
uci_set network "$name" ifname "$if_name"
fi
fi
}
# Get backhaul interfaces for ethernet.
# output: $1 - variable into which we populate interface(eth0.102 or eth1.102).
__repacd_get_backhaul_ifaces_eth_guest() {
local ifaces
local ifaces_guest_intf
ifaces=$(ifconfig 2>&1 | grep eth | grep $guest_vid)
ifaces_guest_intf=$(echo "$ifaces" | cut -d ' ' -f1)
eval "$1='$ifaces_guest_intf'"
}
# Delete the given interface from the given network.
# input: $1 network name
# input: $2 interface name
__repacd_delete_interface() {
local name=$1 interface="$2"
local if_name
if __repacd_network_exist "$name"; then
if [ -n "$interface" ]; then
if_name=$(uci get "network.$name.ifname")
if [ -n "$if_name" ]; then
if_name=${if_name/$interface/}
fi
uci_set network "$name" ifname "$if_name"
fi
fi
}
# Create necessary VLAN interfaces for the backhaul vaps and add the
# created VLAN interfaces to the given network.
# VLAN interfaces are created by concatenating interface name and vlan id.
# input: $1 name of the interface config section
# input: $2 network name
# input: $3 VLAN id
# input: $4 Band '2.4G' or '5G' or 'both'
# input-output: $5 change counter
__repacd_add_vlan_interfaces() {
local config=$1
local id=$3
local backhaul_iface=$4
local changed="$5"
local ifname vlan_ifname
local disabled mode bssid device hwmode
local add_vlan=0
config_get network "$config" network
config_get ifname "$config" ifname
config_get disabled "$config" disabled '0'
config_get mode "$config" mode
config_get device "$config" device
config_get hwmode "$device" hwmode
if [ "$hwmode" != "11ad" ]; then
if [ "$network" = "$network_backhaul" ] && [ -n "$ifname" ] && \
[ "$disabled" -eq 0 ]; then
vlan_ifname=$(iwconfig 2>&1 | grep "$ifname.$id" | cut -d ' ' -f1)
if [ -z "$vlan_ifname" ]; then
if [ "$backhaul_iface" = 'both' ] || [ "$mode" = "ap" ]; then
add_vlan=1
elif [ "$backhaul_iface" = '5G' ] && \
[ "$hwmode" = '11ac' ] || [ "$hwmode" = '11na' ] || [ "$hwmode" = '11a' ]; then
add_vlan=1
elif [ "$backhaul_iface" = '2.4G' ] && \
[ "$hwmode" = '11ng' ] || [ "$hwmode" = '11g' ] || [ "$hwmode" = '11b' ]; then
add_vlan=1
fi
if [ "$add_vlan" -gt 0 ]; then
vconfig add "$ifname" "$id"
brctl addif "br-$2" "$ifname.$id"
ifconfig "$ifname.$id" up
__repacd_add_interface "$2" "$ifname.$id"
changed=$((changed + 1))
eval "$5='$changed'"
fi
fi
fi
fi
}
# Delete VLAN interfaces of backhaul vaps.
# input: $1 name of the interface config section
# input: $2 network name
# input: $3 VLAN id
# input: $4 mode 'sta' or 'ap'
# input-output: $5 change counter
__repacd_delete_vlan_interfaces() {
local config=$1
local id=$3
local changed="$5"
local ifname vlan_ifname
local disabled mode bssid device hwmode
config_get network "$config" network
config_get ifname "$config" ifname
config_get disabled "$config" disabled '0'
config_get mode "$config" mode
config_get device "$config" device
config_get hwmode "$device" hwmode
if [ "$hwmode" != "11ad" ]; then
if [ "$network" = "$network_backhaul" ] && [ -n "$ifname" ] && \
[ "$disabled" -eq 0 ]; then
vlan_ifname=$(iwconfig 2>&1 | grep "$ifname.$id" | cut -d ' ' -f1)
if [ -n "$vlan_ifname" ]; then
if __repacd_is_matching_mode "$4" "$mode"; then
vconfig rem "$ifname.$id"
brctl delif "br-$2" "$ifname.$id"
__repacd_delete_interface "$2" "$ifname.$id"
changed=$((changed + 1))
eval "$5='$changed'"
fi
fi
fi
fi
}
#Create Back haul interface for ethernet guest network and
#add it to the respective bridge
#input:$1 guest network name
#input-output:$2 change counter
__repacd_add_ethernet_vlan_interfaces() {
local backhaul_ifaces_eth
local network=$1
local changed="$2"
__repacd_get_backhaul_ifaces_eth_guest backhaul_ifaces_eth
if [ -n "$backhaul_ifaces_eth" ]; then
__repacd_echo "Add VLAN ifaces for ethernet guest network support"
if [ "$backhaul_ifaces_eth" = "$eth_iface_wan.$guest_vid" ] && [ "$network" = 'guest' ];then
swconfig dev switch0 vlan $guest_vid set ports "0t ${eth_iface_wan_port}t ${eth_iface_lan_port1}t"
swconfig dev switch0 set apply
brctl addif "br-$network" "$backhaul_ifaces_eth"
ifconfig "$backhaul_ifaces_eth" up
__repacd_add_interface "$network" "$backhaul_ifaces_eth"
elif [ "$backhaul_ifaces_eth" = "$eth_iface_lan.$guest_vid" ] && [ "$network" = 'guest' ];then
swconfig dev switch0 vlan $guest_vid set ports "0t ${eth_iface_lan_port1}t ${eth_iface_lan_port2}t"
swconfig dev switch0 set apply
brctl addif "br-$network" "$backhaul_ifaces_eth"
ifconfig "$backhaul_ifaces_eth" up
__repacd_add_interface "$network" "$backhaul_ifaces_eth"
else
__repacd_echo "For Home network all the traffic is untagged,no vlan"
fi
#Do we really need to restart? revisit this
changed=$((changed + 1))
eval "$2='$changed'"
fi
}
# Create firewall rules for the given network if the rule does not exist.
# input: $1 network name
__repacd_set_firewall_rules() {
local network=$1
local no_rule
local rule_name
no_rule=$(uci show firewall | grep zone | grep "$network")
if [ -z "$no_rule" ]; then
local zone
zone=$(uci add firewall zone)
if [ -n "$zone" ]; then
uci_set firewall "$zone" name "$network"
uci add_list "firewall.$zone.network=$network"
uci_set firewall "$zone" input 'REJECT'
uci_set firewall "$zone" output 'ACCEPT'
uci_set firewall "$zone" forward 'REJECT'
local fwd
fwd=$(uci add firewall forwarding)
if [ -n "$fwd" ]; then
uci_set firewall "$fwd" src "$network"
uci_set firewall "$fwd" dest 'wan'
fi
local rule
rule=$(uci add firewall rule)
if [ -n "$rule" ]; then
uci_set firewall "$rule" name 'Allow-DHCP-request'
uci_set firewall "$rule" src "$network"
uci_set firewall "$rule" src_port '67-68'
uci_set firewall "$rule" dest_port '67-68'
uci_set firewall "$rule" proto 'udp'
uci_set firewall "$rule" target 'ACCEPT'
fi
rule=$(uci add firewall rule)
if [ -n "$rule" ]; then
uci_set firewall "$rule" name 'Allow-DNS-queries'
uci_set firewall "$rule" src "$network"
uci_set firewall "$rule" dest_port '53'
uci_set firewall "$rule" proto 'tcpudp'
uci_set firewall "$rule" target 'ACCEPT'
fi
rule=$(uci add firewall rule)
if [ -n "$rule" ]; then
rule_name="Block-$managed_network-$network-forwarding"
uci_set firewall "$rule" name "$rule_name"
uci_set firewall "$rule" src $managed_network
uci_set firewall "$rule" dest "$network"
uci_set firewall "$rule" proto '0'
uci_set firewall "$rule" family 'any'
uci_set firewall "$rule" target 'REJECT'
fi
rule=$(uci add firewall rule)
if [ -n "$rule" ]; then
rule_name="Block-$network-$managed_network-forwarding"
uci_set firewall "$rule" name "$rule_name"
uci_set firewall "$rule" src "$network"
uci_set firewall "$rule" dest $managed_network
uci_set firewall "$rule" proto '0'
uci_set firewall "$rule" family 'any'
uci_set firewall "$rule" target 'REJECT'
fi
fi
fi
uci_commit firewall
}
# Restart firewall.
__repacd_restart_firewall() {
/etc/init.d/firewall restart
}
# Check whether the given interface is the backhaul AP interface on
# the desired network and update the band specific interface names.
#
# input: $1 - config: the name of the interface config section
# input: $2 - network: the name of the network to which the AP interface
# must belong to be matched
# output: $3 - iface: the resolved backhaul AP interface name on 2.4 GHz (if found)
# output: $4 - iface: the resolved backhaul AP interface name on 5 GHz (if found)
__repacd_wifi_check_and_get_backhaul_ap_iface() {
local config="$1"
local network_to_match="$2"
local iface disabled mode device hwmode backhaul_ap
config_get network "$config" network
config_get iface "$config" ifname
config_get disabled "$config" disabled '0'
config_get mode "$config" mode
config_get device "$config" device
config_get backhaul_ap "$config" backhaul_ap '0'
config_get hwmode "$device" hwmode
if [ "$hwmode" != "11ad" ]; then
if [ "$network" = "$network_to_match" ] && [ -n "$iface" ] && [ "$mode" = "ap" ] \
&& [ "$backhaul_ap" -gt 0 ] && [ "$disabled" -eq 0 ]; then
if whc_is_5g_vap "$config"; then
eval "$4=$iface"
else
eval "$3=$iface"
fi
fi
fi
}
# Configure the otherband BSSIDs for both backhaul APs
# input: $1 - network: the name of the network to which the AP interface
# must belong to be matched
# output: None
__repacd_wifi_set_otherband_bssids() {
local otherband_bssid1 otherband_bssid2 bssid_5g bssid_24g
local backhaul_ap_iface_24g backhaul_ap_iface_5g success=0 loop_count=15
while [ "$success" -eq 0 ] && [ "$loop_count" -gt 0 ]; do
config_load wireless
config_foreach __repacd_wifi_check_and_get_backhaul_ap_iface wifi-iface "$1" \
backhaul_ap_iface_24g backhaul_ap_iface_5g
if [ -n "$backhaul_ap_iface_5g" ] && [ -n "$backhaul_ap_iface_24g" ]; then
bssid_5g=$(ifconfig "$backhaul_ap_iface_5g" | grep "HWaddr" | awk -F" " '{print $5}')
bssid_24g=$(ifconfig "$backhaul_ap_iface_24g" | grep "HWaddr" | awk -F" " '{print $5}')
otherband_bssid1=$(echo "$bssid_5g" | sed -e "s/://g" | cut -b 1-8)
otherband_bssid2=$(echo "$bssid_5g" | sed -e "s/://g" | cut -b 9-12)
if [ -z $REPACD_CFG80211 ]; then
iwpriv $backhaul_ap_iface_24g otherband_bssid 0x$otherband_bssid1 0x$otherband_bssid2
else
cfg80211tool $backhaul_ap_iface_24g otherband_bssid 0x$otherband_bssid1 0x$otherband_bssid2
fi
otherband_bssid1=$(echo "$bssid_24g" | sed -e "s/://g" | cut -b 1-8)
otherband_bssid2=$(echo "$bssid_24g" | sed -e "s/://g" | cut -b 9-12)
if [ -z $REPACD_CFG80211 ]; then
iwpriv $backhaul_ap_iface_5g otherband_bssid 0x$otherband_bssid1 0x$otherband_bssid2
else
cfg80211tool $backhaul_ap_iface_5g otherband_bssid 0x$otherband_bssid1 0x$otherband_bssid2
fi
success=1
else
sleep 1
loop_count=$((loop_count - 1))
fi
done
}
# Enumerate all of the wifi interfaces and append
# only station devices to the variable provided.
# output: $1 devices: variable to populate with the station devices
__repacd_get_sta_devices() {
local devices=$1
config_cb() {
local type="$1"
local section="$2"
case "$type" in
wifi-iface)
config_get mode "$section" mode
config_get device "$section" device
if [ "$mode" = 'sta' ];then
eval append $devices "$device"
fi
;;
esac
}
config_load wireless
}
# Configure the vap independent parameter for given wifi interface.
#
# input: $1 - config: interface config name to configure.
# input: $2 - devices: list of devices to match with provided interface.
__repacd_config_vap_ind() {
local config=$1
local devices=$2
local match_found=0
local device
config_load wireless
config_get device "$config" device
for device_to_match in $devices; do
if [ "$device" = "$device_to_match" ]; then
if __repacd_is_son_mode; then
# If in SON mode, STA vaps may be forced down based on
# link strength so configure the VAPs in independent mode.
# This will be used in conjunction with the other feature
# that monitors the backhaul links and brings down the AP VAPs
# if there is no backhaul for a sustained period of time.
__repacd_update_vap_param "$config" 'athnewind' 1
else
__repacd_update_vap_param "$config" 'athnewind' 0
fi
match_found=1
fi
done
# If the feature Manage Front-Haul VAPs independently based on
# CAP's reachability is enabled, then set athnewind value to 1.
if [ "$Manage_front_and_back_hauls_ind" -gt 0 ]; then
__repacd_update_vap_param "$config" 'athnewind' 1
# This is mainly for wsplcd optimization: if wsplcd detects athnewind
# is set to 0, it will not restart VAP; otherwise it will bring down
# the VAP, set athnewind to 0 and bring the VAP back up
elif [ "$match_found" -eq 0 ]; then
__repacd_update_vap_param "$config" 'athnewind' 0
fi
}
# Configure the vap independent parameter for all VAPs
# only if repacd is allowed to configure this parameter.
# input: None
__repacd_config_independent_vaps() {
local sta_devices=
if [ "$manage_vap_ind" -gt 0 ]; then
__repacd_get_sta_devices sta_devices
__repacd_echo "Station device list = $sta_devices"
config_foreach __repacd_config_vap_ind wifi-iface "$sta_devices"
else
# Pass empty device list, so that all vaps set to athnewind=0.
config_foreach __repacd_config_vap_ind wifi-iface "$sta_devices"
fi
}
# Determine the configured RE mode, not applying any automatic mode
# switching rules.
#
# output: $1 variable in which to place the resolved mode
__repacd_get_config_re_mode() {
local resolved_mode=$1
local mode
config_load 'repacd'
config_get mode repacd 'ConfigREMode' 'auto'
eval "$resolved_mode=$mode"
}
# Determine whether the provided mode is an automatic mode.
#
# input: $1 mode: the mode to check
# return: 0 if the mode is an auto mode; otherwise 1
__repacd_is_auto_re_mode() {
local mode=$1
if [ "$mode" = 'auto' ]; then
return 0
fi
return 1
}
# Resolve the current mode in which to operate the range extender.
#
# This mode is either the configured mode (if it is set to a specific
# mode), the automatically derived RE mode based on association information,
# or the default range extender mode for use at startup.
#
# output: $1 - the variable into which to place the resolved mode
__repacd_get_re_mode() {
local resolved_mode=$1
local mode default_mode
__repacd_get_config_re_mode config_re_mode
if __repacd_is_auto_re_mode $config_re_mode; then
config_get default_mode repacd 'DefaultREMode' 'qwrap'
config_get mode repacd 'AssocDerivedREMode' "$default_mode"
else
mode=$config_re_mode
fi
# Get the Association derived sub-mode. If not derived, say "star".
config_get resolved_re_submode repacd 'AssocDerivedRESubMode' 'star'
eval "$resolved_mode=$mode"
}
# Determine if the range extension mode is set to WDS.
#
# return: 0 if the mode is set to WDS; otherwise 1 (meaing QWrap or ExtAP)
__repacd_is_wds_mode() {
__repacd_get_re_mode resolved_re_mode
case "$resolved_re_mode" in
wds|WDS)
return 0
;;
*)
return 1
;;
esac
}
# Determine if the range extension mode is set to QWrap.
#
# return: 0 if the mode is set to QWrap; otherwise 1 (meaning WDS or ExtAP)
__repacd_is_qwrap_mode() {
__repacd_get_re_mode resolved_re_mode
case "$resolved_re_mode" in
qwrap|QWRAP)
return 0
;;
*)
return 1
esac
}
# Determine if the range extension mode is set to SON.
# Note that if the hyd init script is missing, this will be considered as
# SON mode disabled.
#
# return: 0 if the mode is set to SON; otherwise 1 (meaing WDS or an
# interoperable range extension mode)
__repacd_is_son_mode() {
if [ ! -f $HYD_INIT ]; then
return 1
fi
__repacd_get_re_mode resolved_re_mode
case "$resolved_re_mode" in
son|SON)
return 0
;;
*)
return 1
;;
esac
}
# Determine whether the Multi-AP Topology Optimization algorithm is enabled.
#
# return: 0 if the algorithm is enabled; otherwise 1
__repacd_is_map_enabled() {
local map_enabled
config_load 'repacd'
config_get_bool map_enabled MAPConfig 'Enable' '0'
[ "$map_enabled" -gt 0 ]
return $?
}
# Determine if DFS channels are to be blocked even for WDS mode.
#
# return: 0 if DFS channels should not be used; otherwise 1 (meaning they may
# be used)
__repacd_is_block_dfs() {
local block_dfs
config_load 'repacd'
config_get block_dfs repacd 'BlockDFSChannels' '0'
if [ "$block_dfs" -gt 0 ]; then
return 0
else
return 1
fi
}
# Get the configured Rate scaling factor.
# Gives default value in case of configuration miss or invalid value.
#
# output: $1 - rate_scaling_factor
__repacd_get_rate_scaling_factor() {
local scaling_factor
config_load 'repacd'
config_get scaling_factor WiFiLink 'RateScalingFactor' $RE_DEFAULT_RATE_ESTIMATE_SCALING_FACTOR
# If scaling factor out of limits, return the default value "70".
if [ "$scaling_factor" -lt '1' ] || \
[ "$scaling_factor" -gt '100' ]; then
scaling_factor=$RE_DEFAULT_RATE_ESTIMATE_SCALING_FACTOR
fi
eval "$1=$scaling_factor"
}
# check vap is in default configuration by comparing ssid as OpenWrt
# and encryption as none,for now any one VAP with this configuration
# is enough for marking configuration as default configuration.
# Internal driver currently does not support 11ad so ignoring
# 11ad enabled devices for now.
# input: $1 config: section to update
# input: $2 network: Global variable vap_defconf.
# input-output:$2 is set to '0' in case we have any VAP
# with default config.
__repacd_check_default_vaps() {
local config="$1"
config_get device "$config" device
config_get ssid "$config" ssid
config_get encryption "$config" encryption
config_get hwmode "$device" hwmode
config_get type "$device" type
config_get_bool repacd_security_unmanaged "$config" repacd_security_unmanaged '0'
if [ "$hwmode" = '11ad' ] && [ "$type" = 'mac80211' ] ;then
return
fi
if [ "$repacd_security_unmanaged" -eq 1 ] ; then
return
fi
if [ "$ssid" = "OpenWrt" ] && [ "$encryption" = "none" ] ;then
eval "$2='0'"
fi
}
# Determine if the VAPs are in the default configuration.
# For now this is defined simply as any VAP having the default SSID and no
# security enabled or that there are no VAPs whatsoever.
#
# return: 0 if in the default configuration; otherwise non-zero
__repacd_vaps_in_default_config() {
local no_vaps
# If there is no entry, uci will give an error message. We detect this
# by looking for the string in the output.
no_vaps=$(uci show wireless.@wifi-iface[-1] 2>&1 | grep 'Entry not found')
[ -n "$no_vaps" ] && return 0
config_load wireless
config_foreach __repacd_check_default_vaps wifi-iface vap_defconf
return $vap_defconf
}
# Generate a suffix for the SSID using the last 3 bytes of the MAC address
# on the bridge that is being managed.
#
# output: $1 - variable into which to write the SSID suffix
__repacd_generate_ssid_suffix() {
local generated_suffix
generated_suffix=$(ifconfig br-$managed_network | grep HWaddr | awk '{print $5}' | awk -F":" '{print $4$5$6}')
eval "$1=$generated_suffix"
}
# Generate a random pre-shared key for use with WPA2
#
# output: $1 - variable into which to write the PSK
__repacd_generate_psk() {
local generated_key
generated_key=$(dd if=/dev/urandom bs=1 count=8 2> /dev/null | openssl base64)
eval "$1=$generated_key"
}
# Reconfigure all managed VAPs and create new ones as appropriate. This is
# non-destructive in that all configuration parameters for a VAP that are not
# directly controlled by this script will not be modified.
#
# This should generally only be called when starting with a fresh
# configuration (eg. at first boot or due to a user request), as it will
# generate an SSID and passphrase. See __repacd_reset_existing_config() for
# the function used when the SSID and passphrase configured are to be
# preserved.
__repacd_reset_default_config() {
config_load wireless
config_foreach __repacd_resolve_vaps wifi-iface $managed_network
# Use last three bytes of the MAC address to help make the SSID unique.
local ssid_suffix
__repacd_generate_ssid_suffix ssid_suffix
# Generate a random password (which will likely be changed either through
# cloning or by the end user).
local random_psk
__repacd_generate_psk random_psk
__repacd_create_vaps "whc-$ssid_suffix" 'psk2+ccmp' "$random_psk"
uci_commit wireless
}
# Delete all managed VAPs and re-create them according to the current
# configuration.
#
# Unlike the above, this is destructive in that all VAPs not marked as
# repacd_security_unmanaged will be deleted. If this is not desired, set the
# FirstConfigRequired flag to 0 to prevent this step from taking place. In
# this case, the VAPs must be created manually in a manner that matches the
# expectations of this script.
#
# input: $1 - is_controller: whether this device is acting as the controller
__repacd_reset_map_default_config() {
local is_controller=$1
local fronthaul_ssid fronthaul_key backhaul_ssid backhaul_key
local backhaul_suffix
config_load repacd
config_get fronthaul_ssid MAPConfig 'FronthaulSSID' ''
config_get fronthaul_key MAPConfig 'FronthaulKey' ''
config_get backhaul_ssid MAPConfig 'BackhaulSSID' ''
config_get backhaul_key MAPConfig 'BackhaulKey' ''
config_get backhaul_suffix MAPConfig 'BackhaulSuffix' ''
config_load wireless
config_foreach __repacd_delete_managed_vaps wifi-iface $managed_network
uci_commit wireless
# Clear out the environment of all CONFIG_ variables. Seems like there
# should be some way to do this in UCI.
unset $(set | grep '^CONFIG_' | awk -F'=' '{print $1}')
# Reload to reset our variable state after the deletion
config_load wireless
if [ -z "$fronthaul_ssid" ]; then
local ssid_suffix
__repacd_generate_ssid_suffix ssid_suffix
fronthaul_ssid="mapsig-${ssid_suffix}"
__repacd_generate_psk fronthaul_key
fi
if [ -z "$backhaul_ssid" ]; then
backhaul_ssid="${fronthaul_ssid}${backhaul_suffix}"
if [ "$fronthaul_ssid" = "$backhaul_ssid" ]; then
backhaul_key=$fronthaul_key
else
__repacd_generate_psk backhaul_key
fi
fi
__repacd_create_vaps_map "$is_controller" "$fronthaul_ssid" "$fronthaul_key" \
"$backhaul_ssid" "$backhaul_key"
}
# Delete all of the VAPs for the given network that are marked as unmanaged.
#
# input: $1 config: section being considered
# input: $2 network: managed network name
__repacd_delete_managed_vaps() {
local config="$1"
local network repacd_security_unmanaged
config_get network "$config" network
config_get_bool repacd_security_unmanaged "$config" repacd_security_unmanaged '0'
if [ "$2" = "$network" ] && [ "$repacd_security_unmanaged" -eq 0 ]; then
uci delete "wireless.$config"
fi
}
# Create the VAPs needed for Multi-AP SIG Topology Optimization with them all
# initially disabled.
#
# input: $1 is_controller: whether this device is acting as the controller
# input: $2 fronthaul_ssid: the SSID to use on all fronthaul VAPs
# input: $3 fronthaul_key: the PSK for the fronthaul, or the empty string
# for open mode
# input: $4 backhaul_ssid: the SSID to use on all backhaul VAPs
# input: $5 backhaul_key: the PSK for the backhaul, or the empty string
# for open mode
__repacd_create_vaps_map() {
local is_controller=$1
local fronthaul_ssid=$2
local fronthaul_key=$3
local backhaul_ssid=$4
local backhaul_key=$5
local fronthaul_encryption backhaul_encryption
# Whether the same VAP is used for fronthaul and backhaul or not.
local shared_vaps=0
if [ "$fronthaul_ssid" = "$backhaul_ssid" ]; then
shared_vaps=1
fi
if [ -n "$fronthaul_key" ]; then
fronthaul_encryption='psk2+ccmp'
fi
if [ -n "$backhaul_key" ]; then
backhaul_encryption='psk2+ccmp'
else
backhaul_encryption='none'
fi
local DEVICES=
__repacd_get_devices DEVICES
for device in $DEVICES; do
local repacd_auto_create_vaps repacd_create_bsta repacd_bsta_pref
local create_ctrl_fbss create_ctrl_bbss
config_get_bool repacd_auto_create_vaps "$device" repacd_auto_create_vaps '1'
config_get_bool repacd_create_bsta "$device" repacd_create_bsta '1'
config_get repacd_bsta_pref "$device" repacd_map_bsta_preference '0'
config_get_bool create_ctrl_fbss "$device" repacd_create_ctrl_fbss '1'
config_get_bool create_ctrl_bbss "$device" repacd_create_ctrl_bbss '1'
uci_set wireless $device disabled '0'
if [ "$repacd_auto_create_vaps" -gt 0 ] && [ "$repacd_create_bsta" -gt 0 ] && \
! whc_is_5g_radio "$device"; then
# Create a bSTA interface
name=$(uci add wireless wifi-iface)
config_changed=1
__repacd_init_vap "$name" $device 'sta' "$backhaul_ssid" \
$backhaul_encryption "$backhaul_key"
__repacd_update_vap_param "$name" 'map' 1
__repacd_update_vap_param "$name" 'MapBSSType' 128
__repacd_update_vap_param "$name" 'wps_state' 1
__repacd_update_vap_param "$name" 'wps_pbc_skip_connected_sta' 1
# For initial onboarding, 2.4 GHz is the selected bSTA radio
# (unless it is given a preference value of 0, in which case
# no radio is marked as selected and we let the preference values
# determine it entirely).
if whc_is_5g_vap "$name" || [ "$repacd_bsta_pref" -eq 0 ]; then
uci_set wireless $device repacd_map_bsta_selected '0'
else
uci_set wireless $device repacd_map_bsta_selected '1'
fi
fi
# If not acting as the controller, we will let the Multi-AP
# Configuration procedure create the BSSes. However, due to
# limitations in wsplcd, we have to create a BSS on each radio to
# ensure AP Auto-Config takes place. If this is removed, then repacd
# can be updated to only do this on the controller again.
if [ "$repacd_auto_create_vaps" -gt 0 ]; then
# Only create the fBSS on agents (to ensure wsplcd works) or on
# the controller if so configured.
if [ "$is_controller" -eq 0 ] || [ "$create_ctrl_fbss" -gt 0 ]; then
# Create the fBSS (which may also be a bBSS)
name=$(uci add wireless wifi-iface)
config_changed=1
__repacd_init_vap "$name" $device 'ap' "$fronthaul_ssid" \
$fronthaul_encryption "$fronthaul_key"
__repacd_update_vap_param "$name" 'map' 1
if [ "$shared_vaps" -gt 0 ]; then
# fBSS uses same VAP as bBSS
__repacd_update_vap_param "$name" 'MapBSSType' 96
__repacd_update_vap_param "$name" 'multi_cred' 0
else
# Distinct VAPs for backhaul and fronthaul
__repacd_update_vap_param "$name" 'MapBSSType' 32
__repacd_update_vap_param "$name" 'multi_cred' 1
fi
fi
# Now create the bBSS, but only on the controller if configured (and
# only if it is meant to be a unique BSS). The agent will have any
# bBSSes created via the AP Auto-Configuration process.
if [ "$is_controller" -gt 0 ] && [ "$create_ctrl_bbss" -gt 0 ] && \
[ "$shared_vaps" -eq 0 ]; then
name=$(uci add wireless wifi-iface)
config_changed=1
__repacd_init_vap "$name" $device 'ap' "$backhaul_ssid" \
$backhaul_encryption "$backhaul_key"
__repacd_update_vap_param "$name" 'map' 1
__repacd_update_vap_param "$name" 'MapBSSType' 64
# Need to force this disabled per the Multi-AP SIG spec
__repacd_update_vap_param "$name" 'wps_pbc' 0
fi
fi
done
uci_commit wireless
}
# Enumerate all of the devices and append them to the variable provided.
# input: $1 devices: variable to populate with the devices
__repacd_get_devices() {
local devices=$1
config_cb() {
local type="$1"
local section="$2"
case "$type" in
wifi-device)
config_get hwmode "$section" hwmode
config_get type "$section" type
if [ "$type" != 'mac80211' ] && [ "$hwmode" != '11ad' ];then
eval append $devices "$section"
fi
;;
esac
}
config_load wireless
}
# Enable all Wi-Fi devices
__repacd_enable_wifi() {
local DEVICES=
local device changed=0
__repacd_get_devices DEVICES
for device in $DEVICES; do
config_get_bool disabled $device disabled
[ -z "$disabled" ] && continue
[ "$disabled" -eq 0 ] && continue
uci_set wireless $device disabled '0'
changed=1
done
if [ "$changed" -gt 0 ]; then
uci_commit wireless
config_changed=1
fi
}
# Set the parameter in the wireless configuration section provided, recording
# if it actually needed to be changed.
# input: $1 iface_name: section name
# input: $2 param_name: the name of the parameter being set
# input: $3 param_val: the new value for the parameter
__repacd_update_vap_param() {
local iface_name=$1 param_name=$2 param_val=$3
local cur_val
config_get cur_val "$iface_name" "$param_name"
if [ -z "$cur_val" ] || [ ! "$cur_val" = "$param_val" ]; then
uci_set wireless "$iface_name" "$param_name" "$param_val"
config_changed=1
fi
}
# Determine the SSID to apply to a specific VAP based on the current
# configuration of the WPS Push Button Configuration enhancement.
# input: $1 name: section name
# input: $2 device: name of the radio
# input: $3 base_ssid: the SSID from which to derive other ones
__repacd_init_vap_set_ssid_and_pbc() {
local name=$1 device=$2 base_ssid=$3
local mode
local enable_wps_re_enhc global_suffix='' radio_suffix=''
local start_time duration
local auto_create_vaps
# Grab the overall enable first
config_get enable_wps_re_enhc qcawifi wps_pbc_extender_enhance '0'
# Now VAP specific parameters
config_get mode "$name" mode
config_get start_time "$name" wps_pbc_start_time
config_get duration "$name" wps_pbc_duration
config_get_bool repacd_security_unmanaged "$name" repacd_security_unmanaged '0'
config_get_bool auto_create_vaps "$device" repacd_auto_create_vaps '1'
if [ "$enable_wps_re_enhc" -gt 0 ]; then
# Only apply the SSID derivation rules on AP interfaces.
if __repacd_is_matching_mode 'ap' $mode; then
# Potentially two suffixes can be applied
# First is set at the overall AP level.
config_get global_suffix qcawifi wps_pbc_overwrite_ssid_suffix ''
# Second is set at the radio level
config_get radio_suffix "$device" wps_pbc_overwrite_ssid_band_suffix ''
fi
fi
if [ "$repacd_security_unmanaged" -eq 0 ] ; then
__repacd_update_vap_param "$name" 'ssid' "$base_ssid$global_suffix$radio_suffix"
fi
__repacd_update_vap_param "$name" 'wps_pbc' 1
__repacd_update_vap_param "$name" 'wps_pbc_enable' "$enable_wps_re_enhc"
if [ "$traffic_separation_enabled" -gt 0 ]; then
__repacd_update_vap_param "$name" 'wps_pbc_noclone' '1'
fi
# Without a custom config, set all interfaces to be enabled for 2 minutes.
if [ -z "$start_time" ]; then
__repacd_update_vap_param "$name" 'wps_pbc_start_time' 0
fi
if [ -z "$duration" ]; then
if [ "$traffic_separation_enabled" -gt 0 ] && [ "$auto_create_vaps" -eq 1 ]; then
__repacd_update_vap_param "$name" 'wps_pbc_duration' 60
else
__repacd_update_vap_param "$name" 'wps_pbc_duration' 120
fi
fi
}
# Set all of the configuration parameters for the given VAP.
# input: $1 name: section name
# input: $2 device: name of the radio
# input: $3 mode: whether to act as a STA or AP
# input: $4 ssid: the desired SSID for this VAP
# input: $5 encryption: the desired encryption mode for this VAP
# input: $6 key: the desired passphrase for this VAP
__repacd_init_vap() {
local name=$1 device=$2 mode=$3 ssid=$4 encryption=$5 key=$6
local cur_mode
config_get_bool repacd_security_unmanaged "$name" repacd_security_unmanaged '0'
__repacd_update_vap_param "$name" 'device' "$device"
__repacd_update_vap_param "$name" 'network' $managed_network
__repacd_init_vap_set_ssid_and_pbc "$name" "$device" "$ssid"
if [ "$repacd_security_unmanaged" -eq 0 ] ; then
__repacd_update_vap_param "$name" 'encryption' "$encryption"
__repacd_update_vap_param "$name" 'key' "$key"
fi
# Mode needs to be handled separately. If the device is already in one
# of the AP modes and the init is requesting an AP mode, we leave it as
# is. If it is already in the STA mode, we also leave it as is.
config_get cur_mode "$name" 'mode'
if ! __repacd_is_matching_mode "$mode" "$cur_mode"; then
uci_set wireless "$name" 'mode' "$mode"
config_changed=1
fi
}
# Initialise all the additional that we created to support multi ssid traffic
# separation.
# input: $1 name: section name
# input: $2 device: name of the radio
# input: $3 mode: whether to act as a STA or AP
# input: $4 hwmode: radio hardware mode
# input: $5 network: desired network for this VAP
# input: $6 ssid: the desired SSID for this VAP
# input: $7 encryption: the desired encryption mode for this VAP
# input: $8 key: the desired passphrase for this VAP
__repacd_init_additional_vap() {
local name=$1 device=$2 mode=$3 hwmode=$4 network=$5
local ssid=$6 encryption=$7 key=$8
local cur_mode repacd_security_unmanaged auto_create_vaps
local enable_wds enable_rrm enable_qwrap_ap enable_extap block_dfs
local rate_scaling_factor=0
local num_changes=0
local cur_key
__repacd_update_vap_param "$name" 'device' "$device"
__repacd_update_vap_param "$name" 'network' "$network"
config_get_bool repacd_security_unmanaged "$name" repacd_security_unmanaged '0'
if [ "$repacd_security_unmanaged" -eq 0 ] ; then
__repacd_update_vap_param "$name" 'ssid' "$ssid"
__repacd_update_vap_param "$name" 'encryption' "$encryption"
config_get cur_key "$name" 'key'
if [ ! "$cur_key" = "$key" ]; then
__repacd_update_vap_param "$name" 'key' "$key"
fi
fi
# using SON mode related settings to config backhaul VAPs.
config_get_bool auto_create_vaps "$device" repacd_auto_create_vaps '1'
if [ "$network" = "$network_backhaul" ] && [ "$auto_create_vaps" -eq 1 ]; then
__repacd_update_vap_param "$name" 'wps_pbc_noclone' '0'
__repacd_update_vap_param "$name" 'wps_pbc_enable' '1'
__repacd_update_vap_param "$name" 'wps_pbc' '1'
__repacd_update_vap_param "$name" 'wps_pbc_start_time' '61'
__repacd_update_vap_param "$name" 'wps_pbc_duration' '120'
__repacd_update_vap_param "$name" 'wds' '1'
__repacd_update_vap_param "$name" 'extap' '0'
if __repacd_is_matching_mode 'ap' "$mode"; then
__repacd_update_vap_param "$name" 'qwrap_ap' '0'
__repacd_update_vap_param "$name" 'rrm' '1'
__repacd_update_vap_param "$name" 'hidden' '0'
if __repacd_is_block_dfs; then
__repacd_update_vap_param "$name" 'blockdfschan' '1'
else
__repacd_update_vap_param "$name" 'blockdfschan' '0'
fi
fi
else
__repacd_echo "Auto create VAPs disabled"
fi
if [ "$network" = "$network_guest" ] && [ "$auto_create_vaps" -eq 1 ]; then
__repacd_update_vap_param "$name" 'rrm' '1'
fi
# This is mainly for wsplcd optimization: if wsplcd detects athnewind
# is set to 0, it will not restart VAP; otherwise it will bring down
# the VAP, set athnewind to 0 and bring the VAP back up
__repacd_update_vap_param "$name" 'athnewind' 0
# Mode needs to be handled separately. If the device is already in one
# of the AP modes and the init is requesting an AP mode, we leave it as
# is. If it is already in the STA mode, we also leave it as is.
config_get cur_mode "$name" 'mode'
if ! __repacd_is_matching_mode "$mode" "$cur_mode"; then
uci_set wireless "$name" 'mode' "$mode"
config_changed=1
fi
}
# Create the 4 VAPs needed (1 STA and 1 AP for each radio), with them all
# initially disabled. Three radio platforms are not currently handled.
#
# Note that if the VAPs already exist, they will be reconfigured as
# appropriate. Existing VAP section names are given by ${device}_ap and
# ${device}_sta global variables.
#
# input: $1 ssid: the SSID to use on all VAPs
# input: $2 encryption: the encryption mode to use on all VAPs
# input: $3 key: the pre-shared key to use on all VAPs
__repacd_create_vaps() {
local ssid=$1
local encryption=$2
local key=$3
local DEVICES=
local backhaul_selected=0
__repacd_get_devices DEVICES
for device in $DEVICES; do
if whc_is_5g_radio $device && [ "$backhaul_selected" -eq 0 ]; then
# 5 GHz and we do not have a backhaul interface yet, so select
# this one as the backhaul interface.
#
# @todo Consider which 5 GHz radio should be used for backhaul if
# there is more than one.
backhaul_selected=1
fi
config_get_bool repacd_auto_create_vaps "$device" repacd_auto_create_vaps '1'
uci_set wireless $device disabled '0'
local name
name=$(eval "echo \$${device}_ap")
if [ -z "$name" ] && [ "$repacd_auto_create_vaps" -eq 1 ]; then
# No existing entry; create a new one.
name=$(uci add wireless wifi-iface)
config_changed=1
fi
if [ -n "$name" ]; then
# In case of auto config, this will be the fronthaul+backhaul AP VAP
# However in manual config, this can be the fronthaul VAP
# In manual cofig user sets this flag
# We use repacd_auto_create_vaps to distinguish the two cases
if [ "$repacd_auto_create_vaps" -eq 1 ]; then
uci_set wireless "$name" backhaul_ap '1'
fi
__repacd_init_vap "$name" $device 'ap' "$ssid" "$encryption" "$key"
fi
name=$(eval "echo \$${device}_sta")
if [ -z "$name" ] && [ "$repacd_auto_create_vaps" -eq 1 ] && \
[ "$traffic_separation_active" -eq 0 ]; then
# No existing entry; create a new one.
name=$(uci add wireless wifi-iface)
config_changed=1
fi
if [ -n "$name" ]; then
__repacd_init_vap "$name" $device 'sta' "$ssid" "$encryption" "$key"
fi
done
uci_commit wireless
}
# Create the additional vaps required for multi ssid traffic separation.
# 1 guest vap and 1 spcl vap on each radio. Currently no sta vaps created.
# spcl vap on 2.4GHz band will be disabled.
# Note that if the VAPs already exist, they will be reconfigured as
# appropriate. Existing VAP section names are given by
# ${device}_(backhaul/guest)_ap and
# ${device}_(backhaul/guest)_sta global variables.
#
# input: $1 network: network to which this vap belongs
# input: $2 ssid: the SSID to use on all VAPs for the provided network
# input: $3 encryption: the encryption mode to use on all VAPs
# input: $4 key: the pre-shared key to use on all VAPs
__repacd_create_additional_vaps() {
local ssid=$2
local encryption=$3
local key=$4
local network=$1
local DEVICES=
local no_vlan_val
local hwmode marker
if [ "$network" = "$network_backhaul" ]; then
marker="backhaul"
elif [ "$network" = "$network_guest" ]; then
marker="guest"
fi
__repacd_get_devices DEVICES
for device in $DEVICES; do
config_get_bool repacd_auto_create_vaps "$device" repacd_auto_create_vaps '1'
uci_set wireless $device disabled '0'
config_get hwmode $device hwmode
config_get no_vlan_val $device no_vlan '0'
if [ "$no_vlan_val" -eq 0 ]; then
uci_set wireless $device no_vlan '1'
fi
local name_managed
name_managed=$(eval "echo \$${device}_ap")
local name
name=$(eval "echo \$${device}_${marker}_ap")
if [ -z "$name" ] && [ "$repacd_auto_create_vaps" -eq 1 ]; then
# No existing entry; create a new ap.
name=$(uci add wireless wifi-iface)
config_changed=1
fi
if [ -n "$name" ]; then
if [ "$network" = "$network_backhaul" ]; then
uci_set wireless "$name" rept_spl '1'
if [ "$repacd_auto_create_vaps" -eq 1 ]; then
uci_set wireless "$name" backhaul_ap '1'
fi
if [ -n "$name_managed" ]; then
uci_set wireless "$name"_managed backhaul_ap '0'
fi
fi
__repacd_init_additional_vap "$name" $device 'ap' "$hwmode" "$network" \
"$ssid" "$encryption" "$key"
fi
if [ $create_sta -eq 1 ]; then
name=$(eval "echo \$${device}_${marker}_sta")
if [ -z "$name" ] && [ "$repacd_auto_create_vaps" -eq 1 ]; then
# No existing entry; create a new sta.
name=$(uci add wireless wifi-iface)
config_changed=1
fi
if [ -n "$name" ]; then
__repacd_init_additional_vap "$name" $device 'sta' "$hwmode" "$network" \
"$ssid" "$encryption" "$key"
fi
fi
done
uci_commit wireless
}
# Reconfigure the STA vaps of managed network.
# After restarting in Non CAP mode we reconfigure the sta vaps
# to be part of backhaul network. Network,ssid and credential
# are changed other configuration remains same.
#
# input: $1 config: section name
# input: $2 : current network
# input: $3 : backhaul network
# input: $4 ssid_val: backhaul ssid
# input: $5 enc_val: backhaul encryption
# input: $6 key_val: backhaul key
__repacd_reconfig_sta_vaps() {
local config=$1
local network
local ssid_val="$4"
local enc_val="$5"
local key_val="$6"
config_get network "$config" network
if [ "$2" = "$network" ] || [ "$3" = "$network" ]; then
local mode device hwmode type_val disabled
config_get mode "$config" mode
config_get device "$config" device
config_get hwmode "$device" hwmode
config_get type_val "$device" type
config_get disabled "$config" disabled 0
if [ "$hwmode" = '11ad' ] && [ "$type_val" = 'mac80211' ] ;then
return
fi
if [ "$mode" = "sta" ]; then
uci_set wireless "$config" rept_spl '1'
__repacd_init_additional_vap "$config" $device 'sta' "$hwmode" "$3" \
"$ssid_val" "$enc_val" "$key_val"
fi
fi
}
# Determine if the mode on the interface is a match.
# This does fuzzy matching in that multiple actual modes are said to match
# a given general mode.
#
# input: $1 general_mode: one of 'sta' or 'ap'
# input: $2 cur_mode: the currently configured mode
# return: 0 on a match; otherwise non-zero
__repacd_is_matching_mode() {
local general_mode=$1
local cur_mode=$2
if [ "$general_mode" = 'sta' ]; then
if [ "$cur_mode" = 'sta' ]; then
return 0
else
return 1
fi
else
if [ "$cur_mode" = 'ap' ] || [ "$cur_mode" = 'wrap' ]; then
return 0
else
return 1
fi
fi
}
# Detect which VAPs are already configured and their corresponding SSID and
# passphrase.
#
# input: $1 config: section name
# input: $2 network: network for which to update VAPs
#
# Updates $resolved_ssid, $resolved_enc, and $resolved_key as appropriate.
__repacd_resolve_vaps() {
local config="$1"
local network
config_get network "$config" network
if [ "$2" = "$network" ]; then
local device mode ssid_val encryption_val key_val
config_get device "$config" device
config_get mode "$config" mode
config_get ssid_val "$config" ssid
config_get encryption_val "$config" encryption
config_get key_val "$config" key
config_get disabled "$config" disabled 0
config_get_bool repacd_security_unmanaged "$config" repacd_security_unmanaged '0'
config_get hwmode "$device" hwmode
config_get type "$device" type
if [ "$hwmode" = '11ad' ] && [ "$type" = 'mac80211' ] ;then
return
fi
local default_ap
default_ap=$(eval "echo \$${device}_ap")
# Remember the section name for this radio in this mode.
if __repacd_is_matching_mode 'ap' "$mode"; then
if [ -z "$default_ap" ]; then
eval "${device}_ap=$config"
fi
elif [ "$mode" = "sta" ]; then
eval "${device}_sta=$config"
fi
if [ "$repacd_security_unmanaged" -eq 1 ] ; then
return
fi
# Since there is really no way to know which SSID, encryption mode, or
# passphrase to use, we will only store the first one unless we come
# across an enabled STA interface in which case we will prefer that.
# The reason for this is because if WPS is used without wsplcd, only
# the STA interface will have the correct SSID and passphrase once the
# process completes. When switching from pure client mode to RE mode,
# we want to propagate those values to the AP interfaces and the other
# STA interface.
if [ -n "$ssid_val" ] && [ -z "$resolved_ssid" ] || [ "$mode" = "sta" ]; then
if [ "$disabled" -eq 0 ]; then
resolved_ssid="$ssid_val"
fi
fi
if [ -n "$encryption_val" ] && [ -z "$resolved_enc" ] || [ "$mode" = "sta" ]; then
if [ "$disabled" -eq 0 ]; then
resolved_enc="$encryption_val"
fi
fi
if [ -n "$key_val" ] && [ -z "$resolved_key" ] || [ "$mode" = "sta" ]; then
if [ "$disabled" -eq 0 ]; then
resolved_key="$key_val"
fi
fi
fi
}
# Detect which additional VAPs are already configured.
#
# input: $1 config: section name
# input: $2 network: network for which to update VAPs
__repacd_resolve_additional_vaps() {
local config="$1"
local network marker
config_get network "$config" network
if [ "$2" = "$network" ]; then
local device mode hwmode type_val encryption_val key_val
if [ "$network" = "$network_backhaul" ]; then
marker="backhaul"
elif [ "$network" = "$network_guest" ]; then
marker="guest"
fi
config_get device "$config" device
config_get mode "$config" mode
config_get ssid_val "$config" ssid
config_get encryption_val "$config" encryption
config_get key_val "$config" key
config_get disabled "$config" disabled 0
config_get hwmode "$device" hwmode
config_get type_val "$device" type
if [ "$hwmode" = '11ad' ] && [ "$type_val" = 'mac80211' ] ;then
return
fi
# Remember the section name for this radio in this mode.
if __repacd_is_matching_mode 'ap' "$mode"; then
eval "${device}_${marker}_ap=$config"
elif [ "$mode" = "sta" ]; then
eval "${device}_${marker}_sta=$config"
fi
if [ -n "$ssid_val" ] && [ "$disabled" -eq 0 ]; then
if [ "$network" = "$network_backhaul" ]; then
if [ "$backhaul_ssid" = "$def_backhaul_ssid" ] || [ "$mode" = "sta" ]; then
backhaul_ssid="$ssid_val"
fi
elif [ "$network" = "$network_guest" ]; then
if [ "$guest_ssid" = "$def_guest_ssid" ]; then
guest_ssid="$ssid_val"
fi
fi
fi
if [ -n "$encryption_val" ] && [ "$disabled" -eq 0 ]; then
if [ "$network" = "$network_backhaul" ]; then
if [ "$backhaul_enc" = "$def_backhaul_enc" ] || [ "$mode" = "sta" ]; then
backhaul_enc="$encryption_val"
fi
elif [ "$network" = "$network_guest" ]; then
if [ "$guest_enc" = "$def_guest_enc" ]; then
guest_enc="$encryption_val"
fi
fi
fi
if [ -n "$key_val" ] && [ "$disabled" -eq 0 ]; then
if [ "$network" = "$network_backhaul" ]; then
if [ "$backhaul_key" = "$def_backhaul_key" ] || [ "$mode" = "sta" ]; then
backhaul_key="$key_val"
fi
elif [ "$network" = "$network_guest" ]; then
if [ "$guest_key" = "$def_guest_key" ]; then
guest_key="$key_val"
fi
fi
fi
fi
}
# Configure the additional VAPs needed to be consistent with the configuration that
# would be produced if starting from a default configuration. If any VAPs
# need to be created, use the SSID with suitable suffix, encryption mode, and passphrase
# from the managed network vaps
__repacd_reset_additional_config() {
config_load wireless
config_foreach __repacd_resolve_additional_vaps wifi-iface $network_guest
config_foreach __repacd_resolve_additional_vaps wifi-iface $network_backhaul
__repacd_create_additional_vaps $network_backhaul "$backhaul_ssid" "$backhaul_enc" \
"$backhaul_key"
__repacd_create_additional_vaps $network_guest "$guest_ssid" "$guest_enc" \
"$guest_key"
}
# Configure the 4 VAPs needed to be consistent with the configuration that
# would be produced if starting from a default configuration. If any VAPs
# need to be created, carry over the SSID, encryption mode, and passphrase
# from one of the existing ones.
__repacd_reset_existing_config() {
config_load wireless
config_foreach __repacd_resolve_vaps wifi-iface $managed_network
__repacd_create_vaps "$resolved_ssid" "$resolved_enc" "$resolved_key"
}
# Set all VAPs for the given network and mode to disabled or enabled (per
# the parameters).
#
# input: $1 config: section name
# input: $2 network: network for which to update VAPs
# input: $3 mode: sta or ap
# input: $4 disable_24g: 1 - disable, 0 - enable
# input: $5 disable_5g: 1 - disable, 0 - enable
# input-output: $6 change counter
__repacd_disable_vap() {
local config="$1"
local disable_24g="$4"
local disable_5g="$5"
local mode network disabled
local changed="$6"
config_get device "$config" device
config_get hwmode "$device" hwmode
config_get type "$device" type
if [ "$hwmode" = '11ad' ] && [ "$type" = 'mac80211' ] ;then
return
fi
config_get mode "$config" mode
config_get network "$config" network
config_get disabled "$config" disabled 0
if [ "$2" = "$network" ] && __repacd_is_matching_mode "$3" "$mode"; then
local desired_val
if whc_is_5g_vap "$config"; then
desired_val=$disable_5g
else
desired_val=$disable_24g
fi
if [ ! "$desired_val" = "$disabled" ]; then
uci_set wireless "$config" disabled "$desired_val"
changed=$((changed + 1))
eval "$6='$changed'"
__repacd_echo "Set VAP $config to Disabled=$desired_val"
fi
fi
}
# Determine the radio on which the bSTA should be allocated.
#
# If a radio is marked as selected (using the repacd_map_bsta_selected config
# option), it will be used. If instead none is marked, the radio with the
# highest repacd_map_bsta_pref value will be used.
#
# input: $1 config: section name
# output: $2 selected_radio: the radio that is marked as selected
# output: $3 preferred_radio: the radio with the highest preference
__repacd_resolve_bsta_radio() {
local config="$1"
local bsta_selected='' bsta_preference=''
config_get bsta_selected "$config" repacd_map_bsta_selected 0
config_get bsta_preference "$config" repacd_map_bsta_preference
if [ "$bsta_selected" -gt 0 ]; then
eval "$2=$config"
fi
# Radios with no preference set are ignored. This is meant to indicate
# the OEM never wants to use that radio.
if [ -n "$bsta_preference" ]; then
if [ "$bsta_preference" -gt "$map_bsta_max_preference" ]; then
eval "$3=$config"
map_bsta_max_preference="$bsta_preference"
fi
fi
}
# Update the radio on which the bSTA VAP is allocated based on the setting
# at the radio level.
#
# input: $1 config: section name
# input: $2 selected_radio: name of the radio on which to run the bSTA
# input: $3 network: network for which to update VAPs
# input-output: $4 change counter
__repacd_update_map_bsta_radio() {
local config="$1"
local selected_radio="$2"
local changed="$4"
local device hwmode type
config_get device "$config" device
config_get hwmode "$device" hwmode
config_get type "$device" type
if [ "$hwmode" = '11ad' ] && [ "$type" = 'mac80211' ] ;then
return
fi
local mode network disabled bssid
config_get mode "$config" mode
config_get network "$config" network
config_get disabled "$config" disabled 0
config_get bssid "$config" bssid
if [ "$3" = "$network" ] && __repacd_is_matching_mode "sta" "$mode"; then
if [ ! "$device" = "$selected_radio" ]; then
uci_set wireless "$config" device "$selected_radio"
changed=$((changed + 1))
eval "$4='$changed'"
__repacd_echo "Set VAP $config to device=$selected_radio"
if [ -n "$bssid" ]; then
uci delete "wireless.${config}.bssid"
__repacd_echo "Removed BSSID from VAP $config due to radio change"
fi
fi
if [ "$disabled" -eq 1 ]; then
uci_set wireless "$config" disabled 0
changed=$((changed + 1))
eval "$4='$changed'"
__repacd_echo "Set VAP $config to Disabled=0"
fi
fi
}
# Delete the bssid entry from the given STA interface.
#
# input: $1 config: section name
# input: $2 network: network being managed
# output: $3 config_changed: number of configurations changed
__repacd_delete_bssid_entry() {
local config="$1"
local network_to_match="$2"
local changed="$3"
local device hwmode network mode bssid
config_get device "$config" device
config_get hwmode "$device" hwmode
config_get network "$config" network
config_get type "$device" type
if [ "$hwmode" = '11ad' ] && [ "$type" = 'mac80211' ] \
|| [ "$network" != "$network_to_match" ]; then
return
fi
config_get mode "$config" mode
if __repacd_is_matching_mode 'sta' "$mode"; then
config_get bssid "$config" bssid ''
if [ -n "$bssid" ]; then
__repacd_echo "Deleting BSSID $bssid"
uci delete "wireless.${config}.bssid"
changed=$((changed + 1))
eval "$3='$changed'"
fi
fi
}
# Change the wsplcd running mode based on the value provided.
#
# input: $1 new_mode: value to set wsplcd run mode to
# input: $2 new_deep_clone: whether to enable deep cloning (which copies the
# channel and locks the association to the CAP)
# input: $3 new_deep_clone_no_bssid: deep cloning without BSSID cloning
# input: $4 config_sta: whether to use the extension to configure a STA
# interface during cloning
# input: $5 map_enable: whether to operate in Multi-AP SIG mode
# input-output: $6 changed: count of the changes
__repacd_configure_wsplcd() {
local new_mode=$1
local new_deep_clone=$2
local new_deep_clone_no_bssid=$3
local new_config_sta=$4
local new_map_enable=$5
local changed="$6"
local mode deep_clone deep_clone_no_bssid manage_vapind enabled
local map_bss_conf
if [ -f $WSPLCD_INIT ]; then
config_load wsplcd
config_get mode config 'RunMode'
config_get deep_clone config 'DeepClone'
config_get deep_clone_no_bssid config 'DeepCloneNoBSSID'
config_get config_sta config 'ConfigSta'
config_get map_enable config 'MapEnable'
config_get map_bss_conf config 'MapGenericPolicyFile'
config_get manage_vapind config 'ManageVAPInd'
config_get_bool enabled config 'HyFiSecurity' 0
if [ ! "$mode" = "$new_mode" ]; then
uci_set wsplcd config 'RunMode' "$new_mode"
changed=$((changed + 1))
eval "$6='$changed'"
uci_commit wsplcd
__repacd_echo "Set wsplcd to $new_mode mode"
wsplcd_restart=1
fi
if [ ! "$deep_clone" = "$new_deep_clone" ]; then
uci_set wsplcd config 'DeepClone' "$new_deep_clone"
changed=$((changed + 1))
eval "$6='$changed'"
uci_commit wsplcd
__repacd_echo "Set wsplcd DeepClone=$new_deep_clone"
wsplcd_restart=1
fi
if [ ! "$deep_clone_no_bssid" = "$new_deep_clone_no_bssid" ]; then
uci_set wsplcd config 'DeepCloneNoBSSID' "$new_deep_clone_no_bssid"
changed=$((changed + 1))
eval "$6='$changed'"
uci_commit wsplcd
__repacd_echo "Set wsplcd DeepCloneNoBSSID=$new_deep_clone_no_bssid"
wsplcd_restart=1
fi
if [ ! "$config_sta" = "$new_config_sta" ]; then
uci_set wsplcd config 'ConfigSta' "$new_config_sta"
changed=$((changed + 1))
eval "$6='$changed'"
uci_commit wsplcd
__repacd_echo "Set wsplcd ConfigSta=$new_config_sta"
wsplcd_restart=1
fi
if [ ! "$map_enable" = "$new_map_enable" ]; then
uci_set wsplcd config 'MapEnable' "$new_map_enable"
changed=$((changed + 1))
eval "$6='$changed'"
uci_commit wsplcd
__repacd_echo "Set wsplcd MapEnable=$new_map_enable"
wsplcd_restart=1
fi
if [ "$new_map_enable" -gt 0 ] && \
[ ! "$map_bss_conf" = "$WSPLCD_MAP_BSS_POLICY_PATH" ]; then
uci_set wsplcd config 'MapGenericPolicyFile' "$WSPLCD_MAP_BSS_POLICY_PATH"
changed=$((changed + 1))
eval "$6='$changed'"
uci_commit wsplcd
__repacd_echo "Set wsplcd MapGenericPolicyFile=$WSPLCD_MAP_BSS_POLICY_PATH"
wsplcd_restart=1
fi
if [ ! "$manage_vapind" = "0" ]; then
uci_set wsplcd config 'ManageVAPInd' "0"
changed=$((changed + 1))
eval "$6='$changed'"
uci_commit wsplcd
__repacd_echo "Set wsplcd ManageVAPInd=0"
wsplcd_restart=1
fi
if [ ! "$enabled" -eq "$wsplcd_enabled" ]; then
uci_set wsplcd config 'HyFiSecurity' $wsplcd_enabled
changed=$((changed + 1))
eval "$6='$changed'"
uci_commit wsplcd
__repacd_echo "Set wsplcd HyFiSecurity=$wsplcd_enabled"
if [ "$wsplcd_enabled" -gt 0 ]; then
__repacd_echo "Enabled security and configuration"
wsplcd_start=1
else
__repacd_echo "Disabled security and configuration"
wsplcd_stop=1
fi
fi
fi
}
# Change whether mcsd is enabled and running or not
#
# input: $1 manage_mcsd: whether repacd is to manage the state of mcsd
# input: $2 enable_son: whether SON mode is enabled or not (where this could
# include MAP)
__repacd_config_mcsd() {
local manage_mcsd=$1
local enable_son=$2
if [ "$manage_mcsd" -gt 0 ] && [ -f "$MCSD_INIT" ]; then
if [ "$enable_son" -gt 0 ]; then
uci_set mcsd config 'Enable' 0
uci_commit mcsd
# Stop mcsd and keep attempting to stop it in case it
# is being restarted by a hotplug event.
while pgrep mcsd;
do
/etc/init.d/mcsd stop
sleep 2
done
else # switching to non-SON mode, so enable mcsd
uci_set mcsd config 'Enable' 1
uci_commit mcsd
/etc/init.d/mcsd start
fi
fi
}
# Change the hyd and/or lbd configuration based on the parameters provided
# and the allowed feature settings.
#
# input: $1 enable_steering: 1 - AP interfaces support steering;
# 0 - they do not
# input: $2 disable_ap_steering: 1 - disable AP steering feature
# input: $3 enable_son: 1 - multi-AP SON mode should be enabled (so
# long as it is not prohibited by config);
# 0 - multi-AP SON mode should not be enabled
# input: $4 son_mode: one of HYROUTER or HYCLIENT; only relevant if enable_son
# is 1 and SON mode is not prohibited by the config
# input-output: $5 changed: count of the changes
__repacd_configure_son() {
local enable_steering=$1
local disable_ap_steering=$2
local enable_son=$3
local son_mode="$4"
local changed="$5"
local enable_steering_mask enable_son_mask manage_mcsd
config_load repacd
config_get_bool enable_steering_mask repacd 'EnableSteering' 1
config_get_bool enable_son_mask repacd 'EnableSON' 1
config_get_bool manage_mcsd repacd 'ManageMCSD' 1
# If the config does not permit steering or multi AP logic, force it
# off.
if [ "$enable_steering_mask" -eq 0 ]; then
enable_steering=0
fi
if [ "$enable_son_mask" -eq 0 ]; then
enable_son=0
fi
# If the package is not even installed, then we will fall back to
# the uncoordinated steering mode (if enabled).
if [ -f $HYD_INIT ]; then
local cur_mode hyd_enabled
config_load hyd
config_get cur_mode config 'Mode'
config_get hyd_enabled config 'Enable'
config_get disable_steering config 'DisableSteering'
if [ ! "$cur_mode" = "$son_mode" ]; then
uci_set hyd config 'Mode' "$son_mode"
changed=$((changed + 1))
eval "$5='$changed'"
uci_commit hyd
__repacd_echo "Set hyd Mode=$son_mode"
fi
if [ ! "$disable_steering" = "$disable_ap_steering" ]; then
uci_set hyd config 'DisableSteering' "$disable_ap_steering"
changed=$((changed + 1))
eval "$5='$changed'"
uci_commit hyd
__repacd_echo "Set hyd DisableSteering=$disable_ap_steering"
fi
if [ ! "$hyd_enabled" = "$enable_son" ]; then
uci_set hyd config 'Enable' "$enable_son"
changed=$((changed + 1))
eval "$5='$changed'"
uci_commit hyd
/etc/init.d/qrfs disable
/etc/init.d/qrfs stop
__repacd_config_mcsd "$manage_mcsd" "$enable_son"
# hyd should be started/stopped based on the hotplug hooks
# it has installed.
if [ "$enable_son" -gt 0 ]; then
__repacd_echo "Enabled Wi-Fi SON mode"
hyd_start=1
else
__repacd_echo "Disabled Wi-Fi SON mode"
hyd_stop=1
fi
fi
if [ "$enable_son" -gt 0 ]; then
enable_steering=0
fi
fi
if [ -f $LBD_INIT ]; then
local lbd_enabled
config_load lbd
config_get lbd_enabled config 'Enable'
if [ ! "$lbd_enabled" = "$enable_steering" ]; then
uci_set lbd config 'Enable' "$enable_steering"
changed=$((changed + 1))
eval "$5='$changed'"
uci_commit lbd
# Start/stop is handled when Wi-Fi interfaces are reconfigured.
if [ "$enable_steering" -gt 0 ]; then
__repacd_echo "Enabled Wi-Fi steering"
else
__repacd_echo "Disabled Wi-Fi steering"
fi
fi
fi
}
# Change the configuration on the wifi-device object to match what is desired
# (either QWrap enabled or disabled based on the second argument).
#
# input: $1 config: section to update
# input: $2 1 - enable, 0 - disable
# input-output: $3 change counter
__repacd_config_qwrap_device() {
local config="$1"
local mode network
local changed="$3"
# @todo This will need to be updated for 3 radio configurations. The
# qwrap_enable should be set for the radio with the backhaul and
# qwrap_dbdc_enable should be set for the radios with only an AP
# interface.
config_get hwmode "$config" hwmode
config_get type "$config" type
if [ "$hwmode" = '11ad' ] && [ "$type" = 'mac80211' ]; then
return
fi
if whc_is_5g_radio "$1"; then
local qwrap_enable
config_get qwrap_enable "$config" qwrap_enable
if [ ! "$2" = "$qwrap_enable" ]; then
uci_set wireless "$config" qwrap_enable "$2"
changed=$((changed + 1))
eval "$3='$changed'"
__repacd_echo "Set radio $config to QWrap Enabled=$2"
fi
else # must be 2.4 GHz
local qwrap_dbdc_enable
config_get qwrap_dbdc_enable "$config" qwrap_dbdc_enable
if [ ! "$2" = "$qwrap_dbdc_enable" ]; then
uci_set wireless "$config" qwrap_dbdc_enable "$2"
changed=$((changed + 1))
eval "$3='$changed'"
__repacd_echo "Set radio $config to QWrap DBDC Enabled=$2"
fi
fi
}
# Set the option that indicates whether the DBDC repeater feature should be
# enabled or not.
#
# input: $1 config: section to update
# input: $2 1 - enable, 0 - disable
# input-output: $3 change counter
__repacd_config_dbdc_device() {
local config="$1"
local changed="$3"
local dbdc_enable
config_get hwmode "$config" hwmode
config_get type "$config" type
if [ "$hwmode" = '11ad' ] && [ "$type" = 'mac80211' ]; then
return
fi
config_get dbdc_enable "$config" dbdc_enable 1
if [ ! "$2" = "$dbdc_enable" ]; then
uci_set wireless "$config" dbdc_enable "$2"
changed=$((changed + 1))
eval "$3='$changed'"
__repacd_echo "Set radio $config to DBDC Enabled=$2"
fi
}
# Enable or disable the WPS Push Button Configuration Range Extender
# enhancement based on the current configuration.
# input: $1 force_cap_mode - whether to act as gateway connected even without
# a WAN interface
# input-output: $2 change count
__repacd_config_wps_pbc_enhc() {
local force_gwcon_mode=$1
local changed="$2"
local cur_enable
if __repacd_gw_mode || [ "$force_gwcon_mode" -gt 0 ] || \
__repacd_is_wds_mode || __repacd_is_son_mode; then
if [ "$traffic_separation_enabled" -gt 0 ]; then
enable_wps_pbc_enhc=1
else
enable_wps_pbc_enhc=0
fi
else
# Must be QWRAP or ExtAP mode, where we want distinct SSIDs for the
# RE interfaces.
enable_wps_pbc_enhc=1
fi
config_load wireless
config_get cur_enable qcawifi wps_pbc_extender_enhance '0'
if [ ! "$enable_wps_pbc_enhc" = "$cur_enable" ]; then
# Create the section if it does not exist.
uci set wireless.qcawifi=qcawifi
uci_set wireless qcawifi wps_pbc_extender_enhance $enable_wps_pbc_enhc
uci_set wireless qcawifi wps_pbc_overwrite_ap_settings_all 1
__repacd_echo "Set qcawifi.wps_pbc_extender_enhance=$enable_wps_pbc_enhc"
__repacd_echo "Set qcawifi.wps_pbc_overwrite_ap_settings_all=1"
changed=$((changed + 1))
eval "$2='$changed'"
fi
}
# Change the configuration on the wifi-iface object to match what is desired.
# The values provided are determined by the caller based on the desired
# mode of operation (eg. QWrap/ExtAP or not).
#
# input: $1 config: section to update
# input: $2 network: only update if network matches this value
# input: $3 enable_wds: 1 - enable, 0 - disable
# input: $4 qwrap_ap: 1 - enable, 0 - disable
# input: $5 extap: 1 - enable, 0 disable
# input: $6 block_dfs_chan: 1 - block DFS channels, 0 - do not block them
# input: $7 enable_rrm: 1 - enable, 0 disable
# input: $8 re_scalingfactor: 0 - ignore, 1 to 100 valid for sta
# input: $9 default_root_dist: 0 - ignore, 255 - invalid root distance
# input: $10 cap_snr: 0 - disabled, 1-100 valid
# input-output: $11 change counter
__repacd_config_iface() {
local config="$1"
local device mode network enable_wds qwrap_ap extap block_dfs enable_rrm
local re_scalingfactor root_distance cap_snr wps_pbc_skip_connected_sta
local bssid="00:00:00:00:00:00"
local num_changes=0
local changed="${11}"
config_get device "$config" device
config_get hwmode "$device" hwmode
config_get type "$device" type
if [ "$hwmode" = '11ad' ] && [ "$type" = 'mac80211' ] ;then
return
fi
config_get mode "$config" mode
config_get network "$config" network
config_get enable_wds "$config" wds '0'
config_get qwrap_ap "$config" qwrap_ap '0'
config_get extap "$config" extap '0'
config_get block_dfs "$config" blockdfschan '0'
config_get enable_rrm "$config" rrm '0'
config_get re_scalingfactor "$config" re_scalingfactor '0'
config_get root_distance "$config" root_distance '0'
config_get cap_snr "$config" caprssi '0'
config_get wps_pbc_skip_connected_sta "$config" wps_pbc_skip_connected_sta '0'
if [ "$2" = "$network" ]; then
if [ ! "$3" = "$enable_wds" ]; then
uci_set wireless "$config" wds "$3"
num_changes=$((num_changes + 1))
__repacd_echo "Set iface $config to WDS=$3"
fi
# When operating in WDS/SON mode (since we do not use the repeater
# enhancement), set the option to skip activating WPS PBC on a
# connected STA interface. This allows the WPS button to be pressed on
# an RE without causing it to disconnect from its upstream device.
if [ "$mode" = 'sta' ]; then
if [ ! "$3" = "$wps_pbc_skip_connected_sta" ]; then
uci_set wireless "$config" wps_pbc_skip_connected_sta "$3"
num_changes=$((num_changes + 1))
__repacd_echo "Set iface $config to wps_pbc_skip_connected_sta=$3"
fi
fi
# These should only be set on AP interfaces.
if __repacd_is_matching_mode 'ap' "$mode"; then
if [ ! "$4" = "$qwrap_ap" ]; then
uci_set wireless "$config" qwrap_ap "$4"
num_changes=$((num_changes + 1))
__repacd_echo "Set iface $config to QWrapAP=$4"
fi
# @todo If there are multiple 5 GHz radios, will need to figure
# out which can act as the backhaul.
# Set the interface into wrap or vanilla AP mode as appropriate
if whc_is_5g_radio $device; then
if [ "$4" -gt 0 ]; then
if [ ! "$mode" = 'wrap' ]; then
uci_set wireless "$config" mode 'wrap'
num_changes=$((num_changes + 1))
__repacd_echo "Set iface $config mode to wrap"
fi
else # WDS or ExtAP mode
if [ ! "$mode" = 'ap' ]; then
uci_set wireless "$config" mode 'ap'
num_changes=$((num_changes + 1))
__repacd_echo "Set iface $config mode to ap"
fi
fi
fi
if [ ! "$6" = "$block_dfs" ]; then
uci_set wireless "$config" blockdfschan "$6"
num_changes=$((num_changes + 1))
__repacd_echo "Set iface $config to BlockDFSChan=$6"
fi
if [ ! "$7" = "$enable_rrm" ]; then
uci_set wireless "$config" rrm "$7"
num_changes=$((num_changes + 1))
__repacd_echo "Set iface $config to RRM=$7"
fi
fi
if [ ! "$5" = "$extap" ]; then
uci_set wireless "$config" extap "$5"
num_changes=$((num_changes + 1))
__repacd_echo "Set iface $config to ExtAP=$5"
fi
if [ "$daisy_chain" -gt 0 ] && \
__repacd_is_matching_mode 'sta' "$mode"; then
# Need to resolve 2.4G BSSID, So until then configure invalid BSSID
# to avoid association on 2.4G interface.
# Check if bssid updated by wifimon/daisychain, needs restart
if [ "$bssid_resolve_state" = "resolving" ] \
&& ! whc_is_5g_radio $device; then
uci_set wireless "$config" bssid "$bssid"
num_changes=$((num_changes + 1))
__repacd_echo "Set iface $config to BSSID=$bssid"
fi
if [ ! "$8" = "$re_scalingfactor" ]; then
uci_set wireless "$config" re_scalingfactor "$8"
num_changes=$((num_changes + 1))
__repacd_echo "Set iface $config to RE_ScalingFactor=$8"
fi
if [ ! "${10}" = "$cap_snr" ]; then
uci_set wireless "$config" caprssi "${10}"
num_changes=$((num_changes + 1))
__repacd_echo "Set iface $config to caprssi=${10}"
fi
fi
if [ ! "$9" = "$root_distance" ]; then
uci_set wireless "$config" root_distance "$9"
num_changes=$((num_changes + 1))
__repacd_echo "Set iface $config to RootDistance=$9"
fi
if [ "$num_changes" -gt 0 ]; then
changed=$((changed + 1))
eval "${11}='$changed'"
fi
fi
}
# Switch the device into acting as the CAP (main gateway).
# Also update the range extension mode as necessary.
#
# input: $1 is_cap: whether the device should act as the central
# AP or a secondary gateway connected AP
__repacd_config_gwcon_ap_mode() {
local is_cap=$1
local wsplcd_mode son_mode
local rate_scaling_factor=0
local default_root_dist=0
# The WDS, VAP independent, and QWrap AP settings also need to be updated
# based on the range extension mode.
local enable_wds enable_rrm enable_qwrap_ap enable_extap
local block_dfs enable_multi_ap disable_steering=0 config_sta=1
local map_enable=0
__repacd_get_config_re_mode config_re_mode
__repacd_get_re_mode resolved_re_mode
if __repacd_is_auto_re_mode $config_re_mode || __repacd_is_wds_mode || \
__repacd_is_son_mode; then
if __repacd_is_auto_re_mode $config_re_mode || \
__repacd_is_son_mode; then
__repacd_echo "Using SON mode for GW Connected AP"
enable_multi_ap=1
else # Must be vanilla WDS
__repacd_echo "Using WDS mode for GW Connected AP"
enable_multi_ap=0
fi
enable_wds=1
enable_rrm=1
enable_qwrap_ap=0
enable_extap=0
# In WDS/SON modes, we let the OEM customize whether DFS channels
# should be permitted.
if __repacd_is_block_dfs; then
block_dfs=1
else
block_dfs=0
fi
wsplcd_enabled=1
else
__repacd_echo "Using Non-WDS mode for GW Connected AP"
enable_wds=0
enable_multi_ap=0
enable_rrm=0
enable_qwrap_ap=0
enable_extap=0
# In QWrap/ExtAP mode, DFS channels should always be disallowed (as it
# does not appear to suppor them currently). This may be able to
# relaxed in the future.
block_dfs=1
# Since QWrap/ExtAP mode on the CAP is for mimicking a non-QCA AP, do
# not run an IEEE P1905.1 registrar.
wsplcd_enabled=0
fi
config_load repacd
config_get bssid_resolve_state WiFiLink 'BSSIDResolveState' 'resolving'
# In GW-connected AP mode, only the AP interfaces are enabled.
local disable_24g_sta=1 disable_5g_sta=1 disable_24g_ap=0 disable_5g_ap=0
config_load wireless
config_foreach __repacd_disable_vap wifi-iface \
$managed_network 'sta' $disable_24g_sta $disable_5g_sta config_changed
config_foreach __repacd_disable_vap wifi-iface \
$managed_network 'ap' $disable_24g_ap $disable_5g_ap config_changed
# The QWrap parameters should always be set to 0 on the CAP.
config_foreach __repacd_config_qwrap_device wifi-device \
0 config_changed
# Similarly, the DBDC repeater feature should be disabled on the
# CAP.
config_foreach __repacd_config_dbdc_device wifi-device \
0 config_changed
# Now set up the interfaces in the right way.
config_foreach __repacd_config_iface wifi-iface \
$managed_network $enable_wds $enable_qwrap_ap $enable_extap \
$block_dfs $enable_rrm $rate_scaling_factor $default_root_dist $capsnr config_changed
if [ "$traffic_separation_active" -gt 0 ]; then
config_foreach __repacd_config_iface wifi-iface \
$network_backhaul $enable_wds $enable_qwrap_ap $enable_extap \
$block_dfs $enable_rrm $rate_scaling_factor $default_root_dist $capsnr config_changed
config_foreach __repacd_config_iface wifi-iface \
$network_guest $enable_wds $enable_qwrap_ap $enable_extap \
$block_dfs $enable_rrm $rate_scaling_factor $default_root_dist $capsnr config_changed
fi
uci_commit wireless
uci_set repacd repacd Role 'CAP'
uci_commit repacd
if [ "$is_cap" -gt 0 ]; then
wsplcd_mode='REGISTRAR'
son_mode='HYROUTER'
else
wsplcd_mode='ENROLLEE'
son_mode='HYCLIENT'
fi
# Deep cloning is not relevant in registrar mode, but we set it to 1
# anyways (since that is the default).
__repacd_configure_wsplcd $wsplcd_mode 1 0 $config_sta $map_enable \
config_changed
__repacd_configure_son $enable_wds $disable_steering $enable_multi_ap \
$son_mode config_changed
}
# Switch the device to act in one of the NonCAP configurations.
# input: $1 disable_ap - whether to disable the AP interfaces
# input: $2 deep_clone - whether to use deep cloning in wsplcd
# input: $3 deep_clone_no_bssid - whether to use deep cloning without BSSID cloning in wsplcd
__repacd_config_noncap_mode() {
local disable_ap=$1
local deep_clone=$2
local deep_clone_no_bssid=$3
# The WDS and QWrap AP settings also need to be updated based on the
# range extension mode.
local enable_wds enable_qwrap_ap enable_extap enable_dbdc_repeater
local block_dfs enable_rrm enable_multi_ap disable_steering=0 config_sta=1
local map_enable=0
local rate_scaling_factor=$RE_DEFAULT_RATE_ESTIMATE_SCALING_FACTOR
local default_root_dist=$RE_ROOT_AP_DISTANCE_INVALID
local disable_24g_sta=1 disable_5g_sta=0
local disable_24g_ap=$disable_ap disable_5g_ap=$disable_ap
if __repacd_is_wds_mode || __repacd_is_son_mode; then
if __repacd_is_wds_mode; then
__repacd_echo "Using WDS mode for NonCAP"
else # Must be SON mode
__repacd_echo "Using SON mode for NonCAP"
fi
enable_wds=1
enable_qwrap_ap=0
enable_extap=0
# Even if we are not operating in fully coordinated steering mode,
# we should enable RRM for use in the uncoordinated steering
# environment.
enable_rrm=1
# In WDS mode, we let the OEM customize whether DFS channels should
# be permitted.
if __repacd_is_block_dfs; then
block_dfs=1
else
block_dfs=0
fi
wsplcd_enabled=1
__repacd_get_rate_scaling_factor rate_scaling_factor
config_get capsnr WiFiLink 'PreferCAPSNRThreshold5G' '0'
else
enable_wds=0
# Until steering can be well supported on QWRAP/ExtAP, there is no real
# need to have RRM enabled.
enable_rrm=0
# wsplcd needs WDS in order to work (as it sends/receives using the
# bridge interface MAC address). Plus, it is not too likely that the
# main AP will be running an IEEE P1905.1 registrar.
wsplcd_enabled=0
if [ "$disable_ap" -eq 0 ]; then
if __repacd_is_qwrap_mode; then
__repacd_echo "Using QWrap mode for NonCAP"
enable_qwrap_ap=1
enable_extap=0
else
__repacd_echo "Using ExtAP mode for NonCAP"
enable_qwrap_ap=0
enable_extap=1
fi
# In QWrap/ExtAP mode, DFS channels should always be disallowed
# (as these modes may not support them properly).
block_dfs=1
else # client mode
if __repacd_is_qwrap_mode; then
__repacd_echo "Using QWrap mode for NonCAP"
enable_qwrap_ap=0
enable_extap=0
# @todo What mode should be used here? The STA interface is not
# even created if it is not in QWRAP or WDS. We could
# potentially consider standalone Proxy STA
# mode, but we need details on how to configure this.
else
__repacd_echo "Using ExtAP mode for NonCAP"
enable_qwrap_ap=0
enable_extap=1
fi
# We'll rely on the main AP to decide on DFS or not.
block_dfs=0
fi
fi
if __repacd_is_son_mode; then
disable_24g_sta=0
enable_dbdc_repeater=0
enable_multi_ap=1
else
enable_multi_ap=0
# Although currently in non-SON mode we do not enable both STA
# interfaces, just in case we do in the future, set this flag. It
# should make no difference if only one STA interface is active.
enable_dbdc_repeater=1
fi
config_load repacd
config_get bssid_resolve_state WiFiLink 'BSSIDResolveState' 'resolving'
config_load wireless
if [ "$traffic_separation_active" -gt 0 ]; then
config_foreach __repacd_disable_vap wifi-iface \
$network_backhaul 'sta' $disable_24g_sta $disable_5g_sta config_changed
else
config_foreach __repacd_disable_vap wifi-iface \
$managed_network 'sta' $disable_24g_sta $disable_5g_sta config_changed
fi
config_foreach __repacd_disable_vap wifi-iface \
$managed_network 'ap' "$disable_24g_ap" "$disable_5g_ap" config_changed
# First set the special options for QWRAP and DBDC repeaters.
config_foreach __repacd_config_qwrap_device \
wifi-device $enable_qwrap_ap config_changed
config_foreach __repacd_config_dbdc_device wifi-device \
$enable_dbdc_repeater config_changed
config_foreach __repacd_config_iface wifi-iface \
$managed_network $enable_wds $enable_qwrap_ap $enable_extap \
$block_dfs $enable_rrm $rate_scaling_factor $default_root_dist $capsnr config_changed
if [ "$traffic_separation_active" -gt 0 ]; then
config_foreach __repacd_config_iface wifi-iface \
$network_backhaul $enable_wds $enable_qwrap_ap $enable_extap \
$block_dfs $enable_rrm $rate_scaling_factor $default_root_dist $capsnr config_changed
config_foreach __repacd_config_iface wifi-iface \
$network_guest $enable_wds $enable_qwrap_ap $enable_extap \
$block_dfs $enable_rrm $rate_scaling_factor $default_root_dist $capsnr config_changed
fi
__repacd_config_independent_vaps
uci_commit wireless
uci_set repacd repacd Role 'NonCAP'
uci_commit repacd
__repacd_configure_wsplcd 'ENROLLEE' "$deep_clone" "$deep_clone_no_bssid" \
$config_sta $map_enable config_changed
__repacd_configure_son $enable_wds $disable_steering $enable_multi_ap \
'HYCLIENT' config_changed
}
# Switch the device into acting as a range extender.
# Also update the range extension mode as necessary.
__repacd_config_re_mode() {
local disable_ap=0 deep_clone=1 deep_clone_no_bssid=0
# We do deep cloning without BSSID for daisy chaining.
[ "$daisy_chain" -gt 0 ] && deep_clone_no_bssid=1
# TODO - check if this is needed for traffic separation (or maybe use
# ConfigSta = 0).
[ "$traffic_separation_enabled" -gt 0 ] && {
deep_clone=0
deep_clone_no_bssid=0
}
__repacd_config_noncap_mode $disable_ap $deep_clone $deep_clone_no_bssid
}
# Switch the device into acting as a pure client device (no AP interfaces
# enabled).
__repacd_config_client_mode() {
local disable_ap=1 deep_clone=0
__repacd_config_noncap_mode $disable_ap $deep_clone 0
}
# Change the configuration on the wifi-iface object to match what is desired.
# This function is for Multi-AP mode.
#
# input: $1 config: section to update
# input: $2 network: only update if network matches this value
# input: $3 block_dfs_chan: 1 - block DFS channels, 0 - do not block them
# input-output: $4 change counter
__repacd_config_iface_map() {
local enable_wds=1 qwrap_ap=0 extap=0 enable_rrm=1 re_scalingfactor=0
local default_root_dist=0 cap_snr=0
__repacd_config_iface "$1" "$2" $enable_wds $qwrap_ap $extap "$3" $enable_rrm \
$re_scalingfactor $default_root_dist $cap_snr "$4"
}
# Generate the Multi-AP BSS instantiation config file for wsplcd based on
# the selected template and SSID settings.
# input-output: $1 change counter
__repacd_generate_map_bss_conf() {
local changed="$1"
local template_filename
local template_path
local fronthaul_ssid fronthaul_key
local backhaul_ssid backhaul_key
config_load repacd
config_get template_filename MAPConfig BSSInstantiationTemplate
config_get fronthaul_ssid MAPConfig FronthaulSSID
config_get fronthaul_key MAPConfig FronthaulKey
config_get backhaul_ssid MAPConfig BackhaulSSID
config_get backhaul_key MAPConfig BackhaulKey
if [ -z "${template_filename}" ]; then
__repacd_echo "BSS instantiation template not specified"
return 1
fi
template_path="${WSPLCD_MAP_TEMPLATE_DIR}/${template_filename}"
if [ ! -r "${template_path}" ]; then
__repacd_echo "BSS instantiation template ${template_path} not readable"
return 1
fi
__repacd_echo "Using wsplcd BSS instantiation template: ${template_path}"
local tempfile
tempfile=$(mktemp)
cp "${template_path}" "${tempfile}"
# Some of these replacements may not be used, but this covers all of the
# cases of variables that need to be replaced.
#
# Note that in case the variable contains the sed delimeter, it needs to
# be escaped to avoid a sed error.
sed -i -e "s!__FH_SSID_REPLACE__!${fronthaul_ssid/!/\!}!g" \
-e "s!__FH_KEY_REPLACE__!${fronthaul_key/!/\!}!g" \
-e "s!__BH_SSID_REPLACE__!${backhaul_ssid/!/\!}!g" \
-e "s!__BH_KEY_REPLACE__!${backhaul_key/!/\!}!g" \
-e "s!__FHBH_SSID_REPLACE__!${fronthaul_ssid/!/\!}!g" \
-e "s!__FHBH_KEY_REPLACE__!${fronthaul_key/!/\!}!g" \
"${tempfile}"
if [ ! -r "${WSPLCD_MAP_BSS_POLICY_PATH}" ] || \
! cmp -s "${tempfile}" "${WSPLCD_MAP_BSS_POLICY_PATH}"; then
# New file differs from old. Move it into place and update
# the change count.
mv -f "${tempfile}" "${WSPLCD_MAP_BSS_POLICY_PATH}"
changed=$((changed + 1))
eval "$1='$changed'"
else
# No change, so just remove the temporary file
rm -f "${tempfile}"
fi
return 0
}
# Switch the device into acting as a gateway connected AP (no bSTA).
#
# Pre-condition: RE mode has already been checked to be SON
#
# input: $1 is_controller: whether the device should act as the controller
# or just a gateway connected AP
# input: $2 standalone_controller: if a controller, whether the device should
# act as a standalone controller
__repacd_config_gwcon_map_ap() {
local is_controller=$1
local wsplcd_mode son_mode
local rate_scaling_factor=0
local default_root_dist=0
# The WDS, VAP independent, and QWrap AP settings also need to be updated
# based on the range extension mode.
local enable_wds=1 enable_multi_ap=1 disable_steering=0
local deep_clone=0 deep_clone_no_bssid=0 config_sta=0 map_enable=1
local block_dfs
__repacd_echo "Using SON mode for GW Connected AP"
# In WDS/SON modes, we let the OEM customize whether DFS channels
# should be permitted.
if __repacd_is_block_dfs; then
block_dfs=1
else
block_dfs=0
fi
wsplcd_enabled=1
local disable_24g_sta disable_5g_sta disable_24g_ap disable_5g_ap
if [ "$is_controller" -gt 0 ] && [ "$standalone_controller" -gt 0 ]; then
__repacd_echo "Disabling all interfaces for standalone controller"
disable_24g_sta=1
disable_5g_sta=1
disable_24g_ap=1
disable_5g_ap=1
else
# In GW-connected AP mode, only the AP interfaces are enabled.
disable_24g_sta=1
disable_5g_sta=1
disable_24g_ap=0
disable_5g_ap=0
fi
config_load wireless
config_foreach __repacd_disable_vap wifi-iface \
$managed_network 'sta' $disable_24g_sta $disable_5g_sta config_changed
config_foreach __repacd_disable_vap wifi-iface \
$managed_network 'ap' $disable_24g_ap $disable_5g_ap config_changed
# Now set up the interfaces in the right way.
if [ "$standalone_controller" -eq 0 ]; then
config_foreach __repacd_config_iface_map wifi-iface \
$managed_network $block_dfs config_changed
fi
uci_commit wireless
uci_set repacd repacd Role 'CAP'
if [ "$is_controller" -gt 0 ]; then
uci_set hyd MultiAP EnableController 1
# Standalone controller does not act as an Agent
if [ "$standalone_controller" -gt 0 ]; then
uci_set hyd MultiAP EnableAgent 0
else
uci_set hyd MultiAP EnableAgent 1
fi
# Force the remote association tracking on for the controller, as the
# steering is centralized.
uci_set lbd StaDB TrackRemoteAssoc 1
else
uci_set hyd MultiAP EnableController 0
uci_set hyd MultiAP EnableAgent 1
# For an agent, use whatever the current remote association tracking
# setting is. There is still an advantage to tracking remote
# associations as it allows the bridging tables to be cleaned up
# properly when a Topology Notification is missed.
fi
# This generally should nto be needed when operating in gateway connected
# AP mode. Until there is a case where we need it, we'll leave it disabled.
uci_set repacd FrontHaulMgr ManageFrontAndBackHaulsIndependently 0
uci_commit repacd
uci_commit hyd
uci_commit lbd
if [ "$is_controller" -gt 0 ]; then
wsplcd_mode='REGISTRAR'
son_mode='HYROUTER'
if ! __repacd_generate_map_bss_conf config_changed; then
return 1
fi
else
wsplcd_mode='ENROLLEE'
son_mode='HYCLIENT'
fi
# No deep cloning with the MAP algorithms
__repacd_configure_wsplcd $wsplcd_mode $deep_clone $deep_clone_no_bssid \
$config_sta $map_enable config_changed
__repacd_configure_son $enable_wds $disable_steering $enable_multi_ap \
$son_mode config_changed
return 0
}
# Switch the device to act as a range extender.
__repacd_config_map_re() {
# The WDS and QWrap AP settings also need to be updated based on the
# range extension mode.
local enable_wds=1 block_dfs
local enable_multi_ap=1 disable_steering=0
local deep_clone=0 deep_clone_no_bssid=0 config_sta=0 map_enable=1
local disable_24g_ap=0 disable_5g_ap=0
# We let the OEM customize whether DFS channels should be permitted.
if __repacd_is_block_dfs; then
block_dfs=1
else
block_dfs=0
fi
# We let the daemon start wsplcd once it has a stable bSTA association.
wsplcd_enabled=0
wsplcd_stop=1
config_load wireless
# How the bSTA interface is managed is dependent on the selected and
# preference values.
local selected_radio='' preferred_radio=''
map_bsta_max_preference=0
config_foreach __repacd_resolve_bsta_radio wifi-device \
selected_radio preferred_radio
if [ -z "$selected_radio" ]; then
selected_radio="$preferred_radio"
fi
__repacd_echo "Using $selected_radio for bSTA"
config_foreach __repacd_update_map_bsta_radio wifi-iface \
$selected_radio $managed_network config_changed
config_foreach __repacd_disable_vap wifi-iface \
$managed_network 'ap' $disable_24g_ap $disable_5g_ap config_changed
config_foreach __repacd_config_iface_map wifi-iface \
$managed_network $block_dfs config_changed
uci_commit wireless
uci_set repacd repacd Role 'NonCAP'
uci_set repacd FrontHaulMgr ManageFrontAndBackHaulsIndependently 1
uci_commit repacd
uci_set hyd MultiAP EnableController 0
uci_set hyd MultiAP EnableAgent 1
uci_commit hyd
__repacd_configure_wsplcd 'ENROLLEE' $deep_clone $deep_clone_no_bssid \
$config_sta $map_enable config_changed
__repacd_configure_son $enable_wds $disable_steering $enable_multi_ap \
'HYCLIENT' config_changed
}
# Restart wsplcd and the Wi-Fi interfaces based on configuration changes.
__repacd_restart_dependencies() {
if [ "$wsplcd_stop" -gt 0 ]; then
$WSPLCD_INIT stop
fi
if [ "$hyd_stop" -gt 0 ]; then
$HYD_INIT stop
$HYFI_BRIDGING_INIT stop
fi
# When hyd is being started, start the bridging hooks prior to restarting
# the network to ensure any temporary loops are prevented.
if [ "$hyd_start" -gt 0 ]; then
$HYFI_BRIDGING_INIT start
fi
if [ "$config_changed" -gt 0 ]; then
__repacd_echo "Restarting network stack..."
whc_network_restart
else
__repacd_echo "No changes; not restarting network stack..."
fi
if [ "$wsplcd_start" -gt 0 ]; then
__repacd_echo "Starting wsplcd"
$WSPLCD_INIT start
elif [ "$wsplcd_restart" -gt 0 ]; then
__repacd_echo "Restarting wsplcd"
$WSPLCD_INIT restart
fi
if [ "$hyd_start" -gt 0 ]; then
__repacd_echo "Starting hyd"
$HYD_INIT start
fi
}
# Perform the startup actions when operating in the original Wi-Fi SON mode
# (no Multi-AP SIG support).
__start_son() {
local enabled map_enabled device_type
local mode activate_ts
local eth_mon_enabled
config_changed=0
net_config_changed=0
activate_ts=0
config_load 'repacd'
config_get_bool enabled repacd 'Enable' '0'
config_get traffic_separation_enabled repacd TrafficSeparationEnabled '0'
config_get traffic_separation_active repacd TrafficSeparationActive '0'
config_get daisy_chain WiFiLink DaisyChain '0'
config_get backhaul_ssid repacd BackhaulSSID $def_backhaul_ssid
config_get backhaul_enc repacd BackhaulEnc $def_backhaul_enc
config_get backhaul_key repacd BackhaulKey $def_backhaul_key
config_get network_guest repacd NetworkGuest 'guest'
config_get guest_ssid repacd GuestSSID $def_guest_ssid
config_get guest_enc repacd GuestEnc $def_guest_enc
config_get guest_key repacd GuestKey $def_guest_key
config_get guest_backhaul_iface repacd NetworkGuestBackhaulInterface 'both'
config_get eth_mon_enabled repacd 'EnableEthernetMonitoring' '0'
config_get manage_vap_ind WiFiLink 'ManageVAPInd' '0'
config_get Manage_front_and_back_hauls_ind 'FrontHaulMgr' 'ManageFrontAndBackHaulsIndependently' '0'
__repacd_get_config_re_mode config_re_mode
[ "$enabled" -gt 0 ] || {
return 1
}
__repacd_echo "starting WHC auto-configuration"
# For now, we can only manage a single network.
config_get managed_network repacd ManagedNetwork 'lan'
__repacd_echo "Managed network: $managed_network"
config_get device_type repacd DeviceType 'RE'
__repacd_echo "Device type: $device_type"
# Grab a lock to prevent any updates from being made by the daemon.
whc_wifi_config_lock
__repacd_config_wps_pbc_enhc 0 config_changed
# Config_changed is not being gracefully handled in MIPS.
# so commiting the change if wps_pbc_enhn is set
if [ "$config_changed" -gt 0 ]; then
uci_commit wireless
config_changed=0
fi
if __repacd_vaps_in_default_config; then
__repacd_reset_default_config
config_changed=1
__repacd_echo "Reset $managed_network VAPs"
else
# Need to massage the configuration to make it consistent with the
# expectations of repacd.
__repacd_reset_existing_config
__repacd_echo "Initialized $managed_network VAPs"
fi
__repacd_enable_wifi
# create additional vaps if traffic separation enabled
if __repacd_gw_mode || [ "$device_type" = 'RE' ] && [ "$gwcon_mode" != "CAP" ]; then
if [ "$traffic_separation_enabled" -gt 0 ]; then
if __repacd_is_qwrap_mode || \
__repacd_is_son_mode; then
if __repacd_check_additional_network_exist; then
__repacd_set_bridge_empty $network_guest
__repacd_set_firewall_rules $network_guest
__repacd_reset_additional_config
if ! __repacd_gw_mode && __repacd_is_qwrap_mode && \
[ "$traffic_separation_active" -eq 0 ]; then
local disable_24g_ap=1 disable_5g_ap=1
config_load wireless
config_foreach __repacd_disable_vap wifi-iface \
$network_backhaul 'ap' $disable_24g_ap $disable_5g_ap config_changed
config_foreach __repacd_disable_vap wifi-iface \
$network_guest 'ap' $disable_24g_ap $disable_5g_ap config_changed
uci_commit wireless
fi
uci_set repacd repacd NetworkBackhaul $network_backhaul
uci_commit repacd
activate_ts=1
fi
fi
fi
fi
if __repacd_gw_mode; then
# WAN group not empty; this device will act as CAP regardless of
# the GatewayConnectedMode setting
__repacd_config_gwcon_ap_mode 1
elif [ "$device_type" = 'RE' ]; then
# WAN group empty or non-existent
# Switch to range extender mode
# Clear the BSSIDs on fresh restart
config_load wireless
if [ "$traffic_separation_active" -gt 0 ]; then
config_foreach __repacd_delete_bssid_entry wifi-iface $network_backhaul config_changed
else
config_foreach __repacd_delete_bssid_entry wifi-iface $managed_network config_changed
fi
uci_set repacd WiFiLink BSSIDResolveState 'resolving'
uci_commit wireless
uci_commit repacd
__repacd_config_re_mode
if [ "$activate_ts" -eq 1 ]; then
config_load wireless
config_foreach __repacd_reconfig_sta_vaps wifi-iface $managed_network $network_backhaul \
"$backhaul_ssid" "$backhaul_enc" "$backhaul_key"
uci_commit wireless
fi
else
# Must be a client device (that can opportunistically act as an RE).
__repacd_config_client_mode
fi
whc_wifi_config_unlock
__repacd_restart_dependencies
if [ "$traffic_separation_enabled" -gt 0 ]; then
__repacd_wifi_set_otherband_bssids $network_backhaul
else
__repacd_wifi_set_otherband_bssids $managed_network
fi
# create vlan interfaces required for traffic separation.
if [ "$activate_ts" -eq 1 ]; then
config_load network
config_load wireless
config_foreach __repacd_add_vlan_interfaces wifi-iface \
$managed_network $lan_vid 'both' net_config_changed
config_foreach __repacd_add_vlan_interfaces wifi-iface \
$network_guest $guest_vid $guest_backhaul_iface net_config_changed
uci_commit wireless
__repacd_add_ethernet_vlan_interfaces $network_guest net_config_changed
uci_commit network
__repacd_restart_firewall
uci_set repacd repacd TrafficSeparationActive '1'
uci_commit repacd
# stop/start hyd only if there is any change in netwrok config
# due to addition of VLAN interfaces. If required VLAN iface already
# present then we can avoid hyd stop/start. This will save some time
# and avoid any delays after repacd restart.
if [ "$net_config_changed" -gt 0 ] || [ "$config_changed" -gt 0 ]; then
config_changed=0
hyd_stop=1
hyd_start=1
wsplcd_stop=1
wsplcd_start=1
__repacd_restart_dependencies
fi
fi
if [ "$eth_mon_enabled" -eq 1 ]; then
# Make sure lldpd listens on wan and lan interfaces
for int in wan lan; do
if ! uci get lldpd.config.interface | grep $int > /dev/null; then
uci add_list lldpd.config.interface=$int
fi
done
__repacd_echo "Starting lldpd"
repacd_netdet_lldpd_init start
fi
if ! __repacd_gw_mode || [ "$eth_mon_enabled" -eq 1 ]; then
start-stop-daemon -K -n repacd-run.sh -s SIGTERM >/dev/null
# Start the script that monitors the link state.
#
# When in NonCAP mode, it will keep checking whether there is a link
# to the gateway over ethernet. When in CAP mode, it will keep
# checking the WAN/LAN ifaces.
__repacd_echo "Starting RE Placement and Auto-config Daemon"
start-stop-daemon -S -x /usr/sbin/repacd-run.sh -b -- \
"son" init $config_re_mode $resolved_re_mode $resolved_re_submode
fi
}
# Perform the startup actions when operating with Multi-AP SIG Topology
# Optimization.
#
# Pre-condition: repacd has already been determined to be enabled and in
# MAP mode
#
# input: $1 - ether_gwcon: whether the device has been determined to be
# connected to the gateway via Ethernet
# input: $2 - start_role: the startup role for the device
# input: $3 - autoconf: boolean indicating whether this was a start
# initiated due to an auto config change
__start_map() {
local ether_gwcon=$1
local start_role=$2
local autoconf=$3
local enabled gwcon_mode first_config_required manage_mcsd
local traffic_separation_enabled ethernet_monitoring_enabled
local enable_steering standalone_controller
config_changed=0
config_load 'repacd'
config_get_bool enabled repacd 'Enable' '0'
config_get gwcon_mode repacd GatewayConnectedMode 'AP'
config_get_bool first_config_required MAPConfig 'FirstConfigRequired' '0'
config_get_bool manage_mcsd repacd 'ManageMCSD' 1
config_get_bool standalone_controller MAPConfig 'StandaloneController' '0'
# Certain features are not supported with Multi-AP (at least not yet)
config_get traffic_separation_enabled repacd TrafficSeparationEnabled '0'
config_get ethernet_monitoring_enabled repacd EnableEthernetMonitoring '0'
config_get enable_steering repacd EnableSteering '1'
if ! __repacd_is_son_mode; then
__repacd_echo "Multi-AP SIG algorithms must use 'son' RE mode"
return 1
fi
if [ "$traffic_separation_enabled" -gt 0 ]; then
__repacd_echo "Traffic separation not supported with Multi-AP SIG" \
"Topology Optimization"
return 1
fi
if [ "$ethernet_monitoring_enabled" -gt 0 ]; then
__repacd_echo "Ethernet monitoring not supported with Multi-AP SIG" \
"Topology Optimization"
return 1
fi
if [ "$enable_steering" -eq 0 ]; then
__repacd_echo "Steering must be enabled with Multi-AP SIG" \
"Topology Optimization"
return 1
fi
__repacd_echo "Starting Multi-AP SIG auto-configuration"
__repacd_echo "Ethernet connection to GW=$ether_gwcon"
__repacd_echo "GW Connected Mode=$gwcon_mode"
# For now, we can only manage a single network.
config_get managed_network repacd ManagedNetwork 'lan'
__repacd_echo "Managed network: $managed_network"
local is_controller=0
if __repacd_gw_mode || [ "$gwcon_mode" = 'Controller' ]; then
# WAN group not empty; this device will act as controller regardless of
# the GatewayConnectedMode setting
is_controller=1
fi
# Grab a lock to prevent any updates from being made by the daemon.
whc_wifi_config_lock
# Since the controller could tear down all AP interfaces, we need to
# allow hyd to run with no interfaces.
uci_set lbd config_Adv 'AllowZeroAPInterfaces' 1
# Also disable IAS on both bands, as we do not yet have the messaging
# support for it.
uci_set lbd IAS 'Enable_W2' 0
uci_set lbd IAS 'Enable_W5' 0
uci_commit lbd
# Disable the DBDC repeater feature on all devices, as there will only
# ever be a single backhaul STA interface.
config_load wireless
config_foreach __repacd_config_dbdc_device wifi-device \
0 config_changed
# Skip auto config for standalone controller, which must be manually configured
if [ "$first_config_required" -gt 0 ] && [ "$standalone_controller" -eq 0 ]; then
__repacd_reset_map_default_config $is_controller
config_changed=1
uci_set repacd MAPConfig 'FirstConfigRequired' 0
__repacd_echo "Performed initial config on $managed_network VAPs"
fi
if __repacd_gw_mode || [ "$ether_gwcon" -gt 0 ]; then
if ! __repacd_config_gwcon_map_ap $is_controller $standalone_controller; then
return 1
fi
else
# WAN group empty or non-existent
# Switch to agent mode
__repacd_config_map_re
fi
local enable_son=1
__repacd_config_mcsd "$manage_mcsd" "$enable_son"
whc_wifi_config_unlock
__repacd_restart_dependencies
if ! __repacd_gw_mode; then
start-stop-daemon -K -n repacd-run.sh -s SIGTERM >/dev/null
# Transform the boolean value into what the daemon expects
if [ "$autoconf" -gt 0 ]; then
autoconf='autoconf'
else
autoconf=''
fi
# Start the script that monitors the link state.
#
# In this NonCAP mode, it will keep checking whether there is a link
# to the gateway over ethernet.
__repacd_echo "Starting RE Placement and Auto-config Daemon"
start-stop-daemon -S -x /usr/sbin/repacd-run.sh -b -- \
"map" "$start_role" $config_re_mode $resolved_re_mode \
$resolved_re_submode $autoconf
fi
}
# Reset the count of the number of times the 5 GHz bSTA was attempted.
# This should only be invoked on boot and when switching between roles
# (eg. to CAP).
__repacd_map_reset_5g_attempts() {
uci_set repacd 'MAPWiFiLink' '5gAttemptsCount' 0
uci_commit repacd
}
# Script entry point: Perform configuration and start the daemon
start() {
local enabled
config_load 'repacd'
config_get_bool enabled repacd 'Enable' '0'
[ "$enabled" -gt 0 ] || {
return 1
}
if __repacd_is_map_enabled; then
__repacd_map_reset_5g_attempts
local ether_gwcon=0 start_role='init' autoconf=0
__start_map $ether_gwcon $start_role $autoconf
return $?
else
__start_son
return $?
fi
}
# Script entry point: Stop the daemon
stop() {
start-stop-daemon -K -n repacd-run.sh -s SIGTERM >/dev/null
if [ -f $WSPLCD_INIT ]; then
$WSPLCD_INIT stop
fi
}
# Script entry point: Reconfigure and restart the daemon
restart() {
stop
config_load 'repacd'
config_get_bool enabled repacd 'Enable' '0'
[ "$enabled" -gt 0 ] || {
return 1
}
start
}
# Force a restart into CAP mode using the SON algorithms.
#
# @see restart_in_cap_mode
__restart_in_cap_mode_son() {
local gwcon_mode device_type activate_ts
config_load repacd
config_get managed_network repacd ManagedNetwork 'lan'
config_get gwcon_mode repacd GatewayConnectedMode 'AP'
config_get device_type repacd DeviceType 'RE'
config_get traffic_separation_enabled repacd TrafficSeparationEnabled '0'
config_get traffic_separation_active repacd TrafficSeparationActive '0'
config_get daisy_chain WiFiLink DaisyChain '0'
config_get backhaul_ssid repacd BackhaulSSID $def_backhaul_ssid
config_get backhaul_enc repacd BackhaulEnc $def_backhaul_enc
config_get backhaul_key repacd BackhaulKey $def_backhaul_key
config_get network_guest repacd NetworkGuest 'guest'
config_get guest_ssid repacd GuestSSID $def_guest_ssid
config_get guest_enc repacd GuestEnc $def_guest_enc
config_get guest_key repacd GuestKey $def_guest_key
config_get guest_backhaul_iface repacd NetworkGuestBackhaulInterface 'both'
config_get manage_vap_ind WiFiLink 'ManageVAPInd' '0'
__repacd_get_config_re_mode config_re_mode
activate_ts=0
net_config_changed=0
stop
if [ "$gwcon_mode" = "CAP" ]; then
# Explicitly being forced into CAP mode while gateway connected.
# This could be a case where a device is being used as a pure bridge
# due to another device acting as the gateway.
__repacd_config_wps_pbc_enhc 1 config_changed
__repacd_config_gwcon_ap_mode 1
else
# Operate just as a standalone AP. This assumes there is another
# device in the network that operates as CAP.
__repacd_config_wps_pbc_enhc 0 config_changed
__repacd_config_gwcon_ap_mode 0
fi
__repacd_reset_existing_config
if [ "$device_type" = 'RE' ] && [ "$gwcon_mode" != "CAP" ]; then
if [ "$traffic_separation_enabled" -gt 0 ] && \
__repacd_is_son_mode; then
if __repacd_check_additional_network_exist; then
# reset additional vaps if traffic separation enabled
local disable_24g_ap=0 disable_5g_ap=0
local disable_24g_sta=1 disable_5g_sta=1
config_load network
config_load wireless
config_foreach __repacd_disable_vap wifi-iface \
$network_backhaul 'ap' $disable_24g_ap $disable_5g_ap config_changed
config_foreach __repacd_disable_vap wifi-iface \
$network_guest 'ap' $disable_24g_ap $disable_5g_ap config_changed
if [ "$traffic_separation_active" -eq 1 ]; then
config_foreach __repacd_delete_vlan_interfaces wifi-iface \
$managed_network $lan_vid 'ap' net_config_changed
config_foreach __repacd_delete_vlan_interfaces wifi-iface \
$network_guest $guest_vid 'ap' net_config_changed
config_foreach __repacd_delete_vlan_interfaces wifi-iface \
$managed_network $lan_vid 'sta' net_config_changed
config_foreach __repacd_delete_vlan_interfaces wifi-iface \
$network_guest $guest_vid 'sta' net_config_changed
config_foreach __repacd_disable_vap wifi-iface \
$network_backhaul 'sta' $disable_24g_sta $disable_5g_sta config_changed
fi
uci_commit wireless
uci_commit network
__repacd_reset_additional_config
activate_ts=1
fi
fi
fi
if [ "$wsplcd_enabled" -gt 0 ]; then
wsplcd_restart=1
fi
__repacd_restart_dependencies
if [ "$traffic_separation_enabled" -gt 0 ]; then
__repacd_wifi_set_otherband_bssids $network_backhaul
else
__repacd_wifi_set_otherband_bssids $managed_network
fi
if [ "$activate_ts" -eq 1 ]; then
config_load network
config_load wireless
config_foreach __repacd_add_vlan_interfaces wifi-iface \
$managed_network $lan_vid 'both' net_config_changed
config_foreach __repacd_add_vlan_interfaces wifi-iface \
$network_guest $guest_vid $guest_backhaul_iface net_config_changed
uci_commit wireless
__repacd_add_ethernet_vlan_interfaces $network_guest net_config_changed
uci_commit network
__repacd_restart_firewall
uci_set repacd repacd TrafficSeparationActive '1'
uci_commit repacd
if [ "$net_config_changed" -gt 0 ] || [ "$config_changed" -gt 0 ]; then
config_changed=0
hyd_stop=1
hyd_start=1
wsplcd_stop=1
wsplcd_start=1
__repacd_restart_dependencies
fi
fi
if ! __repacd_gw_mode; then
# Start the daemon that monitors link status in CAP mode, telling
# the daemon that it is an auto config-triggered restart.
#
# In this mode, it will just keep checking that the link to the
# gateway is still present on ethernet.
start-stop-daemon -S -x /usr/sbin/repacd-run.sh -b -- \
"son" CAP $config_re_mode $resolved_re_mode $resolved_re_submode \
autoconf
fi
}
# Force a restart into CAP mode using the Multi-AP SIG Topoology Optimization
# algorithm.
#
# @see restart_in_cap_mode
__restart_in_cap_mode_map() {
stop
# Reset the counter here in case we switch back into NonCAP (aka. RE)
# mode. It is easier to do it here than on the NonCAP restart since
# the latter is also used to force a bSTA change.
__repacd_map_reset_5g_attempts
local ether_gwcon=1 start_role='CAP' autoconf=1
__start_map $ether_gwcon $start_role $autoconf
}
# Force a restart into CAP mode.
#
# This is used when the gateway detection logic detects a gateway on
# ethernet when running in a pure bridge mode.
restart_in_cap_mode() {
if __repacd_is_map_enabled; then
__restart_in_cap_mode_map
return $?
else
__restart_in_cap_mode_son
return $?
fi
}
# Force a restart into NonCAP mode using the SON algorithms.
#
# @see restart_in_noncap_mode
__restart_in_noncap_mode_son() {
local device_type activate_ts
config_load repacd
config_get managed_network repacd ManagedNetwork 'lan'
config_get device_type repacd DeviceType 'RE'
config_get gwcon_mode repacd GatewayConnectedMode 'AP'
config_get traffic_separation_enabled repacd TrafficSeparationEnabled '0'
config_get traffic_separation_active repacd TrafficSeparationActive '0'
config_get daisy_chain WiFiLink DaisyChain '0'
config_get backhaul_ssid repacd BackhaulSSID $def_backhaul_ssid
config_get backhaul_enc repacd BackhaulEnc $def_backhaul_enc
config_get backhaul_key repacd BackhaulKey $def_backhaul_key
config_get network_guest repacd NetworkGuest 'guest'
config_get guest_ssid repacd GuestSSID $def_guest_ssid
config_get guest_enc repacd GuestEnc $def_guest_enc
config_get guest_key repacd GuestKey $def_guest_key
config_get guest_backhaul_iface repacd NetworkGuestBackhaulInterface 'both'
config_get manage_vap_ind WiFiLink 'ManageVAPInd' '0'
__repacd_get_config_re_mode config_re_mode
activate_ts=0
stop
net_config_changed=0
# Apply the SSID and passphrase to all interfaces to ensure that if we are
# switching into a SON mode where there are two STA interfaces, they all
# have the right credentials. For the non-SON and WDS modes, this is
# subject to the RE WPS enhancement rules.
__repacd_config_wps_pbc_enhc 0 config_changed
__repacd_reset_existing_config
# Need to resolve the generic NonCAP role to the actual configuration.
if [ "$device_type" = 'RE' ]; then
__repacd_config_re_mode
if [ "$gwcon_mode" != "CAP" ]; then
if [ "$traffic_separation_enabled" -gt 0 ] && \
__repacd_is_son_mode; then
if __repacd_check_additional_network_exist; then
# reset additional vaps if traffic separation enabled
local disable_24g_ap=0 disable_5g_ap=0
config_load wireless
# Enable spcl AP VAPs on NON-CAP only if daisy chain is enabled.
# They are for multi hop support. We don't need them if daisy
# chain is disabled.
if [ "$daisy_chain" -gt 0 ]; then
config_foreach __repacd_disable_vap wifi-iface \
$network_backhaul 'ap' $disable_24g_ap $disable_5g_ap config_changed
fi
config_foreach __repacd_disable_vap wifi-iface \
$network_guest 'ap' $disable_24g_ap $disable_5g_ap config_changed
uci_commit wireless
__repacd_reset_additional_config
config_load wireless
config_foreach __repacd_reconfig_sta_vaps wifi-iface $managed_network $network_backhaul \
"$backhaul_ssid" "$backhaul_enc" "$backhaul_key"
uci_commit wireless
activate_ts=1
fi
fi
fi
else
__repacd_config_client_mode
fi
if [ "$wsplcd_enabled" -gt 0 ]; then
wsplcd_restart=1
fi
__repacd_restart_dependencies
if [ "$traffic_separation_enabled" -gt 0 ]; then
__repacd_wifi_set_otherband_bssids $network_backhaul
else
__repacd_wifi_set_otherband_bssids $managed_network
fi
# create vlan interfaces required for traffic separation.
if [ "$activate_ts" -eq 1 ]; then
config_load network
config_load wireless
config_foreach __repacd_add_vlan_interfaces wifi-iface \
$managed_network $lan_vid 'both' net_config_changed
config_foreach __repacd_add_vlan_interfaces wifi-iface \
$network_guest $guest_vid $guest_backhaul_iface net_config_changed
uci_commit wireless
__repacd_add_ethernet_vlan_interfaces $network_guest net_config_changed
uci_commit network
__repacd_restart_firewall
uci_set repacd repacd TrafficSeparationActive '1'
uci_commit repacd
# stop/start hyd only if there is any change in netwrok config
# due to addition of VLAN interfaces. If required VLAN iface already
# present then we can avoid hyd stop/start. This will save some time
# and avoid any unnecessary delays after repacd restart.
if [ "$net_config_changed" -gt 0 ] || [ "$config_changed" -gt 0 ]; then
config_changed=0
hyd_stop=1
hyd_start=1
wsplcd_stop=1
wsplcd_start=1
__repacd_restart_dependencies
fi
fi
if ! __repacd_gw_mode; then
# Start the script that monitors the link state, telling the daemon that
# it is an auto config-triggered restart.
#
# In this NonCAP mode, it will keep checking whether there is a link
# to the gateway over ethernet.
start-stop-daemon -S -x /usr/sbin/repacd-run.sh -b -- \
"son" NonCAP $config_re_mode $resolved_re_mode \
$resolved_re_submode autoconf
fi
}
# Force a restart in NonCAP mode using the Multi-AP SIG Topology Optimization
# algorithm.
#
# @see restart_in_noncap_mode
__restart_in_noncap_mode_map() {
stop
local ether_gwcon=0 start_role='NonCAP' autoconf=1
__start_map $ether_gwcon $start_role $autoconf
}
# Force a restart into NonCAP mode.
#
# This is used when the gateway detection logic detects that there is no
# longer a gateway connected over ethernet.
restart_in_noncap_mode() {
if __repacd_is_map_enabled; then
__restart_in_noncap_mode_map
return $?
else
__restart_in_noncap_mode_son
return $?
fi
}
# Force a restart into Range Extender (RE) mode with the SON algorithms.
#
# @see restart_in_re_mode
__restart_in_re_mode_son() {
config_load repacd
config_get managed_network repacd ManagedNetwork 'lan'
stop
# By resetting the configuration, this will apply the same SSID and
# passphrase to all interfaces. Then enable the interfaces as appropriate
# for RE mode.
__repacd_config_wps_pbc_enhc 0 config_changed
__repacd_reset_existing_config
__repacd_config_re_mode
if [ "$wsplcd_enabled" -gt 0 ]; then
wsplcd_restart=1
fi
__repacd_restart_dependencies
__repacd_wifi_set_otherband_bssids $managed_network
if ! __repacd_gw_mode; then
# Start the script that monitors the link state, telling the daemon
# that it is an auto config-triggered restart.
#
# In this Range Extender mode, it will keep checking whether there is
# a link to the gateway over ethernet and that the Wi-Fi link is
# sufficient to continue operating as an RE.
start-stop-daemon -S -x /usr/sbin/repacd-run.sh -b -- \
"son" RE $config_re_mode $resolved_re_mode $resolved_re_submode \
autoconf
fi
}
# Force a restart into Range Extender (RE) mode with the Multi-AP SIG Topology
# Optimization algorithm.
#
# @see restart_in_re_mode
__restart_in_re_mode_map() {
stop
local ether_gwcon=0 start_role='RE' autoconf=1
__start_map $ether_gwcon $start_role $autoconf
}
# Force a restart into Range Extender (RE) mode.
#
# This is used when the Wi-Fi link monitoring logic determines that the
# link is in the sweet spot for a device that normally acts as a client
# but is capable (from a CPU and Wi-Fi perspective) of operating as an AP
# and a STA at the same time.
restart_in_re_mode() {
if __repacd_is_map_enabled; then
__restart_in_re_mode_map
return $?
else
__restart_in_re_mode_son
return $?
fi
}