X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fluci.git;a=blobdiff_plain;f=modules%2Fluci-mod-admin-full%2Fluasrc%2Fmodel%2Fcbi%2Fadmin_network%2Fwifi.lua;h=cacaa2595833c1ca93ad61baa0c704bb6f2b7f35;hp=e1e21bcb585b003c7470f45abedc7b3ffd11beca;hb=fdbb417abe9f5cfb950bcaaf03a55ff400226cef;hpb=52a0787c3fd6ad066e98f3d81849c413d8ea3bd4 diff --git a/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/wifi.lua b/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/wifi.lua index e1e21bcb5..cacaa2595 100644 --- a/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/wifi.lua +++ b/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/wifi.lua @@ -7,6 +7,17 @@ local ut = require "luci.util" local nt = require "luci.sys".net local fs = require "nixio.fs" +local acct_port, acct_secret, acct_server, anonymous_identity, ant1, ant2, + auth, auth_port, auth_secret, auth_server, bssid, cacert, cacert2, + cc, ch, cipher, clientcert, clientcert2, ea, eaptype, en, encr, + ft_protocol, ft_psk_generate_local, hidden, htmode, identity, + ieee80211r, ieee80211w, ifname, isolate, key_retries, + legacyrates, max_timeout, meshfwd, meshid, ml, mobility_domain, mode, + mp, nasid, network, password, pmk_r1_push, privkey, privkey2, privkeypwd, + privkeypwd2, r0_key_lifetime, r0kh, r1_key_holder, r1kh, + reassociation_deadline, retry_timeout, ssid, st, tp, wepkey, wepslot, + wmm, wpakey, wps + arg[1] = arg[1] or "" m = Map("wireless", "", @@ -19,16 +30,6 @@ m:chain("network") m:chain("firewall") m.redirect = luci.dispatcher.build_url("admin/network/wireless") -local ifsection - -function m.on_commit(map) - local wnet = nw:get_wifinet(arg[1]) - if ifsection and wnet then - ifsection.section = wnet.sid - m.title = luci.util.pcdata(wnet:get_i18n()) - end -end - nw.init(m.uci) local wnet = nw:get_wifinet(arg[1]) @@ -40,38 +41,6 @@ if not wnet or not wdev then return end --- wireless toggle was requested, commit and reload page -function m.parse(map) - local new_cc = m:formvalue("cbid.wireless.%s.country" % wdev:name()) - local old_cc = m:get(wdev:name(), "country") - - if m:formvalue("cbid.wireless.%s.__toggle" % wdev:name()) then - if wdev:get("disabled") == "1" or wnet:get("disabled") == "1" then - wnet:set("disabled", nil) - else - wnet:set("disabled", "1") - end - wdev:set("disabled", nil) - - nw:commit("wireless") - luci.sys.call("(env -i /bin/ubus call network reload) >/dev/null 2>/dev/null") - - luci.http.redirect(luci.dispatcher.build_url("admin/network/wireless", arg[1])) - return - end - - Map.parse(map) - - if m:get(wdev:name(), "type") == "mac80211" and new_cc and new_cc ~= old_cc then - luci.sys.call("iw reg set %q" % new_cc) - luci.http.redirect(luci.dispatcher.build_url("admin/network/wireless", arg[1])) - return - end -end - -m.title = luci.util.pcdata(wnet:get_i18n()) - - local function txpower_list(iw) local list = iw.txpwrlist or { } local off = tonumber(iw.txpower_offset) or 0 @@ -112,6 +81,57 @@ local hw_modes = iw.hwmodelist or { } local tx_power_list = txpower_list(iw) local tx_power_cur = txpower_current(wdev:get("txpower"), tx_power_list) +-- wireless toggle was requested, commit and reload page +function m.parse(map) + local new_cc = m:formvalue("cbid.wireless.%s.country" % wdev:name()) + local old_cc = m:get(wdev:name(), "country") + + if m:formvalue("cbid.wireless.%s.__toggle" % wdev:name()) then + if wdev:get("disabled") == "1" or wnet:get("disabled") == "1" then + wnet:set("disabled", nil) + else + wnet:set("disabled", "1") + end + wdev:set("disabled", nil) + m.apply_needed = true + m.redirect = nil + end + + Map.parse(map) + + if m:get(wdev:name(), "type") == "mac80211" and new_cc and new_cc ~= old_cc then + luci.sys.call("iw reg set %s" % ut.shellquote(new_cc)) + + local old_ch = tonumber(m:formvalue("cbid.wireless.%s._mode_freq.channel" % wdev:name()) or "") + if old_ch then + local _, c, new_ch + for _, c in ipairs(iw.freqlist) do + if c.channel > old_ch or (old_ch <= 14 and c.channel > 14) then + break + end + new_ch = c.channel + end + if new_ch ~= old_ch then + wdev:set("channel", new_ch) + m.message = translatef("Channel %d is not available in the %s regulatory domain and has been auto-adjusted to %d.", + old_ch, new_cc, new_ch) + end + end + end + + if wdev:get("disabled") == "1" or wnet:get("disabled") == "1" then + en.title = translate("Wireless network is disabled") + en.inputtitle = translate("Enable") + en.inputstyle = "apply" + else + en.title = translate("Wireless network is enabled") + en.inputtitle = translate("Disable") + en.inputstyle = "reset" + end +end + +m.title = luci.util.pcdata(wnet:get_i18n()) + s = m:section(NamedSection, wdev:name(), "wifi-device", translate("Device Configuration")) s.addremove = false @@ -119,29 +139,12 @@ s:tab("general", translate("General Setup")) s:tab("macfilter", translate("MAC-Filter")) s:tab("advanced", translate("Advanced Settings")) ---[[ -back = s:option(DummyValue, "_overview", translate("Overview")) -back.value = "" -back.titleref = luci.dispatcher.build_url("admin", "network", "wireless") -]] - st = s:taboption("general", DummyValue, "__status", translate("Status")) st.template = "admin_network/wifi_status" st.ifname = arg[1] en = s:taboption("general", Button, "__toggle") -if wdev:get("disabled") == "1" or wnet:get("disabled") == "1" then - en.title = translate("Wireless network is disabled") - en.inputtitle = translate("Enable") - en.inputstyle = "apply" -else - en.title = translate("Wireless network is enabled") - en.inputtitle = translate("Disable") - en.inputstyle = "reset" -end - - local hwtype = wdev:get("type") -- NanoFoo @@ -170,9 +173,7 @@ if found_sta then found_sta.channel or "(auto)", table.concat(found_sta.names, ", ")) else ch = s:taboption("general", Value, "_mode_freq", '
'..translate("Operating frequency")) - ch.hwmodes = hw_modes - ch.htmodes = iw.htmodelist - ch.freqlist = iw.freqlist + ch.iwinfo = iw ch.template = "cbi/wireless_modefreq" function ch.cfgvalue(self, section) @@ -228,6 +229,10 @@ if hwtype == "mac80211" then s:taboption("advanced", Value, "country", translate("Country Code"), translate("Use ISO/IEC 3166 alpha2 country codes.")) end + legacyrates = s:taboption("advanced", Flag, "legacy_rates", translate("Allow legacy 802.11b rates")) + legacyrates.rmempty = false + legacyrates.default = "1" + s:taboption("advanced", Value, "distance", translate("Distance Optimization"), translate("Distance to farthest network member in meters.")) @@ -337,7 +342,6 @@ end ----------------------- Interface ----------------------- s = m:section(NamedSection, wnet.sid, "wifi-iface", translate("Interface Configuration")) -ifsection = s s.addremove = false s.anonymous = true s.defaults.device = wdev:name() @@ -347,15 +351,31 @@ s:tab("encryption", translate("Wireless Security")) s:tab("macfilter", translate("MAC-Filter")) s:tab("advanced", translate("Advanced Settings")) -ssid = s:taboption("general", Value, "ssid", translate("ESSID")) -ssid.datatype = "maxlength(32)" - mode = s:taboption("general", ListValue, "mode", translate("Mode")) mode.override_values = true mode:value("ap", translate("Access Point")) mode:value("sta", translate("Client")) mode:value("adhoc", translate("Ad-Hoc")) +meshid = s:taboption("general", Value, "mesh_id", translate("Mesh Id")) +meshid:depends({mode="mesh"}) + +meshfwd = s:taboption("advanced", Flag, "mesh_fwding", translate("Forward mesh peer traffic")) +meshfwd.rmempty = false +meshfwd.default = "1" +meshfwd:depends({mode="mesh"}) + +ssid = s:taboption("general", Value, "ssid", translate("ESSID")) +ssid.datatype = "maxlength(32)" +ssid:depends({mode="ap"}) +ssid:depends({mode="sta"}) +ssid:depends({mode="adhoc"}) +ssid:depends({mode="ahdemo"}) +ssid:depends({mode="monitor"}) +ssid:depends({mode="ap-wds"}) +ssid:depends({mode="sta-wds"}) +ssid:depends({mode="wds"}) + bssid = s:taboption("general", Value, "bssid", translate("BSSID")) network = s:taboption("general", Value, "network", translate("Network"), @@ -460,7 +480,7 @@ if hwtype == "mac80211" then wmm:depends({mode="ap"}) wmm:depends({mode="ap-wds"}) wmm.default = wmm.enabled - + isolate = s:taboption("advanced", Flag, "isolate", translate("Isolate Clients"), translate("Prevents client-to-client communication")) isolate:depends({mode="ap"}) @@ -769,6 +789,9 @@ if hwtype == "mac80211" or hwtype == "prism2" then ieee80211r:depends({mode="ap", encryption="psk"}) ieee80211r:depends({mode="ap", encryption="psk2"}) ieee80211r:depends({mode="ap", encryption="psk-mixed"}) + ieee80211r:depends({mode="ap-wds", encryption="psk"}) + ieee80211r:depends({mode="ap-wds", encryption="psk2"}) + ieee80211r:depends({mode="ap-wds", encryption="psk-mixed"}) end ieee80211r.rmempty = true @@ -790,9 +813,28 @@ if hwtype == "mac80211" or hwtype == "prism2" then mobility_domain.datatype = "and(hexstring,rangelength(4,4))" mobility_domain.rmempty = true + reassociation_deadline = s:taboption("encryption", Value, "reassociation_deadline", + translate("Reassociation Deadline"), + translate("time units (TUs / 1.024 ms) [1000-65535]")) + reassociation_deadline:depends({ieee80211r="1"}) + reassociation_deadline.placeholder = "1000" + reassociation_deadline.datatype = "range(1000,65535)" + reassociation_deadline.rmempty = true + + ft_protocol = s:taboption("encryption", ListValue, "ft_over_ds", translate("FT protocol")) + ft_protocol:depends({ieee80211r="1"}) + ft_protocol:value("1", translatef("FT over DS")) + ft_protocol:value("0", translatef("FT over the Air")) + ft_protocol.rmempty = true + + ft_psk_generate_local = s:taboption("encryption", Flag, "ft_psk_generate_local", + translate("Generate PMK locally"), + translate("When using a PSK, the PMK can be generated locally without inter AP communications")) + ft_psk_generate_local:depends({ieee80211r="1"}) + r0_key_lifetime = s:taboption("encryption", Value, "r0_key_lifetime", translate("R0 Key Lifetime"), translate("minutes")) - r0_key_lifetime:depends({ieee80211r="1"}) + r0_key_lifetime:depends({ieee80211r="1", ft_psk_generate_local=""}) r0_key_lifetime.placeholder = "10000" r0_key_lifetime.datatype = "uinteger" r0_key_lifetime.rmempty = true @@ -800,21 +842,13 @@ if hwtype == "mac80211" or hwtype == "prism2" then r1_key_holder = s:taboption("encryption", Value, "r1_key_holder", translate("R1 Key Holder"), translate("6-octet identifier as a hex string - no colons")) - r1_key_holder:depends({ieee80211r="1"}) + r1_key_holder:depends({ieee80211r="1", ft_psk_generate_local=""}) r1_key_holder.placeholder = "00004f577274" r1_key_holder.datatype = "and(hexstring,rangelength(12,12))" r1_key_holder.rmempty = true - reassociation_deadline = s:taboption("encryption", Value, "reassociation_deadline", - translate("Reassociation Deadline"), - translate("time units (TUs / 1.024 ms) [1000-65535]")) - reassociation_deadline:depends({ieee80211r="1"}) - reassociation_deadline.placeholder = "1000" - reassociation_deadline.datatype = "range(1000,65535)" - reassociation_deadline.rmempty = true - pmk_r1_push = s:taboption("encryption", Flag, "pmk_r1_push", translate("PMK R1 Push")) - pmk_r1_push:depends({ieee80211r="1"}) + pmk_r1_push:depends({ieee80211r="1", ft_psk_generate_local=""}) pmk_r1_push.placeholder = "0" pmk_r1_push.rmempty = true @@ -824,8 +858,7 @@ if hwtype == "mac80211" or hwtype == "prism2" then "
This list is used to map R0KH-ID (NAS Identifier) to a destination " .. "MAC address when requesting PMK-R1 key from the R0KH that the STA " .. "used during the Initial Mobility Domain Association.")) - - r0kh:depends({ieee80211r="1"}) + r0kh:depends({ieee80211r="1", ft_psk_generate_local=""}) r0kh.rmempty = true r1kh = s:taboption("encryption", DynamicList, "r1kh", translate("External R1 Key Holder List"), @@ -834,7 +867,7 @@ if hwtype == "mac80211" or hwtype == "prism2" then "
This list is used to map R1KH-ID to a destination MAC address " .. "when sending PMK-R1 key from the R0KH. This is also the " .. "list of authorized R1KHs in the MD that can request PMK-R1 keys.")) - r1kh:depends({ieee80211r="1"}) + r1kh:depends({ieee80211r="1", ft_psk_generate_local=""}) r1kh.rmempty = true -- End of 802.11r options @@ -978,43 +1011,54 @@ end -- ieee802.11w options if hwtype == "mac80211" then - local has_80211w = (os.execute("hostapd -v11w 2>/dev/null || hostapd -veap 2>/dev/null") == 0) - if has_80211w then - ieee80211w = s:taboption("encryption", ListValue, "ieee80211w", - translate("802.11w Management Frame Protection"), - translate("Requires the 'full' version of wpad/hostapd " .. - "and support from the wifi driver
(as of Feb 2017: " .. - "ath9k and ath10k, in LEDE also mwlwifi and mt76)")) - ieee80211w.default = "" - ieee80211w.rmempty = true - ieee80211w:value("", translate("Disabled (default)")) - ieee80211w:value("1", translate("Optional")) - ieee80211w:value("2", translate("Required")) - ieee80211w:depends({mode="ap", encryption="wpa2"}) - ieee80211w:depends({mode="ap-wds", encryption="wpa2"}) - ieee80211w:depends({mode="ap", encryption="psk2"}) - ieee80211w:depends({mode="ap", encryption="psk-mixed"}) - ieee80211w:depends({mode="ap-wds", encryption="psk2"}) - ieee80211w:depends({mode="ap-wds", encryption="psk-mixed"}) - - max_timeout = s:taboption("encryption", Value, "ieee80211w_max_timeout", - translate("802.11w maximum timeout"), - translate("802.11w Association SA Query maximum timeout")) - max_timeout:depends({ieee80211w="1"}) - max_timeout:depends({ieee80211w="2"}) - max_timeout.datatype = "uinteger" - max_timeout.placeholder = "1000" - max_timeout.rmempty = true - - retry_timeout = s:taboption("encryption", Value, "ieee80211w_retry_timeout", - translate("802.11w retry timeout"), - translate("802.11w Association SA Query retry timeout")) - retry_timeout:depends({ieee80211w="1"}) - retry_timeout:depends({ieee80211w="2"}) - retry_timeout.datatype = "uinteger" - retry_timeout.placeholder = "201" - retry_timeout.rmempty = true - end + local has_80211w = (os.execute("hostapd -v11w 2>/dev/null || hostapd -veap 2>/dev/null") == 0) + if has_80211w then + ieee80211w = s:taboption("encryption", ListValue, "ieee80211w", + translate("802.11w Management Frame Protection"), + translate("Requires the 'full' version of wpad/hostapd " .. + "and support from the wifi driver
(as of Feb 2017: " .. + "ath9k and ath10k, in LEDE also mwlwifi and mt76)")) + ieee80211w.default = "" + ieee80211w.rmempty = true + ieee80211w:value("", translate("Disabled (default)")) + ieee80211w:value("1", translate("Optional")) + ieee80211w:value("2", translate("Required")) + ieee80211w:depends({mode="ap", encryption="wpa2"}) + ieee80211w:depends({mode="ap-wds", encryption="wpa2"}) + ieee80211w:depends({mode="ap", encryption="psk2"}) + ieee80211w:depends({mode="ap", encryption="psk-mixed"}) + ieee80211w:depends({mode="ap-wds", encryption="psk2"}) + ieee80211w:depends({mode="ap-wds", encryption="psk-mixed"}) + + max_timeout = s:taboption("encryption", Value, "ieee80211w_max_timeout", + translate("802.11w maximum timeout"), + translate("802.11w Association SA Query maximum timeout")) + max_timeout:depends({ieee80211w="1"}) + max_timeout:depends({ieee80211w="2"}) + max_timeout.datatype = "uinteger" + max_timeout.placeholder = "1000" + max_timeout.rmempty = true + + retry_timeout = s:taboption("encryption", Value, "ieee80211w_retry_timeout", + translate("802.11w retry timeout"), + translate("802.11w Association SA Query retry timeout")) + retry_timeout:depends({ieee80211w="1"}) + retry_timeout:depends({ieee80211w="2"}) + retry_timeout.datatype = "uinteger" + retry_timeout.placeholder = "201" + retry_timeout.rmempty = true + end + + key_retries = s:taboption("encryption", Flag, "wpa_disable_eapol_key_retries", + translate("Enable key reinstallation (KRACK) countermeasures"), + translate("Complicates key reinstallation attacks on the client side by disabling retransmission of EAPOL-Key frames that are used to install keys. This workaround might cause interoperability issues and reduced robustness of key negotiation especially in environments with heavy traffic load.")) + + key_retries:depends({mode="ap", encryption="wpa2"}) + key_retries:depends({mode="ap", encryption="psk2"}) + key_retries:depends({mode="ap", encryption="psk-mixed"}) + key_retries:depends({mode="ap-wds", encryption="wpa2"}) + key_retries:depends({mode="ap-wds", encryption="psk2"}) + key_retries:depends({mode="ap-wds", encryption="psk-mixed"}) end if hwtype == "mac80211" or hwtype == "prism2" then