Commit graph

13483 commits

Author SHA1 Message Date
Andrew Zaborowski
8215340651
iwd: Update KnownNetwork.AutoConnect on NM connection changes
Watch NMSettingConnection's changes using the
NM_SETTINGS_CONNECTION_UPDATED_INTERNAL signal and update IWD
KnownNetwork's AutoConnect property when NMSettingConnection's
autoconnect property changes.

We will not receive "notify::" NM_SETTING_CONNECTION_AUTOCONNECT signals
normally because the NMConnection seems to be replaced with a new one in
Update2() rather than its settings changing.
2020-11-19 10:12:05 +01:00
Andrew Zaborowski
d09ba36f00
iwd: Roughly respect the NMDevice::autoconnect property
Watch the NMDevice::autoconnect property to disable IWD autoconnect if
requested by user.  We have no way to re-enable it when the device is
idle though.

Make sure to not disable IWD's autoconnect in .deactivate() if not
necessary.  There's not much we can do if we have to call
Station.Disconnect() but we can avoid calling it if unnecessary --
a slight optimization regardless of the autoconnect block flags.
Fortunately NM and IWD block autoconnect on a manual deactivation in
the same way (in MANAGED mode) and unblock it on an activation in the
same way too (in MANAGED mode).

Also if wifi.iwd.autoconnect is in use, unset
NM_DEVICE_AUTOCONNECT_BLOCKED_MANUAL_DISCONNECT under the same
conditions as IWD normally would.  This could be made optional but
with wifi.iwd.autoconnect by default we should follow IWD's autoconnect
logic.
2020-11-19 10:12:04 +01:00
Andrew Zaborowski
dc0e31fb70
iwd: Add the wifi.iwd.autoconnect setting
If this setting it true (or missing) we skip most of the D-Bus
Disconnect() calls whoe purpose was to keep IWD's internal autoconnect
mechanism always disabled.  We use the IWD's Station.State property
updates, and secrets requets through our IWD agent, to find out when IWD
is trying to connect and create "assumed" activations on the NM side to
mirror the IWD state.  This is quite complicated due to the many
possible combinations of NMDevice's state and IWD's state.  A lot of
them are "impossible" but we try to be careful to consider all the
different possibilities.

NM has a nice API for "assuming connections" but it's designed for
slightly different use cases than what we have here and for now we
created normal "managed"-type activations when assuming an IWD automatic
connection.
2020-11-19 10:12:04 +01:00
Andrew Zaborowski
43fd93d8f4
iwd: Order objects from g_dbus_object_manager_get_objects
Before we call interface_added for all interfaces and objects returned
from g_dbus_object_manager_get_objects(), order the objects based on the
interfaces present on them.  This is to avoid processing
Network.KnownNetwork properties referring to KnownNetwork objects that
we haven't processed yet, and new Station.ConnectedNetwork properties
referring to Network objects we haven't processed yet.

In NMDeviceIwd make sure we don't emit unnecessary re-checks if device
is not yet enabled because now we're always going to be adding the APs
(representing IWD Network objects) before the device is enabled, i.e.
before the nm_device_iwd_set_dbus_object() call, when NM first connects
to IWD.
2020-11-19 10:12:04 +01:00
Andrew Zaborowski
abc6177448
iwd: Create mirror connections for non-802.1X IWD known networks
Until now we'd only create mirror NMSettingsConnection objects for IWD
KnownNetwork objects of the "8021x" type in the NMIwdManager class.  Now
create mirror connections, or track existing matching
NMSettingsConnections, for every Known Network, for three reasons:

* to allow NMDeviceIwd to easily look up the NMSettingsConnection
  matching an externally-triggered connection, specifically when we let
  IWD autoconnect,
* to allow users to "forget" those Known Networks,
* to allow us to synchronize the autoconnectable property between
  NM and IWD to later allow users toggling it (not done yet).
2020-11-19 10:12:03 +01:00
Andrew Zaborowski
2198bb8293
wifi: Add NMWifiAp getters for wpa_flags/rsn_flags 2020-11-19 10:12:03 +01:00
Andrew Zaborowski
bb25112b61
iwd: Stop using _nm_utils_ssid_to_utf8()
_nm_utils_ssid_to_utf8() can be quite heavy and also has this comment:

 * Again, this function should be used for debugging and display purposes
 * _only_.

In most places that we used it, we have already validated the
connection's SSID to be valid UTF-8 so we can simply g_strndup() it now,
even in the two places where we actually only needed it for display
purposes.  And we definitely don't need or want the locale-specific
conversions done in _nm_utils_ssid_to_utf8 when the SSID is *not* utf8.

In mirror_8021x_connection we also optimize the lookup loop to avoid
validating and strdup'ing all the SSID.
2020-11-19 10:12:03 +01:00
Andrew Zaborowski
7cc5ee473e
iwd: Validate UTF-8 SSID early in check_connection_compatible/complete_connection
IWD only supports UTF-8 SSIDs internally, any BSS who's SSID doesn't
validate as UTF-8 is ignored.  There's also no way to ask IWD to connect
to such network/start AP/Adhoc etc. because SSIDs are passed as D-Bus
strings.  So validate that connection SSIDs are UTF-8 early in
check_connection_compatible/complete_connection and refactor
check_connection slightly to avoid duplication.

Since NMWifiAPs are created by us, we already know those have valid
SSIDs so once we've also checked new NMConnections in
check_connection_compatible there should be no possibility that an SSID
anywhere else in the code is not UTF8.  We should be able to treat the
GBytes values as UTF8 without redundant validation or the complex
locale-dependent conversions in _nm_utils_ssid_to_utf8.
2020-11-19 10:12:02 +01:00
Andrew Zaborowski
ca820d5f65
iwd: Never lock to BSSID in complete_connection
The AP BSSIDs created by the iwd backend are made up so never lock the
connections to them.  It probably wouldn't matter as long as the iwd
backend is used but the fake BSSID could stay in the connection
properties even if the user switches to wpa_supplicant.
2020-11-19 10:12:02 +01:00
Andrew Zaborowski
61e516bc20
iwd: Move scheduling periodic scan out of set_current_ap()
set_current_ap() would always call schedule_periodic_scan() but: first it
would do nothing when current_ap was non-NULL because we
schedule_periodic_scan makes sure not to auto-scan when connected.
Secondly state_changed() already calls schedule_periodic_scan
indirectly through set_can_scan() so normally when we disconnect and
current_ap becomes NULL we already do trigger a scan.  The only
situation where we didn't is when a connection is cancelled during
NEED_AUTH because IWD's state doesn't change, so we add a
schedule_periodic_scan() call in network_connect_cb() on error.
2020-11-19 10:12:02 +01:00
Andrew Zaborowski
221c8d75f3
iwd: Rename can_connect and iwd_connection
Rename NMDeviceIwdPrivate.can_connect to .nm_autoconnect in preparation
to also add .iwd_autoconnect.

Rename misnamed local variable iwd_connection to nm_connection, we'll
need a new iwd_connection variable later.
2020-11-19 10:12:02 +01:00
Andrew Zaborowski
08bf75f58e
iwd: Allow scanning in NM_DEVICE_STATE_NEED_AUTH
In this state, same as in DISCONNECTED or ACTIVATED, allow scanning if
IWD is in the "connected" or "disconnected" states as there's no reason
not to scan.
2020-11-19 10:12:02 +01:00
Andrew Zaborowski
7d9b37feaf
iwd: Handle the net.connman.iwd.Agent.Cancel() method
Implement a Cancel method on our IWD secrets agent DBus object.  This
results in a call to nm_device_iwd_agent_query() for the device
currently handling the request and the @invocation parameter is NULL to
signal that the current query is being cancelled.

nm_device_iwd_agent_query doesn't do much with this call just yet but
the handling will be necessary when IWD autoconnect is used by NM.
2020-11-19 10:12:02 +01:00
Thomas Haller
adaeb7a872
dns: fix _dns_manager_set_ip_config() for missing device
Fixes: 395665902b ('dns: don't apply DNS configuration for external connections')
2020-11-19 09:25:02 +01:00
Thomas Haller
3a0347e821
core/ovs: for now drop cancellable from ovsdbmethod call again
Currently the cancellable is not yet used. Drop it again.

However, I think the code might be useful, so I hope to revert
this commit afterwards to use it.
2020-11-17 19:49:04 +01:00
Thomas Haller
7055539c9f
core/ovs: support setting OVS external-ids
Also support reapply. During reapply we try to preserve
keys that are added externally.

However, the current implementation does not properly use transactions
to ensure there is no race here.
2020-11-17 19:49:04 +01:00
Thomas Haller
a4b13d5069
core/ovs: log external-ids of Interfaces/Ports/Bridges 2020-11-17 19:49:04 +01:00
Thomas Haller
958d7c092e
core/ovs: cleanup logging of OvsdbMethodCall
We don't need every log line repeat all the parameters
of the call. Each call should have a unique identifier
(which is NM_HASH_OBFUSCATE_PTR(call)) and only the first
message from a call contains all the details.
2020-11-17 19:49:03 +01:00
Thomas Haller
c44c8e7fbc
core/ovs: allow ovsdb calls to be cancelled
In general, providing an async API also requires the
ability to cancel requests. It's not yet used, but add
a way to handle a GCancellable.
2020-11-17 19:49:03 +01:00
Thomas Haller
8b4d77a453
core/ovs: don't fail with "cancelled" reason for disconnected ovsdb
API should fail with a "cancelled" error if (and only if)
the user cancelled the operation. An error to communicate
with OVSDB or being disconnected should fail with a different
reason.
2020-11-17 19:49:03 +01:00
Thomas Haller
2983febf39
core/ovs: track pending calls in a CList instead of GArray
GArray is nice, because it is more memory efficient and encourages
local access. However, growing the array also means that all entries
get relocated, that means, we cannot pass on a pointer to a call
instance.

Next, we will add a way to cancel operations via a GCancellable.
That means, we subscribe to the cancelled signal and need to pass
on a user-data that indicates which call got cancelled. Since with
an GArray the calls can be relocated, we would anyway need an
additional allocation (just for the user data). So, we wouldn't
actually safe anything but make the code more complicated.

As often, CList works great in this use case. Use it.
2020-11-17 19:49:03 +01:00
Thomas Haller
4303618a30
core/ovs: move definitions of structs in "nm-ovsdb.c"
It's in general nicer to have all definitions of structs and enums
a the top of the source file. As enums and structs are commonly used
by functions, it's often nice to have the enums and structs defined
first, before all functions.
2020-11-17 19:49:03 +01:00
Thomas Haller
395665902b
dns: don't apply DNS configuration for external connections
External connections are devices that are configured outside of
NetworkManager. Such devices should be mostly ignored and not
be interfered with.

Note that we tend to create external connection profiles for
such devices. That happens for example if you use wg-quick to
manage a WireGuard interface outside of NetworkManager. But it
really happens for any interface.

This generated profile has no DNS configuration. Unless we use
the systemd-resolved backend, they thus don't contribute to the DNS
settings (which is fine).

However, with systemd-resolved, NetworkManager would also reset
the DNS configuration of those external interfaces. That is clearly
wrong. NetworkManager should only care about the interfaces that it
actively manages and leave others alone.

How to reproduce: use systemd-resolved and configure an interface outside
of NetworkManager. Note that `nmcli device` shows the state as
"connected (externally)". Note that `resolvectl` shows the DNS configuration
on that external interface. Do something in NetworkManager to trigger
a DNS update (e.g. SIGHUB or reactivate a profile). Note in `resolvectl`
that the external interface's DNS configuration was wiped.

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/563#note_673283
2020-11-17 18:49:58 +01:00
Thomas Haller
f1564caa15
dns: minor cleanup in update_dns() to use gsize for size
g_strv_length() returns a guint. That is not the right size for the length
of an array. Use the right size.
2020-11-17 16:55:15 +01:00
Beniamino Galvani
09c8387114 policy: use the hostname setting
Rework update_system_hostname() to use the new properties from the
hostname setting.

In the default configuration where all the 3 boolean properties
hostname.{from-dhcp,from-dns,only-from-default} are true, the behavior
is the same as before.
2020-11-16 16:43:40 +01:00
Beniamino Galvani
abd002642f all: add hostname setting
Add a new setting that contains properties related to how NM should
get the hostname from the connection.
2020-11-16 16:43:39 +01:00
Beniamino Galvani
adf63c8875 ifcfg: reuse the same variable for different settings 2020-11-16 16:43:39 +01:00
Beniamino Galvani
dc6ec6ce7b core: reverse the order of active connections in the manager
When a new active connection is created, it gets added at the
beginning of manager's list. This means that the list contains most
recently activated connections first. Since the list is doubly-linked,
it is possible to efficiently iterate in both directions, so the order
of the list is mostly a matter of convention.

I think it is preferable to have oldest active connections at the
beginning of the list; let's reverse the order.

In most places where the list is iterated, the order doesn't
matter. Where it does, use the *_prev() variant to maintain the old
iteration order.
2020-11-16 16:43:39 +01:00
Beniamino Galvani
740191f7c0 core: add nm_ip_config_get_first_address() 2020-11-16 16:43:39 +01:00
Aleksander Morgado
5b7ce438d9
wwan: update default connection timeout to 200s
The following merge request in ModemManager introduces a more or less
common timeout value for the connection attempts in all plugin and
protocol implementations:

  https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/merge_requests/391

The value chosen by default for the steps that may take long to
complete in a connection attempt is 180s, and 120s for the steps in
the disconnection path.

Until now, every different plugin or protocol had a different timeout
value, all of them <= 180s, and with that change in ModemManager, the
values are now aligned for all.

Note, though, that this does not mean that a connection attempt will
take always less than 180s, as there may be multiple other steps in
addition to the one that took the maximum timeout. The value chosen
for NetworkManager is a compromise between the new defaults from MM
and what the user would expect under e.g. very low quality conditions.

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/678
2020-11-16 16:04:06 +01:00
Andrew Zaborowski
c1ff06e119 iwd: Fix a use after free
In connection_removed we use the id.name that was being g_freed a few
lines further down.

Fixes: bea6c40367 ('wifi/iwd: handle forgetting connection profiles')
2020-11-12 19:58:08 +01:00
Thomas Haller
ab3f18b906
ppp: drop unnecessary cast for return value of g_object_new() (manually) 2020-11-12 16:08:17 +01:00
Thomas Haller
a2b5e22f82
all: drop unnecessary cast for return value of g_object_new()
C casts unconditionally force the type, and as such they don't
necessarily improve type safety, but rather overcome restrictions
from the compiler when necessary.

Casting a void pointer is unnecessary (in C), it does not make the
code more readable nor more safe. In particular for g_object_new(),
which is known to return a void pointer of the right type.

Drop such casts.

  sed 's/([A-Za-z_0-9]\+ *\* *) *g_object_new/g_object_new/g' $(git grep -l g_object_new) -i
  ./contrib/scripts/nm-code-format-container.sh
2020-11-12 16:03:09 +01:00
Thomas Haller
2f83777054
core/trivial: fix clang-format code formatting 2020-11-12 15:34:59 +01:00
Andrew Zaborowski
33b9fa3a3c manager: Keep volatile/external connections while referenced by async_op_lst
If an NMSettingsConnection with the VOLATILE or EXTENRAL flags is created
and passed to nm_manager_activate_connection, it's immediately scheduled
for deletion in an idle callback and will likely be deleted before the
authorization step in nm_manager_activate_connection finishes and the
connection will be aborted.  This is because there's no
NMActiveConnection in priv->active_connection_lst_head referencing it
until _internal_activate_device().  Change
active_connection_find_by_connection to also look for connections in
priv->async_op_lst_head.

New _delete_volatile_connection_do() calls are added.  Previously it
would be called when an active connection may have been removed from
priv->active_connection_lst_head, now also call it when an active
connection may have been removed from priv->async_op_lst_head without
being added to priv->active_connection_lst_head.

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/671
2020-11-12 15:04:56 +01:00
Thomas Haller
31940037fa
device: fix _Generic() types for _NM_DEVICE_CAST() macro (2)
clang (x86_64, 3.4.2-9.el7) fails:

    ../src/devices/nm-device.c:957:9: error: controlling expression type 'typeof (*self) *const' (aka 'struct _NMDevice *const') not compatible with any generic association type
            _LOGT(LOGD_DEVICE,
            ^~~~~~~~~~~~~~~~~~
    ../shared/nm-glib-aux/nm-logging-fwd.h:162:20: note: expanded from macro '_LOGT'
    #define _LOGT(...) _NMLOG(_LOGL_TRACE, __VA_ARGS__)
                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ../src/devices/nm-device-logging.h:34:81: note: expanded from macro '_NMLOG'
                const char *const    _ifname = _nm_device_get_iface(_NM_DEVICE_CAST(_self)); \
                                                                                    ^~~~~
    ../src/devices/nm-device-logging.h:14:63: note: expanded from macro '_NM_DEVICE_CAST'
        #define _NM_DEVICE_CAST(self) _NM_ENSURE_TYPE(NMDevice *, self)
                                                                  ^
    ../shared/nm-glib-aux/nm-macros-internal.h:664:53: note: expanded from macro '_NM_ENSURE_TYPE'
        #define _NM_ENSURE_TYPE(type, value) (_Generic((value), type : (value)))
                                                        ^

Fixes: cc35dc3bdf ('device: improve "nm-device-logging.h" to support a self pointer of NMDevice type')
2020-11-10 22:54:32 +01:00
Thomas Haller
71eeec8c78
device: fix _Generic() types for _NM_DEVICE_CAST() macro
clang (x86_64, 3.4.2-9.el7) fails:

    ../src/devices/nm-device-6lowpan.c:161:9: error: controlling expression type 'typeof (*self) *const' (aka 'struct _NMDevice6Lowpan *const') not compatible with any generic association type
            _LOGW(LOGD_DEVICE, "could not get 6lowpan properties");
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ../shared/nm-glib-aux/nm-logging-fwd.h:165:20: note: expanded from macro '_LOGW'
    #define _LOGW(...) _NMLOG(_LOGL_WARN, __VA_ARGS__)
                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ../src/devices/nm-device-logging.h:32:81: note: expanded from macro '_NMLOG'
                const char *const    _ifname = _nm_device_get_iface(_NM_DEVICE_CAST(_self)); \
                                                                                    ^~~~~
    ../src/devices/nm-device-logging.h:17:19: note: expanded from macro '_NM_DEVICE_CAST'
            _Generic((self), _NMLOG_DEVICE_TYPE *        \
                      ^

Fixes: cc35dc3bdf ('device: improve "nm-device-logging.h" to support a self pointer of NMDevice type')
2020-11-10 19:44:10 +01:00
Thomas Haller
bac5dc99d7
core/ovs: refactor duplicate code in ovsdb_next_command() 2020-11-09 17:53:19 +01:00
Thomas Haller
9b5bb3e45c
core/ovs: split payload out of OvsdbMethodCall struct
Before, ovsdb_call_method() has a long list of arguments
to account for all possible commands. That does not scale.

Instead, introduce a separate OvsdbMethodPayload type and
only add a macro to allow passing the right parameters.
2020-11-09 17:53:18 +01:00
Thomas Haller
81863c959b
core/ovs: rename logging output for _LOGT_call()
The text should match the OvsdbCommand enum. If the enum
value is named OVSDB_ADD_INTERFACE, then we should print
"add-interface". Or alternatively, if you think spelling
out interface is too long, then the enum should be renamed.
I don't care, but name should correspond.
2020-11-09 17:53:18 +01:00
Thomas Haller
487c78733e
core/ovs: name union fields in OvsdbMethodCall
As we add more command types, the union gets more members.
Name each union field explicitly to match the OvsdbCommand
type.
2020-11-09 17:53:18 +01:00
Thomas Haller
2d8c5e9efa
core/ovs: cleanup debug logging for OVS command
- always print the JSON string as last (if present). Previously
  that didn't happen with OVSDB_SET_INTERFACE_MTU.

- introduce _QUOTE_MSG() macro.
2020-11-09 17:53:18 +01:00
Thomas Haller
1eeca3c606
core/ovs: track external-ids for cached ovsdb objects
We will need them later.
2020-11-09 17:53:18 +01:00
Thomas Haller
7cf1f7fe02
core/ovs: cleanup logic in update handling of ovsdb_got_update()
ovsdb sends monitor updates, with "new" and "old" values that indicate
whether this is an addition, and update, or a removal.

Since we also cache the entries, we might not agree with what ovsdb
says. E.g. if ovsdb says this is an update, but we didn't have the
interface in our cache, we should rather pretend that the interface
was added. Even if this possibly indicates some inconsistency between
what OVS says and what we have cached, we should make the best of it.

Rework the code. On update, we compare the result with our cache
and care less about the "new" / "old" values.
2020-11-09 17:53:18 +01:00
Thomas Haller
f6d3b5f5f4
core/ovs: change function signature of _free_{bridge,port,interface}
We will call the function directly as well. Lets aim to
get the types right.

Also the compiler would warn if the cast to (GDestroyNotify)
would be to a fundamtally different function signature.
2020-11-09 17:53:18 +01:00
Thomas Haller
7dc4d0c666
core/ovs: use helper functions to emit NM_OVSDB_* signals 2020-11-09 17:53:18 +01:00
Thomas Haller
cb3b6a2417
core/ovs: move code in "nm-ovsdb.c" around to have simple helpers at the top 2020-11-09 17:53:17 +01:00
Thomas Haller
e403f76544
core/ovs: track key for OpenvswitchInterface in same struct 2020-11-09 17:53:17 +01:00
Thomas Haller
51495e4e9a
core/ovs: track key for OpenvswitchPort in same struct 2020-11-09 17:53:17 +01:00
Thomas Haller
2094cbb5d1
core/ovs: track key for OpenvswitchBridge in same struct
GHashTable is optimized for data that has no separate value
pointer. We can use the OpenvswitchBridge structs as key themselves,
by having the id as first field of the structure and only use
g_hash_table_add().
2020-11-09 17:53:17 +01:00