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("ffwizard")
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"))
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()
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")
98 function meship.cfgvalue(self, section)
99 return uci:get("freifunk", "wizard", "meship_" .. dev)
101 function meship.validate(self, value)
102 local x = ip.IPv4(value)
103 return ( x and x:prefix() == 32 ) and x:string() or ""
105 function meship.write(self, sec, value)
106 uci:set("freifunk", "wizard", "meship_" .. dev, value)
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))
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")
123 function d.cfgvalue(self, section)
124 return uci:get("freifunk", "wizard", "device_" .. dev)
126 function d.write(self, sec, value)
128 uci:set("freifunk", "wizard", "device_" .. dev, value)
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)
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 ""
146 function dhcpmesh.write(self, sec, value)
147 uci:set("freifunk", "wizard", "dhcpmesh_" .. dev, value)
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)
159 function client.write(self, sec, value)
160 uci:set("freifunk", "wizard", "client_" .. dev, value)
167 local ifacelist = uci:get_list("manager", "heartbeat", "interface") or {}
168 table.insert(ifacelist,dev .. "dhcp")
169 uci:set_list("manager", "heartbeat", "interface", ifacelist)
174 function uci_radvd(n)
175 uci:section("radvd", "interface", nil, {
179 AdvOtherConfigFlag =0,
182 uci:section("radvd", "prefix", nil, {
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})
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."))
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"))
211 pw2 = f:field(Value, "pw2", translate("Password confirmation"))
215 function pw2.validate(self, value, section)
216 return pw1:formvalue(section) == value and value
222 local cc = uci:get(community, "wifi_device", "country") or "DE"
224 main = f:field(Flag, "netconfig", translate("Configure network"), translate("Select this checkbox to configure your network interfaces."))
226 uci:foreach("wireless", "wifi-device", function(section)
227 local device = section[".name"]
228 local hwtype = section.type
229 local syscc = section.country
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)
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")
248 function chan.cfgvalue(self, section)
249 return uci:get("freifunk", "wizard", "chan_" .. device)
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)
258 function chan.write(self, sec, value)
260 uci:set("freifunk", "wizard", "chan_" .. device, value)
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")
276 function vap.cfgvalue(self, section)
277 return uci:get("freifunk", "wizard", "vap_" .. device)
279 function vap.write(self, sec, value)
280 uci:set("freifunk", "wizard", "vap_" .. device, value)
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
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")
306 function share.write(self, section, value)
307 uci:set("freifunk", "wizard", "share", value)
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"
320 function wanproto.write(self, section, value)
321 uci:set("network", "wan", "proto", value)
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")
329 function wanip.write(self, section, value)
330 uci:set("network", "wan", "ipaddr", value)
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")
338 function wannm.write(self, section, value)
339 uci:set("network", "wan", "netmask", value)
342 wangw = f:field(Value, "wangateway", translate("Gateway"))
343 wangw:depends("wanproto", "static")
345 function wangw.cfgvalue(self, section)
346 return uci:get("network", "wan", "gateway")
348 function wangw.write(self, section, value)
349 uci:set("network", "wan", "gateway", value)
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")
358 function wandns.write(self, section, value)
359 uci:set("network", "wan", "dns", value)
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")
368 function wanusr.write(self, section, value)
369 uci:set("network", "wan", "username", value)
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")
379 function wanpwd.write(self, section, value)
380 uci:set("network", "wan", "password", value)
384 wansec = f:field(Flag, "wansec", translate("Protect LAN"), translate("Check this to protect your LAN from other nodes or clients") .. " (" .. translate("recommended") .. ").")
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")
392 function wansec.write(self, section, value)
393 uci:set("freifunk", "wizard", "wan_security", value)
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")
402 function wanqosdown.write(self, section, value)
403 uci:set("qos", "wan", "download", value)
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")
411 function wanqosup.write(self, section, value)
412 uci:set("qos", "wan", "upload", value)
418 gvpn = f:field(Flag, "gvpn", translate("L2gvpn tunnel"), translate("Connect your node with other nodes with a tunnel via the internet."))
420 gvpn:depends("sharenet", "1")
421 function gvpn.cfgvalue(self, section)
422 return uci:get("freifunk", "wizard", "gvpn")
424 function gvpn.write(self, section, value)
425 uci:set("freifunk", "wizard", "gvpn", value)
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")
433 function gvpnip.validate(self, value)
434 local x = ip.IPv4(value)
435 return ( x and x:prefix() == 32 ) and x:string() or ""
440 hb = f:field(Flag, "hb", translate("Heartbeat"), translate("Allow to transfer anonymous statistics about this node") .. " (" .. translate("recommended") .. ").")
442 hb:depends("netconfig", "1")
443 function hb.cfgvalue(self, section)
444 return uci:get("freifunk", "wizard", "hb")
446 function hb.write(self, section, value)
447 uci:set("freifunk", "wizard", "hb", value)
452 -------------------- Control --------------------
453 function f.handle(self, state, data)
454 if state == FORM_VALID then
455 local debug = uci:get("freifunk", "wizard", "debug")
458 local stat = luci.sys.user.setpasswd("root", data.pw1) == 0
460 f.message = translate("Password successfully changed")
462 f.errmessage = translate("Unknown Error")
467 luci.http.redirect(luci.dispatcher.build_url(unpack(luci.dispatcher.context.requested.path), "system", "system"))
470 local stat = luci.sys.user.setpasswd("root", data.pw1) == 0
474 uci:commit("freifunk")
475 uci:commit("wireless")
476 uci:commit("network")
478 uci:commit("luci_splash")
479 uci:commit("firewall")
482 uci:commit("manager")
484 uci:commit("autoipv6")
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"))
500 elseif state == FORM_INVALID then
501 self.errmessage = "Ungültige Eingabe: Bitte die Formularfelder auf Fehler prüfen."
506 local function _strip_internals(tbl)
508 for k, v in pairs(tbl) do
509 if k:sub(1, 1) == "." then
515 -- Configure Freifunk checked
516 function main.write(self, section, value)
518 uci:set("freifunk", "wizard", "netconfig", "0")
522 -- Collect IP-Address
523 uci:set("freifunk", "wizard", "net", uci:get_first(community, "community", "mesh_network"))
527 if not community then
528 net.tag_missing[section] = true
532 uci:set("freifunk", "wizard", "netconfig", "1")
535 local netname = "wireless"
537 network = ip.IPv4(uci:get_first(community, "community", "mesh_network") or "104.0.0.0/8")
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"})
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)
550 uci:foreach("freifunk", "fw_forwarding", function(section)
551 uci:section("firewall", "forwarding", nil, section)
553 uci:foreach(community, "fw_forwarding", function(section)
554 uci:section("firewall", "forwarding", nil, section)
557 uci:foreach("freifunk", "fw_rule", function(section)
558 uci:section("firewall", "rule", nil, section)
560 uci:foreach(community, "fw_rule", function(section)
561 uci:section("firewall", "rule", nil, section)
566 uci:delete("manager", "heartbeat", "interface")
570 uci:delete_all("olsrd", "olsrd")
572 olsrbase = uci:get_all("freifunk", "olsrd") or {}
573 util.update(olsrbase, uci:get_all(community, "olsrd") or {})
575 olsrbase.IpVersion='6and4'
577 olsrbase.IpVersion='4'
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",
587 UdpDestPort = "224.0.0.251 5353",
590 -- Delete http plugin
591 uci:delete_all("olsrd", "LoadPlugin", {library="olsrd_httpinfo.so.0.1"})
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",
599 local device = sec[".name"]
600 if not luci.http.formvalue("cbid.ffwizward.1.device_" .. device) then
603 node_ip = luci.http.formvalue("cbid.ffwizward.1.meship_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.meship_" .. device))
605 node_ip6 = luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device) and ip.IPv6(luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device))
607 if not node_ip or not network or not network:contains(node_ip) then
608 meship.tag_missing[section] = true
612 -- rename the wireless interface s/wifi/wireless/
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)
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)
634 uci:delete("dhcp", device)
635 uci:delete("dhcp", device .. "dhcp")
636 uci:delete("dhcp", nif)
637 uci:delete("dhcp", nif .. "dhcp")
639 uci:delete_all("luci_splash", "iface", {network=device.."dhcp", zone="freifunk"})
640 uci:delete_all("luci_splash", "iface", {network=nif.."dhcp", zone="freifunk"})
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"
654 devconfig.diversity = sec.diversity or "1"
655 if sec.txantenna then
656 devconfig.txantenna = sec.txantenna
658 if sec.rxantenna then
659 devconfig.rxantenna = sec.rxantenna
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
676 bssid = "00:" .. channel ..":CA:FF:EE:EE"
677 elseif chan >= 100 and chan <= 140 then
680 bssid = "01:" .. string.sub(channel, 2) .. ":CA:FF:EE:EE"
682 devconfig.hwmode = hwmode
684 devconfig.country = cc
685 ssid = ssid .. " - ch" .. channel
687 uci:tset("wireless", device, devconfig)
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
694 ifconfig.bssid = bssid
695 ifconfig.encryption="none"
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()
702 netconfig.ip6addr = node_ip6:string()
704 uci:section("network", "interface", nif, netconfig)
708 tools.firewall_zone_add_interface("freifunk", nif)
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)
719 local dhcpmeshnet = luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device))
722 if not dhcpmeshnet:minhost() or not dhcpmeshnet:mask() then
723 dhcpmesh.tag_missing[section] = true
727 dhcp_ip = dhcpmeshnet:minhost():string()
728 dhcp_mask = dhcpmeshnet:mask():string()
729 dhcp_network = dhcpmeshnet:network():string()
730 uci:section("olsrd", "Hna4", nil, {
732 netaddr = dhcp_network
734 uci:foreach("olsrd", "LoadPlugin",
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)
741 nonolsr = nif.."dhcp "..nonolsr
743 nonolsr = nif.." "..nonolsr
745 uci:set("olsrd", s['.name'], "NonOlsrIf", nonolsr)
749 gen_dhcp_range(netconfig.ipaddr)
751 if dhcp_ip and dhcp_mask then
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)
760 uci:section("network", "interface", nif .. "dhcp", aliasbase)
761 uci:section("wireless", "wifi-iface", nil, {
765 network =nif .. "dhcp",
769 uci_radvd(nif .. "dhcp")
771 tools.firewall_zone_add_interface("freifunk", nif .. "dhcp")
773 ifconfig.mcast_rate = nil
774 ifconfig.encryption="none"
776 aliasbase.interface = nif
777 uci:section("network", "alias", nif .. "dhcp", aliasbase)
780 local dhcpbase = uci:get_all("freifunk", "dhcp")
781 util.update(dhcpbase, uci:get_all(community, "dhcp") or {})
782 dhcpbase.interface = nif .. "dhcp"
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", {
792 uci:section("firewall", "rule", nil, {
798 uci:delete_all("firewall", "rule", {
804 uci:section("firewall", "rule", nil, {
811 uci:delete_all("firewall", "rule", {
816 uci:section("firewall", "rule", nil, {
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")
830 uci:delete_all("luci_splash", "iface", {network=device.."dhcp", zone="freifunk"})
832 --Write Ad-Hoc wifi section after AP wifi section
833 uci:section("wireless", "wifi-iface", nil, ifconfig)
840 -- Create wired ip and firewall config
841 uci:foreach("network", "interface",
843 local device = sec[".name"]
844 if not luci.http.formvalue("cbid.ffwizward.1.device_" .. device) then
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
849 node_ip = luci.http.formvalue("cbid.ffwizward.1.meship_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.meship_" .. device))
851 node_ip6 = luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device) --and ip.IPv6(luci.http.formvalue("cbid.ffwizward.1.meship6_" .. device))
853 if not node_ip or not network or not network:contains(node_ip) then
854 meship.tag_missing[section] = true
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")
865 uci:delete("dhcp", device)
866 uci:delete("dhcp", device .. "dhcp")
868 uci:delete_all("luci_splash", "iface", {network=device.."dhcp", zone="freifunk"})
870 uci_clean_radvd(device)
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()
878 netconfig.ip6addr = node_ip6:string()
880 uci:section("network", "interface", device, netconfig)
885 tools.firewall_zone_add_interface("freifunk", device)
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)
897 local dhcpmeshnet = luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device) and ip.IPv4(luci.http.formvalue("cbid.ffwizward.1.dhcpmesh_" .. device))
901 if not dhcpmeshnet:minhost() or not dhcpmeshnet:mask() then
902 dhcpmesh.tag_missing[section] = true
906 dhcp_ip = dhcpmeshnet:minhost():string()
907 dhcp_mask = dhcpmeshnet:mask():string()
908 dhcp_network = dhcpmeshnet:network():string()
909 uci:section("olsrd", "Hna4", nil, {
911 netaddr = dhcp_network
913 uci:foreach("olsrd", "LoadPlugin",
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)
922 gen_dhcp_range(netconfig.ipaddr)
924 if dhcp_ip and dhcp_mask then
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)
934 local dhcpbase = uci:get_all("freifunk", "dhcp")
935 util.update(dhcpbase, uci:get_all(community, "dhcp") or {})
936 dhcpbase.interface = device .. "dhcp"
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", {
946 uci:section("firewall", "rule", nil, {
952 uci:delete_all("firewall", "rule", {
958 uci:section("firewall", "rule", nil, {
965 uci:delete_all("firewall", "rule", {
970 uci:section("firewall", "rule", nil, {
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")
991 sys.init.enable("radvd")
993 -- Enforce firewall include
994 local has_include = false
995 uci:foreach("firewall", "include",
997 if section.path == "/etc/firewall.freifunk" then
1002 if not has_include then
1003 uci:section("firewall", "include", nil,
1004 { path = "/etc/firewall.freifunk" })
1006 -- Allow state: invalid packets
1007 uci:foreach("firewall", "defaults",
1009 uci:set("firewall", section[".name"], "drop_invalid", "0")
1012 -- Prepare advanced config
1013 local has_advanced = false
1014 uci:foreach("firewall", "advanced",
1015 function(section) has_advanced = true end)
1017 if not has_advanced then
1018 uci:section("firewall", "advanced", nil,
1019 { tcp_ecn = "0", ip_conntrack_max = "8192", tcp_westwood = "1" })
1021 uci:save("wireless")
1023 uci:save("firewall")
1027 local dhcphb = hb:formvalue(section)
1029 uci:set("manager", "heartbeat", "enabled", "1")
1030 -- Make sure that heartbeat is enabled
1031 sys.init.enable("machash")
1033 uci:set("manager", "heartbeat", "enabled", "0")
1034 -- Make sure that heartbeat is enabled
1035 sys.init.disable("machash")
1040 uci:foreach("system", "system",
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')
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",
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"
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)
1079 -- Make sure that OLSR is enabled
1080 sys.init.enable("olsrd")
1084 -- Import hosts and set domain
1086 uci:foreach("dhcp", "dnsmasq", function(s)
1087 uci:set_list("dhcp", s[".name"], "addnhosts", {"/var/etc/hosts.olsr","/var/etc/hosts.olsr.ipv6"})
1090 uci:foreach("dhcp", "dnsmasq", function(s)
1091 uci:set_list("dhcp", s[".name"], "addnhosts", "/var/etc/hosts.olsr")
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"})
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")
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')
1120 if wansec:formvalue(section) == "1" then
1121 uci:foreach("firewall", "zone",
1123 if s.name == "wan" then
1124 uci:set("firewall", s['.name'], "local_restrict", "1")
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")
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",
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",
1152 if s.name == "wan" then
1153 uci:delete("firewall", s['.name'], "local_restrict")
1158 -- Write gvpn dummy interface
1161 local vpn = gvpn:formvalue(section)
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 ,
1178 netmask =gvpnif.subnet or "255.255.255.192" ,
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)
1189 uci:save("firewall")
1191 sys.init.enable("l2gvpn")
1195 sys.exec("/etc/init.d/l2gvpn stop")
1196 sys.init.disable("l2gvpn")
1201 uci:save("freifunk")
1202 uci:save("firewall")