Add shared per-radio structure for wpa_supplicant
struct wpa_radio is used as a shared data structure between all struct wpa_supplicant instances that share the same physical radio. Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
73c00fd794
commit
202dec2a94
2 changed files with 80 additions and 1 deletions
|
@ -2872,10 +2872,61 @@ int wpas_init_ext_pw(struct wpa_supplicant *wpa_s)
|
|||
}
|
||||
|
||||
|
||||
static struct wpa_radio * radio_add_interface(struct wpa_supplicant *wpa_s,
|
||||
const char *rn)
|
||||
{
|
||||
struct wpa_supplicant *iface = wpa_s->global->ifaces;
|
||||
struct wpa_radio *radio;
|
||||
|
||||
while (rn && iface) {
|
||||
radio = iface->radio;
|
||||
if (radio && os_strcmp(rn, radio->name) == 0) {
|
||||
wpa_printf(MSG_DEBUG, "Add interface %s to existing radio %s",
|
||||
wpa_s->ifname, rn);
|
||||
dl_list_add(&radio->ifaces, &wpa_s->radio_list);
|
||||
return radio;
|
||||
}
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "Add interface %s to a new radio %s",
|
||||
wpa_s->ifname, rn ? rn : "N/A");
|
||||
radio = os_zalloc(sizeof(*radio));
|
||||
if (radio == NULL)
|
||||
return NULL;
|
||||
|
||||
if (rn)
|
||||
os_strlcpy(radio->name, rn, sizeof(radio->name));
|
||||
dl_list_init(&radio->ifaces);
|
||||
dl_list_add(&radio->ifaces, &wpa_s->radio_list);
|
||||
|
||||
return radio;
|
||||
}
|
||||
|
||||
|
||||
static void radio_remove_interface(struct wpa_supplicant *wpa_s)
|
||||
{
|
||||
struct wpa_radio *radio = wpa_s->radio;
|
||||
|
||||
if (!radio)
|
||||
return;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "Remove interface %s from radio %s",
|
||||
wpa_s->ifname, radio->name);
|
||||
dl_list_del(&wpa_s->radio_list);
|
||||
wpa_s->radio = NULL;
|
||||
|
||||
if (!dl_list_empty(&radio->ifaces))
|
||||
return; /* Interfaces remain for this radio */
|
||||
|
||||
wpa_printf(MSG_DEBUG, "Remove radio %s", radio->name);
|
||||
os_free(radio);
|
||||
}
|
||||
|
||||
|
||||
static int wpas_init_driver(struct wpa_supplicant *wpa_s,
|
||||
struct wpa_interface *iface)
|
||||
{
|
||||
const char *ifname, *driver;
|
||||
const char *ifname, *driver, *rn;
|
||||
|
||||
driver = iface->driver;
|
||||
next_driver:
|
||||
|
@ -2909,6 +2960,17 @@ next_driver:
|
|||
os_strlcpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
|
||||
}
|
||||
|
||||
if (wpa_s->driver->get_radio_name)
|
||||
rn = wpa_s->driver->get_radio_name(wpa_s->drv_priv);
|
||||
else
|
||||
rn = NULL;
|
||||
if (rn && rn[0] == '\0')
|
||||
rn = NULL;
|
||||
|
||||
wpa_s->radio = radio_add_interface(wpa_s, rn);
|
||||
if (wpa_s->radio == NULL)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3180,6 +3242,8 @@ static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
|
|||
}
|
||||
#endif /* CONFIG_P2P */
|
||||
|
||||
radio_remove_interface(wpa_s);
|
||||
|
||||
if (wpa_s->drv_priv)
|
||||
wpa_drv_deinit(wpa_s);
|
||||
|
||||
|
|
|
@ -270,6 +270,19 @@ struct wpa_global {
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
* struct wpa_radio - Internal data for per-radio information
|
||||
*
|
||||
* This structure is used to share data about configured interfaces
|
||||
* (struct wpa_supplicant) that share the same physical radio, e.g., to allow
|
||||
* better coordination of offchannel operations.
|
||||
*/
|
||||
struct wpa_radio {
|
||||
char name[16]; /* from driver_ops get_radio_name() or empty if not
|
||||
* available */
|
||||
struct dl_list ifaces; /* struct wpa_supplicant::radio_list entries */
|
||||
};
|
||||
|
||||
/**
|
||||
* offchannel_send_action_result - Result of offchannel send Action frame
|
||||
*/
|
||||
|
@ -307,6 +320,8 @@ struct wpa_ssid_value {
|
|||
*/
|
||||
struct wpa_supplicant {
|
||||
struct wpa_global *global;
|
||||
struct wpa_radio *radio; /* shared radio context */
|
||||
struct dl_list radio_list; /* list head: struct wpa_radio::ifaces */
|
||||
struct wpa_supplicant *parent;
|
||||
struct wpa_supplicant *next;
|
||||
struct l2_packet_data *l2;
|
||||
|
|
Loading…
Reference in a new issue