meshwizard.lua 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. -- wizard rewrite wip
  2. local uci = require "luci.model.uci".cursor()
  3. local sys = require "luci.sys"
  4. local util = require "luci.util"
  5. local ip = require "luci.ip"
  6. local community = "profile_" .. (uci:get("freifunk", "community", "name") or "Freifunk")
  7. local mesh_network = ip.IPv4(uci:get_first(community, "community", "mesh_network") or "10.0.0.0/8")
  8. local community_ipv6 = uci:get_first(community, "community", "ipv6") or 0
  9. local community_ipv6mode = uci:get_first(community, "community", "ipv6_config") or "static"
  10. local meshkit_ipv6 = uci:get("meshwizard", "ipv6", "enabled") or 0
  11. local community_vap = uci:get_first(community, "community", "vap") or 0
  12. m = Map("meshwizard", translate("Wizard"), translate("This wizard will assist you in setting up your router for Freifunk " ..
  13. "or another similar wireless community network."))
  14. n = m:section(NamedSection, "netconfig", nil, translate("Interfaces"))
  15. n.anonymous = true
  16. -- common functions
  17. function cbi_configure(device)
  18. local configure = n:taboption(device, Flag, device .. "_config", translate("Configure this interface"),
  19. translate("Note: this will set up this interface for mesh operation, i.e. add it to zone 'freifunk' and enable olsr."))
  20. end
  21. function cbi_ip4addr(device)
  22. local ip4addr = n:taboption(device, Value, device .. "_ip4addr", translate("Mesh IP address"),
  23. translate("This is a unique address in the mesh (e.g. 10.1.1.1) and has to be registered at your local community."))
  24. ip4addr:depends(device .. "_config", 1)
  25. ip4addr.datatype = "ip4addr"
  26. function ip4addr.validate(self, value)
  27. local x = ip.IPv4(value)
  28. if mesh_network:contains(x) then
  29. return value
  30. else
  31. return nil, translate("The given IP address is not inside the mesh network range ") ..
  32. "(" .. mesh_network:string() .. ")."
  33. end
  34. end
  35. end
  36. function cbi_ip6addr(device)
  37. local ip6addr = n:taboption(device, Value, device .. "_ip6addr", translate("Mesh IPv6 address"),
  38. translate("This is a unique IPv6 address in CIDR notation (e.g. 2001:1:2:3::1/64) and has to be registered at your local community."))
  39. ip6addr:depends(device .. "_config", 1)
  40. ip6addr.datatype = "ip6addr"
  41. end
  42. function cbi_dhcp(device)
  43. local dhcp = n:taboption(device, Flag, device .. "_dhcp", translate("Enable DHCP"),
  44. translate("DHCP will automatically assign ip addresses to clients"))
  45. dhcp:depends(device .. "_config", 1)
  46. dhcp.rmempty = true
  47. end
  48. function cbi_ra(device)
  49. local ra = n:taboption(device, Flag, device .. "_ipv6ra", translate("Enable RA"),
  50. translate("Send router advertisements on this device."))
  51. ra:depends(device .. "_config", 1)
  52. ra.rmempty = true
  53. end
  54. function cbi_dhcprange(device)
  55. local dhcprange = n:taboption(device, Value, device .. "_dhcprange", translate("DHCP IP range"),
  56. translate("The IP range from which clients are assigned ip addresses (e.g. 10.1.2.1/28). " ..
  57. "If this is a range inside your mesh network range, then it will be announced as HNA. Any other range will use NAT. " ..
  58. "If left empty then the defaults from the community profile will be used."))
  59. dhcprange:depends(device .. "_dhcp", "1")
  60. dhcprange.rmempty = true
  61. dhcprange.datatype = "ip4addr"
  62. end
  63. -- create tabs and config for wireless
  64. local nets={}
  65. uci:foreach("wireless", "wifi-device", function(section)
  66. local device = section[".name"]
  67. table.insert(nets, device)
  68. end)
  69. local wired_nets = {}
  70. uci:foreach("network", "interface", function(section)
  71. local device = section[".name"]
  72. if not util.contains(nets, device) and device ~= "loopback" and not device:find("wireless") then
  73. table.insert(nets, device)
  74. table.insert(wired_nets, device)
  75. end
  76. end)
  77. for _, net in util.spairs(nets, function(a,b) return (nets[a] < nets[b]) end) do
  78. n:tab(net, net)
  79. end
  80. -- create cbi config for wireless
  81. uci:foreach("wireless", "wifi-device", function(section)
  82. local device = section[".name"]
  83. local hwtype = section.type
  84. local syscc = section.country or uci:get(community, "wifi_device", "country") or
  85. uci:get("freifunk", "wifi_device", "country")
  86. cbi_configure(device)
  87. -- Channel selection
  88. if hwtype == "atheros" then
  89. local cc = util.trim(sys.exec("grep -i '" .. syscc .. "' /lib/wifi/cc_translate.txt |cut -d ' ' -f 2")) or 0
  90. sys.exec('"echo " .. cc .. " > /proc/sys/dev/" .. device .. "/countrycode"')
  91. elseif hwtype == "mac80211" then
  92. sys.exec("iw reg set " .. syscc)
  93. elseif hwtype == "broadcom" then
  94. sys.exec ("wlc country " .. syscc)
  95. end
  96. local chan = n:taboption(device, ListValue, device .. "_channel", translate("Channel"),
  97. translate("Your device and neighbouring nodes have to use the same channel."))
  98. chan:depends(device .. "_config", 1)
  99. chan:value('default')
  100. local iwinfo = sys.wifi.getiwinfo(device)
  101. if iwinfo and iwinfo.freqlist then
  102. for _, f in ipairs(iwinfo.freqlist) do
  103. if not f.restricted then
  104. chan:value(f.channel)
  105. end
  106. end
  107. end
  108. -- IPv4 address
  109. cbi_ip4addr(device)
  110. -- DHCP enable
  111. cbi_dhcp(device)
  112. -- DHCP range
  113. cbi_dhcprange(device)
  114. -- IPv6 addr and RA
  115. if community_ipv6 == "1" then
  116. if community_ipv6mode == "static" then
  117. cbi_ip6addr(device)
  118. end
  119. cbi_ra(device)
  120. end
  121. -- Enable VAP
  122. local supports_vap = 0
  123. if sys.call("/usr/bin/meshwizard/helpers/supports_vap.sh " .. device .. " " .. hwtype) == 0 then
  124. supports_vap = 1
  125. end
  126. if supports_vap == 1 then
  127. local vap = n:taboption(device, Flag, device .. "_vap", translate("Virtual Access Point (VAP)"),
  128. translate("This will setup a new virtual wireless interface in Access Point mode."))
  129. vap:depends(device .. "_dhcp", "1")
  130. vap.rmempty = true
  131. if community_vap == "1" then
  132. vap.default = "1"
  133. end
  134. end
  135. end)
  136. for _, device in pairs(wired_nets) do
  137. cbi_configure(device)
  138. cbi_ip4addr(device)
  139. cbi_dhcp(device)
  140. cbi_dhcprange(device)
  141. -- IPv6 addr and RA
  142. if community_ipv6 == "1" then
  143. if community_ipv6mode == "static" then
  144. cbi_ip6addr(device)
  145. end
  146. cbi_ra(device)
  147. end
  148. end
  149. -- General settings
  150. g = m:section(TypedSection, "general", translate("General Settings"))
  151. g.anonymous = true
  152. local cleanup = g:option(Flag, "cleanup", translate("Cleanup config"),
  153. translate("If this is selected then config is cleaned before setting new config options."))
  154. cleanup.default = "1"
  155. local restrict = g:option(Flag, "local_restrict", translate("Protect LAN"),
  156. translate("Check this to protect your LAN from other nodes or clients") .. " (" .. translate("recommended") .. ").")
  157. local share = g:option(Flag, "sharenet", translate("Share your internet connection"),
  158. translate("Select this to allow others to use your connection to access the internet."))
  159. share.rmempty = true
  160. -- IPv6 config
  161. if community_ipv6 == "1" then
  162. v6 = m:section(NamedSection, "ipv6", nil, translate("IPv6 Settings"))
  163. local enabled = v6:option(Flag, "enabled", translate("Enabled"),
  164. translate("Activate or deactivate IPv6 config globally."))
  165. enabled.default = meshkit_ipv6
  166. enabled.rmempty = false
  167. end
  168. return m