hwsim: Look up radio address in radio_info
In mac80211_hwsim each radio is assigned two addresses, the second (addr 1) being used over nl80211. In SendFrame we'd hardcode the mapping of address 0 to address 1 even though we track all the addresses in radio_info, so instead use that data to find the radio that has given address 0. Also if no address 0 matches what was supplied over DBus try to find a matching address 1. There are ways userspace can request different addresses when managing mac80211_hwsim radios and the hardcoded mapping would become wrong.
This commit is contained in:
parent
676a1f48c3
commit
465488878e
|
@ -340,6 +340,14 @@ static bool radio_info_match_wiphy_id(const void *a, const void *b)
|
||||||
return rec->wiphy_id == id;
|
return rec->wiphy_id == id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool radio_info_match_addr0(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
const struct radio_info_rec *rec = a;
|
||||||
|
const uint8_t *addr0 = b;
|
||||||
|
|
||||||
|
return !memcmp(rec->addrs[0], addr0, ETH_ALEN);
|
||||||
|
}
|
||||||
|
|
||||||
static bool radio_info_match_addr1(const void *a, const void *b)
|
static bool radio_info_match_addr1(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
const struct radio_info_rec *rec = a;
|
const struct radio_info_rec *rec = a;
|
||||||
|
@ -1233,7 +1241,6 @@ static void send_custom_frame_destroy(void *user_data)
|
||||||
l_dbus_message_unref(info->user_data);
|
l_dbus_message_unref(info->user_data);
|
||||||
|
|
||||||
l_free(info->frame);
|
l_free(info->frame);
|
||||||
l_free(info->radio);
|
|
||||||
l_free(info);
|
l_free(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1242,7 +1249,6 @@ static bool send_custom_frame(const uint8_t *addr, uint32_t freq,
|
||||||
void *user_data)
|
void *user_data)
|
||||||
{
|
{
|
||||||
struct hwsim_frame *frame = l_new(struct hwsim_frame, 1);
|
struct hwsim_frame *frame = l_new(struct hwsim_frame, 1);
|
||||||
struct radio_info_rec *radio = l_new(struct radio_info_rec, 1);
|
|
||||||
struct send_frame_info *info = l_new(struct send_frame_info, 1);
|
struct send_frame_info *info = l_new(struct send_frame_info, 1);
|
||||||
|
|
||||||
frame->frequency = freq;
|
frame->frequency = freq;
|
||||||
|
@ -1251,27 +1257,26 @@ static bool send_custom_frame(const uint8_t *addr, uint32_t freq,
|
||||||
frame->payload = payload;
|
frame->payload = payload;
|
||||||
|
|
||||||
info->frame = frame;
|
info->frame = frame;
|
||||||
info->radio = radio;
|
|
||||||
info->user_data = user_data;
|
info->user_data = user_data;
|
||||||
|
|
||||||
memcpy(info->radio->addrs[0], addr, ETH_ALEN);
|
info->radio = l_queue_find(radio_info, radio_info_match_addr0, addr) ?:
|
||||||
memcpy(info->radio->addrs[1], addr, ETH_ALEN);
|
l_queue_find(radio_info, radio_info_match_addr1, addr);
|
||||||
|
if (!info->radio)
|
||||||
/* hwsim expects the first nibble of the address byte to be '4' */
|
goto error;
|
||||||
info->radio->addrs[1][0] |= 0x40;
|
|
||||||
|
|
||||||
if (!send_frame(info, send_custom_frame_callback,
|
if (!send_frame(info, send_custom_frame_callback,
|
||||||
send_custom_frame_destroy)) {
|
send_custom_frame_destroy))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
error:
|
||||||
l_free(frame);
|
l_free(frame);
|
||||||
l_free(radio);
|
|
||||||
l_free(info);
|
l_free(info);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct interface_match_data {
|
struct interface_match_data {
|
||||||
struct radio_info_rec *radio;
|
struct radio_info_rec *radio;
|
||||||
const uint8_t *addr;
|
const uint8_t *addr;
|
||||||
|
|
Loading…
Reference in New Issue