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.
Add function nm_utils_connection_match_spec_list() to check whether a
connection matches a spec list. Also document the supported syntax in
the man page.
Add a new 'keep-configuration' device option, set to 'yes' by
default. When set to 'no', on startup NetworkManager ignores that the
interface is pre-configured and doesn't try to keep its
configuration. Instead, it activates one of the persistent
connections.
To talk to ovsdb, we use the unix socket at
/var/run/openvswitch/db.sock. But that socket is owned by another user
and NetworkManager would need dac_override capability to open it.
We want to drop dac_override, but we still need to talk to ovsdb. Add a
GetFD() method to nm-sudo.
We still first try to open the socket directly. Maybe it just works.
Note that SELinux may block passing file descriptors from nm-sudo. If it
doesn't work for you, test with SELinux permissive mode and wait for an
SELinux update.
NetworkManager runs as root and has lots of capabilities.
We want to reduce the attach surface by dropping capabilities,
but there is a genuine need to do certain things.
For example, we currently require dac_override capability, to open
the unix socket of ovsdb. Most users wouldn't use OVS, so we should
find a way to not require that dac_override capability. The solution
is to have a separate, D-Bus activate service (nm-sudo), which
has the capability to open and provide the file descriptor.
For authentication, we only rely on D-Bus. We watch the name owner
of NetworkManager, and only accept requests from that service. We trust
D-Bus to get it right a request from that name owner is really coming
from NetworkManager. If we couldn't trust that, how could PolicyKit
or any authentication via D-Bus work? For testing, the user can set
NM_SUDO_NO_AUTH_FOR_TESTING=1.
https://bugzilla.redhat.com/show_bug.cgi?id=1921826
NetworkManager (and NetworkManager-all-sym) must not only contain symbols
that are used by itself. Also the device and settings plugin are dlopen'd
by NetworkManager and use symobls form the binary.
That means, if a symbols is only used by a plugin, then we must make sure
that the linker keeps it in the binary. Add a mechanism for that.
This is a normalization employed by NMSettingIPConfig.gateway.
Also rework NMSettingIPConfig.set_property() to no longer assert against
valid input. We want to pass there untrusted strings from D-Bus,
asserting is a horrible idea. Instead, either normalize the string or
keep the invalid text that will be rejected by verify().
This is like using nm_ascii_is_ctrl_or_del() instead of
nm_ascii_is_ctrl() in the previous version of the patch.
We thus now always will switch to ANSIC escaping if we see
a ASCII DEL character. That is probable desirable, but either
way should not make a big difference (because we can parse
the DEL character both in regular quotation and in ANSIC quotation).
The patch is however larger, to also take the opportunity to only check
for nm_ascii_is_regular() in the "fast path". The behavior is the same
as changing nm_ascii_is_ctrl() to nm_ascii_is_ctrl_or_del().
Problems of this patch:
- the code does not differentiate between an ifcfg file and an alias
file. Different shell variables are honored however depending on the
context and the warning should reflect that.
- there are no warnings about /etc/sysconfig/network. The main problem
is that we read this file for every ifcfg file we parse, and we would
need to ratelimit the number of warnings. Another problem is that
the file likely contains keys that we intentionally don't support.
We would need a new way to omit warnings about those lines.
Example:
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=dhcp
DEFROUTE=yes
STABLE_ID=$'xxx\xF4yy'
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
XX=foo
XX1=foo'
'
IPV6_AUTOCONF=yes xxxx
IPV6_DEFROUTE=yesx
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=xxx
UUID=9d8ed7ff-3cdd-4336-9e26-3e978dc87102
ONBOOT=no
<warn> [...] ifcfg-rh: ifcfg,/etc/sysconfig/network-scripts/ifcfg-xxx:6: key STABLE_ID does not contain valid UTF-8 and is treated as ""
<debug> [...] ifcfg-rh: ifcfg,/etc/sysconfig/network-scripts/ifcfg-xxx:9: key XX is unknown and ignored
<warn> [...] ifcfg-rh: ifcfg,/etc/sysconfig/network-scripts/ifcfg-xxx:10: key XX1 is badly quoted and is treated as ""
<warn> [...] ifcfg-rh: ifcfg,/etc/sysconfig/network-scripts/ifcfg-xxx:11: invalid line ignored
<warn> [...] ifcfg-rh: ifcfg,/etc/sysconfig/network-scripts/ifcfg-xxx:12: key IPV6_AUTOCONF is badly quoted and is treated as ""
<warn> [...] ifcfg-rh: ifcfg,/etc/sysconfig/network-scripts/ifcfg-xxx:13: key IPV6_DEFROUTE is duplicated and the early occurrence ignored
https://bugzilla.redhat.com/show_bug.cgi?id=1959656
ifcfg files are a text format. It makes no sense to ever accept
non-UTF-8 blobs. If binary data is to be encoded in a ifcfg file, then
the upper layers must escape/encode it in valid UTF-8.
Let svUnescape() silently reject any binary "text". This will lead to treat such
strings as empty strings "". This is no different than some invalid
quoting: the string is not parsable as (UTF-8) text and will be treated
as such.
This is potentially a breaking change. But the benefit is that all the
upper layers can rely on only getting valid UTF-8 strings. For example,
a non-UTF-8 string cannot be converted to a "s" GVariant (of course not,
it's not a string). But our nm_connection_verify() commonly does not
check that all strings are in fact valid UTF-8. So a user who edits
an ifcfg file could inject non-valid strings, and cause assertion
failures later on.
It's actually easy to provoke a crash (or at least an assertion failure)
by writing an ifcfg file with certain keys as binary.
Note that you can either reproduce the binary files by writing non-UTF-8
"strings" dirctly, or by using \x, \u, or \U escape sequences.
Note that also '\0' gets rejected and renders the string as invalid
(i.e. as empty). Before the returned string would have been simply
truncated and the rest ignored. Such NUL bytes can only be produced
using the escape sequences, because the ifcfg reader already (silently)
truncates the file on the first binary NUL.
Note that previously the check
if (s[slen] < ' ') {
...
return (*to_free = _escape_ansic(s));
}
would be TRUE for all UTF-8 characters if `char` is signed. That means,
depending on the compiler, we would always ANSI escape all UTF-8
characters. With this patch, we no longer do that!
Instead, valid unicode gets now preserved (albeit quoted).
On the other hand, always ANSIC escape invalid UTF-8 (regardless of the
compiler). ifcfg-rh is really a text based format. If a caller wants to store
binary data, they need to escape it first, for example with some own escaping
scheme, base64 or bin2hexstr.
A caller passing a non-text to svEscape() is likely a bug already and
they should have not done that.
Still, let svEscape() handle that by using ANSIC escaping. That works
as far as escaping is concerned, but likely later will be a problem
during unescaping, when the reader expects a valid UTF-8 string.
svEscape() is in no place to signal a sensible error, so proceed the
best it can, by escaping.
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=1912423https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/927
NMDeviceModem has priv->modem set from construction to dispose, and
the NM_MODEM_IP4_CONFIG_RESULT/NM_MODEM_IP6_CONFIG_RESULT signals
connected all the time.
On the other hand, NMModem may hook up to NMPPPManager's
NM_PPP_MANAGER_SIGNAL_IP{4,6}_CONFIG signals, which emit the
config-results signals. And PPP manager emits the config signals
from impl_ppp_manager_set_ip{4,6}_config().
That means, at any moment can be a D-Bus calls, which leads to emitting
those signals and calling into modem_ip4_config_result() and
modem_ip6_config_result().
At least, it's not clear from review what would prevent that from
happening. If you cannot easily verify that certain conditions are
satisfied, then this is not the place to assert, but to handle the case
as something that can happen regularly.
Handle signals in the unexpected state by ignoring them.
https://bugzilla.redhat.com/show_bug.cgi?id=1916192https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/926
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
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
Let the default normalization from nm_connection_normalize() choose
'ipv6.method'. It will now choose "disabled" for dummy profiles, which
is just what we need.
In particular, we don't want to enable autoconf for dummy devices --
unless the profile which the user provides already has it enabled (in
which case nm_connection_normalize() doesn't change it).
$ ip link add dd type dummy
$ nmcli device
DEVICE TYPE STATE CONNECTION
...
dd dummy unmanaged --
$ nmcli device connect dd
Error: Failed to add/activate new connection: A 'dummy' setting is required.
There are two problems here. The first is that we don't pass
the interface name to nm_utils_complete_generic(), but dummy
devices require "connection.interface-name" set. As a consequence,
nm_utils_complete_generic() fails to normalize the connection
and there is no [dummy] setting. Which then results in a failure
with complete_connection().
The important part of the fix is to set the interface name. Once
we do that, nm_utils_complete_generic() should be able to add
the [dummy] setting and the second part is not strictly necessary.
Still, the job of complete_connection() is not to verify the
profile but to create it with best effort. If a [dummy] setting
is still missing, we should just add it. The caller will then
again try to normalize/verify the connection, and that might then
fail -- but this time not with the wrong error message about
missing 'dummy' setting.
https://bugzilla.redhat.com/show_bug.cgi?id=1763054
I missed that we already have a gettid() wrapper. Drop the duplicated
again and use nm_utils_gettid().
Fixes: e874c5bf6b ('random: Provide missing gettid() declaration')
Add a new property to specify the minimum time interval in
milliseconds for which dynamic IP configuration should be tried before
the connection succeeds.
This property is useful for example if both IPv4 and IPv6 are enabled
and are allowed to fail. Normally the connection succeeds as soon as
one of the two address families completes; by setting a required
timeout for e.g. IPv4, one can ensure that even if IP6 succeeds
earlier than IPv4, NetworkManager waits some time for IPv4 before the
connection becomes active.
We have two GKeyfile files (timestamps and seen-bssids).
When a profile was deleted while NetworkManager was running, then
entries were removed from these keyfiles. But if a profile disappeared
while NetworkManger was stopped, then those UUIDs piled up.
This also happens if you have temporary connections in /run and reboot.
We need a way to garbage collect entries that are no longer relevant.
As the keyfile databases only get loaded once from disk, we will prune
all UUIDs for which we have no more connection loaded, on the first time
we write out the files again.
Note what this means: if you "temporarily" remove a connection profile
(without NetworkManager noticing) and restore it later, then the additional
information might have been pruned. There is no way how NetworkManager
could know that this UUID is coming back. The alternative is what we did
before: pile them up indefinitely. That seems more problematic.
Previously, there was no limit how many seen-bssids are tracked.
That seems problematic, also because there is no API how to get
rid of an excessive list of entries.
We should limit the number of entries. Add an (arbitrary) limit
of 30.
But this means that we drop the surplus of entries, and for that it
seems important to keep the newest, most recently seen entries.
Previously, entries were merely sorted ASCIIbetically. Now, honor
their order (with most recently seen first).
Also, normalize the BSSIDs. From internal code, we should only get
normalize strings, but when we load them from disk, they might be bogus.
As we might cut of the list, we don't want that invalid entries
cut of valid ones. And of course, invalid entries make no sense at
all.
ifcfg-rh plugin never stored the seen bssid list to file, and
keyfile no longer does, and it's no longer parsed from GVariant.
So there is actually no way how anything could be set here.
The seen-bssids should only be populate from
"/var/lib/NetworkManager/seen-bssids". Nowhere else.
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.