#!/bin/sh . /lib/functions.sh . /usr/share/libubox/jshn.sh NMTMPDIR=/var/netmodes OLD_MODE_FILE=/var/netmodes/old_mode CONF_BACKUP_DIR=/var/netmodes/backup/ SWITCHMODELOCK="/tmp/switching_mode" MODEDIR=$(uci -q get netmode.setup.dir) MTK=0 opkg list-installed | grep -q kmod-mt.*mtk && MTK=1 [ -n "$MODEDIR" ] || MODEDIR="/etc/netmodes" toggle_firewall() { local section=$1 local disable=$2 config_get name "$1" name if [ "$name" == "wan" ]; then uci -q set firewall.settings.disabled=$disable if [ "$disable" == "1" ]; then uci -q set firewall.$section.input="ACCEPT" else uci -q set firewall.$section.input="REJECT" fi uci -q commit firewall fi } disable_firewall() { config_load firewall config_foreach toggle_firewall zone $1 /etc/init.d/firewall reload } is_known_macaddr() { macaddr=$1 echo $macaddr | grep -i -e "^00:22:07" \ -e "^02:22:07" \ -e "^44:D4:37" \ -e "^00:0C:07" \ -e "^02:0C:07" \ -e "^06:0C:07" \ -e "^00:0C:43" \ -e "^02:0C:43" \ -e "^06:0C:43" \ && return false } get_wifi_wet_interface() { local ifname="" handle_interface() { [ -n "$ifname" ] && return config_get mode "$1" mode if [ "$mode" == "sta" -o "$mode" == "wet" ]; then config_get ifname "$1" ifname fi } config_load wireless config_foreach handle_interface wifi-iface echo "$ifname" } get_wifi_iface_cfgstr() { get_cfgno() { config_get ifname "$1" ifname [ "$ifname" == "$2" ] && echo "wireless.$1" } config_load wireless config_foreach get_cfgno wifi-iface $1 } correct_uplink() { local IFACE="$1" local WANDEV="$(db -q get hw.board.ethernetWanPort)" local WETIF="$(get_wifi_wet_interface)" local link wetcfg wetnet wetmac [ $MTK -eq 1 ] || WANDEV="$WANDEV.1" [ -n "$IFACE" -a "$IFACE" != "$WANDEV" -a "$IFACE" != "$WETIF" ] && return link=$(cat /sys/class/net/${WANDEV:0:4}/operstate) [ $MTK -eq 1 ] && link=$(swconfig dev switch0 port 0 get link | awk '{print$2}' | cut -d':' -f2) if [ ! -f /tmp/netmodes/uplink-macaddr-corrected ]; then wetcfg="$(get_wifi_iface_cfgstr $WETIF)" wetnet="$(uci -q get $wetcfg.network)" wetmac="$(ifconfig $WETIF | grep HWaddr | awk '{print$NF}')" ethwanmac="$(ifconfig $WANDEV | grep HWaddr | awk '{print$NF}')" if [ -d /sys/class/net/br-$wetnet ]; then if [ "$link" == "up" ]; then ifconfig br-$wetnet hw ether $ethwanmac else ifconfig br-$wetnet hw ether $wetmac fi #touch -f /tmp/netmodes/uplink-macaddr-corrected fi fi if [ "$link" == "up" ]; then ubus call network.device set_state "{\"name\":\"$WETIF\", \"defer\":true}" ifconfig $WETIF down echo ethernet > /tmp/netmodes/uplink_type ubus call network.device set_state "{\"name\":\"$WANDEV\", \"defer\":false}" else ubus call network.device set_state "{\"name\":\"$WETIF\", \"defer\":false}" ifconfig $WETIF up echo wireless > /tmp/netmodes/uplink_type ubus call network.device set_state "{\"name\":\"$WANDEV\", \"defer\":true}" ubus call led.internet set '{"state" : "notice"}' fi } run_netmode_scripts() { local mode=$1 local when=$2 local script if [ -d /etc/netmodes/$mode/scripts/$when ]; then logger -s -p user.info -t $0 "[netmode] Executing $when netmode scripts" >/dev/console for script in $(ls /etc/netmodes/$mode/scripts/$when/); do sh /etc/netmodes/$mode/scripts/$when/$script done fi } switch_netmode() { local newmode="$1" [ -f /etc/config/netmode -a -d $MODEDIR ] || return [ -n "$newmode" ] && uci -q set netmode.setup.curmode="$newmode" local curmode conf old_mode # NETMODE CONFIG # config_load netmode config_get curmode setup curmode uci -q set netmode.setup.repeaterready="0" # set default JUCI page to overview uci -q set juci.juci.homepage="overview" uci commit juci if [ "$curmode" == "repeater" ]; then if [ $MTK -eq 1 ]; then curmode="repeater_mtk_5g_up_dual_down" else curmode="repeater_brcm_2g_up_dual_down" fi uci set netmode.setup.curmode="$curmode" fi if [ "$curmode" == "routed" ]; then if [ $MTK -eq 1 ]; then curmode="routed_mtk" else curmode="routed_brcm" fi uci set netmode.setup.curmode="$curmode" fi uci commit netmode # end of NETMODE CONFIG # old_mode="$(cat $OLD_MODE_FILE 2>/dev/null)" # if curmode has not changed do not copy configs if [ "$curmode" == "$old_mode" ]; then /etc/init.d/environment reload return fi echo $curmode >$OLD_MODE_FILE [ -d "/etc/netmodes/$curmode" ] || return run_netmode_scripts $curmode "pre" # make backup of current config before switching rm -rf $CONF_BACKUP_DIR mkdir -p $CONF_BACKUP_DIR cp -af /etc/config/* $CONF_BACKUP_DIR logger -s -p user.info -t $0 "[netmode] Copying /etc/netmodes/$curmode in /etc/config" >/dev/console for file in $(ls /etc/netmodes/$curmode/); do case "$file" in DETAILS|scripts) continue ;; esac cp /etc/netmodes/$curmode/$file /etc/config/ done sync #commit owsd to reload all init.d scripts dependent on its config ubus call uci commit '{"config":"owsd"}' local reboot=$(uci -q get netmode.$curmode.reboot) if [ "$reboot" != "0" ]; then run_netmode_scripts $curmode "post" reboot & exit fi /etc/init.d/environment reload case "$curmode" in repeater*) touch $SWITCHMODELOCK logger -s -p user.info -t $0 "Switching to $curmode mode" > /dev/console ubus call leds set '{"state" : "allflash"}' [ -f /etc/init.d/omcproxy ] && /etc/init.d/omcproxy stop [ -f /etc/init.d/igmpproxy ] && /etc/init.d/igmpproxy stop [ -f /etc/init.d/layer2 ] && /etc/init.d/layer2 reload ubus call network reload wifi reload nodat ubus call router.network reload rm -f /tmp/netmodes/uplink-macaddr-corrected correct_uplink ubus call leds set '{"state" : "normal"}' rm -f $SWITCHMODELOCK ;; *) [ -f /etc/init.d/layer2 ] && /etc/init.d/layer2 reload ubus call uci commit '{"config":"network"}' ;; esac run_netmode_scripts $curmode "post" } revert_netmode() { local from="$1" local to="$2" local rready="$3" ubus call leds set '{"state" : "allflash"}' echo "Could not switch to '$from' mode; going back to '$to' mode" > /dev/console uci -q set netmode.setup.curmode="$to" uci -q set netmode.setup.repeaterready="$rready" uci commit netmode cp -af $CONF_BACKUP_DIR/* /etc/config/ sync rm -rf $CONF_BACKUP_DIR rm -rf $OLD_MODE_FILE echo "Restarting network services" > /dev/console ubus call network reload wifi reload ubus call router.network reload ubus call leds set '{"state" : "normal"}' } wificontrol_takes_over() { local ret [ -f /sbin/wificontrol ] || return ubus call leds set '{"state" : "allflash"}' if pidof wificontrol >/dev/null; then ret=0 # let netmode-conf up to 20 seconds before switching mode for tm in 2 4 6 8; do if [ -f /tmp/wificontrol.txt ]; then ret=1 break fi sleep $tm done # let netmode-conf take over [ $ret -eq 1 ] && return 0 fi return 1 } wait_for_netmode_handler() { for tm in 2 4 6 8; do if [ ! -f $SWITCHMODELOCK ]; then break fi sleep $tm done } netmode_get_ip_type() { [ -n "$(echo $1 | grep -E '^(192\.168|10\.|172\.1[6789]\.|172\.2[0-9]\.|172\.3[01]\.)')" ] && { logger -t "[netmode]" "netmode_get_ip_type: ip $1 is private" echo "private" } || { logger -t "[netmode]" "netmode_get_ip_type: ip $1 is public" echo "public" } } get_device_of() { local PORT_NAMES=$(db get hw.board.ethernetPortNames) local PORT_ORDER=$(db get hw.board.ethernetPortOrder) local cnt=1 local idx=0 local pnum=$(echo $PORT_NAMES | wc -w) if [ $pnum -le 2 ]; then PORT_NAMES=$(echo $PORT_NAMES | sed 's/LAN/LAN1/g') fi # get index of interface name for i in $PORT_NAMES; do if [ "$i" == "$1" ]; then idx=$cnt fi cnt=$((cnt+1)) done # get port name from index cnt=1 for i in $PORT_ORDER; do if [ "$cnt" == "$idx" ]; then echo $i fi cnt=$((cnt+1)) done } populate_netmodes() { [ -f /etc/config/netmode -a -d $MODEDIR ] || return local curmode config_load netmode config_get curmode setup curmode mkdir -p $NMTMPDIR if [ "$curmode" == "routed" ]; then if [ $MTK -eq 1 ]; then curmode="routed_mtk" else curmode="routed_brcm" fi fi echo $curmode > $OLD_MODE_FILE delete_netmode() { uci delete netmode.$1 } config_foreach delete_netmode netmode uci commit netmode wan=$(get_device_of WAN) lan1=$(get_device_of LAN1) lan2=$(get_device_of LAN2) lan3=$(get_device_of LAN3) lan4=$(get_device_of LAN4) lan5=$(get_device_of LAN5) for file in $(find $MODEDIR -type f); do conf="$(echo $file | cut -d'/' -f5)" if [ "$conf" == "layer2_interface_ethernet" ]; then grep -q "\$WAN" $file && sed -i "s/\$WAN/$wan/g" $file fi if [ "$conf" == "network" ]; then grep -q "\$WAN" $file && sed -i "s/\$WAN/$wan/g" $file grep -q "\$LAN1" $file && sed -i "s/\$LAN1/$lan1/g" $file grep -q "\$LAN2" $file && sed -i "s/\$LAN2/$lan2/g" $file grep -q "\$LAN3" $file && sed -i "s/\$LAN3/$lan3/g" $file grep -q "\$LAN4" $file && sed -i "s/\$LAN4/$lan4/g" $file ifname="$(uci -q get $file.wan.ifname | sed 's/[ \t]*$//')" uci -q set $file.wan.ifname="$ifname" uci -q commit $file fi done local hardware=$(db get hw.board.hardware) local keys lang desc exp exclude for mode in $(ls $MODEDIR); do case "$mode" in repeater*) wlctl -i wl1 ap >/dev/null 2>&1 || ifconfig rai0 2>/dev/null | grep -q rai0 || continue ;; esac lang="" desc="" exp="" uci -q set netmode.$mode=netmode json_load "$(cat $MODEDIR/$mode/DETAILS)" if json_select excluded_boards; then exclude=0 _i=1 while json_get_var board $_i; do case "$hardware" in $board) uci -q delete netmode.$mode exclude=1 break ;; esac _i=$((_i+1)) done json_select .. [ $exclude -eq 1 ] && continue fi if json_select acl; then _i=1 while json_get_var user $_i; do uci del_list netmode.$mode._access_r="$user" uci del_list netmode.$mode._access_w="$user" uci add_list netmode.$mode._access_r="$user" uci add_list netmode.$mode._access_w="$user" _i=$((_i+1)) done json_select .. fi json_select description json_get_keys keys for k in $keys; do json_get_keys lang $k lang=$(echo $lang | sed 's/^[ \t]*//;s/[ \t]*$//') json_select $k json_get_var desc $lang uci -q set netmode.$mode."desc_$lang"="$desc" [ "$lang" == "en" ] && uci -q set netmode.$mode."desc"="$desc" json_select .. done json_select .. json_select explanation json_get_keys keys for k in $keys; do json_get_keys lang $k lang=$(echo $lang | sed 's/^[ \t]*//;s/[ \t]*$//') json_select $k json_get_var exp $lang uci -q set netmode.$mode."exp_$lang"="$exp" [ "$lang" == "en" ] && uci -q set netmode.$mode."exp"="$exp" json_select .. done json_select .. json_get_var cred credentials uci -q set netmode.$mode.askcred="$cred" json_get_var ulb uplink_band uci -q set netmode.$mode.uplink_band="$ulb" json_get_var reboot reboot uci -q set netmode.$mode.reboot="$reboot" done config_get curmode setup curmode [ -d /etc/netmodes/$curmode ] || { [ $MTK -eq 1 ] && uci -q set netmode.setup.curmode="routed_mtk" || uci -q set netmode.setup.curmode="routed_brcm" } uci commit netmode } start_netmode_tools() { local curmode repeaterready wificontrol discover killall -9 wificontrol >/dev/null 2>&1 killall -9 netmode-discover >/dev/null 2>&1 config_load netmode config_get_bool repeaterready setup repeaterready 0 config_get_bool wificontrol tools wificontrol 1 config_get_bool arp_discovery tools arp_discovery 1 [ $repeaterready -eq 1 ] && { [ $arp_discovery -eq 1 ] && /sbin/netmode-discover & [ $wificontrol -eq 1 ] && /sbin/wificontrol --repeater & return } config_get curmode setup curmode case "$curmode" in repeater*) [ $arp_discovery -eq 1 ] && /sbin/netmode-discover & [ $wificontrol -eq 1 ] && /sbin/wificontrol --repeater & ;; esac } stop_netmode_tools() { killall -9 netmode-discover >/dev/null 2>&1 killall -9 wificontrol >/dev/null 2>&1 }