#!/bin/sh # Copyright (C) 2014 Xiaomi # # $1 = opt. open/close # usage: # ap_mode.sh open/close # . /lib/functions.sh config_load misc &>/dev/null config_get cmd_bridgeap_connect switchop bridgeap_connect &>/dev/null; config_get cmd_bridgeap_open switchop bridgeap_open &>/dev/null; config_get cmd_bridgeap_close switchop bridgeap_close &>/dev/null; config_get cmd_vlan1_port ports vlan1 &>/dev/null; config_get cmd_vlan2_port ports vlan2 &>/dev/null; config_get cmd_vlan1_bridgeap_port ports vlan1_bridgeap &>/dev/null; config_get cmd_vlan2_bridgeap_port ports vlan2_bridgeap &>/dev/null; config_get cmd_ifname_2G wireless ifname_2G &>/dev/null; config_get cmd_ifname_5G wireless ifname_5G &>/dev/null; wan_device=$(uci get network.wan.ifname) [ "$wan_device" == "" ] && wan_device="eth0.2" lan_device=$(uci get network.lan.ifname) [ "$lan_device" == "" ] && lan_device="eth0.1" usage() { echo "usage:" echo " ap_mode.sh opt=open/close/check_gw" echo " example1: ap_mode.sh open" echo " example2: ap_mode.sh close" echo " example2: ap_mode.sh check_gw" } #$1 : log message bridgeap_logger() { logger -t bridgeap "$1" } bridgeap_open_r1cm() { uci -q batch <<-EOF >/dev/null #we don't to delete network.ap_mode when xq change to ap mode, backup file would cover it. #set network.ap_mode="bridgeap" set network.lan.ifname='$lan_device $wan_device $cmd_ifname_2G $cmd_ifname_5G' set network.lan.type='bridge' delete network.wan delete network.vpn commit network set dhcp.lan.ignore=1; commit network commit dhcp EOF } bridgeap_close_r1cm_default() { echo "#######################bridgeap_close_r1cm_default###############" uci -q batch <<-EOF >/dev/null delete network set network.loopback=interface set network.loopback.ifname=lo set network.loopback.proto=static set network.loopback.ipaddr=127.0.0.1 set network.loopback.netmask=255.0.0.0 set network.lan=interface set network.lan.ifname=eth0.1 set network.lan.type=bridge set network.lan.proto=static set network.lan.ipaddr=192.168.31.1 set network.lan.netmask=255.255.255.0 set network.wan=interface set network.wan.ifname=eth0.2 set network.wan.proto=dhcp commit network delete dhcp.lan.ignore; commit dhcp EOF } # #config backupfile /etc/config/.network.mode.router is create by dhcp_apclient.sh:router_config_backup() # bridgeap_close_r1cm() { local router_backup_file="/etc/config/.network.mode.router" [ ! -f "$router_backup_file" ] && bridgeap_close_r1cm_default && return; mv $router_backup_file "/etc/config/network" uci -q batch <<-EOF >/dev/null delete network.wan.auto commit network delete dhcp.lan.ignore; commit dhcp EOF } bridgeap_open_r1d() { echo "#######################bridgeap_open_r1d###############" uci -q batch <<-EOF >/dev/null set network.eth0_1.ports="$cmd_vlan1_bridgeap_port" set network.eth0_2.ports="$cmd_vlan2_bridgeap_port" delete network.wan delete network.vpn commit network set dhcp.lan.ignore=1; commit dchp EOF nvram set vlan1ports="$cmd_vlan1_bridgeap_port" nvram set vlan2ports="$cmd_vlan2_bridgeap_port" nvram set mode=AP nvram commit rmmod et insmod et } bridgeap_open_r3d() { echo "#######################bridgeap_open_r3d###############" uci -q batch <<-EOF >/dev/null delete network.wan delete network.vpn set network.lan.ifname='eth0 eth1' commit network set dhcp.lan.ignore=1; commit dchp EOF nvram set vlan1ports="$cmd_vlan1_bridgeap_port" nvram set vlan2ports="$cmd_vlan2_bridgeap_port" nvram set mode=AP nvram commit rmmod et insmod et } # #config backupfile /etc/config/.network.mode.router is create by dhcp_apclient.sh:router_config_backup() # bridgeap_close_r1d(){ echo "#######################bridgeap_close_r1d###############" local router_backup_file="/etc/config/.network.mode.router" [ ! -f "$router_backup_file" ] && bridgeap_close_r1d_default && return; mv $router_backup_file "/etc/config/network" uci -q batch <<-EOF >/dev/null delete network.wan.auto commit network delete dhcp.lan.ignore; commit dhcp EOF nvram set vlan1ports="$cmd_vlan1_port" nvram set vlan2ports="$cmd_vlan2_port" nvram set mode=Router nvram commit rmmod et insmod et } bridgeap_close_r3d(){ echo "#######################bridgeap_close_r3d###############" local router_backup_file="/etc/config/.network.mode.router" [ ! -f "$router_backup_file" ] && bridgeap_close_r1d_default && return; mv $router_backup_file "/etc/config/network" uci -q batch <<-EOF >/dev/null delete network.wan.auto commit network delete dhcp.lan.ignore; commit dhcp EOF nvram set vlan1ports="$cmd_vlan1_port" nvram set vlan2ports="$cmd_vlan2_port" nvram set mode=Router nvram commit rmmod et insmod et } bridgeap_close_r1d_default() { echo "#######################bridgeap_close_r1d_default###############" uci -q batch <<-EOF >/dev/null delete network set network.eth0=switch set network.eth0.enable=1 set network.eth0_1=switch_vlan set network.eth0_1.device=eth0 set network.eth0_1.vlan=1 set network.eth0_1.ports="$cmd_vlan1_port" set network.eth0_2=switch_vlan set network.eth0_2.device=eth0 set network.eth0_2.vlan=2 set network.eth0_2.ports="$cmd_vlan2_port" set network.loopback=interface set network.loopback.ifname=lo set network.loopback.proto=static set network.loopback.ipaddr=127.0.0.1 set network.loopback.netmask=255.0.0.0 set network.lan=interface set network.lan.type=bridge set network.lan.ifname=eth0.1 set network.lan.proto=static set network.lan.ipaddr=192.168.31.1 set network.lan.netmask=255.255.255.0 set network.wan=interface set network.wan.proto=dhcp set network.wan.ifname=eth0.2 commit network delete dhcp.lan.ignore; commit dhcp EOF } #return value 1: gw ip unreachable; #return value 0: gw ip exists bridgeap_check_gw() { local bridgeap_gw_ip=`uci get network.lan.gateway` bridgeap_logger "current gateway ip $bridgeap_gw_ip" [ -z $bridgeap_gw_ip ] && return 0; bridgeap_gw_ip_noexist=`arping $bridgeap_gw_ip -I br-lan -c 3 &>/dev/null; echo $?`; bridgeap_logger "current gateway ip $bridgeap_gw_ip exist $bridgeap_gw_ip_noexist(1:gw ip unreachable)." return $bridgeap_gw_ip_noexist; } # return value 1: not ap mode # return value 0: ap mode; bridgeap_check_apmode() { local network_apmode=`uci get xiaoqiang.common.NETMODE` bridgeap_logger "network apmode $network_apmode." [ "$network_apmode" == "lanapmode" ] && return 0; bridgeap_logger "network apmode $network_apmode false." return 1; } bridgeap_open() { [ -z "$cmd_bridgeap_open" ] && exit 1 eval ${cmd_bridgeap_open} } bridgeap_close() { [ -z "$cmd_bridgeap_close" ] && exit 1 eval ${cmd_bridgeap_close} } bridgeap_lan_restart() { bridgeap_logger "try restart lan." for i in `seq 1 10` do /usr/sbin/dhcp_apclient.sh restart [ $? = '0' ] && return 0; bridgeap_logger "restart lan fail, try again in $i seconds." sleep $i done return 1; } # add timer task to crontab # eg. # bridgeap mode gateway check # */1 * * * * /usr/sbin/ap_mode.sh check_gw bridgeap_check_gw_stop() { grep -v "/usr/sbin/ap_mode.sh check_gw" /etc/crontabs/root > /etc/crontabs/root.new; mv /etc/crontabs/root.new /etc/crontabs/root /etc/init.d/cron restart } bridgeap_check_gw_start() { grep -v "/usr/sbin/ap_mode.sh check_gw" /etc/crontabs/root > /etc/crontabs/root.new; echo "*/1 * * * * /usr/sbin/ap_mode.sh check_gw" >> /etc/crontabs/root.new mv /etc/crontabs/root.new /etc/crontabs/root /etc/init.d/cron restart } bridgeap_plugin_restart() { plugin_script="/etc/init.d/plugin_start_script.sh" #r1cl doesn't have plugin service. [ -f $plugin_script ] || return $plugin_script stop $plugin_script start return; } wan_start() { has_wan=$(ifconfig $wan_device 1>/dev/null 2>/dev/null; echo $?) [ "$has_wan" == "0" ] && return ifup wan return $? } OPT=$1 if [ $# -ne 1 ]; then usage exit 1 fi case $OPT in connect) wan_start /usr/sbin/dhcp_apclient.sh start $wan_device return $? ;; open) ifdown vpn bridgeap_open; /etc/init.d/network restart /etc/init.d/dnsmasq stop /etc/init.d/dnsmasq disable /usr/sbin/dhcp_apclient.sh restart /usr/sbin/vasinfo_fw.sh off /etc/init.d/trafficd restart /etc/init.d/xqbc restart bridgeap_check_gw_start bridgeap_plugin_restart return $? ;; close) bridgeap_check_gw_stop bridgeap_close; /etc/init.d/network restart /etc/init.d/dnsmasq enable /etc/init.d/dnsmasq restart /usr/sbin/dhcp_apclient.sh restart /usr/sbin/vasinfo_fw.sh post_ota /etc/init.d/trafficd restart /etc/init.d/xqbc restart bridgeap_plugin_restart return $? ;; check_gw) #this part is used for "link up/down" "root ap change" check, in those situation # gateway/lan/sta ip must be "dhcp renew" bridgeap_logger "check apmode." bridgeap_check_apmode [ $? = '1' ] && exit 0; bridgeap_logger "check gateway." bridgeap_check_gw [ $? = '0' ] && exit 0; # in bridge ap mode and gateway unreachable, we had to run dhcp renew issue; # if can't renew ipaddr, script should exit. otherwise, restart network && lan bridgeap_logger "gateway changed, try dhcp renew." local lan_ipaddr_ori=`uci get network.lan.ipaddr 2>/dev/null` /usr/sbin/dhcp_apclient.sh start br-lan; local lan_ipaddr_now=`uci get network.lan.ipaddr 2>/dev/null` [ "$lan_ipaddr_ori" = "$lan_ipaddr_now" ] && exit 0; bridgeap_logger "gateway changed, lan ip changed from $lan_ipaddr_ori to $lan_ipaddr_now." /etc/init.d/network restart bridgeap_logger "gateway changed, try lan restart" bridgeap_lan_restart exit 0; ;; * ) echo "usage:" >&2 ;; esac