branches/luci-0.8: remove bitrot
[project/luci.git] / applications / luci-siitwizard / luasrc / model / cbi / siitwizard.lua
1 --[[
2 LuCI - Lua Configuration Interface
3
4 Copyright 2008 Steven Barth <steven@midlink.org>
5 Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
6
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
10
11 http://www.apache.org/licenses/LICENSE-2.0
12
13 $Id: siitwizard.lua 3940 2008-12-23 16:49:48Z jow $
14
15 ]]--
16
17 local uci = require "luci.model.uci".cursor()
18
19 -------------------- View --------------------
20 f = SimpleForm("siitwizward", "4over6-Assistent",
21 "Dieser Assistent unterstüzt bei der Einrichtung von IPv4-over-IPv6 Translation.")
22
23 mode = f:field(ListValue, "mode", "Betriebsmodus")
24 mode:value("client", "Client")
25 mode:value("gateway", "Gateway")
26
27 dev = f:field(ListValue, "device", "WLAN-Gerät")
28 uci:foreach("wireless", "wifi-device",
29 function(section)
30 dev:value(section[".name"])
31 end)
32
33 lanip = f:field(Value, "ipaddr", "LAN IP Adresse")
34 lanip.value = "172.23.1.1"
35
36 lanmsk = f:field(Value, "lanmask", "Lokale LAN Netzmaske")
37 lanmsk.value = "255.255.255.0"
38
39 gv4msk = f:field(Value, "gv4mask", "Globale LAN Netzmaske")
40 gv4msk.value = "255.255.0.0"
41
42
43 -------------------- Control --------------------
44 LL_PREFIX = luci.ip.IPv6("fe80::/64")
45
46 --
47 -- find link-local address
48 --
49 function find_ll()
50 for _, r in ipairs(luci.sys.net.routes6()) do
51 if LL_PREFIX:contains(r.dest) and r.dest:higher(LL_PREFIX) then
52 return r.dest:sub(LL_PREFIX)
53 end
54 end
55 return luci.ip.IPv6("::")
56 end
57
58
59
60 function f.handle(self, state, data)
61 if state == FORM_VALID then
62 luci.http.redirect(luci.dispatcher.build_url("admin", "uci", "changes"))
63 return false
64 elseif state == FORM_INVALID then
65 self.errmessage = "Ungültige Eingabe: Bitte die Formularfelder auf Fehler prüfen."
66 end
67 return true
68 end
69
70 function mode.write(self, section, value)
71
72 -- lan interface
73 local lan_net = luci.ip.IPv4(
74 lanip:formvalue(section) or "192.168.1.1",
75 lanmsk:formvalue(section) or "255.255.255.0"
76 )
77
78 local gv4_net = luci.ip.IPv4(
79 lanip:formvalue(section) or "192.168.1.1",
80 gv4msk:formvalue(section) or "255.255.0.0"
81 )
82
83 --
84 -- Configure wifi device
85 --
86 local wifi_device = dev:formvalue(section)
87 local wifi_essid = uci:get("siit", "wifi", "essid") or "6mesh.freifunk.net"
88 local wifi_bssid = uci:get("siit", "wifi", "bssid") or "02:ca:ff:ee:ba:be"
89 local wifi_channel = uci:get("siit", "wifi", "channel") or "1"
90
91 -- nuke old device definition
92 uci:delete_all("wireless", "wifi-iface",
93 function(s) return s.device == wifi_device end )
94
95 uci:delete_all("network", "interface",
96 function(s) return s['.name'] == wifi_device end )
97
98 -- create wifi device definition
99 uci:tset("wireless", wifi_device, {
100 disabled = 0,
101 channel = wifi_channel,
102 -- txantenna = 1,
103 -- rxantenna = 1,
104 -- diversity = 0
105 })
106
107 uci:section("wireless", "wifi-iface", nil, {
108 encryption = "none",
109 mode = "adhoc",
110 network = wifi_device,
111 device = wifi_device,
112 ssid = wifi_essid,
113 bssid = wifi_bssid,
114 })
115
116
117 --
118 -- Determine defaults
119 --
120 local ula_prefix = uci:get("siit", "ipv6", "ula_prefix") or "fd00::"
121 local ula_global = uci:get("siit", "ipv6", "ula_global") or "00ca:ffee:babe::" -- = Freifunk
122 local ula_subnet = uci:get("siit", "ipv6", "ula_subnet") or "0000:0000:0000:4223::" -- = Berlin
123 local siit_prefix = uci:get("siit", "ipv6", "siit_prefix") or "::ffff:0000:0000"
124
125 -- Find wifi interface
126 local device = dev:formvalue(section)
127
128 --
129 -- Generate ULA
130 --
131 local ula = luci.ip.IPv6("::/64")
132
133 for _, prefix in ipairs({ ula_prefix, ula_global, ula_subnet }) do
134 ula = ula:add(luci.ip.IPv6(prefix))
135 end
136
137 ula = ula:add(find_ll())
138
139
140 --
141 -- Gateway mode
142 --
143 -- * wan port is dhcp, lan port is 172.23.1.1/24
144 -- * siit0 gets a dummy address: 169.254.42.42
145 -- * wl0 gets an ipv6 address, in this case the fdca:ffee:babe::1:1/64
146 -- * we do a ::ffff:ffff:0/96 route into siit0, so everything from 6mesh goes into translation.
147 -- * an HNA6 of ::ffff:ffff:0:0/96 announces the mapped 0.0.0.0/0 ipv4 space.
148 -- * MTU on WAN, LAN down to 1400, ipv6 headers are slighly larger.
149
150 if value == "gateway" then
151
152
153 -- wan mtu
154 uci:set("network", "wan", "mtu", 1400)
155
156 -- lan settings
157 uci:tset("network", "lan", {
158 mtu = 1400,
159 ipaddr = lan_net:host():string(),
160 netmask = lan_net:mask():string()
161 })
162
163 -- use full siit subnet
164 siit_route = luci.ip.IPv6(siit_prefix .. "/96")
165
166 -- v4 <-> siit route
167 uci:delete_all("network", "route",
168 function(s) return s.interface == "siit0" end)
169
170 uci:section("network", "route", nil, {
171 interface = "siit0",
172 target = gv4_net:network():string(),
173 netmask = gv4_net:mask():string()
174 })
175
176 --
177 -- Client mode
178 --
179 -- * 172.23.2.1/24 on its lan, fdca:ffee:babe::1:2 on wl0 and the usual dummy address on siit0.
180 -- * 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.
181 -- * same route as HNA6 announcement to catch the traffic out of the mesh.
182 -- * Also, MTU on LAN reduced to 1400.
183
184 else
185
186 -- lan settings
187 uci:tset("network", "lan", {
188 mtu = 1400,
189 ipaddr = lan_net:host():string(),
190 netmask = lan_net:mask():string()
191 })
192
193 -- derive siit subnet from lan config
194 siit_route = luci.ip.IPv6(
195 siit_prefix .. "/" .. (96 + lan_net:prefix())
196 ):add(lan_net[2])
197
198 -- ipv4 <-> siit route
199 uci:delete_all("network", "route",
200 function(s) return s.interface == "siit0" end)
201
202 -- XXX: kind of a catch all, gv4_net would be better
203 -- but does not cover non-local v4 space
204 uci:section("network", "route", nil, {
205 interface = "siit0",
206 target = "0.0.0.0",
207 netmask = "0.0.0.0"
208 })
209 end
210
211 -- setup the firewall
212 uci:delete_all("firewall", "zone",
213 function(s) return (
214 s['.name'] == "siit0" or s.name == "siit0" or
215 s.network == "siit0" or s['.name'] == wifi_device or
216 s.name == wifi_device or s.network == wifi_device
217 ) end)
218
219 uci:delete_all("firewall", "forwarding",
220 function(s) return (
221 s.src == wifi_device and s.dest == "siit0" or
222 s.dest == wifi_device and s.src == "siit0" or
223 s.src == "lan" and s.dest == "siit0" or
224 s.dest == "lan" and s.src == "siit0"
225 ) end)
226
227 uci:section("firewall", "zone", "siit0", {
228 name = "siit0",
229 network = "siit0",
230 input = "ACCEPT",
231 output = "ACCEPT",
232 forward = "ACCEPT"
233 })
234
235 uci:section("firewall", "zone", wifi_device, {
236 name = wifi_device,
237 network = wifi_device,
238 input = "ACCEPT",
239 output = "ACCEPT",
240 forward = "ACCEPT"
241 })
242
243 uci:section("firewall", "forwarding", nil, {
244 src = wifi_device,
245 dest = "siit0"
246 })
247
248 uci:section("firewall", "forwarding", nil, {
249 src = "siit0",
250 dest = wifi_device
251 })
252
253 uci:section("firewall", "forwarding", nil, {
254 src = "lan",
255 dest = "siit0"
256 })
257
258 uci:section("firewall", "forwarding", nil, {
259 src = "siit0",
260 dest = "lan"
261 })
262
263 -- firewall include
264 uci:delete_all("firewall", "include",
265 function(s) return s.path == "/etc/firewall.user" end)
266
267 uci:section("firewall", "include", nil, {
268 path = "/etc/firewall.user"
269 })
270
271
272 -- siit0 interface
273 uci:delete_all("network", "interface",
274 function(s) return ( s.ifname == "siit0" ) end)
275
276 uci:section("network", "interface", "siit0", {
277 ifname = "siit0",
278 proto = "none"
279 })
280
281 -- siit0 route
282 uci:delete_all("network", "route6",
283 function(s) return siit_route:contains(luci.ip.IPv6(s.target)) end)
284
285 uci:section("network", "route6", nil, {
286 interface = "siit0",
287 target = siit_route:string()
288 })
289
290 -- create wifi network interface
291 uci:section("network", "interface", wifi_device, {
292 proto = "static",
293 mtu = 1400,
294 ip6addr = ula:string()
295 })
296
297 -- nuke old olsrd interfaces
298 uci:delete_all("olsrd", "Interface",
299 function(s) return s.interface == wifi_device end)
300
301 -- configure olsrd interface
302 uci:foreach("olsrd", "olsrd",
303 function(s) uci:set("olsrd", s['.name'], "IpVersion", 6) end)
304
305 uci:section("olsrd", "Interface", nil, {
306 ignore = 0,
307 interface = wifi_device,
308 Ip6AddrType = "global"
309 })
310
311 -- hna6
312 uci:delete_all("olsrd", "Hna6",
313 function(s)
314 if s.netaddr and s.prefix then
315 return siit_route:contains(luci.ip.IPv6(s.netaddr.."/"..s.prefix))
316 end
317 end)
318
319 uci:section("olsrd", "Hna6", nil, {
320 netaddr = siit_route:host():string(),
321 prefix = siit_route:prefix()
322 })
323
324 -- txtinfo v6
325 uci:foreach("olsrd", "LoadPlugin",
326 function(s)
327 if s.library == "olsrd_txtinfo.so.0.1" then
328 uci:set("olsrd", s['.name'], "accept", "::1")
329 end
330 end)
331
332 uci:save("wireless")
333 uci:save("firewall")
334 uci:save("network")
335 uci:save("olsrd")
336 end
337
338 return f