applications/ffwizard: rdate config not needed anymore
[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("ffwizard")
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("admin", "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 cbi_meship(dev)
94         meship = f:field(Value, "meship_" .. dev, dev:upper() .. " " .. translate("Mesh IP address"), 
95                 translate("This is a unique address in the mesh (e.g. 10.1.1.1) and has to be registered at your local community."))
96         meship:depends("device_" .. dev, "1")
97         meship.rmempty = true
98         function meship.cfgvalue(self, section)
99                 return uci:get("freifunk", "wizard", "meship_" .. dev)
100         end
101         function meship.validate(self, value)
102                 local x = ip.IPv4(value)
103                 return ( x and x:prefix() == 32 ) and x:string() or ""
104         end
105         function meship.write(self, sec, value)
106                 uci:set("freifunk", "wizard", "meship_" .. dev, value)
107         end
108 end
109
110 function cbi_meship6(dev)
111         local meship6 = f:field(Value, "meship6_" .. dev, dev:upper() .. " " .. translate("Mesh IPv6 Address"), translate("The ipv6 address is calculated auomatically."))
112         meship6:depends("device_" .. dev, "1")
113         meship6.rmempty = true
114         function meship6.cfgvalue(self, section)
115                 return get_ula(get_mac(dev))
116         end
117 end
118
119 function cbi_netconf(dev)
120         local d = f:field(Flag, "device_" .. dev , " <b>"  .. dev:upper() .. "</b>", translate("Configure this interface."))
121         d:depends("netconfig", "1")
122         d.rmempty = false
123         function d.cfgvalue(self, section)
124                 return uci:get("freifunk", "wizard", "device_" .. dev)
125         end
126         function d.write(self, sec, value)
127                 if value then
128                         uci:set("freifunk", "wizard", "device_" .. dev, value)
129                         uci:save("freifunk")
130                 end
131         end
132 end
133
134 function cbi_meshdhcp(dev)
135         local dhcpmesh = f:field(Value, "dhcpmesh_" .. dev, dev:upper() .. " " .. translate("DHCP IP range"),
136                 translate("The IP range from which clients are assigned ip addresses (e.g. 10.1.2.1/28). If this is a range inside your mesh network range, then it will be announced as HNA. Any other range will use NAT. If left empty then the defaults from the community profile will be used."))
137         dhcpmesh:depends("client_" .. dev, "1")
138         dhcpmesh.rmempty = true
139         function dhcpmesh.cfgvalue(self, section)
140                 return uci:get("freifunk", "wizard", "dhcpmesh_" .. dev)
141         end
142         function dhcpmesh.validate(self, value)
143                 local x = ip.IPv4(value)
144                 return ( x and x:prefix() <= 30 and x:minhost()) and x:string() or ""
145         end
146         function dhcpmesh.write(self, sec, value)
147                 uci:set("freifunk", "wizard", "dhcpmesh_" .. dev, value)
148                 uci:save("freifunk")
149         end
150 end
151
152 function cbi_dhcp(dev)
153         local client = f:field(Flag, "client_" .. dev, dev:upper() .. " " .. translate("Enable DHCP"), translate("DHCP will automatically assign ip addresses to clients"))
154         client:depends("device_" .. dev, "1")
155         client.rmempty = true
156         function client.cfgvalue(self, section)
157                 return uci:get("freifunk", "wizard", "client_" .. dev)
158         end
159         function client.write(self, sec, value)
160                 uci:set("freifunk", "wizard", "client_" .. dev, value)
161                 uci:save("freifunk")
162         end
163 end
164
165 function hbconf(dev)
166         if has_hb then
167                 local ifacelist = uci:get_list("manager", "heartbeat", "interface") or {}
168                 table.insert(ifacelist,dev .. "dhcp")
169                 uci:set_list("manager", "heartbeat", "interface", ifacelist)
170                 uci:save("manager")
171         end
172 end
173
174 function uci_radvd(n)
175         uci:section("radvd", "interface", nil, {
176                 interface          =n,
177                 AdvSendAdvert      =1,
178                 AdvManagedFlag     =0,
179                 AdvOtherConfigFlag =0,
180                 ignore             =0
181                 })
182         uci:section("radvd", "prefix", nil, {
183                 interface          =n,
184                 AdvOnLink          =1,
185                 AdvAutonomous      =1,
186                 AdvRouterAddr      =0,
187                 ignore             =0,
188                 })
189         uci:save("radvd")
190 end
191
192 function uci_clean_radvd (n)
193         uci:delete_all("radvd", "interface", {interface=n.."dhcp"})
194         uci:delete_all("radvd", "interface", {interface=n})
195         uci:delete_all("radvd", "prefix", {interface=n.."dhcp"})
196         uci:delete_all("radvd", "prefix", {interface=n})
197 end
198
199
200 -------------------- View --------------------
201 f = SimpleForm("ffwizward", translate("Wizard"),
202  translate("This wizard will assist you in setting up your router for Freifunk " ..
203         "or another similar wireless community network."))
204
205 -- if password is not set or default then force the user to set a new one
206 if sys.exec("diff /rom/etc/passwd /etc/passwd") == "" then
207         pw1 = f:field(Value, "pw1", translate("Password"))
208         pw1.password = true
209         pw1.rmempty = false
210
211         pw2 = f:field(Value, "pw2", translate("Password confirmation"))
212         pw2.password = true
213         pw2.rmempty = false
214
215         function pw2.validate(self, value, section)
216                 return pw1:formvalue(section) == value and value
217         end
218 end
219
220 -- main netconfig
221
222 local cc = uci:get(community, "wifi_device", "country") or "DE"
223
224 main = f:field(Flag, "netconfig", translate("Configure network"), translate("Select this checkbox to configure your network interfaces."))
225
226 uci:foreach("wireless", "wifi-device", function(section)
227         local device = section[".name"]
228         local hwtype = section.type
229         local syscc = section.country
230
231         if not syscc then
232                 if hwtype == "atheros" then
233                         cc = sys.exec("grep -i '" .. cc .. "' /lib/wifi/cc_translate.txt |cut -d ' ' -f 2") or 0
234                         sys.exec("echo " .. cc .. " > /proc/sys/dev/" .. device .. "/countrycode")
235                 elseif hwtype == "mac80211" then
236                         sys.exec("iw reg set " .. cc)
237                 elseif hwtype == "broadcom" then
238                         sys.exec ("wlc country " .. cc)
239                 end
240         else
241                 cc = syscc
242         end
243
244         cbi_netconf(device)             
245         local chan = f:field(ListValue, "chan_" .. device, device:upper() .. " " .. translate("Channel"), translate("Your device and neighbouring nodes have to use the same channel."))
246         chan:depends("device_" .. device, "1")
247         chan.rmempty = true
248         function chan.cfgvalue(self, section)
249                 return uci:get("freifunk", "wizard", "chan_" .. device)
250         end
251         chan:value('default')
252         for _, f in ipairs(sys.wifi.channels(device)) do
253                 if not f.restricted then
254                         chan:value(f.channel)
255                 end
256         end
257
258         function chan.write(self, sec, value)
259                 if value then
260                         uci:set("freifunk", "wizard", "chan_" .. device, value)
261                         uci:save("freifunk")
262                 end
263         end
264
265         cbi_meship(device)
266         if has_ipv6 then
267                 cbi_meship6(device)
268         end
269         cbi_dhcp(device)
270         cbi_meshdhcp(device)
271         local hwtype = section.type
272         if hwtype == "atheros" then
273                 local vap = f:field(Flag, "vap_" .. device , " " .. translate("Virtual Access Point (VAP)"), translate("This will setup a new virtual wireless interface in Access Point mode."))
274                 vap:depends("client_" .. device, "1")
275                 vap.rmempty = false
276                 function vap.cfgvalue(self, section)
277                         return uci:get("freifunk", "wizard", "vap_" .. device)
278                 end
279                 function vap.write(self, sec, value)
280                         uci:set("freifunk", "wizard", "vap_" .. device, value)
281                         uci:save("freifunk")
282                 end
283         end
284 end)
285
286 uci:foreach("network", "interface",     function(section)
287         local device = section[".name"]
288         local ifname = uci_state:get("network",device,"ifname")
289         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
290                 cbi_netconf(device)
291                 cbi_meship(device)
292                 if has_ipv6 then
293                         cbi_meship6(device)
294                 end
295                 cbi_dhcp(device)
296                 cbi_meshdhcp(device)
297         end
298 end)
299
300 share = f:field(Flag, "sharenet", "<b>" .. translate("Share your internet connection") .. "</b>", translate("Select this to allow others to use your connection to access the internet."))
301 share.rmempty = false
302 share:depends("netconfig", "1")
303 function share.cfgvalue(self, section)
304         return uci:get("freifunk", "wizard", "share")
305 end
306 function share.write(self, section, value)
307         uci:set("freifunk", "wizard", "share", value)
308         uci:save("freifunk")
309 end
310
311 wanproto = f:field(ListValue, "wanproto", translate("Protocol"), translate ("The protocol to use for internet connectivity."))
312 wanproto:depends("sharenet", "1")
313 wanproto:value("static", translate("static", "static"))
314 wanproto:value("dhcp", translate("dhcp", "dhcp"))
315 if has_pppoe then wanproto:value("pppoe", "PPPoE") end
316 if has_pptp  then wanproto:value("pptp",  "PPTP")  end
317 function wanproto.cfgvalue(self, section)
318         return uci:get("network", "wan", "proto") or "dhcp"
319 end
320 function wanproto.write(self, section, value)
321         uci:set("network", "wan", "proto", value)
322         uci:save("network")
323 end
324 wanip = f:field(Value, "wanipaddr", translate("IP address"))
325 wanip:depends("wanproto", "static")
326 function wanip.cfgvalue(self, section)
327         return uci:get("network", "wan", "ipaddr")
328 end
329 function wanip.write(self, section, value)
330         uci:set("network", "wan", "ipaddr", value)
331         uci:save("network")
332 end
333 wannm = f:field(Value, "wannetmask", translate("Netmask"))
334 wannm:depends("wanproto", "static")
335 function wannm.cfgvalue(self, section)
336         return uci:get("network", "wan", "netmask")
337 end
338 function wannm.write(self, section, value)
339         uci:set("network", "wan", "netmask", value)
340         uci:save("network")
341 end
342 wangw = f:field(Value, "wangateway", translate("Gateway"))
343 wangw:depends("wanproto", "static")
344 wangw.rmempty = true
345 function wangw.cfgvalue(self, section)
346         return uci:get("network", "wan", "gateway")
347 end
348 function wangw.write(self, section, value)
349         uci:set("network", "wan", "gateway", value)
350         uci:save("network")
351 end
352 wandns = f:field(Value, "wandns", translate("DNS Server"))
353 wandns:depends("wanproto", "static")
354 wandns.rmempty = true
355 function wandns.cfgvalue(self, section)
356         return uci:get("network", "wan", "dns")
357 end
358 function wandns.write(self, section, value)
359         uci:set("network", "wan", "dns", value)
360         uci:save("network")
361 end
362 wanusr = f:field(Value, "wanusername", translate("Username"))
363 wanusr:depends("wanproto", "pppoe")
364 wanusr:depends("wanproto", "pptp")
365 function wanusr.cfgvalue(self, section)
366         return uci:get("network", "wan", "username")
367 end
368 function wanusr.write(self, section, value)
369         uci:set("network", "wan", "username", value)
370         uci:save("network")
371 end
372 wanpwd = f:field(Value, "wanpassword", translate("Password"))
373 wanpwd.password = true
374 wanpwd:depends("wanproto", "pppoe")
375 wanpwd:depends("wanproto", "pptp")
376 function wanpwd.cfgvalue(self, section)
377         return uci:get("network", "wan", "password")
378 end
379 function wanpwd.write(self, section, value)
380         uci:set("network", "wan", "password", value)
381         uci:save("network")
382 end
383
384 wansec = f:field(Flag, "wansec", translate("Protect LAN"), translate("Check this to protect your LAN from other nodes or clients") .. " (" .. translate("recommended") .. ").")
385 wansec.default = "1"
386 wansec.rmempty = false
387 wansec:depends("wanproto", "static")
388 wansec:depends("wanproto", "dhcp")
389 function wansec.cfgvalue(self, section)
390         return uci:get("freifunk", "wizard", "wan_security")
391 end
392 function wansec.write(self, section, value)
393         uci:set("freifunk", "wizard", "wan_security", value)
394         uci:save("freifunk")
395 end
396 if has_qos then
397         wanqosdown = f:field(Value, "wanqosdown", translate("Limit download bandwidth"), translate("kbit/s"))
398         wanqosdown:depends("sharenet", "1")
399         function wanqosdown.cfgvalue(self, section)
400                 return uci:get("qos", "wan", "download")
401         end
402         function wanqosdown.write(self, section, value)
403                 uci:set("qos", "wan", "download", value)
404                 uci:save("qos")
405         end
406         wanqosup = f:field(Value, "wanqosup", translate("Limit upload bandwidth"), translate("kbit/s"))
407         wanqosup:depends("sharenet", "1")
408         function wanqosup.cfgvalue(self, section)
409                 return uci:get("qos", "wan", "upload")
410         end
411         function wanqosup.write(self, section, value)
412                 uci:set("qos", "wan", "upload", value)
413                 uci:save("qos")
414         end
415 end
416
417 if has_l2gvpn then
418         gvpn = f:field(Flag, "gvpn", translate("L2gvpn tunnel"), translate("Connect your node with other nodes with a tunnel via the internet."))
419         gvpn.rmempty = false
420         gvpn:depends("sharenet", "1")
421         function gvpn.cfgvalue(self, section)
422                 return uci:get("freifunk", "wizard", "gvpn")
423         end
424         function gvpn.write(self, section, value)
425                 uci:set("freifunk", "wizard", "gvpn", value)
426                 uci:save("freifunk")
427         end
428         gvpnip = f:field(Value, "gvpnipaddr", translate("IP address"))
429         gvpnip:depends("gvpn", "1")
430         function gvpnip.cfgvalue(self, section)
431                 return uci:get("l2gvpn", "bbb", "ip") or uci:get("network", "gvpn", "ipaddr")
432         end
433         function gvpnip.validate(self, value)
434                 local x = ip.IPv4(value)
435                 return ( x and x:prefix() == 32 ) and x:string() or ""
436         end
437 end
438
439 if has_hb then
440         hb = f:field(Flag, "hb", translate("Heartbeat"), translate("Allow to transfer anonymous statistics about this node") .. " (" .. translate("recommended") .. ").")
441         hb.rmempty = false
442         hb:depends("netconfig", "1")
443         function hb.cfgvalue(self, section)
444                 return uci:get("freifunk", "wizard", "hb")
445         end
446         function hb.write(self, section, value)
447                 uci:set("freifunk", "wizard", "hb", value)
448                 uci:save("freifunk")
449         end
450 end
451
452 -------------------- Control --------------------
453 function f.handle(self, state, data)
454         if state == FORM_VALID then
455                 local debug = uci:get("freifunk", "wizard", "debug")
456                 if debug == "1" then
457                         if data.pw1 then
458                                 local stat = luci.sys.user.setpasswd("root", data.pw1) == 0
459                                 if stat then
460                                         f.message = translate("Password successfully changed")
461                                 else
462                                         f.errmessage = translate("Unknown Error")
463                                 end
464                         end
465                         data.pw1 = nil
466                         data.pw2 = nil
467                         luci.http.redirect(luci.dispatcher.build_url(unpack(luci.dispatcher.context.requested.path), "system", "system"))
468                 else
469                         if data.pw1 then
470                                 local stat = luci.sys.user.setpasswd("root", data.pw1) == 0
471                         end
472                         data.pw1 = nil
473                         data.pw2 = nil
474                         uci:commit("freifunk")
475                         uci:commit("wireless")
476                         uci:commit("network")
477                         uci:commit("dhcp")
478                         uci:commit("luci_splash")
479                         uci:commit("firewall")
480                         uci:commit("system")
481                         uci:commit("olsrd")
482                         uci:commit("manager")
483                         if has_autoipv6 then
484                                 uci:commit("autoipv6")
485                         end
486                         if has_qos then
487                                 uci:commit("qos")
488                         end
489                         if has_l2gvpn then
490                                 uci:commit("l2gvpn")
491                         end
492                         if has_radvd then
493                                 uci:commit("radvd")
494                         end
495
496                         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 &" )
497                         luci.http.redirect(luci.dispatcher.build_url(luci.dispatcher.context.path[1], "freifunk", "ffwizard"))
498                 end
499                 return false
500         elseif state == FORM_INVALID then
501                 self.errmessage = "Ungültige Eingabe: Bitte die Formularfelder auf Fehler prüfen."
502         end
503         return true
504 end
505
506 local function _strip_internals(tbl)
507         tbl = tbl or {}
508         for k, v in pairs(tbl) do
509                 if k:sub(1, 1) == "." then
510                         tbl[k] = nil
511                 end
512         end
513         return tbl
514 end
515 -- Configure Freifunk checked
516 function main.write(self, section, value)
517         if value == "0" then
518                 uci:set("freifunk", "wizard", "netconfig", "0")
519                 uci:save("freifunk")
520                 return
521         end
522         -- Collect IP-Address
523         uci:set("freifunk", "wizard", "net", uci:get_first(community, "community", "mesh_network"))
524         uci:save("freifunk")
525
526         -- Invalidate fields
527         if not community then
528                 net.tag_missing[section] = true
529                 return
530         end
531
532         uci:set("freifunk", "wizard", "netconfig", "1")
533         uci:save("freifunk")
534
535         local netname = "wireless"
536         local network
537         network = ip.IPv4(uci:get_first(community, "community", "mesh_network") or "104.0.0.0/8")
538
539         -- Cleanup
540         uci:delete_all("firewall","zone", {name="freifunk"})
541         uci:delete_all("firewall","forwarding", {dest="freifunk"})
542         uci:delete_all("firewall","forwarding", {src="freifunk"})
543         uci:delete_all("firewall","rule", {dest="freifunk"})
544         uci:delete_all("firewall","rule", {src="freifunk"})
545         uci:save("firewall")
546         -- Create firewall zone and add default rules (first time)
547         -- firewall_create_zone("name"    , "input" , "output", "forward ", Masqurade)
548         local newzone = tools.firewall_create_zone("freifunk", "ACCEPT", "ACCEPT", "REJECT"  , true)
549         if newzone then
550                 uci:foreach("freifunk", "fw_forwarding", function(section)
551                         uci:section("firewall", "forwarding", nil, section)
552                 end)
553                 uci:foreach(community, "fw_forwarding", function(section)
554                         uci:section("firewall", "forwarding", nil, section)
555                 end)
556
557                 uci:foreach("freifunk", "fw_rule", function(section)
558                         uci:section("firewall", "rule", nil, section)
559                 end)
560                 uci:foreach(community, "fw_rule", function(section)
561                         uci:section("firewall", "rule", nil, section)
562                 end)
563         end
564         uci:save("firewall")
565         if has_hb then
566                 uci:delete("manager", "heartbeat", "interface")
567                 uci:save("manager")
568         end
569         -- Delete olsrdv4
570         uci:delete_all("olsrd", "olsrd")
571         local olsrbase
572         olsrbase = uci:get_all("freifunk", "olsrd") or {}
573         util.update(olsrbase, uci:get_all(community, "olsrd") or {})
574         if has_ipv6 then
575                 olsrbase.IpVersion='6and4'
576         else
577                 olsrbase.IpVersion='4'
578         end
579         uci:section("olsrd", "olsrd", nil, olsrbase)
580         -- Delete olsrdv4 old p2pd settings
581         uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_mdns.so.1.0.0"})
582         uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_p2pd.so.0.1.0"})
583         -- Write olsrdv4 new p2pd settings
584         uci:section("olsrd", "LoadPlugin", nil, {
585                 library     = "olsrd_p2pd.so.0.1.0",
586                 P2pdTtl     = 10,
587                 UdpDestPort = "224.0.0.251 5353",
588                 ignore      = 1,
589         })
590         -- Delete http plugin
591         uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_httpinfo.so.0.1"})
592
593         -- Delete olsrdv4 old interface
594         uci:delete_all("olsrd", "Interface")
595         uci:delete_all("olsrd", "Hna4")
596         -- Create wireless ip4/ip6 and firewall config
597         uci:foreach("wireless", "wifi-device",
598         function(sec)
599                 local device = sec[".name"]
600                 if not luci.http.formvalue("cbid.ffwizward.1.device_" .. device) then
601                         return
602                 end
603                 node_ip = luci.http.formvalue("cbid.ffwizward.1.meship_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.meship_" .. device))
604                 if has_ipv6 then
605                         node_ip6 = luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device) and ip.IPv6(luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device))
606                 end
607                 if not node_ip or not network or not network:contains(node_ip) then
608                         meship.tag_missing[section] = true
609                         node_ip = nil
610                         return
611                 end
612                 -- rename the wireless interface s/wifi/wireless/
613                 local nif
614                 if string.find(device, "wifi") then
615                         nif = string.gsub(device,"wifi", netname)
616                 elseif string.find(device, "wl") then
617                         nif = string.gsub(device,"wl", netname)
618                 elseif string.find(device, "wlan") then
619                         nif = string.gsub(device,"wlan", netname)
620                 elseif string.find(device, "radio") then
621                         nif = string.gsub(device,"radio", netname)
622                 end
623                 -- Cleanup
624                 tools.wifi_delete_ifaces(device)
625                 -- tools.network_remove_interface(device)
626                 uci:delete("network", device .. "dhcp")
627                 uci:delete("network", device)
628                 tools.firewall_zone_remove_interface("freifunk", device)
629                 -- tools.network_remove_interface(nif)
630                 uci:delete("network", nif .. "dhcp")
631                 uci:delete("network", nif)
632                 tools.firewall_zone_remove_interface("freifunk", nif)
633                 -- Delete old dhcp
634                 uci:delete("dhcp", device)
635                 uci:delete("dhcp", device .. "dhcp")
636                 uci:delete("dhcp", nif)
637                 uci:delete("dhcp", nif .. "dhcp")
638                 -- Delete old splash
639                 uci:delete_all("luci_splash", "iface", {network=device.."dhcp", zone="freifunk"})
640                 uci:delete_all("luci_splash", "iface", {network=nif.."dhcp", zone="freifunk"})
641                 -- Delete old radvd
642                 if has_radvd then
643                         uci_clean_radvd(nif)
644                 end
645                 -- New Config
646                 -- Tune wifi device
647                 local ssid = uci:get_first(community, "community", "ssid") or "olsr.freifunk.net"
648                 local devconfig = uci:get_all("freifunk", "wifi_device")
649                 util.update(devconfig, uci:get_all(community, "wifi_device") or {})
650                 local channel = luci.http.formvalue("cbid.ffwizward.1.chan_" .. device)
651                 local hwmode = "11bg"
652                 local bssid = uci:get_all(community, "wifi_iface", "bssid") or "02:CA:FF:EE:BA:BE"
653                 local mrate = 5500
654                 devconfig.diversity = sec.diversity or "1"
655                 if sec.txantenna then
656                         devconfig.txantenna = sec.txantenna
657                 end
658                 if sec.rxantenna then
659                         devconfig.rxantenna = sec.rxantenna
660                 end
661
662                 -- set bssid, see https://kifuse02.pberg.freifunk.net/moin/channel-bssid-essid for schema
663                 if channel and channel ~= "default" then
664                         if devconfig.channel ~= channel then
665                                 devconfig.channel = channel
666                                 local chan = tonumber(channel)
667                                 if chan >= 0 and chan < 10 then
668                                         bssid = channel .. "2:CA:FF:EE:BA:BE"
669                                 elseif chan == 10 then 
670                                         bssid = "02:CA:FF:EE:BA:BE" 
671                                 elseif chan >= 11 and chan <= 14 then
672                                         bssid = string.format("%X",channel) .. "2:CA:FF:EE:BA:BE"
673                                 elseif chan >= 36 and chan <= 64 then
674                                         hwmode = "11a"
675                                         mrate = ""
676                                         bssid = "00:" .. channel ..":CA:FF:EE:EE"
677                                 elseif chan >= 100 and chan <= 140 then
678                                         hwmode = "11a"
679                                         mrate = ""
680                                         bssid = "01:" .. string.sub(channel, 2) .. ":CA:FF:EE:EE"
681                                 end
682                                 devconfig.hwmode = hwmode
683                         end
684                         devconfig.country = cc
685                         ssid = ssid .. " - ch" .. channel
686                 end
687                 uci:tset("wireless", device, devconfig)
688                 -- Create wifi iface
689                 local ifconfig = uci:get_all("freifunk", "wifi_iface")
690                 util.update(ifconfig, uci:get_all(community, "wifi_iface") or {})
691                 ifconfig.device = device
692                 ifconfig.network = nif
693                 ifconfig.ssid = ssid
694                 ifconfig.bssid = bssid
695                 ifconfig.encryption="none"
696                 -- Read Preset 
697                 local netconfig = uci:get_all("freifunk", "interface")
698                 util.update(netconfig, uci:get_all(community, "interface") or {})
699                 netconfig.proto = "static"
700                 netconfig.ipaddr = node_ip:string()
701                 if has_ipv6 then
702                         netconfig.ip6addr = node_ip6:string()
703                 end
704                 uci:section("network", "interface", nif, netconfig)
705                 if has_radvd then
706                         uci_radvd(nif)
707                 end
708                 tools.firewall_zone_add_interface("freifunk", nif)
709                 uci:save("firewall")
710                 -- Write new olsrv4 interface
711                 local olsrifbase = uci:get_all("freifunk", "olsr_interface")
712                 util.update(olsrifbase, uci:get_all(community, "olsr_interface") or {})
713                 olsrifbase.interface = nif
714                 olsrifbase.ignore    = "0"
715                 uci:section("olsrd", "Interface", nil, olsrifbase)
716                 -- Collect MESH DHCP IP NET
717                 local client = luci.http.formvalue("cbid.ffwizward.1.client_" .. device)
718                 if client then
719                         local dhcpmeshnet = luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device))
720                         hbconf(nif)
721                         if dhcpmeshnet then
722                                 if not dhcpmeshnet:minhost() or not dhcpmeshnet:mask() then
723                                         dhcpmesh.tag_missing[section] = true
724                                         dhcpmeshnet = nil
725                                         return
726                                 end
727                                 dhcp_ip = dhcpmeshnet:minhost():string()
728                                 dhcp_mask = dhcpmeshnet:mask():string()
729                                 dhcp_network = dhcpmeshnet:network():string()
730                                 uci:section("olsrd", "Hna4", nil, {
731                                         netmask  = dhcp_mask,
732                                         netaddr  = dhcp_network
733                                 })
734                                 uci:foreach("olsrd", "LoadPlugin",
735                                         function(s)             
736                                                 if s.library == "olsrd_p2pd.so.0.1.0" then
737                                                         uci:set("olsrd", s['.name'], "ignore", "0")
738                                                         local nonolsr = uci:get("olsrd", s['.name'], "NonOlsrIf") or ""
739                                                         vap = luci.http.formvalue("cbid.ffwizward.1.vap_" .. device)
740                                                         if vap then
741                                                                 nonolsr = nif.."dhcp "..nonolsr
742                                                         else
743                                                                 nonolsr = nif.." "..nonolsr
744                                                         end
745                                                         uci:set("olsrd", s['.name'], "NonOlsrIf", nonolsr)
746                                                 end
747                                         end)
748                         else
749                                 gen_dhcp_range(netconfig.ipaddr)
750                         end
751                         if dhcp_ip and dhcp_mask then
752                                 -- Create alias
753                                 local aliasbase = uci:get_all("freifunk", "alias")
754                                 util.update(aliasbase, uci:get_all(community, "alias") or {})
755                                 aliasbase.ipaddr = dhcp_ip
756                                 aliasbase.netmask = dhcp_mask
757                                 aliasbase.proto = "static"
758                                 vap = luci.http.formvalue("cbid.ffwizward.1.vap_" .. device)
759                                 if vap then
760                                         uci:section("network", "interface", nif .. "dhcp", aliasbase)
761                                         uci:section("wireless", "wifi-iface", nil, {
762                                                 device     =device,
763                                                 mode       ="ap",
764                                                 encryption ="none",
765                                                 network    =nif .. "dhcp",
766                                                 ssid       ="AP-" .. ssid
767                                         })
768                                         if has_radvd then
769                                                 uci_radvd(nif .. "dhcp")
770                                         end
771                                         tools.firewall_zone_add_interface("freifunk", nif .. "dhcp")
772                                         uci:save("wireless")
773                                         ifconfig.mcast_rate = nil
774                                         ifconfig.encryption="none"
775                                 else
776                                         aliasbase.interface = nif
777                                         uci:section("network", "alias", nif .. "dhcp", aliasbase)
778                                 end
779                                 -- Create dhcp
780                                 local dhcpbase = uci:get_all("freifunk", "dhcp")
781                                 util.update(dhcpbase, uci:get_all(community, "dhcp") or {})
782                                 dhcpbase.interface = nif .. "dhcp"
783                                 dhcpbase.force = 1
784                                 uci:section("dhcp", "dhcp", nif .. "dhcp", dhcpbase)
785                                 uci:set_list("dhcp", nif .. "dhcp", "dhcp_option", "119,olsr")
786                                 -- Create firewall settings
787                                 uci:delete_all("firewall", "rule", {
788                                         src="freifunk",
789                                         proto="udp",
790                                         dest_port="53"
791                                 })
792                                 uci:section("firewall", "rule", nil, {
793                                         src="freifunk",
794                                         proto="udp",
795                                         dest_port="53",
796                                         target="ACCEPT"
797                                 })
798                                 uci:delete_all("firewall", "rule", {
799                                         src="freifunk",
800                                         proto="udp",
801                                         src_port="68",
802                                         dest_port="67"
803                                 })
804                                 uci:section("firewall", "rule", nil, {
805                                         src="freifunk",
806                                         proto="udp",
807                                         src_port="68",
808                                         dest_port="67",
809                                         target="ACCEPT"
810                                 })
811                                 uci:delete_all("firewall", "rule", {
812                                         src="freifunk",
813                                         proto="tcp",
814                                         dest_port="8082",
815                                 })
816                                 uci:section("firewall", "rule", nil, {
817                                         src="freifunk",
818                                         proto="tcp",
819                                         dest_port="8082",
820                                         target="ACCEPT"
821                                 })
822                                 -- Register splash
823                                 uci:section("luci_splash", "iface", nil, {network=nif.."dhcp", zone="freifunk"})
824                                 uci:save("luci_splash")
825                                 -- Make sure that luci_splash is enabled
826                                 sys.init.enable("luci_splash")
827                         end
828                 else
829                         -- Delete old splash
830                         uci:delete_all("luci_splash", "iface", {network=device.."dhcp", zone="freifunk"})
831                 end
832                 --Write Ad-Hoc wifi section after AP wifi section
833                 uci:section("wireless", "wifi-iface", nil, ifconfig)
834                 uci:save("network")
835                 uci:save("wireless")
836                 uci:save("network")
837                 uci:save("firewall")
838                 uci:save("dhcp")
839         end)
840         -- Create wired ip and firewall config
841         uci:foreach("network", "interface",
842                 function(sec)
843                 local device = sec[".name"]
844                 if not luci.http.formvalue("cbid.ffwizward.1.device_" .. device) then
845                         return
846                 end
847                 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
848                         local node_ip
849                         node_ip = luci.http.formvalue("cbid.ffwizward.1.meship_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.meship_" .. device))
850                         if has_ipv6 then
851                                 node_ip6 = luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device) --and ip.IPv6(luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device))
852                         end
853                         if not node_ip or not network or not network:contains(node_ip) then
854                                 meship.tag_missing[section] = true
855                                 node_ip = nil
856                                 return
857                         end
858                         -- Cleanup
859                         tools.firewall_zone_remove_interface(device, device)
860                         uci:delete_all("firewall","zone", {name=device})
861                         uci:delete_all("firewall","forwarding", {src=device})
862                         uci:delete_all("firewall","forwarding", {dest=device})
863                         uci:delete("network", device .. "dhcp")
864                         -- Delete old dhcp
865                         uci:delete("dhcp", device)
866                         uci:delete("dhcp", device .. "dhcp")
867                         -- Delete old splash
868                         uci:delete_all("luci_splash", "iface", {network=device.."dhcp", zone="freifunk"})
869                         if has_radvd then
870                                 uci_clean_radvd(device)
871                         end
872                         -- New Config
873                         local netconfig = uci:get_all("freifunk", "interface")
874                         util.update(netconfig, uci:get_all(community, "interface") or {})
875                         netconfig.proto = "static"
876                         netconfig.ipaddr = node_ip:string()
877                         if has_ipv6 then
878                                 netconfig.ip6addr = node_ip6:string()
879                         end
880                         uci:section("network", "interface", device, netconfig)
881                         uci:save("network")
882                         if has_radvd then
883                                 uci_radvd(device)
884                         end
885                         tools.firewall_zone_add_interface("freifunk", device)
886                         uci:save("firewall")
887                         -- Write new olsrv4 interface
888                         local olsrifbase = uci:get_all("freifunk", "olsr_interface")
889                         util.update(olsrifbase, uci:get_all(community, "olsr_interface") or {})
890                         olsrifbase.interface = device
891                         olsrifbase.ignore    = "0"
892                         uci:section("olsrd", "Interface", nil, olsrifbase)
893                         olsrifbase.Mode = 'ether'
894                         -- Collect MESH DHCP IP NET
895                         local client = luci.http.formvalue("cbid.ffwizward.1.client_" .. device)
896                         if client then
897                                 local dhcpmeshnet = luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device))
898                                 hbconf(device)
899
900                                 if dhcpmeshnet then
901                                         if not dhcpmeshnet:minhost() or not dhcpmeshnet:mask() then
902                                                 dhcpmesh.tag_missing[section] = true
903                                                 dhcpmeshnet = nil
904                                                 return
905                                         end
906                                         dhcp_ip = dhcpmeshnet:minhost():string()
907                                         dhcp_mask = dhcpmeshnet:mask():string()
908                                         dhcp_network = dhcpmeshnet:network():string()
909                                         uci:section("olsrd", "Hna4", nil, {
910                                                 netmask  = dhcp_mask,
911                                                 netaddr  = dhcp_network
912                                         })
913                                         uci:foreach("olsrd", "LoadPlugin",
914                                                 function(s)             
915                                                         if s.library == "olsrd_p2pd.so.0.1.0" then
916                                                                 uci:set("olsrd", s['.name'], "ignore", "0")
917                                                                 local nonolsr = uci:get("olsrd", s['.name'], "NonOlsrIf") or ""
918                                                                 uci:set("olsrd", s['.name'], "NonOlsrIf", device .." ".. nonolsr)
919                                                         end
920                                                 end)
921                                 else
922                                         gen_dhcp_range(netconfig.ipaddr)
923                                 end
924                                 if dhcp_ip and dhcp_mask then
925                                         -- Create alias
926                                         local aliasbase = uci:get_all("freifunk", "alias")
927                                         util.update(aliasbase, uci:get_all(community, "alias") or {})
928                                         aliasbase.interface = device
929                                         aliasbase.ipaddr = dhcp_ip
930                                         aliasbase.netmask = dhcp_mask
931                                         aliasbase.proto = "static"
932                                         uci:section("network", "alias", device .. "dhcp", aliasbase)
933                                         -- Create dhcp
934                                         local dhcpbase = uci:get_all("freifunk", "dhcp")
935                                         util.update(dhcpbase, uci:get_all(community, "dhcp") or {})
936                                         dhcpbase.interface = device .. "dhcp"
937                                         dhcpbase.force = 1
938                                         uci:section("dhcp", "dhcp", device .. "dhcp", dhcpbase)
939                                         uci:set_list("dhcp", device .. "dhcp", "dhcp_option", "119,olsr")
940                                         -- Create firewall settings
941                                         uci:delete_all("firewall", "rule", {
942                                                 src="freifunk",
943                                                 proto="udp",
944                                                 dest_port="53"
945                                         })
946                                         uci:section("firewall", "rule", nil, {
947                                                 src="freifunk",
948                                                 proto="udp",
949                                                 dest_port="53",
950                                                 target="ACCEPT"
951                                         })
952                                         uci:delete_all("firewall", "rule", {
953                                                 src="freifunk",
954                                                 proto="udp",
955                                                 src_port="68",
956                                                 dest_port="67"
957                                         })
958                                         uci:section("firewall", "rule", nil, {
959                                                 src="freifunk",
960                                                 proto="udp",
961                                                 src_port="68",
962                                                 dest_port="67",
963                                                 target="ACCEPT"
964                                         })
965                                         uci:delete_all("firewall", "rule", {
966                                                 src="freifunk",
967                                                 proto="tcp",
968                                                 dest_port="8082",
969                                         })
970                                         uci:section("firewall", "rule", nil, {
971                                                 src="freifunk",
972                                                 proto="tcp",
973                                                 dest_port="8082",
974                                                 target="ACCEPT"
975                                         })
976                                         -- Register splash
977                                         uci:section("luci_splash", "iface", nil, {network=device.."dhcp", zone="freifunk"})
978                                         uci:save("luci_splash")
979                                         -- Make sure that luci_splash is enabled
980                                         sys.init.enable("luci_splash")
981                                 end
982                         end
983                         uci:save("wireless")
984                         uci:save("network")
985                         uci:save("firewall")
986                         uci:save("dhcp")
987                 end
988         end)
989         --enable radvd
990         if has_radvd then
991                 sys.init.enable("radvd")
992         end
993         -- Enforce firewall include
994         local has_include = false
995         uci:foreach("firewall", "include",
996                 function(section)
997                         if section.path == "/etc/firewall.freifunk" then
998                                 has_include = true
999                         end
1000                 end)
1001
1002         if not has_include then
1003                 uci:section("firewall", "include", nil,
1004                         { path = "/etc/firewall.freifunk" })
1005         end
1006         -- Allow state: invalid packets
1007         uci:foreach("firewall", "defaults",
1008                 function(section)
1009                         uci:set("firewall", section[".name"], "drop_invalid", "0")
1010                 end)
1011
1012         -- Prepare advanced config
1013         local has_advanced = false
1014         uci:foreach("firewall", "advanced",
1015                 function(section) has_advanced = true end)
1016
1017         if not has_advanced then
1018                 uci:section("firewall", "advanced", nil,
1019                         { tcp_ecn = "0", ip_conntrack_max = "8192", tcp_westwood = "1" })
1020         end
1021         uci:save("wireless")
1022         uci:save("network")
1023         uci:save("firewall")
1024         uci:save("dhcp")
1025
1026         if has_hb then
1027                 local dhcphb = hb:formvalue(section)
1028                 if dhcphb then
1029                         uci:set("manager", "heartbeat", "enabled", "1")
1030                         -- Make sure that heartbeat is enabled
1031                         sys.init.enable("machash")
1032                 else
1033                         uci:set("manager", "heartbeat", "enabled", "0")
1034                         -- Make sure that heartbeat is enabled
1035                         sys.init.disable("machash")
1036                 end
1037                 uci:save("manager")
1038         end
1039
1040         uci:foreach("system", "system",
1041                 function(s)
1042                         -- Make crond silent
1043                         uci:set("system", s['.name'], "cronloglevel", "10")
1044                         -- Make set timzone and zonename
1045                         uci:set("system", s['.name'], "zonename", "Europe/Berlin")
1046                         uci:set("system", s['.name'], "timezone", 'CET-1CEST,M3.5.0,M10.5.0/3')
1047                 end)
1048         uci:save("system")
1049
1050         -- Delete old watchdog settings
1051         uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_watchdog.so.0.1"})
1052         -- Write new watchdog settings
1053         uci:section("olsrd", "LoadPlugin", nil, {
1054                 library  = "olsrd_watchdog.so.0.1",
1055                 file     = "/var/run/olsrd.watchdog",
1056                 interval = "30"
1057         })
1058
1059         -- Delete old nameservice settings
1060         uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_nameservice.so.0.3"})
1061         -- Write new nameservice settings
1062         uci:section("olsrd", "LoadPlugin", nil, {
1063                 library     = "olsrd_nameservice.so.0.3",
1064                 suffix      = "." .. suffix ,
1065                 hosts_file  = "/var/etc/hosts.olsr",
1066                 latlon_file = "/var/run/latlon.js",
1067                 lat         = lat and string.format("%.15f", lat) or "",
1068                 lon         = lon and string.format("%.15f", lon) or "",
1069                 services_file = "/var/etc/services.olsr"
1070         })
1071
1072         -- Import hosts and set domain
1073         uci:foreach("dhcp", "dnsmasq", function(s)
1074                 uci:set_list("dhcp", s[".name"], "addnhosts", "/var/etc/hosts.olsr")
1075                 uci:set("dhcp", s[".name"], "local", "/" .. suffix .. "/")
1076                 uci:set("dhcp", s[".name"], "domain", suffix)
1077         end)
1078
1079         -- Make sure that OLSR is enabled
1080         sys.init.enable("olsrd")
1081
1082         uci:save("olsrd")
1083         uci:save("dhcp")
1084         -- Import hosts and set domain
1085         if has_ipv6 then
1086                 uci:foreach("dhcp", "dnsmasq", function(s)
1087                         uci:set_list("dhcp", s[".name"], "addnhosts", {"/var/etc/hosts.olsr","/var/etc/hosts.olsr.ipv6"})
1088                 end)
1089         else
1090                 uci:foreach("dhcp", "dnsmasq", function(s)
1091                         uci:set_list("dhcp", s[".name"], "addnhosts", "/var/etc/hosts.olsr")
1092                 end)
1093         end
1094
1095         uci:save("dhcp")
1096
1097         -- Internet sharing
1098         local share_value = share:formvalue(section)
1099         if share_value == "1" then
1100                 uci:set("freifunk", "wizard", "netconfig", "1")
1101                 uci:section("firewall", "forwarding", nil, {src="freifunk", dest="wan"})
1102
1103                 if has_autoipv6 then
1104                         -- Set autoipv6 tunnel mode
1105                         uci:set("autoipv6", "olsr_node", "enable", "0")
1106                         uci:set("autoipv6", "tunnel", "enable", "1")
1107                         uci:save("autoipv6")
1108                 end
1109
1110                 -- Delete/Disable gateway plugin
1111                 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_dyn_gw.so.0.5"})
1112                 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_dyn_gw_plain.so.0.4"})
1113                 -- Enable gateway_plain plugin
1114                 uci:section("olsrd", "LoadPlugin", nil, {library="olsrd_dyn_gw_plain.so.0.4"})
1115                 sys.exec("chmod +x /etc/init.d/freifunk-p2pblock")
1116                 sys.init.enable("freifunk-p2pblock")
1117                 sys.init.enable("qos")
1118                 sys.exec('grep wan /etc/crontabs/root >/dev/null || echo "0 6 * * *     ifup wan" >> /etc/crontabs/root')
1119
1120                 if wansec:formvalue(section) == "1" then
1121                         uci:foreach("firewall", "zone",
1122                                 function(s)             
1123                                         if s.name == "wan" then
1124                                                 uci:set("firewall", s['.name'], "local_restrict", "1")
1125                                                 return false
1126                                         end
1127                                 end)
1128                 end
1129         else
1130                 uci:set("freifunk", "wizard", "netconfig", "0")
1131                 uci:save("freifunk")
1132                 if has_autoipv6 then
1133                         -- Set autoipv6 olsrd mode
1134                         uci:set("autoipv6", "olsr_node", "enable", "1")
1135                         uci:set("autoipv6", "tunnel", "enable", "0")
1136                         uci:save("autoipv6")
1137                 end
1138                 -- Delete gateway plugins
1139                 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_dyn_gw.so.0.5"})
1140                 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_dyn_gw_plain.so.0.4"})
1141                 -- Disable gateway_plain plugin
1142                 uci:section("olsrd", "LoadPlugin", nil, {
1143                         library     = "olsrd_dyn_gw_plain.so.0.4",
1144                         ignore      = 1,
1145                 })
1146                 sys.init.disable("freifunk-p2pblock")
1147                 sys.init.disable("qos")
1148                 sys.exec("chmod -x /etc/init.d/freifunk-p2pblock")
1149                 uci:delete_all("firewall", "forwarding", {src="freifunk", dest="wan"})
1150                 uci:foreach("firewall", "zone",
1151                         function(s)             
1152                                 if s.name == "wan" then
1153                                         uci:delete("firewall", s['.name'], "local_restrict")
1154                                         return false
1155                                 end
1156                         end)
1157         end
1158         -- Write gvpn dummy interface
1159         if has_l2gvpn then
1160                 if gvpn then
1161                         local vpn = gvpn:formvalue(section)
1162                         if vpn then
1163                                 uci:delete_all("l2gvpn", "l2gvpn")
1164                                 uci:delete_all("l2gvpn", "node")
1165                                 uci:delete_all("l2gvpn", "supernode")
1166                                 -- Write olsr tunnel interface options
1167                                 local olsr_gvpnifbase = uci:get_all("freifunk", "olsr_gvpninterface")
1168                                 util.update(olsr_gvpnifbase, uci:get_all(community, "olsr_gvpninterface") or {})
1169                                 uci:section("olsrd", "Interface", nil, olsr_gvpnifbase)
1170                                 local vpnip = gvpnip:formvalue(section)
1171                                 local gvpnif = uci:get_all("freifunk", "gvpn_node")
1172                                 util.update(gvpnif, uci:get_all(community, "gvpn_node") or {})
1173                                 if gvpnif and gvpnif.tundev and vpnip then
1174                                         uci:section("network", "interface", gvpnif.tundev, {
1175                                                 ifname  =gvpnif.tundev ,
1176                                                 proto   ="static" ,
1177                                                 ipaddr  =vpnip ,
1178                                                 netmask =gvpnif.subnet or "255.255.255.192" ,
1179                                         })
1180                                         gvpnif.ip=""
1181                                         gvpnif.subnet=""
1182                                         gvpnif.up=""
1183                                         gvpnif.down=""
1184                                         gvpnif.mac="00:00:48:"..string.format("%X",string.gsub( vpnip, ".*%." , "" ))..":00:00"
1185                                         tools.firewall_zone_add_interface("freifunk", gvpnif.tundev)
1186                                         uci:section("l2gvpn", "node" , gvpnif.community , gvpnif)
1187                                         uci:save("network")
1188                                         uci:save("l2gvpn")
1189                                         uci:save("firewall")
1190                                         uci:save("olsrd")
1191                                         sys.init.enable("l2gvpn")
1192                                 end
1193                         else
1194                                 -- Disable l2gvpn
1195                                 sys.exec("/etc/init.d/l2gvpn stop")
1196                                 sys.init.disable("l2gvpn")
1197                         end
1198                 end
1199         end
1200
1201         uci:save("freifunk")
1202         uci:save("firewall")
1203         uci:save("olsrd")
1204         uci:save("system")
1205 end
1206
1207 return f
1208