interface_added expects mirror_8021x_connection() to return the pointer to
the existing connection if one exists, and NULL on error, rather than
NULL if a conneciton exists. While touching that, add logic to return
specifically a connection with EAP method set to 'external' if one
exists even though this should not affect any other logic we have
currently.
Some internal logic causes the secrets in a connection to be
occasionally moved to NMSettingConnection's priv->system_secrets after a
connection attempt so we need to use nm_act_request_get_secrets to get
them added to the device's settings connection and applied connection if
the PSK is missing during an AP or AdHoc mode activation (in
infrastructure mode we already do secret requests though they're cached
by IWD in most cases).
The common steps for the PSK available and unavailable scenarios is moved
from act_stage2_config to act_set_mode.
This simplifies the code by using g_variant_lookup. In this handler
where we parse more than one property this is probably slower although
the number of string comparisons will be the same.
This flag is more granular in whether to consider the connection
available or not. We probably should never check for the combined
flag NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST directly, but
always explicitly for the relevant parts.
Also, improve the error message, to indicate whether the device is
strictly unmanaged or whether it could be overruled.
The flags NMDeviceCheckConAvailableFlags and NMDeviceCheckDevAvailableFlags
both control whether a device appears available (either, available in
general, or related to a particular profile).
Also, both flag types strictly increase availability. Meaning: more flags,
more available.
There is some overlap between the flags, however they still have
their own distinct parts.
Improve the mapping from NMDeviceCheckConAvailableFlags to
NMDeviceCheckDevAvailableFlags, by picking exactly the flags
that are relevant.
- fix stopping ppp-manager. Previously, we would take a reference
to priv->ppp_manager to cancel it later. However, deactivate_cleanup()
is called first, which already issues nm_ppp_manager_stop().
Thereby, not using a callback and not waiting for the operation
to complete.
- get rid of this "step" state machine. There are litterally two steps
that need to be performed asynchornously. Instead chain the calls.
- it is now obviously visible, that the async callback never completes
synchronously upon being called (provided that all async operations
that it calls themself have this behavior -- which they should).
Previously nm_ppp_manager_stop() would return a handle which
makes it easy to cancel the operation.
However, sometimes, we may want to cancel an operation based on
an GCancellable. So, extend nm_ppp_manager_stop() to hook it
with a cancellable.
Essentially, move the code from nm-modem.c to nm-ppp-manager-call.c,
where it belongs and where the functionality gets available to every
component.
We should not use GAsyncResult. At least, not for internal API.
It's more cumbersome then helpful, in my opinion. It requires
this awkward async_finish() pattern.
Instead, let the caller pass a suitable callback of the right type.
All operations must be cancellable in a timely manner, otherwise, the objects
hang during shutdown.
Also, get rid of the GAsyncResult pattern. It is more cumbersome than
helpful.
There are still several issues, marked by FIXME comments.
When the client terminates, we really don't care if it exited cleanly,
with an error or killed by a signal. We expect the client to never
exit and so all these situations are equally bad for us. Introduce a
new TERMINATED state instead of reusing existing FAIL or DONE states,
which are set when receiving particular events from the client.
The @was_active flag indicates that we started DHCP on an assumed
connection. The idea is that if DHCP succeeded before, any failure
must be treated like a renewal failure (and so it should start a grace
period) rather than a failure in getting an initial lease (which fails
the IP method).
When we clean up the DHCP instance, the flag must be reset to FALSE,
otherwise it will be potentially considered for other connections.
The effect of a DHCPv6 failure should depend only on current IP state.
This in the analogous of commit bd63d39252 ("dhcp: fix handling of
failure events") for IPv6.
We're hooking the signal on construction, but we only queue a pending
action on reaching UNAVAILABLE state. The signal could fire in between:
<info> [1539282167.9666] manager: (msh0): new 802.11 OLPC Mesh device (/org/freedesktop/NetworkManager/Devices/4)
<info> [1539282168.1440] manager: (wlan0): new 802.11 WiFi device (/org/freedesktop/NetworkManager/Devices/5)
<info> [1539282168.1831] device (msh0): found companion WiFi device wlan0
<warn> [1539282168.2110] device (msh0): remove_pending_action (1): 'waiting-for-companion' not pending
file src/devices/nm-device.c: line 13966 (<dropped>): should not be reached
https://github.com/NetworkManager/NetworkManager/pull/229
Instead of walking through the list all known networks and comparing
name & SSIDs to judge whether a network is an IWD KnownNetwork, look at
the Network.KnownNetwork pre-IWD-0.8 property.
Ensure priv->can_connect is up to date on IWD state changed. If we
exited the function early priv->can_connect would sometimes be wrongly
TRUE and we'd start a new autoconnect too early after IP configuration
had failed for example.
Handle AP mode connections by setting the Mode property on IWD's Device
interface to "ap" (which will make the Station interface go away, the
Powered property -- normally controlled by set_enabled -- to switch to
FALSE and back to TRUE, and then the AccessPoint interface to appear)
and then calling the AccessPoint.Start method. This is all done in the
CONFIG phase in NM. We also attempt to always set Mode back to
"station" and wait for the Station interface to reappear before going to
the NM DISCONNECTED state. All this complicates the code a little.
While making the necessary changes simplify a lot of the checks which
are implied by other things we've checked already, for example
priv->can_scan and priv->can_connect can now only be TRUE when device is
powered up and in station mode (Station interface is present) so we can
skip other checks. Also assume that check_connection_compatible has
been called before other methods are called so we can skip multiple
connection mode checks and checks that a IWD KnownNetwork exsists for
EAP connections.
act_stage1_prepare and act_stage2_config now borrow more code from
nm-device-wifi.c because both backend now handle multiple modes.
Use nm_utils_error_is_cancelled instead of checking
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED), set
consider_is_disposing false. Also use the DBUS_INTERFACE_PROPERTIES
macro.
Make sure we g_variant_unref() the values returned from
g_dbus_proxy_call_finish. In get_ordered_networks_cb also make sure we
don't access the NMDeviceIwd data until after we know the call has not
been cancelled. Switch from _nm_dbus_proxy_call_finish to
g_dbus_proxy_call_finish where we don't care about the variant type
returned.
Only call nm_platform_wifi_get_capabilities and
nm_platform_wifi_get_mode with the wpa_supplicant backend. They're used
to initialize the wireless-capabilities property and to skip creating
NMDevices for interfaces in unknown wifi mode which IWD handles already.
Under valgrind, we cannot create an NAcd instance.
--10916-- WARNING: unhandled amd64-linux syscall: 321
--10916-- You may be able to write your own handler.
--10916-- Read the file README_MISSING_SYSCALL_OR_IOCTL.
--10916-- Nevertheless we consider this a bug. Please report
--10916-- it at http://valgrind.org/support/bug_reports.html.
This limitation already poses a problem, because running NetworkManager
under valgrind might fail. However, for tests it doesn't matter and we
can just skip them.
See the logfile at [1], for how NetworkManager first attempts to connect
using WPS (which takes about 30 seconds). However, early on, the user logs
into KDE and a secret agent would register, which possibly could provide
secrets to connect. I think it is problematic to wait for WPS (which is
unlikely to succeed) if a secret agent shows up in the meantime.
A possible fix would be that when
- WPS is pending
- the secret request already failed
- another secret-agent registers
then the activation (and WPS) is aborted and autoconnect may be tried
again, possibly with secrets provided by the new secret-agent.
However, this patch goes a step further: it always cancels activation
when the secret request fails. That means, WPS only works while the
user is also prompted for a secret. That makes sense to me, because
an action from the user is required. However, without secret prompt,
the user wouldn't be aware of that and is unlikely to press the WPS
push botton.
[1] https://bugzilla.opensuse.org/show_bug.cgi?id=1079672#c33https://github.com/NetworkManager/NetworkManager/pull/216
We already have nm_utils_bin2hexstr() and _nm_utils_bin2hexstr_full().
This is confusing.
- nm_utils_bin2hexstr() is public API of libnm. Also, it has
a last argument @final_len to truncate the string at that
length.
It uses no delimiter and lower-case characters.
- _nm_utils_bin2hexstr_full() does not do any truncation, but
it has options to specify a delimiter, the character case,
and to update a given buffer in-place. Also, like
nm_utils_bin2hexstr() and _nm_utils_bin2hexstr() it can
allocate a new buffer on demand.
- _nm_utils_bin2hexstr() would use ':' as delimiter and make
the case configurable. Also, it would always allocate the returned
buffer.
It's too much and confusing. Drop _nm_utils_bin2hexstr() which is internal
API and just a wrapper around _nm_utils_bin2hexstr_full().
NMAcdManager is a rather simple instance.
It does not need (thread-safe) ref-counting, in fact, having
it ref-counted makes it slighly ugly that we connect a signal,
but never bother to disconnect it (while the ref-counted instance
could outlife the signal subscriber).
We also don't need GObject signals. They have more overhead
and are less type-safe than a regular function pointers. Signals
would make sense, if there could be multiple independent listeners,
but that just doesn't make sense.
Implementing it as a plain struct is less lines of code, and less
runtime over head.
Also drop the possiblitiy to reset the NMAcdManager instance.
It wasn't needed and I think it was buggy because it wouldn't
reset the n-acd instance.
https://github.com/NetworkManager/NetworkManager/pull/213
Kernel complains with:
platform-linux: link: change 10: token: set IPv6 address generation token to ::bbbb
platform-linux: do-change-link[10]: failure changing link: failure 22 (Invalid argument)
if we try to set an IPv6 token in ip_config_merge_and_apply() and we
haven't set accept_ra=1 yet. Since the flag is set when starting
router discovery, ensure that we don't try to set a token before that.
https://github.com/NetworkManager/NetworkManager/pull/214https://bugzilla.redhat.com/show_bug.cgi?id=1560652
The net.connman.iwd.Station interface, unlike the Device interface, can
go away and come back when the device changes modes or goes DOWN and UP.
The GDbusProxy for the interface becomes invalid after the interface
disappeared and reappeared. This would make the IWD backend stop
working after rfkill was used or after suspend/resume (provided the
suspend/resume events are detected, without them everything works and is
really fast too).
Redo the handling of the Powered property changes, corresponding to
device UP state, to get a new GDBusProxy when the Station interface
reappears. Simplify some checks knowing that priv->can_scan implies for
example that the Station interface is present, and that priv->enabled
implies the NM device state is >= DISCONNECTED.
https://github.com/NetworkManager/NetworkManager/pull/211
When there are profiles with wifi.hidden=yes, NetworkManager
will actively scan for these SSIDs. This makes the scan request
(and thus the user) recognizable and trackable.
It seems generally a bad idea to use hidden networks, as they
compromise either the privacy or usablity for the clients.
Log a (rate-limited) warning about this.
In update update_ext_ip_config() we remove from various internal
configurations those addresses and routes that were removed externally
by users.
When the interface is brought down, the kernel automatically removes
routes associated with it and so we should not consider them as
"removed by users".
Instead, keep them so that they can be restored when the interface
comes up again.
device_link_changed() can't use nm_device_update_from_platform_link()
to update the device private fields because the latter overwrites
priv->iface and priv->up, and so the checks below as:
if (info.name[0] && strcmp (priv->iface, info.name) != 0) {
and:
was_up = priv->up;
priv->up = NM_FLAGS_HAS (info.n_ifi_flags, IFF_UP);
...
if (priv->up && !was_up) {
never succeed.
Fixes: d7f7725ae8
Nothing changes practically, as the NMDevice still starts this with
AF_UNSPEC. That is going to change in the following commit.
The ugly part:
priv->concheck_x[0] in few places. I believe we shouldn't be using union
aliasing here, and instead of indexing the v4/v6 arrays by a boolean it
should be an enum. I'm not fixing it here, but I eventually plan to if
this gets an ACK.
This allows us to use the correct DNS server for the particular interface
independent of what the system resolver is configured to use.
The ugly part:
Unfortunately, it is not all that easy. The libc's libresolv.so API does
not provide means for influencing neither interface nor name servers used
for DNS resolving.
Curl can also be compiled with c-ares resolver backend that does provide
the necessary functionality, but it requires and extra library and the
Linux distributions don't seem to enable it. (Fedora doesn't, which is a
good sign we don't have an option of relying on it.)
systemd-resolved does provide everything we need. If we take care to
keep its congfiguration up to date, we can use it to do the resolving on
a particular interface with that interface's DNS configuration. Great!
There's one more problem: Curl doesn't provide callbacks for resolving
host names. It doesn't, however, allow us to pass in the pre-resolved
hostnames in form of an CURLOPT_RESOLVE(3) option. This means we have to
parse the host name out of the URL ourselves. Fair enough I guess...