git: ba26206ad9e3 - stable/13 - LinuxKPI: 802.11: implement some *eleme/ie* lookup functions

From: Bjoern A. Zeeb <bz_at_FreeBSD.org>
Date: Wed, 18 Jan 2023 16:25:00 UTC
The branch stable/13 has been updated by bz:

URL: https://cgit.FreeBSD.org/src/commit/?id=ba26206ad9e34af730095f5e20f3ecf517dbd89c

commit ba26206ad9e34af730095f5e20f3ecf517dbd89c
Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2022-12-31 01:33:28 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2023-01-18 13:26:21 +0000

    LinuxKPI: 802.11: implement some *eleme/ie* lookup functions
    
    Implement cfg80211_find_elem(), ieee80211_bss_get_elem(),
    ieee80211_bss_get_ie(), and cfg80211_find_vendor_ie() with the last
    one having a short cut always also checking oui_type in the pattern.
    
    Sponsored by:   The FreeBSD Foundation
    
    (cherry picked from commit 5db817d864241232c51d654836996282c69f5e28)
---
 sys/compat/linuxkpi/common/include/net/cfg80211.h | 76 +++++++++++++++++++----
 sys/compat/linuxkpi/common/include/net/mac80211.h | 14 -----
 2 files changed, 65 insertions(+), 25 deletions(-)

diff --git a/sys/compat/linuxkpi/common/include/net/cfg80211.h b/sys/compat/linuxkpi/common/include/net/cfg80211.h
index b5135f34981e..55a74227a338 100644
--- a/sys/compat/linuxkpi/common/include/net/cfg80211.h
+++ b/sys/compat/linuxkpi/common/include/net/cfg80211.h
@@ -1321,13 +1321,75 @@ struct element {
 	uint8_t					data[0];
 } __packed;
 
-static __inline const struct element *
-cfg80211_find_elem(enum ieee80211_eid eid, uint8_t *data, size_t len)
+static inline const struct element *
+lkpi_cfg80211_find_elem_pattern(enum ieee80211_eid eid,
+    const uint8_t *data, size_t len, uint8_t *pattern, size_t plen)
 {
-	TODO();
+	const struct element *elem;
+	const uint8_t *p;
+	size_t ielen;
+
+	p = data;
+	elem = (const struct element *)p;
+	ielen = len;
+	while (elem != NULL && ielen > 1) {
+		if ((2 + elem->datalen) > ielen)
+			/* Element overruns our memory. */
+			return (NULL);
+		if (elem->id == eid) {
+			if (pattern == NULL)
+				return (elem);
+			if (elem->datalen >= plen &&
+			    memcmp(elem->data, pattern, plen) == 0)
+				return (elem);
+		}
+		ielen -= 2 + elem->datalen;
+		p += 2 + elem->datalen;
+		elem = (const struct element *)p;
+	}
+
 	return (NULL);
 }
 
+static inline const struct element *
+cfg80211_find_elem(enum ieee80211_eid eid, const uint8_t *data, size_t len)
+{
+
+	return (lkpi_cfg80211_find_elem_pattern(eid, data, len, NULL, 0));
+}
+
+static inline const struct element *
+ieee80211_bss_get_elem(struct cfg80211_bss *bss, uint32_t eid)
+{
+
+	if (bss->ies == NULL)
+		return (NULL);
+	return (cfg80211_find_elem(eid, bss->ies->data, bss->ies->len));
+}
+
+static inline const uint8_t *
+ieee80211_bss_get_ie(struct cfg80211_bss *bss, uint32_t eid)
+{
+
+	return ((const uint8_t *)ieee80211_bss_get_elem(bss, eid));
+}
+
+static inline uint8_t *
+cfg80211_find_vendor_ie(unsigned int oui, int oui_type,
+    uint8_t *data, size_t len)
+{
+	const struct element *elem;
+	uint8_t pattern[4] = { oui << 16, oui << 8, oui, oui_type };
+	uint8_t plen = 4;		/* >= 3? oui_type always part of this? */
+	IMPROVE("plen currently always incl. oui_type");
+
+	elem = lkpi_cfg80211_find_elem_pattern(IEEE80211_ELEMID_VENDOR,
+	    data, len, pattern, plen);
+	if (elem == NULL)
+		return (NULL);
+	return (__DECONST(uint8_t *, elem));
+}
+
 static __inline uint32_t
 cfg80211_calculate_bitrate(struct rate_info *rate)
 {
@@ -1439,14 +1501,6 @@ wiphy_read_of_freq_limits(struct wiphy *wiphy)
 #endif
 }
 
-static __inline uint8_t *
-cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type,
-    uint8_t *data, size_t len)
-{
-	TODO();
-	return (NULL);
-}
-
 static __inline void
 wiphy_ext_feature_set(struct wiphy *wiphy, enum nl80211_ext_feature ef)
 {
diff --git a/sys/compat/linuxkpi/common/include/net/mac80211.h b/sys/compat/linuxkpi/common/include/net/mac80211.h
index 230d42947e7b..d548b9bb956f 100644
--- a/sys/compat/linuxkpi/common/include/net/mac80211.h
+++ b/sys/compat/linuxkpi/common/include/net/mac80211.h
@@ -2183,13 +2183,6 @@ SET_IEEE80211_PERM_ADDR	(struct ieee80211_hw *hw, uint8_t *addr)
 	ether_addr_copy(hw->wiphy->perm_addr, addr);
 }
 
-static __inline uint8_t *
-ieee80211_bss_get_ie(struct cfg80211_bss *bss, uint32_t eid)
-{
-	TODO();
-	return (NULL);
-}
-
 static __inline void
 ieee80211_report_low_ack(struct ieee80211_sta *sta, int x)
 {
@@ -2368,13 +2361,6 @@ ieee80211_tx_status_ext(struct ieee80211_hw *hw,
 	TODO();
 }
 
-static __inline const struct element *
-ieee80211_bss_get_elem(struct cfg80211_bss *bss, uint32_t eid)
-{
-	TODO();
-	return (NULL);
-}
-
 static __inline void
 ieee80211_color_change_finish(struct ieee80211_vif *vif)
 {