From 3b71bdde66e29a71f077c113abf57baefad90edf Mon Sep 17 00:00:00 2001 From: Yuvarani V Date: Fri, 8 Dec 2023 15:49:12 +0530 Subject: [PATCH] hostapd: Parse attribute to update critical params Parse NL80211_ATTR_MLD_CRITICAL_UPDATE attribute to update critical params on hostapd_data. Signed-off-by: Rathees Kumar R Chinannan Signed-off-by: Yuvarani V --- src/drivers/driver_nl80211_event.c | 111 +++++++++++++++++++++++++++-- src/drivers/nl80211_copy.h | 74 ++++++++++++++++++- 2 files changed, 180 insertions(+), 5 deletions(-) diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c index 56cd951..83dedd8 100644 --- a/src/drivers/driver_nl80211_event.c +++ b/src/drivers/driver_nl80211_event.c @@ -1344,9 +1344,107 @@ static void mlme_timeout_event(struct wpa_driver_nl80211_data *drv, } +static void +mlme_event_mgmt_critical_update(struct i802_bss *bss, struct nlattr *rx_cu_param) +{ + struct nlattr *cu[NL80211_CU_ATTR_MAX + 1]; + struct nlattr *mld_list; + struct nlattr *mld[NL80211_CU_MLD_ATTR_MAX + 1]; + struct nlattr *link_list; + struct nlattr *link[NL80211_CU_MLD_LINK_ATTR_MAX + 1]; + struct wpa_driver_nl80211_data *drv = bss->drv; + struct i802_bss *link_bss, *tmp_bss; + union wpa_event_data event; + int rem, limit; + int ifidx = -1, mlo_link_id; + + static struct nla_policy + link_policy[NL80211_CU_MLD_LINK_ATTR_MAX + 1] = { + [NL80211_CU_MLD_LINK_ATTR_ID] = { .type = NLA_U8 }, + [NL80211_CU_MLD_LINK_ATTR_CRITICAL_FLAG] = { .type = NLA_FLAG }, + [NL80211_CU_MLD_LINK_ATTR_BPCC] = { .type = NLA_U8 }, + [NL80211_CU_MLD_LINK_ATTR_SWITCH_COUNT] = { .type = NLA_U8 }, + }; + static struct nla_policy + mld_policy[NL80211_CU_MLD_ATTR_MAX + 1] = { + [NL80211_CU_MLD_ATTR_IFINDEX] = { .type = NLA_U32 }, + [NL80211_CU_MLD_ATTR_LINK_LIST] = { .type = NLA_NESTED }, + }; + static struct nla_policy + cu_policy[NL80211_CU_ATTR_MAX + 1] = { + [NL80211_CU_ATTR_MLD_LIST] = { .type = NLA_NESTED }, + }; + + if (!rx_cu_param) + return; + nla_parse_nested(cu, NL80211_CU_ATTR_MAX, rx_cu_param, cu_policy); + + nla_for_each_nested(mld_list, cu[NL80211_CU_ATTR_MLD_LIST], rem) { + if (nla_parse_nested(mld, NL80211_CU_MLD_ATTR_MAX, + mld_list, mld_policy)) { + return; + } + tmp_bss = NULL; + ifidx = -1; + if (mld[NL80211_CU_MLD_ATTR_IFINDEX]) { + ifidx = nla_get_u32( + mld[NL80211_CU_MLD_ATTR_IFINDEX]); + tmp_bss = get_bss_ifindex(drv, ifidx); + if (tmp_bss == NULL) { + wpa_printf(MSG_WARNING, + "nl80211: Unknown ifindex (%d) for critical update", + ifidx); + return; + } + } + if (tmp_bss && mld[NL80211_CU_MLD_ATTR_LINK_LIST]) { + nla_for_each_nested(link_list, + mld[NL80211_CU_MLD_ATTR_LINK_LIST], + limit) { + if (nla_parse_nested(link, + NL80211_CU_MLD_LINK_ATTR_MAX, + link_list, link_policy)) { + return; + } + os_memset(&event, 0, sizeof(event)); + mlo_link_id = -1; + if (link[NL80211_CU_MLD_LINK_ATTR_ID]) { + mlo_link_id = + nla_get_u8(link[NL80211_CU_MLD_LINK_ATTR_ID]); + link_bss = get_link_bss_ifindex(tmp_bss, + ifidx, mlo_link_id); + if (link_bss == NULL) { + wpa_printf(MSG_WARNING, + "nl80211: Unknown link_id (%d) for critical update", + mlo_link_id); + return; + } + event.cu_event.link_ctx = link_bss->ctx; + + if (link[NL80211_CU_MLD_LINK_ATTR_CRITICAL_FLAG]) { + event.cu_event.critical_flag = + nla_get_flag(link[NL80211_CU_MLD_LINK_ATTR_CRITICAL_FLAG]); + } + if (link[NL80211_CU_MLD_LINK_ATTR_BPCC]) { + event.cu_event.bpcc = + nla_get_u8(link[NL80211_CU_MLD_LINK_ATTR_BPCC]); + } + if (link[NL80211_CU_MLD_LINK_ATTR_SWITCH_COUNT]) { + event.cu_event.switch_count = + nla_get_u8(link[NL80211_CU_MLD_LINK_ATTR_SWITCH_COUNT]); + } + wpa_supplicant_event(drv->ctx, + EVENT_RX_CRITICAL_UPDATE, &event); + } + } + } + } +} + + static void mlme_event_mgmt(struct i802_bss *bss, struct nlattr *freq, struct nlattr *sig, - const u8 *frame, size_t len, + const u8 *frame, size_t len, struct nlattr *rx_cu_param, int link_id) { struct wpa_driver_nl80211_data *drv = bss->drv; @@ -1385,6 +1483,10 @@ static void mlme_event_mgmt(struct i802_bss *bss, event.rx_mgmt.frame_len = len; event.rx_mgmt.ssi_signal = ssi_signal; event.rx_mgmt.drv_priv = bss; + if (rx_cu_param && ((stype == WLAN_FC_STYPE_PROBE_REQ) || (stype == WLAN_FC_STYPE_ASSOC_REQ) + || (stype == WLAN_FC_STYPE_REASSOC_REQ))) + mlme_event_mgmt_critical_update(bss, rx_cu_param); + event.rx_mgmt.ctx = bss->ctx; event.rx_mgmt.link_id = link_id; @@ -1682,7 +1784,7 @@ static void mlme_event(struct i802_bss *bss, struct nlattr *freq, struct nlattr *ack, struct nlattr *cookie, struct nlattr *sig, struct nlattr *wmm, struct nlattr *req_ie, - struct nlattr *link) + struct nlattr *rx_cu_param, struct nlattr *link) { struct wpa_driver_nl80211_data *drv = bss->drv; u16 stype = 0, auth_type = 0; @@ -1782,7 +1884,7 @@ static void mlme_event(struct i802_bss *bss, break; case NL80211_CMD_FRAME: mlme_event_mgmt(bss, freq, sig, nla_data(frame), - nla_len(frame), link_id); + nla_len(frame), rx_cu_param, link_id); break; case NL80211_CMD_FRAME_TX_STATUS: mlme_event_mgmt_tx_status(bss, cookie, nla_data(frame), @@ -4180,7 +4282,7 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd, tb[NL80211_ATTR_COOKIE], tb[NL80211_ATTR_RX_SIGNAL_DBM], tb[NL80211_ATTR_STA_WME], - tb[NL80211_ATTR_REQ_IE], + tb[NL80211_ATTR_REQ_IE], NULL, tb[NL80211_ATTR_MLO_LINK_ID]); break; case NL80211_CMD_CONNECT: @@ -4426,6 +4528,7 @@ int process_bss_event(struct nl_msg *msg, void *arg) tb[NL80211_ATTR_COOKIE], tb[NL80211_ATTR_RX_SIGNAL_DBM], tb[NL80211_ATTR_STA_WME], NULL, + tb[NL80211_ATTR_RXMGMT_CRITICAL_UPDATE], tb[NL80211_ATTR_MLO_LINK_ID]); break; case NL80211_CMD_UNEXPECTED_FRAME: diff --git a/src/drivers/nl80211_copy.h b/src/drivers/nl80211_copy.h index 0f281dd..def4335 100644 --- a/src/drivers/nl80211_copy.h +++ b/src/drivers/nl80211_copy.h @@ -2812,7 +2812,7 @@ enum nl80211_commands { * @NL80211_ATTR_TD_BITMAP: Transition Disable bitmap, for subsequent * (re)associations. * - * @NL80211_ATTR_PUNCT_BITMAP: (u32) Preamble puncturing bitmap, lowest + *src/drivers/nl80211_copy.h @NL80211_ATTR_PUNCT_BITMAP: (u32) Preamble puncturing bitmap, lowest * bit corresponds to the lowest 20 MHz channel. Each bit set to 1 * indicates that the sub-channel is punctured. Higher 16 bits are * reserved. @@ -2870,6 +2870,9 @@ enum nl80211_commands { * corresponds to the lowest 20MHZ channel. Each bit set to 1 * indicates that radar is detected in that sub-channel. * + * @NL80211_ATTR_RXMGMT_CRITICAL_UPDATE: Nested attribute listing the critical + * update for each MLD. In each nested item, it contains attributes + * defined in &enum nl80211_cu_attrs. * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined @@ -3428,6 +3431,11 @@ enum nl80211_attrs { NL80211_ATTR_AP_PS, NL80211_ATTR_MULTI_HW_MACS, NL80211_ATTR_RADAR_BITMAP, + NL80211_ATTR_EHT_240MHZ_CAPABILITY, + NL80211_ATTR_ADD_MULTI_CHAN, + NL80211_ATTR_DEL_MULTI_CHAN, + NL80211_ATTR_RXMGMT_CRITICAL_UPDATE, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -8119,4 +8127,68 @@ enum nl80211_multi_hw_mac_chan_list_attrs { NL80211_MULTI_HW_MAC_CHAN_LIST_ATTR_MAX = __NL80211_MULTI_HW_MAC_CHAN_LIST_ATTR_LAST - 1 }; + +/** + * nl80211_cu_attrs - critical update attributes + * + * @__NL80211_CU_ATTR_INVALID: invalid + * @NL80211_CU_ATTR_MLD_LIST: nested attribute specifying list of mld, + * see &enum nl80211_mld_list_cu_attrs + * @__NL80211_CU_ATTR_LAST: internal use + * @NL80211_CU_ATTR_MAX: maximum critical update attribute + */ +enum nl80211_cu_attrs { + __NL80211_CU_ATTR_INVALID, + + NL80211_CU_ATTR_MLD_LIST, + + /* keep last */ + __NL80211_CU_ATTR_LAST, + NL80211_CU_ATTR_MAX = __NL80211_CU_ATTR_LAST - 1 +}; + +/** + * nl80211_cu_mld_attrs - per mld critical update attributes + * + * @__NL80211_CU_MLD_ATTR_INVALID: invalid + * @NL80211_CU_MLD_ATTR_IFINDEX: network interface index of the device to operate on + * @NL80211_CU_MLD_ATTR_LINK_LIST: nested attribute specifying list of links + * on each mld, see &enum nl80211_cu_mld_link_attrs + * @__NL80211_CU_MLD_ATTR_LAST: internal use + * @NL80211_CU_MLD_ATTR_MAX: maximum per mld critical update attribute + */ +enum nl80211_cu_mld_attrs { + __NL80211_CU_MLD_ATTR_INVALID, + + NL80211_CU_MLD_ATTR_IFINDEX, + NL80211_CU_MLD_ATTR_LINK_LIST, + + /* keep last */ + __NL80211_CU_MLD_ATTR_LAST, + NL80211_CU_MLD_ATTR_MAX = __NL80211_CU_MLD_ATTR_LAST - 1 +}; + +/** + * nl80211_cu_mld_link_attrs - per link critical update attributes + * + * @__NL80211_CU_MLD_LINK_ATTR_INVALID: invalid + * @NL80211_CU_MLD_LINK_ATTR_ID: Link Id + * @NL80211_CU_MLD_LINK_ATTR_CRITICAL_FLAG: critical flag value + * @NL80211_CU_MLD_LINK_ATTR_BPCC: BSS parameter change count value + * @NL80211_CU_MLD_LINK_ATTR_SWITCH_COUNT: CSA/CCA switch count + * @__NL80211_CU_MLD_LINK_ATTR_LAST: internal use + * @NL80211_CU_MLD_LINK ATTR_MAX: maximum per link critical update attribute + */ +enum nl80211_cu_mld_link_attrs { + __NL80211_CU_MLD_LINK_ATTR_INVALID, + + NL80211_CU_MLD_LINK_ATTR_ID, + NL80211_CU_MLD_LINK_ATTR_CRITICAL_FLAG, + NL80211_CU_MLD_LINK_ATTR_BPCC, + NL80211_CU_MLD_LINK_ATTR_SWITCH_COUNT, + + /* keep last */ + __NL80211_CU_MLD_LINK_ATTR_LAST, + NL80211_CU_MLD_LINK_ATTR_MAX = __NL80211_CU_MLD_LINK_ATTR_LAST - 1 +}; #endif /* __LINUX_NL80211_H */ -- 2.17.1