#!/bin/sh /etc/rc.common START=20 USE_PROCD=1 boot() { # procd will call service_triggers rc_procd true } service_triggers() { procd_add_reload_trigger "network" "ap_modem" } find_uci_section_i() { local key="$2" local value="$3" local testv config_get testv "$1" "$key" [[ "$value" = "$testv" ]] && echo "$1" } find_uci_section() { local config="$1" local type="$2" local key="$3" local value="$4" ( config_load "$config" config_foreach find_uci_section_i "$type" "$key" "$value" ) } generate_config() { [[ "`uci -q get network.lan.device`" = "br-lan" ]] || { echo "network.lan.device != br-lan in uci" >&2 return 1 } local wan_dev="`uci -q get network.wan.device`" [[ -z "$wan_dev" ]] && { echo "get network.wan.device in uci failed" >&2 return 1 } local lan_dev=`find_uci_section network device name 'br-lan' | head -1` [[ -z "$lan_dev" ]] && { echo "network.device.name=br-lan not found in uci" >&2 return 1 } local wan_zone=`find_uci_section firewall zone name 'wan' | head -1` [[ -z "$wan_zone" ]] && { echo "firewall.zone.name=wan not found in uci" >&2 return 1 } # virutal lan device uci -q get network.veth_lan >/dev/null || uci -q batch <<-EOF >/dev/null set network.veth_lan=device set network.veth_lan.type=veth set network.veth_lan.name=vap-lan set network.veth_lan.sendredirects=0 set network.veth_lan.ipv6=0 set network.veth_lan.multicast=0 set network.veth_lan.peer_name=vap-lan-peer EOF uci -q get network.veth_lan_peer >/dev/null || uci -q batch <<-EOF >/dev/null set network.veth_lan_peer=device set network.veth_lan_peer.name=vap-lan-peer set network.veth_lan_peer.sendredirects=0 set network.veth_lan_peer.ipv6=0 set network.veth_lan_peer.multicast=0 EOF uci -q get "network.$lan_dev.ports" | grep -Fwq 'vap-lan' || uci add_list "network.$lan_dev.ports=vap-lan" # interface if uci -q get network.vap_lan >/dev/null; then uci -q delete network.vap_lan.auto else uci -q batch <<-EOF >/dev/null set network.vap_lan=interface set network.vap_lan.proto=static set network.vap_lan.device=vap-lan-peer set network.vap_lan.defaultroute=0 set network.vap_lan.delegate=0 EOF fi if uci -q get network.vap_wan >/dev/null; then uci -q delete network.vap_wan.auto else uci -q batch <<-EOF >/dev/null set network.vap_wan=interface set network.vap_wan.proto=static set network.vap_wan.device=$wan_dev set network.vap_wan.defaultroute=0 set network.vap_wan.delegate=0 EOF fi # firewall local fw_wan_net="`uci -q get firewall.$wan_zone.network`" echo "$fw_wan_net" | grep -Fwq 'vap_lan' || uci -q batch <<-EOF >/dev/null add_list firewall.$wan_zone.network=vap_lan EOF echo "$fw_wan_net" | grep -Fwq 'vap_wan' || uci -q batch <<-EOF >/dev/null add_list firewall.$wan_zone.network=vap_wan EOF uci commit firewall # ip local bip local black_ip="127.0.0.1/8" [[ "`uci -q get network.lan.proto`" = "static" ]] && { local lan_ip="`uci -q get network.lan.ipaddr`" if [[ -n "$lan_ip" ]]; then local netmask="`uci -q get network.lan.netmask`" [[ -n "$netmask" ]] || netmask=255.255.255.255 for bip in $lan_ip; do if [[ "$bip" = "*/*" ]]; then eval "$(ipcalc.sh $bip )";black_ip="$black_ip $IP/$PREFIX" else eval "$(ipcalc.sh $bip $netmask )";black_ip="$black_ip $IP/$PREFIX" fi done fi } logger -t 'ap_modem' -p INFO "black: $black_ip" local ipaddr local vip local vip_p local vnet local bnet local ok local vif for vif in lan wan; do config_get ipaddr $vif ipaddr [[ -n "$ipaddr" ]] || continue for vip in $ipaddr; do ok=1 [[ "$vip" = "*/*" ]] || vip="$vip/24" eval "$(ipcalc.sh $vip )";vip="$IP";vip_p="$PREFIX" [[ "$vip_p" = 32 ]] && { logger -t 'ap_modem' -p DEBUG "vap_$vif skip $vip/$vip_p" break } for bip in $black_ip; do eval "$(ipcalc.sh "$bip" )";bip="$IP"; [[ "$PREFIX" -le "$vip_p" ]] || PREFIX=$vip_p eval "$(ipcalc.sh "$vip/$PREFIX" )";vnet="$NETWORK"; eval "$(ipcalc.sh "$bip/$PREFIX" )";bnet="$NETWORK"; if [[ "$vnet" = "$bnet" ]]; then logger -t 'ap_modem' -p DEBUG "vap_$vif skip $vip/$vip_p" ok=0 break fi done [[ "$ok" = 1 ]] && { uci add_list "network.vap_$vif.ipaddr=$vip/$vip_p" black_ip="$black_ip $vip/$vip_p" } done done uci commit network } clean_config() { local wan_zone=`find_uci_section firewall zone name 'wan' | head -1` [[ -z "$wan_zone" ]] || uci -q batch <<-EOF >/dev/null del_list firewall.$wan_zone.network=vap_lan del_list firewall.$wan_zone.network=vap_wan commit firewall EOF local lan_dev=`find_uci_section network device name 'br-lan' | head -1` [[ -z "$lan_dev" ]] || { uci del_list "network.$lan_dev.ports=vap-lan" } uci -q batch <<-EOF >/dev/null set network.vap_lan.auto=0 set network.vap_wan.auto=0 delete network.veth_lan_peer delete network.veth_lan commit network EOF } start_service() { config_load ap_modem config_get_bool enabled "config" enabled 0 uci -q batch <<-EOF >/dev/null delete network.vap_lan.ipaddr delete network.vap_wan.ipaddr commit network EOF if [[ "$enabled" = "1" ]]; then generate_config else clean_config fi /etc/init.d/network reload return 0 } stop_service() { clean_config /etc/init.d/network reload }