3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-11-13 23:49:23 +01:00
Commit Graph

202 Commits

Author SHA1 Message Date
James Prestwood
694ccf62d0 station: add Roam() diagnostics method
This is being added as a developer method and should not be used
in production. For testing purposes though, it is quite useful as
it forces IWD to roam to a provided BSS and bypasses IWD's roaming
and ranking logic for choosing a roam candidate.

To use this a BSSID is provided as the only parameter. If this
BSS is not in IWD's current scan results -EINVAL will be returned.
If IWD knows about the BSS it will attempt to roam to it whether
that is via FT, FT-over-DS, or Reassociation. These details are
still sorted out in IWDs station_transition_start() logic.
2021-05-07 08:45:42 -05:00
James Prestwood
a3906272cc station: print reason why autoconnect failed 2021-05-04 10:30:55 -05:00
James Prestwood
1b5a58233c station: separate FT-over-DS stages
FT-over-DS was refactored to separate the FT action frame and
reassociation. From stations standpoint IWD needs to call
netdev_fast_transition_over_ds_action prior to actually roaming.
For now these two stages are being combined and the action
roam happens immediately after the action response callback.
2021-04-30 13:09:13 -05:00
James Prestwood
0531e9ab08 station: remove diagnostic interface on station_free
If station gets removed ungracefully (e.g. rfkill/hotplug) it
may not have a chance to disconnect, meaning the diagnostic
interface would remain up.
2021-04-28 14:46:16 -05:00
James Prestwood
3b3f6d33fe station: tie diagnostic interface cleanup to DISCONNECTING
Prior to this the diagnostic interface was taken down when station
transitioned to DISCONNECTED. This worked but once station is in
a DISCONNECTING state it then calls netdev_disconnect(). Trying to
get any diagnostic data during this time may not work as its
unknown what state exactly the kernel is in. To be safe take the
interface down when station is DISCONNECTING.
2021-04-28 14:31:33 -05:00
Denis Kenzior
a0911ca778 station: Make sure roam_scan_id is always canceled
Under very rare circumstances the roaming scan triggered might not be
canceled properly.  This is because we issue the roam scan recursively
from within a scan callback and re-use the id of the scan for the
subsequent request.  The destroy callback is invoked right after the
callback and resets the id.  This leads to the scan not being canceled
properly in roam_state_clear().

src/netdev.c:netdev_mlme_notify() MLME notification Notify CQM(64)
src/station.c:station_roam_trigger_cb() 37
src/station.c:station_roam_scan() ifindex: 37
src/station.c:station_roam_trigger_cb() Using cached neighbor report for roam
...
src/scan.c:get_scan_done() get_scan_done
src/station.c:station_roam_failed() 37
src/station.c:station_roam_scan() ifindex: 37
src/scan.c:scan_request_triggered() Active scan triggered for wdev 22
^CTerminate
src/netdev.c:netdev_free() Freeing netdev wlan0[37]
src/device.c:device_free()
src/station.c:station_free()
...
Removing scan context for wdev 22
src/scan.c:scan_context_free() sc: 0x4a362a0
src/wiphy.c:wiphy_radio_work_done() Work item 14 done
==19542== Invalid write of size 4
==19542==    at 0x411500: station_roam_scan_destroy (station.c:2010)
==19542==    by 0x420B5B: scan_request_free (scan.c:156)
==19542==    by 0x410BAC: destroy_work (wiphy.c:294)
==19542==    by 0x410BAC: wiphy_radio_work_done (wiphy.c:1613)
==19542==    by 0x46C66E: l_queue_clear (queue.c:107)
==19542==    by 0x46C6B8: l_queue_destroy (queue.c:82)
==19542==    by 0x420BAE: scan_context_free (scan.c:205)
==19542==    by 0x424135: scan_wdev_remove (scan.c:2272)
==19542==    by 0x408754: netdev_free (netdev.c:847)
==19542==    by 0x40E18C: netdev_shutdown (netdev.c:5773)
==19542==    by 0x404756: iwd_shutdown (main.c:78)
==19542==    by 0x404756: iwd_shutdown (main.c:65)
==19542==    by 0x470E21: handle_callback (signal.c:78)
==19542==    by 0x470E21: signalfd_read_cb (signal.c:104)
==19542==    by 0x47166B: io_callback (io.c:120)
==19542==  Address 0x4d81f98 is 200 bytes inside a block of size 288 free'd
==19542==    at 0x48399CB: free (vg_replace_malloc.c:538)
==19542==    by 0x47F3E5: interface_instance_free (dbus-service.c:510)
==19542==    by 0x481DEA: _dbus_object_tree_remove_interface (dbus-service.c:1694)
==19542==    by 0x481F1C: _dbus_object_tree_object_destroy (dbus-service.c:795)
==19542==    by 0x40894F: netdev_free (netdev.c:844)
==19542==    by 0x40E18C: netdev_shutdown (netdev.c:5773)
==19542==    by 0x404756: iwd_shutdown (main.c:78)
==19542==    by 0x404756: iwd_shutdown (main.c:65)
==19542==    by 0x470E21: handle_callback (signal.c:78)
==19542==    by 0x470E21: signalfd_read_cb (signal.c:104)
==19542==    by 0x47166B: io_callback (io.c:120)
==19542==    by 0x47088C: l_main_iterate (main.c:478)
==19542==    by 0x47095B: l_main_run (main.c:525)
==19542==    by 0x47095B: l_main_run (main.c:507)
==19542==    by 0x470B6B: l_main_run_with_signal (main.c:647)
==19542==  Block was alloc'd at
==19542==    at 0x483879F: malloc (vg_replace_malloc.c:307)
==19542==    by 0x46AB2D: l_malloc (util.c:62)
==19542==    by 0x416599: station_create (station.c:3448)
==19542==    by 0x406D55: netdev_newlink_notify (netdev.c:5324)
==19542==    by 0x46D4BC: l_hashmap_foreach (hashmap.c:612)
==19542==    by 0x472F46: process_broadcast (netlink.c:158)
==19542==    by 0x472F46: can_read_data (netlink.c:279)
==19542==    by 0x47166B: io_callback (io.c:120)
==19542==    by 0x47088C: l_main_iterate (main.c:478)
==19542==    by 0x47095B: l_main_run (main.c:525)
==19542==    by 0x47095B: l_main_run (main.c:507)
==19542==    by 0x470B6B: l_main_run_with_signal (main.c:647)
==19542==    by 0x403EDB: main (main.c:490)
==19542==
2021-04-28 13:15:45 -05:00
James Prestwood
9d9c516596 wiphy: add fils_hint to wiphy_can_connect
A prior commit refactored the AKM selection in wiphy.c. This
ended up breaking FILS tests due to the hard coding of a
false fils_hint in wiphy_select_akm. Since our FILS tests
only advertise FILS AKMs wiphy_can_connect would return false
for these networks.

Similar to wiphy_select_akm, add a fils hint parameter to
wiphy_can_connect and pass that down directly to wiphy_select_akm.
2021-04-27 14:48:23 -05:00
James Prestwood
bba47527d3 station: update to use network_has_erp_identity 2021-04-27 14:48:09 -05:00
Denis Kenzior
4a1dafb907 station: Move AP directed roam watch to station
Logically this frame watch belongs in station.  It was kept in device.c
for the purported reason that the station object was removed with
ifdown/ifup changes and hence the frame watch might need to be removed
and re-added unnecessarily.  Since the kernel does not actually allow to
unregister a frame watch (only when the netdev is removed or its iftype
changes), re-adding a frame watch might trigger a -EALREADY or similar
error.

Avoid this by registering the frame watch when a new netdev is detected
in STATION mode, or when the interface type changes to STATION.
2021-04-23 09:51:46 -05:00
Denis Kenzior
ca085d799d station: Do not set or use the offload bit
station should be isolated as much as possible from the details of the
driver type and how a particular AKM is handled under the hood.  It will
be up to wiphy to pick the best AKM for a given bss.  netdev in turn
will pick how to drive the particular AKM that was picked.
2021-03-31 11:27:10 -05:00
James Prestwood
28a7dd7fba station: get neighbor report after roaming
In the same vein as requesting a neighbor report after
connecting for the first time, it should also be done
after a roam to obtain the latest neighbor information.
2021-03-29 14:12:02 -05:00
James Prestwood
9b682d43db station: unify firmware/normal roaming
This doesn't change much functionally but does unify the
two roaming paths by ending with 'station_roamed()'.
2021-03-29 14:11:45 -05:00
James Prestwood
21e95dd2d8 station: clear out roam frequencies after roam 2021-03-29 14:11:37 -05:00
James Prestwood
c2330c5332 station: add Security key to GetDiagnostics 2021-03-29 13:18:01 -05:00
Denis Kenzior
e730baac4a station: Make sure to reset scanning property
When we cancel a quick scan that has already been triggered, the
Scanning property is never reset to false.  This doesn't fully reflect
the actual scanning state of the hardware since we don't (yet) abort
the scan, but at least corrects the public API behavior.

{Network} [/net/connman/iwd/0/7/73706733_psk] Connected = False
{Station} [/net/connman/iwd/0/7] Scanning = True
{Station} [/net/connman/iwd/0/7] State = connecting
{Station} [/net/connman/iwd/0/7] ConnectedNetwork =
/net/connman/iwd/0/7/73706733_psk
{Network} [/net/connman/iwd/0/7/73706733_psk] Connected = True
2021-03-29 10:44:02 -05:00
Denis Kenzior
9a67a21bd2 station: Add a warning of rekey fails 2021-03-24 13:10:32 -05:00
James Prestwood
0b38aabde3 station: set handshake offload if required
If IWD is connecting to a SAE/WPA3 BSS and Auth/Assoc commands
are not supported the only option is SAE offload. At this point
network_connect should have verified that the extended feature
for SAE offload exists so we can simply enable offload if these
commands are not supported.
2021-03-22 14:16:31 -05:00
James Prestwood
2b5e566c9d station: use network_bss_update
This fixes a dangling pointer in network where station was
freeing the scan_bss but network still had a pointer to it
in its own bss_list.
2021-03-15 14:47:42 -05:00
James Prestwood
97de24e694 station: disable roaming logic for auto-roaming cards
If the hardware roams automatically we want to be sure to not
react to CQM events and attempt to roam/disconnect on our own.

Note: this is only important for very new kernels where CQM
events were recently added to brcmfmac.
2021-03-15 13:32:35 -05:00
James Prestwood
133347440e netdev: station: support full mac roaming
Roaming on a full mac card is quite different than soft mac
and needs to be specially handled. The process starts with
the CMD_ROAM event, which tells us the driver is already
roamed and associated with a new AP. After this it expects
the 4-way handshake to be initiated. This in itself is quite
simple, the complexity comes with how this is piped into IWD.

After CMD_ROAM fires its assumed that a scan result is
available in the kernel, which is obtained using a newly
added scan API scan_get_firmware_scan. The only special
bit of this is that it does not 'schedule' a scan but simply
calls GET_SCAN. This is treated special and will not be
queued behind any other pending scan requests. This lets us
reuse some parsing code paths in scan and initialize a
scan_bss object which ultimately gets handed to station so
it can update connected_bss/bss_list.

For consistency station must also transition to a roaming state.
Since this roam is all handled by netdev two new events were
added, NETDEV_EVENT_ROAMING and NETDEV_EVENT_ROAMED. Both allow
station to transition between roaming/connected states, and ROAMED
provides station with the new scan_bss to replace connected_bss.
2021-03-15 13:14:39 -05:00
James Prestwood
c026337792 station: move scan cancelation to __station_connect_network
An earlier patch fixed a problem where a queued quick scan would
be triggered and fail once already connected, resulting in a state
transition from connected --> autoconnect_full. This fixed the
Connect() path but this could also happen via autoconnect. Starting
from a connected state, the sequence goes:

 - DBus scan is triggered
 - AP disconnects IWD
 - State transition from disconnected --> autoconnect_quick
 - Queue quick scan
 - DBus scan results come in and used to autoconnect
 - A connect work item is inserted ahead of all others, transition
   from autoconnect_quick --> connecting.
 - Connect completes, transition from connecting --> connected
 - Quick scan can finally get triggered, which the kernel fails to
   do since IWD is connected, transition from connected -->
   autoconnect_full.

This can be fixed by checking for a pending quick scan in the
autoconnect path.
2021-02-04 20:56:34 -06:00
Denis Kenzior
0c277e442e station: Remove unneeded logic from dbus_scan_done
Commit eac2410c83 ("station: Take scanned frequencies into account")
has made it unnecessary to explicitly invoke station_set_scan_results
with the expire to true in case a dbus scan finished prematurely or a
subset was not able to be started.  Remove this no-longer needed logic.

Fixes: eac2410c83 ("station: Take scanned frequencies into account")
2021-02-03 14:39:42 -06:00
James Prestwood
c3e160880f station: only add diagnostic interface when connected
The diagnostic interface returns an error anyways if station is
not connected so it makes more sense to only bring the interface
up when its actually usable. This also removes the interface
when station disconnects, which was never done before (the
interface stayed up indefinitely due to a forgotten remove call).
2021-02-03 13:37:19 -06:00
Denis Kenzior
6ced1ec9de station: Use active scan in autoconnect mode
When we're auto-connecting and have hidden networks configured, use
active scans regardless of whether we see any hidden BSSes in our
existing scan results.

This allows us to more effectively see/connect to hidden networks
when first powering up or after suspend.
2021-02-03 13:36:36 -06:00
Denis Kenzior
73309686bd station: Use flush flag for all scans 2021-02-03 13:36:27 -06:00
Denis Kenzior
ab5fd961c8 station: Also reset the SSID when hiding
Make the SSID all zeros when hiding a network.  This makes sure that the
BSS isn't inadvertently confused for a non-hidden one
2021-02-03 13:36:19 -06:00
Denis Kenzior
9af25d937d station: Make sure bss_match also matches the ssid
Kernel might report hidden BSSes that are reported from beacon frames
separately than ones reported due to probe responses.  This may confuse
the station network collation logic since the scan_bss generated by the
probe response might be removed erroneously when processing the scan_bss
that was generated due to a beacon.

Make sure that bss_match also takes the SSID into account and only
matches scan_bss structures that have the same BSSID and SSID contents.
2021-02-03 13:36:09 -06:00
Denis Kenzior
8fd6985214 station: move filtering of non-utf8 scan_bss entries
Instead of silently ignoring entries with non-utf8 SSIDs, drop them from
the new_bss_list entirely.
2021-02-03 13:35:58 -06:00
Denis Kenzior
eac2410c83 station: Take scanned frequencies into account
Instead of manually managing whether to expire BSSes or not, use the
scanned frequency set instead.  This makes the API slightly easier to
understand (dropping two boolean arguments in a row) and also a bit more
future-proof.
2021-02-03 13:35:03 -06:00
Denis Kenzior
ccbd32503b scan: Pass the frequencies scanned to notify cb 2021-02-03 13:34:44 -06:00
James Prestwood
1c80672983 station: add Frequency to diagnostics dictionary 2021-02-03 12:54:59 -06:00
Denis Kenzior
c3f76cb5a5 station: Return NotHidden error
Commit d372d59bea checks whether a hidden network had a previous
connection attempt and re-tries.  However, it inadvertently dropped
handling of a condition where a non-hidden network SSID is provided to
ConnectHiddenNetwork.  Fix that.

Fixes: d372d59bea ("station: Allow ConnectHiddenNetwork to be retried")
2021-02-03 09:12:08 -06:00
Denis Kenzior
c319bca477 station: correctly set mac randomization hint
Now that ConnectHiddenNetwork can be invoked while we're connected, set
the mac randomization hint parameter properly.  The kernel will reject
requests if randomization is enabled while we're connected to a network.
2021-02-02 09:54:34 -06:00
Denis Kenzior
06ca8e20a9 station: Hide forgotten hidden networks
If we forget a hidden network, then make sure to remove it from the
network list completely.  Otherwise it would be possible to still
issue a Network.Connect to that particular object, but the fact that the
network is hidden would be lost.
2021-02-02 09:36:37 -06:00
Denis Kenzior
add3d43dad station: expire networks found by hidden scan sooner 2021-02-01 15:30:15 -06:00
Denis Kenzior
08a295c348 station: Fix leaking of roam_freqs on shutdown
==17639== 72 (16 direct, 56 indirect) bytes in 1 blocks are definitely
lost in loss record 3 of 3
==17639==    at 0x4C2F0CF: malloc (vg_replace_malloc.c:299)
==17639==    by 0x4670AD: l_malloc (util.c:61)
==17639==    by 0x4215AA: scan_freq_set_new (scan.c:1906)
==17639==    by 0x412A9C: parse_neighbor_report (station.c:1910)
==17639==    by 0x407335: netdev_neighbor_report_frame_event
(netdev.c:3522)
==17639==    by 0x44BBE6: frame_watch_unicast_notify (frame-xchg.c:233)
==17639==    by 0x470C04: dispatch_unicast_watches (genl.c:961)
==17639==    by 0x470C04: process_unicast (genl.c:980)
==17639==    by 0x470C04: received_data (genl.c:1101)
==17639==    by 0x46D9DB: io_callback (io.c:118)
==17639==    by 0x46CC0C: l_main_iterate (main.c:477)
==17639==    by 0x46CCDB: l_main_run (main.c:524)
==17639==    by 0x46CF01: l_main_run_with_signal (main.c:656)
==17639==    by 0x403EDE: main (main.c:490)
2021-02-01 15:12:17 -06:00
Denis Kenzior
d372d59bea station: Allow ConnectHiddenNetwork to be retried
In the case that ConnectHiddenNetwork scans successfully, but fails for
some other reason, the network object is left in the scan results until
it expires.  This will prevent subsequent attempts to use
ConnectHiddenNetwork with a .NotHidden error.  Fix that by checking
whether a found network is hidden, and if so, allow the request to
proceed.
2021-02-01 14:19:37 -06:00
Denis Kenzior
e04ae506a3 network: rework network_connect_new_hidden_network
Rework the logic slightly so that this function returns an error message
on error and NULL on success, just like other D-Bus method
implementations.  This also simplifies the code slightly.
2021-02-01 13:37:07 -06:00
Denis Kenzior
56538bf75b station: Allow ConnectHiddenNetwork while connected
We used to not allow to connect to a different network while already
connected.  One had to disconnect first.  This also applied to
ConnectHiddenNetwork calls.

This restriction can be dropped now.  station will intelligently
disconnect from the current AP when a station_connect_network() is
issued.
2021-02-01 13:37:07 -06:00
Denis Kenzior
fc10ee8745 station: Fix not cleaning up pending_connect
If the disconnect fails and station_disconnect_onconnect_cb is called
with an error, we reply to the original message accordingly.
Unfortunately pending_connect is not unrefed or cleared in this case.
Fix that.

Fixes: d0ee923dda ("station: Disconnect, if needed, on a new connection attempt")
2021-02-01 13:37:07 -06:00
James Prestwood
7b2ce98abd station: fix leak on parse_neighbor_report 2021-01-29 17:22:20 -06:00
James Prestwood
a9c32d85ea station: cancel quick scans on Connect()
At some point the non-interactive client tests began failing.
This was due to a bug in station where it would transition from
'connected' to 'autoconnect' due to a failed scan request. This
happened because a quick scan got scheduled during an ongoing
scan, then a Connect() gets issued. The work queue treats the
Connect as a priority so it delays the quick scan until after the
connection succeeds. This results in a failed quick scan which
IWD does not expect to happen when in a 'connected' state. This
failed scan actually triggers a state transition which then
gets IWD into a strange state where its connected from the
kernel point of view but does not think it is:

src/station.c:station_connect_cb() 13, result: 0
src/station.c:station_enter_state() Old State: connecting, new state: connected
src/wiphy.c:wiphy_radio_work_done() Work item 6 done
src/wiphy.c:wiphy_radio_work_next() Starting work item 5
src/station.c:station_quick_scan_triggered() Quick scan trigger failed: -95
src/station.c:station_enter_state() Old State: connected, new state: autoconnect_full

To fix this IWD should simply cancel any pending quick scans
if/when a Connect() call comes in.
2021-01-26 14:45:00 -06:00
James Prestwood
158dc40340 station: refactor to use diagnostic_info_to_dict 2021-01-22 14:59:47 -06:00
James Prestwood
5a6b474a14 netdev: move netdev_station_info to diagnostic.h
With AP now getting its own diagnostic interface it made sense
to move the netdev_station_info struct definition into its own
header which eventually can be accompanied by utilities in
diagnostic.c. These utilities can then be shared with AP and
station as needed.
2021-01-22 14:40:45 -06:00
Alvin Šipraga
4266b88658 station: add RoamRetryInterval setting 2021-01-22 13:46:25 -06:00
Alvin Šipraga
f456501b9e station: retry roaming unless notified of a high RSSI
Following a successful roaming sequence, schedule another attempt unless
the driver has sent a high RSSI notification. This makes the behaviour
analogous to a failed roaming attempt where we remained connected to the
same BSS.

This makes iwd compatible with wireless drivers which do not necessarily
send out a duplicate low RSSI notification upon reassociation. Without
this change, iwd risks getting indefinitely stuck to a BSS with low
signal strength, even though a better BSS might later become available.

In the case of a high RSSI notification, the minimum roam time will also
be reset to zero. This preserves the original behaviour in the case
where a high RSSI notification is processed after station_roamed().
Doing so also gives a chance for faster roaming action in the following
example scenario:

    1. RSSI LOW
    2. schedule roam in 5 seconds
        (5 seconds pass)
    3. try roaming
    4. roaming fails, same BSS
    5. schedule roam in 60 seconds
        (20 seconds pass)
    6. RSSI HIGH
    7. cancel scheduled roam
        (20 seconds pass)
    8. RSSI LOW
    9. schedule roam in 5 seconds or 20 seconds?

By resetting the minimum roam time, we can avoid waiting 20 seconds when
the station may have moved considerably. And since the high/low RSSI
notifications are configured with a hysteresis, we should still be
protected against too frequent spurious roaming attempts.
2021-01-22 13:41:07 -06:00
Alvin Šipraga
9edd941bc2 station: remove unused roam_no_orig_ap state variable
Since commit 836beb1276 removed beacon
loss handling, the roam_no_orig_ap variable has no use and is always set
to false. This commit removes it.
2021-01-20 11:14:06 -06:00
James Prestwood
a17e5e0f7f station: create StationDiagnostic interface
This interface sits aside the regular station interface but
provides low level connection details for diagnostic and
testing purposes.
2021-01-14 15:02:13 -06:00
Andrew Zaborowski
f5a30a1cfc station: Don't expire BSSes between freq subset scans
Add a parameter to station_set_scan_results to allow skipping the
removal of old BSSes.  In the DBus-triggered scan only expire BSSes
after having gone through the full supported frequency set.

It should be safe to pass partial scan results to
station_set_scan_results() when not expiring BSSes so using this new
parameter I guess we could also call it for roam scan results.
2020-12-17 20:22:47 -06:00
Andrew Zaborowski
e3bece76f9 station: Split DBus scans into 3 frequency subsets
A scan normally takes about 2 seconds on my dual-band wifi adapter when
connected.  The drivers will normally probe on each supported channel in
some unspecified order and will have new partial results after each step
but the kernel sends NL80211_CMD_NEW_SCAN_RESULTS only when the full
scan request finishes, and for segmented scans we will wait for all
segments to finish before calling back from scan_active() or
scan_passive().

To improve user experience define our own channel order favouring the
2.4 channels 1, 6 and 11 and probe those as an individual scan request
so we can update most our DBus org.connman.iwd.Network objects more
quickly, before continuing with 5GHz band channels, updating DBus
objects again and finally the other 2.4GHz band channels.

The overall DBus-triggered scan on my wifi adapter takes about the same
time but my measurements were not very strict, and were not very
consistent with and without this change.  With the change most Network
objects are updated after about 200ms though, meaning that I get most
of the network updates in the nm-applet UI 200ms from opening the
network list.  The 5GHz band channels take another 1 to 1.5s to scan and
remaining 2.4GHz band channels another ~300ms.

Hopefully this is similar when using other drivers although I can easily
imagine a driver that parallelizes 2.4GHz and 5GHz channel probing using
two radios, or uses 2, 4 or another number of dual-band radios to probe
2, 4, ... channels simultanously.  We'd then lose some of the
performance benefit.  The faster scan results may be worth the longer
overall scan time anyway.
I'm also assuming that the wiphy's supported frequency list is exactly
what was scanned when we passed no frequency list to
NL80211_CMD_TRIGGER_SCAN and we won't get errors for passing some
frequency that shouldn't have been scanned.
2020-12-17 20:15:37 -06:00