| 1 | #!/bin/sh /etc/rc.common |
|---|
| 2 | |
|---|
| 3 | START=70 |
|---|
| 4 | EXTRA_COMMANDS=clear_leases |
|---|
| 5 | LIMIT_DOWN=0 |
|---|
| 6 | LIMIT_DOWN_BURST=0 |
|---|
| 7 | LIMIT_UP=0 |
|---|
| 8 | |
|---|
| 9 | IPT_REPLAY=/var/run/luci_splash.iptlog |
|---|
| 10 | LOCK=/var/run/luci_splash.lock |
|---|
| 11 | |
|---|
| 12 | silent() { |
|---|
| 13 | "$@" 2>/dev/null |
|---|
| 14 | } |
|---|
| 15 | |
|---|
| 16 | ipt_log() { |
|---|
| 17 | iptables -I "$@" |
|---|
| 18 | echo iptables -D "$@" >> $IPT_REPLAY |
|---|
| 19 | } |
|---|
| 20 | |
|---|
| 21 | iface_add() { |
|---|
| 22 | local cfg="$1" |
|---|
| 23 | |
|---|
| 24 | config_get zone "$cfg" zone |
|---|
| 25 | [ -n "$zone" ] || return 0 |
|---|
| 26 | |
|---|
| 27 | config_get net "$cfg" network |
|---|
| 28 | [ -n "$net" ] || return 0 |
|---|
| 29 | |
|---|
| 30 | config_get ifname "$net" ifname |
|---|
| 31 | [ -n "$ifname" ] || return 0 |
|---|
| 32 | |
|---|
| 33 | config_get ipaddr "$net" ipaddr |
|---|
| 34 | [ -n "$ipaddr" ] || return 0 |
|---|
| 35 | |
|---|
| 36 | config_get netmask "$net" netmask |
|---|
| 37 | [ -n "$netmask" ] || return 0 |
|---|
| 38 | |
|---|
| 39 | config_get parentiface "$net" interface |
|---|
| 40 | [ -n "$parentiface" ] && { |
|---|
| 41 | config_get parentproto "$parentiface" proto |
|---|
| 42 | config_get parentipaddr "$parentiface" ipaddr |
|---|
| 43 | config_get parentnetmask "$parentiface" netmask |
|---|
| 44 | } |
|---|
| 45 | |
|---|
| 46 | eval "$(ipcalc.sh $ipaddr $netmask)" |
|---|
| 47 | |
|---|
| 48 | ### Add interface specific chain entry rules |
|---|
| 49 | ipt_log "zone_${zone}_prerouting" -i "${ifname%:*}" -s "$NETWORK/$PREFIX" -j luci_splash_prerouting -t nat |
|---|
| 50 | ipt_log "zone_${zone}_forward" -i "${ifname%:*}" -s "$NETWORK/$PREFIX" -j luci_splash_forwarding -t filter |
|---|
| 51 | |
|---|
| 52 | ### Allow traffic to the same subnet |
|---|
| 53 | iptables -t nat -I luci_splash_prerouting -d "$ipaddr/${netmask:-32}" -j RETURN |
|---|
| 54 | iptables -t filter -I luci_splash_forwarding -d "$ipaddr/${netmask:-32}" -j RETURN |
|---|
| 55 | |
|---|
| 56 | ### Allow traffic to the mesh subnet |
|---|
| 57 | [ "$parentproto" = "static" -a -n "$parentipaddr" ] && { |
|---|
| 58 | iptables -t nat -I luci_splash_prerouting -d "$parentipaddr/${parentnetmask:-32}" -j RETURN |
|---|
| 59 | iptables -t filter -I luci_splash_forwarding -d "$parentipaddr/${parentnetmask:-32}" -j RETURN |
|---|
| 60 | } |
|---|
| 61 | |
|---|
| 62 | qos_iface_add "$ifname" |
|---|
| 63 | } |
|---|
| 64 | |
|---|
| 65 | iface_del() { |
|---|
| 66 | config_get zone "$1" zone |
|---|
| 67 | [ -n "$zone" ] || return 0 |
|---|
| 68 | |
|---|
| 69 | config_get net "$1" network |
|---|
| 70 | [ -n "$net" ] || return 0 |
|---|
| 71 | |
|---|
| 72 | config_get ifname "$net" ifname |
|---|
| 73 | [ -n "$ifname" ] || return 0 |
|---|
| 74 | |
|---|
| 75 | # Clear interface specific rules |
|---|
| 76 | [ -s $IPT_REPLAY ] && { |
|---|
| 77 | grep -- "-i ${ifname%:*}" $IPT_REPLAY | while read ln; do silent $ln; done |
|---|
| 78 | sed -ie "/-i ${ifname%:*}/d" $IPT_REPLAY |
|---|
| 79 | } |
|---|
| 80 | |
|---|
| 81 | qos_iface_del "$ifname" |
|---|
| 82 | } |
|---|
| 83 | |
|---|
| 84 | mac_add() { |
|---|
| 85 | config_get mac "$1" mac |
|---|
| 86 | append MACS "$mac" |
|---|
| 87 | } |
|---|
| 88 | |
|---|
| 89 | subnet_add() { |
|---|
| 90 | local cfg="$1" |
|---|
| 91 | |
|---|
| 92 | config_get ipaddr "$cfg" ipaddr |
|---|
| 93 | config_get netmask "$cfg" netmask |
|---|
| 94 | |
|---|
| 95 | [ -n "$ipaddr" ] && { |
|---|
| 96 | iptables -t nat -I luci_splash_prerouting -d "$ipaddr/${netmask:-32}" -j RETURN |
|---|
| 97 | iptables -t filter -I luci_splash_forwarding -d "$ipaddr/${netmask:-32}" -j RETURN |
|---|
| 98 | } |
|---|
| 99 | } |
|---|
| 100 | |
|---|
| 101 | qos_iface_add() { |
|---|
| 102 | local iface="$1" |
|---|
| 103 | |
|---|
| 104 | # 77 -> download root qdisc |
|---|
| 105 | # 78 -> upload root qdisc |
|---|
| 106 | # 79 -> fwmark: client->inet |
|---|
| 107 | # 80 -> fwmark: inet->client |
|---|
| 108 | |
|---|
| 109 | silent tc qdisc del dev "$iface" root handle 77: |
|---|
| 110 | |
|---|
| 111 | if [ "$LIMIT_UP" -gt 0 -a "$LIMIT_DOWN" -gt 0 ]; then |
|---|
| 112 | tc qdisc add dev "$iface" root handle 77: htb |
|---|
| 113 | |
|---|
| 114 | # assume maximum rate of 20.000 kilobit for wlan |
|---|
| 115 | tc class add dev "$iface" parent 77: classid 77:1 htb rate 20000kbit |
|---|
| 116 | |
|---|
| 117 | # set download limit and burst |
|---|
| 118 | tc class add dev "$iface" parent 77:1 classid 77:10 htb \ |
|---|
| 119 | rate ${LIMIT_DOWN}kbit ceil ${LIMIT_DOWN_BURST}kbit prio 2 |
|---|
| 120 | |
|---|
| 121 | tc qdisc add dev "$iface" parent 77:10 handle 78: sfq perturb 10 |
|---|
| 122 | |
|---|
| 123 | # adding ingress can result in "File exists" if qos-scripts are active |
|---|
| 124 | silent tc qdisc add dev "$iface" ingress |
|---|
| 125 | |
|---|
| 126 | # set client download speed |
|---|
| 127 | tc filter add dev "$iface" parent 77: protocol ip prio 2 \ |
|---|
| 128 | handle 80 fw flowid 77:10 |
|---|
| 129 | |
|---|
| 130 | # set client upload speed |
|---|
| 131 | tc filter add dev "$iface" parent ffff: protocol ip prio 1 \ |
|---|
| 132 | handle 79 fw police rate ${LIMIT_UP}kbit mtu 6k burst 6k drop |
|---|
| 133 | fi |
|---|
| 134 | } |
|---|
| 135 | |
|---|
| 136 | qos_iface_del() { |
|---|
| 137 | local iface="$1" |
|---|
| 138 | |
|---|
| 139 | silent tc qdisc del dev "$iface" root handle 77: |
|---|
| 140 | silent tc qdisc del dev "$iface" root handle 78: |
|---|
| 141 | silent tc filter del dev "$iface" parent ffff: protocol ip prio 1 handle 79 fw |
|---|
| 142 | } |
|---|
| 143 | |
|---|
| 144 | boot() { |
|---|
| 145 | ### Setup splash-relay |
|---|
| 146 | uci get uhttpd.splash 2>/dev/null || { |
|---|
| 147 | uci batch <<EOF |
|---|
| 148 | set uhttpd.splash=uhttpd |
|---|
| 149 | set uhttpd.splash.home="/www/cgi-bin/splash/" |
|---|
| 150 | set uhttpd.splash.interpreter=".sh=/bin/ash" |
|---|
| 151 | set uhttpd.splash.listen_http="8082" |
|---|
| 152 | set uhttpd.splash.index_page="splash.sh" |
|---|
| 153 | set uhttpd.splash.error_page="/splash.sh" |
|---|
| 154 | |
|---|
| 155 | commit uhttpd |
|---|
| 156 | EOF |
|---|
| 157 | } |
|---|
| 158 | |
|---|
| 159 | ### We are started by the firewall include |
|---|
| 160 | exit 0 |
|---|
| 161 | } |
|---|
| 162 | |
|---|
| 163 | start() { |
|---|
| 164 | lock -w $LOCK && lock $LOCK |
|---|
| 165 | |
|---|
| 166 | include /lib/network |
|---|
| 167 | scan_interfaces |
|---|
| 168 | config_load luci_splash |
|---|
| 169 | |
|---|
| 170 | ### Find QoS limits |
|---|
| 171 | config_get LIMIT_UP general limit_up |
|---|
| 172 | config_get LIMIT_DOWN general limit_down |
|---|
| 173 | config_get LIMIT_DOWN_BURST general limit_down_burst |
|---|
| 174 | |
|---|
| 175 | LIMIT_UP="$((8*${LIMIT_UP:-0}))" |
|---|
| 176 | LIMIT_DOWN="$((8*${LIMIT_DOWN:-0}))" |
|---|
| 177 | LIMIT_DOWN_BURST="${LIMIT_DOWN_BURST:+$((8*$LIMIT_DOWN_BURST))}" |
|---|
| 178 | LIMIT_DOWN_BURST="${LIMIT_DOWN_BURST:-$(($LIMIT_DOWN / 5 * 6))}" |
|---|
| 179 | |
|---|
| 180 | ### Load required modules |
|---|
| 181 | [ "$LIMIT_UP" -gt 0 -a "$LIMIT_DOWN" -gt 0 ] && { |
|---|
| 182 | silent insmod act_police |
|---|
| 183 | silent insmod cls_fw |
|---|
| 184 | silent insmod cls_u32 |
|---|
| 185 | silent insmod sch_htb |
|---|
| 186 | silent insmod sch_sfq |
|---|
| 187 | silent insmod sch_ingress |
|---|
| 188 | } |
|---|
| 189 | |
|---|
| 190 | ### Create subchains |
|---|
| 191 | iptables -t nat -N luci_splash_prerouting |
|---|
| 192 | iptables -t nat -N luci_splash_leases |
|---|
| 193 | iptables -t filter -N luci_splash_forwarding |
|---|
| 194 | iptables -t filter -N luci_splash_filter |
|---|
| 195 | |
|---|
| 196 | ### Clear iptables replay log |
|---|
| 197 | [ -s $IPT_REPLAY ] && . $IPT_REPLAY |
|---|
| 198 | echo -n > $IPT_REPLAY |
|---|
| 199 | |
|---|
| 200 | ### Build the main and portal rule |
|---|
| 201 | config_foreach iface_add iface |
|---|
| 202 | config_foreach subnet_add subnet |
|---|
| 203 | |
|---|
| 204 | ### Add interface independant prerouting rules |
|---|
| 205 | iptables -t nat -A luci_splash_prerouting -j luci_splash_leases |
|---|
| 206 | iptables -t nat -A luci_splash_leases -p udp --dport 53 -j REDIRECT --to-ports 53 |
|---|
| 207 | iptables -t nat -A luci_splash_leases -p tcp --dport 80 -j REDIRECT --to-ports 8082 |
|---|
| 208 | |
|---|
| 209 | ### Add interface independant forwarding rules |
|---|
| 210 | iptables -t filter -A luci_splash_forwarding -j luci_splash_filter |
|---|
| 211 | iptables -t filter -A luci_splash_filter -p tcp -j REJECT --reject-with tcp-reset |
|---|
| 212 | iptables -t filter -A luci_splash_filter -j REJECT --reject-with icmp-net-prohibited |
|---|
| 213 | |
|---|
| 214 | ### Add QoS chain |
|---|
| 215 | [ "$LIMIT_UP" -gt 0 -a "$LIMIT_DOWN" -gt 0 ] && { |
|---|
| 216 | iptables -t mangle -N luci_splash_mark_out |
|---|
| 217 | iptables -t mangle -N luci_splash_mark_in |
|---|
| 218 | iptables -t mangle -I PREROUTING -j luci_splash_mark_out |
|---|
| 219 | iptables -t mangle -I POSTROUTING -j luci_splash_mark_in |
|---|
| 220 | } |
|---|
| 221 | |
|---|
| 222 | ### Find active mac addresses |
|---|
| 223 | MACS="" |
|---|
| 224 | config_foreach mac_add lease |
|---|
| 225 | config_foreach mac_add blacklist |
|---|
| 226 | config_foreach mac_add whitelist |
|---|
| 227 | |
|---|
| 228 | ### Add crontab entry |
|---|
| 229 | test -f /etc/crontabs/root || touch /etc/crontabs/root |
|---|
| 230 | grep -q luci-splash /etc/crontabs/root || { |
|---|
| 231 | echo '*/5 * * * * /usr/sbin/luci-splash sync' >> /etc/crontabs/root |
|---|
| 232 | } |
|---|
| 233 | |
|---|
| 234 | lock -u $LOCK |
|---|
| 235 | |
|---|
| 236 | ### Populate iptables |
|---|
| 237 | [ -n "$MACS" ] && luci-splash add-rules $MACS |
|---|
| 238 | } |
|---|
| 239 | |
|---|
| 240 | stop() { |
|---|
| 241 | lock -w $LOCK && lock $LOCK |
|---|
| 242 | |
|---|
| 243 | include /lib/network |
|---|
| 244 | scan_interfaces |
|---|
| 245 | config_load luci_splash |
|---|
| 246 | |
|---|
| 247 | ### Clear interface rules |
|---|
| 248 | config_foreach iface_del iface |
|---|
| 249 | |
|---|
| 250 | silent iptables -t mangle -D PREROUTING -j luci_splash_mark_out |
|---|
| 251 | silent iptables -t mangle -D POSTROUTING -j luci_splash_mark_in |
|---|
| 252 | |
|---|
| 253 | ### Clear subchains |
|---|
| 254 | silent iptables -t nat -F luci_splash_prerouting |
|---|
| 255 | silent iptables -t nat -F luci_splash_leases |
|---|
| 256 | silent iptables -t filter -F luci_splash_forwarding |
|---|
| 257 | silent iptables -t filter -F luci_splash_filter |
|---|
| 258 | silent iptables -t mangle -F luci_splash_mark_out |
|---|
| 259 | silent iptables -t mangle -F luci_splash_mark_in |
|---|
| 260 | |
|---|
| 261 | ### Delete subchains |
|---|
| 262 | silent iptables -t nat -X luci_splash_prerouting |
|---|
| 263 | silent iptables -t nat -X luci_splash_leases |
|---|
| 264 | silent iptables -t filter -X luci_splash_forwarding |
|---|
| 265 | silent iptables -t filter -X luci_splash_filter |
|---|
| 266 | silent iptables -t mangle -X luci_splash_mark_out |
|---|
| 267 | silent iptables -t mangle -X luci_splash_mark_in |
|---|
| 268 | |
|---|
| 269 | sed -ie '/\/usr\/sbin\/luci-splash sync/d' /var/spool/cron/crontabs/root |
|---|
| 270 | |
|---|
| 271 | lock -u $LOCK |
|---|
| 272 | } |
|---|
| 273 | |
|---|
| 274 | clear_leases() { |
|---|
| 275 | ### Find active mac addresses |
|---|
| 276 | MACS="" |
|---|
| 277 | config_foreach mac_add lease |
|---|
| 278 | |
|---|
| 279 | ### Clear leases |
|---|
| 280 | [ -n "$MACS" ] && luci-splash remove $MACS |
|---|
| 281 | } |
|---|
| 282 | |
|---|