From 7f3b0af6d90e260ea119cd0a81786a97501c9541 Mon Sep 17 00:00:00 2001 From: Manuel Munz Date: Mon, 25 Mar 2013 16:31:34 +0000 Subject: [PATCH] applications/luci-splash: Add limited IPv6 Support --- applications/luci-splash/README | 5 +++ .../luci-splash/root/etc/init.d/luci_splash | 51 +++++++++++++++++++++- applications/luci-splash/root/usr/sbin/luci-splash | 44 +++++++++++++++++-- 3 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 applications/luci-splash/README diff --git a/applications/luci-splash/README b/applications/luci-splash/README new file mode 100644 index 000000000..5a7af14c2 --- /dev/null +++ b/applications/luci-splash/README @@ -0,0 +1,5 @@ + +* IPv6 support is only partial: + - will only work when used together with IPv4 (Dual stack) + - No bandwidth limiting + diff --git a/applications/luci-splash/root/etc/init.d/luci_splash b/applications/luci-splash/root/etc/init.d/luci_splash index 0d21bf50b..a6c636609 100755 --- a/applications/luci-splash/root/etc/init.d/luci_splash +++ b/applications/luci-splash/root/etc/init.d/luci_splash @@ -8,6 +8,7 @@ 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 @@ -18,6 +19,13 @@ ipt_log() { echo iptables -D "$@" >> $IPT_REPLAY } +ipt6_log() { + [ "$HAS_IPV6" = 1 ] || return + ip6tables -I "$@" + echo ip6tables -D "$@" >> $IPT_REPLAY +} + + iface_add() { local cfg="$1" @@ -33,6 +41,9 @@ iface_add() { config_get ipaddr "$net" ipaddr [ -n "$ipaddr" ] || return 0 + config_get ip6addr "$net" ip6addr + #[ -n "$ipaddr" ] || return 0 + config_get netmask "$net" netmask [ -n "$netmask" ] || return 0 @@ -53,6 +64,10 @@ iface_add() { ipt_log "zone_${zone}_prerouting" -i "${ifname%:*}" -s "$NETWORK/$PREFIX" -j luci_splash_prerouting -t nat ipt_log "zone_${zone}_forward" -i "${ifname%:*}" -s "$NETWORK/$PREFIX" -j luci_splash_forwarding -t filter + if [ "$HAS_IPV6" = 1 ]; then + ipt6_log "zone_${zone}_forward" -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 @@ -197,6 +212,11 @@ start() { iptables -t filter -N luci_splash_forwarding iptables -t filter -N luci_splash_filter + if [ "$HAS_IPV6" = 1 ]; then + ip6tables -t filter -N luci_splash_forwarding + ip6tables -t filter -N luci_splash_filter + fi + ### Clear iptables replay log [ -s $IPT_REPLAY ] && . $IPT_REPLAY echo -n > $IPT_REPLAY @@ -215,12 +235,24 @@ start() { 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 [ "$LIMIT_UP" -gt 0 -a "$LIMIT_DOWN" -gt 0 ] && { 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 @@ -254,6 +286,11 @@ stop() { 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 silent iptables -t nat -F luci_splash_prerouting silent iptables -t nat -F luci_splash_leases @@ -262,6 +299,13 @@ stop() { 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 silent iptables -t nat -X luci_splash_prerouting silent iptables -t nat -X luci_splash_leases @@ -269,7 +313,12 @@ stop() { 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 diff --git a/applications/luci-splash/root/usr/sbin/luci-splash b/applications/luci-splash/root/usr/sbin/luci-splash index 474617380..bf32d635e 100755 --- a/applications/luci-splash/root/usr/sbin/luci-splash +++ b/applications/luci-splash/root/usr/sbin/luci-splash @@ -9,10 +9,13 @@ require("luci.sys.iptparser") local uci = luci.model.uci.cursor_state() local ipt = luci.sys.iptparser.IptParser() local net = luci.sys.net +local fs = require "luci.fs" local limit_up = 0 local limit_down = 0 +local has_ipv6 = fs.access("/proc/net/ipv6_route") and fs.access("/usr/sbin/ip6tables") + function lock() os.execute("lock /var/run/luci_splash.lock") end @@ -191,6 +194,22 @@ function ipt_delete_all(args, comp, off) end end +function ipt6_delete_all(args, comp, off) + off = off or { } + for i, r in ipairs(ipt:find(args)) do + if comp == nil or comp(r) then + off[r.table] = off[r.table] or { } + off[r.table][r.chain] = off[r.table][r.chain] or 0 + + os.execute("ip6tables -t %q -D %q %d 2>/dev/null" + %{ r.table, r.chain, r.index - off[r.table][r.chain] }) + + off[r.table][r.chain] = off[r.table][r.chain] + 1 + end + end +end + + -- Convert mac to uci-compatible section name function convert_mac_to_secname(mac) return string.gsub(mac, ":", "") @@ -290,8 +309,12 @@ function add_lease_rule(mac, ipaddr) os.execute("iptables -t mangle -I luci_splash_mark_in -d %q -j MARK --set-mark 80" % ipaddr) end + os.execute("iptables -t filter -I luci_splash_filter -m mac --mac-source %q -j RETURN" % mac) os.execute("iptables -t nat -I luci_splash_leases -m mac --mac-source %q -j RETURN" % mac) + if has_ipv6 then + os.execute("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %q -j RETURN" % mac) + end end @@ -306,6 +329,9 @@ function remove_lease_rule(mac, ipaddr) ipt_delete_all({table="filter", chain="luci_splash_filter", options={"MAC", mac:upper()}}) ipt_delete_all({table="nat", chain="luci_splash_leases", options={"MAC", mac:upper()}}) + if has_ipv6 then + ipt6_delete_all({table="filter", chain="luci_splash_filter", options={"MAC", mac:upper()}}) + end end @@ -313,12 +339,18 @@ end function add_whitelist_rule(mac) os.execute("iptables -t filter -I luci_splash_filter -m mac --mac-source %q -j RETURN" % mac) os.execute("iptables -t nat -I luci_splash_leases -m mac --mac-source %q -j RETURN" % mac) + if has_ipv6 then + os.execute("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %q -j RETURN" % mac) + end end -- Add blacklist rules function add_blacklist_rule(mac) os.execute("iptables -t filter -I luci_splash_filter -m mac --mac-source %q -j DROP" % mac) + if has_ipv6 then + os.execute("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %q -j DROP" % mac) + end end @@ -365,16 +397,22 @@ function sync() ipt_delete_all({table="filter", chain="luci_splash_filter", options={"MAC"}}, function(r) return not macs[r.options[2]:lower()] end) - ipt_delete_all({table="nat", chain="luci_splash_leases", options={"MAC"}}, function(r) return not macs[r.options[2]:lower()] end) - ipt_delete_all({table="mangle", chain="luci_splash_mark_out", options={"MAC", "MARK", "set"}}, function(r) return not macs[r.options[2]:lower()] end) - ipt_delete_all({table="mangle", chain="luci_splash_mark_in", options={"MARK", "set"}}, function(r) return not ips[r.destination] end) + if has_ipv6 then + ipt6_delete_all({table="filter", chain="luci_splash_filter", options={"MAC"}}, + function(r) return not macs[r.options[2]:lower()] end) + ipt_delete_all({table="mangle", chain="luci_splash_mark_out", options={"MAC", "MARK", "set"}}, + function(r) return not macs[r.options[2]:lower()] end) + ipt_delete_all({table="mangle", chain="luci_splash_mark_in", options={"MARK", "set"}}, + function(r) return not ips[r.destination] end) + end + unlock() end -- 2.11.0