2 LuCI - Lua Configuration Interface
4 Copyright 2008 Steven Barth <steven@midlink.org>
5 Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
7 Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
11 http://www.apache.org/licenses/LICENSE-2.0
17 local uci = require "luci.model.uci".cursor()
19 -------------------- View --------------------
20 f = SimpleForm("siitwizward", "4over6-Assistent",
21 "Dieser Assistent unterstüzt bei der Einrichtung von IPv4-over-IPv6 Translation.")
23 mode = f:field(ListValue, "mode", "Betriebsmodus")
24 mode:value("gateway", "Gateway")
25 mode:value("client", "Client")
27 dev = f:field(ListValue, "device", "WLAN-Gerät")
28 uci:foreach("wireless", "wifi-device",
30 dev:value(section[".name"])
33 lanip = f:field(Value, "ipaddr", "LAN IP Adresse")
34 lanip.value = "127.23.1.1"
36 lanmsk = f:field(Value, "netmask", "LAN Netzmaske")
37 lanmsk.value = "255.255.0.0"
40 -------------------- Control --------------------
41 LL_PREFIX = luci.ip.IPv6("fe80::/64")
44 -- find link-local address
47 for _, r in ipairs(luci.sys.net.routes6()) do
48 if LL_PREFIX:contains(r.dest) and r.dest:higher(LL_PREFIX) then
49 return r.dest:sub(LL_PREFIX)
52 return luci.ip.IPv6("::")
57 function f.handle(self, state, data)
58 if state == FORM_VALID then
59 luci.http.redirect(luci.dispatcher.build_url("admin", "uci", "changes"))
61 elseif state == FORM_INVALID then
62 self.errmessage = "Ungültige Eingabe: Bitte die Formularfelder auf Fehler prüfen."
67 function mode.write(self, section, value)
70 -- Configure wifi device
72 local wifi_device = dev:formvalue(section)
73 local wifi_essid = uci:get("siit", "wifi", "essid") or "6mesh.freifunk.net"
74 local wifi_bssid = uci:get("siit", "wifi", "bssid") or "02:ca:ff:ee:ba:be"
75 local wifi_channel = uci:get("siit", "wifi", "channel") or "1"
77 -- nuke old device definition
78 uci:delete_all("wireless", "wifi-iface",
79 function(s) return s.device == wifi_device end )
81 uci:delete_all("network", "interface",
82 function(s) return s['.name'] == wifi_device end )
84 -- create wifi device definition
85 uci:tset("wireless", wifi_device, {
87 channel = wifi_channel,
93 uci:section("wireless", "wifi-iface", nil, {
96 network = wifi_device,
104 -- Determine defaults
106 local ula_prefix = uci:get("siit", "ipv6", "ula_prefix") or "fd00::"
107 local ula_global = uci:get("siit", "ipv6", "ula_global") or "00ca:ffee:babe::" -- = Freifunk
108 local ula_subnet = uci:get("siit", "ipv6", "ula_subnet") or "0000:0000:0000:4223::" -- = Berlin
109 local siit_prefix = uci:get("siit", "ipv6", "siit_prefix") or "::ffff:0000:0000"
111 -- Find wifi interface
112 local device = dev:formvalue(section)
117 local ula = luci.ip.IPv6("::/64")
119 for _, prefix in ipairs({ ula_prefix, ula_global, ula_subnet }) do
120 ula = ula:add(luci.ip.IPv6(prefix))
123 ula = ula:add(find_ll())
129 -- * wan port is dhcp, lan port is 172.23.1.1/24
130 -- * siit0 gets a dummy address: 169.254.42.42
131 -- * wl0 gets an ipv6 address, in this case the fdca:ffee:babe::1:1/64
132 -- * we do a ::ffff:ffff:0/96 route into siit0, so everything from 6mesh goes into translation.
133 -- * an HNA6 of ::ffff:ffff:0:0/96 announces the mapped 0.0.0.0/0 ipv4 space.
134 -- * MTU on WAN, LAN down to 1400, ipv6 headers are slighly larger.
136 if value == "gateway" then
138 uci:set("network", "wan", "mtu", 1400)
140 -- use full siit subnet
141 siit_route = luci.ip.IPv6(siit_prefix .. "/96")
146 -- * 172.23.2.1/24 on its lan, fdca:ffee:babe::1:2 on wl0 and the usual dummy address on siit0.
147 -- * we do a ::ffff:ffff:172.13.2.0/120 to siit0, because in this case, only traffic directed to clients needs to go into translation.
148 -- * same route as HNA6 announcement to catch the traffic out of the mesh.
149 -- * Also, MTU on LAN reduced to 1400.
153 local lan_net = luci.ip.IPv4(
154 lanip:formvalue(section) or "192.168.1.1",
155 lanmsk:formvalue(section) or "255.255.255.0"
158 uci:tset("network", "lan", {
160 ipaddr = lan_net:host():string(),
161 netmask = lan_net:mask():string()
164 -- derive siit subnet from lan config
165 siit_route = luci.ip.IPv6(
166 siit_prefix .. "/" .. (96 + lan_net:prefix())
172 uci:delete_all("network", "interface",
173 function(s) return ( s.ifname == "siit0" ) end)
175 uci:section("network", "interface", "siit0", {
178 ipaddr = "169.254.42.42",
179 netmask = "255.255.255.0"
183 uci:delete_all("network", "route6",
184 function(s) return siit_route:contains(luci.ip.IPv6(s.target)) end)
186 uci:section("network", "route6", nil, {
188 target = siit_route:string()
191 -- create wifi network interface
192 uci:section("network", "interface", wifi_device, {
195 ip6addr = ula:string()
198 -- nuke old olsrd interfaces
199 uci:delete_all("olsrd", "Interface",
200 function(s) return s.interface == wifi_device end)
202 -- configure olsrd interface
203 uci:foreach("olsrd", "olsrd",
204 function(s) uci:set("olsrd", s['.name'], "IpVersion", 6) end)
206 uci:section("olsrd", "Interface", nil, {
208 interface = wifi_device,
209 Ip6AddrType = "global"
213 uci:delete_all("olsrd", "Hna6",
215 if s.netaddr and s.prefix then
216 return siit_route:contains(luci.ip.IPv6(s.netaddr.."/"..s.prefix))
220 uci:section("olsrd", "Hna6", nil, {
221 netaddr = siit_route:host():string(),
222 prefix = siit_route:prefix()