mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-10-29 01:22:25 +00:00
hostapd: add enhanced MPSK support
Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
@@ -604,7 +604,7 @@ define Package/afcd/install
|
||||
endef
|
||||
|
||||
define Install/hostapd
|
||||
$(INSTALL_DIR) $(1)/usr/sbin $(1)/usr/share/hostap
|
||||
$(INSTALL_DIR) $(1)/usr/sbin $(1)/usr/share/hostap $(1)/etc/init.d
|
||||
$(INSTALL_DATA) ./files/hostapd.uc $(1)/usr/share/hostap/
|
||||
$(INSTALL_DIR) $(1)/etc/init.d $(1)/etc/config $(1)/etc/radius
|
||||
ln -sf hostapd $(1)/usr/sbin/hostapd-radius
|
||||
@@ -612,6 +612,8 @@ define Install/hostapd
|
||||
$(INSTALL_DATA) ./files/radius.config $(1)/etc/config/radius
|
||||
$(INSTALL_DATA) ./files/radius.clients $(1)/etc/radius/clients
|
||||
$(INSTALL_DATA) ./files/radius.users $(1)/etc/radius/users
|
||||
$(INSTALL_BIN) ./files/mpskd $(1)/usr/share/hostap/
|
||||
$(INSTALL_BIN) ./files/mpskd.init $(1)/etc/init.d/mpskd
|
||||
endef
|
||||
|
||||
define Install/supplicant
|
||||
|
||||
319
feeds/ipq807x_v5.4/hostapd/files/mpskd
Normal file
319
feeds/ipq807x_v5.4/hostapd/files/mpskd
Normal file
@@ -0,0 +1,319 @@
|
||||
#!/usr/bin/env ucode
|
||||
'use strict';
|
||||
import * as uloop from 'uloop';
|
||||
import * as libubus from 'ubus';
|
||||
|
||||
uloop.init();
|
||||
let ubus = libubus.connect();
|
||||
|
||||
let interfaces = {};
|
||||
let ssids = {};
|
||||
let cache = {};
|
||||
let sub_6g = [];
|
||||
let sub_6g_obj;
|
||||
let reload_timer;
|
||||
let gc_timer;
|
||||
|
||||
let timeout = 48 * 60 * 60;
|
||||
|
||||
function event_cb_6g(req) {
|
||||
//printf('6g %s %.J\n', req.data, req.type);
|
||||
if (req.type != 'auth' && req.type != 'probe')
|
||||
return 0;
|
||||
|
||||
let addr = req.data.address;
|
||||
let iface = interfaces[req.data.ifname];
|
||||
if (!iface)
|
||||
return 0;
|
||||
|
||||
let ssid = iface.ssid;
|
||||
if (!ssid || !length(ssids[ssid].keys))
|
||||
return 0;
|
||||
|
||||
let ssid_cache = cache[ssid];
|
||||
if (ssid_cache && ssid_cache[addr])
|
||||
return 0;
|
||||
|
||||
if (req.type == 'probe') {
|
||||
printf(`Ignore probe ${req.type} on ${req.data.ifname} from ${addr}\n`);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf(`reject ${req.type} on ${req.data.ifname} from ${addr}\n`);
|
||||
return 5;
|
||||
}
|
||||
|
||||
function event_cb(req) {
|
||||
//printf('normal %s %.J\n', req.data, req.type);
|
||||
if (req.type != 'probe')
|
||||
return 0;
|
||||
|
||||
let addr = req.data.address;
|
||||
let iface = interfaces[req.data.ifname];
|
||||
if (!iface)
|
||||
return 0;
|
||||
|
||||
let ssid = iface.ssid;
|
||||
if (!ssid || !length(ssids[ssid].keys))
|
||||
return 0;
|
||||
|
||||
let ssid_cache = cache[ssid];
|
||||
if (ssid_cache && ssid_cache[addr])
|
||||
return 0;
|
||||
|
||||
printf(`reply to ${req.type} on ${req.data.ifname} from ${addr} without 6G RNR\n`);
|
||||
return 2;
|
||||
}
|
||||
|
||||
function create_6g_subscriber() {
|
||||
for (let cur_sub in sub_6g)
|
||||
cur_sub.remove();
|
||||
sub_6g = [];
|
||||
|
||||
for (let ifname, iface in interfaces) {
|
||||
let obj = 'hostapd.' + ifname;
|
||||
let cur_sub;
|
||||
if (iface.band == '6g')
|
||||
cur_sub = ubus.subscriber((req) => event_cb_6g(req));
|
||||
else
|
||||
cur_sub = ubus.subscriber((req) => event_cb(req));
|
||||
cur_sub.subscribe(obj);
|
||||
push(sub_6g, cur_sub);
|
||||
printf(`subscribe ${ifname}\n`);
|
||||
ubus.call(obj, 'notify_response', { notify_response: 1 });
|
||||
}
|
||||
}
|
||||
|
||||
function cache_gc() {
|
||||
let ts = time();
|
||||
|
||||
for (let ssid in keys(cache)) {
|
||||
if (!ssids[ssid]) {
|
||||
delete cache[ssid];
|
||||
continue;
|
||||
}
|
||||
|
||||
let ssid_cache = cache[ssid];
|
||||
ssid = ssids[ssid];
|
||||
|
||||
for (let addr in keys(ssid_cache)) {
|
||||
let sta = ssid_cache[addr];
|
||||
let keep = ts < cache.timeout;
|
||||
|
||||
if (keep && !ssid.keys[sta.key])
|
||||
keep = false;
|
||||
if (keep)
|
||||
sta.keydata = ssid.keys[sta.key];
|
||||
if (!keep)
|
||||
delete cache[addr];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function netifd_reload() {
|
||||
let data = ubus.call('network.wireless', 'status');
|
||||
|
||||
ssids = {};
|
||||
interfaces = {};
|
||||
|
||||
for (let radio_name, radio in data) {
|
||||
if (!radio.up)
|
||||
continue;
|
||||
|
||||
for (let iface in radio.interfaces) {
|
||||
let config = iface.config;
|
||||
|
||||
if (config.mode != 'ap' || !iface.ifname)
|
||||
continue;
|
||||
|
||||
let band = radio.config.band;
|
||||
let nr_data = ubus.call('hostapd.' + iface.ifname, 'rrm_nr_get_own');
|
||||
let nr;
|
||||
if (nr_data && nr_data.value && nr_data.value[2])
|
||||
nr = nr_data.value[2];
|
||||
interfaces[iface.ifname] = {
|
||||
band, nr,
|
||||
ssid: config.ssid,
|
||||
};
|
||||
|
||||
ssids[config.ssid] ??= {
|
||||
interfaces: [],
|
||||
keys: {},
|
||||
bands: {},
|
||||
};
|
||||
let ssid = ssids[config.ssid];
|
||||
|
||||
push(ssid.interfaces, iface.ifname);
|
||||
ssid.bands[band] = iface.ifname;
|
||||
for (let sta in iface.stations) {
|
||||
let stacfg = sta.config;
|
||||
|
||||
let key = stacfg.key;
|
||||
if (!key)
|
||||
continue;
|
||||
|
||||
let keydata = {};
|
||||
let vid = stacfg.vid;
|
||||
if (vid)
|
||||
keydata.vlan = +vid;
|
||||
|
||||
ssid.keys[key] = keydata;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf('New config: %.J\n', { ssids, interfaces });
|
||||
cache_gc();
|
||||
create_6g_subscriber();
|
||||
}
|
||||
|
||||
function iface_ssid(ifname) {
|
||||
let iface = interfaces[ifname];
|
||||
if (!iface)
|
||||
return;
|
||||
|
||||
return iface.ssid;
|
||||
}
|
||||
|
||||
function sta_cache_entry_get(ssid, addr) {
|
||||
let ssid_cache = cache[ssid] ?? {};
|
||||
|
||||
let entry = ssid_cache[addr];
|
||||
if (entry)
|
||||
entry.timeout = time() + timeout;
|
||||
|
||||
printf(`Get cache entry ssid=${ssid} addr=${addr}: ${entry}\n`);
|
||||
return entry;
|
||||
}
|
||||
|
||||
function sta_cache_entry_add(ssid, addr, key) {
|
||||
cache[ssid] ??= {};
|
||||
let ssid_cache = cache[ssid];
|
||||
let ssid_data = ssids[ssid];
|
||||
let keydata = ssid_data.keys[key];
|
||||
|
||||
let cache_data = {
|
||||
timeout: time() + timeout,
|
||||
ssid, key,
|
||||
data: keydata ?? {},
|
||||
};
|
||||
ssid_cache[addr] = cache_data;
|
||||
printf(`Added cache entry ssid=${ssid} addr=${addr}\n`);
|
||||
return cache_data;
|
||||
}
|
||||
|
||||
function ssid_psk(ssid) {
|
||||
ssid = ssids[ssid];
|
||||
if (!ssid)
|
||||
return [];
|
||||
|
||||
return keys(ssid.keys);
|
||||
}
|
||||
|
||||
function sta_auth_psk(ifname, addr) {
|
||||
let ssid = iface_ssid(ifname);
|
||||
if (!ssid)
|
||||
return;
|
||||
|
||||
let cache = sta_cache_entry_get(ssid, addr);
|
||||
if (cache)
|
||||
return [ cache.key ];
|
||||
|
||||
return ssid_psk(ssid);
|
||||
}
|
||||
|
||||
function sta_auth_cache(ifname, addr, idx) {
|
||||
let ssid = iface_ssid(ifname);
|
||||
if (!ssid)
|
||||
return;
|
||||
|
||||
let cache = sta_cache_entry_get(ssid, addr);
|
||||
if (cache)
|
||||
return cache.data;
|
||||
|
||||
let psk = ssid_psk(ssid);
|
||||
if (!psk)
|
||||
return;
|
||||
|
||||
psk = psk[idx];
|
||||
if (!psk)
|
||||
return;
|
||||
|
||||
cache = sta_cache_entry_add(ssid, addr, psk);
|
||||
if (!cache)
|
||||
return;
|
||||
|
||||
let ssid_data = ssids[ssid];
|
||||
if (!ssid_data)
|
||||
return cache.data;
|
||||
|
||||
let target_ifname = ssid_data.bands['6g'];
|
||||
if (!target_ifname)
|
||||
return cache.data;
|
||||
|
||||
let target_iface = interfaces[target_ifname];
|
||||
if (!target_iface)
|
||||
return cache.data;
|
||||
|
||||
cache.timer = uloop.timer(30 * 1000, () => {
|
||||
let msg = {
|
||||
addr,
|
||||
disassociation_imminent: false,
|
||||
neighbors: [
|
||||
target_iface.nr
|
||||
],
|
||||
abridged: false,
|
||||
};
|
||||
printf(`ubus call hostapd.${ifname} bss_transition_request '${msg}'\n`);
|
||||
ubus.call('hostapd.' + ifname, 'bss_transition_request', msg);
|
||||
delete cache.timer;
|
||||
});
|
||||
|
||||
return cache.data;
|
||||
}
|
||||
|
||||
function auth_cb(msg) {
|
||||
let data = msg.data;
|
||||
|
||||
printf(`Event ${msg.type}: ${msg.data}\n`);
|
||||
switch (msg.type) {
|
||||
case 'sta_auth':
|
||||
return {
|
||||
psk: sta_auth_psk(data.iface, data.sta),
|
||||
force_psk: true,
|
||||
};
|
||||
case 'sta_connected':
|
||||
if (data.psk_idx == null)
|
||||
return;
|
||||
return sta_auth_cache(data.iface, data.sta, data.psk_idx);
|
||||
case 'reload':
|
||||
netifd_reload();
|
||||
reload_timer.set(5000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let ubus_methods = {
|
||||
state: {
|
||||
call: function(req) {
|
||||
return {
|
||||
interfaces,
|
||||
ssids,
|
||||
cache
|
||||
};
|
||||
},
|
||||
args: {
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
reload_timer = uloop.timer(-1, () => { netifd_reload(); });
|
||||
gc_timer = uloop.timer(1000, () => { gc_timer.set(30 * 1000); cache_gc(); });
|
||||
ubus.publish('mpsk', ubus_methods);
|
||||
let sub = ubus.subscriber(auth_cb);
|
||||
let listener = ubus.listener('ubus.object.add', (event, msg) => {
|
||||
if (msg.path == 'hostapd-auth')
|
||||
sub.subscribe(msg.path);
|
||||
});
|
||||
sub.subscribe('hostapd-auth');
|
||||
netifd_reload();
|
||||
uloop.run();
|
||||
13
feeds/ipq807x_v5.4/hostapd/files/mpskd.init
Normal file
13
feeds/ipq807x_v5.4/hostapd/files/mpskd.init
Normal file
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=19
|
||||
|
||||
USE_PROCD=1
|
||||
NAME=mpskd
|
||||
|
||||
start_service() {
|
||||
procd_open_instance mpskd
|
||||
procd_set_param command /usr/share/hostap/mpskd
|
||||
procd_set_param respawn
|
||||
procd_close_instance
|
||||
}
|
||||
156
feeds/ipq807x_v5.4/hostapd/patches/zzz-deny-6g-probe-resp.patch
Normal file
156
feeds/ipq807x_v5.4/hostapd/patches/zzz-deny-6g-probe-resp.patch
Normal file
@@ -0,0 +1,156 @@
|
||||
--- a/src/ap/ieee802_11.c
|
||||
+++ b/src/ap/ieee802_11.c
|
||||
@@ -7740,7 +7740,7 @@ enum colocation_mode get_colocation_mode
|
||||
}
|
||||
|
||||
|
||||
-size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type)
|
||||
+size_t _hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type, int add_6g)
|
||||
{
|
||||
size_t len = 0, current_len = 0;
|
||||
enum colocation_mode mode = get_colocation_mode(hapd);
|
||||
@@ -7753,7 +7753,7 @@ size_t hostapd_eid_rnr_len(struct hostap
|
||||
/* fallthrough */
|
||||
|
||||
case WLAN_FC_STYPE_PROBE_RESP:
|
||||
- if (mode == COLOCATED_LOWER_BAND)
|
||||
+ if (add_6g && mode == COLOCATED_LOWER_BAND)
|
||||
len += hostapd_eid_rnr_colocation_len(hapd,
|
||||
¤t_len);
|
||||
|
||||
@@ -7776,6 +7776,10 @@ size_t hostapd_eid_rnr_len(struct hostap
|
||||
return len;
|
||||
}
|
||||
|
||||
+size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type)
|
||||
+{
|
||||
+ return _hostapd_eid_rnr_len(hapd, type, 1);
|
||||
+}
|
||||
|
||||
static u8 *hostapd_eid_rnr_iface(struct hostapd_data *hapd,
|
||||
struct hostapd_data *reporting_hapd,
|
||||
@@ -7938,7 +7942,7 @@ static u8 *hostapd_eid_neighbor_report_d
|
||||
}
|
||||
|
||||
|
||||
-u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type)
|
||||
+u8 * _hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type, int add_6g)
|
||||
{
|
||||
u8 *eid_start = eid;
|
||||
size_t current_len = 0;
|
||||
@@ -7955,7 +7959,7 @@ u8 * hostapd_eid_rnr(struct hostapd_data
|
||||
/* fallthrough */
|
||||
|
||||
case WLAN_FC_STYPE_PROBE_RESP:
|
||||
- if (mode == COLOCATED_LOWER_BAND)
|
||||
+ if (add_6g && mode == COLOCATED_LOWER_BAND)
|
||||
eid = hostapd_eid_rnr_colocation(hapd, eid,
|
||||
¤t_len);
|
||||
|
||||
@@ -7981,4 +7985,9 @@ u8 * hostapd_eid_rnr(struct hostapd_data
|
||||
return eid;
|
||||
}
|
||||
|
||||
+u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type)
|
||||
+{
|
||||
+ return _hostapd_eid_rnr(hapd, eid, type, 1);
|
||||
+}
|
||||
+
|
||||
#endif /* CONFIG_NATIVE_WINDOWS */
|
||||
--- a/src/ap/ieee802_11.h
|
||||
+++ b/src/ap/ieee802_11.h
|
||||
@@ -135,6 +135,7 @@ u8 * hostapd_eid_time_zone(struct hostap
|
||||
int hostapd_update_time_adv(struct hostapd_data *hapd);
|
||||
void hostapd_client_poll_ok(struct hostapd_data *hapd, const u8 *addr);
|
||||
u8 * hostapd_eid_bss_max_idle_period(struct hostapd_data *hapd, u8 *eid);
|
||||
+u8 * _hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type, int add_6g);
|
||||
u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type);
|
||||
u8 * hostapd_eid_multiple_bssid(struct hostapd_data *hapd,
|
||||
struct hostapd_data *req_bss, u8 *eid, u8 *end,
|
||||
@@ -146,6 +147,7 @@ size_t hostapd_eid_multiple_bssid_len(st
|
||||
struct hostapd_data *req_bss, u32 type,
|
||||
const u8 *known_bssids,
|
||||
u8 known_bssids_len, size_t *rnr_len);
|
||||
+size_t _hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type, int add_6g);
|
||||
size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type);
|
||||
int auth_sae_init_committed(struct hostapd_data *hapd, struct sta_info *sta);
|
||||
#ifdef CONFIG_SAE
|
||||
--- a/src/ap/beacon.c
|
||||
+++ b/src/ap/beacon.c
|
||||
@@ -463,7 +463,8 @@ static u8 * hostapd_eid_supported_op_cla
|
||||
static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
|
||||
const struct ieee80211_mgmt *req,
|
||||
int is_p2p, size_t *resp_len,
|
||||
- const u8 *known_bssids, u8 known_bssids_len)
|
||||
+ const u8 *known_bssids, u8 known_bssids_len,
|
||||
+ int add_6g)
|
||||
{
|
||||
struct hostapd_data *req_bss = NULL;
|
||||
struct ieee80211_mgmt *resp;
|
||||
@@ -523,7 +524,7 @@ static u8 * hostapd_gen_probe_resp(struc
|
||||
known_bssids,
|
||||
known_bssids_len,
|
||||
NULL);
|
||||
- buflen += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_PROBE_RESP);
|
||||
+ buflen += _hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_PROBE_RESP, add_6g);
|
||||
|
||||
resp = os_zalloc(buflen);
|
||||
if (resp == NULL)
|
||||
@@ -706,7 +707,7 @@ static u8 * hostapd_gen_probe_resp(struc
|
||||
pos = hostapd_eid_mbo(hapd, pos, (u8 *) resp + buflen - pos);
|
||||
pos = hostapd_eid_owe_trans(hapd, pos, (u8 *) resp + buflen - pos);
|
||||
pos = hostapd_eid_dpp_cc(hapd, pos, (u8 *) resp + buflen - pos);
|
||||
- pos = hostapd_eid_rnr(hapd, pos, WLAN_FC_STYPE_PROBE_RESP);
|
||||
+ pos = _hostapd_eid_rnr(hapd, pos, WLAN_FC_STYPE_PROBE_RESP, add_6g);
|
||||
|
||||
if (hapd->conf->vendor_elements) {
|
||||
os_memcpy(pos, wpabuf_head(hapd->conf->vendor_elements),
|
||||
@@ -930,6 +931,7 @@ void handle_probe_req(struct hostapd_dat
|
||||
.ssi_signal = ssi_signal,
|
||||
.elems = &elems,
|
||||
};
|
||||
+ int ubus_response;
|
||||
|
||||
if (hapd->iconf->rssi_ignore_probe_request && ssi_signal &&
|
||||
ssi_signal < hapd->iconf->rssi_ignore_probe_request)
|
||||
@@ -1118,7 +1120,12 @@ void handle_probe_req(struct hostapd_dat
|
||||
}
|
||||
#endif /* CONFIG_P2P */
|
||||
|
||||
- if (hostapd_ubus_handle_event(hapd, &req)) {
|
||||
+ ubus_response = hostapd_ubus_handle_event(hapd, &req);
|
||||
+
|
||||
+ if (ubus_response == 2) {
|
||||
+ wpa_printf(MSG_DEBUG, "Probe request for " MACSTR " without 6G RNR.\n",
|
||||
+ MAC2STR(mgmt->sa));
|
||||
+ } else if (ubus_response) {
|
||||
wpa_printf(MSG_DEBUG, "Probe request for " MACSTR " rejected by ubus handler.\n",
|
||||
MAC2STR(mgmt->sa));
|
||||
return;
|
||||
@@ -1170,7 +1177,7 @@ void handle_probe_req(struct hostapd_dat
|
||||
|
||||
resp = hostapd_gen_probe_resp(hapd, mgmt, elems.p2p != NULL,
|
||||
&resp_len, elems.known_bssids,
|
||||
- elems.known_bssids_len);
|
||||
+ elems.known_bssids_len, ubus_response == 2 ? 0 : 1);
|
||||
if (resp == NULL)
|
||||
return;
|
||||
|
||||
@@ -1239,7 +1246,7 @@ static u8 * hostapd_probe_resp_offloads(
|
||||
"this");
|
||||
|
||||
/* Generate a Probe Response template for the non-P2P case */
|
||||
- return hostapd_gen_probe_resp(hapd, NULL, 0, resp_len, NULL, 0);
|
||||
+ return hostapd_gen_probe_resp(hapd, NULL, 0, resp_len, NULL, 0, 1);
|
||||
}
|
||||
|
||||
#endif /* NEED_AP_MLME */
|
||||
@@ -1269,7 +1276,7 @@ static u8 * hostapd_unsol_bcast_probe_re
|
||||
|
||||
return hostapd_gen_probe_resp(hapd, NULL, 0,
|
||||
¶ms->unsol_bcast_probe_resp_tmpl_len,
|
||||
- NULL, 0);
|
||||
+ NULL, 0, 1);
|
||||
}
|
||||
#endif /* CONFIG_IEEE80211AX */
|
||||
|
||||
@@ -1864,6 +1864,7 @@ int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_req
|
||||
|
||||
blob_buf_init(&b, 0);
|
||||
blobmsg_add_macaddr(&b, "address", addr);
|
||||
blobmsg_add_string(&b, "ifname", hapd->conf->iface);
|
||||
if (req->mgmt_frame)
|
||||
blobmsg_add_macaddr(&b, "target", req->mgmt_frame->da);
|
||||
if (req->ssi_signal)
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
{
|
||||
"uuid": 2,
|
||||
"radios": [
|
||||
{
|
||||
"band": "2G",
|
||||
"country": "US",
|
||||
"channel-mode": "HE",
|
||||
"channel-width": 20,
|
||||
"channel": "auto"
|
||||
}, {
|
||||
"band": "5G",
|
||||
"country": "US",
|
||||
"channel-mode": "HE",
|
||||
"channel-width": 80,
|
||||
"channel": 36
|
||||
}, {
|
||||
"band": "6G",
|
||||
"country": "US",
|
||||
"channel-mode": "HE",
|
||||
"channel-width": 80,
|
||||
"channel": 33
|
||||
}
|
||||
],
|
||||
|
||||
"interfaces": [
|
||||
{
|
||||
"name": "WAN",
|
||||
"role": "upstream",
|
||||
"services": [ "lldp" ],
|
||||
"ethernet": [
|
||||
{
|
||||
"select-ports": [
|
||||
"WAN*"
|
||||
]
|
||||
}
|
||||
],
|
||||
"ipv4": {
|
||||
"addressing": "dynamic"
|
||||
},
|
||||
"ssids": [
|
||||
{
|
||||
"name": "OpenWifi-roam",
|
||||
"wifi-bands": [
|
||||
"2G", "5G"
|
||||
],
|
||||
"bss-mode": "ap",
|
||||
"encryption": {
|
||||
"proto": "psk2",
|
||||
"key": "OpenWifi",
|
||||
"ieee80211w": "optional"
|
||||
},
|
||||
"rrm": {
|
||||
"reduced-neighbor-reporting": true
|
||||
},
|
||||
"multi-psk": [
|
||||
{
|
||||
"key": "aaaaaaaa"
|
||||
}, {
|
||||
"key": "bbbbbbbb"
|
||||
}
|
||||
],
|
||||
"roaming": true
|
||||
}, {
|
||||
"name": "OpenWifi-roam",
|
||||
"wifi-bands": [
|
||||
"6G"
|
||||
],
|
||||
"bss-mode": "ap",
|
||||
"encryption": {
|
||||
"proto": "sae",
|
||||
"key": "OpenWifi",
|
||||
"ieee80211w": "required"
|
||||
},
|
||||
"rrm": {
|
||||
"reduced-neighbor-reporting": true
|
||||
},
|
||||
"roaming": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "LAN",
|
||||
"role": "downstream",
|
||||
"services": [ "ssh", "lldp" ],
|
||||
"ethernet": [
|
||||
{
|
||||
"select-ports": [
|
||||
"LAN*"
|
||||
]
|
||||
}
|
||||
],
|
||||
"ipv4": {
|
||||
"addressing": "static",
|
||||
"subnet": "192.168.1.1/24",
|
||||
"dhcp": {
|
||||
"lease-first": 10,
|
||||
"lease-count": 100,
|
||||
"lease-time": "6h"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"metrics": {
|
||||
"statistics": {
|
||||
"interval": 120,
|
||||
"types": [ "ssids", "lldp", "clients" ]
|
||||
},
|
||||
"health": {
|
||||
"interval": 120
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"lldp": {
|
||||
"describe": "uCentral",
|
||||
"location": "universe"
|
||||
},
|
||||
"ssh": {
|
||||
"port": 22
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user