mac80211: support profile split between elements
Since an element is limited to 255 octets, a profile may be split split to several elements. Support the split as defined in the 11ax draft 3. Signed-off-by: Sara Sharon <sara.sharon@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
fe806e4992
commit
5023b14cf4
2 changed files with 37 additions and 20 deletions
|
@ -1505,7 +1505,6 @@ struct ieee802_11_elems {
|
||||||
const struct ieee80211_bss_max_idle_period_ie *max_idle_period_ie;
|
const struct ieee80211_bss_max_idle_period_ie *max_idle_period_ie;
|
||||||
const struct ieee80211_multiple_bssid_configuration *mbssid_config_ie;
|
const struct ieee80211_multiple_bssid_configuration *mbssid_config_ie;
|
||||||
const struct ieee80211_bssid_index *bssid_index;
|
const struct ieee80211_bssid_index *bssid_index;
|
||||||
const u8 *nontransmitted_bssid_profile;
|
|
||||||
u8 max_bssid_indicator;
|
u8 max_bssid_indicator;
|
||||||
u8 dtim_count;
|
u8 dtim_count;
|
||||||
u8 dtim_period;
|
u8 dtim_period;
|
||||||
|
|
|
@ -1254,15 +1254,18 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
|
||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ieee802_11_find_bssid_profile(const u8 *start, size_t len,
|
static size_t ieee802_11_find_bssid_profile(const u8 *start, size_t len,
|
||||||
struct ieee802_11_elems *elems,
|
struct ieee802_11_elems *elems,
|
||||||
u8 *transmitter_bssid,
|
u8 *transmitter_bssid,
|
||||||
u8 *bss_bssid)
|
u8 *bss_bssid,
|
||||||
|
u8 **nontransmitted_profile)
|
||||||
{
|
{
|
||||||
const struct element *elem, *sub;
|
const struct element *elem, *sub;
|
||||||
|
size_t profile_len = 0;
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
if (!bss_bssid || !transmitter_bssid)
|
if (!bss_bssid || !transmitter_bssid)
|
||||||
return;
|
return profile_len;
|
||||||
|
|
||||||
for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, start, len) {
|
for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, start, len) {
|
||||||
if (elem->datalen < 2)
|
if (elem->datalen < 2)
|
||||||
|
@ -1287,9 +1290,17 @@ static void ieee802_11_find_bssid_profile(const u8 *start, size_t len,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(*nontransmitted_profile, 0, len);
|
||||||
|
profile_len = cfg80211_merge_profile(start, len,
|
||||||
|
elem,
|
||||||
|
sub,
|
||||||
|
nontransmitted_profile,
|
||||||
|
len);
|
||||||
|
|
||||||
/* found a Nontransmitted BSSID Profile */
|
/* found a Nontransmitted BSSID Profile */
|
||||||
index = cfg80211_find_ie(WLAN_EID_MULTI_BSSID_IDX,
|
index = cfg80211_find_ie(WLAN_EID_MULTI_BSSID_IDX,
|
||||||
sub->data, sub->datalen);
|
*nontransmitted_profile,
|
||||||
|
profile_len);
|
||||||
if (!index || index[1] < 1 || index[2] == 0) {
|
if (!index || index[1] < 1 || index[2] == 0) {
|
||||||
/* Invalid MBSSID Index element */
|
/* Invalid MBSSID Index element */
|
||||||
continue;
|
continue;
|
||||||
|
@ -1300,14 +1311,15 @@ static void ieee802_11_find_bssid_profile(const u8 *start, size_t len,
|
||||||
index[2],
|
index[2],
|
||||||
new_bssid);
|
new_bssid);
|
||||||
if (ether_addr_equal(new_bssid, bss_bssid)) {
|
if (ether_addr_equal(new_bssid, bss_bssid)) {
|
||||||
elems->nontransmitted_bssid_profile =
|
found = true;
|
||||||
elem->data;
|
|
||||||
elems->bssid_index_len = index[1];
|
elems->bssid_index_len = index[1];
|
||||||
elems->bssid_index = (void *)&index[2];
|
elems->bssid_index = (void *)&index[2];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return found ? profile_len : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
|
u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
|
||||||
|
@ -1316,30 +1328,34 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
|
||||||
u8 *bss_bssid)
|
u8 *bss_bssid)
|
||||||
{
|
{
|
||||||
const struct element *non_inherit = NULL;
|
const struct element *non_inherit = NULL;
|
||||||
|
u8 *nontransmitted_profile;
|
||||||
|
int nontransmitted_profile_len = 0;
|
||||||
|
|
||||||
memset(elems, 0, sizeof(*elems));
|
memset(elems, 0, sizeof(*elems));
|
||||||
elems->ie_start = start;
|
elems->ie_start = start;
|
||||||
elems->total_len = len;
|
elems->total_len = len;
|
||||||
|
|
||||||
ieee802_11_find_bssid_profile(start, len, elems, transmitter_bssid,
|
nontransmitted_profile = kmalloc(len, GFP_ATOMIC);
|
||||||
bss_bssid);
|
if (nontransmitted_profile) {
|
||||||
|
nontransmitted_profile_len =
|
||||||
if (elems->nontransmitted_bssid_profile)
|
ieee802_11_find_bssid_profile(start, len, elems,
|
||||||
|
transmitter_bssid,
|
||||||
|
bss_bssid,
|
||||||
|
&nontransmitted_profile);
|
||||||
non_inherit =
|
non_inherit =
|
||||||
cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
|
cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
|
||||||
&elems->nontransmitted_bssid_profile[2],
|
nontransmitted_profile,
|
||||||
elems->nontransmitted_bssid_profile[1]);
|
nontransmitted_profile_len);
|
||||||
|
}
|
||||||
|
|
||||||
crc = _ieee802_11_parse_elems_crc(start, len, action, elems, filter,
|
crc = _ieee802_11_parse_elems_crc(start, len, action, elems, filter,
|
||||||
crc, non_inherit);
|
crc, non_inherit);
|
||||||
|
|
||||||
/* Override with nontransmitted profile, if found */
|
/* Override with nontransmitted profile, if found */
|
||||||
if (transmitter_bssid && elems->nontransmitted_bssid_profile) {
|
if (nontransmitted_profile_len)
|
||||||
const u8 *profile = elems->nontransmitted_bssid_profile;
|
_ieee802_11_parse_elems_crc(nontransmitted_profile,
|
||||||
|
nontransmitted_profile_len,
|
||||||
_ieee802_11_parse_elems_crc(&profile[2], profile[1],
|
|
||||||
action, elems, 0, 0, NULL);
|
action, elems, 0, 0, NULL);
|
||||||
}
|
|
||||||
|
|
||||||
if (elems->tim && !elems->parse_error) {
|
if (elems->tim && !elems->parse_error) {
|
||||||
const struct ieee80211_tim_ie *tim_ie = elems->tim;
|
const struct ieee80211_tim_ie *tim_ie = elems->tim;
|
||||||
|
@ -1359,6 +1375,8 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
|
||||||
offsetofend(struct ieee80211_bssid_index, dtim_count))
|
offsetofend(struct ieee80211_bssid_index, dtim_count))
|
||||||
elems->dtim_count = elems->bssid_index->dtim_count;
|
elems->dtim_count = elems->bssid_index->dtim_count;
|
||||||
|
|
||||||
|
kfree(nontransmitted_profile);
|
||||||
|
|
||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue