netdev: Allow reassociation if not currently connected

Allow attempts to connect to a new AP using the Reassociation frame even
if netdev->operational is false.  This is needed if we want to continue
an ongoing roam attempt after the original connection broke and will be
needed when we start using cached PMKSAs in the future.
This commit is contained in:
Andrew Zaborowski 2017-08-14 14:31:19 +02:00 committed by Denis Kenzior
parent a4edbbd429
commit 6e03933e62
3 changed files with 17 additions and 13 deletions

View File

@ -100,6 +100,9 @@ static struct l_queue *device_list;
static void device_roam_timeout_rearm(struct device *device, int seconds);
static void device_netdev_event(struct netdev *netdev, enum netdev_event event,
void *user_data);
uint32_t device_watch_add(device_watch_func_t func,
void *userdata, device_destroy_func_t destroy)
{
@ -807,8 +810,9 @@ static void device_transition_reassociate(struct device *device,
struct scan_bss *bss,
struct handshake_state *new_hs)
{
if (netdev_reassociate(device->netdev, bss, new_hs,
device_reassociate_cb) < 0) {
if (netdev_reassociate(device->netdev, bss, device->connected_bss,
new_hs, device_netdev_event,
device_reassociate_cb, device) < 0) {
handshake_state_free(new_hs);
device_roam_failed(device);

View File

@ -2187,7 +2187,9 @@ int netdev_disconnect(struct netdev *netdev,
}
int netdev_reassociate(struct netdev *netdev, struct scan_bss *target_bss,
struct handshake_state *hs, netdev_connect_cb_t cb)
struct scan_bss *orig_bss, struct handshake_state *hs,
netdev_event_func_t event_filter,
netdev_connect_cb_t cb, void *user_data)
{
struct l_genl_msg *cmd_connect;
struct handshake_state *old_hs;
@ -2195,11 +2197,8 @@ int netdev_reassociate(struct netdev *netdev, struct scan_bss *target_bss,
bool is_rsn = hs->own_ie != NULL;
int err;
if (!netdev->operational)
return -ENOTCONN;
cmd_connect = netdev_build_cmd_connect(netdev, target_bss, hs,
netdev->handshake->aa);
orig_bss->addr);
if (!cmd_connect)
return -EINVAL;
@ -2210,12 +2209,11 @@ int netdev_reassociate(struct netdev *netdev, struct scan_bss *target_bss,
old_hs = netdev->handshake;
err = netdev_connect_common(netdev, cmd_connect, target_bss, hs, sm,
netdev->event_filter, cb,
netdev->user_data);
event_filter, cb, user_data);
if (err < 0)
return err;
memcpy(netdev->prev_bssid, old_hs->aa, ETH_ALEN);
memcpy(netdev->prev_bssid, orig_bss->addr, ETH_ALEN);
netdev->operational = false;
@ -2238,7 +2236,8 @@ int netdev_reassociate(struct netdev *netdev, struct scan_bss *target_bss,
if (old_sm)
eapol_sm_free(old_sm);
handshake_state_free(old_hs);
if (old_hs)
handshake_state_free(old_hs);
return err;
}

View File

@ -101,8 +101,9 @@ int netdev_connect_wsc(struct netdev *netdev, struct scan_bss *bss,
int netdev_disconnect(struct netdev *netdev,
netdev_disconnect_cb_t cb, void *user_data);
int netdev_reassociate(struct netdev *netdev, struct scan_bss *target_bss,
struct handshake_state *hs,
netdev_connect_cb_t cb);
struct scan_bss *orig_bss, struct handshake_state *hs,
netdev_event_func_t event_filter,
netdev_connect_cb_t cb, void *user_data);
int netdev_fast_transition(struct netdev *netdev, struct scan_bss *target_bss,
netdev_connect_cb_t cb);
int netdev_preauthenticate(struct netdev *netdev, struct scan_bss *target_bss,