200-wireless 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. #!/usr/bin/lua
  2. local util = require 'gluon.util'
  3. local site = require 'gluon.site'
  4. local sysconfig = require 'gluon.sysconfig'
  5. local iwinfo = require 'iwinfo'
  6. local uci = require('simple-uci').cursor()
  7. -- Initial
  8. if not sysconfig.gluon_version then
  9. uci:delete_all('wireless', 'wifi-iface')
  10. end
  11. local function get_channel(radio, config)
  12. local channel
  13. if uci:get_first('gluon-core', 'wireless', 'preserve_channels') then
  14. channel = radio.channel
  15. end
  16. return channel or config.channel()
  17. end
  18. local function get_htmode(radio)
  19. local phy = util.find_phy(radio)
  20. if iwinfo.nl80211.hwmodelist(phy).ac then
  21. return 'VHT20'
  22. else
  23. return 'HT20'
  24. end
  25. end
  26. local function is_disabled(name)
  27. if uci:get('wireless', name) then
  28. return uci:get_bool('wireless', name, 'disabled')
  29. else
  30. return false
  31. end
  32. end
  33. -- Returns the first argument that is not nil; don't call without any non-nil arguments!
  34. local function first_non_nil(first, ...)
  35. if first ~= nil then
  36. return first
  37. else
  38. return first_non_nil(...)
  39. end
  40. end
  41. local function configure_ibss(config, radio, index, suffix, disabled)
  42. local radio_name = radio['.name']
  43. local name = 'ibss_' .. radio_name
  44. uci:delete('network', name)
  45. uci:delete('network', name .. '_vlan')
  46. uci:delete('wireless', name)
  47. if not config then
  48. return
  49. end
  50. local macaddr = util.get_wlan_mac(uci, radio, index, 3)
  51. if not macaddr then
  52. return
  53. end
  54. if config.vlan then
  55. uci:section('network', 'interface', name, {
  56. proto = 'none',
  57. })
  58. uci:section('network', 'interface', name .. '_vlan', {
  59. ifname = '@' .. name .. '.' .. config.vlan,
  60. proto = 'gluon_mesh',
  61. })
  62. else
  63. uci:section('network', 'interface', name, {
  64. proto = 'gluon_mesh',
  65. })
  66. end
  67. uci:section('wireless', 'wifi-iface', name, {
  68. device = radio_name,
  69. network = name,
  70. mode = 'adhoc',
  71. ssid = config.ssid,
  72. bssid = config.bssid,
  73. macaddr = macaddr,
  74. mcast_rate = config.mcast_rate,
  75. ifname = suffix and 'ibss' .. suffix,
  76. disabled = disabled,
  77. })
  78. end
  79. local function configure_mesh(config, radio, index, suffix, disabled)
  80. local radio_name = radio['.name']
  81. local name = 'mesh_' .. radio_name
  82. local macfilter = uci:get('wireless', name, 'macfilter')
  83. local maclist = uci:get('wireless', name, 'maclist')
  84. uci:delete('network', name)
  85. uci:delete('network', name .. '_vlan')
  86. uci:delete('wireless', name)
  87. if not config then
  88. return
  89. end
  90. local macaddr = util.get_wlan_mac(uci, radio, index, 2)
  91. if not macaddr then
  92. return
  93. end
  94. uci:section('network', 'interface', name, {
  95. proto = 'gluon_mesh',
  96. })
  97. uci:section('wireless', 'wifi-iface', name, {
  98. device = radio_name,
  99. network = name,
  100. mode = 'mesh',
  101. mesh_id = config.id,
  102. mesh_fwding = false,
  103. macaddr = macaddr,
  104. mcast_rate = config.mcast_rate,
  105. ifname = suffix and 'mesh' .. suffix,
  106. disabled = disabled,
  107. macfilter = macfilter,
  108. maclist = maclist,
  109. })
  110. end
  111. local function fixup_wan(radio, index)
  112. local radio_name = radio['.name']
  113. local name = 'wan_' .. radio_name
  114. if not uci:get('wireless', name) then
  115. return
  116. end
  117. local macaddr = util.get_wlan_mac(uci, radio, index, 4)
  118. if not macaddr then
  119. return
  120. end
  121. uci:set('wireless', name, 'macaddr', macaddr)
  122. end
  123. util.foreach_radio(uci, function(radio, index, config)
  124. local radio_name = radio['.name']
  125. if not config() then
  126. uci:set('wireless', radio_name, 'disabled', true)
  127. return
  128. end
  129. local suffix = radio_name:match('^radio(%d+)$')
  130. if not suffix then
  131. return
  132. end
  133. local channel = get_channel(radio, config)
  134. local htmode = get_htmode(radio)
  135. uci:delete('wireless', radio_name, 'disabled')
  136. uci:set('wireless', radio_name, 'channel', channel)
  137. uci:set('wireless', radio_name, 'htmode', htmode)
  138. uci:set('wireless', radio_name, 'country', site.regdom())
  139. uci:set_list('wireless', radio_name, 'supported_rates', config.supported_rates())
  140. uci:set_list('wireless', radio_name, 'basic_rate', config.basic_rate())
  141. local ibss_disabled = is_disabled('ibss_' .. radio_name)
  142. local mesh_disabled = is_disabled('mesh_' .. radio_name)
  143. configure_ibss(config.ibss(), radio, index, suffix,
  144. first_non_nil(
  145. ibss_disabled,
  146. mesh_disabled,
  147. config.ibss.disabled(false)
  148. )
  149. )
  150. configure_mesh(config.mesh(), radio, index, suffix,
  151. first_non_nil(
  152. mesh_disabled,
  153. ibss_disabled,
  154. config.mesh.disabled(false)
  155. )
  156. )
  157. fixup_wan(radio, index)
  158. end)
  159. if uci:get('system', 'rssid_wlan0') then
  160. if uci:get('wireless', 'mesh_radio0') then
  161. uci:set('system', 'rssid_wlan0', 'dev', 'mesh0')
  162. else
  163. uci:set('system', 'rssid_wlan0', 'dev', 'ibss0')
  164. end
  165. uci:save('system')
  166. end
  167. uci:save('wireless')
  168. uci:save('network')