struct hostapd_freq_params *freq);
static int
-wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
- const u8 *set_addr, int first,
+wpa_driver_nl80211_finish_drv_init(struct i802_bss *bss,
+ const u8 *set_addr,
const char *driver_params,
enum wpa_p2p_mode p2p_mode);
static int nl80211_send_frame_cmd(struct i802_bss *bss,
static void wpa_driver_nl80211_event_newlink(
- struct nl80211_global *global, struct wpa_driver_nl80211_data *drv,
+ struct nl80211_global *global, struct i802_bss *bss,
int ifindex, const char *ifname)
{
union wpa_event_data event;
- if (drv && os_strcmp(drv->first_bss->ifname, ifname) == 0) {
- if (if_nametoindex(drv->first_bss->ifname) == 0) {
+ if (bss && os_strcmp(bss->ifname, ifname) == 0) {
+ if (if_nametoindex(bss->ifname) == 0) {
wpa_printf(MSG_DEBUG, "nl80211: Interface %s does not exist - ignore RTM_NEWLINK",
- drv->first_bss->ifname);
+ bss->ifname);
return;
}
- if (!drv->if_removed)
+ if (!bss->if_removed)
return;
wpa_printf(MSG_DEBUG, "nl80211: Mark if_removed=0 for %s based on RTM_NEWLINK event",
- drv->first_bss->ifname);
- drv->if_removed = 0;
+ bss->ifname);
+ bss->if_removed = 0;
}
os_memset(&event, 0, sizeof(event));
os_strlcpy(event.interface_status.ifname, ifname,
sizeof(event.interface_status.ifname));
event.interface_status.ievent = EVENT_INTERFACE_ADDED;
- if (drv)
- wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
+ if (bss)
+ wpa_supplicant_event(bss->ctx, EVENT_INTERFACE_STATUS, &event);
else
wpa_supplicant_event_global(global->ctx, EVENT_INTERFACE_STATUS,
&event);
static void wpa_driver_nl80211_event_dellink(
- struct nl80211_global *global, struct wpa_driver_nl80211_data *drv,
+ struct nl80211_global *global, struct i802_bss *bss,
int ifindex, const char *ifname)
{
union wpa_event_data event;
- if (drv && os_strcmp(drv->first_bss->ifname, ifname) == 0) {
- if (drv->if_removed) {
+ if (bss && os_strcmp(bss->ifname, ifname) == 0) {
+ if (bss->if_removed) {
wpa_printf(MSG_DEBUG, "nl80211: if_removed already set - ignore RTM_DELLINK event for %s",
ifname);
return;
}
wpa_printf(MSG_DEBUG, "RTM_DELLINK: Interface '%s' removed - mark if_removed=1",
ifname);
- drv->if_removed = 1;
+ bss->if_removed = 1;
} else {
wpa_printf(MSG_DEBUG, "RTM_DELLINK: Interface '%s' removed",
ifname);
os_strlcpy(event.interface_status.ifname, ifname,
sizeof(event.interface_status.ifname));
event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
- if (drv)
- wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
+ if (bss)
+ wpa_supplicant_event(bss->ctx, EVENT_INTERFACE_STATUS, &event);
else
wpa_supplicant_event_global(global->ctx, EVENT_INTERFACE_STATUS,
&event);
}
-static int wpa_driver_nl80211_own_ifname(struct wpa_driver_nl80211_data *drv,
+static int wpa_driver_nl80211_own_ifname(const char *ifname,
u8 *buf, size_t len)
{
int attrlen, rta_len;
rta_len = RTA_ALIGN(sizeof(struct rtattr));
while (RTA_OK(attr, attrlen)) {
if (attr->rta_type == IFLA_IFNAME) {
- if (os_strcmp(((char *) attr) + rta_len,
- drv->first_bss->ifname) == 0)
+ if (os_strcmp(((char *) attr) + rta_len, ifname) == 0)
return 1;
else
break;
}
-static int wpa_driver_nl80211_own_ifindex(struct wpa_driver_nl80211_data *drv,
+static int wpa_driver_nl80211_own_ifindex(struct i802_bss *bss,
int ifindex, u8 *buf, size_t len)
{
- if (drv->ifindex == ifindex)
+ if (bss->ifindex == ifindex)
return 1;
- if (drv->if_removed && wpa_driver_nl80211_own_ifname(drv, buf, len)) {
- nl80211_check_global(drv->global);
+ if (bss->if_removed &&
+ wpa_driver_nl80211_own_ifname(bss->ifname, buf, len)) {
+ struct wpa_driver_nl80211_data *drv = bss->drv;
+
+ if (drv->first_bss == bss)
+ nl80211_check_global(drv->global);
+
wpa_printf(MSG_DEBUG, "nl80211: Update ifindex for a removed "
"interface");
- del_ifidx(drv, drv->ifindex, IFIDX_ANY);
- if (wpa_driver_nl80211_finish_drv_init(drv, NULL, 0, NULL,
+ del_ifidx(drv, bss->ifindex, IFIDX_ANY);
+ if (wpa_driver_nl80211_finish_drv_init(bss, NULL, NULL,
WPA_P2P_MODE_WFD_R1) < 0)
return -1;
return 1;
}
-static struct wpa_driver_nl80211_data *
-nl80211_find_drv(struct nl80211_global *global, int idx, u8 *buf, size_t len,
+static struct i802_bss *
+nl80211_find_bss(struct nl80211_global *global, int idx, u8 *buf, size_t len,
int *init_failed)
{
struct wpa_driver_nl80211_data *drv;
*init_failed = 0;
dl_list_for_each(drv, &global->interfaces,
struct wpa_driver_nl80211_data, list) {
- res = wpa_driver_nl80211_own_ifindex(drv, idx, buf, len);
- if (res < 0) {
- wpa_printf(MSG_DEBUG,
- "nl80211: Found matching own interface, but failed to complete reinitialization");
- if (init_failed)
- *init_failed = 1;
- return drv;
+ struct i802_bss *bss;
+
+ for (bss = drv->first_bss; bss; bss = bss->next) {
+ res = wpa_driver_nl80211_own_ifindex(bss, idx, buf,
+ len);
+ if (res < 0) {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: Found matching own interface, but failed to complete reinitialization");
+ if (init_failed)
+ *init_failed = 1;
+ return bss;
+ }
+ if (res > 0)
+ return bss;
}
- if (res > 0 || nl80211_has_ifidx(drv, idx, IFIDX_ANY))
- return drv;
}
return NULL;
}
u8 *buf, size_t len)
{
struct nl80211_global *global = ctx;
- struct wpa_driver_nl80211_data *drv;
+ struct wpa_driver_nl80211_data *drv = NULL;
+ struct i802_bss *bss = NULL;
int attrlen;
struct rtattr *attr;
u32 brid = 0;
(ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
(ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");
- drv = nl80211_find_drv(global, ifi->ifi_index, buf, len, &init_failed);
- if (!drv)
+ bss = nl80211_find_bss(global, ifi->ifi_index, buf, len, &init_failed);
+ if (!bss)
goto event_newlink;
if (init_failed)
return; /* do not update interface state */
- if (!drv->if_disabled && !(ifi->ifi_flags & IFF_UP)) {
+ drv = bss->drv;
+
+ if (!bss->if_disabled && !(ifi->ifi_flags & IFF_UP)) {
namebuf[0] = '\0';
if (if_indextoname(ifi->ifi_index, namebuf) &&
linux_iface_up(drv->global->ioctl_sock, namebuf) > 0) {
wpa_printf(MSG_DEBUG, "nl80211: Ignore interface down "
"event since interface %s is up", namebuf);
- drv->ignore_if_down_event = 0;
+ bss->ignore_if_down_event = 0;
/* Re-read MAC address as it may have changed */
nl80211_refresh_mac(drv, ifi->ifi_index, 1);
return;
}
wpa_printf(MSG_DEBUG, "nl80211: Interface down (%s/%s)",
namebuf, ifname);
- if (os_strcmp(drv->first_bss->ifname, ifname) != 0) {
- wpa_printf(MSG_DEBUG,
- "nl80211: Not the main interface (%s) - do not indicate interface down",
- drv->first_bss->ifname);
- } else if (drv->ignore_if_down_event) {
+ if (bss->ignore_if_down_event) {
wpa_printf(MSG_DEBUG, "nl80211: Ignore interface down "
"event generated by mode change");
- drv->ignore_if_down_event = 0;
+ bss->ignore_if_down_event = 0;
} else {
- drv->if_disabled = 1;
- wpa_supplicant_event(drv->ctx,
+ bss->if_disabled = 1;
+ wpa_supplicant_event(bss->ctx,
EVENT_INTERFACE_DISABLED, NULL);
/*
* part of the EVENT_INTERFACE_DISABLED handling for
* dynamic interfaces
*/
- drv = nl80211_find_drv(global, ifi->ifi_index,
- buf, len, NULL);
- if (!drv)
+ drv = NULL;
+ bss = nl80211_find_bss(global, ifi->ifi_index, buf, len,
+ &init_failed);
+ if (!bss)
return;
+
+ drv = bss->drv;
}
}
- if (drv->if_disabled && (ifi->ifi_flags & IFF_UP)) {
+ if (bss->if_disabled && (ifi->ifi_flags & IFF_UP)) {
namebuf[0] = '\0';
if (if_indextoname(ifi->ifi_index, namebuf) &&
linux_iface_up(drv->global->ioctl_sock, namebuf) == 0) {
}
wpa_printf(MSG_DEBUG, "nl80211: Interface up (%s/%s)",
namebuf, ifname);
- if (os_strcmp(drv->first_bss->ifname, ifname) != 0) {
- wpa_printf(MSG_DEBUG,
- "nl80211: Not the main interface (%s) - do not indicate interface up",
- drv->first_bss->ifname);
- } else if (if_nametoindex(drv->first_bss->ifname) == 0) {
+ if (if_nametoindex(bss->ifname) == 0) {
wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
"event since interface %s does not exist",
- drv->first_bss->ifname);
- } else if (drv->if_removed) {
+ bss->ifname);
+ } else if (bss->if_removed) {
wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
"event since interface %s is marked "
- "removed", drv->first_bss->ifname);
+ "removed", bss->ifname);
} else {
/* Re-read MAC address as it may have changed */
nl80211_refresh_mac(drv, ifi->ifi_index, 0);
- drv->if_disabled = 0;
- wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED,
+ bss->if_disabled = 0;
+ wpa_supplicant_event(bss->ctx, EVENT_INTERFACE_ENABLED,
NULL);
}
}
* fails. This will hit us when wpa_supplicant does not need to do
* IEEE 802.1X authentication
*/
- if (drv->operstate == 1 &&
+ if (bss->operstate == 1 &&
(ifi->ifi_flags & (IFF_LOWER_UP | IFF_DORMANT)) == IFF_LOWER_UP &&
!(ifi->ifi_flags & IFF_RUNNING)) {
wpa_printf(MSG_DEBUG, "nl80211: Set IF_OPER_UP again based on ifi_flags and expected operstate");
- netlink_send_oper_ifla(drv->global->netlink, drv->ifindex,
+ netlink_send_oper_ifla(drv->global->netlink, bss->ifindex,
-1, IF_OPER_UP);
}
event_newlink:
if (ifname[0])
- wpa_driver_nl80211_event_newlink(global, drv, ifi->ifi_index,
+ wpa_driver_nl80211_event_newlink(global, bss, ifi->ifi_index,
ifname);
- if (ifi->ifi_family == AF_BRIDGE && brid && drv) {
- struct i802_bss *bss;
-
+ if (ifi->ifi_family == AF_BRIDGE && brid && drv && bss) {
/* device has been added to bridge */
if (!if_indextoname(brid, namebuf)) {
wpa_printf(MSG_DEBUG,
brid, namebuf);
add_ifidx(drv, brid, ifi->ifi_index);
- for (bss = drv->first_bss; bss; bss = bss->next) {
- if (os_strcmp(ifname, bss->ifname) == 0) {
- os_strlcpy(bss->brname, namebuf, IFNAMSIZ);
- break;
- }
- }
+ if (os_strcmp(ifname, bss->ifname) == 0)
+ os_strlcpy(bss->brname, namebuf, IFNAMSIZ);
}
}
u8 *buf, size_t len)
{
struct nl80211_global *global = ctx;
- struct wpa_driver_nl80211_data *drv;
+ struct wpa_driver_nl80211_data *drv = NULL;
+ struct i802_bss *bss = NULL;
int attrlen;
struct rtattr *attr;
u32 brid = 0;
(ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
(ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");
- drv = nl80211_find_drv(global, ifi->ifi_index, buf, len, NULL);
+ bss = nl80211_find_bss(global, ifi->ifi_index, buf, len, NULL);
+ if (bss)
+ drv = bss->drv;
if (ifi->ifi_family == AF_BRIDGE && brid && drv) {
/* device has been removed from bridge */
}
if (ifi->ifi_family != AF_BRIDGE || !brid)
- wpa_driver_nl80211_event_dellink(global, drv, ifi->ifi_index,
+ wpa_driver_nl80211_event_dellink(global, bss, ifi->ifi_index,
ifname);
}
if (nl80211_init_bss(bss))
goto failed;
- if (wpa_driver_nl80211_finish_drv_init(drv, set_addr, 1, driver_params,
+ if (wpa_driver_nl80211_finish_drv_init(bss, set_addr, driver_params,
p2p_mode))
goto failed;
static int
-wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
- const u8 *set_addr, int first,
+wpa_driver_nl80211_finish_drv_init(struct i802_bss *bss, const u8 *set_addr,
const char *driver_params,
enum wpa_p2p_mode p2p_mode)
{
- struct i802_bss *bss = drv->first_bss;
+ struct wpa_driver_nl80211_data *drv = bss->drv;
int send_rfkill_event = 0;
enum nl80211_iftype nlmode;
+ bool first = drv->first_bss == bss;
- drv->ifindex = if_nametoindex(bss->ifname);
- bss->ifindex = drv->ifindex;
+ bss->ifindex = if_nametoindex(bss->ifname);
+ if (first)
+ drv->ifindex = bss->ifindex;
bss->wdev_id = drv->global->if_add_wdevid;
bss->wdev_id_set = drv->global->if_add_wdevid_set;
bss->if_dynamic = drv->ifindex == drv->global->if_add_ifindex;
bss->if_dynamic = bss->if_dynamic || drv->global->if_add_wdevid_set;
- drv->global->if_add_wdevid_set = 0;
+ if (first)
+ drv->global->if_add_wdevid_set = 0;
if (!bss->if_dynamic && nl80211_get_ifmode(bss) == NL80211_IFTYPE_AP)
bss->static_ap = 1;
if (first &&
nl80211_get_ifmode(bss) != NL80211_IFTYPE_P2P_DEVICE &&
linux_iface_up(drv->global->ioctl_sock, bss->ifname) > 0)
- drv->start_iface_up = 1;
+ bss->start_iface_up = 1;
- if (wpa_driver_nl80211_capa(drv))
+ if (first && wpa_driver_nl80211_capa(drv))
return -1;
if (driver_params && nl80211_set_param(bss, driver_params) < 0)
else
nlmode = NL80211_IFTYPE_STATION;
- if (wpa_driver_nl80211_set_mode(bss, nlmode) < 0) {
+ if (first && wpa_driver_nl80211_set_mode(bss, nlmode) < 0) {
wpa_printf(MSG_ERROR, "nl80211: Could not configure driver mode");
return -1;
}
wpa_printf(MSG_DEBUG, "nl80211: Could not yet enable "
"interface '%s' due to rfkill", bss->ifname);
if (nlmode != NL80211_IFTYPE_P2P_DEVICE)
- drv->if_disabled = 1;
+ bss->if_disabled = 1;
send_rfkill_event = 1;
}
if (!drv->hostapd && nlmode != NL80211_IFTYPE_P2P_DEVICE)
- netlink_send_oper_ifla(drv->global->netlink, drv->ifindex,
+ netlink_send_oper_ifla(drv->global->netlink, bss->ifindex,
1, IF_OPER_DORMANT);
if (nlmode != NL80211_IFTYPE_P2P_DEVICE) {
if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
bss->addr))
return -1;
- os_memcpy(drv->perm_addr, bss->addr, ETH_ALEN);
+ if (first)
+ os_memcpy(drv->perm_addr, bss->addr, ETH_ALEN);
}
- if (send_rfkill_event) {
+ if (send_rfkill_event)
eloop_register_timeout(0, 0, wpa_driver_nl80211_send_rfkill,
- drv, drv->ctx);
- }
+ drv, bss->ctx);
if (drv->vendor_cmd_test_avail)
qca_vendor_test(drv);
if (drv->disabled_11b_rates)
nl80211_disable_11b_rates(drv, drv->ifindex, 0);
- netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, 0,
+ netlink_send_oper_ifla(drv->global->netlink, bss->ifindex, 0,
IF_OPER_UP);
eloop_cancel_timeout(wpa_driver_nl80211_send_rfkill, drv, drv->ctx);
rfkill_deinit(drv->rfkill);
- eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, bss->ctx);
+ eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
- if (!drv->start_iface_up)
+ if (!bss->start_iface_up)
(void) i802_set_iface_flags(bss, 0);
if (drv->addr_changed) {
wpa_printf(MSG_DEBUG, "nl80211: Mode change succeeded while "
"interface is down");
drv->nlmode = nlmode;
- drv->ignore_if_down_event = 1;
+ bss->ignore_if_down_event = 1;
}
/* Bring the interface back up */
struct wpa_driver_nl80211_data *drv = bss->drv;
wpa_printf(MSG_DEBUG, "nl80211: Set %s operstate %d->%d (%s)",
- bss->ifname, drv->operstate, state,
+ bss->ifname, bss->operstate, state,
state ? "UP" : "DORMANT");
- drv->operstate = state;
- return netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, -1,
+ bss->operstate = state;
+ return netlink_send_oper_ifla(drv->global->netlink, bss->ifindex, -1,
state ? IF_OPER_UP : IF_OPER_DORMANT);
}
drv->phyname,
MAC2STR(drv->perm_addr),
drv->ifindex,
- drv->operstate,
+ bss->operstate,
scan_state_str(drv->scan_state),
MAC2STR(drv->auth_bssid),
MAC2STR(drv->auth_attempt_bssid),
drv->assoc_freq,
drv->last_mgmt_freq,
drv->eapol_tx_sock,
- drv->ignore_if_down_event ?
+ bss->ignore_if_down_event ?
"ignore_if_down_event=1\n" : "",
drv->scan_complete_events ?
"scan_complete_events=1\n" : "",