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 translate("This wizard will assist you in setting up your router for your local Freifunk network or another similar wireless community network."))
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", translate("Configure network"), translate("Select this checkbox to configure your network interfaces."))
126 uci:foreach("wireless", "wifi-device",
128 local device = section[".name"]
129 local hwtype = section.type
130 local syscc = section.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 sys.exec ("wlc country " .. cc)
145 local dev = f:field(Flag, "device_" .. device , "<b>Drahtloses Netzwerk \"" .. device:upper() .. "\"</b> ", "Konfigurieren Sie Ihre drahtlose " .. device:upper() .. "Schnittstelle (WLAN).")
146 dev:depends("netconfig", "1")
148 function dev.cfgvalue(self, section)
149 return uci:get("freifunk", "wizard", "device_" .. device)
151 function dev.write(self, sec, value)
153 uci:set("freifunk", "wizard", "device_" .. device, value)
157 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.")
158 chan:depends("device_" .. device, "1")
160 function chan.cfgvalue(self, section)
161 return uci:get("freifunk", "wizard", "chan_" .. device)
164 chan:value('default')
165 for _, f in ipairs(sys.wifi.channels(device)) do
166 if not f.restricted then
167 chan:value(f.channel)
171 function chan.write(self, sec, value)
173 uci:set("freifunk", "wizard", "chan_" .. device, value)
178 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.")
179 meship:depends("device_" .. device, "1")
180 meship.rmempty = true
181 function meship.cfgvalue(self, section)
182 return uci:get("freifunk", "wizard", "meship_" .. device)
184 function meship.validate(self, value)
185 local x = ip.IPv4(value)
186 return ( x and x:prefix() == 32 ) and x:string() or ""
188 function meship.write(self, sec, value)
189 uci:set("freifunk", "wizard", "meship_" .. device, value)
192 local meship6 = f:field(Value, "meship6_" .. device, device:upper() .. " Mesh IPv6 Adresse einrichten", "Ihre Mesh IP Adresse wird automatisch berechnet")
193 meship6:depends("device_" .. device, "1")
194 meship6.rmempty = true
195 function meship6.cfgvalue(self, section)
196 return get_ula(get_mac(device))
200 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.")
201 client:depends("device_" .. device, "1")
202 client.rmempty = true
203 function client.cfgvalue(self, section)
204 return uci:get("freifunk", "wizard", "client_" .. device)
206 function client.write(self, sec, value)
207 uci:set("freifunk", "wizard", "client_" .. device, value)
210 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")
211 dhcpmesh:depends("client_" .. device, "1")
212 dhcpmesh.rmempty = true
213 function dhcpmesh.cfgvalue(self, section)
214 return uci:get("freifunk", "wizard", "dhcpmesh_" .. device)
216 function dhcpmesh.validate(self, value)
217 local x = ip.IPv4(value)
218 return ( x and x:minhost()) and x:string() or ""
220 function dhcpmesh.write(self, sec, value)
221 uci:set("freifunk", "wizard", "dhcpmesh_" .. device, value)
224 local hwtype = section.type
225 if hwtype == "atheros" then
226 local vap = f:field(Flag, "vap_" .. device , "Virtueller Drahtloser Zugangspunkt", "Konfigurieren Sie Ihren Virtuellen AP")
227 vap:depends("client_" .. device, "1")
229 function vap.cfgvalue(self, section)
230 return uci:get("freifunk", "wizard", "vap_" .. device)
232 function vap.write(self, sec, value)
233 uci:set("freifunk", "wizard", "vap_" .. device, value)
239 uci:foreach("network", "interface",
241 local device = section[".name"]
242 local ifname = uci_state:get("network",device,"ifname")
243 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
244 dev = f:field(Flag, "device_" .. device , "<b>Drahtgebundenes Netzwerk \"" .. device:upper() .. "\"</b>", "Konfigurieren Sie Ihre drahtgebunde " .. device:upper() .. " Schnittstelle (LAN).")
245 dev:depends("netconfig", "1")
247 function dev.cfgvalue(self, section)
248 return uci:get("freifunk", "wizard", "device_" .. device)
250 function dev.write(self, sec, value)
251 uci:set("freifunk", "wizard", "device_" .. device, value)
254 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.")
255 meship:depends("device_" .. device, "1")
256 meship.rmempty = true
257 function meship.cfgvalue(self, section)
258 return uci:get("freifunk", "wizard", "meship_" .. device)
260 function meship.validate(self, value)
261 local x = ip.IPv4(value)
262 return ( x and x:prefix() == 32 ) and x:string() or ""
264 function meship.write(self, sec, value)
265 uci:set("freifunk", "wizard", "meship_" .. device, value)
268 meship6 = f:field(Value, "meship6_" .. device, device:upper() .. " Mesh IPv6 Adresse einrichten", "Ihre Mesh IP Adresse wird automatisch berechnet")
269 meship6:depends("device_" .. device, "1")
270 meship6.rmempty = true
271 function meship6.cfgvalue(self, section)
272 return get_ula(get_mac(ifname))
276 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.")
277 client:depends("device_" .. device, "1")
278 client.rmempty = false
279 function client.cfgvalue(self, section)
280 return uci:get("freifunk", "wizard", "client_" .. device)
282 function client.write(self, sec, value)
283 uci:set("freifunk", "wizard", "client_" .. device, value)
286 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")
287 dhcpmesh:depends("client_" .. device, "1")
288 dhcpmesh.rmempty = true
289 function dhcpmesh.cfgvalue(self, section)
290 return uci:get("freifunk", "wizard", "dhcpmesh_" .. device)
292 function dhcpmesh.validate(self, value)
293 local x = ip.IPv4(value)
294 return ( x and x:prefix() <= 30 and x:minhost()) and x:string() or ""
296 function dhcpmesh.write(self, sec, value)
297 uci:set("freifunk", "wizard", "dhcpmesh_" .. device, value)
303 share = f:field(Flag, "sharenet", "Eigenen Internetzugang freigeben", "Geben Sie Ihren Internetzugang im Freifunknetz frei.")
304 share.rmempty = false
305 share:depends("netconfig", "1")
306 function share.cfgvalue(self, section)
307 return uci:get("freifunk", "wizard", "share")
309 function share.write(self, section, value)
310 uci:set("freifunk", "wizard", "share", value)
314 wanproto = f:field(ListValue, "wanproto", "Protokoll des Internetzugangs", "Geben Sie das Protokol an ueber das eine Internet verbindung hergestellt werden kann.")
315 wanproto:depends("sharenet", "1")
316 wanproto:value("static", translate("static", "static"))
317 wanproto:value("dhcp", translate("dhcp", "dhcp"))
318 if has_pppoe then wanproto:value("pppoe", "PPPoE") end
319 if has_pptp then wanproto:value("pptp", "PPTP") end
320 function wanproto.cfgvalue(self, section)
321 return uci:get("network", "wan", "proto") or "dhcp"
323 function wanproto.write(self, section, value)
324 uci:set("network", "wan", "proto", value)
327 wanip = f:field(Value, "wanipaddr", translate("ipaddress"))
328 wanip:depends("wanproto", "static")
329 function wanip.cfgvalue(self, section)
330 return uci:get("network", "wan", "ipaddr")
332 function wanip.write(self, section, value)
333 uci:set("network", "wan", "ipaddr", value)
336 wannm = f:field(Value, "wannetmask", translate("netmask"))
337 wannm:depends("wanproto", "static")
338 function wannm.cfgvalue(self, section)
339 return uci:get("network", "wan", "netmask")
341 function wannm.write(self, section, value)
342 uci:set("network", "wan", "netmask", value)
345 wangw = f:field(Value, "wangateway", translate("gateway"))
346 wangw:depends("wanproto", "static")
348 function wangw.cfgvalue(self, section)
349 return uci:get("network", "wan", "gateway")
351 function wangw.write(self, section, value)
352 uci:set("network", "wan", "gateway", value)
355 wandns = f:field(Value, "wandns", translate("dnsserver"))
356 wandns:depends("wanproto", "static")
357 wandns.rmempty = true
358 function wandns.cfgvalue(self, section)
359 return uci:get("network", "wan", "dns")
361 function wandns.write(self, section, value)
362 uci:set("network", "wan", "dns", value)
365 wanusr = f:field(Value, "wanusername", translate("username"))
366 wanusr:depends("wanproto", "pppoe")
367 wanusr:depends("wanproto", "pptp")
368 function wanusr.cfgvalue(self, section)
369 return uci:get("network", "wan", "username")
371 function wanusr.write(self, section, value)
372 uci:set("network", "wan", "username", value)
375 wanpwd = f:field(Value, "wanpassword", translate("password"))
376 wanpwd.password = true
377 wanpwd:depends("wanproto", "pppoe")
378 wanpwd:depends("wanproto", "pptp")
379 function wanpwd.cfgvalue(self, section)
380 return uci:get("network", "wan", "password")
382 function wanpwd.write(self, section, value)
383 uci:set("network", "wan", "password", value)
387 wansec = f:field(Flag, "wansec", "WAN-Zugriff auf Gateway beschränken", "Verbieten Sie Zugriffe auf Ihr lokales Netzwerk aus dem Freifunknetz.")
388 wansec.rmempty = false
389 wansec:depends("wanproto", "static")
390 wansec:depends("wanproto", "dhcp")
391 function wansec.cfgvalue(self, section)
392 return uci:get("freifunk", "wizard", "wan_security")
394 function wansec.write(self, section, value)
395 uci:set("freifunk", "wizard", "wan_security", value)
399 wanqosdown = f:field(Value, "wanqosdown", "Download Bandbreite begrenzen", "kb/s")
400 wanqosdown:depends("sharenet", "1")
401 function wanqosdown.cfgvalue(self, section)
402 return uci:get("qos", "wan", "download")
404 function wanqosdown.write(self, section, value)
405 uci:set("qos", "wan", "download", value)
408 wanqosup = f:field(Value, "wanqosup", "Upload Bandbreite begrenzen", "kb/s")
409 wanqosup:depends("sharenet", "1")
410 function wanqosup.cfgvalue(self, section)
411 return uci:get("qos", "wan", "upload")
413 function wanqosup.write(self, section, value)
414 uci:set("qos", "wan", "upload", value)
420 gvpn = f:field(Flag, "gvpn", "Freifunk Internet Tunnel", "Verbinden Sie ihren Router ueber das Internet mit anderen Freifunknetzen.")
422 gvpn:depends("sharenet", "1")
423 function gvpn.cfgvalue(self, section)
424 return uci:get("freifunk", "wizard", "gvpn")
426 function gvpn.write(self, section, value)
427 uci:set("freifunk", "wizard", "gvpn", value)
430 gvpnip = f:field(Value, "gvpnipaddr", translate("ipaddress"))
431 gvpnip:depends("gvpn", "1")
432 function gvpnip.cfgvalue(self, section)
433 return uci:get("l2gvpn", "bbb", "ip") or uci:get("network", "gvpn", "ipaddr")
435 function gvpnip.validate(self, value)
436 local x = ip.IPv4(value)
437 return ( x and x:prefix() == 32 ) and x:string() or ""
442 hb = f:field(Flag, "hb", "Heartbeat aktivieren","Dem Gerät erlauben anonyme Statistiken zu übertragen. (empfohlen)")
444 hb:depends("netconfig", "1")
445 function hb.cfgvalue(self, section)
446 return uci:get("freifunk", "wizard", "hb")
448 function hb.write(self, section, value)
449 uci:set("freifunk", "wizard", "hb", value)
454 -------------------- Control --------------------
455 function f.handle(self, state, data)
456 if state == FORM_VALID then
457 local debug = uci:get("freifunk", "wizard", "debug")
460 local stat = luci.sys.user.setpasswd("root", data.pw1) == 0
462 f.message = translate("a_s_changepw_changed")
464 f.errmessage = translate("unknownerror")
469 luci.http.redirect(luci.dispatcher.build_url(unpack(luci.dispatcher.context.requested.path), "system", "system"))
472 local stat = luci.sys.user.setpasswd("root", data.pw1) == 0
476 uci:commit("freifunk")
477 uci:commit("wireless")
478 uci:commit("network")
480 uci:commit("luci_splash")
481 uci:commit("firewall")
484 uci:commit("manager")
486 uci:commit("autoipv6")
498 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 &" )
499 luci.http.redirect(luci.dispatcher.build_url(luci.dispatcher.context.path[1], "freifunk", "ffwizard"))
502 elseif state == FORM_INVALID then
503 self.errmessage = "Ungültige Eingabe: Bitte die Formularfelder auf Fehler prüfen."
508 local function _strip_internals(tbl)
510 for k, v in pairs(tbl) do
511 if k:sub(1, 1) == "." then
517 -- Configure Freifunk checked
518 function main.write(self, section, value)
520 uci:set("freifunk", "wizard", "netconfig", "0")
524 -- Collect IP-Address
525 uci:set("freifunk", "wizard", "net", uci:get_first(community, "community", "mesh_network"))
529 if not community then
530 net.tag_missing[section] = true
534 uci:set("freifunk", "wizard", "netconfig", "1")
537 local netname = "wireless"
539 network = ip.IPv4(uci:get_first(community, "community", "mesh_network") or "104.0.0.0/8")
541 -- Tune community settings
542 -- if community and uci:get("freifunk", community) then
543 -- uci:get_all(community)
547 uci:delete_all("firewall","zone", {name="freifunk"})
548 uci:delete_all("firewall","forwarding", {dest="freifunk"})
549 uci:delete_all("firewall","forwarding", {src="freifunk"})
550 uci:delete_all("firewall","rule", {dest="freifunk"})
551 uci:delete_all("firewall","rule", {src="freifunk"})
553 -- Create firewall zone and add default rules (first time)
554 -- firewall_create_zone("name" , "input" , "output", "forward ", Masqurade)
555 local newzone = tools.firewall_create_zone("freifunk", "ACCEPT", "ACCEPT", "REJECT" , true)
557 uci:foreach("freifunk", "fw_forwarding", function(section)
558 uci:section("firewall", "forwarding", nil, section)
560 uci:foreach(community, "fw_forwarding", function(section)
561 uci:section("firewall", "forwarding", nil, section)
564 uci:foreach("freifunk", "fw_rule", function(section)
565 uci:section("firewall", "rule", nil, section)
567 uci:foreach(community, "fw_rule", function(section)
568 uci:section("firewall", "rule", nil, section)
573 uci:delete("manager", "heartbeat", "interface")
577 uci:delete_all("olsrd", "olsrd")
579 olsrbase = uci:get_all("freifunk", "olsrd") or {}
580 util.update(olsrbase, uci:get_all(community, "olsrd") or {})
582 olsrbase.IpVersion='6and4'
584 olsrbase.IpVersion='4'
586 uci:section("olsrd", "olsrd", nil, olsrbase)
587 -- Delete olsrdv4 old p2pd settings
588 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_mdns.so.1.0.0"})
589 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_p2pd.so.0.1.0"})
590 -- Write olsrdv4 new p2pd settings
591 uci:section("olsrd", "LoadPlugin", nil, {
592 library = "olsrd_p2pd.so.0.1.0",
594 UdpDestPort = "224.0.0.251 5353",
597 -- Delete http plugin
598 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_httpinfo.so.0.1"})
600 -- Delete olsrdv4 old interface
601 uci:delete_all("olsrd", "Interface")
602 uci:delete_all("olsrd", "Hna4")
603 -- Create wireless ip4/ip6 and firewall config
604 uci:foreach("wireless", "wifi-device",
606 local device = sec[".name"]
607 if not luci.http.formvalue("cbid.ffwizward.1.device_" .. device) then
610 node_ip = luci.http.formvalue("cbid.ffwizward.1.meship_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.meship_" .. device))
612 node_ip6 = luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device) and ip.IPv6(luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device))
614 if not node_ip or not network or not network:contains(node_ip) then
615 meship.tag_missing[section] = true
619 -- rename the wireless interface s/wifi/wireless/
621 if string.find(device, "wifi") then
622 nif = string.gsub(device,"wifi", netname)
623 elseif string.find(device, "wl") then
624 nif = string.gsub(device,"wl", netname)
625 elseif string.find(device, "wlan") then
626 nif = string.gsub(device,"wlan", netname)
627 elseif string.find(device, "radio") then
628 nif = string.gsub(device,"radio", netname)
631 tools.wifi_delete_ifaces(device)
632 -- tools.network_remove_interface(device)
633 uci:delete("network", device .. "dhcp")
634 uci:delete("network", device)
635 tools.firewall_zone_remove_interface("freifunk", device)
636 -- tools.network_remove_interface(nif)
637 uci:delete("network", nif .. "dhcp")
638 uci:delete("network", nif)
639 tools.firewall_zone_remove_interface("freifunk", nif)
641 uci:delete("dhcp", device)
642 uci:delete("dhcp", device .. "dhcp")
643 uci:delete("dhcp", nif)
644 uci:delete("dhcp", nif .. "dhcp")
646 uci:delete_all("luci_splash", "iface", {network=device.."dhcp", zone="freifunk"})
647 uci:delete_all("luci_splash", "iface", {network=nif.."dhcp", zone="freifunk"})
650 uci:delete_all("radvd", "interface", {interface=nif.."dhcp"})
651 uci:delete_all("radvd", "interface", {interface=nif})
652 uci:delete_all("radvd", "prefix", {interface=nif.."dhcp"})
653 uci:delete_all("radvd", "prefix", {interface=nif})
657 local ssid = uci:get_first(community, "community", "ssid") or "olsr.freifunk.net"
658 local devconfig = uci:get_all("freifunk", "wifi_device")
659 util.update(devconfig, uci:get_all(community, "wifi_device") or {})
660 local channel = luci.http.formvalue("cbid.ffwizward.1.chan_" .. device)
661 local hwmode = "11bg"
662 local bssid = uci:get_all(community, "wifi_iface", "bssid") or "02:CA:FF:EE:BA:BE"
664 devconfig.diversity = sec.diversity or "1"
665 if sec.txantenna then
666 devconfig.txantenna = sec.txantenna
668 if sec.rxantenna then
669 devconfig.rxantenna = sec.rxantenna
672 -- set bssid, see https://kifuse02.pberg.freifunk.net/moin/channel-bssid-essid for schema
673 if channel and channel ~= "default" then
674 if devconfig.channel ~= channel then
675 devconfig.channel = channel
676 local chan = tonumber(channel)
677 if chan >= 0 and chan < 10 then
678 bssid = channel .. "2:CA:FF:EE:BA:BE"
679 elseif chan == 10 then
680 bssid = "02:CA:FF:EE:BA:BE"
681 elseif chan >= 11 and chan <= 14 then
682 bssid = string.format("%X",channel) .. "2:CA:FF:EE:BA:BE"
683 elseif chan >= 36 and chan <= 64 then
686 bssid = "00:" .. channel ..":CA:FF:EE:EE"
687 elseif chan >= 100 and chan <= 140 then
690 bssid = "01:" .. string.sub(channel, 2) .. ":CA:FF:EE:EE"
692 devconfig.hwmode = hwmode
694 devconfig.country = cc
695 ssid = ssid .. " - ch" .. channel
697 uci:tset("wireless", device, devconfig)
699 local ifconfig = uci:get_all("freifunk", "wifi_iface")
700 util.update(ifconfig, uci:get_all(community, "wifi_iface") or {})
701 ifconfig.device = device
702 ifconfig.network = nif
704 ifconfig.bssid = bssid
705 ifconfig.encryption="none"
707 local netconfig = uci:get_all("freifunk", "interface")
708 util.update(netconfig, uci:get_all(community, "interface") or {})
709 netconfig.proto = "static"
710 netconfig.ipaddr = node_ip:string()
712 netconfig.ip6addr = node_ip6:string()
714 uci:section("network", "interface", nif, netconfig)
716 uci:section("radvd", "interface", nil, {
720 AdvOtherConfigFlag =0,
723 uci:section("radvd", "prefix", nil, {
732 tools.firewall_zone_add_interface("freifunk", nif)
734 -- Write new olsrv4 interface
735 local olsrifbase = uci:get_all("freifunk", "olsr_interface")
736 util.update(olsrifbase, uci:get_all(community, "olsr_interface") or {})
737 olsrifbase.interface = nif
738 olsrifbase.ignore = "0"
739 uci:section("olsrd", "Interface", nil, olsrifbase)
740 -- Collect MESH DHCP IP NET
741 local client = luci.http.formvalue("cbid.ffwizward.1.client_" .. device)
743 local dhcpmeshnet = luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device))
747 local ifacelist = uci:get_list("manager", "heartbeat", "interface") or {}
748 table.insert(ifacelist,nif .. "dhcp")
749 uci:set_list("manager", "heartbeat", "interface", ifacelist)
754 if not dhcpmeshnet:minhost() or not dhcpmeshnet:mask() then
755 dhcpmesh.tag_missing[section] = true
759 dhcp_ip = dhcpmeshnet:minhost():string()
760 dhcp_mask = dhcpmeshnet:mask():string()
761 dhcp_network = dhcpmeshnet:network():string()
762 uci:section("olsrd", "Hna4", nil, {
764 netaddr = dhcp_network
766 uci:foreach("olsrd", "LoadPlugin",
768 if s.library == "olsrd_p2pd.so.0.1.0" then
769 uci:set("olsrd", s['.name'], "ignore", "0")
770 local nonolsr = uci:get("olsrd", s['.name'], "NonOlsrIf") or ""
771 vap = luci.http.formvalue("cbid.ffwizward.1.vap_" .. device)
773 nonolsr = nif.."dhcp "..nonolsr
775 nonolsr = nif.." "..nonolsr
777 uci:set("olsrd", s['.name'], "NonOlsrIf", nonolsr)
781 gen_dhcp_range(netconfig.ipaddr)
783 if dhcp_ip and dhcp_mask then
785 local aliasbase = uci:get_all("freifunk", "alias")
786 util.update(aliasbase, uci:get_all(community, "alias") or {})
787 aliasbase.ipaddr = dhcp_ip
788 aliasbase.netmask = dhcp_mask
789 aliasbase.proto = "static"
790 vap = luci.http.formvalue("cbid.ffwizward.1.vap_" .. device)
792 uci:section("network", "interface", nif .. "dhcp", aliasbase)
793 uci:section("wireless", "wifi-iface", nil, {
797 network =nif .. "dhcp",
801 uci:section("radvd", "interface", nil, {
802 interface =nif .. "dhcp",
805 AdvOtherConfigFlag =0,
808 uci:section("radvd", "prefix", nil, {
809 interface =nif .. "dhcp",
817 tools.firewall_zone_add_interface("freifunk", nif .. "dhcp")
819 ifconfig.mcast_rate = nil
820 ifconfig.encryption="none"
822 aliasbase.interface = nif
823 uci:section("network", "alias", nif .. "dhcp", aliasbase)
826 local dhcpbase = uci:get_all("freifunk", "dhcp")
827 util.update(dhcpbase, uci:get_all(community, "dhcp") or {})
828 dhcpbase.interface = nif .. "dhcp"
830 uci:section("dhcp", "dhcp", nif .. "dhcp", dhcpbase)
831 uci:set_list("dhcp", nif .. "dhcp", "dhcp_option", "119,olsr")
832 -- Create firewall settings
833 uci:delete_all("firewall", "rule", {
838 uci:section("firewall", "rule", nil, {
844 uci:delete_all("firewall", "rule", {
850 uci:section("firewall", "rule", nil, {
857 uci:delete_all("firewall", "rule", {
862 uci:section("firewall", "rule", nil, {
869 uci:section("luci_splash", "iface", nil, {network=nif.."dhcp", zone="freifunk"})
870 uci:save("luci_splash")
871 -- Make sure that luci_splash is enabled
872 sys.init.enable("luci_splash")
876 uci:delete_all("luci_splash", "iface", {network=device.."dhcp", zone="freifunk"})
878 --Write Ad-Hoc wifi section after AP wifi section
879 uci:section("wireless", "wifi-iface", nil, ifconfig)
886 -- Create wired ip and firewall config
887 uci:foreach("network", "interface",
889 local device = sec[".name"]
890 if not luci.http.formvalue("cbid.ffwizward.1.device_" .. device) then
893 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
895 node_ip = luci.http.formvalue("cbid.ffwizward.1.meship_" .. device) --and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.meship_" .. device))
897 node_ip6 = luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device) --and ip.IPv6(luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device))
899 if not node_ip or not network or not network:contains(node_ip) then
900 meship.tag_missing[section] = true
905 tools.firewall_zone_remove_interface(device, device)
906 uci:delete_all("firewall","zone", {name=device})
907 uci:delete_all("firewall","forwarding", {src=device})
908 uci:delete_all("firewall","forwarding", {dest=device})
909 uci:delete("network", device .. "dhcp")
911 uci:delete("dhcp", device)
912 uci:delete("dhcp", device .. "dhcp")
914 uci:delete_all("luci_splash", "iface", {network=device.."dhcp", zone="freifunk"})
916 uci:delete_all("radvd", "interface", {interface=device.."dhcp"})
917 uci:delete_all("radvd", "interface", {interface=device})
918 uci:delete_all("radvd", "prefix", {interface=device.."dhcp"})
919 uci:delete_all("radvd", "prefix", {interface=device})
922 local netconfig = uci:get_all("freifunk", "interface")
923 util.update(netconfig, uci:get_all(community, "interface") or {})
924 netconfig.proto = "static"
925 netconfig.ipaddr = node_ip:string()
927 netconfig.ip6addr = node_ip6:string()
929 uci:section("network", "interface", device, netconfig)
932 uci:section("radvd", "interface", nil, {
936 AdvOtherConfigFlag =0,
939 uci:section("radvd", "prefix", nil, {
948 tools.firewall_zone_add_interface("freifunk", device)
950 -- Write new olsrv4 interface
951 local olsrifbase = uci:get_all("freifunk", "olsr_interface")
952 util.update(olsrifbase, uci:get_all(community, "olsr_interface") or {})
953 olsrifbase.interface = device
954 olsrifbase.ignore = "0"
955 uci:section("olsrd", "Interface", nil, olsrifbase)
956 olsrifbase.Mode = 'ether'
957 -- Collect MESH DHCP IP NET
958 local client = luci.http.formvalue("cbid.ffwizward.1.client_" .. device)
960 local dhcpmeshnet = luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device))
965 local ifacelist = uci:get_list("manager", "heartbeat", "interface") or {}
966 table.insert(ifacelist,device .. "dhcp")
967 uci:set_list("manager", "heartbeat", "interface", ifacelist)
973 if not dhcpmeshnet:minhost() or not dhcpmeshnet:mask() then
974 dhcpmesh.tag_missing[section] = true
978 dhcp_ip = dhcpmeshnet:minhost():string()
979 dhcp_mask = dhcpmeshnet:mask():string()
980 dhcp_network = dhcpmeshnet:network():string()
981 uci:section("olsrd", "Hna4", nil, {
983 netaddr = dhcp_network
985 uci:foreach("olsrd", "LoadPlugin",
987 if s.library == "olsrd_p2pd.so.0.1.0" then
988 uci:set("olsrd", s['.name'], "ignore", "0")
989 local nonolsr = uci:get("olsrd", s['.name'], "NonOlsrIf") or ""
990 uci:set("olsrd", s['.name'], "NonOlsrIf", device .." ".. nonolsr)
994 gen_dhcp_range(netconfig.ipaddr)
996 if dhcp_ip and dhcp_mask then
998 local aliasbase = uci:get_all("freifunk", "alias")
999 util.update(aliasbase, uci:get_all(community, "alias") or {})
1000 aliasbase.interface = device
1001 aliasbase.ipaddr = dhcp_ip
1002 aliasbase.netmask = dhcp_mask
1003 aliasbase.proto = "static"
1004 uci:section("network", "alias", device .. "dhcp", aliasbase)
1006 local dhcpbase = uci:get_all("freifunk", "dhcp")
1007 util.update(dhcpbase, uci:get_all(community, "dhcp") or {})
1008 dhcpbase.interface = device .. "dhcp"
1010 uci:section("dhcp", "dhcp", device .. "dhcp", dhcpbase)
1011 uci:set_list("dhcp", device .. "dhcp", "dhcp_option", "119,olsr")
1012 -- Create firewall settings
1013 uci:delete_all("firewall", "rule", {
1018 uci:section("firewall", "rule", nil, {
1024 uci:delete_all("firewall", "rule", {
1030 uci:section("firewall", "rule", nil, {
1037 uci:delete_all("firewall", "rule", {
1042 uci:section("firewall", "rule", nil, {
1049 uci:section("luci_splash", "iface", nil, {network=device.."dhcp", zone="freifunk"})
1050 uci:save("luci_splash")
1051 -- Make sure that luci_splash is enabled
1052 sys.init.enable("luci_splash")
1055 uci:save("wireless")
1057 uci:save("firewall")
1063 sys.init.enable("radvd")
1065 -- Enforce firewall include
1066 local has_include = false
1067 uci:foreach("firewall", "include",
1069 if section.path == "/etc/firewall.freifunk" then
1074 if not has_include then
1075 uci:section("firewall", "include", nil,
1076 { path = "/etc/firewall.freifunk" })
1078 -- Allow state: invalid packets
1079 uci:foreach("firewall", "defaults",
1081 uci:set("firewall", section[".name"], "drop_invalid", "0")
1084 -- Prepare advanced config
1085 local has_advanced = false
1086 uci:foreach("firewall", "advanced",
1087 function(section) has_advanced = true end)
1089 if not has_advanced then
1090 uci:section("firewall", "advanced", nil,
1091 { tcp_ecn = "0", ip_conntrack_max = "8192", tcp_westwood = "1" })
1093 uci:save("wireless")
1095 uci:save("firewall")
1099 local dhcphb = hb:formvalue(section)
1101 uci:set("manager", "heartbeat", "enabled", "1")
1102 -- Make sure that heartbeat is enabled
1103 sys.init.enable("machash")
1105 uci:set("manager", "heartbeat", "enabled", "0")
1106 -- Make sure that heartbeat is enabled
1107 sys.init.disable("machash")
1112 uci:foreach("system", "system",
1114 -- Make crond silent
1115 uci:set("system", s['.name'], "cronloglevel", "10")
1116 -- Make set timzone and zonename
1117 uci:set("system", s['.name'], "zonename", "Europe/Berlin")
1118 uci:set("system", s['.name'], "timezone", 'CET-1CEST,M3.5.0,M10.5.0/3')
1121 -- Create time rdate_servers
1122 local rdate = uci:get_all("freifunk", "time")
1123 uci:delete_all("system", "time")
1124 uci:section("system", "time", "rdate_servers", rdate)
1125 rdate.server = rdate.rdate_servers
1126 rdate.rdate_servers = ""
1127 uci:delete_all("system", "rdate", nil)
1128 uci:section("system", "rdate", nil, rdate)
1131 -- Delete old watchdog settings
1132 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_watchdog.so.0.1"})
1133 -- Write new watchdog settings
1134 uci:section("olsrd", "LoadPlugin", nil, {
1135 library = "olsrd_watchdog.so.0.1",
1136 file = "/var/run/olsrd.watchdog",
1140 -- Delete old nameservice settings
1141 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_nameservice.so.0.3"})
1142 -- Write new nameservice settings
1143 uci:section("olsrd", "LoadPlugin", nil, {
1144 library = "olsrd_nameservice.so.0.3",
1145 suffix = "." .. suffix ,
1146 hosts_file = "/var/etc/hosts.olsr",
1147 latlon_file = "/var/run/latlon.js",
1148 lat = lat and string.format("%.15f", lat) or "",
1149 lon = lon and string.format("%.15f", lon) or "",
1150 services_file = "/var/etc/services.olsr"
1153 -- Import hosts and set domain
1154 uci:foreach("dhcp", "dnsmasq", function(s)
1155 uci:set_list("dhcp", s[".name"], "addnhosts", "/var/etc/hosts.olsr")
1156 uci:set("dhcp", s[".name"], "local", "/" .. suffix .. "/")
1157 uci:set("dhcp", s[".name"], "domain", suffix)
1160 -- Make sure that OLSR is enabled
1161 sys.init.enable("olsrd")
1165 -- Import hosts and set domain
1167 uci:foreach("dhcp", "dnsmasq", function(s)
1168 uci:set_list("dhcp", s[".name"], "addnhosts", {"/var/etc/hosts.olsr","/var/etc/hosts.olsr.ipv6"})
1171 uci:foreach("dhcp", "dnsmasq", function(s)
1172 uci:set_list("dhcp", s[".name"], "addnhosts", "/var/etc/hosts.olsr")
1179 local share_value = share:formvalue(section)
1180 if share_value == "1" then
1181 uci:set("freifunk", "wizard", "netconfig", "1")
1182 uci:section("firewall", "forwarding", nil, {src="freifunk", dest="wan"})
1184 if has_autoipv6 then
1185 -- Set autoipv6 tunnel mode
1186 uci:set("autoipv6", "olsr_node", "enable", "0")
1187 uci:set("autoipv6", "tunnel", "enable", "1")
1188 uci:save("autoipv6")
1191 -- Delete/Disable gateway plugin
1192 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_dyn_gw.so.0.5"})
1193 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_dyn_gw_plain.so.0.4"})
1194 -- Enable gateway_plain plugin
1195 uci:section("olsrd", "LoadPlugin", nil, {library="olsrd_dyn_gw_plain.so.0.4"})
1196 sys.exec("chmod +x /etc/init.d/freifunk-p2pblock")
1197 sys.init.enable("freifunk-p2pblock")
1198 sys.init.enable("qos")
1199 sys.exec('grep wan /etc/crontabs/root >/dev/null || echo "0 6 * * * ifup wan" >> /etc/crontabs/root')
1201 if wansec:formvalue(section) == "1" then
1202 uci:foreach("firewall", "zone",
1204 if s.name == "wan" then
1205 uci:set("firewall", s['.name'], "local_restrict", "1")
1211 uci:set("freifunk", "wizard", "netconfig", "0")
1212 uci:save("freifunk")
1213 if has_autoipv6 then
1214 -- Set autoipv6 olsrd mode
1215 uci:set("autoipv6", "olsr_node", "enable", "1")
1216 uci:set("autoipv6", "tunnel", "enable", "0")
1217 uci:save("autoipv6")
1219 -- Delete gateway plugins
1220 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_dyn_gw.so.0.5"})
1221 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_dyn_gw_plain.so.0.4"})
1222 -- Disable gateway_plain plugin
1223 uci:section("olsrd", "LoadPlugin", nil, {
1224 library = "olsrd_dyn_gw_plain.so.0.4",
1227 sys.init.disable("freifunk-p2pblock")
1228 sys.init.disable("qos")
1229 sys.exec("chmod -x /etc/init.d/freifunk-p2pblock")
1230 uci:delete_all("firewall", "forwarding", {src="freifunk", dest="wan"})
1231 uci:foreach("firewall", "zone",
1233 if s.name == "wan" then
1234 uci:delete("firewall", s['.name'], "local_restrict")
1239 -- Write gvpn dummy interface
1242 local vpn = gvpn:formvalue(section)
1244 uci:delete_all("l2gvpn", "l2gvpn")
1245 uci:delete_all("l2gvpn", "node")
1246 uci:delete_all("l2gvpn", "supernode")
1247 -- Write olsr tunnel interface options
1248 local olsr_gvpnifbase = uci:get_all("freifunk", "olsr_gvpninterface")
1249 util.update(olsr_gvpnifbase, uci:get_all(community, "olsr_gvpninterface") or {})
1250 uci:section("olsrd", "Interface", nil, olsr_gvpnifbase)
1251 local vpnip = gvpnip:formvalue(section)
1252 local gvpnif = uci:get_all("freifunk", "gvpn_node")
1253 util.update(gvpnif, uci:get_all(community, "gvpn_node") or {})
1254 if gvpnif and gvpnif.tundev and vpnip then
1255 uci:section("network", "interface", gvpnif.tundev, {
1256 ifname =gvpnif.tundev ,
1259 netmask =gvpnif.subnet or "255.255.255.192" ,
1265 gvpnif.mac="00:00:48:"..string.format("%X",string.gsub( vpnip, ".*%." , "" ))..":00:00"
1266 tools.firewall_zone_add_interface("freifunk", gvpnif.tundev)
1267 uci:section("l2gvpn", "node" , gvpnif.community , gvpnif)
1270 uci:save("firewall")
1272 sys.init.enable("l2gvpn")
1276 sys.exec("/etc/init.d/l2gvpn stop")
1277 sys.init.disable("l2gvpn")
1282 uci:save("freifunk")
1283 uci:save("firewall")