[PATCH 01/50] nl80211: Refactor i802_bss to support multiple links
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Wed Feb 15 15:08:15 PST 2023
From: Ilan Peer <ilan.peer at intel.com>
Refactor struct i802_bss to support multiple links as a
preparation to support MLD AP.
Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
src/drivers/driver_nl80211.c | 78 +++++++++++++++++++-----------
src/drivers/driver_nl80211.h | 20 ++++++--
src/drivers/driver_nl80211_event.c | 8 +--
3 files changed, 71 insertions(+), 35 deletions(-)
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 3f6c05c094..a3b4ab8ea4 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -273,7 +273,7 @@ void nl80211_mark_disconnected(struct wpa_driver_nl80211_data *drv)
drv->associated = 0;
os_memset(&drv->sta_mlo_info, 0, sizeof(drv->sta_mlo_info));
os_memset(drv->bssid, 0, ETH_ALEN);
- drv->first_bss->freq = 0;
+ drv->first_bss->flink->freq = 0;
#ifdef CONFIG_DRIVER_NL80211_QCA
os_free(drv->pending_roam_data);
drv->pending_roam_data = NULL;
@@ -911,7 +911,7 @@ nl80211_get_wiphy_data_ap(struct i802_bss *bss)
dl_list_init(&w->drvs);
/* Beacon frames not supported in IEEE 802.11ad */
- if (ieee80211_freq_to_chan(bss->freq, &channel) !=
+ if (ieee80211_freq_to_chan(bss->flink->freq, &channel) !=
HOSTAPD_MODE_IEEE80211AD) {
w->nl_cb = nl_cb_alloc(NL_CB_DEFAULT);
if (!w->nl_cb) {
@@ -2230,6 +2230,7 @@ static void * wpa_driver_nl80211_drv_init(void *ctx, const char *ifname,
{
struct wpa_driver_nl80211_data *drv;
struct i802_bss *bss;
+ u32 i;
if (global_priv == NULL)
return NULL;
@@ -2308,6 +2309,17 @@ skip_wifi_status:
drv->in_interface_list = 1;
}
+ /*
+ * Set the default link to be the first one, and set its address to that
+ * of the interface
+ */
+ bss->flink = &bss->links[0];
+ bss->n_links = 1;
+ os_memcpy(bss->flink->addr, bss->addr, ETH_ALEN);
+
+ for (i = 0; i < MAX_NUM_MLD_LINKS; i++)
+ bss->links[i].link_id = NL80211_DRV_LINK_ID_NA;
+
return bss;
failed:
@@ -2982,8 +2994,8 @@ static int wpa_driver_nl80211_del_beacon(struct i802_bss *bss)
wpa_printf(MSG_DEBUG, "nl80211: Remove beacon (ifindex=%d)",
drv->ifindex);
- bss->beacon_set = 0;
- bss->freq = 0;
+ bss->flink->beacon_set = 0;
+ bss->flink->freq = 0;
nl80211_put_wiphy_data_ap(bss);
msg = nl80211_drv_msg(drv, 0, NL80211_CMD_DEL_BEACON);
return send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
@@ -4109,10 +4121,10 @@ static int wpa_driver_nl80211_send_mlme(struct i802_bss *bss, const u8 *data,
if (drv->device_ap_sme && is_ap_interface(drv->nlmode)) {
if (freq == 0) {
wpa_printf(MSG_DEBUG, "nl80211: Use bss->freq=%d",
- bss->freq);
- freq = bss->freq;
+ bss->flink->freq);
+ freq = bss->flink->freq;
}
- if ((int) freq == bss->freq)
+ if ((int)freq == bss->flink->freq)
wait_time = 0;
goto send_frame_cmd;
}
@@ -4174,14 +4186,14 @@ static int wpa_driver_nl80211_send_mlme(struct i802_bss *bss, const u8 *data,
}
if (freq == 0) {
wpa_printf(MSG_DEBUG, "nl80211: send_mlme - Use bss->freq=%u",
- bss->freq);
- freq = bss->freq;
+ bss->flink->freq);
+ freq = bss->flink->freq;
}
if (drv->use_monitor && is_ap_interface(drv->nlmode)) {
wpa_printf(MSG_DEBUG,
"nl80211: send_frame(freq=%u bss->freq=%u) -> send_monitor",
- freq, bss->freq);
+ freq, bss->flink->freq);
return nl80211_send_monitor(drv, data, data_len, encrypt,
noack);
}
@@ -4694,7 +4706,7 @@ static int wpa_driver_nl80211_set_ap(void *priv,
struct wpa_driver_mesh_bss_params mesh_params;
#endif /* CONFIG_MESH */
- beacon_set = params->reenable ? 0 : bss->beacon_set;
+ beacon_set = params->reenable ? 0 : bss->flink->beacon_set;
wpa_printf(MSG_DEBUG, "nl80211: Set beacon (beacon_set=%d)",
beacon_set);
@@ -4994,17 +5006,17 @@ static int wpa_driver_nl80211_set_ap(void *priv,
wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)",
ret, strerror(-ret));
} else {
- bss->beacon_set = 1;
+ bss->flink->beacon_set = 1;
nl80211_set_bss(bss, params->cts_protect, params->preamble,
params->short_slot_time, params->ht_opmode,
params->isolate, params->basic_rates);
nl80211_set_multicast_to_unicast(bss,
params->multicast_to_unicast);
if (beacon_set && params->freq &&
- params->freq->bandwidth != bss->bandwidth) {
+ params->freq->bandwidth != bss->flink->bandwidth) {
wpa_printf(MSG_DEBUG,
"nl80211: Update BSS %s bandwidth: %d -> %d",
- bss->ifname, bss->bandwidth,
+ bss->ifname, bss->flink->bandwidth,
params->freq->bandwidth);
ret = nl80211_set_channel(bss, params->freq, 1);
if (ret) {
@@ -5014,7 +5026,7 @@ static int wpa_driver_nl80211_set_ap(void *priv,
} else {
wpa_printf(MSG_DEBUG,
"nl80211: Frequency set succeeded for ht2040 coex");
- bss->bandwidth = params->freq->bandwidth;
+ bss->flink->bandwidth = params->freq->bandwidth;
}
} else if (!beacon_set && params->freq) {
/*
@@ -5022,7 +5034,7 @@ static int wpa_driver_nl80211_set_ap(void *priv,
* mode only at the point when beaconing is started, so
* set the initial value here.
*/
- bss->bandwidth = params->freq->bandwidth;
+ bss->flink->bandwidth = params->freq->bandwidth;
}
}
@@ -5172,7 +5184,7 @@ static int nl80211_set_channel(struct i802_bss *bss,
ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
if (ret == 0) {
- bss->freq = freq->freq;
+ bss->flink->freq = freq->freq;
return 0;
}
wpa_printf(MSG_DEBUG, "nl80211: Failed to set channel (freq=%d): "
@@ -5800,7 +5812,7 @@ static void nl80211_teardown_ap(struct i802_bss *bss)
nl80211_mgmt_unsubscribe(bss, "AP teardown");
nl80211_put_wiphy_data_ap(bss);
- bss->beacon_set = 0;
+ bss->flink->beacon_set = 0;
}
@@ -7738,7 +7750,7 @@ static int i802_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
struct ieee80211_mgmt mgmt;
u8 channel;
- if (ieee80211_freq_to_chan(bss->freq, &channel) ==
+ if (ieee80211_freq_to_chan(bss->flink->freq, &channel) ==
HOSTAPD_MODE_IEEE80211AD) {
/* Deauthentication is not used in DMG/IEEE 802.11ad;
* disassociate the STA instead. */
@@ -8359,12 +8371,18 @@ static int wpa_driver_nl80211_if_add(void *priv, enum wpa_driver_if_type type,
if (type == WPA_IF_AP_BSS && setup_ap) {
struct i802_bss *new_bss = os_zalloc(sizeof(*new_bss));
+ size_t i;
+
if (new_bss == NULL) {
if (added)
nl80211_remove_iface(drv, ifidx);
return -1;
}
+ /* Initialize here before any failure path */
+ for (i = 0; i < MAX_NUM_MLD_LINKS; i++)
+ new_bss->links[i].link_id = NL80211_DRV_LINK_ID_NA;
+
if (bridge &&
i802_check_bridge(drv, new_bss, bridge, ifname) < 0) {
wpa_printf(MSG_ERROR, "nl80211: Failed to add the new "
@@ -8388,7 +8406,11 @@ static int wpa_driver_nl80211_if_add(void *priv, enum wpa_driver_if_type type,
new_bss->ifindex = ifidx;
new_bss->drv = drv;
new_bss->next = drv->first_bss->next;
- new_bss->freq = drv->first_bss->freq;
+ new_bss->flink = &new_bss->links[0];
+ new_bss->n_links = 1;
+ os_memcpy(new_bss->flink->addr, new_bss->addr, ETH_ALEN);
+
+ new_bss->flink->freq = drv->first_bss->flink->freq;
new_bss->ctx = bss_ctx;
new_bss->added_if = added;
drv->first_bss->next = new_bss;
@@ -8595,8 +8617,8 @@ static int wpa_driver_nl80211_send_action(struct i802_bss *bss,
struct ieee80211_hdr *hdr;
int offchanok = 1;
- if (is_ap_interface(drv->nlmode) && (int) freq == bss->freq &&
- bss->beacon_set)
+ if (is_ap_interface(drv->nlmode) && (int)freq == bss->flink->freq &&
+ bss->flink->beacon_set)
offchanok = 0;
wpa_printf(MSG_DEBUG, "nl80211: Send Action frame (ifindex=%d, "
@@ -8632,7 +8654,7 @@ static int wpa_driver_nl80211_send_action(struct i802_bss *bss,
modes = nl80211_get_hw_feature_data(bss, &num_modes,
&flags, &dfs_domain);
if (dfs_domain != HOSTAPD_DFS_REGION_ETSI &&
- ieee80211_is_dfs(bss->freq, modes, num_modes))
+ ieee80211_is_dfs(bss->flink->freq, modes, num_modes))
offchanok = 0;
if (modes) {
for (i = 0; i < num_modes; i++) {
@@ -8646,7 +8668,7 @@ static int wpa_driver_nl80211_send_action(struct i802_bss *bss,
if (is_ap_interface(drv->nlmode) &&
(!(drv->capa.flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) ||
- (int) freq == bss->freq || drv->device_ap_sme ||
+ (int)freq == bss->flink->freq || drv->device_ap_sme ||
!drv->use_monitor))
ret = wpa_driver_nl80211_send_mlme(bss, buf, 24 + data_len,
0, freq, no_cck, offchanok,
@@ -10203,8 +10225,8 @@ static int wpa_driver_nl80211_status(void *priv, char *buf, size_t buflen)
bss->ifname,
bss->brname,
MAC2STR(bss->addr),
- bss->freq,
- bss->beacon_set ? "beacon_set=1\n" : "",
+ bss->flink->freq,
+ bss->flink->beacon_set ? "beacon_set=1\n" : "",
bss->added_if_into_bridge ?
"added_if_into_bridge=1\n" : "",
bss->already_in_bridge ? "already_in_bridge=1\n" : "",
@@ -11265,7 +11287,7 @@ static int nl80211_join_mesh(struct i802_bss *bss,
goto fail;
}
ret = 0;
- drv->assoc_freq = bss->freq = params->freq.freq;
+ drv->assoc_freq = bss->flink->freq = params->freq.freq;
wpa_printf(MSG_DEBUG, "nl80211: mesh join request send successfully");
fail:
@@ -11321,7 +11343,7 @@ static int wpa_driver_nl80211_leave_mesh(void *priv)
} else {
wpa_printf(MSG_DEBUG,
"nl80211: mesh leave request send successfully");
- drv->first_bss->freq = 0;
+ drv->first_bss->flink->freq = 0;
}
if (drv->start_mode_sta &&
diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
index a6cb14c5ac..45fa36a6ff 100644
--- a/src/drivers/driver_nl80211.h
+++ b/src/drivers/driver_nl80211.h
@@ -49,15 +49,31 @@ struct nl80211_wiphy_data {
int wiphy_idx;
};
+#define NL80211_DRV_LINK_ID_NA (-1)
+
+struct i802_link {
+ unsigned int beacon_set:1;
+
+ s8 link_id;
+ int freq;
+ int bandwidth;
+ u8 addr[ETH_ALEN];
+ void *ctx;
+};
+
struct i802_bss {
struct wpa_driver_nl80211_data *drv;
struct i802_bss *next;
+
+ size_t n_links;
+ struct i802_link links[MAX_NUM_MLD_LINKS];
+ struct i802_link *flink;
+
int ifindex;
int br_ifindex;
u64 wdev_id;
char ifname[IFNAMSIZ + 1];
char brname[IFNAMSIZ];
- unsigned int beacon_set:1;
unsigned int added_if_into_bridge:1;
unsigned int already_in_bridge:1;
unsigned int added_bridge:1;
@@ -70,8 +86,6 @@ struct i802_bss {
u8 addr[ETH_ALEN];
u8 prev_addr[ETH_ALEN];
- int freq;
- int bandwidth;
int if_dynamic;
void *ctx;
diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c
index 29613161b9..3469db1c7e 100644
--- a/src/drivers/driver_nl80211_event.c
+++ b/src/drivers/driver_nl80211_event.c
@@ -327,7 +327,7 @@ static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
}
event.assoc_info.freq = drv->assoc_freq;
- drv->first_bss->freq = drv->assoc_freq;
+ drv->first_bss->flink->freq = drv->assoc_freq;
nl80211_parse_wmm_params(wmm, &event.assoc_info.wmm_params);
@@ -852,7 +852,7 @@ static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
}
event.assoc_info.freq = nl80211_get_assoc_freq(drv);
- drv->first_bss->freq = drv->assoc_freq;
+ drv->first_bss->flink->freq = drv->assoc_freq;
if ((!ssid || ssid[1] == 0 || ssid[1] > 32) &&
(ssid_len = nl80211_get_assoc_ssid(drv, drv->ssid)) > 0) {
@@ -1057,7 +1057,7 @@ static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv,
data.ch_switch.cf2 = nla_get_u32(cf2);
if (finished)
- bss->freq = data.ch_switch.freq;
+ bss->flink->freq = data.ch_switch.freq;
if (link) {
u8 link_id = nla_get_u8(link);
@@ -1569,7 +1569,7 @@ static void mlme_event_join_ibss(struct wpa_driver_nl80211_data *drv,
if (freq) {
wpa_printf(MSG_DEBUG, "nl80211: IBSS on frequency %u MHz",
freq);
- drv->first_bss->freq = freq;
+ drv->first_bss->flink->freq = freq;
}
os_memset(&event, 0, sizeof(event));
--
2.38.1
More information about the Hostap
mailing list