2 LuCI - Lua Configuration Interface
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>
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
13 http://www.apache.org/licenses/LICENSE-2.0
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"
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"
39 luci.i18n.loadc("freifunk")
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"))
48 if string.find(ix, "radio") then
49 ix = string.gsub(ix,"radio", 'wlan')
51 local mac = fs.readfile("/sys/class/net/" .. ix .. "/address")
53 mac = luci.util.exec("ifconfig " .. ix)
54 mac = mac and mac:match(" ([A-F0-9:]+)%s*\n")
58 if mac and #mac > 0 then
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'
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)
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))
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()
95 local ifacelist = uci:get_list("manager", "heartbeat", "interface") or {}
96 table.insert(ifacelist,dev .. "dhcp")
97 uci:set_list("manager", "heartbeat", "interface", ifacelist)
102 -------------------- View --------------------
103 f = SimpleForm("ffwizward", "Freifunkassistent",
104 "Dieser Assistent unterstützt Sie bei der Einrichtung des Routers für das Freifunknetz.")
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"))
112 pw2 = f:field(Value, "pw2", translate("confirmation"))
116 function pw2.validate(self, value, section)
117 return pw1:formvalue(section) == value and value
123 local cc = uci:get(community, "wifi_device", "country") or "DE"
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",
128 local device = section[".name"]
129 local hwtype = section.type
131 local syscc = uci:get("wireless", device, "country")
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)
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")
149 function dev.cfgvalue(self, section)
150 return uci:get("freifunk", "wizard", "device_" .. device)
152 function dev.write(self, sec, value)
154 uci:set("freifunk", "wizard", "device_" .. device, value)
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")
161 function chan.cfgvalue(self, section)
162 return uci:get("freifunk", "wizard", "chan_" .. device)
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)
172 function chan.write(self, sec, value)
174 uci:set("freifunk", "wizard", "chan_" .. device, value)
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)
185 function meship.validate(self, value)
186 local x = ip.IPv4(value)
187 return ( x and x:prefix() == 32 ) and x:string() or ""
189 function meship.write(self, sec, value)
190 uci:set("freifunk", "wizard", "meship_" .. device, value)
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))
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)
207 function client.write(self, sec, value)
208 uci:set("freifunk", "wizard", "client_" .. device, value)
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)
217 function dhcpmesh.validate(self, value)
218 local x = ip.IPv4(value)
219 return ( x and x:minhost()) and x:string() or ""
221 function dhcpmesh.write(self, sec, value)
222 uci:set("freifunk", "wizard", "dhcpmesh_" .. device, value)
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")
230 function vap.cfgvalue(self, section)
231 return uci:get("freifunk", "wizard", "vap_" .. device)
233 function vap.write(self, sec, value)
234 uci:set("freifunk", "wizard", "vap_" .. device, value)
240 uci:foreach("network", "interface",
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")
248 function dev.cfgvalue(self, section)
249 return uci:get("freifunk", "wizard", "device_" .. device)
251 function dev.write(self, sec, value)
252 uci:set("freifunk", "wizard", "device_" .. device, value)
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)
261 function meship.validate(self, value)
262 local x = ip.IPv4(value)
263 return ( x and x:prefix() == 32 ) and x:string() or ""
265 function meship.write(self, sec, value)
266 uci:set("freifunk", "wizard", "meship_" .. device, value)
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))
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)
283 function client.write(self, sec, value)
284 uci:set("freifunk", "wizard", "client_" .. device, value)
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)
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 ""
297 function dhcpmesh.write(self, sec, value)
298 uci:set("freifunk", "wizard", "dhcpmesh_" .. device, value)
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")
310 function share.write(self, section, value)
311 uci:set("freifunk", "wizard", "share", value)
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"
324 function wanproto.write(self, section, value)
325 uci:set("network", "wan", "proto", value)
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")
333 function wanip.write(self, section, value)
334 uci:set("network", "wan", "ipaddr", value)
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")
342 function wannm.write(self, section, value)
343 uci:set("network", "wan", "netmask", value)
346 wangw = f:field(Value, "wangateway", translate("gateway"))
347 wangw:depends("wanproto", "static")
349 function wangw.cfgvalue(self, section)
350 return uci:get("network", "wan", "gateway")
352 function wangw.write(self, section, value)
353 uci:set("network", "wan", "gateway", value)
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")
362 function wandns.write(self, section, value)
363 uci:set("network", "wan", "dns", value)
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")
372 function wanusr.write(self, section, value)
373 uci:set("network", "wan", "username", value)
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")
383 function wanpwd.write(self, section, value)
384 uci:set("network", "wan", "password", value)
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")
395 function wansec.write(self, section, value)
396 uci:set("freifunk", "wizard", "wan_security", value)
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")
405 function wanqosdown.write(self, section, value)
406 uci:set("qos", "wan", "download", value)
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")
414 function wanqosup.write(self, section, value)
415 uci:set("qos", "wan", "upload", value)
421 gvpn = f:field(Flag, "gvpn", "Freifunk Internet Tunnel", "Verbinden Sie ihren Router ueber das Internet mit anderen Freifunknetzen.")
423 gvpn:depends("sharenet", "1")
424 function gvpn.cfgvalue(self, section)
425 return uci:get("freifunk", "wizard", "gvpn")
427 function gvpn.write(self, section, value)
428 uci:set("freifunk", "wizard", "gvpn", value)
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")
436 function gvpnip.validate(self, value)
437 local x = ip.IPv4(value)
438 return ( x and x:prefix() == 32 ) and x:string() or ""
443 hb = f:field(Flag, "hb", "Heartbeat aktivieren","Dem Gerät erlauben anonyme Statistiken zu übertragen. (empfohlen)")
445 hb:depends("netconfig", "1")
446 function hb.cfgvalue(self, section)
447 return uci:get("freifunk", "wizard", "hb")
449 function hb.write(self, section, value)
450 uci:set("freifunk", "wizard", "hb", value)
455 -------------------- Control --------------------
456 function f.handle(self, state, data)
457 if state == FORM_VALID then
458 local debug = uci:get("freifunk", "wizard", "debug")
461 local stat = luci.sys.user.setpasswd("root", data.pw1) == 0
463 f.message = translate("a_s_changepw_changed")
465 f.errmessage = translate("unknownerror")
470 luci.http.redirect(luci.dispatcher.build_url(unpack(luci.dispatcher.context.requested.path), "system", "system"))
473 local stat = luci.sys.user.setpasswd("root", data.pw1) == 0
477 uci:commit("freifunk")
478 uci:commit("wireless")
479 uci:commit("network")
481 uci:commit("luci_splash")
482 uci:commit("firewall")
485 uci:commit("manager")
487 uci:commit("autoipv6")
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"))
503 elseif state == FORM_INVALID then
504 self.errmessage = "Ungültige Eingabe: Bitte die Formularfelder auf Fehler prüfen."
509 local function _strip_internals(tbl)
511 for k, v in pairs(tbl) do
512 if k:sub(1, 1) == "." then
518 -- Configure Freifunk checked
519 function main.write(self, section, value)
521 uci:set("freifunk", "wizard", "netconfig", "0")
525 -- Collect IP-Address
526 uci:set("freifunk", "wizard", "net", uci:get_first(community, "community", "mesh_network"))
530 if not community then
531 net.tag_missing[section] = true
535 uci:set("freifunk", "wizard", "netconfig", "1")
538 local netname = "wireless"
540 network = ip.IPv4(uci:get_first(community, "community", "mesh_network") or "104.0.0.0/8")
542 -- Tune community settings
543 -- if community and uci:get("freifunk", community) then
544 -- uci:get_all(community)
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"})
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)
558 uci:foreach("freifunk", "fw_forwarding", function(section)
559 uci:section("firewall", "forwarding", nil, section)
561 uci:foreach(community, "fw_forwarding", function(section)
562 uci:section("firewall", "forwarding", nil, section)
565 uci:foreach("freifunk", "fw_rule", function(section)
566 uci:section("firewall", "rule", nil, section)
568 uci:foreach(community, "fw_rule", function(section)
569 uci:section("firewall", "rule", nil, section)
574 uci:delete("manager", "heartbeat", "interface")
578 uci:delete_all("olsrd", "olsrd")
580 olsrbase = uci:get_all("freifunk", "olsrd") or {}
581 util.update(olsrbase, uci:get_all(community, "olsrd") or {})
583 olsrbase.IpVersion='6and4'
585 olsrbase.IpVersion='4'
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",
595 UdpDestPort = "224.0.0.251 5353",
598 -- Delete http plugin
599 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_httpinfo.so.0.1"})
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",
607 local device = sec[".name"]
608 if not luci.http.formvalue("cbid.ffwizward.1.device_" .. device) then
611 node_ip = luci.http.formvalue("cbid.ffwizward.1.meship_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.meship_" .. device))
613 node_ip6 = luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device) and ip.IPv6(luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device))
615 if not node_ip or not network or not network:contains(node_ip) then
616 meship.tag_missing[section] = true
620 -- rename the wireless interface s/wifi/wireless/
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)
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)
642 uci:delete("dhcp", device)
643 uci:delete("dhcp", device .. "dhcp")
644 uci:delete("dhcp", nif)
645 uci:delete("dhcp", nif .. "dhcp")
647 uci:delete_all("luci_splash", "iface", {network=device.."dhcp", zone="freifunk"})
648 uci:delete_all("luci_splash", "iface", {network=nif.."dhcp", zone="freifunk"})
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})
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"
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
679 bssid = "00:" .. channel ..":CA:FF:EE:EE"
680 elseif chan >= 100 and chan <= 140 then
683 bssid = "01:" .. string.sub(channel, 2) .. ":CA:FF:EE:EE"
685 devconfig.hwmode = hwmode
687 devconfig.country = cc
688 ssid = ssid .. " - ch" .. channel
690 uci:tset("wireless", device, devconfig)
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
697 ifconfig.bssid = bssid
698 ifconfig.encryption="none"
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()
705 netconfig.ip6addr = node_ip6:string()
707 uci:section("network", "interface", nif, netconfig)
709 uci:section("radvd", "interface", nil, {
713 AdvOtherConfigFlag =0,
716 uci:section("radvd", "prefix", nil, {
725 tools.firewall_zone_add_interface("freifunk", nif)
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)
736 local dhcpmeshnet = luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device))
740 local ifacelist = uci:get_list("manager", "heartbeat", "interface") or {}
741 table.insert(ifacelist,nif .. "dhcp")
742 uci:set_list("manager", "heartbeat", "interface", ifacelist)
747 if not dhcpmeshnet:minhost() or not dhcpmeshnet:mask() then
748 dhcpmesh.tag_missing[section] = true
752 dhcp_ip = dhcpmeshnet:minhost():string()
753 dhcp_mask = dhcpmeshnet:mask():string()
754 dhcp_network = dhcpmeshnet:network():string()
755 uci:section("olsrd", "Hna4", nil, {
757 netaddr = dhcp_network
759 uci:foreach("olsrd", "LoadPlugin",
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)
766 nonolsr = nif.."dhcp "..nonolsr
768 nonolsr = nif.." "..nonolsr
770 uci:set("olsrd", s['.name'], "NonOlsrIf", nonolsr)
774 gen_dhcp_range(netconfig.ipaddr)
776 if dhcp_ip and dhcp_mask then
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)
785 uci:section("network", "interface", nif .. "dhcp", aliasbase)
786 uci:section("wireless", "wifi-iface", nil, {
790 network =nif .. "dhcp",
794 uci:section("radvd", "interface", nil, {
795 interface =nif .. "dhcp",
798 AdvOtherConfigFlag =0,
801 uci:section("radvd", "prefix", nil, {
802 interface =nif .. "dhcp",
810 tools.firewall_zone_add_interface("freifunk", nif .. "dhcp")
812 ifconfig.mcast_rate = nil
813 ifconfig.encryption="none"
815 aliasbase.interface = nif
816 uci:section("network", "alias", nif .. "dhcp", aliasbase)
819 local dhcpbase = uci:get_all("freifunk", "dhcp")
820 util.update(dhcpbase, uci:get_all(community, "dhcp") or {})
821 dhcpbase.interface = nif .. "dhcp"
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", {
831 uci:section("firewall", "rule", nil, {
837 uci:delete_all("firewall", "rule", {
843 uci:section("firewall", "rule", nil, {
850 uci:delete_all("firewall", "rule", {
855 uci:section("firewall", "rule", nil, {
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")
869 uci:delete_all("luci_splash", "iface", {network=device.."dhcp", zone="freifunk"})
871 --Write Ad-Hoc wifi section after AP wifi section
872 uci:section("wireless", "wifi-iface", nil, ifconfig)
879 -- Create wired ip and firewall config
880 uci:foreach("network", "interface",
882 local device = sec[".name"]
883 if not luci.http.formvalue("cbid.ffwizward.1.device_" .. device) then
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
888 node_ip = luci.http.formvalue("cbid.ffwizward.1.meship_" .. device) --and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.meship_" .. device))
890 node_ip6 = luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device) --and ip.IPv6(luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device))
892 if not node_ip or not network or not network:contains(node_ip) then
893 meship.tag_missing[section] = true
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")
904 uci:delete("dhcp", device)
905 uci:delete("dhcp", device .. "dhcp")
907 uci:delete_all("luci_splash", "iface", {network=device.."dhcp", zone="freifunk"})
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})
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()
920 netconfig.ip6addr = node_ip6:string()
922 uci:section("network", "interface", device, netconfig)
925 uci:section("radvd", "interface", nil, {
929 AdvOtherConfigFlag =0,
932 uci:section("radvd", "prefix", nil, {
941 tools.firewall_zone_add_interface("freifunk", device)
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)
953 local dhcpmeshnet = luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. 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)
966 if not dhcpmeshnet:minhost() or not dhcpmeshnet:mask() then
967 dhcpmesh.tag_missing[section] = true
971 dhcp_ip = dhcpmeshnet:minhost():string()
972 dhcp_mask = dhcpmeshnet:mask():string()
973 dhcp_network = dhcpmeshnet:network():string()
974 uci:section("olsrd", "Hna4", nil, {
976 netaddr = dhcp_network
978 uci:foreach("olsrd", "LoadPlugin",
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)
987 gen_dhcp_range(netconfig.ipaddr)
989 if dhcp_ip and dhcp_mask then
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)
999 local dhcpbase = uci:get_all("freifunk", "dhcp")
1000 util.update(dhcpbase, uci:get_all(community, "dhcp") or {})
1001 dhcpbase.interface = device .. "dhcp"
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", {
1011 uci:section("firewall", "rule", nil, {
1017 uci:delete_all("firewall", "rule", {
1023 uci:section("firewall", "rule", nil, {
1030 uci:delete_all("firewall", "rule", {
1035 uci:section("firewall", "rule", nil, {
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")
1048 uci:save("wireless")
1050 uci:save("firewall")
1056 sys.init.enable("radvd")
1058 -- Enforce firewall include
1059 local has_include = false
1060 uci:foreach("firewall", "include",
1062 if section.path == "/etc/firewall.freifunk" then
1067 if not has_include then
1068 uci:section("firewall", "include", nil,
1069 { path = "/etc/firewall.freifunk" })
1071 -- Allow state: invalid packets
1072 uci:foreach("firewall", "defaults",
1074 uci:set("firewall", section[".name"], "drop_invalid", "0")
1077 -- Prepare advanced config
1078 local has_advanced = false
1079 uci:foreach("firewall", "advanced",
1080 function(section) has_advanced = true end)
1082 if not has_advanced then
1083 uci:section("firewall", "advanced", nil,
1084 { tcp_ecn = "0", ip_conntrack_max = "8192", tcp_westwood = "1" })
1086 uci:save("wireless")
1088 uci:save("firewall")
1092 local dhcphb = hb:formvalue(section)
1094 uci:set("manager", "heartbeat", "enabled", "1")
1095 -- Make sure that heartbeat is enabled
1096 sys.init.enable("machash")
1098 uci:set("manager", "heartbeat", "enabled", "0")
1099 -- Make sure that heartbeat is enabled
1100 sys.init.disable("machash")
1105 uci:foreach("system", "system",
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')
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)
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",
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"
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)
1153 -- Make sure that OLSR is enabled
1154 sys.init.enable("olsrd")
1158 -- Import hosts and set domain
1160 uci:foreach("dhcp", "dnsmasq", function(s)
1161 uci:set_list("dhcp", s[".name"], "addnhosts", {"/var/etc/hosts.olsr","/var/etc/hosts.olsr.ipv6"})
1164 uci:foreach("dhcp", "dnsmasq", function(s)
1165 uci:set_list("dhcp", s[".name"], "addnhosts", "/var/etc/hosts.olsr")
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"})
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")
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')
1194 if wansec:formvalue(section) == "1" then
1195 uci:foreach("firewall", "zone",
1197 if s.name == "wan" then
1198 uci:set("firewall", s['.name'], "local_restrict", "1")
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")
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",
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",
1226 if s.name == "wan" then
1227 uci:delete("firewall", s['.name'], "local_restrict")
1232 -- Write gvpn dummy interface
1235 local vpn = gvpn:formvalue(section)
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 ,
1252 netmask =gvpnif.subnet or "255.255.255.192" ,
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)
1263 uci:save("firewall")
1265 sys.init.enable("l2gvpn")
1269 sys.exec("/etc/init.d/l2gvpn stop")
1270 sys.init.disable("l2gvpn")
1275 uci:save("freifunk")
1276 uci:save("firewall")