3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-12-22 21:22:37 +01:00

ie: refactor parsing supported data rates

Both ext/supported rates IEs are obtained from scan results. These
IEs are passed to ie_tlv_init/ie_tlv_next, as well as direct length
checks (for supported rates at least, extended supported rates can
be as long as a single byte integer can hold, 1 - 255) which verifies
that the length in the IE matches the overall IE length that is
stored in scan_bss. Because of this, ie_parse_supported_rates_from_data
was doing double duty re-initializing a TLV iterator.

Intead, since we know the IE length is within bounds, the length/data
can simply be directly accessed out of the buffer. This avoids the need
for a wrapper function entirely.

The length parameters were also removed, since this is now obtained
directly from the IE.
This commit is contained in:
James Prestwood 2021-05-14 12:22:52 -07:00 committed by Denis Kenzior
parent 02e46542e3
commit 7c9561f027
2 changed files with 20 additions and 62 deletions

View File

@ -1662,10 +1662,9 @@ static const struct basic_rate_map rate_rssi_map[] = {
{ -65, 108 }, { -65, 108 },
}; };
static int ie_parse_supported_rates(struct ie_tlv_iter *supp_rates_iter, static int ie_parse_supported_rates_from_data(const uint8_t *supp_rates_ie,
struct ie_tlv_iter *ext_supp_rates_iter, const uint8_t *ext_supp_rates_ie,
int32_t rssi, int32_t rssi, uint64_t *data_rate)
uint64_t *data_rate)
{ {
uint8_t max_rate = 0; uint8_t max_rate = 0;
uint8_t highest = 0; uint8_t highest = 0;
@ -1673,11 +1672,6 @@ static int ie_parse_supported_rates(struct ie_tlv_iter *supp_rates_iter,
unsigned int len; unsigned int len;
unsigned int i; unsigned int i;
len = ie_tlv_iter_get_length(supp_rates_iter);
if (len == 0)
return -EINVAL;
/* Find highest rates possible with our RSSI */ /* Find highest rates possible with our RSSI */
for (i = 0; i < L_ARRAY_SIZE(rate_rssi_map); i++) { for (i = 0; i < L_ARRAY_SIZE(rate_rssi_map); i++) {
const struct basic_rate_map *map = &rate_rssi_map[i]; const struct basic_rate_map *map = &rate_rssi_map[i];
@ -1688,9 +1682,17 @@ static int ie_parse_supported_rates(struct ie_tlv_iter *supp_rates_iter,
max_rate = map->rate; max_rate = map->rate;
} }
if (supp_rates_iter) { /*
/* Find highest rate in Supported Rates IE */ * Find highest rate in Supported Rates IE. These IEs have at least
rates = ie_tlv_iter_get_data(supp_rates_iter); * been verfied that the length is within the buffer bounds (as has
* ext_supp_rates_ie).
*/
if (supp_rates_ie) {
len = supp_rates_ie[1];
if (len == 0)
return -EINVAL;
rates = supp_rates_ie + 2;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
uint8_t r = rates[i] & 0x7f; uint8_t r = rates[i] & 0x7f;
@ -1701,9 +1703,12 @@ static int ie_parse_supported_rates(struct ie_tlv_iter *supp_rates_iter,
} }
/* Find highest rate in Extended Supported Rates IE */ /* Find highest rate in Extended Supported Rates IE */
if (ext_supp_rates_iter) { if (ext_supp_rates_ie) {
len = ie_tlv_iter_get_length(ext_supp_rates_iter); len = ext_supp_rates_ie[1];
rates = ie_tlv_iter_get_data(ext_supp_rates_iter); if (len == 0)
return -EINVAL;
rates = ext_supp_rates_ie + 2;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
uint8_t r = rates[i] & 0x7f; uint8_t r = rates[i] & 0x7f;
@ -1721,45 +1726,6 @@ static int ie_parse_supported_rates(struct ie_tlv_iter *supp_rates_iter,
return 0; return 0;
} }
int ie_parse_supported_rates_from_data(const uint8_t *supp_rates_ie,
uint8_t supp_rates_len,
const uint8_t *ext_supp_rates_ie,
uint8_t ext_supp_rates_len,
int32_t rssi, uint64_t *data_rate)
{
struct ie_tlv_iter supp_rates_iter;
struct ie_tlv_iter ext_supp_rates_iter;
if (supp_rates_ie) {
ie_tlv_iter_init(&supp_rates_iter, supp_rates_ie,
supp_rates_len);
if (!ie_tlv_iter_next(&supp_rates_iter))
return -EMSGSIZE;
if (ie_tlv_iter_get_tag(&supp_rates_iter) !=
IE_TYPE_SUPPORTED_RATES)
return -EPROTOTYPE;
}
if (ext_supp_rates_ie) {
ie_tlv_iter_init(&ext_supp_rates_iter, ext_supp_rates_ie,
ext_supp_rates_len);
if (!ie_tlv_iter_next(&ext_supp_rates_iter))
return -EMSGSIZE;
if (ie_tlv_iter_get_tag(&ext_supp_rates_iter) !=
IE_TYPE_EXTENDED_SUPPORTED_RATES)
return -EPROTOTYPE;
}
return ie_parse_supported_rates(
(supp_rates_ie) ? &supp_rates_iter : NULL,
(ext_supp_rates_ie) ? &ext_supp_rates_iter : NULL,
rssi, data_rate);
}
enum ht_vht_channel_width { enum ht_vht_channel_width {
HT_VHT_CHANNEL_WIDTH_20MHZ = 0, HT_VHT_CHANNEL_WIDTH_20MHZ = 0,
HT_VHT_CHANNEL_WIDTH_40MHZ, HT_VHT_CHANNEL_WIDTH_40MHZ,
@ -2173,9 +2139,7 @@ int ie_parse_data_rates(const uint8_t *supp_rates_ie,
if (supp_rates_ie || ext_supp_rates_ie) { if (supp_rates_ie || ext_supp_rates_ie) {
ret = ie_parse_supported_rates_from_data(supp_rates_ie, ret = ie_parse_supported_rates_from_data(supp_rates_ie,
IE_LEN(supp_rates_ie),
ext_supp_rates_ie, ext_supp_rates_ie,
IE_LEN(supp_rates_ie),
rssi, &rate); rssi, &rate);
if (ret == 0) if (ret == 0)
goto done; goto done;

View File

@ -484,12 +484,6 @@ int ie_parse_bss_load_from_data(const uint8_t *data, uint8_t len,
uint8_t *out_channel_utilization, uint8_t *out_channel_utilization,
uint16_t *out_admission_capacity); uint16_t *out_admission_capacity);
int ie_parse_supported_rates_from_data(const uint8_t *supp_rates_ie,
uint8_t supp_rates_len,
const uint8_t *ext_supp_rates_ie,
uint8_t ext_supp_rates_len,
int32_t rssi, uint64_t *data_rate);
int ie_parse_data_rates(const uint8_t *supp_rates_ie, int ie_parse_data_rates(const uint8_t *supp_rates_ie,
const uint8_t *ext_supp_rates_ie, const uint8_t *ext_supp_rates_ie,
const uint8_t *ht_ie, const uint8_t *ht_ie,