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=e8d43a1ba5580882d1a4657d418d60feaddff273;hp=9db42e3c4e9c870f75905dbccfc73ae166e53f57;hb=63255ec38b2f5849fec9e54d3f3e2aa7ef76bd72;hpb=6d7b293692e339459b591a5da27ea32f268e4bc7 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 9db42e3c4..e8d43a1ba 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 @@ -42,6 +42,9 @@ 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) @@ -56,7 +59,14 @@ function m.parse(map) 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()) @@ -94,7 +104,7 @@ local function txpower_current(pwr, list) end end end - return (list[#list] and list[#list].driver_dbm) or pwr or 0 + return pwr or "" end local iw = luci.sys.wifi.getiwinfo(arg[1]) @@ -191,7 +201,7 @@ end ------------------- MAC80211 Device ------------------ if hwtype == "mac80211" then - if #tx_power_list > 1 then + if #tx_power_list > 0 then tp = s:taboption("general", ListValue, "txpower", translate("Transmit Power"), "dBm") tp.rmempty = true @@ -200,6 +210,7 @@ if hwtype == "mac80211" then return txpower_current(Value.cfgvalue(...), tx_power_list) end + tp:value("", translate("auto")) for _, p in ipairs(tx_power_list) do tp:value(p.driver_dbm, "%i dBm (%i mW)" %{ p.display_dbm, p.display_mw }) @@ -237,9 +248,9 @@ if hwtype == "mac80211" then end -------------------- Madwifi Device ------------------ +------------------- Broadcom Device ------------------ -if hwtype == "atheros" then +if hwtype == "broadcom" then tp = s:taboption("general", (#tx_power_list > 0) and ListValue or Value, "txpower", translate("Transmit Power"), "dBm") @@ -251,66 +262,40 @@ if hwtype == "atheros" then return txpower_current(Value.cfgvalue(...), tx_power_list) end + tp:value("", translate("auto")) for _, p in ipairs(tx_power_list) do tp:value(p.driver_dbm, "%i dBm (%i mW)" %{ p.display_dbm, p.display_mw }) end - s:taboption("advanced", Flag, "diversity", translate("Diversity")).rmempty = false - - if not nsantenna then - ant1 = s:taboption("advanced", ListValue, "txantenna", translate("Transmitter Antenna")) - ant1.widget = "radio" - ant1.orientation = "horizontal" - ant1:depends("diversity", "") - ant1:value("0", translate("auto")) - ant1:value("1", translate("Antenna 1")) - ant1:value("2", translate("Antenna 2")) - - ant2 = s:taboption("advanced", ListValue, "rxantenna", translate("Receiver Antenna")) - ant2.widget = "radio" - ant2.orientation = "horizontal" - ant2:depends("diversity", "") - ant2:value("0", translate("auto")) - ant2:value("1", translate("Antenna 1")) - ant2:value("2", translate("Antenna 2")) - - else -- NanoFoo - local ant = s:taboption("advanced", ListValue, "antenna", translate("Transmitter Antenna")) - ant:value("auto") - ant:value("vertical") - ant:value("horizontal") - ant:value("external") + mode = s:taboption("advanced", ListValue, "hwmode", translate("Band")) + if hw_modes.b then + mode:value("11b", "2.4GHz (802.11b)") + if hw_modes.g then + mode:value("11bg", "2.4GHz (802.11b+g)") + end end - - s:taboption("advanced", Value, "distance", translate("Distance Optimization"), - translate("Distance to farthest network member in meters.")) - s:taboption("advanced", Value, "regdomain", translate("Regulatory Domain")) - s:taboption("advanced", Value, "country", translate("Country Code")) - s:taboption("advanced", Flag, "outdoor", translate("Outdoor Channels")) - - --s:option(Flag, "nosbeacon", translate("Disable HW-Beacon timer")) -end - - - -------------------- Broadcom Device ------------------ - -if hwtype == "broadcom" then - tp = s:taboption("general", - (#tx_power_list > 0) and ListValue or Value, - "txpower", translate("Transmit Power"), "dBm") - - tp.rmempty = true - tp.default = tx_power_cur - - function tp.cfgvalue(...) - return txpower_current(Value.cfgvalue(...), tx_power_list) + if hw_modes.g then + mode:value("11g", "2.4GHz (802.11g)") + mode:value("11gst", "2.4GHz (802.11g + Turbo)") + mode:value("11lrs", "2.4GHz (802.11g Limited Rate Support)") end - - for _, p in ipairs(tx_power_list) do - tp:value(p.driver_dbm, "%i dBm (%i mW)" - %{ p.display_dbm, p.display_mw }) + if hw_modes.a then mode:value("11a", "5GHz (802.11a)") end + if hw_modes.n then + if hw_modes.g then + mode:value("11ng", "2.4GHz (802.11g+n)") + mode:value("11n", "2.4GHz (802.11n)") + end + if hw_modes.a then + mode:value("11na", "5GHz (802.11a+n)") + mode:value("11n", "5GHz (802.11n)") + end + htmode = s:taboption("advanced", ListValue, "htmode", translate("HT mode (802.11n)")) + htmode:depends("hwmode", "11ng") + htmode:depends("hwmode", "11na") + htmode:depends("hwmode", "11n") + htmode:value("HT20", "20MHz") + htmode:value("HT40", "40MHz") end ant1 = s:taboption("advanced", ListValue, "txantenna", translate("Transmitter Antenna")) @@ -362,15 +347,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("internal forwarding of Mesh-peers")) +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"), @@ -475,100 +476,14 @@ if hwtype == "mac80211" then wmm:depends({mode="ap"}) wmm:depends({mode="ap-wds"}) wmm.default = wmm.enabled -end - - - --------------------- Madwifi Interface ---------------------- -if hwtype == "atheros" then - mode:value("ahdemo", translate("Pseudo Ad-Hoc (ahdemo)")) - mode:value("monitor", translate("Monitor")) - mode:value("ap-wds", "%s (%s)" % {translate("Access Point"), translate("WDS")}) - mode:value("sta-wds", "%s (%s)" % {translate("Client"), translate("WDS")}) - mode:value("wds", translate("Static WDS")) - - function mode.write(self, section, value) - if value == "ap-wds" then - ListValue.write(self, section, "ap") - m.uci:set("wireless", section, "wds", 1) - elseif value == "sta-wds" then - ListValue.write(self, section, "sta") - m.uci:set("wireless", section, "wds", 1) - else - ListValue.write(self, section, value) - m.uci:delete("wireless", section, "wds") - end - end - - function mode.cfgvalue(self, section) - local mode = ListValue.cfgvalue(self, section) - local wds = m.uci:get("wireless", section, "wds") == "1" - - if mode == "ap" and wds then - return "ap-wds" - elseif mode == "sta" and wds then - return "sta-wds" - else - return mode - end - end - - bssid:depends({mode="adhoc"}) - bssid:depends({mode="ahdemo"}) - bssid:depends({mode="wds"}) - - wdssep = s:taboption("advanced", Flag, "wdssep", translate("Separate WDS")) - wdssep:depends({mode="ap-wds"}) - - s:taboption("advanced", Flag, "doth", "802.11h") - hidden = s:taboption("general", Flag, "hidden", translate("Hide ESSID")) - hidden:depends({mode="ap"}) - hidden:depends({mode="adhoc"}) - hidden:depends({mode="ap-wds"}) - hidden:depends({mode="sta-wds"}) - isolate = s:taboption("advanced", Flag, "isolate", translate("Separate Clients"), + isolate = s:taboption("advanced", Flag, "isolate", translate("Isolate Clients"), translate("Prevents client-to-client communication")) isolate:depends({mode="ap"}) - s:taboption("advanced", Flag, "bgscan", translate("Background Scan")) + isolate:depends({mode="ap-wds"}) - mp = s:taboption("macfilter", ListValue, "macpolicy", translate("MAC-Address Filter")) - mp:value("", translate("disable")) - mp:value("allow", translate("Allow listed only")) - mp:value("deny", translate("Allow all except listed")) - - ml = s:taboption("macfilter", DynamicList, "maclist", translate("MAC-List")) - ml.datatype = "macaddr" - ml:depends({macpolicy="allow"}) - ml:depends({macpolicy="deny"}) - nt.mac_hints(function(mac, name) ml:value(mac, "%s (%s)" %{ mac, name }) end) - - s:taboption("advanced", Value, "rate", translate("Transmission Rate")) - s:taboption("advanced", Value, "mcast_rate", translate("Multicast Rate")) - s:taboption("advanced", Value, "frag", translate("Fragmentation Threshold")) - s:taboption("advanced", Value, "rts", translate("RTS/CTS Threshold")) - s:taboption("advanced", Value, "minrate", translate("Minimum Rate")) - s:taboption("advanced", Value, "maxrate", translate("Maximum Rate")) - s:taboption("advanced", Flag, "compression", translate("Compression")) - - s:taboption("advanced", Flag, "bursting", translate("Frame Bursting")) - s:taboption("advanced", Flag, "turbo", translate("Turbo Mode")) - s:taboption("advanced", Flag, "ff", translate("Fast Frames")) - - s:taboption("advanced", Flag, "wmm", translate("WMM Mode")) - s:taboption("advanced", Flag, "xr", translate("XR Support")) - s:taboption("advanced", Flag, "ar", translate("AR Support")) - - local swm = s:taboption("advanced", Flag, "sw_merge", translate("Disable HW-Beacon timer")) - swm:depends({mode="adhoc"}) - - local nos = s:taboption("advanced", Flag, "nosbeacon", translate("Disable HW-Beacon timer")) - nos:depends({mode="sta"}) - nos:depends({mode="sta-wds"}) - - local probereq = s:taboption("advanced", Flag, "probereq", translate("Do not send probe responses")) - probereq.enabled = "0" - probereq.disabled = "1" + ifname = s:taboption("advanced", Value, "ifname", translate("Interface name"), translate("Override default interface name")) + ifname.optional = true end @@ -692,7 +607,7 @@ encr:value("none", "No Encryption") encr:value("wep-open", translate("WEP Open System"), {mode="ap"}, {mode="sta"}, {mode="ap-wds"}, {mode="sta-wds"}, {mode="adhoc"}, {mode="ahdemo"}, {mode="wds"}) encr:value("wep-shared", translate("WEP Shared Key"), {mode="ap"}, {mode="sta"}, {mode="ap-wds"}, {mode="sta-wds"}, {mode="adhoc"}, {mode="ahdemo"}, {mode="wds"}) -if hwtype == "atheros" or hwtype == "mac80211" or hwtype == "prism2" then +if hwtype == "mac80211" or hwtype == "prism2" then local supplicant = fs.access("/usr/sbin/wpa_supplicant") local hostapd = fs.access("/usr/sbin/hostapd") @@ -701,9 +616,9 @@ if hwtype == "atheros" or hwtype == "mac80211" or hwtype == "prism2" then local has_sta_eap = (os.execute("wpa_supplicant -veap >/dev/null 2>/dev/null") == 0) if hostapd and supplicant then - encr:value("psk", "WPA-PSK", {mode="ap"}, {mode="sta"}, {mode="ap-wds"}, {mode="sta-wds"}) - encr:value("psk2", "WPA2-PSK", {mode="ap"}, {mode="sta"}, {mode="ap-wds"}, {mode="sta-wds"}) - encr:value("psk-mixed", "WPA-PSK/WPA2-PSK Mixed Mode", {mode="ap"}, {mode="sta"}, {mode="ap-wds"}, {mode="sta-wds"}) + encr:value("psk", "WPA-PSK", {mode="ap"}, {mode="sta"}, {mode="ap-wds"}, {mode="sta-wds"}, {mode="adhoc"}) + encr:value("psk2", "WPA2-PSK", {mode="ap"}, {mode="sta"}, {mode="ap-wds"}, {mode="sta-wds"}, {mode="adhoc"}) + encr:value("psk-mixed", "WPA-PSK/WPA2-PSK Mixed Mode", {mode="ap"}, {mode="sta"}, {mode="ap-wds"}, {mode="sta-wds"}, {mode="adhoc"}) if has_ap_eap and has_sta_eap then encr:value("wpa", "WPA-EAP", {mode="ap"}, {mode="sta"}, {mode="ap-wds"}, {mode="sta-wds"}) encr:value("wpa2", "WPA2-EAP", {mode="ap"}, {mode="sta"}, {mode="ap-wds"}, {mode="sta-wds"}) @@ -721,9 +636,9 @@ if hwtype == "atheros" or hwtype == "mac80211" or hwtype == "prism2" then "and ad-hoc mode) to be installed." ) elseif not hostapd and supplicant then - encr:value("psk", "WPA-PSK", {mode="sta"}, {mode="sta-wds"}) - encr:value("psk2", "WPA2-PSK", {mode="sta"}, {mode="sta-wds"}) - encr:value("psk-mixed", "WPA-PSK/WPA2-PSK Mixed Mode", {mode="sta"}, {mode="sta-wds"}) + encr:value("psk", "WPA-PSK", {mode="sta"}, {mode="sta-wds"}, {mode="adhoc"}) + encr:value("psk2", "WPA2-PSK", {mode="sta"}, {mode="sta-wds"}, {mode="adhoc"}) + encr:value("psk-mixed", "WPA-PSK/WPA2-PSK Mixed Mode", {mode="sta"}, {mode="sta-wds"}, {mode="adhoc"}) if has_sta_eap then encr:value("wpa", "WPA-EAP", {mode="sta"}, {mode="sta-wds"}) encr:value("wpa2", "WPA2-EAP", {mode="sta"}, {mode="sta-wds"}) @@ -853,14 +768,105 @@ for slot=1,4 do end -if hwtype == "atheros" or hwtype == "mac80211" or hwtype == "prism2" then - nasid = s:taboption("encryption", Value, "nasid", translate("NAS ID")) +if hwtype == "mac80211" or hwtype == "prism2" then + + -- Probe 802.11r support (and EAP support as a proxy for Openwrt) + local has_80211r = (os.execute("hostapd -v11r 2>/dev/null || hostapd -veap 2>/dev/null") == 0) + + ieee80211r = s:taboption("encryption", Flag, "ieee80211r", + translate("802.11r Fast Transition"), + translate("Enables fast roaming among access points that belong " .. + "to the same Mobility Domain")) + ieee80211r:depends({mode="ap", encryption="wpa"}) + ieee80211r:depends({mode="ap", encryption="wpa2"}) + ieee80211r:depends({mode="ap-wds", encryption="wpa"}) + ieee80211r:depends({mode="ap-wds", encryption="wpa2"}) + if has_80211r 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 + + nasid = s:taboption("encryption", Value, "nasid", translate("NAS ID"), + translate("Used for two different purposes: RADIUS NAS ID and " .. + "802.11r R0KH-ID. Not needed with normal WPA(2)-PSK.")) nasid:depends({mode="ap", encryption="wpa"}) nasid:depends({mode="ap", encryption="wpa2"}) nasid:depends({mode="ap-wds", encryption="wpa"}) nasid:depends({mode="ap-wds", encryption="wpa2"}) + nasid:depends({ieee80211r="1"}) nasid.rmempty = true + mobility_domain = s:taboption("encryption", Value, "mobility_domain", + translate("Mobility Domain"), + translate("4-character hexadecimal ID")) + mobility_domain:depends({ieee80211r="1"}) + mobility_domain.placeholder = "4f57" + 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", ft_psk_generate_local=""}) + r0_key_lifetime.placeholder = "10000" + r0_key_lifetime.datatype = "uinteger" + r0_key_lifetime.rmempty = true + + 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", ft_psk_generate_local=""}) + r1_key_holder.placeholder = "00004f577274" + r1_key_holder.datatype = "and(hexstring,rangelength(12,12))" + r1_key_holder.rmempty = true + + pmk_r1_push = s:taboption("encryption", Flag, "pmk_r1_push", translate("PMK R1 Push")) + pmk_r1_push:depends({ieee80211r="1", ft_psk_generate_local=""}) + pmk_r1_push.placeholder = "0" + pmk_r1_push.rmempty = true + + r0kh = s:taboption("encryption", DynamicList, "r0kh", translate("External R0 Key Holder List"), + translate("List of R0KHs in the same Mobility Domain. " .. + "
Format: MAC-address,NAS-Identifier,128-bit key as hex string. " .. + "
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", ft_psk_generate_local=""}) + r0kh.rmempty = true + + r1kh = s:taboption("encryption", DynamicList, "r1kh", translate("External R1 Key Holder List"), + translate ("List of R1KHs in the same Mobility Domain. ".. + "
Format: MAC-address,R1KH-ID as 6 octets with colons,128-bit key as hex string. ".. + "
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", ft_psk_generate_local=""}) + r1kh.rmempty = true + -- End of 802.11r options + eaptype = s:taboption("encryption", ListValue, "eap_type", translate("EAP-Method")) eaptype:value("tls", "TLS") eaptype:value("ttls", "TTLS") @@ -964,6 +970,24 @@ if hwtype == "atheros" or hwtype == "mac80211" or hwtype == "prism2" then identity:depends({mode="sta-wds", eap_type="tls", encryption="wpa2"}) identity:depends({mode="sta-wds", eap_type="tls", encryption="wpa"}) + anonymous_identity = s:taboption("encryption", Value, "anonymous_identity", translate("Anonymous Identity")) + anonymous_identity:depends({mode="sta", eap_type="fast", encryption="wpa2"}) + anonymous_identity:depends({mode="sta", eap_type="fast", encryption="wpa"}) + anonymous_identity:depends({mode="sta", eap_type="peap", encryption="wpa2"}) + anonymous_identity:depends({mode="sta", eap_type="peap", encryption="wpa"}) + anonymous_identity:depends({mode="sta", eap_type="ttls", encryption="wpa2"}) + anonymous_identity:depends({mode="sta", eap_type="ttls", encryption="wpa"}) + anonymous_identity:depends({mode="sta-wds", eap_type="fast", encryption="wpa2"}) + anonymous_identity:depends({mode="sta-wds", eap_type="fast", encryption="wpa"}) + anonymous_identity:depends({mode="sta-wds", eap_type="peap", encryption="wpa2"}) + anonymous_identity:depends({mode="sta-wds", eap_type="peap", encryption="wpa"}) + anonymous_identity:depends({mode="sta-wds", eap_type="ttls", encryption="wpa2"}) + anonymous_identity:depends({mode="sta-wds", eap_type="ttls", encryption="wpa"}) + anonymous_identity:depends({mode="sta", eap_type="tls", encryption="wpa2"}) + anonymous_identity:depends({mode="sta", eap_type="tls", encryption="wpa"}) + anonymous_identity:depends({mode="sta-wds", eap_type="tls", encryption="wpa2"}) + anonymous_identity:depends({mode="sta-wds", eap_type="tls", encryption="wpa"}) + password = s:taboption("encryption", Value, "password", translate("Password")) password:depends({mode="sta", eap_type="fast", encryption="wpa2"}) password:depends({mode="sta", eap_type="fast", encryption="wpa"}) @@ -981,7 +1005,59 @@ if hwtype == "atheros" or hwtype == "mac80211" or hwtype == "prism2" then password.password = true end -if hwtype == "atheros" or hwtype == "mac80211" or hwtype == "prism2" then +-- 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 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 local wpasupplicant = fs.access("/usr/sbin/wpa_supplicant") local hostcli = fs.access("/usr/sbin/hostapd_cli") if hostcli and wpasupplicant then