Created
February 27, 2025 11:13
-
-
Save rickmark/3da20e15c9a0be1bafe9df25bd067980 to your computer and use it in GitHub Desktop.
sys wrapper.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
exec >> /tmp/syswrapper.log | |
exec 2>&1 | |
echo "$(date) {$@}" | |
. /usr/bin/platdep_funcs.sh | |
. /usr/bin/state_lock_funcs.sh | |
. /usr/bin/unifi_util_funcs.sh | |
guest_portal_enabled() { | |
get_config_enabled "/run/redirector.cfg" "redirector.status" | |
} | |
DEFAULT_GUEST_IPSET='UBIOS_authorized_guests' | |
DEFAULT_REDIRECTOR_HTTP_PORT=39080 | |
DEFAULT_REDIRECTOR_HTTPS_PORT=39443 | |
GUEST_IPTABLES_REDIRECTOR=UBIOS_REDIRECTOR | |
. /usr/bin/guest_portal_funcs.sh | |
CONFIG_DIR='/data/udapi-config' | |
LINKCHECK_CONFIG_FOLDER=/var/run/linkcheck | |
SYSID=`awk -F= '/^systemid=/{print $2}' /proc/ubnthal/system.info` | |
LCM_CONTROL='/usr/bin/lcm-control' | |
SYSINFO_FILE='/proc/ubnthal/system.info' | |
IsLocated='/proc/ubnthal/status/IsLocated' | |
UBNT_SYSTOOL='/sbin/ubnt-systool' | |
SYSTEM_CFG="/tmp/system.cfg" | |
LED_CTRL="/usr/bin/uled-ctrl" | |
LED_GPIODEV_DIR="/proc/gpio" | |
MTK_UAP=`grep radio0 /proc/ubnthal/system.info | grep -c -e MT` | |
QCA_UAP_MAPLE_DAKOTA=`grep -c -e Maple -e Dakota /proc/ubnthal/system.info` | |
QCA_UAP_MIAMI=`grep -c -e Miami /proc/ubnthal/system.info` | |
UPLINK_FILE="/var/run/system.uplink" | |
UPLINK_FILE_PREV="${UPLINK_FILE}.prev" | |
UPLINK_FILE_LOOP="${UPLINK_FILE}.loop" | |
ALLOWED_UPLINKS="/var/run/allowed_uplinks" | |
ISOLATION_LOGS_LOCATION='/etc/persistent/isolation_logs' | |
ISOLATION_LOGS_LOCATION_SENT="${ISOLATION_LOGS_LOCATION}_sent" | |
ISOLATION_LOGS_LOCATION_META="${ISOLATION_LOGS_LOCATION}/meta" | |
HOSTAPD_RUN_DIR="/var/run/hostapd" | |
CONFIG_DIR="/data/udapi-config" | |
MGMT_PATH="$CONFIG_DIR/mgmt" | |
IS_UPLINK=`[ "$SYSID" = "a667" -o "$SYSID" = "a69b" ] && echo "true"` | |
POE_PATH="/sys/class/poe" | |
BOOT_TIMESTAMP_FILE="/var/run/boot-timestamp" | |
WAN_ADOPT_IP_FILE="/var/run/adopt.eth.ip" | |
GEOIP_DB_SCRIPT_PATH="/usr/bin/geoip-db-script" | |
NEARBY_CTRLER_LAST_SEEN_FILE="/tmp/controller.last_seen" | |
ARPING="/usr/sbin/arping" | |
log() { | |
logger -s -t "syswrapper" "$*" | |
} | |
safe_call() { | |
function_name=$1 | |
shift | |
if command -v "$function_name" >/dev/null 2>&1; then | |
"$function_name" "$@" | |
else | |
log "Function '$function_name' does not exist or is not defined on this platform." | |
return 1 | |
fi | |
} | |
is_setup_completed() { | |
local is_setup="false" | |
if [ -f "$MGMT_PATH" ] ; then | |
is_setup=$(grep mgmt.is_setup_completed "$MGMT_PATH" | cut -d= -f 2) | |
fi | |
echo "${is_setup}" | |
} | |
add_stat() { | |
local n=$(cat "$1" 2>/dev/null) | |
local inc=$2 | |
echo $((n+inc)) > "$1" | |
} | |
# check if interface is within schedule inside /var/run/schedules/schedule_*.ath* file | |
within_schedule() { | |
schedule="/var/run/schedules/schedule.$1" | |
now=`date "+%w %H:%M %Y"` | |
mode="up" | |
timesynced=`timedatectl | grep 'System clock synchronized:' | awk '{print $4}'` | |
[ -f /var/run/schedules/schedule_invert.$1 ] && mode="down" | |
# if timesyncd is running, we assume always within schedule | |
if [ $timesynced = "yes" ]; then | |
if [ -e $schedule ]; then | |
blocks=`grep $(echo $now | cut -c1)= $schedule` | |
todayMins=`expr $(echo $now | cut -c3-4) \* 60 + $(echo $now | cut -c6-7)` | |
for b in $blocks; do | |
b=$(echo $b | cut -c3-${#b}) | |
fromMins=`expr $(echo $b | cut -c1-2) \* 60 + $(echo $b | cut -c4-5)` | |
toMins=`expr $(echo $b | cut -c7-8) \* 60 + $(echo $b | cut -c10-11)` | |
if [ $todayMins -ge $fromMins ] && [ $todayMins -le $toMins ]; then | |
if [ "$mode" = "up" ]; then | |
echo "true" | |
else | |
echo "false" | |
fi | |
return | |
fi | |
done | |
if [ "$mode" = "up" ]; then | |
echo "false" | |
else | |
echo "true" | |
fi | |
else | |
log 'schedules not found in /var/run/schedules' | |
echo "false" | |
fi | |
else | |
log 'current time is not set yet' | |
echo "true" | |
fi | |
} | |
configure_vap() { | |
[ ! -z "$3" ] && [ -f /var/run/wlan_devnames ] || return | |
vaps=`cat /var/run/wlan_devnames` | |
run_vap= | |
stop_vap= | |
uplink_vaps= | |
allowed_uplinks= | |
downlink_vaps= | |
n_uplink_vaps=0 | |
uplink_states= | |
uplink_state=$1 | |
service_state=$2 | |
downlink_state=$3 | |
if [ -f $ALLOWED_UPLINKS ]; then | |
allowed_uplinks=`cat $ALLOWED_UPLINKS` | |
fi | |
for ath in $vaps; do | |
usage="unknown" | |
if [ -f /var/run/vapusage.$ath ]; then | |
usage=`cat /var/run/vapusage.$ath` | |
fi | |
if [ -f ${HOSTAPD_RUN_DIR}/cfg_error.$ath ]; then | |
usage=unusable | |
fi | |
case $usage in | |
uplink) | |
n_uplink_vaps=`expr $n_uplink_vaps + 1` | |
uplink_vaps="$uplink_vaps $ath" | |
if [ "$uplink_state" = "down" ]; then | |
stop_vap="$stop_vap $ath" | |
uplink_states="$uplink_states down" | |
else | |
# 3 cases to "up" a vport interface when uplink_state = up | |
# 1. no ALLOWED_UPLINKS file, wpa_supplicant will run | |
# 2. ALLOWED_UPLINKS file is empty, wpa_supplicant will not run | |
# (assume device with multiple vport, set all vports up for scanning) | |
# 3. interface listed in ALLOWED_UPLINKS file, wpa_supplicant will run | |
# (assume device with multiple vport, set selected vport for uplink) | |
if [ ! -f $ALLOWED_UPLINKS ]; then | |
# case 1 above | |
run_vap="$run_vap $ath" | |
uplink_states="$uplink_states up" | |
else | |
if [ -z "$allowed_uplinks" ]; then | |
# case 2 above | |
if [ -f /var/run/system.multi_uplink ]; then | |
run_vap="$run_vap $ath" | |
fi | |
uplink_states="$uplink_states down" | |
else | |
# case 3 above | |
is_allowed_uplink="false" | |
for allowed_uplink in $allowed_uplinks; do | |
if [ $ath = $allowed_uplink ]; then | |
if [ -f /var/run/system.multi_uplink ]; then | |
run_vap="$run_vap $ath" | |
fi | |
uplink_states="$uplink_states up" | |
is_allowed_uplink="true" | |
break | |
fi | |
done | |
if [ $is_allowed_uplink = "false" ]; then | |
if [ -f /var/run/system.multi_uplink ]; then | |
stop_vap="$stop_vap $ath" | |
fi | |
uplink_states="$uplink_states down" | |
fi | |
fi | |
fi | |
fi | |
;; | |
user) | |
if [ "$service_state" = "down" ]; then | |
stop_vap="$stop_vap $ath" | |
else | |
scheduled=`within_schedule $ath` | |
if [ $scheduled = "true" ]; then | |
run_vap="$run_vap $ath" | |
else | |
stop_vap="$stop_vap $ath" | |
touch "/var/run/schedule_wlan_stop_work.$ath" | |
fi | |
fi | |
;; | |
guest) | |
if [ "$service_state" = "down" ]; then | |
stop_vap="$stop_vap $ath" | |
else | |
scheduled=`within_schedule $ath` | |
if [ $scheduled = "true" ]; then | |
run_vap="$run_vap $ath" | |
else | |
stop_vap="$stop_vap $ath" | |
touch "/var/run/schedule_wlan_stop_work.$ath" | |
fi | |
fi | |
;; | |
downlink) | |
if [ "$downlink_state" = "down" ]; then | |
stop_vap="$stop_vap $ath" | |
else | |
run_vap="$run_vap $ath" | |
downlink_vaps="$downlink_vaps $ath" | |
fi | |
;; | |
wireless-bridge) | |
run_vap="$run_vap $ath" | |
;; | |
wireless-bridge-failover) | |
# Bring down the failover link in default state no matter | |
# udhcpc lease fail or not | |
if [ "$ath" = "${PRS_INTC}" ]; then | |
brctl delif br0 $ath | |
fi | |
stop_vap="$stop_vap $ath" | |
;; | |
esac | |
done | |
# Currently we set vap_ind = 1 for wds vap, simply relying | |
# on uplink-monitor to adjust vap status. | |
# QCA requires wds vap to be up before all ap vap. | |
for ath in $stop_vap; do | |
/sbin/ifconfig $ath down | |
done | |
if [ ! -e /var/run/hostapd_reload ]; then | |
for ath in $run_vap; do | |
if [ "${MTK_UAP}" = "1" ]; then | |
if [ -f /var/run/wds_skip_up ]; then | |
rm /var/run/wds_skip_up | |
elif [ `check_if_hostapd_killed $ath` = "true" ]; then | |
: | |
else | |
/sbin/ifconfig $ath up | |
fi | |
else | |
if ( iface_is_in_bridge $ath ) || \ | |
( iface_is_create_vlan $ath && are_all_vlan_interfaces_in_bridge $ath ); then | |
/sbin/ifconfig $ath up | |
fi | |
fi | |
done | |
fi | |
for ath in $downlink_vaps; do | |
# skip U6-Pro mt7622 radio since it dose not support VWIRE | |
var=`expr substr "$ath" 3 1` | |
if [ "${MTK_UAP}" = "1" -a "${RADIO_MT7622}" = "1" -a "${var}" != "i" ]; then | |
continue | |
fi | |
# need to move to platform_funs.sh | |
if [ "${MTK_UAP}" = "1" ]; then | |
uif_str="set uif=" | |
else | |
uif_str="uif " | |
fi | |
if [ `cat ${UPLINK_FILE}` = "eth" ]; then | |
/sbin/iwpriv $ath ${uif_str}1 | |
elif [ `cat ${UPLINK_FILE}` = "wds" ]; then | |
/sbin/iwpriv $ath ${uif_str}2 | |
fi | |
done | |
# log "[configure_vap] \$n_uplink_vaps = $n_uplink_vaps" | |
# log "[configure_vap] \$uplink_vaps = $uplink_vaps" | |
# log "[configure_vap] \$uplink_states = $uplink_states" | |
for i in `seq 1 $n_uplink_vaps`; do | |
ath=`echo $uplink_vaps | cut -d " " -f $i` | |
action=`echo $uplink_states | cut -d " " -f $i` | |
configure_uplink $ath $action | |
done | |
if [ -f /var/run/hostapd_reload ]; then | |
if systemctl list-units --type=service | grep -q hostapd-global.service; then | |
systemctl reload hostapd-global | |
else | |
hostapd-action reload | |
fi | |
fi | |
} | |
check_if_hostapd_killed() { | |
if [ -f "/var/run/schedule_wlan_stop_work.$1" ]; then | |
systemctl restart hostapd@$1 | |
rm /var/run/schedule_wlan_stop_work.$1 | |
echo "true" | |
else | |
echo "false" | |
fi | |
} | |
schedule_action() { | |
if [ -f ${UPLINK_FILE} ]; then | |
# need to check system state busy first in case the deac lock for the syswrapper.sh | |
exit_if_busy $cmd $* | |
exit_if_state_lock_failed $cmd $* | |
state_reload | |
state_unlock | |
else | |
configure_vap down up up | |
fi | |
} | |
exit_if_fake() { | |
if [ "`uname -a | grep -E \"mips|arm|aarch64\"`" = "" -o -f "/tmp/FAKE" ] ; then | |
# fake, simply dump it to console and exit 0 | |
logger -s -t "syswrapper" "[fake] skipping $*" | |
exit 0 | |
fi | |
} | |
is_wds() { | |
if [ -f ${UPLINK_FILE} ]; then | |
local UPLINK=`cat ${UPLINK_FILE}` | |
if [ "${UPLINK}" = "wds" ]; then | |
return 0 | |
fi | |
fi | |
return 1 | |
} | |
led_reload() { | |
# Check if system is running | |
set_led_state "idle" | |
} | |
# obtain lock first | |
state_reload() { | |
local state="init" | |
local default="true" | |
local locating="false" | |
if [ -f /proc/ubnthal/status/IsDefault ]; then | |
default=`cat /proc/ubnthal/status/IsDefault` | |
fi | |
if [ -f /proc/ubnthal/status/IsLocated ]; then | |
locating=`cat /proc/ubnthal/status/IsLocated` | |
fi | |
if [ -f ${SYSTEM_STATE} ] ; then | |
state=`cat ${SYSTEM_STATE}` | |
fi | |
if [ "$IS_UPLINK" = "true" ]; then | |
uplink_reload $state $default | |
else | |
configure_vap down up up | |
fi | |
} | |
uplink_reload() { | |
local state="$1" | |
local default="$2" | |
local uplink="unknown" | |
local prev_uplink="unknown" | |
local uplink_loop="false" | |
if [ "$(is_setup_completed)" = "true" ]; then | |
default="false" | |
fi | |
if [ -f ${UPLINK_FILE} ]; then | |
uplink=`cat ${UPLINK_FILE}` | |
if [ -e ${UPLINK_FILE_PREV} ]; then | |
prev_uplink=`cat ${UPLINK_FILE_PREV}` | |
else | |
prev_uplink=$uplink | |
fi | |
echo $uplink > ${UPLINK_FILE_PREV} | |
fi | |
if [ -f ${UPLINK_FILE_LOOP} ]; then | |
uplink_loop=`cat ${UPLINK_FILE_LOOP}` | |
fi | |
if [ "$state" = "upgrading" ]; then | |
# TO-DO: Change device indication to "upgrading" | |
return | |
fi | |
if [ "$default" = "true" ]; then | |
# TO-DO: Change device indication to "default-ready" | |
case $uplink in | |
init | eth | unknown) | |
configure_vap down up up | |
;; | |
down) | |
configure_vap up down down | |
log "[state_reload-3] up down down" | |
;; | |
esac | |
return | |
fi | |
case $uplink in | |
eth) | |
if [ "$prev_uplink" != "init" -a "$prev_uplink" != "eth" -a "$QCA_UAP_MIAMI" = "1" ]; then | |
log "[state_reload][$prev_uplink -> eth] reload hostapd" | |
touch /var/run/hostapd_reload | |
touch /var/run/hostapd_check_skip | |
echo "eth" > /var/run/mesh_state | |
fi | |
if [ "$uplink_loop" = "true" ]; then | |
configure_vap down up down | |
else | |
configure_vap down up up | |
fi | |
if [ "$prev_uplink" != "init" -a "$prev_uplink" != "eth" ]; then | |
channel_resume | |
fi | |
# TO-DO: Change device indication to "ready" | |
return | |
;; | |
wds) | |
if [ "$prev_uplink" != "init" -a "$prev_uplink" != "wds" -a "$QCA_UAP_MIAMI" = "1" ]; then | |
log "[state_reload][$prev_uplink -> wds] reload hostapd" | |
touch /var/run/hostapd_reload | |
touch /var/run/hostapd_check_skip | |
echo "wds" > /var/run/mesh_state | |
fi | |
if [ -f /var/run/vport_down ]; then | |
log "[state_reload][wds] vport down" | |
configure_vap up down down | |
elif [ -f /var/run/system.mesh ]; then | |
configure_vap up up up | |
else | |
configure_vap up up down | |
fi | |
# TO-DO: Change device indication to "ready" | |
return | |
;; | |
down) | |
if [ -f /var/run/system.isolated_wlan_on ]; then | |
configure_vap up up down | |
# TO-DO: Change device indication to "isolation" | |
else | |
if [ "$prev_uplink" = wds ]; then | |
configure_vap down down down | |
add_stat /var/run/vwire_disconnected.count 1 | |
else | |
configure_vap up down down | |
fi | |
# TO-DO: Change device indication to "isolation" | |
fi | |
if [ "$default" != "true" -a \ | |
"`grep wireless.1.usage=uplink /tmp/system.cfg`" != "" -a \ | |
"`grep wireless.1.mode=master /tmp/system.cfg`" != "" ] ; then | |
# for V2 AP using old wireless uplink, we need to _migrate_ the uplink vap | |
# by reset the config but leave | |
ubnt-systool reset2defaults | |
reboot 'controller' | |
fi | |
return | |
;; | |
lte_prov) | |
# do nothing. lte provisioning wifi network is separate from udhcpc interface. | |
;; | |
esac | |
if [ "$state" = "ready" ]; then | |
# TO-DO: Change device indication to "ready" | |
return | |
fi | |
} | |
# obtain lock first | |
set_state_reload() { | |
set_state "$1" | |
state_reload | |
} | |
# obtain lock first | |
cfg_save() { | |
set_state 'cfgupdate' | |
cp /tmp/system.cfg $CONFIG_DIR/.unifi.tmp | |
# ensure file copy is atomic | |
mv $CONFIG_DIR/.unifi.tmp $CONFIG_DIR/unifi | |
set_state_reload ready | |
} | |
do_fast_apply() { | |
ubntconf_apply_failed=/tmp/failed.cfg | |
rm -rf /tmp/apply.sh | |
rm -rf "${ubntconf_apply_failed}" | |
if ubntconf -c /tmp/system.cfg -p /tmp/running.cfg -d /tmp/apply.sh; then | |
log "[apply-config] using fast apply" | |
if [ -f /tmp/apply.sh ]; then | |
if /bin/sh /tmp/apply.sh; then | |
cp -f /tmp/running.cfg /tmp/previous.cfg | |
cp -f /tmp/system.cfg /tmp/running.cfg | |
return 0 | |
fi | |
log "[error] fast-apply failed" | |
cp -f /tmp/system.cfg "${ubntconf_apply_failed}" | |
return 1 | |
fi | |
return 0 | |
fi | |
cp -f /tmp/system.cfg "${ubntconf_apply_failed}" | |
return 1 | |
} | |
do_performance() { | |
# thermal | |
if [ -f /usr/sbin/thermal.sh ]; then | |
log "[do_performance] run thermal script" | |
/bin/bash /usr/sbin/thermal.sh | |
fi | |
# smp_affinity | |
if [ -f /usr/sbin/smp_affinity.sh ]; then | |
log "[do_performance] run smp_affinity script" | |
/bin/bash /usr/sbin/smp_affinity.sh | |
fi | |
} | |
# Generate a support file in the specified path. | |
# | |
# Usage: gen_support_file <path> <dir> | |
# | |
# This function generates a support file at the specified path. The process is | |
# running in the background, so the support file may not exist when the function | |
# returns. | |
gen_support_file() { | |
local support_file_path=$1 | |
local support_file_dir=$2 | |
# If there is an ongoing process of generating support file, skip it. | |
local gen_support_pid_file="/var/run/gen_support.pid" | |
if [ -e ${gen_support_pid_file} ]; then | |
local gen_support_pid=$(cat ${gen_support_pid_file}) | |
echo pid = ${gen_support_pid} | |
local COMM=$(cat /proc/${gen_support_pid}/comm) | |
if echo "${0}" | grep -q "${COMM}"; then | |
return | |
fi | |
fi | |
# It takes a lot of time to generate a support file, so let it run in the background. | |
( | |
ubnt-systool support ${support_file_path}/${support_file_dir}; | |
tar -czf ${support_file_path}/${support_file_dir}.tar.gz -C ${support_file_path} ${support_file_dir} | |
rm -r ${support_file_path}/${support_file_dir} | |
rm ${gen_support_pid_file} | |
) & | |
echo -n $! > ${gen_support_pid_file} | |
} | |
dump_syslog_to_persistent() { | |
local isolation_log_tmp='/var/log/isolation' | |
local wul_info_tmp='/var/log/wul_info' | |
local loop_pkt_tmp='/var/log/loop_pkt.pcap' | |
local syslog_file="/var/log/messages" | |
local uplink_eth="$(cat /var/run/uplink_eth)" | |
local uplink_wds="$(cat /var/run/uplink_wds)" | |
local uplink_model=$1 | |
# Each log takes up to ~8kB after compression | |
local isolation_log_length=500 | |
local isolation_log_limit=4 | |
local support_file_limit=2 | |
mkdir -p ${ISOLATION_LOGS_LOCATION} | |
mkdir -p ${ISOLATION_LOGS_LOCATION_SENT} | |
mkdir -p ${ISOLATION_LOGS_LOCATION_META} | |
if [ -e "$syslog_file" ]; then | |
tail -n "$isolation_log_length" "$syslog_file" > "$isolation_log_tmp" | |
else | |
echo "Missing $syslog_file" > "$isolation_log_tmp" | |
dmesg | tail -n "$isolation_log_length" >> "$isolation_log_tmp" | |
fi | |
echo -n "$uplink_eth: " > $wul_info_tmp | |
cat /sys/class/net/$uplink_eth/address >> $wul_info_tmp | |
echo -n "$uplink_wds: " >> $wul_info_tmp | |
cat /sys/class/net/$uplink_wds/address >> $wul_info_tmp | |
echo "uplink_model: $uplink_model" >> $wul_info_tmp | |
# remove old logs if we have more than a specified limit | |
rm -f `ls -d ${ISOLATION_LOGS_LOCATION}/isolated_* | head -n -${isolation_log_limit}` | |
rm -f `ls -d ${ISOLATION_LOGS_LOCATION}/support_* | head -n -${support_file_limit}` | |
# prune sent and meta files when a log file has been removed | |
for FILE in ${ISOLATION_LOGS_LOCATION_SENT}/* ${ISOLATION_LOGS_LOCATION_META}/* ; do | |
[ -f "${ISOLATION_LOGS_LOCATION}/$(basename ${FILE})" ] || rm -f ${FILE} | |
done | |
mkdir -p ${ISOLATION_LOGS_LOCATION} | |
local TIMESTAMP=`date +%s` | |
gen_support_file "${ISOLATION_LOGS_LOCATION}" "/support_${TIMESTAMP}" | |
tar -czf ${ISOLATION_LOGS_LOCATION}/isolated_${TIMESTAMP}.tar.gz ${isolation_log_tmp} ${loop_pkt_tmp} ${wul_info_tmp} | |
rm -f ${isolation_log_tmp} ${loop_pkt_tmp} ${wul_info_tmp} | |
} | |
upgrade_ready() { | |
local msg | |
msg=$* | |
mca-custom-alert.sh -k "event_string" -v "Upgrade" -k "up_type" -v "UpgradeReady" -k "up_stage" -v "${msg}" | |
#sleep for send out the notification to the controller | |
sleep 2 | |
} | |
wifi_status() { | |
local msg | |
msg=$* | |
mca-custom-alert.sh -k "event_string" -v "WiFiStatus" -k "status" -v "${msg}" | |
#sleep for send out the notification to the controller | |
sleep 2 | |
} | |
set_lcm_command() { | |
if [ -f ${SYSINFO_FILE} ] && [ -x ${LCM_CONTROL} ]; then | |
if [ $# = 1 ]; then | |
${LCM_CONTROL} --command $1 --sender syswrapper | |
else | |
${LCM_CONTROL} --command $1 --parameter $2 --sender syswrapper | |
fi | |
fi | |
} | |
set_led_state() { | |
local fw_state=$1 | |
if [ -x $LED_CTRL ]; then | |
case "$fw_state" in | |
locate) | |
$LED_CTRL -sn fw $fw_state >/dev/null 2>&1 | |
;; | |
idle) | |
systemctl -q is-system-running && $LED_CTRL fw $fw_state >/dev/null 2>&1 | |
;; | |
*) | |
return | |
;; | |
esac | |
elif [ -d $LED_GPIODEV_DIR ]; then | |
local default="true" | |
if [ -f /proc/ubnthal/status/IsDefault ]; then | |
default=`cat /proc/ubnthal/status/IsDefault` | |
fi | |
case "$fw_state" in | |
locate) | |
echo 12 > $LED_GPIODEV_DIR/led_pattern | |
echo 480 > $LED_GPIODEV_DIR/led_tempo | |
;; | |
idle) | |
echo 0 > $LED_GPIODEV_DIR/led_pattern | |
if [ -f "$MGMT_PATH" ]; then | |
led_disabled=$(grep mgmt.led_enabled=false "$MGMT_PATH") | |
fi | |
if [ -z "$led_disabled" ]; then | |
if [ "$default" = "true" ]; then | |
echo 2 > $LED_GPIODEV_DIR/led_pattern | |
else | |
echo 1 > $LED_GPIODEV_DIR/led_pattern | |
fi | |
fi | |
echo 120 > $LED_GPIODEV_DIR/led_tempo | |
;; | |
*) | |
return | |
;; | |
esac | |
fi | |
} | |
set_ubnt_systool() { | |
[ -f ${UBNT_SYSTOOL} ] || return; | |
${UBNT_SYSTOOL} $1 | |
} | |
do_ufn_connection_trace() { | |
local ufn_connection_status=`echo -n "${1:-unknown}" | base64 -w 0` | |
ubnt_report_handler trace_ufn_connection --status ${ufn_connection_status} | |
} | |
do_udapi_request_trace() { | |
local error_message=`echo -n "${1:-unknown}" | base64 -w 0` | |
if systemctl -q is-active udapi-server; then | |
ubnt_report_handler trace_udapi_request_failed --logs ${error_message} | |
fi | |
} | |
skip_apply() { | |
local sysid=`awk -F= '/^systemid=/{print $2}' ${SYSINFO_FILE}` | |
if [ "$sysid" = "eccc" ] ; then #UDR | |
local non_hide_ssid=$(grep -r hide_ssid ${SYSTEM_CFG} | awk 'BEGIN {FS="=";i=0} {if($2 == "false") {++i}} END {print i}') | |
local isSetup=$(grep -r isSetup /data/unifi-core/config/settings.yaml | awk '{print $2}') | |
if [ ${non_hide_ssid} -eq 0 ] && [ ${isSetup} = "false" ]; then | |
log "skip apply-config due to not setup" | |
return 0 | |
fi | |
fi | |
return 1 | |
} | |
do_power_cycle() { | |
local power_cycle_path="${POE_PATH}/port-$1/power_cycle" | |
if [ -e $power_cycle_path ]; then | |
# delay 1000 ms | |
echo 1000 > $power_cycle_path | |
fi | |
} | |
[ $# -lt 1 ] && exit 1 | |
cmd="$1" | |
shift | |
do_teleport_call() { | |
local request_id=$1 | |
local method=$2 | |
local path=$3 | |
local payload="$4" | |
local response | |
[ "$payload" = "" ] && payload="{}" | |
response=`curl -s --max-time 60 -X $method http://localhost:8000/$path -d "$payload"` | |
[ $? -ne 0 ] && response='{"error": "Could not connect to Teleport daemon"}' | |
mca-custom-alert.sh -k event_string -v teleport_response -k request_id -v "$request_id" -k params -j "$response" | |
} | |
del_bridge_vlans() { | |
for br in $(ifconfig -a | grep "^$1\(\.\| \)" | sed -e "s/ .*//"); do | |
for _iface in $(ls -1 /sys/class/net/${br}/brif); do | |
local iface=$(basename "$_iface") | |
if echo "$iface" | grep -q "\."; then | |
vconfig rem "$iface" | |
fi | |
done | |
ifconfig "$br" down | |
brctl delbr "$br" | |
done | |
} | |
fw_triggers_restart_ulogd() { | |
local fw_triggers_act="${1}" | |
local conf_string_log | |
local conf_string_ct | |
local conf_string_geo | |
if [ "${fw_triggers_act}" = "init" ]; then | |
touch /var/run/fw-triggers | |
conf_string_log="s/^#stack=unifi_log/stack=unifi_log/g" | |
conf_string_ct="s/^#stack=flow_nfct/stack=flow_nfct/g" | |
conf_string_geo="/^#stack=geo_log:NFLOG.*geo_json:JSON/s/^#//g" | |
else | |
rm -f /var/run/fw-triggers | |
conf_string_log="s/^stack=unifi_log/#stack=unifi_log/g" | |
conf_string_ct="s/^stack=flow_nfct/#stack=flow_nfct/g" | |
conf_string_geo="/^stack=geo_log:NFLOG.*geo_json:JSON/s/^/#/g" | |
fi | |
if ! is_high_performance_model; then | |
conf_string_ct="" | |
fi | |
if is_low_performance_model; then | |
conf_string_geo="" | |
fi | |
sed -e "$conf_string_log" \ | |
${conf_string_ct:+-e "$conf_string_ct"} \ | |
${conf_string_geo:+-e "$conf_string_geo"} \ | |
/etc/ulogd.conf > /tmp/ulogd.conf.tmp | |
mv /tmp/ulogd.conf.tmp /etc/ulogd.conf | |
systemctl restart ulogd2 | |
} | |
get_virtual_meminfo(){ | |
local fields="VmSize VmRSS VmSwap" | |
local field_count=$(echo $fields | wc -w) | |
local title="cmdline,comm,pid,ppid,$(echo "$fields" | sed 's/ /,/g')" | |
local file_payload=$(mktemp /tmp/tmp_file_XXXXXX) file_cmdlines=$(mktemp /tmp/tmp_file_XXXXXX) | |
local awk_program=' | |
/Name/ { | |
$1=""; | |
gsub(/^ /,""); | |
gsub(/ /,"_"); | |
printf "\n%s",$0 | |
} | |
/^Pid/ { | |
printf " %d",$2 | |
} | |
/^PPid/ { | |
printf " %d",$2 | |
} | |
$1 ~ fields { | |
printf " %d",$2/1024 | |
}' | |
local status=$(for file in /proc/*/status; do cat $file; done 2>/dev/null | awk -v fields=$(echo "$fields" | sed 's/ /|/g') "$awk_program") | |
local payload="$(echo "$status" | sed '1d' | sort -r -k 4 -n | awk 'BEGIN{OFS=",";} {FS=" "} $4 >= 0 {print $1,$2,$3,$4,$5,$6}')" | |
echo "$payload" > $file_payload | |
local pid="$(echo "$payload" | awk 'BEGIN{FS=","} {print $2}')" | |
local cmdline="" | |
local cmdlines=$(echo "$pid" | | |
while read -r pids; | |
do | |
cmdline="$(cat /proc/$pids/cmdline 2>/dev/null)" | |
if [ $? -eq 0 ]; then | |
echo "$cmdline" | |
fi | |
done) | |
echo "$cmdlines" | sed 's/,/-/g' > $file_cmdlines | |
payload=$(paste -d "," $file_cmdlines $file_payload) | |
rm -f $file_payload $file_cmdlines | |
echo "$title\n$payload" | |
} | |
gather_memory_trend() { | |
local budget="$1" | |
local output="$2" | |
local meminfo="$(awk '{print $1,$2}' /proc/meminfo | sed 's/: /,/g')" | |
local vmem_info="$(get_virtual_meminfo)" | |
if [ ! -f "$BOOT_TIMESTAMP_FILE" ]; then | |
echo "$(($(date +%s) - $(cut -f1 -d. /proc/uptime)))" > "$BOOT_TIMESTAMP_FILE" | |
fi | |
local date_info="$(printf "timestamp,%s,%s" "$(date "+%Y%m%d%H%M%S" --date=@$(cat "$BOOT_TIMESTAMP_FILE"))" "$(date '+%Y%m%d%H%M%S')")" | |
if [ -f "$output" ]; then | |
local first_record_last_line=$(($(grep -n timestamp "$output" | sed '1d' | head -n 1 | cut -d ":" -f 1)-1)) | |
echo "first_record_last_line: $first_record_last_line" | |
if [ "$(grep -c timestamp "$output")" -ge "$budget" ]; then | |
sed -i "1,${first_record_last_line}d" "$output" | |
fi | |
fi | |
printf "%s\n%s\n%s\n\n" "$date_info" "$meminfo" "$vmem_info" >> "$output" | |
} | |
do_hwaccel() { | |
case "$SYSID-$1" in | |
eccc-) | |
[ "`lsmod | grep mtkhnat`" = "" ] && echo "Off" || echo "On" | |
;; | |
eccc-on) | |
modprobe mtkhnat | |
;; | |
eccc-off) | |
modprobe -r mtkhnat | |
;; | |
a667-|a677-|a678-|a69a-|a69b-|a690-|a6aa-|a67a-|a6a8-) | |
[ "`lsmod | grep ecm`" = "" ] && echo "Off" || echo "On" | |
;; | |
a667-on|a677-on|a69b-on|a678-on|a69a-on|a690-on|a6aa-on|a67a-on|a6a8-on) | |
[ "`lsmod | grep ecm`" = "" ] && systemctl restart qca-nss-ecm | |
;; | |
a667-off|a677-off|a69b-off|a678-off|a69a-off|a690-off|a6aa-off|a67a-off|a6a8-off) | |
systemctl stop qca-nss-ecm | |
;; | |
eccc-*|a667-*|a677-*|a678-*|a69a-*|a69b-*|a67a-*|a6a8-*) | |
echo "Usage: $0 hwaccel [on|off]" | |
;; | |
*) | |
echo "Unsupported platform: $SYSID" | |
;; | |
esac | |
} | |
do_qos_netflow_checking() { | |
CFG_PATH=/tmp/udapi.cfg | |
OFFLD=true | |
if jq -e '.qos.global.connectivity[]? | select(.downloadSpeed != null or .uploadSpeed != null)' $CFG_PATH > /dev/null 2>&1; then | |
OFFLD=false | |
if [ "$SYSID" = "a667" ] || [ "$SYSID" = "a677" ]; then | |
# For ipq5018, support the nss version to do traffic control, so don't need to stop qca-nss-ecm when enable smart queue feature | |
if jq -e '.qos.global.connectivity[]? | select(.interfaceID | (startswith("eth") and (contains(".") | not)))' $CFG_PATH > /dev/null 2>&1; then | |
# only eth interfaces are supported; pppoe and vlans are not supported | |
OFFLD=true | |
fi | |
if jq -e '.qos.fw.queues[]? | select(length > 0)' $CFG_PATH > /dev/null 2>&1; then | |
# offloading cannot be enabled if a traffic rule exists | |
OFFLD=false | |
fi | |
fi | |
elif [ "`grep maxspeed /tmp/system.cfg`" != "" -o "`grep downloadSpeed $CFG_PATH`" != "" ]; then | |
OFFLD=false | |
elif [ "`jq -e '.services.flowAccounting | select(.enabled == true)' $CFG_PATH > /dev/null && echo true`" ]; then | |
if [ "$SYSID" = "a667" ] || [ "$SYSID" = "a677" ]; then | |
# For ipq5018, support of the netflow is disabled | |
OFFLD=true | |
else | |
OFFLD=false | |
fi | |
else | |
OFFLD=true | |
fi | |
if [ "$OFFLD" = true ] ; then | |
do_hwaccel on | |
else | |
do_hwaccel off | |
fi | |
} | |
# Send request inform to get the GeoIP DB update info then updating the DB. | |
do_geoip_req_inform() { | |
mca-ctrl -t req-inform -r geo-ip-update | |
} | |
do_geoip_update() { | |
local platform="${1}" | |
local new_db_md5="${2}" | |
local dl_url="${3}" | |
if [ "${platform}" = "udm-v1" ]; then | |
local dst_dir="/usr/share/xt_geoip" | |
elif [ "${platform}" = "udm-v2" ]; then | |
local dst_dir="/usr/share/dpi/geoip/" | |
else | |
echo "Unsupport geoip platform: ${platform}" | |
return | |
fi | |
${GEOIP_DB_SCRIPT_PATH} "${dst_dir}" "${platform}" "${new_db_md5}" "${dl_url}" | |
} | |
do_relay_restart_action() { | |
# currently this will turn off/on on all outlets | |
# turn off AC relay | |
state_lock | |
ubios-udapi-client put -r /peripherals "$(ubios-udapi-client get -r /peripherals | jq '.acOutlets[].relayState=false')" | |
sleep ${1} | |
# turn on AC relay | |
ubios-udapi-client put -r /peripherals "$(ubios-udapi-client get -r /peripherals | jq '.acOutlets[].relayState=true')" | |
state_unlock | |
} | |
do_relay_ctl() { | |
local relaytime="${1:-5}" | |
do_relay_restart_action "${relaytime}" & | |
} | |
is_low_performance_model() { | |
# a667: UX, a677: UXGLT | |
if [ "$SYSID" = "a667" ] || [ "$SYSID" = "a677" ]; then | |
return 0 | |
fi | |
return 1 | |
} | |
is_high_performance_model() { | |
# ea3d: UDMENT, ea3e: UXGENT | |
if [ "$SYSID" = "ea3d" ] || [ "$SYSID" = "ea3e" ]; then | |
return 0 | |
fi | |
return 1 | |
} | |
upload_support_file_err() { | |
local curl_err_code=$1 | |
local http_code=$2 | |
ubntbox trace -n 'unifi:network:firmware:event' -t 'anomaly' "{ | |
\"reason\": \"system\", | |
\"anomaly\": \"upload support file failed\", | |
\"curl_rc\": \"${curl_err_code}\", | |
\"http_code\": \"${http_code}\", | |
\"ppid_cmdline\": \"$(ppid_cmdline)\" | |
}" | |
} | |
get_support_file() { | |
[ $# -eq 3 ] || return 1 | |
local token="$1" | |
local pinned_cert="$2" | |
local upload_url="$3" | |
local support_dir=$(mktemp -d /tmp/support-XXXXXXXXXX) | |
local support_file="${support_dir}.tgz" | |
ubnt-systool support "${support_dir}" | |
tar -C "${support_dir}" -czf "${support_file}" . | |
rm -rf "${support_dir}" | |
local http_code=$(curl \ | |
--insecure \ | |
-w '%{http_code}' \ | |
--form "file=@${support_file}" \ | |
-H "Authorization: Bearer ${token}" \ | |
--pinnedpubkey "${pinned_cert}" \ | |
"${upload_url}") | |
local rc=$? | |
rm -f "${support_file}" | |
if [ "${rc}" = "0" -a "${http_code}" = "200" ]; then | |
return 0 | |
fi | |
if [ "${rc}" -ne 0 ] || [ "${http_code}" -ne 204 ]; then | |
echo "Failed to upload support file. Http code: ${http_code}, rc: ${rc}" | |
upload_support_file_err "${rc}" "${http_code}" | |
return 1 | |
fi | |
} | |
is_ipv4() { | |
local address="$1" | |
echo "$address" | grep -E -q '^([0-9]{1,3}\.){3}[0-9]{1,3}$' | |
} | |
wan_arp_poll() { | |
local if_table_json=$(mca-dump | jq -r '.if_table[]') | |
local if_list=$(echo "$if_table_json" | jq -r 'select(.comment and (.comment | |
| startswith("WAN")) and .name and (.name | |
| startswith("eth"))) | .name' | paste -sd "," -) | |
if [ -z $if_list ]; then | |
exit 0 | |
fi | |
IFS=',' | |
for iface in $if_list; do | |
local gw_list=$(echo "$if_table_json" | jq -r 'select(.name == "'$iface'" and .gateways) | .gateways[]' | paste -sd "," -) | |
if [ -z "$gw_list" ]; then | |
continue | |
fi | |
for gw in $gw_list; do | |
if is_ipv4 "$gw"; then | |
$ARPING -c 1 "$gw" > /dev/null | |
break | |
fi | |
done | |
done | |
} | |
err() { | |
local rc msg | |
rc=$1 | |
shift | |
msg=$* | |
>&2 echo "ERROR: ${msg}" | |
exit ${rc} | |
} | |
pcap_alert() { | |
local event="$1" | |
local rc="$2" | |
local msg="pcap-$event: $3" | |
mca-custom-alert.sh \ | |
-k "event_string" -v "pcap-$event" \ | |
-k "rc" -v "$rc" \ | |
-k "reason" -v "$msg" | |
if [ "$rc" -ne 0 ]; then | |
err "$rc" "$msg" | |
fi | |
} | |
pcap_start() { | |
local duration=$(echo "$1" | sed 's/[^0-9]//g') | |
local upload_url="$2" | |
local auth_token="$3" | |
local target_interfaces="$(echo "$4" | tr "," "\n")" | |
local max_size=$(echo "$5" | sed 's/[^0-9]//g') | |
local filter_parameters="${6}" | |
local pcap_dir="/tmp/pcap" | |
local pcap_archive="$pcap_dir.tar.gz" | |
local http_code rc | |
local ifname | |
local count=0 | |
local size_arg=1 | |
local valid_interfaces="" | |
[ $# -lt 5 ] && pcap_alert "start" 1 "too few arguments" | |
[ -z "$duration" ] && pcap_alert "start" 2 "<duration> required" | |
[ -z "$upload_url" ] && pcap_alert "start" 3 "<upload_url> required" | |
[ -z "$auth_token" ] && pcap_alert "start" 4 "<auth_token> required" | |
[ -z "$target_interfaces" ] && pcap_alert "start" 5 "<target_interfaces> required" | |
[ -z "$max_size" ] && pcap_alert "start" 6 "<max_size> required" | |
pidof tcpdump && pcap_alert "start" 7 "packet capture already running" | |
for ifname in $target_interfaces; do | |
if [ -d "/sys/class/net/$ifname" ]; then | |
count=$((count + 1)) | |
valid_interfaces="$valid_interfaces $ifname" | |
else | |
log "[warning] pcap_start: wrong ifname: $ifname" | |
fi | |
done | |
[ "$count" -lt 1 ] && pcap_alert "start" 9 "no valid interfaces" | |
max_size=$((max_size / 1024 / count)) | |
[ "$max_size" -gt 1 ] && size_arg=$max_size | |
required_space=$((size_arg * 1024 * count)) | |
mkdir -p "$pcap_dir" || pcap_alert "start" 10 "failed to create pcap directory" | |
df_output=$(df "$pcap_dir") | |
if [ $? -ne 0 ]; then | |
rm -rf "$pcap_dir" | |
pcap_alert "start" 8 "failed to check disk space" | |
fi | |
total_space=$(echo "$df_output" | awk 'NR==2 {print $2}') | |
used_space=$(echo "$df_output" | awk 'NR==2 {print $3}') | |
threshold_space=$(( total_space * 95 / 100 )) | |
if [ $((required_space + used_space)) -gt $threshold_space ]; then | |
rm -rf "$pcap_dir" | |
pcap_alert "start" 11 "required max. capture size exceeds available space" | |
fi | |
for ifname in $valid_interfaces; do | |
timeout -s KILL "$duration" \ | |
tcpdump -i "$ifname" \ | |
-w "$pcap_dir/$ifname.pcap" \ | |
-C $size_arg \ | |
-W 1 \ | |
"$filter_parameters"\ | |
-Z root \ | |
2>/dev/null & | |
echo $! > "$pcap_dir/$ifname.pid" | |
done | |
pcap_alert "start" 0 "capture started" | |
wait | |
pcap_alert "done" 0 "capture finished" | |
rm "$pcap_dir"/*.pid 2>/dev/null | |
tar -czf "$pcap_archive" -C "$pcap_dir" . || { | |
rm -rf "$pcap_dir" | |
pcap_alert "upload" 20 "failed to compress" | |
} | |
http_code=$(curl \ | |
--insecure \ | |
-w '%{http_code}' \ | |
--form "file=@$pcap_archive" \ | |
-H "Authorization: Bearer $auth_token" \ | |
"$upload_url") | |
rc=$? | |
wait | |
rm -rf "$pcap_dir" | |
rm "$pcap_archive" | |
pcap_alert "upload" "$rc" "finished with http code $http_code" | |
[ "$rc" -eq 0 ] || [ "$http_code" -eq 200 ] | |
} | |
pcap_stop() { | |
local pcap_dir="/tmp/pcap" | |
for pid_file in "$pcap_dir"/*.pid; do | |
kill "$(cat "$pid_file")" | |
done | |
} | |
has_stp_on_uplink_bridge() { | |
local status=$(grep "^connectivity.status=" "$SYSTEM_CFG" | cut -d'=' -f2) | |
local uplink_bridge=$(grep "^connectivity.uplink_bridge=" "$SYSTEM_CFG" | cut -d'=' -f2) | |
local stplog="/var/log/sniffer.log" | |
if [ "$status" = "enabled" ]; then | |
rm -rf $stplog | |
timeout 5 tcpdump -i $uplink_bridge llc > $stplog 2>/dev/null | |
cat $stplog | grep -E "802.1d" > /dev/null | |
exit $? | |
fi | |
} | |
case "$cmd" in | |
enter-isolated) | |
if command -v renew_all_ips > /dev/null 2>&1; then | |
renew_all_ips | |
fi | |
;; | |
soft-restart) | |
exit_if_busy $cmd $* | |
state_lock | |
/usr/share/ubntconf/ubntconf restart | |
do_performance | |
state_reload | |
state_unlock | |
;; | |
apply-config) | |
# apply-config | |
exit_if_busy $cmd $* | |
state_lock | |
cfg_save | |
if ! do_fast_apply; then | |
if ! skip_apply; then | |
/usr/share/ubntconf/ubntconf restart | |
do_performance | |
fi | |
fi | |
state_reload | |
state_unlock | |
;; | |
save-config) | |
state_lock | |
cfg_save | |
led_reload | |
state_unlock | |
;; | |
reload) | |
exit_if_busy $cmd $* | |
exit_if_state_lock_failed $cmd $* | |
state_reload | |
state_unlock | |
;; | |
set-ready) | |
# called by mcagent | |
state_lock | |
set_state_reload ready | |
state_unlock | |
;; | |
speed-test) | |
if [ -z "$1" ]; then | |
rm -f "$LINKCHECK_CONFIG_FOLDER/source-interface" | |
else | |
echo "$1" > "$LINKCHECK_CONFIG_FOLDER/source-interface" | |
fi | |
systemctl kill -s SIGUSR1 linkcheck | |
;; | |
if-up-event) | |
# if-up-event <interface> | |
ifname=$1 | |
if [ -f /var/run/if_up_hook.$ifname ]; then | |
/bin/sh /var/run/if_up_hook.$ifname | |
fi | |
;; | |
set-uboot-var) | |
if command -v set_uboot_var > /dev/null 2>&1; then | |
set_uboot_var "$@" | |
fi | |
;; | |
scan-rrm) | |
is_wds | |
[ "$?" = "1" ] && scan_rrm $@ | |
;; | |
scan-rrm-check) | |
is_wds | |
[ "$?" = "1" ] && scan_rrm_check | |
;; | |
spectrum-scan) | |
exit_if_busy $cmd $* | |
spectrum_scan $@ | |
;; | |
spectrum-scan-clean) | |
exit_if_busy $cmd $* | |
;; | |
spectrum-scan-qca-done) | |
exit_if_busy $cmd $* | |
spectrum_scan_done $@ | |
;; | |
kick-sta) | |
exit_if_fake $cmd $* | |
kick_sta $1 | |
;; | |
kick-sta-on) | |
exit_if_fake $cmd $* | |
kick_sta_on $2 $1 $3 | |
;; | |
block-sta) | |
exit_if_fake $cmd $* | |
driver_kick_block_sta $1 | |
add_mac ${PERSISTENT_DATA_PATH}/blocked_sta "$1" | |
#state_lock | |
#cfg_save | |
#state_unlock | |
;; | |
unblock-sta) | |
exit_if_fake $cmd $* | |
del_mac ${PERSISTENT_DATA_PATH}/blocked_sta "$1" | |
driver_unblock_sta $1 | |
#state_lock$ | |
#cfg_save | |
#state_unlock | |
;; | |
apply-blocked-sta) | |
driver_apply_blocklist | |
;; | |
apply-blocked-sta-ifup) | |
driver_apply_blocklist_ifup $1 | |
;; | |
handle-dyn) | |
exit_if_fake $cmd $* | |
handle_dyn "$@" | |
;; | |
set-element-payload) | |
systemctl kill -s SIGUSR1 element-adopt-monitor@* | |
;; | |
unset-element-payload) | |
systemctl kill -s SIGUSR2 element-adopt-monitor@* | |
;; | |
set-meshv3-payload) | |
systemctl kill -s SIGUSR1 mesh-monitor@* | |
;; | |
unset-meshv3-payload) | |
systemctl kill -s SIGUSR2 mesh-monitor@* | |
;; | |
dump-isolation-log) | |
# Do not dump isolation logs just after uplink-monitor restart as they are expected | |
if [ `expr $(date +%s) - $(stat -c %Y /proc/$(pidof uplink-monitor))` -gt 90 ]; then | |
if [ -f "/etc/first_setup_completed" ]; then | |
dump_syslog_to_persistent "$@" | |
fi | |
# save done by uplink-monitor | |
fi | |
;; | |
set-eth-discover) | |
interface="" | |
type="" | |
remote_ip="" | |
netapp_id="" | |
while [ -n "$1" ]; do | |
case "$1" in | |
-i) | |
shift | |
interface="$1" | |
;; | |
-r) | |
shift | |
remote_ip="$1" | |
;; | |
-u) | |
shift | |
netapp_id="$1" | |
;; | |
-t) | |
shift | |
type="$1" | |
;; | |
*) | |
echo "Unknown option: $1" | |
;; | |
esac | |
shift | |
done | |
if ! safe_call "check_wan_adoption_eligibility"; then | |
log "ETH Adoption: device isn't eligible for adoption" | |
exit $? | |
fi | |
# Found UniFi console from ethernet. | |
# Update the timestamp to let LCM show correct status. | |
date +%s > ${NEARBY_CTRLER_LAST_SEEN_FILE}.${type} | |
if [ "$type" = "lan" ]; then | |
if [ -f "/etc/meshmode.conf" ] && ! grep -q "eth_adoption" /etc/meshmode.conf; then | |
log "ETH Adoption: adoption is already in progress" | |
exit $? | |
fi | |
fi | |
beaconing=$(awk 'NR==1 {print; exit}' /var/run/adopt.eth.beaconing 2>/dev/null) | |
prev_interface=$(cat /var/run/adopt.eth.interface 2>/dev/null) | |
prev_remote_ip=$(cat /var/run/adopt.eth.ip 2>/dev/null) | |
if [ "$beaconing" != "enabled" ]; then | |
echo "$interface" > /var/run/adopt.eth.interface | |
echo "$remote_ip" > /var/run/adopt.eth.ip | |
echo "$netapp_id" > /var/run/adopt.eth.netapp_id | |
echo "$type" > /var/run/adopt.eth.type | |
safe_call "network_subnet_check_and_reconf" "br0" "$interface" "$remote_ip" | |
mca-ctrl -t eth-discover -a on -i "$interface" -R "$remote_ip" -T "$type" | |
elif [ "$interface" != "$prev_interface" ] || [ "$remote_ip" != "$prev_remote_ip" ]; then | |
mca-ctrl -t eth-discover -a off | |
echo "$interface" > /var/run/adopt.eth.interface | |
echo "$remote_ip" > /var/run/adopt.eth.ip | |
echo "$netapp_id" > /var/run/adopt.eth.netapp_id | |
echo "$type" > /var/run/adopt.eth.type | |
safe_call "network_subnet_check_and_reconf" "br0" "$interface" "$remote_ip" | |
mca-ctrl -t eth-discover -a on -i "$interface" -R "$remote_ip" -T "$type" | |
else | |
log "ETH Adoption: beaconing already active one the same interface $interface" | |
fi | |
;; | |
ssh-adopt) | |
ip=$1 | |
sdn_ip=`ifconfig br0| sed -n 's/.*inet addr:\([0-9.]\+\)\s.*/\1/p'` | |
url=http://$sdn_ip:8080/inform | |
# use the most ordinary form to set-inform | |
DROPBEAR_PASSWORD=ubnt ssh ubnt@$ip -y mca-ctrl -t connect -s $url | |
;; | |
dhclient-renew-subnet) | |
if command -v renew_ip_on_subnet_change > /dev/null 2>&1; then | |
renew_ip_on_subnet_change "$@" | |
fi | |
;; | |
dhclient-renew-dhcprange) | |
if command -v renew_ip_on_dhcp_range_change > /dev/null 2>&1; then | |
renew_ip_on_dhcp_range_change "$@" | |
fi | |
;; | |
set-locate) | |
exit_if_busy $cmd $* | |
echo "true" > ${IsLocated} | |
set_lcm_command "locate" "enable" | |
set_led_state "locate" | |
;; | |
unset-locate) | |
exit_if_busy $cmd $* | |
echo "false" > ${IsLocated} | |
set_lcm_command "locate" "disable" | |
led_reload | |
;; | |
lcm-tracker) | |
set_lcm_command "ar" "$1" | |
;; | |
restart) | |
exit_if_busy $cmd $* | |
set_ubnt_systool "reboot $@" | |
;; | |
redirector-init) | |
exit_if_fake $cmd $* | |
guest_redirector_init_iptables "$@" | |
;; | |
redirector-deinit) | |
exit_if_fake $cmd $* | |
guest_redirector_deinit_iptables "$@" | |
;; | |
authorize-guest) | |
exit_if_fake $cmd $* | |
guest_authorize "$@" | |
;; | |
unauthorize-guest) | |
exit_if_fake $cmd $* | |
guest_unauthorize "$@" | |
kick_sta $1 | |
;; | |
apply-authorized-guests) | |
exit_if_fake $cmd $* | |
guest_authorized_reload "$@" | |
;; | |
clear-authorized-guests) | |
exit_if_fake $cmd $* | |
guest_authorized_flush "$@" | |
;; | |
lcm-sync) | |
#src_mac="$1" | |
#screen="$2" | |
#timestamp="$3" | |
set_lcm_command "screen" "$2" | |
;; | |
schedule-action) | |
schedule_action | |
;; | |
ufn_connection_trace) | |
do_ufn_connection_trace $@ | |
;; | |
udapi-request-trace) | |
do_udapi_request_trace "$@" | |
;; | |
teleport-connect) | |
do_teleport_call $1 PUT client/$2 "$3" | |
;; | |
teleport-disconnect) | |
do_teleport_call $1 DELETE client/$2 | |
;; | |
set-adopt) | |
url="$1" | |
authkey="$2" | |
if [ -f "$WAN_ADOPT_IP_FILE" ] && [ ! -f "/etc/meshmode.conf" ]; then | |
log "ETH Adoption: initiating device adoption via Ethernet port" | |
# Create a flag to indicate that device is transforming into mesh | |
echo "eth_adoption" > /etc/meshmode.conf | |
# Notify the LCM daemon about the device mode change | |
lcm-control --command mesh --sender mesh-tool | |
# Mark reset to defaults just in case | |
safe_call "reset_to_defaults" "mark" | |
# Clean-up service set and change default target | |
systemctl set-default sysready-mesh.target | |
systemctl isolate sysready-mesh.target | |
# Set new inform url and let mcagent reprovision the device | |
mca-ctrl -t connect -s "$url" -k "$authkey" | |
# Refresh SSHD to apply any potential changes | |
systemctl restart device-ssh | |
log "Device adoption completed successfully" | |
echo "change_mesh_done" > /etc/meshmode.conf | |
# Remove reset to defaults mark due to successful adoption | |
safe_call "reset_to_defaults" "unmark" | |
else | |
mca-ctrl -t connect -s "$url" -k "$authkey" | |
fi | |
;; | |
restore-default) | |
reason="${1:-unknown}" | |
exit_if_fake $cmd $* | |
exit_if_busy $cmd $* | |
# When the performance of the device is too low, | |
# there will be a very long delay between triggering the reset to default and the screen change. | |
# So we will implement a workaround here to change the screen earlier. | |
is_low_performance_model && set_lcm_command "reset" | |
ubnt-systool reset2defaults | |
;; | |
relayctl) | |
do_relay_ctl "$@" | |
;; | |
del-bridge-vlans) | |
del_bridge_vlans "$@" | |
;; | |
power-cycle) | |
exit_if_busy $cmd $* | |
do_power_cycle $* | |
;; | |
fw-triggers-restart-ulogd) | |
fw_triggers_restart_ulogd "$@" | |
;; | |
gather-mem-info) | |
gather_memory_trend "$@" | |
;; | |
qos-netflow-checking) | |
do_qos_netflow_checking | |
;; | |
hwaccel) | |
do_hwaccel "$@" | |
;; | |
system-led-idle) | |
exit_if_busy $cmd $* | |
state_lock | |
state_reload | |
led_reload | |
state_unlock | |
;; | |
geoip-req-inform) | |
do_geoip_req_inform | |
;; | |
geoip-update) | |
do_geoip_update "$@" | |
;; | |
set-24G-scan) | |
if command -v set_24G_scan > /dev/null 2>&1; then | |
set_24G_scan "$@" | |
fi | |
;; | |
unset-24G-scan) | |
if command -v unset_24G_scan > /dev/null 2>&1; then | |
unset_24G_scan "$@" | |
fi | |
;; | |
mesh-halt) | |
if [ `cat ${UPLINK_FILE}` = "eth" ]; then | |
log "halt mesh status only on uplink is eth case" | |
mca-cli-op mesh-halt "$1" | |
fi | |
;; | |
upgrade-ready) | |
upgrade_ready "FWCheckOK" | |
cat /proc/uptime > /var/run/download_firmware.finished | |
mca-cli-op inform | |
;; | |
notify-wifi-ready) | |
if [ "$(grep hwaddrbbase ${BOARD_FILE} | cut -d '=' -f2)" = "$@" ] && [ -f "/etc/first_setup_completed" ] && [ ! -f "/etc/first_wifi_setup_ready" ]; then | |
touch /etc/first_wifi_setup_ready | |
wifi_status "WiFiReady" | |
mca-cli-op inform | |
fi | |
;; | |
wireless-vlan-add) | |
guest_update_interface_ebtables add "$1" | |
;; | |
wireless-vlan-del) | |
guest_update_interface_ebtables del "$1" | |
;; | |
get-support-file) | |
get_support_file "$@" | |
;; | |
wan-arp-poll) | |
wan_arp_poll "$@" | |
;; | |
pcap-start) | |
pcap_start "$@" | |
;; | |
pcap-stop) | |
pcap_stop | |
;; | |
has_stp_on_uplink_bridge) | |
has_stp_on_uplink_bridge | |
;; | |
esac | |
root@EFG:/usr/bin# cat syswrapper.sh | grep set-inform | |
# use the most ordinary form to set-inform | |
root@EFG:/usr/bin# cat syswrapper.sh | grep set-inform -B 10 -A 30 | |
safe_call "network_subnet_check_and_reconf" "br0" "$interface" "$remote_ip" | |
mca-ctrl -t eth-discover -a on -i "$interface" -R "$remote_ip" -T "$type" | |
else | |
log "ETH Adoption: beaconing already active one the same interface $interface" | |
fi | |
;; | |
ssh-adopt) | |
ip=$1 | |
sdn_ip=`ifconfig br0| sed -n 's/.*inet addr:\([0-9.]\+\)\s.*/\1/p'` | |
url=http://$sdn_ip:8080/inform | |
# use the most ordinary form to set-inform | |
DROPBEAR_PASSWORD=ubnt ssh ubnt@$ip -y mca-ctrl -t connect -s $url | |
;; | |
dhclient-renew-subnet) | |
if command -v renew_ip_on_subnet_change > /dev/null 2>&1; then | |
renew_ip_on_subnet_change "$@" | |
fi | |
;; | |
dhclient-renew-dhcprange) | |
if command -v renew_ip_on_dhcp_range_change > /dev/null 2>&1; then | |
renew_ip_on_dhcp_range_change "$@" | |
fi | |
;; | |
set-locate) | |
exit_if_busy $cmd $* | |
echo "true" > ${IsLocated} | |
set_lcm_command "locate" "enable" | |
set_led_state "locate" | |
;; | |
unset-locate) | |
exit_if_busy $cmd $* | |
echo "false" > ${IsLocated} | |
set_lcm_command "locate" "disable" | |
led_reload | |
;; | |
lcm-tracker) | |
set_lcm_command "ar" "$1" | |
;; | |
restart) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment