* luci/app-ffwizard: fix deletion of olsrd interface
[project/luci.git] / applications / luci-ffwizard-leipzig / luasrc / model / cbi / ffwizard.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$
14
15 ]]--
16
17
18 local uci = require "luci.model.uci".cursor()
19 local tools = require "luci.tools.ffwizard"
20 local util = require "luci.util"
21
22
23 -------------------- View --------------------
24 f = SimpleForm("ffwizward", "Freifunkassistent",
25  "Dieser Assistent unterstüzt bei der Einrichtung des Routers für das Freifunknetz.")
26
27
28 dev = f:field(ListValue, "device", "WLAN-Gerät")
29 uci:foreach("wireless", "wifi-device",
30         function(section)
31                 dev:value(section[".name"])
32         end)
33
34
35 main = f:field(Flag, "wifi", "Freifunkzugang einrichten")
36
37 net = f:field(Value, "net", "Freifunknetz", "1. Teil der IP-Adresse")
38 net.rmempty = true
39 net:depends("wifi", "1")
40 uci:foreach("freifunk", "community", function(s)
41         net:value(s[".name"], "%s (%s)" % {s.name, s.prefix})
42 end)
43
44 function net.cfgvalue(self, section)
45         return uci:get("freifunk", "wizard", "net")
46 end
47 function net.write(self, section, value)
48         uci:set("freifunk", "wizard", "net", value)
49         uci:save("freifunk")
50 end
51
52
53 subnet = f:field(Value, "subnet", "Subnetz (Projekt)", "2. Teil der IP-Adresse")
54 subnet.rmempty = true
55 subnet:depends("wifi", "1")
56 function subnet.cfgvalue(self, section)
57         return uci:get("freifunk", "wizard", "subnet")
58 end
59 function subnet.write(self, section, value)
60         uci:set("freifunk", "wizard", "subnet", value)
61         uci:save("freifunk")
62 end
63
64 node = f:field(Value, "node", "Knoten", "3. Teil der IP-Adresse")
65 node.rmempty = true
66 node:depends("wifi", "1")
67 for i=1, 51 do
68         node:value(i)
69 end
70 function node.cfgvalue(self, section)
71         return uci:get("freifunk", "wizard", "node")
72 end
73 function node.write(self, section, value)
74         uci:set("freifunk", "wizard", "node", value)
75         uci:save("freifunk")
76 end
77
78 client = f:field(Flag, "client", "WLAN-DHCP anbieten")
79 client:depends("wifi", "1")
80 client.rmempty = true
81 function client.cfgvalue(self, section)
82         return uci:get("freifunk", "wizard", "client")
83 end
84 function client.write(self, section, value)
85         uci:set("freifunk", "wizard", "client", value)
86         uci:save("freifunk")
87 end
88
89
90 olsr = f:field(Flag, "olsr", "OLSR einrichten")
91
92 share = f:field(Flag, "sharenet", "Eigenen Internetzugang freigeben")
93 share.rmempty = true
94 function share.cfgvalue(self, section)
95         return uci:get("freifunk", "wizard", "sharenet")
96 end
97 function share.write(self, section, value)
98         uci:set("freifunk", "wizard", "sharenet", value)
99         uci:save("freifunk")
100 end
101
102
103
104 -------------------- Control --------------------
105 function f.handle(self, state, data)
106         if state == FORM_VALID then
107                 luci.http.redirect(luci.dispatcher.build_url("admin", "uci", "changes"))
108                 return false
109         elseif state == FORM_INVALID then
110                 self.errmessage = "Ungültige Eingabe: Bitte die Formularfelder auf Fehler prüfen."
111         end
112         return true
113 end
114
115 local function _strip_internals(tbl)
116         tbl = tbl or {}
117         for k, v in pairs(tbl) do
118                 if k:sub(1, 1) == "." then
119                         tbl[k] = nil
120                 end
121         end
122         return tbl
123 end
124
125 -- Configure Freifunk checked
126 function main.write(self, section, value)
127         if value == "0" then
128                 return
129         end
130
131         local device = dev:formvalue(section)
132         local community, external
133
134         -- Collect IP-Address
135         local inet = net:formvalue(section)
136         local isubnet = subnet:formvalue(section)
137         local inode = node:formvalue(section)
138
139         -- Invalidate fields
140         if not inet then
141                 net.tag_missing[section] = true
142         else
143                 community = inet
144                 external  = uci:get("freifunk", community, "external") or ""
145                 inet = uci:get("freifunk", community, "prefix") or inet
146         end
147         if not isubnet then
148                 subnet.tag_missing[section] = true
149         end
150         if not inode then
151                 node.tag_missing[section] = true
152         end
153
154         if not inet or not isubnet or not inode then
155                 return
156         end
157
158         local ip = "%s.%s.%s" % {inet, isubnet, inode}
159
160
161         -- Cleanup
162         tools.wifi_delete_ifaces(device)
163         tools.network_remove_interface(device)
164         tools.firewall_zone_remove_interface("freifunk", device)
165
166         -- Tune community settings
167         if community then
168                 uci:tset("freifunk", "community", uci:get_all("freifunk", community))
169         end
170
171         -- Tune wifi device
172         local devconfig = uci:get_all("freifunk", "wifi_device")
173         util.update(devconfig, uci:get_all(external, "wifi_device") or {})
174         uci:tset("wireless", device, devconfig)
175
176         -- Create wifi iface
177         local ifconfig = uci:get_all("freifunk", "wifi_iface")
178         util.update(ifconfig, uci:get_all(external, "wifi_iface") or {})
179         ifconfig.device = device
180         ifconfig.network = device
181         ifconfig.ssid = uci:get("freifunk", community, "ssid")
182         uci:section("wireless", "wifi-iface", nil, ifconfig)
183
184         -- Save wifi
185         uci:save("wireless")
186
187         -- Create firewall zone and add default rules (first time)
188         local newzone = tools.firewall_create_zone("freifunk", "DROP", "ACCEPT", "DROP", true)
189         if newzone then
190                 uci:foreach("freifunk", "fw_forwarding", function(section)
191                         uci:section("firewall", "forwarding", nil, section)
192                 end)
193                 uci:foreach(external, "fw_forwarding", function(section)
194                         uci:section("firewall", "forwarding", nil, section)
195                 end)
196
197                 uci:foreach("freifunk", "fw_rule", function(section)
198                         uci:section("firewall", "rule", nil, section)
199                 end)
200                 uci:foreach(external, "fw_rule", function(section)
201                         uci:section("firewall", "rule", nil, section)
202                 end)
203
204                 uci:save("firewall")
205         end
206
207
208         -- Crate network interface
209         local netconfig = uci:get_all("freifunk", "interface")
210         util.update(netconfig, uci:get_all(external, "interface") or {})
211         netconfig.proto = "static"
212         netconfig.ipaddr = ip
213         uci:section("network", "interface", device, netconfig)
214
215         uci:save("network")
216
217         tools.firewall_zone_add_interface("freifunk", device)
218 end
219
220
221 function olsr.write(self, section, value)
222         if value == "0" then
223                 return
224         end
225
226
227         local device = dev:formvalue(section)
228
229         local community = net:formvalue(section)
230         local external  = community and uci:get("freifunk", community, "external") or ""
231
232         -- Delete old interface
233         uci:delete_all("olsrd", "Interface", {interface=device})
234
235         -- Write new interface
236         local olsrbase = uci:get_all("freifunk", "olsr_interface")
237         util.update(olsrbase, uci:get_all(external, "olsr_interface") or {})
238         olsrbase.interface = device
239         olsrbase.ignore    = "0"
240         uci:section("olsrd", "Interface", nil, olsrbase)
241         uci:save("olsrd")
242 end
243
244
245 function share.write(self, section, value)
246         uci:delete_all("firewall", "forwarding", {src="freifunk", dest="wan"})
247
248         if value == "1" then
249                 uci:section("firewall", "forwarding", nil, {src="freifunk", dest="wan"})
250         end
251         uci:save("firewall")
252 end
253
254
255 function client.write(self, section, value)
256         if value == "0" then
257                 return
258         end
259
260         local device = dev:formvalue(section)
261
262         -- Collect IP-Address
263         local inet = net:formvalue(section)
264         local isubnet = subnet:formvalue(section)
265         local inode = node:formvalue(section)
266
267         if not inet or not isubnet or not inode then
268                 return
269         end
270         local community = inet
271         local external  = community and uci:get("freifunk", community, "external") or ""
272         inet = uci:get("freifunk", community, "prefix") or inet
273
274         local dhcpbeg = 48 + tonumber(inode) * 4
275         local dclient = "%s.%s.%s" % {inet:gsub("^[0-9]+", "10"), isubnet, dhcpbeg}
276         local limit = dhcpbeg < 252 and 3 or 2
277
278         -- Delete old alias
279         uci:delete("network", device .. "dhcp")
280
281         -- Create alias
282         local aliasbase = uci:get_all("freifunk", "alias")
283         util.update(aliasbase, uci:get_all(external, "alias") or {})
284         aliasbase.interface = device
285         aliasbase.ipaddr = dclient
286         aliasbase.proto = "static"
287         uci:section("network", "alias", device .. "dhcp", aliasbase)
288         uci:save("network")
289
290
291         -- Create dhcp
292         local dhcpbase = uci:get_all("freifunk", "dhcp")
293         util.update(dhcpbase, uci:get_all(external, "dhcp") or {})
294         dhcpbase.interface = device .. "dhcp"
295         dhcpbase.start = dhcpbeg
296         dhcpbase.limit = limit
297
298         uci:section("dhcp", "dhcp", device .. "dhcp", dhcpbase)
299         uci:save("dhcp")
300
301         uci:delete_all("firewall", "rule", {
302                 src="freifunk",
303                 proto="udp",
304                 src_port="68",
305                 dest_port="67"
306         })
307         uci:section("firewall", "rule", nil, {
308                 src="freifunk",
309                 proto="udp",
310                 src_port="68",
311                 dest_port="67",
312                 target="ACCEPT"
313         })
314
315
316
317         -- Delete old splash
318         uci:delete_all("luci_splash", "iface", {net=device, zone="freifunk"})
319
320         -- Register splash
321         uci:section("luci_splash", "iface", nil, {net=device, zone="freifunk"})
322         uci:save("luci_splash")
323 end
324
325 return f