From b3aafd5a8713ec26b86e9b93986b6ceaba734c3a Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Tue, 21 Nov 2023 01:51:18 +0200 Subject: [PATCH] common: Simplify and avoid confusing defragmentation API Three functions were provided for defragmentation. First ieee802_11_defrag(), ieee802_11_defrag_mle() and then ieee802_11_defrag_data() which would do the actual job. With ieee802_11_defrag() picking the member in the elements struct for an EID. The problem with this is, that for the Multi-Link element, there are multiple entries in the elems struct depending on its type. As such, remove the intermediate function and simply pass the correct members directly. Signed-off-by: Benjamin Berg Signed-off-by: Andrei Otcheretianski --- src/ap/drv_callbacks.c | 2 +- src/ap/ieee802_11.c | 10 ++-- src/ap/ieee802_11_eht.c | 2 +- src/common/ieee802_11_common.c | 78 +----------------------------- src/common/ieee802_11_common.h | 6 +-- src/common/wpa_common.c | 3 +- src/drivers/driver_nl80211_event.c | 6 ++- src/pasn/pasn_initiator.c | 10 ++-- src/pasn/pasn_responder.c | 11 ++--- wlantest/rx_mgmt.c | 2 +- wpa_supplicant/bss.c | 22 +-------- wpa_supplicant/bss.h | 1 - wpa_supplicant/sme.c | 7 ++- 13 files changed, 33 insertions(+), 127 deletions(-) diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c index 7c79f0672..a1ee1bb70 100644 --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -158,7 +158,7 @@ static int hostapd_update_sta_links_status(struct hostapd_data *hapd, return -1; } - mlebuf = ieee802_11_defrag_mle(&elems, MULTI_LINK_CONTROL_TYPE_BASIC); + mlebuf = ieee802_11_defrag(elems.basic_mle, elems.basic_mle_len, true); if (!mlebuf) { wpa_printf(MSG_ERROR, "MLO: Basic Multi-Link element not found in (Re)Association Response frame"); diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 1f39107d8..30edc5bfc 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -2520,8 +2520,8 @@ static int pasn_wd_handle_fils(struct hostapd_data *hapd, struct sta_info *sta, FILS_SESSION_LEN); os_memcpy(fils->session, elems.fils_session, FILS_SESSION_LEN); - fils_wd = ieee802_11_defrag(&elems, WLAN_EID_EXTENSION, - WLAN_EID_EXT_WRAPPED_DATA); + fils_wd = ieee802_11_defrag(elems.wrapped_data, elems.wrapped_data_len, + true); if (!fils_wd) { wpa_printf(MSG_DEBUG, "PASN: FILS: Missing wrapped data"); @@ -2690,8 +2690,8 @@ static void hapd_pasn_update_params(struct hostapd_data *hapd, return; } if (pasn_params.wrapped_data_format != WPA_PASN_WRAPPED_DATA_NO) { - wrapped_data = ieee802_11_defrag(&elems, WLAN_EID_EXTENSION, - WLAN_EID_EXT_WRAPPED_DATA); + wrapped_data = ieee802_11_defrag(elems.wrapped_data, + elems.wrapped_data_len, true); if (!wrapped_data) { wpa_printf(MSG_DEBUG, "PASN: Missing wrapped data"); return; @@ -4401,7 +4401,7 @@ static void ieee80211_ml_process_link(struct hostapd_data *hapd, goto out; } - mlbuf = ieee802_11_defrag_mle(&elems, MULTI_LINK_CONTROL_TYPE_BASIC); + mlbuf = ieee802_11_defrag(elems.basic_mle, elems.basic_mle_len, true); if (!mlbuf) goto out; diff --git a/src/ap/ieee802_11_eht.c b/src/ap/ieee802_11_eht.c index 565268287..d3c1f20f4 100644 --- a/src/ap/ieee802_11_eht.c +++ b/src/ap/ieee802_11_eht.c @@ -919,7 +919,7 @@ u16 hostapd_process_ml_assoc_req(struct hostapd_data *hapd, int ret = -1; u16 ml_control; - mlbuf = ieee802_11_defrag_mle(elems, MULTI_LINK_CONTROL_TYPE_BASIC); + mlbuf = ieee802_11_defrag(elems->basic_mle, elems->basic_mle_len, true); if (!mlbuf) return WLAN_STATUS_SUCCESS; diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c index 70d56ffbf..37a300ea4 100644 --- a/src/common/ieee802_11_common.c +++ b/src/common/ieee802_11_common.c @@ -3201,8 +3201,7 @@ enum oper_chan_width op_class_to_ch_width(u8 op_class) } -struct wpabuf * ieee802_11_defrag_data(const u8 *data, size_t len, - bool ext_elem) +struct wpabuf * ieee802_11_defrag(const u8 *data, size_t len, bool ext_elem) { struct wpabuf *buf; const u8 *pos, *end = data + len; @@ -3242,44 +3241,6 @@ struct wpabuf * ieee802_11_defrag_data(const u8 *data, size_t len, } -struct wpabuf * ieee802_11_defrag(struct ieee802_11_elems *elems, - u8 eid, u8 eid_ext) -{ - const u8 *data; - size_t len; - - /* - * TODO: Defragmentation mechanism can be supported for all IEs. For now - * handle only those that are used (or use ieee802_11_defrag_data()). - */ - switch (eid) { - case WLAN_EID_EXTENSION: - switch (eid_ext) { - case WLAN_EID_EXT_FILS_HLP_CONTAINER: - data = elems->fils_hlp; - len = elems->fils_hlp_len; - break; - case WLAN_EID_EXT_WRAPPED_DATA: - data = elems->wrapped_data; - len = elems->wrapped_data_len; - break; - default: - wpa_printf(MSG_DEBUG, - "Defragmentation not supported. eid_ext=%u", - eid_ext); - return NULL; - } - break; - default: - wpa_printf(MSG_DEBUG, - "Defragmentation not supported. eid=%u", eid); - return NULL; - } - - return ieee802_11_defrag_data(data, len, true); -} - - const u8 * get_ml_ie(const u8 *ies, size_t len, u8 type) { const struct element *elem; @@ -3314,40 +3275,3 @@ const u8 * get_basic_mle_mld_addr(const u8 *buf, size_t len) return &buf[mld_addr_pos]; } - - -struct wpabuf * ieee802_11_defrag_mle(struct ieee802_11_elems *elems, u8 type) -{ - const u8 *data; - size_t len; - - switch (type) { - case MULTI_LINK_CONTROL_TYPE_BASIC: - data = elems->basic_mle; - len = elems->basic_mle_len; - break; - case MULTI_LINK_CONTROL_TYPE_PROBE_REQ: - data = elems->probe_req_mle; - len = elems->probe_req_mle_len; - break; - case MULTI_LINK_CONTROL_TYPE_RECONF: - data = elems->reconf_mle; - len = elems->reconf_mle_len; - break; - case MULTI_LINK_CONTROL_TYPE_TDLS: - data = elems->tdls_mle; - len = elems->tdls_mle_len; - break; - case MULTI_LINK_CONTROL_TYPE_PRIOR_ACCESS: - data = elems->prior_access_mle; - len = elems->prior_access_mle_len; - break; - default: - wpa_printf(MSG_DEBUG, - "Defragmentation not supported for Multi-Link element type=%u", - type); - return NULL; - } - - return ieee802_11_defrag_data(data, len, true); -} diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h index 00dc2fb10..a8a2118b1 100644 --- a/src/common/ieee802_11_common.h +++ b/src/common/ieee802_11_common.h @@ -350,11 +350,7 @@ void hostapd_encode_edmg_chan(int edmg_enable, u8 edmg_channel, int ieee802_edmg_is_allowed(struct ieee80211_edmg_config allowed, struct ieee80211_edmg_config requested); -struct wpabuf * ieee802_11_defrag_data(const u8 *data, size_t len, - bool ext_elem); -struct wpabuf * ieee802_11_defrag(struct ieee802_11_elems *elems, - u8 eid, u8 eid_ext); -struct wpabuf * ieee802_11_defrag_mle(struct ieee802_11_elems *elems, u8 type); +struct wpabuf * ieee802_11_defrag(const u8 *data, size_t len, bool ext_elem); const u8 * get_ml_ie(const u8 *ies, size_t len, u8 type); const u8 * get_basic_mle_mld_addr(const u8 *buf, size_t len); diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c index d897e0eca..e4930a291 100644 --- a/src/common/wpa_common.c +++ b/src/common/wpa_common.c @@ -1329,8 +1329,7 @@ int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse, if (fte_len < 255) { res = wpa_ft_parse_fte(key_mgmt, fte, fte_len, parse); } else { - parse->fte_buf = ieee802_11_defrag_data(fte, fte_len, - false); + parse->fte_buf = ieee802_11_defrag(fte, fte_len, false); if (!parse->fte_buf) goto fail; res = wpa_ft_parse_fte(key_mgmt, diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c index 4f477ea5a..3e67fe569 100644 --- a/src/drivers/driver_nl80211_event.c +++ b/src/drivers/driver_nl80211_event.c @@ -660,7 +660,8 @@ static int nl80211_update_rejected_links_info(struct driver_sta_mlo_info *mlo, return -1; } - mle = ieee802_11_defrag_mle(&req_elems, MULTI_LINK_CONTROL_TYPE_BASIC); + mle = ieee802_11_defrag(req_elems.basic_mle, req_elems.basic_mle_len, + true); if (!mle) { wpa_printf(MSG_INFO, "nl80211: MLO: Basic Multi-Link element not found in Association Request"); @@ -671,7 +672,8 @@ static int nl80211_update_rejected_links_info(struct driver_sta_mlo_info *mlo, &req_info); wpabuf_free(mle); - mle = ieee802_11_defrag_mle(&resp_elems, MULTI_LINK_CONTROL_TYPE_BASIC); + mle = ieee802_11_defrag(resp_elems.basic_mle, resp_elems.basic_mle_len, + true); if (!mle) { wpa_printf(MSG_ERROR, "nl80211: MLO: Basic Multi-Link element not found in Association Response"); diff --git a/src/pasn/pasn_initiator.c b/src/pasn/pasn_initiator.c index 1f9a50830..5d73f8195 100644 --- a/src/pasn/pasn_initiator.c +++ b/src/pasn/pasn_initiator.c @@ -378,8 +378,8 @@ static int wpas_pasn_wd_fils_rx(struct pasn_data *pasn, struct wpabuf *wd) return -1; } - fils_wd = ieee802_11_defrag(&elems, WLAN_EID_EXTENSION, - WLAN_EID_EXT_WRAPPED_DATA); + fils_wd = ieee802_11_defrag(elems.wrapped_data, elems.wrapped_data_len, + true); if (!fils_wd) { wpa_printf(MSG_DEBUG, @@ -1200,9 +1200,9 @@ int wpa_pasn_auth_rx(struct pasn_data *pasn, const u8 *data, size_t len, } if (pasn_params->wrapped_data_format != WPA_PASN_WRAPPED_DATA_NO) { - wrapped_data = ieee802_11_defrag(&elems, - WLAN_EID_EXTENSION, - WLAN_EID_EXT_WRAPPED_DATA); + wrapped_data = ieee802_11_defrag(elems.wrapped_data, + elems.wrapped_data_len, + true); if (!wrapped_data) { wpa_printf(MSG_DEBUG, "PASN: Missing wrapped data"); diff --git a/src/pasn/pasn_responder.c b/src/pasn/pasn_responder.c index 47be40324..7501e7a56 100644 --- a/src/pasn/pasn_responder.c +++ b/src/pasn/pasn_responder.c @@ -753,9 +753,8 @@ int handle_auth_pasn_1(struct pasn_data *pasn, derive_keys = true; if (pasn_params.wrapped_data_format != WPA_PASN_WRAPPED_DATA_NO) { - wrapped_data = ieee802_11_defrag(&elems, - WLAN_EID_EXTENSION, - WLAN_EID_EXT_WRAPPED_DATA); + wrapped_data = ieee802_11_defrag(elems.wrapped_data, + elems.wrapped_data_len, true); if (!wrapped_data) { wpa_printf(MSG_DEBUG, "PASN: Missing wrapped data"); status = WLAN_STATUS_UNSPECIFIED_FAILURE; @@ -979,9 +978,9 @@ int handle_auth_pasn_3(struct pasn_data *pasn, const u8 *own_addr, } if (pasn_params.wrapped_data_format != WPA_PASN_WRAPPED_DATA_NO) { - wrapped_data = ieee802_11_defrag(&elems, - WLAN_EID_EXTENSION, - WLAN_EID_EXT_WRAPPED_DATA); + wrapped_data = ieee802_11_defrag(elems.wrapped_data, + elems.wrapped_data_len, + true); if (!wrapped_data) { wpa_printf(MSG_DEBUG, "PASN: Missing wrapped data"); diff --git a/wlantest/rx_mgmt.c b/wlantest/rx_mgmt.c index 5d1233b64..c6bf65ddf 100644 --- a/wlantest/rx_mgmt.c +++ b/wlantest/rx_mgmt.c @@ -390,7 +390,7 @@ static void parse_basic_ml_elems(struct ieee802_11_elems *elems, bool ap, { struct wpabuf *mlbuf; - mlbuf = ieee802_11_defrag_mle(elems, MULTI_LINK_CONTROL_TYPE_BASIC); + mlbuf = ieee802_11_defrag(elems->basic_mle, elems->basic_mle_len, true); if (mlbuf) { parse_basic_ml(wpabuf_head(mlbuf), wpabuf_len(mlbuf), ap, sta, fields_len); diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c index a11291550..ca11e7200 100644 --- a/wpa_supplicant/bss.c +++ b/wpa_supplicant/bss.c @@ -1497,24 +1497,6 @@ int wpa_bss_ext_capab(const struct wpa_bss *bss, unsigned int capab) } -/** - * wpa_bss_defrag_mle - Get a buffer holding a de-fragmented ML element - * @bss: BSS table entry - * @type: ML control type - */ -struct wpabuf * wpa_bss_defrag_mle(const struct wpa_bss *bss, u8 type) -{ - struct ieee802_11_elems elems; - const u8 *pos = wpa_bss_ie_ptr(bss); - size_t len = bss->ie_len; - - if (ieee802_11_parse_elems(pos, len, &elems, 1) == ParseFailed) - return NULL; - - return ieee802_11_defrag_mle(&elems, type); -} - - static void wpa_bss_parse_ml_rnr_ap_info(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, u8 mbssid_idx, @@ -1634,7 +1616,7 @@ int wpa_bss_parse_basic_ml_element(struct wpa_supplicant *wpa_s, return ret; } - mlbuf = ieee802_11_defrag_mle(&elems, MULTI_LINK_CONTROL_TYPE_BASIC); + mlbuf = ieee802_11_defrag(elems.basic_mle, elems.basic_mle_len, true); if (!mlbuf) { wpa_dbg(wpa_s, MSG_DEBUG, "MLD: No Multi-Link element"); return ret; @@ -1770,7 +1752,7 @@ u16 wpa_bss_parse_reconf_ml_element(struct wpa_supplicant *wpa_s, if (!elems.reconf_mle || !elems.reconf_mle_len) return 0; - mlbuf = ieee802_11_defrag_mle(&elems, MULTI_LINK_CONTROL_TYPE_RECONF); + mlbuf = ieee802_11_defrag(elems.reconf_mle, elems.reconf_mle_len, true); if (!mlbuf) return 0; diff --git a/wpa_supplicant/bss.h b/wpa_supplicant/bss.h index 042b5d264..7b0b24c61 100644 --- a/wpa_supplicant/bss.h +++ b/wpa_supplicant/bss.h @@ -213,7 +213,6 @@ void calculate_update_time(const struct os_reltime *fetch_time, unsigned int age_ms, struct os_reltime *update_time); -struct wpabuf * wpa_bss_defrag_mle(const struct wpa_bss *bss, u8 type); int wpa_bss_parse_basic_ml_element(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, u8 *ap_mld_addr, diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index 8c81824f0..02114acae 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -485,6 +485,7 @@ static bool wpas_ml_element(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, u8 ml_ie_len; const struct ieee80211_eht_ml *eht_ml; const struct eht_ml_basic_common_info *ml_basic_common_info; + struct ieee802_11_elems elems; u8 i; const u16 control = host_to_le16(MULTI_LINK_CONTROL_TYPE_BASIC | @@ -497,7 +498,11 @@ static bool wpas_ml_element(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, if (!(wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_MLO)) return false; - mlbuf = wpa_bss_defrag_mle(bss, MULTI_LINK_CONTROL_TYPE_BASIC); + if (ieee802_11_parse_elems(wpa_bss_ie_ptr(bss), + bss->ie_len, &elems, 1) == ParseFailed) + return false; + + mlbuf = ieee802_11_defrag(elems.basic_mle, elems.basic_mle_len, true); if (!mlbuf) { wpa_dbg(wpa_s, MSG_DEBUG, "MLD: No ML element"); return false;