3047ec37a9b6dd6c52bb22be1aa8a4e406db8ea4
[project/luci.git] / applications / luci-ffwizard / luasrc / model / cbi / freifunk / 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 Copyright 2011 Patrick Grimm <patrick@pberg.freifunk.net>
7 Copyright 2011 Manuel Munz <freifunk at somakoma dot de>
8
9 Licensed under the Apache License, Version 2.0 (the "License");
10 you may not use this file except in compliance with the License.
11 You may obtain a copy of the License at
12
13 http://www.apache.org/licenses/LICENSE-2.0
14 ]]--
15
16
17 local uci = require "luci.model.uci".cursor()
18 local uci_state = require "luci.model.uci".cursor_state()
19 local tools = require "luci.tools.ffwizard"
20 local util = require "luci.util"
21 local sys = require "luci.sys"
22 local ip = require "luci.ip"
23 local fs  = require "nixio.fs"
24
25 local has_pptp  = fs.access("/usr/sbin/pptp")
26 local has_pppoe = fs.glob("/usr/lib/pppd/*/rp-pppoe.so")()
27 local has_l2gvpn  = fs.access("/usr/sbin/node")
28 local has_radvd  = fs.access("/etc/config/radvd")
29 local has_rom  = fs.access("/rom/etc")
30 local has_autoipv6  = fs.access("/usr/bin/auto-ipv6")
31 local has_qos  = fs.access("/etc/init.d/qos")
32 local has_ipv6 = fs.access("/proc/sys/net/ipv6")
33 local has_hb = fs.access("/sbin/heartbeat")
34 local community = "profile_" .. (uci:get("freifunk", "community", "name") or "na")
35 local lat = uci:get_first("system", "system", "latitude")
36 local lon = uci:get_first("system", "system", "longitude")
37 local suffix = uci:get_first(community, "community", "suffix") or "olsr"
38
39 luci.i18n.loadc("freifunk")
40
41 -- Check if all necessary variables are available
42 if not (community ~= "profile_na" and lat and lon) then
43         luci.http.redirect(luci.dispatcher.build_url(unpack(luci.dispatcher.context.requested.path), "freifunk", "ffwizard_error"))
44         return
45 end
46
47 function get_mac(ix)
48         if string.find(ix, "radio") then
49                 ix = string.gsub(ix,"radio", 'wlan')
50         end
51         local mac = fs.readfile("/sys/class/net/" .. ix .. "/address")
52         if not mac then
53                 mac = luci.util.exec("ifconfig " .. ix)
54                 mac = mac and mac:match(" ([A-F0-9:]+)%s*\n")
55         else
56                 mac = mac:sub(1,17)
57         end
58         if mac and #mac > 0 then
59                 return mac:lower()
60         end
61         return "?"
62 end
63
64 function get_ula(imac)
65         if string.len(imac) == 17 then
66                 local mac1 = string.sub(imac,4,8)
67                 local mac2 = string.sub(imac,10,14)
68                 local mac3 = string.sub(imac,16,17)
69                 return 'fdca:ffee:babe::02'..mac1..'ff:fe'..mac2..mac3..'/64'
70         end
71         return "?"
72 end
73
74 function gen_dhcp_range(n)
75         local subnet_prefix = tonumber(uci:get_first(community, "community", "splash_prefix")) or 27
76         local pool_network = uci:get_first(community, "community", "splash_network") or "10.104.0.0/16"
77         local pool = luci.ip.IPv4(pool_network)
78         local ip = tostring(n)
79         if pool and ip then
80                 local hosts_per_subnet = 2^(32 - subnet_prefix)
81                 local number_of_subnets = (2^pool:prefix())/hosts_per_subnet
82                 local seed1, seed2 = ip:match("(%d+)%.(%d+)$")
83                 if seed1 and seed2 then
84                         math.randomseed((seed1+1)*(seed2+1))
85                 end
86                 local subnet = pool:add(hosts_per_subnet * math.random(number_of_subnets))
87                 dhcp_ip = subnet:network(subnet_prefix):add(1):string()
88                 dhcp_mask = subnet:mask(subnet_prefix):string()
89         end
90         return "?"
91 end
92
93 function hbconf(dev)
94         if has_hb then
95                 local ifacelist = uci:get_list("manager", "heartbeat", "interface") or {}
96                 table.insert(ifacelist,dev .. "dhcp")
97                 uci:set_list("manager", "heartbeat", "interface", ifacelist)
98                 uci:save("manager")
99         end
100 end
101
102 -------------------- View --------------------
103 f = SimpleForm("ffwizward", "Freifunkassistent",
104  "Dieser Assistent unterstützt Sie bei der Einrichtung des Routers für das Freifunknetz.")
105
106 -- if password is not set or default then force the user to set a new one
107 if sys.exec("diff /rom/etc/passwd /etc/passwd") == "" then
108         pw1 = f:field(Value, "pw1", translate("password"))
109         pw1.password = true
110         pw1.rmempty = false
111
112         pw2 = f:field(Value, "pw2", translate("confirmation"))
113         pw2.password = true
114         pw2.rmempty = false
115
116         function pw2.validate(self, value, section)
117                 return pw1:formvalue(section) == value and value
118         end
119 end
120
121 -- main netconfig
122
123 local cc = uci:get(community, "wifi_device", "country") or "DE"
124
125 main = f:field(Flag, "netconfig", "Netzwerk einrichten", "Setzen Sie den Haken, wenn Sie Ihr Freifunk Netzwerk einrichten wollen.")
126 uci:foreach("wireless", "wifi-device",
127         function(section)
128                 local device = section[".name"]
129                 local hwtype = section.type
130
131                 local syscc  = uci:get("wireless", device, "country")
132                 if not syscc then
133                         if hwtype == "atheros" then
134                                 cc = sys.exec("grep -i '" .. cc .. "' /lib/wifi/cc_translate.txt |cut -d ' ' -f 2") or 0
135                                 sys.exec("echo " .. cc .. " > /proc/sys/dev/" .. device .. "/countrycode")
136                         elseif hwtype == "mac80211" then
137                                 sys.exec("iw reg set " .. cc)
138                         elseif hwtype == "broadcom" then
139                                 -- verify that ot works!
140                                 sys.exec ("wlc country " .. cc)
141                         end
142                 else
143                         cc = syscc
144                 end
145
146                 local dev = f:field(Flag, "device_" .. device , "<b>Drahtloses Netzwerk \"" .. device:upper() .. "\"</b> ", "Konfigurieren Sie Ihre drahtlose " .. device:upper() .. "Schnittstelle (WLAN).")
147                         dev:depends("netconfig", "1")
148                         dev.rmempty = false
149                         function dev.cfgvalue(self, section)
150                                 return uci:get("freifunk", "wizard", "device_" .. device)
151                         end
152                         function dev.write(self, sec, value)
153                                 if value then
154                                         uci:set("freifunk", "wizard", "device_" .. device, value)
155                                         uci:save("freifunk")
156                                 end
157                         end
158                 local chan = f:field(ListValue, "chan_" .. device, device:upper() .. "  Freifunk Kanal einrichten", "Ihr Gerät und benachbarte Freifunk Knoten müssen auf demselben Kanal senden. Je nach Gerätetyp können Sie zwischen verschiedenen 2,4Ghz und 5Ghz Kanälen auswählen.")
159                         chan:depends("device_" .. device, "1")
160                         chan.rmempty = true
161                         function chan.cfgvalue(self, section)
162                                 return uci:get("freifunk", "wizard", "chan_" .. device)
163                         end
164
165                         chan:value('default')
166                         for _, f in ipairs(sys.wifi.channels(device)) do
167                                 if not f.restricted then
168                                         chan:value(f.channel)
169                                 end
170                         end
171
172                         function chan.write(self, sec, value)
173                                 if value then
174                                         uci:set("freifunk", "wizard", "chan_" .. device, value)
175                                         uci:save("freifunk")
176                                 end
177                         end
178
179                 local meship = f:field(Value, "meship_" .. device, device:upper() .. "  Mesh IP Adresse einrichten", "Ihre Mesh IP Adresse erhalten Sie von der Freifunk Gemeinschaft in Ihrer Nachbarschaft. Es ist eine netzweit eindeutige Identifikation, z.B. 104.1.1.1.")
180                         meship:depends("device_" .. device, "1")
181                         meship.rmempty = true
182                         function meship.cfgvalue(self, section)
183                                 return uci:get("freifunk", "wizard", "meship_" .. device)
184                         end
185                         function meship.validate(self, value)
186                                 local x = ip.IPv4(value)
187                                 return ( x and x:prefix() == 32 ) and x:string() or ""
188                         end
189                         function meship.write(self, sec, value)
190                                 uci:set("freifunk", "wizard", "meship_" .. device, value)
191                         end
192                 if has_ipv6 then
193                         local meship6 = f:field(Value, "meship6_" .. device, device:upper() .. "  Mesh IPv6 Adresse einrichten", "Ihre Mesh IP Adresse wird automatisch berechnet")
194                         meship6:depends("device_" .. device, "1")
195                         meship6.rmempty = true
196                         function meship6.cfgvalue(self, section)
197                                 return get_ula(get_mac(device))
198                         end
199                 end
200         
201                 local client = f:field(Flag, "client_" .. device, device:upper() .. "  DHCP anbieten", "DHCP weist verbundenen Benutzern automatisch eine Adresse zu. Diese Option sollten Sie unbedingt aktivieren, wenn Sie Nutzer an der drahtlosen Schnittstelle erwarten.")
202                         client:depends("device_" .. device, "1")
203                         client.rmempty = true
204                         function client.cfgvalue(self, section)
205                                 return uci:get("freifunk", "wizard", "client_" .. device)
206                         end
207                         function client.write(self, sec, value)
208                                 uci:set("freifunk", "wizard", "client_" .. device, value)
209                                 uci:save("freifunk")
210                         end
211                 local dhcpmesh = f:field(Value, "dhcpmesh_" .. device, device:upper() .. "  Mesh DHCP anbieten", "Bestimmen Sie den Adressbereich aus dem Ihre Nutzer IP Adressen erhalten. Es wird empfohlen einen Adressbereich aus Ihrer lokalen Freifunk Gemeinschaft zu nutzen. Der Adressbereich ist ein netzweit eindeutiger Netzbereich. z.B. 104.1.2.1/28")
212                         dhcpmesh:depends("client_" .. device, "1")
213                         dhcpmesh.rmempty = true
214                         function dhcpmesh.cfgvalue(self, section)
215                                 return uci:get("freifunk", "wizard", "dhcpmesh_" .. device)
216                         end
217                         function dhcpmesh.validate(self, value)
218                                 local x = ip.IPv4(value)
219                                 return ( x and x:minhost()) and x:string() or ""
220                         end
221                         function dhcpmesh.write(self, sec, value)
222                                 uci:set("freifunk", "wizard", "dhcpmesh_" .. device, value)
223                                 uci:save("freifunk")
224                         end
225                 local hwtype = section.type
226                 if hwtype == "atheros" then
227                         local vap = f:field(Flag, "vap_" .. device , "Virtueller Drahtloser Zugangspunkt", "Konfigurieren Sie Ihren Virtuellen AP")
228                         vap:depends("client_" .. device, "1")
229                         vap.rmempty = false
230                         function vap.cfgvalue(self, section)
231                                 return uci:get("freifunk", "wizard", "vap_" .. device)
232                         end
233                         function vap.write(self, sec, value)
234                                 uci:set("freifunk", "wizard", "vap_" .. device, value)
235                                 uci:save("freifunk")
236                         end
237                 end
238         end)
239
240 uci:foreach("network", "interface",
241         function(section)
242                 local device = section[".name"]
243                 local ifname = uci_state:get("network",device,"ifname")
244                 if device ~= "loopback" and not string.find(device, "gvpn")  and not string.find(device, "wifi") and not string.find(device, "wl") and not string.find(device, "wlan") and not string.find(device, "wireless") and not string.find(device, "radio") then
245                         dev = f:field(Flag, "device_" .. device , "<b>Drahtgebundenes Netzwerk \"" .. device:upper() .. "\"</b>", "Konfigurieren Sie Ihre drahtgebunde " .. device:upper() .. " Schnittstelle (LAN).")
246                                 dev:depends("netconfig", "1")
247                                 dev.rmempty = false
248                                 function dev.cfgvalue(self, section)
249                                         return uci:get("freifunk", "wizard", "device_" .. device)
250                                 end
251                                 function dev.write(self, sec, value)
252                                         uci:set("freifunk", "wizard", "device_" .. device, value)
253                                         uci:save("freifunk")
254                                 end
255                         meship = f:field(Value, "meship_" .. device, device:upper() .. "  Mesh IP Adresse einrichten", "Ihre Mesh IP Adresse erhalten Sie von der Freifunk Gemeinschaft in Ihrer Nachbarschaft. Es ist eine netzweit eindeutige Identifikation, z.B. 104.1.1.1.")
256                                 meship:depends("device_" .. device, "1")
257                                 meship.rmempty = true
258                                 function meship.cfgvalue(self, section)
259                                         return uci:get("freifunk", "wizard", "meship_" .. device)
260                                 end
261                                 function meship.validate(self, value)
262                                         local x = ip.IPv4(value)
263                                         return ( x and x:prefix() == 32 ) and x:string() or ""
264                                 end
265                                 function meship.write(self, sec, value)
266                                         uci:set("freifunk", "wizard", "meship_" .. device, value)
267                                 end
268                         if has_ipv6 then
269                                 meship6 = f:field(Value, "meship6_" .. device, device:upper() .. "  Mesh IPv6 Adresse einrichten", "Ihre Mesh IP Adresse wird automatisch berechnet")
270                                 meship6:depends("device_" .. device, "1")
271                                 meship6.rmempty = true
272                                 function meship6.cfgvalue(self, section)
273                                         return get_ula(get_mac(ifname))
274                                 end
275                         end
276
277                         client = f:field(Flag, "client_" .. device, device:upper() .. "  DHCP anbieten","DHCP weist verbundenen Benutzern automatisch eine Adresse zu. Diese Option sollten Sie unbedingt aktivieren, wenn Sie Nutzer an der drahtlosen Schnittstelle erwarten.")
278                                 client:depends("device_" .. device, "1")
279                                 client.rmempty = false
280                                 function client.cfgvalue(self, section)
281                                         return uci:get("freifunk", "wizard", "client_" .. device)
282                                 end
283                                 function client.write(self, sec, value)
284                                         uci:set("freifunk", "wizard", "client_" .. device, value)
285                                         uci:save("freifunk")
286                                 end
287                         dhcpmesh = f:field(Value, "dhcpmesh_" .. device, device:upper() .. "  Mesh DHCP anbieten ", "Bestimmen Sie den Adressbereich aus dem Ihre Nutzer IP Adressen erhalten. Es wird empfohlen einen Adressbereich aus Ihrer lokalen Freifunk Gemeinschaft zu nutzen. Der Adressbereich ist ein netzweit eindeutiger Netzbereich. z.B. 104.1.2.1/28")
288                                 dhcpmesh:depends("client_" .. device, "1")
289                                 dhcpmesh.rmempty = true
290                                 function dhcpmesh.cfgvalue(self, section)
291                                         return uci:get("freifunk", "wizard", "dhcpmesh_" .. device)
292                                 end
293                                 function dhcpmesh.validate(self, value)
294                                         local x = ip.IPv4(value)
295                                         return ( x and x:prefix() <= 30 and x:minhost()) and x:string() or ""
296                                 end
297                                 function dhcpmesh.write(self, sec, value)
298                                         uci:set("freifunk", "wizard", "dhcpmesh_" .. device, value)
299                                         uci:save("freifunk")
300                                 end
301                 end
302         end)
303
304 share = f:field(Flag, "sharenet", "Eigenen Internetzugang freigeben", "Geben Sie Ihren Internetzugang im Freifunknetz frei.")
305 share.rmempty = false
306 share:depends("netconfig", "1")
307 function share.cfgvalue(self, section)
308         return uci:get("freifunk", "wizard", "share")
309 end
310 function share.write(self, section, value)
311         uci:set("freifunk", "wizard", "share", value)
312         uci:save("freifunk")
313 end
314
315 wanproto = f:field(ListValue, "wanproto", "Protokoll des Internetzugangs", "Geben Sie das Protokol an ueber das eine Internet verbindung hergestellt werden kann.")
316 wanproto:depends("sharenet", "1")
317 wanproto:value("static", translate("static", "static"))
318 wanproto:value("dhcp", translate("dhcp", "dhcp"))
319 if has_pppoe then wanproto:value("pppoe", "PPPoE") end
320 if has_pptp  then wanproto:value("pptp",  "PPTP")  end
321 function wanproto.cfgvalue(self, section)
322         return uci:get("network", "wan", "proto") or "dhcp"
323 end
324 function wanproto.write(self, section, value)
325         uci:set("network", "wan", "proto", value)
326         uci:save("network")
327 end
328 wanip = f:field(Value, "wanipaddr", translate("ipaddress"))
329 wanip:depends("wanproto", "static")
330 function wanip.cfgvalue(self, section)
331         return uci:get("network", "wan", "ipaddr")
332 end
333 function wanip.write(self, section, value)
334         uci:set("network", "wan", "ipaddr", value)
335         uci:save("network")
336 end
337 wannm = f:field(Value, "wannetmask", translate("netmask"))
338 wannm:depends("wanproto", "static")
339 function wannm.cfgvalue(self, section)
340         return uci:get("network", "wan", "netmask")
341 end
342 function wannm.write(self, section, value)
343         uci:set("network", "wan", "netmask", value)
344         uci:save("network")
345 end
346 wangw = f:field(Value, "wangateway", translate("gateway"))
347 wangw:depends("wanproto", "static")
348 wangw.rmempty = true
349 function wangw.cfgvalue(self, section)
350         return uci:get("network", "wan", "gateway")
351 end
352 function wangw.write(self, section, value)
353         uci:set("network", "wan", "gateway", value)
354         uci:save("network")
355 end
356 wandns = f:field(Value, "wandns", translate("dnsserver"))
357 wandns:depends("wanproto", "static")
358 wandns.rmempty = true
359 function wandns.cfgvalue(self, section)
360         return uci:get("network", "wan", "dns")
361 end
362 function wandns.write(self, section, value)
363         uci:set("network", "wan", "dns", value)
364         uci:save("network")
365 end
366 wanusr = f:field(Value, "wanusername", translate("username"))
367 wanusr:depends("wanproto", "pppoe")
368 wanusr:depends("wanproto", "pptp")
369 function wanusr.cfgvalue(self, section)
370         return uci:get("network", "wan", "username")
371 end
372 function wanusr.write(self, section, value)
373         uci:set("network", "wan", "username", value)
374         uci:save("network")
375 end
376 wanpwd = f:field(Value, "wanpassword", translate("password"))
377 wanpwd.password = true
378 wanpwd:depends("wanproto", "pppoe")
379 wanpwd:depends("wanproto", "pptp")
380 function wanpwd.cfgvalue(self, section)
381         return uci:get("network", "wan", "password")
382 end
383 function wanpwd.write(self, section, value)
384         uci:set("network", "wan", "password", value)
385         uci:save("network")
386 end
387
388 wansec = f:field(Flag, "wansec", "WAN-Zugriff auf Gateway beschränken", "Verbieten Sie Zugriffe auf Ihr lokales Netzwerk aus dem Freifunknetz.")
389 wansec.rmempty = false
390 wansec:depends("wanproto", "static")
391 wansec:depends("wanproto", "dhcp")
392 function wansec.cfgvalue(self, section)
393         return uci:get("freifunk", "wizard", "wan_security")
394 end
395 function wansec.write(self, section, value)
396         uci:set("freifunk", "wizard", "wan_security", value)
397         uci:save("freifunk")
398 end
399 if has_qos then
400         wanqosdown = f:field(Value, "wanqosdown", "Download Bandbreite begrenzen", "kb/s")
401         wanqosdown:depends("sharenet", "1")
402         function wanqosdown.cfgvalue(self, section)
403                 return uci:get("qos", "wan", "download")
404         end
405         function wanqosdown.write(self, section, value)
406                 uci:set("qos", "wan", "download", value)
407                 uci:save("qos")
408         end
409         wanqosup = f:field(Value, "wanqosup", "Upload Bandbreite begrenzen", "kb/s")
410         wanqosup:depends("sharenet", "1")
411         function wanqosup.cfgvalue(self, section)
412                 return uci:get("qos", "wan", "upload")
413         end
414         function wanqosup.write(self, section, value)
415                 uci:set("qos", "wan", "upload", value)
416                 uci:save("qos")
417         end
418 end
419
420 if has_l2gvpn then
421         gvpn = f:field(Flag, "gvpn", "Freifunk Internet Tunnel", "Verbinden Sie ihren Router ueber das Internet mit anderen Freifunknetzen.")
422         gvpn.rmempty = false
423         gvpn:depends("sharenet", "1")
424         function gvpn.cfgvalue(self, section)
425                 return uci:get("freifunk", "wizard", "gvpn")
426         end
427         function gvpn.write(self, section, value)
428                 uci:set("freifunk", "wizard", "gvpn", value)
429                 uci:save("freifunk")
430         end
431         gvpnip = f:field(Value, "gvpnipaddr", translate("ipaddress"))
432         gvpnip:depends("gvpn", "1")
433         function gvpnip.cfgvalue(self, section)
434                 return uci:get("l2gvpn", "bbb", "ip") or uci:get("network", "gvpn", "ipaddr")
435         end
436         function gvpnip.validate(self, value)
437                 local x = ip.IPv4(value)
438                 return ( x and x:prefix() == 32 ) and x:string() or ""
439         end
440 end
441
442 if has_hb then
443         hb = f:field(Flag, "hb", "Heartbeat aktivieren","Dem Gerät erlauben anonyme Statistiken zu übertragen. (empfohlen)")
444         hb.rmempty = false
445         hb:depends("netconfig", "1")
446         function hb.cfgvalue(self, section)
447                 return uci:get("freifunk", "wizard", "hb")
448         end
449         function hb.write(self, section, value)
450                 uci:set("freifunk", "wizard", "hb", value)
451                 uci:save("freifunk")
452         end
453 end
454
455 -------------------- Control --------------------
456 function f.handle(self, state, data)
457         if state == FORM_VALID then
458                 local debug = uci:get("freifunk", "wizard", "debug")
459                 if debug == "1" then
460                         if data.pw1 then
461                                 local stat = luci.sys.user.setpasswd("root", data.pw1) == 0
462                                 if stat then
463                                         f.message = translate("a_s_changepw_changed")
464                                 else
465                                         f.errmessage = translate("unknownerror")
466                                 end
467                         end
468                         data.pw1 = nil
469                         data.pw2 = nil
470                         luci.http.redirect(luci.dispatcher.build_url(unpack(luci.dispatcher.context.requested.path), "system", "system"))
471                 else
472                         if data.pw1 then
473                                 local stat = luci.sys.user.setpasswd("root", data.pw1) == 0
474                         end
475                         data.pw1 = nil
476                         data.pw2 = nil
477                         uci:commit("freifunk")
478                         uci:commit("wireless")
479                         uci:commit("network")
480                         uci:commit("dhcp")
481                         uci:commit("luci_splash")
482                         uci:commit("firewall")
483                         uci:commit("system")
484                         uci:commit("olsrd")
485                         uci:commit("manager")
486                         if has_autoipv6 then
487                                 uci:commit("autoipv6")
488                         end
489                         if has_qos then
490                                 uci:commit("qos")
491                         end
492                         if has_l2gvpn then
493                                 uci:commit("l2gvpn")
494                         end
495                         if has_radvd then
496                                 uci:commit("radvd")
497                         end
498
499                         sys.exec("for s in network dnsmasq luci_splash firewall olsrd radvd l2gvpn; do [ -x /etc/init.d/$s ] && /etc/init.d/$s restart;done > /dev/null &" )
500                         luci.http.redirect(luci.dispatcher.build_url(luci.dispatcher.context.path[1], "freifunk", "ffwizard"))
501                 end
502                 return false
503         elseif state == FORM_INVALID then
504                 self.errmessage = "Ungültige Eingabe: Bitte die Formularfelder auf Fehler prüfen."
505         end
506         return true
507 end
508
509 local function _strip_internals(tbl)
510         tbl = tbl or {}
511         for k, v in pairs(tbl) do
512                 if k:sub(1, 1) == "." then
513                         tbl[k] = nil
514                 end
515         end
516         return tbl
517 end
518 -- Configure Freifunk checked
519 function main.write(self, section, value)
520         if value == "0" then
521                 uci:set("freifunk", "wizard", "netconfig", "0")
522                 uci:save("freifunk")
523                 return
524         end
525         -- Collect IP-Address
526         uci:set("freifunk", "wizard", "net", uci:get_first(community, "community", "mesh_network"))
527         uci:save("freifunk")
528
529         -- Invalidate fields
530         if not community then
531                 net.tag_missing[section] = true
532                 return
533         end
534
535         uci:set("freifunk", "wizard", "netconfig", "1")
536         uci:save("freifunk")
537
538         local netname = "wireless"
539         local network
540         network = ip.IPv4(uci:get_first(community, "community", "mesh_network") or "104.0.0.0/8")
541
542         -- Tune community settings
543 --      if community and uci:get("freifunk", community) then
544 --              uci:get_all(community)
545 --      end
546
547         -- Cleanup
548         uci:delete_all("firewall","zone", {name="freifunk"})
549         uci:delete_all("firewall","forwarding", {dest="freifunk"})
550         uci:delete_all("firewall","forwarding", {src="freifunk"})
551         uci:delete_all("firewall","rule", {dest="freifunk"})
552         uci:delete_all("firewall","rule", {src="freifunk"})
553         uci:save("firewall")
554         -- Create firewall zone and add default rules (first time)
555         --                    firewall_create_zone("name"    , "input" , "output", "forward ", Masqurade)
556         local newzone = tools.firewall_create_zone("freifunk", "ACCEPT", "ACCEPT", "REJECT"  , true)
557         if newzone then
558                 uci:foreach("freifunk", "fw_forwarding", function(section)
559                         uci:section("firewall", "forwarding", nil, section)
560                 end)
561                 uci:foreach(community, "fw_forwarding", function(section)
562                         uci:section("firewall", "forwarding", nil, section)
563                 end)
564
565                 uci:foreach("freifunk", "fw_rule", function(section)
566                         uci:section("firewall", "rule", nil, section)
567                 end)
568                 uci:foreach(community, "fw_rule", function(section)
569                         uci:section("firewall", "rule", nil, section)
570                 end)
571         end
572         uci:save("firewall")
573         if has_hb then
574                 uci:delete("manager", "heartbeat", "interface")
575                 uci:save("manager")
576         end
577         -- Delete olsrdv4
578         uci:delete_all("olsrd", "olsrd")
579         local olsrbase
580         olsrbase = uci:get_all("freifunk", "olsrd") or {}
581         util.update(olsrbase, uci:get_all(community, "olsrd") or {})
582         if has_ipv6 then
583                 olsrbase.IpVersion='6and4'
584         else
585                 olsrbase.IpVersion='4'
586         end
587         uci:section("olsrd", "olsrd", nil, olsrbase)
588         -- Delete olsrdv4 old p2pd settings
589         uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_mdns.so.1.0.0"})
590         uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_p2pd.so.0.1.0"})
591         -- Write olsrdv4 new p2pd settings
592         uci:section("olsrd", "LoadPlugin", nil, {
593                 library     = "olsrd_p2pd.so.0.1.0",
594                 P2pdTtl     = 10,
595                 UdpDestPort = "224.0.0.251 5353",
596                 ignore      = 1,
597         })
598         -- Delete http plugin
599         uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_httpinfo.so.0.1"})
600
601         -- Delete olsrdv4 old interface
602         uci:delete_all("olsrd", "Interface")
603         uci:delete_all("olsrd", "Hna4")
604         -- Create wireless ip4/ip6 and firewall config
605         uci:foreach("wireless", "wifi-device",
606         function(sec)
607                 local device = sec[".name"]
608                 if not luci.http.formvalue("cbid.ffwizward.1.device_" .. device) then
609                         return
610                 end
611                 node_ip = luci.http.formvalue("cbid.ffwizward.1.meship_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.meship_" .. device))
612                 if has_ipv6 then
613                         node_ip6 = luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device) and ip.IPv6(luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device))
614                 end
615                 if not node_ip or not network or not network:contains(node_ip) then
616                         meship.tag_missing[section] = true
617                         node_ip = nil
618                         return
619                 end
620                 -- rename the wireless interface s/wifi/wireless/
621                 local nif
622                 if string.find(device, "wifi") then
623                         nif = string.gsub(device,"wifi", netname)
624                 elseif string.find(device, "wl") then
625                         nif = string.gsub(device,"wl", netname)
626                 elseif string.find(device, "wlan") then
627                         nif = string.gsub(device,"wlan", netname)
628                 elseif string.find(device, "radio") then
629                         nif = string.gsub(device,"radio", netname)
630                 end
631                 -- Cleanup
632                 tools.wifi_delete_ifaces(device)
633                 -- tools.network_remove_interface(device)
634                 uci:delete("network", device .. "dhcp")
635                 uci:delete("network", device)
636                 tools.firewall_zone_remove_interface("freifunk", device)
637                 -- tools.network_remove_interface(nif)
638                 uci:delete("network", nif .. "dhcp")
639                 uci:delete("network", nif)
640                 tools.firewall_zone_remove_interface("freifunk", nif)
641                 -- Delete old dhcp
642                 uci:delete("dhcp", device)
643                 uci:delete("dhcp", device .. "dhcp")
644                 uci:delete("dhcp", nif)
645                 uci:delete("dhcp", nif .. "dhcp")
646                 -- Delete old splash
647                 uci:delete_all("luci_splash", "iface", {network=device.."dhcp", zone="freifunk"})
648                 uci:delete_all("luci_splash", "iface", {network=nif.."dhcp", zone="freifunk"})
649                 -- Delete old radvd
650                 if has_radvd then
651                         uci:delete_all("radvd", "interface", {interface=nif.."dhcp"})
652                         uci:delete_all("radvd", "interface", {interface=nif})
653                         uci:delete_all("radvd", "prefix", {interface=nif.."dhcp"})
654                         uci:delete_all("radvd", "prefix", {interface=nif})
655                 end
656                 -- New Config
657                 -- Tune wifi device
658                 local ssid = uci:get_first(community, "community", "ssid") or "olsr.freifunk.net"
659                 local devconfig = uci:get_all("freifunk", "wifi_device")
660                 util.update(devconfig, uci:get_all(community, "wifi_device") or {})
661                 local channel = luci.http.formvalue("cbid.ffwizward.1.chan_" .. device)
662                 local hwmode = "11bg"
663                 local bssid = uci:get_all(community, "wifi_iface", "bssid") or "02:CA:FF:EE:BA:BE"
664                 local mrate = 5500
665                 -- set bssid, see https://kifuse02.pberg.freifunk.net/moin/channel-bssid-essid for schema
666                 if channel and channel ~= "default" then
667                         if devconfig.channel ~= channel then
668                                 devconfig.channel = channel
669                                 local chan = tonumber(channel)
670                                 if chan >= 0 and chan < 10 then
671                                         bssid = channel .. "2:CA:FF:EE:BA:BE"
672                                 elseif chan == 10 then 
673                                         bssid = "02:CA:FF:EE:BA:BE" 
674                                 elseif chan >= 11 and chan <= 14 then
675                                         bssid = string.format("%X",channel) .. "2:CA:FF:EE:BA:BE"
676                                 elseif chan >= 36 and chan <= 64 then
677                                         hwmode = "11a"
678                                         mrate = ""
679                                         bssid = "00:" .. channel ..":CA:FF:EE:EE"
680                                 elseif chan >= 100 and chan <= 140 then
681                                         hwmode = "11a"
682                                         mrate = ""
683                                         bssid = "01:" .. string.sub(channel, 2) .. ":CA:FF:EE:EE"
684                                 end
685                                 devconfig.hwmode = hwmode
686                         end
687                         devconfig.country = cc
688                         ssid = ssid .. " - ch" .. channel
689                 end
690                 uci:tset("wireless", device, devconfig)
691                 -- Create wifi iface
692                 local ifconfig = uci:get_all("freifunk", "wifi_iface")
693                 util.update(ifconfig, uci:get_all(community, "wifi_iface") or {})
694                 ifconfig.device = device
695                 ifconfig.network = nif
696                 ifconfig.ssid = ssid
697                 ifconfig.bssid = bssid
698                 ifconfig.encryption="none"
699                 -- Read Preset 
700                 local netconfig = uci:get_all("freifunk", "interface")
701                 util.update(netconfig, uci:get_all(community, "interface") or {})
702                 netconfig.proto = "static"
703                 netconfig.ipaddr = node_ip:string()
704                 if has_ipv6 then
705                         netconfig.ip6addr = node_ip6:string()
706                 end
707                 uci:section("network", "interface", nif, netconfig)
708                 if has_radvd then
709                         uci:section("radvd", "interface", nil, {
710                                 interface          =nif,
711                                 AdvSendAdvert      =1,
712                                 AdvManagedFlag     =0,
713                                 AdvOtherConfigFlag =0,
714                                 ignore             =0
715                         })
716                         uci:section("radvd", "prefix", nil, {
717                                 interface          =nif,
718                                 AdvOnLink          =1,
719                                 AdvAutonomous      =1,
720                                 AdvRouterAddr      =0,
721                                 ignore             =0,
722                         })
723                         uci:save("radvd")
724                 end
725                 tools.firewall_zone_add_interface("freifunk", nif)
726                 uci:save("firewall")
727                 -- Write new olsrv4 interface
728                 local olsrifbase = uci:get_all("freifunk", "olsr_interface")
729                 util.update(olsrifbase, uci:get_all(community, "olsr_interface") or {})
730                 olsrifbase.interface = nif
731                 olsrifbase.ignore    = "0"
732                 uci:section("olsrd", "Interface", nil, olsrifbase)
733                 -- Collect MESH DHCP IP NET
734                 local client = luci.http.formvalue("cbid.ffwizward.1.client_" .. device)
735                 if client then
736                         local dhcpmeshnet = luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device))
737                         hbconf(nif)
738                         --[[
739                         if has_hb then
740                                 local ifacelist = uci:get_list("manager", "heartbeat", "interface") or {}
741                                 table.insert(ifacelist,nif .. "dhcp")
742                                 uci:set_list("manager", "heartbeat", "interface", ifacelist)
743                                 uci:save("manager")
744                         end
745                         ]]
746                         if dhcpmeshnet then
747                                 if not dhcpmeshnet:minhost() or not dhcpmeshnet:mask() then
748                                         dhcpmesh.tag_missing[section] = true
749                                         dhcpmeshnet = nil
750                                         return
751                                 end
752                                 dhcp_ip = dhcpmeshnet:minhost():string()
753                                 dhcp_mask = dhcpmeshnet:mask():string()
754                                 dhcp_network = dhcpmeshnet:network():string()
755                                 uci:section("olsrd", "Hna4", nil, {
756                                         netmask  = dhcp_mask,
757                                         netaddr  = dhcp_network
758                                 })
759                                 uci:foreach("olsrd", "LoadPlugin",
760                                         function(s)             
761                                                 if s.library == "olsrd_p2pd.so.0.1.0" then
762                                                         uci:set("olsrd", s['.name'], "ignore", "0")
763                                                         local nonolsr = uci:get("olsrd", s['.name'], "NonOlsrIf") or ""
764                                                         vap = luci.http.formvalue("cbid.ffwizward.1.vap_" .. device)
765                                                         if vap then
766                                                                 nonolsr = nif.."dhcp "..nonolsr
767                                                         else
768                                                                 nonolsr = nif.." "..nonolsr
769                                                         end
770                                                         uci:set("olsrd", s['.name'], "NonOlsrIf", nonolsr)
771                                                 end
772                                         end)
773                         else
774                                 gen_dhcp_range(netconfig.ipaddr)
775                         end
776                         if dhcp_ip and dhcp_mask then
777                                 -- Create alias
778                                 local aliasbase = uci:get_all("freifunk", "alias")
779                                 util.update(aliasbase, uci:get_all(community, "alias") or {})
780                                 aliasbase.ipaddr = dhcp_ip
781                                 aliasbase.netmask = dhcp_mask
782                                 aliasbase.proto = "static"
783                                 vap = luci.http.formvalue("cbid.ffwizward.1.vap_" .. device)
784                                 if vap then
785                                         uci:section("network", "interface", nif .. "dhcp", aliasbase)
786                                         uci:section("wireless", "wifi-iface", nil, {
787                                                 device     =device,
788                                                 mode       ="ap",
789                                                 encryption ="none",
790                                                 network    =nif .. "dhcp",
791                                                 ssid       ="AP-" .. ssid
792                                         })
793                                         if has_radvd then
794                                                 uci:section("radvd", "interface", nil, {
795                                                         interface          =nif .. "dhcp",
796                                                         AdvSendAdvert      =1,
797                                                         AdvManagedFlag     =0,
798                                                         AdvOtherConfigFlag =0,
799                                                         ignore             =0
800                                                 })
801                                                 uci:section("radvd", "prefix", nil, {
802                                                         interface          =nif .. "dhcp",
803                                                         AdvOnLink          =1,
804                                                         AdvAutonomous      =1,
805                                                         AdvRouterAddr      =0,
806                                                         ignore             =0
807                                                 })
808                                                 uci:save("radvd")
809                                         end
810                                         tools.firewall_zone_add_interface("freifunk", nif .. "dhcp")
811                                         uci:save("wireless")
812                                         ifconfig.mcast_rate = nil
813                                         ifconfig.encryption="none"
814                                 else
815                                         aliasbase.interface = nif
816                                         uci:section("network", "alias", nif .. "dhcp", aliasbase)
817                                 end
818                                 -- Create dhcp
819                                 local dhcpbase = uci:get_all("freifunk", "dhcp")
820                                 util.update(dhcpbase, uci:get_all(community, "dhcp") or {})
821                                 dhcpbase.interface = nif .. "dhcp"
822                                 dhcpbase.force = 1
823                                 uci:section("dhcp", "dhcp", nif .. "dhcp", dhcpbase)
824                                 uci:set_list("dhcp", nif .. "dhcp", "dhcp_option", "119,olsr")
825                                 -- Create firewall settings
826                                 uci:delete_all("firewall", "rule", {
827                                         src="freifunk",
828                                         proto="udp",
829                                         dest_port="53"
830                                 })
831                                 uci:section("firewall", "rule", nil, {
832                                         src="freifunk",
833                                         proto="udp",
834                                         dest_port="53",
835                                         target="ACCEPT"
836                                 })
837                                 uci:delete_all("firewall", "rule", {
838                                         src="freifunk",
839                                         proto="udp",
840                                         src_port="68",
841                                         dest_port="67"
842                                 })
843                                 uci:section("firewall", "rule", nil, {
844                                         src="freifunk",
845                                         proto="udp",
846                                         src_port="68",
847                                         dest_port="67",
848                                         target="ACCEPT"
849                                 })
850                                 uci:delete_all("firewall", "rule", {
851                                         src="freifunk",
852                                         proto="tcp",
853                                         dest_port="8082",
854                                 })
855                                 uci:section("firewall", "rule", nil, {
856                                         src="freifunk",
857                                         proto="tcp",
858                                         dest_port="8082",
859                                         target="ACCEPT"
860                                 })
861                                 -- Register splash
862                                 uci:section("luci_splash", "iface", nil, {network=nif.."dhcp", zone="freifunk"})
863                                 uci:save("luci_splash")
864                                 -- Make sure that luci_splash is enabled
865                                 sys.init.enable("luci_splash")
866                         end
867                 else
868                         -- Delete old splash
869                         uci:delete_all("luci_splash", "iface", {network=device.."dhcp", zone="freifunk"})
870                 end
871                 --Write Ad-Hoc wifi section after AP wifi section
872                 uci:section("wireless", "wifi-iface", nil, ifconfig)
873                 uci:save("network")
874                 uci:save("wireless")
875                 uci:save("network")
876                 uci:save("firewall")
877                 uci:save("dhcp")
878         end)
879         -- Create wired ip and firewall config
880         uci:foreach("network", "interface",
881                 function(sec)
882                 local device = sec[".name"]
883                 if not luci.http.formvalue("cbid.ffwizward.1.device_" .. device) then
884                         return
885                 end
886                 if device ~= "loopback" and not string.find(device, "wifi") and not string.find(device, "wl") and not string.find(device, "wlan") and not string.find(device, "wireless") and not string.find(device, "radio") then
887                         local node_ip
888                         node_ip = luci.http.formvalue("cbid.ffwizward.1.meship_" .. device) --and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.meship_" .. device))
889                         if has_ipv6 then
890                                 node_ip6 = luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device) --and ip.IPv6(luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device))
891                         end
892                         if not node_ip or not network or not network:contains(node_ip) then
893                                 meship.tag_missing[section] = true
894                                 node_ip = nil
895                                 return
896                         end
897                         -- Cleanup
898                         tools.firewall_zone_remove_interface(device, device)
899                         uci:delete_all("firewall","zone", {name=device})
900                         uci:delete_all("firewall","forwarding", {src=device})
901                         uci:delete_all("firewall","forwarding", {dest=device})
902                         uci:delete("network", device .. "dhcp")
903                         -- Delete old dhcp
904                         uci:delete("dhcp", device)
905                         uci:delete("dhcp", device .. "dhcp")
906                         -- Delete old splash
907                         uci:delete_all("luci_splash", "iface", {network=device.."dhcp", zone="freifunk"})
908                         if has_radvd then
909                                 uci:delete_all("radvd", "interface", {interface=device.."dhcp"})
910                                 uci:delete_all("radvd", "interface", {interface=device})
911                                 uci:delete_all("radvd", "prefix", {interface=device.."dhcp"})
912                                 uci:delete_all("radvd", "prefix", {interface=device})
913                         end
914                         -- New Config
915                         local netconfig = uci:get_all("freifunk", "interface")
916                         util.update(netconfig, uci:get_all(community, "interface") or {})
917                         netconfig.proto = "static"
918                         netconfig.ipaddr = node_ip:string()
919                         if has_ipv6 then
920                                 netconfig.ip6addr = node_ip6:string()
921                         end
922                         uci:section("network", "interface", device, netconfig)
923                         uci:save("network")
924                         if has_radvd then
925                                 uci:section("radvd", "interface", nil, {
926                                         interface          =device,
927                                         AdvSendAdvert      =1,
928                                         AdvManagedFlag     =0,
929                                         AdvOtherConfigFlag =0,
930                                         ignore             =0
931                                 })
932                                 uci:section("radvd", "prefix", nil, {
933                                         interface          =device,
934                                         AdvOnLink          =1,
935                                         AdvAutonomous      =1,
936                                         AdvRouterAddr      =0,
937                                         ignore             =0,
938                                 })
939                                 uci:save("radvd")
940                         end
941                         tools.firewall_zone_add_interface("freifunk", device)
942                         uci:save("firewall")
943                         -- Write new olsrv4 interface
944                         local olsrifbase = uci:get_all("freifunk", "olsr_interface")
945                         util.update(olsrifbase, uci:get_all(community, "olsr_interface") or {})
946                         olsrifbase.interface = device
947                         olsrifbase.ignore    = "0"
948                         uci:section("olsrd", "Interface", nil, olsrifbase)
949                         olsrifbase.Mode = 'ether'
950                         -- Collect MESH DHCP IP NET
951                         local client = luci.http.formvalue("cbid.ffwizward.1.client_" .. device)
952                         if client then
953                                 local dhcpmeshnet = luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device))
954                                 hbconf(device)
955 --[[
956                                 if has_hb then
957                                         hbconf(device)
958                                         local ifacelist = uci:get_list("manager", "heartbeat", "interface") or {}
959                                         table.insert(ifacelist,device .. "dhcp")
960                                         uci:set_list("manager", "heartbeat", "interface", ifacelist)
961                                         uci:save("manager")
962                                         
963                                 end
964 ]]
965                                 if dhcpmeshnet then
966                                         if not dhcpmeshnet:minhost() or not dhcpmeshnet:mask() then
967                                                 dhcpmesh.tag_missing[section] = true
968                                                 dhcpmeshnet = nil
969                                                 return
970                                         end
971                                         dhcp_ip = dhcpmeshnet:minhost():string()
972                                         dhcp_mask = dhcpmeshnet:mask():string()
973                                         dhcp_network = dhcpmeshnet:network():string()
974                                         uci:section("olsrd", "Hna4", nil, {
975                                                 netmask  = dhcp_mask,
976                                                 netaddr  = dhcp_network
977                                         })
978                                         uci:foreach("olsrd", "LoadPlugin",
979                                                 function(s)             
980                                                         if s.library == "olsrd_p2pd.so.0.1.0" then
981                                                                 uci:set("olsrd", s['.name'], "ignore", "0")
982                                                                 local nonolsr = uci:get("olsrd", s['.name'], "NonOlsrIf") or ""
983                                                                 uci:set("olsrd", s['.name'], "NonOlsrIf", device .." ".. nonolsr)
984                                                         end
985                                                 end)
986                                 else
987                                         gen_dhcp_range(netconfig.ipaddr)
988                                 end
989                                 if dhcp_ip and dhcp_mask then
990                                         -- Create alias
991                                         local aliasbase = uci:get_all("freifunk", "alias")
992                                         util.update(aliasbase, uci:get_all(community, "alias") or {})
993                                         aliasbase.interface = device
994                                         aliasbase.ipaddr = dhcp_ip
995                                         aliasbase.netmask = dhcp_mask
996                                         aliasbase.proto = "static"
997                                         uci:section("network", "alias", device .. "dhcp", aliasbase)
998                                         -- Create dhcp
999                                         local dhcpbase = uci:get_all("freifunk", "dhcp")
1000                                         util.update(dhcpbase, uci:get_all(community, "dhcp") or {})
1001                                         dhcpbase.interface = device .. "dhcp"
1002                                         dhcpbase.force = 1
1003                                         uci:section("dhcp", "dhcp", device .. "dhcp", dhcpbase)
1004                                         uci:set_list("dhcp", device .. "dhcp", "dhcp_option", "119,olsr")
1005                                         -- Create firewall settings
1006                                         uci:delete_all("firewall", "rule", {
1007                                                 src="freifunk",
1008                                                 proto="udp",
1009                                                 dest_port="53"
1010                                         })
1011                                         uci:section("firewall", "rule", nil, {
1012                                                 src="freifunk",
1013                                                 proto="udp",
1014                                                 dest_port="53",
1015                                                 target="ACCEPT"
1016                                         })
1017                                         uci:delete_all("firewall", "rule", {
1018                                                 src="freifunk",
1019                                                 proto="udp",
1020                                                 src_port="68",
1021                                                 dest_port="67"
1022                                         })
1023                                         uci:section("firewall", "rule", nil, {
1024                                                 src="freifunk",
1025                                                 proto="udp",
1026                                                 src_port="68",
1027                                                 dest_port="67",
1028                                                 target="ACCEPT"
1029                                         })
1030                                         uci:delete_all("firewall", "rule", {
1031                                                 src="freifunk",
1032                                                 proto="tcp",
1033                                                 dest_port="8082",
1034                                         })
1035                                         uci:section("firewall", "rule", nil, {
1036                                                 src="freifunk",
1037                                                 proto="tcp",
1038                                                 dest_port="8082",
1039                                                 target="ACCEPT"
1040                                         })
1041                                         -- Register splash
1042                                         uci:section("luci_splash", "iface", nil, {network=device.."dhcp", zone="freifunk"})
1043                                         uci:save("luci_splash")
1044                                         -- Make sure that luci_splash is enabled
1045                                         sys.init.enable("luci_splash")
1046                                 end
1047                         end
1048                         uci:save("wireless")
1049                         uci:save("network")
1050                         uci:save("firewall")
1051                         uci:save("dhcp")
1052                 end
1053         end)
1054         --enable radvd
1055         if has_radvd then
1056                 sys.init.enable("radvd")
1057         end
1058         -- Enforce firewall include
1059         local has_include = false
1060         uci:foreach("firewall", "include",
1061                 function(section)
1062                         if section.path == "/etc/firewall.freifunk" then
1063                                 has_include = true
1064                         end
1065                 end)
1066
1067         if not has_include then
1068                 uci:section("firewall", "include", nil,
1069                         { path = "/etc/firewall.freifunk" })
1070         end
1071         -- Allow state: invalid packets
1072         uci:foreach("firewall", "defaults",
1073                 function(section)
1074                         uci:set("firewall", section[".name"], "drop_invalid", "0")
1075                 end)
1076
1077         -- Prepare advanced config
1078         local has_advanced = false
1079         uci:foreach("firewall", "advanced",
1080                 function(section) has_advanced = true end)
1081
1082         if not has_advanced then
1083                 uci:section("firewall", "advanced", nil,
1084                         { tcp_ecn = "0", ip_conntrack_max = "8192", tcp_westwood = "1" })
1085         end
1086         uci:save("wireless")
1087         uci:save("network")
1088         uci:save("firewall")
1089         uci:save("dhcp")
1090
1091         if has_hb then
1092                 local dhcphb = hb:formvalue(section)
1093                 if dhcphb then
1094                         uci:set("manager", "heartbeat", "enabled", "1")
1095                         -- Make sure that heartbeat is enabled
1096                         sys.init.enable("machash")
1097                 else
1098                         uci:set("manager", "heartbeat", "enabled", "0")
1099                         -- Make sure that heartbeat is enabled
1100                         sys.init.disable("machash")
1101                 end
1102                 uci:save("manager")
1103         end
1104
1105         uci:foreach("system", "system",
1106                 function(s)
1107                         -- Make crond silent
1108                         uci:set("system", s['.name'], "cronloglevel", "10")
1109                         -- Make set timzone and zonename
1110                         uci:set("system", s['.name'], "zonename", "Europe/Berlin")
1111                         uci:set("system", s['.name'], "timezone", 'CET-1CEST,M3.5.0,M10.5.0/3')
1112                 end)
1113
1114         -- Create time rdate_servers
1115         local rdate = uci:get_all("freifunk", "time")
1116         uci:delete_all("system", "time")
1117         uci:section("system", "time", "rdate_servers", rdate)
1118         rdate.server = rdate.rdate_servers
1119         rdate.rdate_servers = ""
1120         uci:delete_all("system", "rdate", nil)
1121         uci:section("system", "rdate", nil, rdate)
1122         uci:save("system")
1123
1124         -- Delete old watchdog settings
1125         uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_watchdog.so.0.1"})
1126         -- Write new watchdog settings
1127         uci:section("olsrd", "LoadPlugin", nil, {
1128                 library  = "olsrd_watchdog.so.0.1",
1129                 file     = "/var/run/olsrd.watchdog",
1130                 interval = "30"
1131         })
1132
1133         -- Delete old nameservice settings
1134         uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_nameservice.so.0.3"})
1135         -- Write new nameservice settings
1136         uci:section("olsrd", "LoadPlugin", nil, {
1137                 library     = "olsrd_nameservice.so.0.3",
1138                 suffix      = "." .. suffix ,
1139                 hosts_file  = "/var/etc/hosts.olsr",
1140                 latlon_file = "/var/run/latlon.js",
1141                 lat         = lat and string.format("%.15f", lat) or "",
1142                 lon         = lon and string.format("%.15f", lon) or "",
1143                 services_file = "/var/etc/services.olsr"
1144         })
1145
1146         -- Import hosts and set domain
1147         uci:foreach("dhcp", "dnsmasq", function(s)
1148                 uci:set_list("dhcp", s[".name"], "addnhosts", "/var/etc/hosts.olsr")
1149                 uci:set("dhcp", s[".name"], "local", "/" .. suffix .. "/")
1150                 uci:set("dhcp", s[".name"], "domain", suffix)
1151         end)
1152
1153         -- Make sure that OLSR is enabled
1154         sys.init.enable("olsrd")
1155
1156         uci:save("olsrd")
1157         uci:save("dhcp")
1158         -- Import hosts and set domain
1159         if has_ipv6 then
1160                 uci:foreach("dhcp", "dnsmasq", function(s)
1161                         uci:set_list("dhcp", s[".name"], "addnhosts", {"/var/etc/hosts.olsr","/var/etc/hosts.olsr.ipv6"})
1162                 end)
1163         else
1164                 uci:foreach("dhcp", "dnsmasq", function(s)
1165                         uci:set_list("dhcp", s[".name"], "addnhosts", "/var/etc/hosts.olsr")
1166                 end)
1167         end
1168
1169         uci:save("dhcp")
1170
1171         -- Internet sharing
1172         local share_value = share:formvalue(section)
1173         if share_value == "1" then
1174                 uci:set("freifunk", "wizard", "netconfig", "1")
1175                 uci:section("firewall", "forwarding", nil, {src="freifunk", dest="wan"})
1176
1177                 if has_autoipv6 then
1178                         -- Set autoipv6 tunnel mode
1179                         uci:set("autoipv6", "olsr_node", "enable", "0")
1180                         uci:set("autoipv6", "tunnel", "enable", "1")
1181                         uci:save("autoipv6")
1182                 end
1183
1184                 -- Delete/Disable gateway plugin
1185                 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_dyn_gw.so.0.5"})
1186                 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_dyn_gw_plain.so.0.4"})
1187                 -- Enable gateway_plain plugin
1188                 uci:section("olsrd", "LoadPlugin", nil, {library="olsrd_dyn_gw_plain.so.0.4"})
1189                 sys.exec("chmod +x /etc/init.d/freifunk-p2pblock")
1190                 sys.init.enable("freifunk-p2pblock")
1191                 sys.init.enable("qos")
1192                 sys.exec('grep wan /etc/crontabs/root >/dev/null || echo "0 6 * * *     ifup wan" >> /etc/crontabs/root')
1193
1194                 if wansec:formvalue(section) == "1" then
1195                         uci:foreach("firewall", "zone",
1196                                 function(s)             
1197                                         if s.name == "wan" then
1198                                                 uci:set("firewall", s['.name'], "local_restrict", "1")
1199                                                 return false
1200                                         end
1201                                 end)
1202                 end
1203         else
1204                 uci:set("freifunk", "wizard", "netconfig", "0")
1205                 uci:save("freifunk")
1206                 if has_autoipv6 then
1207                         -- Set autoipv6 olsrd mode
1208                         uci:set("autoipv6", "olsr_node", "enable", "1")
1209                         uci:set("autoipv6", "tunnel", "enable", "0")
1210                         uci:save("autoipv6")
1211                 end
1212                 -- Delete gateway plugins
1213                 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_dyn_gw.so.0.5"})
1214                 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_dyn_gw_plain.so.0.4"})
1215                 -- Disable gateway_plain plugin
1216                 uci:section("olsrd", "LoadPlugin", nil, {
1217                         library     = "olsrd_dyn_gw_plain.so.0.4",
1218                         ignore      = 1,
1219                 })
1220                 sys.init.disable("freifunk-p2pblock")
1221                 sys.init.disable("qos")
1222                 sys.exec("chmod -x /etc/init.d/freifunk-p2pblock")
1223                 uci:delete_all("firewall", "forwarding", {src="freifunk", dest="wan"})
1224                 uci:foreach("firewall", "zone",
1225                         function(s)             
1226                                 if s.name == "wan" then
1227                                         uci:delete("firewall", s['.name'], "local_restrict")
1228                                         return false
1229                                 end
1230                         end)
1231         end
1232         -- Write gvpn dummy interface
1233         if has_l2gvpn then
1234                 if gvpn then
1235                         local vpn = gvpn:formvalue(section)
1236                         if vpn then
1237                                 uci:delete_all("l2gvpn", "l2gvpn")
1238                                 uci:delete_all("l2gvpn", "node")
1239                                 uci:delete_all("l2gvpn", "supernode")
1240                                 -- Write olsr tunnel interface options
1241                                 local olsr_gvpnifbase = uci:get_all("freifunk", "olsr_gvpninterface")
1242                                 util.update(olsr_gvpnifbase, uci:get_all(community, "olsr_gvpninterface") or {})
1243                                 uci:section("olsrd", "Interface", nil, olsr_gvpnifbase)
1244                                 local vpnip = gvpnip:formvalue(section)
1245                                 local gvpnif = uci:get_all("freifunk", "gvpn_node")
1246                                 util.update(gvpnif, uci:get_all(community, "gvpn_node") or {})
1247                                 if gvpnif and gvpnif.tundev and vpnip then
1248                                         uci:section("network", "interface", gvpnif.tundev, {
1249                                                 ifname  =gvpnif.tundev ,
1250                                                 proto   ="static" ,
1251                                                 ipaddr  =vpnip ,
1252                                                 netmask =gvpnif.subnet or "255.255.255.192" ,
1253                                         })
1254                                         gvpnif.ip=""
1255                                         gvpnif.subnet=""
1256                                         gvpnif.up=""
1257                                         gvpnif.down=""
1258                                         gvpnif.mac="00:00:48:"..string.format("%X",string.gsub( vpnip, ".*%." , "" ))..":00:00"
1259                                         tools.firewall_zone_add_interface("freifunk", gvpnif.tundev)
1260                                         uci:section("l2gvpn", "node" , gvpnif.community , gvpnif)
1261                                         uci:save("network")
1262                                         uci:save("l2gvpn")
1263                                         uci:save("firewall")
1264                                         uci:save("olsrd")
1265                                         sys.init.enable("l2gvpn")
1266                                 end
1267                         else
1268                                 -- Disable l2gvpn
1269                                 sys.exec("/etc/init.d/l2gvpn stop")
1270                                 sys.init.disable("l2gvpn")
1271                         end
1272                 end
1273         end
1274
1275         uci:save("freifunk")
1276         uci:save("firewall")
1277         uci:save("olsrd")
1278         uci:save("system")
1279 end
1280
1281 return f
1282