1 #!/bin/sh /etc/rc.common
4 EXTRA_COMMANDS=clear_leases
10 IPT6=/usr/sbin/ip6tables
12 IPT_REPLAY=/var/run/luci_splash.iptlog
13 LOCK=/var/run/luci_splash.lock
14 [ -x $IPT6 ] && [ -f /proc/net/ipv6_route ] && HAS_IPV6=1
22 echo $IPT -D "$@" >> $IPT_REPLAY
26 [ "$HAS_IPV6" = 1 ] || return
28 echo $IPT6 -D "$@" >> $IPT_REPLAY
35 config_get zone "$cfg" zone
36 [ -n "$zone" ] || return 0
38 config_get net "$cfg" network
39 [ -n "$net" ] || return 0
41 config_get ifname "$net" ifname
42 [ -n "$ifname" ] || return 0
44 config_get ipaddr "$net" ipaddr
45 [ -n "$ipaddr" ] || return 0
47 config_get netmask "$net" netmask
48 [ -n "$netmask" ] || return 0
50 config_get ip6addr "$net" ip6addr
52 config_get type "$net" type
54 parentiface="$(uci -q get network.${net}.ifname)"
56 [ -n "$parentiface" ] && [ ! "$type" = "bridge" ] && {
57 parentiface=${parentiface#@}
58 config_get parentproto "$parentiface" proto
59 config_get parentipaddr "$parentiface" ipaddr
60 config_get parentnetmask "$parentiface" netmask
63 eval "$(ipcalc.sh $ipaddr $netmask)"
65 logger -s -p info -t splash "Add $NETWORK/$PREFIX ($ifname) to splashed networks."
67 ### Add interface specific chain entry rules
68 ipt_log "prerouting_${zone}_rule" -i "${ifname%:*}" -s "$NETWORK/$PREFIX" -j luci_splash_prerouting -t nat
69 ipt_log "forwarding_${zone}_rule" -i "${ifname%:*}" -s "$NETWORK/$PREFIX" -j luci_splash_forwarding -t filter
71 if [ "$HAS_IPV6" = 1 ] && [ -n "$ip6addr" ]; then
72 ipt6_log "forwarding_${zone}_rule" -i "${ifname%:*}" -s "$ip6addr" -j luci_splash_forwarding -t filter
75 ### Allow traffic to the same subnet
76 $IPT -t nat -I luci_splash_prerouting -d "$ipaddr/${netmask:-32}" -j RETURN
77 $IPT -t filter -I luci_splash_forwarding -d "$ipaddr/${netmask:-32}" -j RETURN
79 ### Allow traffic to the mesh subnet
80 [ "$parentproto" = "static" -a -n "$parentipaddr" ] && {
81 $IPT -t nat -I luci_splash_prerouting -d "$parentipaddr/${parentnetmask:-32}" -j RETURN
82 $IPT -t filter -I luci_splash_forwarding -d "$parentipaddr/${parentnetmask:-32}" -j RETURN
85 qos_iface_add "$ifname" "$NETWORK" "$PREFIX"
89 config_get zone "$1" zone
90 [ -n "$zone" ] || return 0
92 config_get net "$1" network
93 [ -n "$net" ] || return 0
95 config_get ifname "$net" ifname
96 [ -n "$ifname" ] || return 0
98 # Clear interface specific rules
99 [ -s $IPT_REPLAY ] && {
100 logger -s -p info -t splash "Remove $ifname from splashed networks."
101 grep -- "-i ${ifname%:*}" $IPT_REPLAY | while read ln; do silent $ln; done
102 sed -ie "/-i ${ifname%:*}/d" $IPT_REPLAY
105 qos_iface_del "$ifname"
109 config_get mac "$1" mac
114 config_get mac "$1" mac
116 $TC filter add dev "$iface" parent ffff: protocol ip prio 1 u32 match ether src $mac police pass
117 $TC filter add dev "$iface" parent 1:0 protocol ip prio 1 u32 match ether dst $mac classid 1:1
124 config_get ipaddr "$cfg" ipaddr
125 config_get netmask "$cfg" netmask
127 [ -n "$ipaddr" ] && {
128 $IPT -t nat -I luci_splash_prerouting -d "$ipaddr/${netmask:-32}" -j RETURN
129 $IPT -t filter -I luci_splash_forwarding -d "$ipaddr/${netmask:-32}" -j RETURN
138 # 77 -> download root qdisc
139 # ffff -> upload root qdisc
141 silent $TC qdisc del dev "$iface" root handle 1:
142 silent $TC class del dev "$iface" parent 1: classid 1:ffff
143 silent $TC class del dev "$iface" parent 1: classid 1:1
144 silent $TC filter del dev "$iface" parent ffff: protocol ip prio 1 u32
145 silent $TC filter del dev "$iface" parent ffff: protocol ip prio 2 u32
146 silent $TC filter del dev "$iface" parent ffff: protocol ip prio 3 u32
148 if [ "$LIMIT_UP" -gt 0 -a "$LIMIT_DOWN" -gt 0 ]; then
150 $TC qdisc add dev "$iface" root handle 1: htb default 1
151 silent $TC qdisc add dev "$iface" ingress
153 # Default class - all clients which are not otherwise handled are put in that class
154 # and share that bandwidth.
155 $TC class add dev "$iface" parent 1: classid 1:ffff htb rate ${LIMIT_DOWN}kbit
157 # default class and class for whitelisted clients = unlimited
158 $TC class add dev "$iface" parent 1: classid 1:1 htb rate 100mbit
160 # All traffic to the dhcp subnet is put into the limited class
161 $TC filter add dev "$iface" parent 1:0 protocol ip prio 3 u32 match ip dst $network/$prefix classid 1:ffff
162 $TC qdisc add dev "$iface" parent 1:ffff sfq perturb 10
163 $TC filter add dev "$iface" parent ffff: protocol ip prio 3 u32 match ip src $network/$prefix police rate ${LIMIT_UP}kbit mtu 6k burst 6k drop
165 # classify packets by their iptables MARK set in luci_splash_mark_in (mangle table)
166 # every client gets his own class and so his own bandwidth limit
167 $TC filter add dev "$iface" parent 1:0 protocol ip prio 2 fw
169 config_foreach whitelist_add whitelist $iface
175 silent $TC qdisc del dev "$iface" root handle 77:
179 ### Setup splash-relay
180 uci get uhttpd.splash 2>/dev/null || {
182 set uhttpd.splash=uhttpd
183 set uhttpd.splash.home="/www/cgi-bin/splash/"
184 set uhttpd.splash.interpreter=".sh=/bin/ash"
185 set uhttpd.splash.listen_http="8082"
186 set uhttpd.splash.index_page="splash.sh"
187 set uhttpd.splash.error_page="/splash.sh"
188 set uhttpd.splash.http_keepalive='0'
193 ### We are started by the firewall include
199 logger -s -p info -t splash "Starting luci-splash"
201 . /lib/functions/network.sh
203 config_load luci_splash
206 config_get LIMIT_UP general limit_up
207 config_get LIMIT_DOWN general limit_down
208 config_get LIMIT_DOWN_BURST general limit_down_burst
210 LIMIT_UP="$((8*${LIMIT_UP:-0}))"
211 LIMIT_DOWN="$((8*${LIMIT_DOWN:-0}))"
212 LIMIT_DOWN_BURST="${LIMIT_DOWN_BURST:+$((8*$LIMIT_DOWN_BURST))}"
213 LIMIT_DOWN_BURST="${LIMIT_DOWN_BURST:-$(($LIMIT_DOWN / 5 * 6))}"
215 ### Load required modules
216 [ "$LIMIT_UP" -gt 0 -a "$LIMIT_DOWN" -gt 0 ] && {
217 silent insmod act_police
219 silent insmod cls_u32
220 silent insmod sch_htb
221 silent insmod sch_sfq
222 silent insmod sch_ingress
226 $IPT -t nat -N luci_splash_prerouting
227 $IPT -t nat -N luci_splash_leases
228 $IPT -t filter -N luci_splash_forwarding
229 $IPT -t filter -N luci_splash_filter
231 if [ "$HAS_IPV6" = 1 ]; then
232 $IPT6 -t filter -N luci_splash_forwarding
233 $IPT6 -t filter -N luci_splash_filter
236 ### Clear iptables replay log
237 [ -s $IPT_REPLAY ] && . $IPT_REPLAY
238 echo -n > $IPT_REPLAY
240 ### Add interface independant prerouting rules
241 $IPT -t nat -A luci_splash_prerouting -j luci_splash_leases
242 $IPT -t nat -A luci_splash_leases -p udp --dport 53 -j REDIRECT --to-ports 53
243 $IPT -t nat -A luci_splash_leases -p tcp --dport 80 -j REDIRECT --to-ports 8082
245 ### Add interface independant forwarding rules
246 $IPT -t filter -A luci_splash_forwarding -j luci_splash_filter
247 $IPT -t filter -A luci_splash_filter -p tcp -j REJECT --reject-with tcp-reset
248 $IPT -t filter -A luci_splash_filter -j REJECT --reject-with icmp-net-prohibited
250 if [ "$HAS_IPV6" = 1 ]; then
251 $IPT6 -t filter -A luci_splash_forwarding -j luci_splash_filter
252 $IPT6 -t filter -A luci_splash_filter -p tcp -j REJECT --reject-with tcp-reset
253 $IPT6 -t filter -A luci_splash_filter -j REJECT --reject-with adm-prohibited
257 $IPT -t mangle -N luci_splash_mark_out
258 $IPT -t mangle -N luci_splash_mark_in
259 $IPT -t mangle -I PREROUTING -j luci_splash_mark_out
260 $IPT -t mangle -I POSTROUTING -j luci_splash_mark_in
262 if [ "$HAS_IPV6" = 1 ]; then
263 $IPT6 -t mangle -N luci_splash_mark_out
264 $IPT6 -t mangle -N luci_splash_mark_in
265 $IPT6 -t mangle -I PREROUTING -j luci_splash_mark_out
266 $IPT6 -t mangle -I POSTROUTING -j luci_splash_mark_in
269 ### Build the main and portal rule
270 config_foreach iface_add iface
271 config_foreach subnet_add subnet
273 ### Add the community homepage to the list of allowed destination subnets
274 hp=$(uci -q get freifunk.community.homepage) && {
277 $IPT -t nat -I luci_splash_prerouting -d "${chp}/32" -j RETURN
278 $IPT -t filter -I luci_splash_forwarding -d "${chp}/32" -j RETURN
281 ### Find active mac addresses
285 config_foreach mac_add blacklist
286 config_foreach mac_add whitelist
288 config_load luci_splash_leases
289 config_foreach mac_add lease
291 ### Add crontab entry
292 test -f /etc/crontabs/root || touch /etc/crontabs/root
293 grep -q luci-splash /etc/crontabs/root || {
294 echo '*/5 * * * * /usr/sbin/luci-splash sync' >> /etc/crontabs/root
299 ### Populate iptables
300 [ -n "$MACS" ] && luci-splash add-rules $MACS
308 config_load luci_splash
310 ### Clear interface rules
311 config_foreach iface_del iface
313 silent $IPT -t mangle -D PREROUTING -j luci_splash_mark_out
314 silent $IPT -t mangle -D POSTROUTING -j luci_splash_mark_in
316 if [ "$HAS_IPV6" = 1 ]; then
317 silent $IPT6 -t mangle -D PREROUTING -j luci_splash_mark_out
318 silent $IPT6 -t mangle -D POSTROUTING -j luci_splash_mark_in
322 silent $IPT -t nat -F luci_splash_prerouting
323 silent $IPT -t nat -F luci_splash_leases
324 silent $IPT -t filter -F luci_splash_forwarding
325 silent $IPT -t filter -F luci_splash_filter
326 silent $IPT -t mangle -F luci_splash_mark_out
327 silent $IPT -t mangle -F luci_splash_mark_in
329 if [ "$HAS_IPV6" = 1 ]; then
330 $IPT6 -t filter -F luci_splash_forwarding
331 $IPT6 -t filter -F luci_splash_filter
332 $IPT6 -t mangle -F luci_splash_mark_out
333 $IPT6 -t mangle -F luci_splash_mark_in
337 silent $IPT -t nat -X luci_splash_prerouting
338 silent $IPT -t nat -X luci_splash_leases
339 silent $IPT -t filter -X luci_splash_forwarding
340 silent $IPT -t filter -X luci_splash_filter
341 silent $IPT -t mangle -X luci_splash_mark_out
342 silent $IPT -t mangle -X luci_splash_mark_in
343 if [ "$HAS_IPV6" = 1 ]; then
344 $IPT6 -t filter -X luci_splash_forwarding
345 $IPT6 -t filter -X luci_splash_filter
346 $IPT6 -t mangle -X luci_splash_mark_out
347 $IPT6 -t mangle -X luci_splash_mark_in
349 sed -ie '/\/usr\/sbin\/luci-splash sync/d' /var/spool/cron/crontabs/root
355 ### Find active mac addresses
357 config_foreach mac_add lease
360 [ -n "$MACS" ] && luci-splash remove $MACS