]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
AP MLD: Handle Vendor Specific element inheritance in per STA profile
authorArunpandi Kannan <quic_arunpand@quicinc.com>
Wed, 7 Aug 2024 06:41:46 +0000 (12:11 +0530)
committerJouni Malinen <j@w1.fi>
Wed, 7 Aug 2024 15:58:32 +0000 (18:58 +0300)
As per IEEE P802.11be/D7.0, 35.3.3.5.1 (Inheritance in the Per-STA
Profile subelement of Basic Multi-Link element), Note 1, if there exists
one or more Vendor Specific elements carried in a Management frame that
includes the Basic Multi-Link element containing a per-STA profile for a
reported STA, and the contents of the Information field for at least one
of the Vendor Specific elements is not the same as that of at least one
Vendor Specific element that applies to the reported STA, then each
Vendor Specific element that applies to the reported STA is included in
its Per-STA Profile subelement.

Handle this.

Signed-off-by: Arunpandi Kannan <quic_arunpand@quicinc.com>
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
src/ap/beacon.c

index df3371d93188890b2dc24692422ac3ace5b4b158..c9ffbba756dfe34e333d14d764d0f13e92726e1f 100644 (file)
@@ -2898,6 +2898,8 @@ static size_t hostapd_add_sta_profile(struct ieee80211_mgmt *link_fdata,
        u8 non_inherit_ele_ext_list_len = 0;
        u8 non_inherit_ele_list[256] = { 0 };
        u8 non_inherit_ele_list_len = 0;
+       u8 num_link_elem_vendor_ies = 0, num_own_elem_vendor_ies = 0;
+       bool add_vendor_ies = false, is_identical_vendor_ies = true;
        /* The bitmap of parsed EIDs. There are 256 EIDs and ext EIDs, so 32
         * bytes to store the bitmaps. */
        u8 parsed_eid_bmap[32] = { 0 }, parsed_ext_eid_bmap[32] = { 0 };
@@ -2967,8 +2969,20 @@ static size_t hostapd_add_sta_profile(struct ieee80211_mgmt *link_fdata,
                        /* Ignore if the contents is identical. */
                        if (own_ele_len == link_ele_len &&
                            os_memcmp(own_elem->data, link_elem->data,
-                                     own_ele_len) == 0)
+                                     own_ele_len) == 0) {
+                               if (own_eid == WLAN_EID_VENDOR_SPECIFIC) {
+                                       is_identical_vendor_ies = true;
+                                       num_own_elem_vendor_ies++;
+                               }
                                continue;
+                       }
+
+                       /* No need to include this non-matching Vendor Specific
+                        * element explicitly at this point. */
+                       if (own_eid == WLAN_EID_VENDOR_SPECIFIC) {
+                               is_identical_vendor_ies = false;
+                               continue;
+                       }
 
                        /* This element is present in the reported profile
                         * as well as present in the reporting profile.
@@ -2992,6 +3006,13 @@ static size_t hostapd_add_sta_profile(struct ieee80211_mgmt *link_fdata,
                        break;
                }
 
+               /* We found at least one Vendor Specific element in reporting
+                * link which is not same (or present) in the reported link. We
+                * need to include all Vendor Specific elements from the
+                * reported link. */
+               if (!is_identical_vendor_ies)
+                       add_vendor_ies = true;
+
                /* This is a unique element in the reporting profile which is
                 * not present in the reported profile. Update the
                 * non-inheritance list. */
@@ -3013,6 +3034,13 @@ static size_t hostapd_add_sta_profile(struct ieee80211_mgmt *link_fdata,
                link_elem_data = link_elem->data;
                link_ele_len = link_elem->datalen;
 
+               /* No need to check this Vendor Specific element at this point.
+                * Just take the count and continue. */
+               if (link_elem->id == WLAN_EID_VENDOR_SPECIFIC) {
+                       num_link_elem_vendor_ies++;
+                       continue;
+               }
+
                if (link_elem->id == WLAN_EID_EXTENSION) {
                        link_eid = *(link_elem_data);
 
@@ -3037,6 +3065,30 @@ static size_t hostapd_add_sta_profile(struct ieee80211_mgmt *link_fdata,
                }
        }
 
+       /* Handle Vendor Specific elements
+        * Add all the Vendor Specific elements of the reported link if
+        *  a. There is at least one non-matching Vendor Specific element, or
+        *  b. The number of Vendor Specific elements in reporting and reported
+        *     link is not same. */
+       if (add_vendor_ies ||
+           num_own_elem_vendor_ies != num_link_elem_vendor_ies) {
+               for_each_element(link_elem, link_data, link_data_len) {
+                       link_elem_data = link_elem->data;
+                       link_ele_len = link_elem->datalen;
+
+                       if (link_elem->id != WLAN_EID_VENDOR_SPECIFIC)
+                               continue;
+
+                       sta_profile_len += link_ele_len + extra_len;
+                       if (sta_profile) {
+                               os_memcpy(sta_profile,
+                                         link_elem_data - extra_len,
+                                         link_ele_len + extra_len);
+                               sta_profile += link_ele_len + extra_len;
+                       }
+               }
+       }
+
        /* Handle non-inheritance
         * Non-Inheritance element:
         *      Element ID Ext: 1 octet