X-Git-Url: https://git.archive.openwrt.org/?a=blobdiff_plain;f=applications%2Fluci-splash%2Froot%2Fetc%2Finit.d%2Fluci_splash;h=d2628c86fe62c2ee6534ca4e5a4f5c516738c604;hb=2a366f4c554d46a33f727bc04e4d7a7798e5be3b;hp=7541f9935b5efdc4f466f1f4fa1548ade441e34b;hpb=2755a46c4db548cbceafcfcdfa67d476b9c0a1c5;p=project%2Fluci.git diff --git a/applications/luci-splash/root/etc/init.d/luci_splash b/applications/luci-splash/root/etc/init.d/luci_splash index 7541f9935..d2628c86f 100755 --- a/applications/luci-splash/root/etc/init.d/luci_splash +++ b/applications/luci-splash/root/etc/init.d/luci_splash @@ -1,70 +1,336 @@ #!/bin/sh /etc/rc.common + START=70 +EXTRA_COMMANDS=clear_leases +LIMIT_DOWN=0 +LIMIT_DOWN_BURST=0 +LIMIT_UP=0 + +IPT_REPLAY=/var/run/luci_splash.iptlog +LOCK=/var/run/luci_splash.lock +[ -x /usr/sbin/ip6tables ] && [ -f /proc/net/ipv6_route ] && HAS_IPV6=1 + +silent() { + "$@" 2>/dev/null +} + +ipt_log() { + iptables -I "$@" + echo iptables -D "$@" >> $IPT_REPLAY +} + +ipt6_log() { + [ "$HAS_IPV6" = 1 ] || return + ip6tables -I "$@" + echo ip6tables -D "$@" >> $IPT_REPLAY +} + iface_add() { local cfg="$1" - + config_get zone "$cfg" zone [ -n "$zone" ] || return 0 - - config_get gw "$cfg" gateway + + config_get net "$cfg" network + [ -n "$net" ] || return 0 + + config_get ifname "$net" ifname + [ -n "$ifname" ] || return 0 + + config_get ipaddr "$net" ipaddr + [ -n "$ipaddr" ] || return 0 + + config_get netmask "$net" netmask + [ -n "$netmask" ] || return 0 + + config_get ip6addr "$net" ip6addr + + config_get type "$net" type + + parentiface="$(uci -q get network.${net}.ifname)" + + [ -n "$parentiface" ] && [ ! "$type" = "bridge" ] && { + parentiface=${parentiface#@} + config_get parentproto "$parentiface" proto + config_get parentipaddr "$parentiface" ipaddr + config_get parentnetmask "$parentiface" netmask + } + + eval "$(ipcalc.sh $ipaddr $netmask)" + + logger -s -p info -t splash "Add $NETWORK/$PREFIX ($ifname) to splashed networks." + + ### Add interface specific chain entry rules + ipt_log "prerouting_${zone}_rule" -i "${ifname%:*}" -s "$NETWORK/$PREFIX" -j luci_splash_prerouting -t nat + ipt_log "forwarding_${zone}_rule" -i "${ifname%:*}" -s "$NETWORK/$PREFIX" -j luci_splash_forwarding -t filter + + if [ "$HAS_IPV6" = 1 ] && [ -n "$ip6addr" ]; then + ipt6_log "forwarding_${zone}_rule" -i "${ifname%:*}" -s "$ip6addr" -j luci_splash_forwarding -t filter + fi + + ### Allow traffic to the same subnet + iptables -t nat -I luci_splash_prerouting -d "$ipaddr/${netmask:-32}" -j RETURN + iptables -t filter -I luci_splash_forwarding -d "$ipaddr/${netmask:-32}" -j RETURN + + ### Allow traffic to the mesh subnet + [ "$parentproto" = "static" -a -n "$parentipaddr" ] && { + iptables -t nat -I luci_splash_prerouting -d "$parentipaddr/${parentnetmask:-32}" -j RETURN + iptables -t filter -I luci_splash_forwarding -d "$parentipaddr/${parentnetmask:-32}" -j RETURN + } + + qos_iface_add "$ifname" +} + +iface_del() { + config_get zone "$1" zone [ -n "$zone" ] || return 0 - - iptables -t nat -A zone_$zone_prerouting -j luci_splash_portal - iptables -t nat -A luci_splash_portal -d "$gw" -p tcp -m multiport --dports 22,80,443 -j RETURN + + config_get net "$1" network + [ -n "$net" ] || return 0 + + config_get ifname "$net" ifname + [ -n "$ifname" ] || return 0 + + # Clear interface specific rules + [ -s $IPT_REPLAY ] && { + logger -s -p info -t splash "Remove $ifname from splashed networks." + grep -- "-i ${ifname%:*}" $IPT_REPLAY | while read ln; do silent $ln; done + sed -ie "/-i ${ifname%:*}/d" $IPT_REPLAY + } + + qos_iface_del "$ifname" } -blacklist_add() { - local cfg="$1" - - config_get mac "$cfg" mac - [ -n "$mac" ] && iptables -t nat -A luci_splash_portal -m mac --mac-source "$mac" -j DROP +mac_add() { + config_get mac "$1" mac + append MACS "$mac" } -whitelist_add() { +subnet_add() { local cfg="$1" - - config_get mac "$cfg" mac - [ -n "$mac" ] && iptables -t nat -A luci_splash_portal -m mac --mac-source "$mac" -j RETURN + + config_get ipaddr "$cfg" ipaddr + config_get netmask "$cfg" netmask + + [ -n "$ipaddr" ] && { + iptables -t nat -I luci_splash_prerouting -d "$ipaddr/${netmask:-32}" -j RETURN + iptables -t filter -I luci_splash_forwarding -d "$ipaddr/${netmask:-32}" -j RETURN + } +} + +qos_iface_add() { + local iface="$1" + + # 77 -> download root qdisc + # 78 -> upload root qdisc + # 79 -> fwmark: client->inet + # 80 -> fwmark: inet->client + + silent tc qdisc del dev "$iface" root handle 77: + + if [ "$LIMIT_UP" -gt 0 -a "$LIMIT_DOWN" -gt 0 ]; then + tc qdisc add dev "$iface" root handle 77: htb + + # assume maximum rate of 20.000 kilobit for wlan + tc class add dev "$iface" parent 77: classid 77:1 htb rate 20000kbit + + # set download limit and burst + tc class add dev "$iface" parent 77:1 classid 77:10 htb \ + rate ${LIMIT_DOWN}kbit ceil ${LIMIT_DOWN_BURST}kbit prio 2 + + tc qdisc add dev "$iface" parent 77:10 handle 78: sfq perturb 10 + + # adding ingress can result in "File exists" if qos-scripts are active + silent tc qdisc add dev "$iface" ingress + + # set client download speed + tc filter add dev "$iface" parent 77: protocol ip prio 2 \ + handle 80 fw flowid 77:10 + + # set client upload speed + tc filter add dev "$iface" parent ffff: protocol ip prio 1 \ + handle 79 fw police rate ${LIMIT_UP}kbit mtu 6k burst 6k drop + fi +} + +qos_iface_del() { + local iface="$1" + + silent tc qdisc del dev "$iface" root handle 77: + silent tc qdisc del dev "$iface" root handle 78: + silent tc filter del dev "$iface" parent ffff: protocol ip prio 1 handle 79 fw +} + +boot() { + ### Setup splash-relay + uci get uhttpd.splash 2>/dev/null || { +uci batch < $IPT_REPLAY + ### Build the main and portal rule - config_foreach blacklist_add blacklist - config_foreach whitelist_add whitelist config_foreach iface_add iface - - ### Build the portal rule - iptables -t nat -A luci_splash_portal -p udp --dport 53 -j RETURN - iptables -t nat -A luci_splash_portal -j luci_splash_leases - - ### Build the leases rule + config_foreach subnet_add subnet + + ### Add interface independant prerouting rules + iptables -t nat -A luci_splash_prerouting -j luci_splash_leases + iptables -t nat -A luci_splash_leases -p udp --dport 53 -j REDIRECT --to-ports 53 iptables -t nat -A luci_splash_leases -p tcp --dport 80 -j REDIRECT --to-ports 8082 - iptables -t nat -A luci_splash_leases -j DROP - - ### Start the splash httpd - start-stop-daemon -S -b -q -x /usr/bin/luci-splashd + + ### Add interface independant forwarding rules + iptables -t filter -A luci_splash_forwarding -j luci_splash_filter + iptables -t filter -A luci_splash_filter -p tcp -j REJECT --reject-with tcp-reset + iptables -t filter -A luci_splash_filter -j REJECT --reject-with icmp-net-prohibited + + if [ "$HAS_IPV6" = 1 ]; then + ip6tables -t filter -A luci_splash_forwarding -j luci_splash_filter + ip6tables -t filter -A luci_splash_filter -p tcp -j REJECT --reject-with tcp-reset + ip6tables -t filter -A luci_splash_filter -j REJECT --reject-with adm-prohibited + fi + + ### Add QoS chain + iptables -t mangle -N luci_splash_mark_out + iptables -t mangle -N luci_splash_mark_in + iptables -t mangle -I PREROUTING -j luci_splash_mark_out + iptables -t mangle -I POSTROUTING -j luci_splash_mark_in + if [ "$HAS_IPV6" = 1 ]; then + ip6tables -t mangle -N luci_splash_mark_out + ip6tables -t mangle -N luci_splash_mark_in + ip6tables -t mangle -I PREROUTING -j luci_splash_mark_out + ip6tables -t mangle -I POSTROUTING -j luci_splash_mark_in + fi + + ### Find active mac addresses + MACS="" + config_foreach mac_add lease + config_foreach mac_add blacklist + config_foreach mac_add whitelist + + ### Add crontab entry + test -f /etc/crontabs/root || touch /etc/crontabs/root + grep -q luci-splash /etc/crontabs/root || { + echo '*/5 * * * * /usr/sbin/luci-splash sync' >> /etc/crontabs/root + } + + lock -u $LOCK + + ### Populate iptables + [ -n "$MACS" ] && luci-splash add-rules $MACS } -stop() { +stop() { + lock $LOCK + + include /lib/network + scan_interfaces + config_load luci_splash + + ### Clear interface rules + config_foreach iface_del iface + + silent iptables -t mangle -D PREROUTING -j luci_splash_mark_out + silent iptables -t mangle -D POSTROUTING -j luci_splash_mark_in + + if [ "$HAS_IPV6" = 1 ]; then + silent ip6tables -t mangle -D PREROUTING -j luci_splash_mark_out + silent ip6tables -t mangle -D POSTROUTING -j luci_splash_mark_in + fi + ### Clear subchains - iptables -t nat -F luci_splash_leases - iptables -t nat -F luci_splash_portal - iptables -t nat -F luci_splash - + silent iptables -t nat -F luci_splash_prerouting + silent iptables -t nat -F luci_splash_leases + silent iptables -t filter -F luci_splash_forwarding + silent iptables -t filter -F luci_splash_filter + silent iptables -t mangle -F luci_splash_mark_out + silent iptables -t mangle -F luci_splash_mark_in + + if [ "$HAS_IPV6" = 1 ]; then + ip6tables -t filter -F luci_splash_forwarding + ip6tables -t filter -F luci_splash_filter + ip6tables -t mangle -F luci_splash_mark_out + ip6tables -t mangle -F luci_splash_mark_in + fi + ### Delete subchains - iptables -t nat -X luci_splash_leases - iptables -t nat -X luci_splash_portal - iptables -t nat -X luci_splash + silent iptables -t nat -X luci_splash_prerouting + silent iptables -t nat -X luci_splash_leases + silent iptables -t filter -X luci_splash_forwarding + silent iptables -t filter -X luci_splash_filter + silent iptables -t mangle -X luci_splash_mark_out + silent iptables -t mangle -X luci_splash_mark_in + if [ "$HAS_IPV6" = 1 ]; then + ip6tables -t filter -X luci_splash_forwarding + ip6tables -t filter -X luci_splash_filter + ip6tables -t mangle -X luci_splash_mark_out + ip6tables -t mangle -X luci_splash_mark_in + fi + sed -ie '/\/usr\/sbin\/luci-splash sync/d' /var/spool/cron/crontabs/root + + lock -u $LOCK +} + +clear_leases() { + ### Find active mac addresses + MACS="" + config_foreach mac_add lease + + ### Clear leases + [ -n "$MACS" ] && luci-splash remove $MACS }