Commit graph

95 commits

Author SHA1 Message Date
Beniamino Galvani
e0691f9528 device: ensure tc_commit() is called only once per activation
Stage2 can be called multiple times. Ensure that tc_commit() is only
called the first time. This is important now that tc synchronization
requires to clear all qdiscs and recreate them.
2021-09-20 13:27:15 +02:00
Beniamino Galvani
3981bff2a0 core: rework tc sync functions
Update nm_platform_qdisc_sync() and nm_platform_tfilter_sync() to
avoid looking into the platform cache, so that we no longer require to
keep tc and qdiscs in the cache.

There is no API in kernel to retrieve tc objects only for a specific
interface, so NM had to receive all tc events, even for unmanaged
interfaces.  This could cause high CPU usage in some scenarios with
many objects.

Instead, try to delete root qdiscs and filters and then add the known
ones.

Also, combine the two functions together since they are related. In
particular, removing all qdiscs also removes all attached filters.
2021-09-20 13:27:15 +02:00
Thomas Haller
17e4da8bf3
device: suppress warning for external device if it is down (!IFF_UP)
External devices are not to be touched by NetworkManager. If it is down,
that is not something to warn about.
2021-09-16 08:40:04 +02:00
Thomas Haller
571ce653fd
device: set up device also while "assuming"
"assuming" means to gracefully take over after restart. The result
should be a working configuration with a device fully managed by
NetworkManager.

If we are assuming, and the interface is down we still want to set it
up.
2021-09-16 08:38:25 +02:00
josef radinger
3f5cb1f932
core/trivial: fix small typo Ipv vs IPv
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/978
2021-09-13 09:22:17 +02:00
Thomas Haller
5a4124f738
core: refactor nm_utils_ipv6_addr_set_stable_privacy() to not fail
It's great to have functions that cannot fail, because it allows to
skip any error handling.

_set_stable_privacy() as it was could not fail, so the only reason why
nm_utils_ipv6_addr_set_stable_privacy() could fail is because the DAD
counter exhausted.

Also, it will be useful to have a function that does not do the counter
check, where the caller wants to handle that differently.

Rename some functions, and make the core nm_utils_ipv6_addr_set_stable_privacy()
not failable.
2021-08-31 16:49:46 +02:00
Thomas Haller
4b6e119010
all: pass pointer to "struct NMUtilsIPv6IfaceId" to functions instead of struct
While NMUtilsIPv6IfaceId is only 8 bytes large, it seems unidiomatic to
pass the plain struct around.

With a "const NMUtilsIPv6IfaceId *" argument it is more clear what the
meaning of this is.

Change to use pointers.
2021-08-31 16:49:46 +02:00
Thomas Haller
bcd2c99aab
platform: require RTA_PREF support in kernel
The preference for IPv6 routes was added in kernel v4.1,
22 June 2015. It is even in latest RHEL7 kernels.

Drop trying to be compatible with such old kernels.
2021-08-31 16:41:57 +02:00
Thomas Haller
eb1c266280
platform: require extended IFA_FLAGS support in kernel
We use extended IFA_FLAGS for IFA_F_MANAGETEMPADDR (IPv6) and
IFA_F_NOPREFIXROUTE (IPv4 and IPv6).

These flags for IPv4 were added to kernel 3.14, 30 March, 2014.
The flag for IPv4 was added to kernel 4.4, 11 January 2016.
Even latest RHEL-7 kernels have backport for IFA_F_NOPREFIXROUTE
for IPv4 (rh#1221311).

Drop this. The backward compatibility code paths are likely broken
anyway, and add considerable complexity.
2021-08-31 16:41:57 +02:00
Thomas Haller
b2b50eba1b
platform: require IFLA_INET6_ADDR_GEN_MODE support in kernel
This is supported since kernel 3.17, dated 5 October, 2014. Drop the backward
compatibility for that.

It's very hard to sensibly support a mode where we set the interface up,
but prevent kernel from enabling IPv6. We would hack around that by disabling
IPv6 altogether.

But these code paths are not tested and likely make no sense. And it's hard
to implement a sensible behavior in this case anyway.
2021-08-31 16:41:57 +02:00
Thomas Haller
98ed0e9858
platform: rename "user_ipv6ll" API to "inet6_addr_gen_mode"
The term "user_ipv6ll" is confusing and not something somebody familiar
with kernel or `ip -d link` would understand.

Also, it maps a boolean to addr-gen-mode "none" or "eui64", although
there are 2 more address generation modes in kernel.

Don't abstract the underlying API, and name things as they are in
kernel.
2021-08-31 16:41:57 +02:00
Thomas Haller
0d0f532b12
device: setup firewall zone inside stage3_ip_config_start()
nm_device_activate_schedule_stage3_ip_config_start() should only... schedule.
2021-08-31 16:41:57 +02:00
Thomas Haller
31b74aab34
device: minor cleanup of dispatching function in nm_device_activate_schedule_ip_config_timeout() 2021-08-31 16:40:45 +02:00
Wen Liang
60bad3a41e
platform: obtain l_perm_address via netlink or lookup via ethtool
Add and call the new `nm_platform_link_get_permanent_address()` to
obtain `l_perm_address` via netlink or lookup via ethtool if kernel
does not expose the `IFLA_PERM_ADDRESS`.

And call the new `nm_platform_link_get_permanent_address()` in the unit
tests.

https://bugzilla.redhat.com/show_bug.cgi?id=1987286

Signed-off-by: Wen Liang <liangwen12year@gmail.com>
2021-08-24 21:04:22 +02:00
Wen Liang
2b70e02ef5
platform: rename nm_platform_link_get_permanent_address()
Rename `nm_platform_link_get_permanent_address()`, `link_get_permanent_address()` to
`nm_platform_link_get_permanent_address_ethtool()`, `link_get_permanent_address_ethtool()`.

Signed-off-by: Wen Liang <liangwen12year@gmail.com>
2021-08-24 21:04:21 +02:00
Wen Liang
1605fa460d
platform: update nm_platform_link_get_permanent_address() to accept NMPLinkAddress argument
Replace the arguments "buf+length" of
`nm_platform_link_get_permanent_address()` with "NMPLinkAddress *out_addr"

Signed-off-by: Wen Liang <liangwen12year@gmail.com>
2021-08-24 21:04:21 +02:00
Thomas Haller
f5dbf476e3
core: rename to_str() methods to to_string()
It's more common to name the to-string method *_to_string(). Rename.
2021-08-11 14:17:25 +02:00
Thomas Haller
dbdd8303fc
dhcp: replace NMDhcpClient's signals with "notify" and one notify data argument
NMDhcpClient communicates events via GObject signals. GObject signals in
principle could have several subscribers. In practice, a NMDhcpClient
instance has only one subscriber, because it was constructed with
certain parameters, so it's unlikely to be shared.

That one subscriber, always needs to subscribe to all signals
("state-changed" and "prefix-delegated"), Unless the subscriber only
creates a IPv4 client. In which case they won't subscribe to
"prefix-delegated", but that signal is also not invoked for IPv4
clients.

Combine the signals in one, and pass all parameters via a new
NMDhcpClientNotfiyData payload. I feel this is nicer, to pack all
parameters together. I find this more type-aware, where we can
switch (in the callback) based on a notify-type enum, instead
of subscribing multiple signal handlers.

With l3cfg work, DHCP handling will be refactored, where this model of
having one "generic" notify signal makes more sense than here. For the
moment, it is arguably pretty much the same. Also, because NMDhcpClient
subscribes two different handlers for IPv4 and IPv6. In the future,
there will be only one notify handler, and that can cover IPv4 and IPv6
and both "state-changed" and "prefix-delegated" (and other notification
types).
2021-08-11 14:17:24 +02:00
Beniamino Galvani
3f42e2005a device: store the original MTU before force-setting it
In case the MTU is force-set (e.g. for bridges), priv->mtu_initial and
priv->ip6_mtu_initial must be initialized before changing the MTU,
otherwise the wrong value will be restored on deactivation.

Fixes: e23798a5e5 ('bridge: force (hack)-set of the MTU when explicitly set in the profile')

https://bugzilla.redhat.com/show_bug.cgi?id=1973536
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/955
2021-08-06 15:31:02 +02:00
Thomas Haller
a3b7030d74
dispatcher: rename NM_DISPATCHER_ACTION_DHCP_CHANGE_X enums
add a NM_DISPATCHER_ACTION_DHCP_CHANGE_X() macro that can select the
right action based on a parameter.

Also rename the IPv4/IPv6 enum values, so that their naming scheme works
better with the NM_DISPATCHER_ACTION_DHCP_CHANGE_X() macro.
2021-08-05 14:59:17 +02:00
Thomas Haller
b4e4b8d614
core: cleanup arguments for GObject signal of NMDhcpClient 2021-08-05 14:59:13 +02:00
Thomas Haller
3f6365f5d0
all: use G_CALLBACK() macro instead of plain cast 2021-08-05 14:59:11 +02:00
Thomas Haller
5e6b50ec73
device: track pending actions with a sorted string list instead of GSList
We call add/remove pending actions for every state change.

I think GSList is never the best choice of a data structure. Use a plain
array instead. Keep it sorted, so we can use binary search.
2021-08-05 14:59:10 +02:00
Thomas Haller
a29d8b712f
l3cfg: set NMIPConfigSource for NML3ConfigData at construct time
Each NML3ConfigData should have a source set, and in fact most callers
would call nm_l3_config_data_set_source() right after creating the
instance.

Move the source parameter to the new() constructor function. Also remove
the setter, making the source of an instance immutable.

As every l3cfg instance generally has a clear purpose, the source should
always be known from the start and doesn't need to change.
2021-08-03 20:36:08 +02:00
Thomas Haller
4ac66a4215
all: rename nm_utils_strdup_reset*() to nm_strdup_reset*() 2021-08-02 09:26:47 +02:00
Thomas Haller
d0ba87a1ad
all: rename nm_utils_strbuf_*() API to nm_strbuf_*()
The "utils" part does not seem useful in the name.

Note that we also have NMStrBuf, which is named nm_str_buf_*().
There is an unfortunate similarity between the two, but it's still
distinct enough (in particular, because one takes an NMStrBuf and
the other not).
2021-08-02 09:26:42 +02:00
Thomas Haller
4c3aac899e
all: unify and rename strv helper API
Naming is important, because the name of a thing should give you a good
idea what it does. Also, to find a thing, it needs a good name in the
first place. But naming is also hard.

Historically, some strv helper API was named as nm_utils_strv_*(),
and some API had a leading underscore (as it is internal API).

This was all inconsistent. Do some renaming and try to unify things.

We get rid of the leading underscore if this is just a regular
(internal) helper. But not for example from _nm_strv_find_first(),
because that is the implementation of nm_strv_find_first().

  - _nm_utils_strv_cleanup()                 -> nm_strv_cleanup()
  - _nm_utils_strv_cleanup_const()           -> nm_strv_cleanup_const()
  - _nm_utils_strv_cmp_n()                   -> _nm_strv_cmp_n()
  - _nm_utils_strv_dup()                     -> _nm_strv_dup()
  - _nm_utils_strv_dup_packed()              -> _nm_strv_dup_packed()
  - _nm_utils_strv_find_first()              -> _nm_strv_find_first()
  - _nm_utils_strv_sort()                    -> _nm_strv_sort()
  - _nm_utils_strv_to_ptrarray()             -> nm_strv_to_ptrarray()
  - _nm_utils_strv_to_slist()                -> nm_strv_to_gslist()
  - nm_utils_strv_cmp_n()                    -> nm_strv_cmp_n()
  - nm_utils_strv_dup()                      -> nm_strv_dup()
  - nm_utils_strv_dup_packed()               -> nm_strv_dup_packed()
  - nm_utils_strv_dup_shallow_maybe_a()      -> nm_strv_dup_shallow_maybe_a()
  - nm_utils_strv_equal()                    -> nm_strv_equal()
  - nm_utils_strv_find_binary_search()       -> nm_strv_find_binary_search()
  - nm_utils_strv_find_first()               -> nm_strv_find_first()
  - nm_utils_strv_make_deep_copied()         -> nm_strv_make_deep_copied()
  - nm_utils_strv_make_deep_copied_n()       -> nm_strv_make_deep_copied_n()
  - nm_utils_strv_make_deep_copied_nonnull() -> nm_strv_make_deep_copied_nonnull()
  - nm_utils_strv_sort()                     -> nm_strv_sort()

Note that no names are swapped and none of the new names existed
previously. That means, all the new names are really new, which
simplifies to find errors due to this larger refactoring. E.g. if
you backport a patch from after this change to an old branch, you'll
get a compiler error and notice that something is missing.
2021-07-29 10:26:50 +02:00
Thomas Haller
3775f4395a
all: drop unnecessary casts from nm_utils_strv_find_first()
And, where the argument is a GPtrArray, use
nm_strv_ptrarray_find_first() instead.
2021-07-29 09:33:50 +02:00
Beniamino Galvani
bace14fe1f core: introduce device 'allowed-connections' property
Configuration can have [device*] and [connection*] settings and both
can include a 'match-device=' key, which is a list of device-specs.

Introduce a new 'allowed-connections' key for [device*] sections,
which specifies a list of connection-specs to indicate which
connections can be activated on the device.

With this, it becomes possible to have a device configuration like:

  [device-enp1s0]
  match-device=interface-name:enp1s0
  allowed-connections=except:origin:nm-initrd-generator

so that NM in the real root ignores connections created by the
nm-initrd-generator, and starts activating a persistent
connection. This requires also setting 'keep-configuration=no' to not
generate an assumed connection.
2021-07-27 17:43:45 +02:00
Beniamino Galvani
b1644fa826 manager: exit early in get_existing_connection()
Later the function will become more complex. Add a check to exit early
if the device can't assume connections.
2021-07-27 16:36:47 +02:00
Beniamino Galvani
bb37e30867 core: add comments about assuming connections 2021-07-27 16:36:47 +02:00
Thomas Haller
85f53f43e9
device/dhcp: avoid crash by not starting DHCPv6 client without ifindex
https://bugzilla.redhat.com/show_bug.cgi?id=1973199
2021-07-14 18:19:46 +02:00
Thomas Haller
63a248ecb2
device: avoid crash setting VPN config during unrealize
During nm_device_unrealize(), we first clear the device's ifindex. Then
we call _set_state_full(NM_DEVICE_STATE_UNMANAGED).

NMVpnConnection are subclasses of NMActiveConnection, it is that way
connected to NM_DEVICE_STATE_CHANGED signal. And this leads to a call
to _set_vpn_state(), which then calls nm_device_replace_vpn6_config()
to unregister the config. Thereby an assertion fails because the
ifindex no longer matches.

Fix that by relaxing the assertion. Also, don't apply the IP
configuration in unexpected device states.

https://bugzilla.redhat.com/show_bug.cgi?id=1912423

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/927
2021-07-13 17:23:55 +02:00
Beniamino Galvani
62869621bd device: start DHCPv6 when a prefix delegation is needed
If a prefix delegation is needed, currently NM restarts DHCPv6 on the
device with default route, but only if DHCPv6 was already running.

Allow the device to start DHCPv6 for a PD even if it was running
without DHCPv6.

See also: https://github.com/coreos/fedora-coreos-tracker/issues/888
2021-07-13 09:43:04 +02:00
Beniamino Galvani
1377f160ed device: send ARP announcements when there is carrier
Previously we sent announcements immediately for non-controllers, or
after the first port was attached for controllers.

This has two problems:

 - announcements can be sent when there is no carrier and they would
   be lost;

 - if a controller has a port, the port could be itself a controller;
   in that case we start sending ARPs with the fake address of the
   port. Later, when a leaf port is added to the second-level
   controller, the correct port MAC will be propagated by kernel up to
   both controllers.

To solve both problems, send ARP announcements only when the interface
has carrier. This also solves the second issue because controllers
created by NM have carrier only when there is a port with carrier.

Fixes: de1022285a ('device: do ARP announcements only after masters have a slave')

https://bugzilla.redhat.com/show_bug.cgi?id=1956793
2021-07-13 09:27:20 +02:00
Björn Lindqvist
44481bd7c7
core: fail IPv6 early if disabled in kernel
Adds the following info message in case ipv6 is disabled:

    <info>  device (enp0s18f2u3): The kernel does not support IPv6.

[thaller@redhat.com: modified original patch]

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/401
2021-07-05 16:27:48 +02:00
Beniamino Galvani
35cccc41cb device: use the 'required-timeout' property from IP setting
Change the logic in check_ip_state() to delay the connection ACTIVATED
state if an address family is pending and its required-timeout has not
expired.
2021-07-05 15:15:45 +02:00
Thomas Haller
05aa751957
core,glib-aux: move nm_hostname_manager_validate_hostname() to shared-utils
This function is badly named, because it has no NMHostnameManager self
argument. It's just a simple function that entirely operates on a string
argument.

Move it away from "nm-hostname-manager.h" to "libnm-glib-aux/nm-shared-utils.h".

Hostname handling is complicated enough. Simple string validation
functions should not obscure the view on the complicated parts.
2021-06-28 14:32:05 +02:00
Thomas Haller
b9c10512cb
device: track refresh_rate timer as GSource instead of source id
Using the guint source ID always requires an additional hash lookup
during removal to find the real source instance. Use instead the
underlying GSource instance.
2021-06-28 13:31:33 +02:00
Thomas Haller
9452d69465
config: avoid cloning string during nm_config_data_get_connection_default() et al.
NMConfigData is immutable and with the previous commit are the strings
already cached internally. There is no need to clone it.

Of course, the callers must not assume that the string stays alive after
a config reload (SIGHUP), where the NMConfigData might change. So they
are not always alive, but long enough for all callers to avoid cloning
the string.
2021-06-21 17:23:53 +02:00
Thomas Haller
b929caa95c
core: use nm_config_data_get_device_config_int64() for getting integer setting 2021-06-21 17:23:53 +02:00
Beniamino Galvani
3c55db886a device: prefer IPv6 not-deprecated addresses for hostname lookup
In presence of a IPv6 deprecated address and a non-deprecated one, the
latter will be used by kernel for new connections according to RFC
6724 section 5 (Source Address Selection). Prefer it also to lookup a
hostname via reverse DNS.

While at it, also prefer non-link-local addresses over link-local
ones.
2021-06-21 10:08:27 +02:00
Beniamino Galvani
ca31cbbc74 core: add nm_ip_config_find_first_address()
Replace nm_ip6_config_find_first_address() with a version generic for
IPv4 and IPv6.
2021-06-21 10:08:27 +02:00
Beniamino Galvani
709b497938 device: remove unused variable
Fixes: 620fbb7894 ('device: use nm_device_resolve_address()')
(cherry picked from commit c89ac8f0c7)
2021-06-11 21:59:18 +02:00
Beniamino Galvani
f468e15248 device: use nm_device_resolve_address()
(cherry picked from commit 620fbb7894)
2021-06-11 21:59:12 +02:00
Beniamino Galvani
a48edd0410 core,libnm: don't touch device TC configuration by default
NetworkManager supports a very limited set of qdiscs. If users want to
configure a unsupported qdisc, they need to do it outside of
NetworkManager using tc.

The problem is that NM also removes all qdiscs and filters during
activation if the connection doesn't contain a TC setting. Therefore,
setting TC configuration outside of NM is hard because users need to
do it *after* the connection is up (for example through a dispatcher
script).

Let NM consider the presence (or absence) of a TC setting in the
connection to determine whether NM should configure (or not) qdiscs
and filters on the interface. We already do something similar for
SR-IOV configuration.

Since new connections don't have the TC setting, the new behavior
(ignore existing configuration) will be the default. The impact of
this change in different scenarios is:

 - the user previously configured TC settings via NM. This continues
   to work as before;

 - the user didn't set any qdiscs or filters in the connection, and
   expected NM to clear them from the interface during activation.
   Here there is a change in behavior, but it seems unlikely that
   anybody relied on the old one;

 - the user didn't care about qdiscs and filters; NM removed all
   qdiscs upon activation, and so the default qdisc from kernel was
   used. After this change, NM will not touch qdiscs and the default
   qdisc will be used, as before;

 - the user set a different qdisc via tc and NM cleared it during
   activation. Now this will work as expected.

So, the new default behavior seems better than the previous one.

https://bugzilla.redhat.com/show_bug.cgi?id=1928078
2021-06-03 09:01:57 +02:00
Thomas Haller
6439c243e7
systemd: move "src/core/systemd" to "src/libnm-systemd-core"
This follows the recently introduced naming scheme and directory layout.
"libnm-systemd-core" is an independent component, and as such should no
be inside "src/core/".

Move it.

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/875
2021-05-30 09:45:05 +02:00
Thomas Haller
bb1a495213
device: refactor dhcp-anycast-address handling for OLPC mesh device
dhcp-anycast-address is only set by OLPC mesh device. It's ugly to have
this in form of a nm_device_set_dhcp_anycast_address() method, because
that means to cache the address in NMDevice. Meaning, we have more state
in NMDevice, where it's not clear where it comes from.

Instead, whenever we need to DHCP anycast address, as the subclass to
provide it (if any). This way, it gets extracted from the currently
applied connection at the moment when it is needed. Beyond that, the
setting is not duplicated/cached in NMDevice anymore.
2021-05-18 09:41:53 +02:00
Thomas Haller
98a89a05ec
core: explicitly disable ethtool.pause-autoneg when setting pause-rx/pause-tx
Kernel will coerce values like

    ethtool -A eth0 autoneg on rx off

to have autonet still on.

Also, if autoneg on the interface is enabled, then `ethtool  -A eth0 tx off`
has no effect.

In NetworkManager, the user cannot configure "autoneg on" together with
any rx/tx settings. That would render the profile invalid. However, we
also need to take care that a profile

  nmcli connection add ... ethtool.pause-autoneg ignore ethtool.pause-tx off

really means off. That means, we must coerce an unspecified autoneg
setting to "off".
2021-05-17 23:31:21 +02:00
Beniamino Galvani
e67ddd826f device: commit MTU during stage2
Currently we commit the MTU to the device when updating the IP
configuration, or when a port device is added to the controller. This
means that for a connection with DHCP, the MTU is set only after DHCP
has completed. In particular, if DHCP doesn't complete and the
connection has an infinite timeout, the MTU is never set.

_commit_mtu() tracks different sources for the MTU of a device, and
each source has a different priority. Among these sources there are
the parent link (for VLANs), a dynamic IP configuration (DHCP, PPP)
and the connection profile.

A MTU from the connection always has the highest priority and
overrides other sources.

Therefore, if the connection specifies an MTU it can be applied at
stage2, even before configuring IP addressing.

https://bugzilla.redhat.com/show_bug.cgi?id=1890234
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/859
2021-05-17 16:20:36 +02:00