Introduce a new "prefix-delegation" setting. It contains properties
related to the configuration of downstream interfaces using IPv6
prefix-delegation. The only property at the moment is "subnet-id",
which specifies which prefix to choose when the delegation contains
multiple /64 networks.
Move nm_keyfile_add_group() to libnm-glib-aux so that it can be used
by other components such as nm-initrd-generator. Rename it to
nm_key_file_add_group() to be consistent with the GLib API names
(g_key_file_*()).
We have encountered multiple incidents where users face connectivity
issues after booting, particularly due to hardware like switches that do
not pass traffic for a few seconds after startup. And services such as
NFS fail to mount because they try to initiate before the network is
fully reachable. Therefore, we are supporting
`connection.ip-ping-addresses` and `connection.ip-ping-timeout` to
allow administrators to configure the network to verify connectivity to
a specific target(such as a service like NFS) instead of relying on
gateway reachability, which may not always be relevant in certain
network configurations.
Resolves: https://issues.redhat.com/browse/RHEL-21160https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/2034https://gitlab.freedesktop.org/NetworkManager/NetworkManager-ci/-/merge_requests/1797
This patch add support to IPVLAN interface. IPVLAN is a driver for a
virtual network device that can be used in container environment to
access the host network. IPVLAN exposes a single MAC address to the
external network regardless the number of IPVLAN device created inside
the host network. This means that a user can have multiple IPVLAN
devices in multiple containers and the corresponding switch reads a
single MAC address. IPVLAN driver is useful when the local switch
imposes constraints on the total number of MAC addresses that it can
manage.
This property indicates that a non-null strv array is expected, and
an empty strv array should be returned instead of NULL if it hadn't
been created yet.
Most string properties should not accept empty strings. Add a generic
way to reject them during verify.
Add a new flag NMSettInfoProperty.direct_string_allow_empty.
Note that properties must opt-in to allow empty values. Since all
existing properties didn't have this check (but hopefully re-implemented
it in verify()), all existing properties get this flag set to TRUE.
The main point here it that new properties get the strict check by
default.
We should also review existing uses of direct_string_allow_empty,
whether the flag can be cleared. This can be done if verify() already
enforces a non-empty string, or if we accept to break behavior by
tightening up the check.
Specially in the case of BEST_EFFORT it's not completely clear what each
flag means. For example: with BEST_EFFORT, in the case of partial
success should we return an error value or a success value?
Add some comments and documentation to clarify.
Check for invalid DNS, addresses and routes errors in the `_from_dbus`
functions. With NM_SETTING_PARSE_FLAGS_STRICT, stop parsing and return
error at first error. With NM_SETTING_PARSE_FLAGS_BEST_EFFORT don't
return any error and return the values of the list which are valid.
This is the same that was done in a previous commit for ipv4 properties.
Report an error if the data type of the address-labels received via DBus
is not the expected.
Also, fix the assignment of the labels to their corresponding addresses.
As they are matched by array position, if any invalid address was
received, the array of addresses that we generate is shorter than the
array of address-labels. We were not considering this so we were
assigning the address-labels to incorrect addresses. Fix it by moving the
assignment of the labels to _nm_utils_ip4_addresses_from_variant, where
we still have the information of what the original position in the array
the address had.
Invalid addresses received via DBUS were just ignored and filtered out,
only emitting a warning to the logs. If there were still some valid
addresses, those were configured and the client was unaware of the
errors. Only if there was not any valid address at all and method was
manual, an error was returned from `verify`, but not reflecting the
real cause:
ipv4.addresses: this property cannot be empty for 'method=manual'
Check for invalid addresses errors in the `_from_dbus` functions. With
NM_SETTING_PARSE_FLAG_STRICT, parsing is aborted on first error and
error is returned. With NM_SETTING_PARSE_BEST_EFFORT, we keep parsing
and set only the valid values.
Actually, the invalid addresses were dropped in a helper function that
converts from GVariant to NMIPAddress. As it is part of the public API,
we can't change now its signature to add the GError argument. Instead,
create a new internal function and call it from the public one. The
public function will ignore the error, as it was doing previously, but
it won't emit any warning to avoid spamming the logs (we don't even
know if ignoring the invalid values was intentional when calling the
function). The new internal function might be made public in
the future, deprecating the other, but probably it is not necessary
because clients are never going to receive invalid addresses from the
daemon.
Do the same as explained above for DNS entries and routes.
Also, fix the documentation of nm_utils_ip_routes_to/from_dbus, which
said that it accepts new style routes but described the old style ones.
We will deprecate "connection.master" for "connection.controller". The
old property will become an alias for the new one. That means, when
setting the property we must emit notifications for both the old and the
new property.
Add "NMSettInfoProperty.direct_also_notify" for that. This is not fully
flexible, as it only works for direct properties (duh) and only allows
to specify one addtitional GParamSpec (of the same NMSetting). It is
however sufficient for our use.
direct_hook is a union, which currently only has one member (the set function
for a direct string). Extending this might make sense, for other set functions
(e.g. overwriting setting a strv array).
However, then the name was bad. The union is already for the set-function of
direct properties, it's not a place for various kinds of hooks (as it is
a union).
Rename.
This patch add support to HSR/PRP interface. Please notice that PRP
driver is represented as HSR too. They are different drivers but on
kernel they are integrated together.
HSR/PRP is a network protocol standard for Ethernet that provides
seamless failover against failure of any network component. It intends
to be transparent to the application. These protocols are useful for
applications that request high availability and short switchover time
e.g electrical substation or high power inverters.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1791
It also doesn't make much sense to have this. We may use a
GPtrArray to construct and keep track of a (dynamic) strv list.
Then we add the strings to the GPtrArray one by one.
We almost never will want to create a GPtrArray based on a strv array.
For most strv or string properties, we cannot distinguish between
NULL/unset/default and empty.
It would be difficult to enter in nmcli or grasp how it differs. There
are probably many bugs, where we accept empty strings, and fail to
handle them correctly.
Anyway. For most strv arrays, and empty array and NULL/unset/default are
treated the same. That means, g_object_get() tends to always return NULL
(never an empty strv array) and g_object_set() of an empty strv array
will internally leave the GArray at NULL.
For a few properties, there is a difference. See "ipv[46].dns-options".
See also "clear_emptyunset_fcn" hook in libnm-setting.
Add a way to handle such strv properties with the "direct" mechanism.
_nm_utils_dns_option_validate() allows specifying the address family,
and filters based on that. Note that all options are valid for IPv6,
but some are not valid for IPv4.
It's not obvious, that such filtering is only performed if
"option_descs" argument is provied. Otherwise, the "ipv6" argument is
ignored.
Regardless, it's also confusing to have a boolean "ipv6". When most
callers don't want a filtering based on the address family. They
actually don't want any filtering at all, as they don't pass an
"option_descs". At the same time passing a TRUE/FALSE "ipv6" is
redundant and ignored. It should be possible, to explicitly not select
an address family (as it's ignored anyway).
Instead, make the "gboolean ipv6" argument an "int addr_family".
Selecting AF_UNSPEC means clearly to accept any address family.
Most profiles don't have "connection.permissions" set. Avoid resolving the
UID to the name via getpwuid() (in nm_auth_is_subject_in_acl()), until we
know that we require it.
Historically, the NMSetting types were in public headers. Theoretically,
that allowed users to subtype our classes. However in practice that was
impossible because they lacked required access to internal functions to
fully create an NMSetting class outside of libnm. And it also was not
useful, because you simply cannot extend libnm by subtyping a libnm
class. And supporting such a use case would be hard and limit what we can
do in libnm.
Having GObject structs in public headers also require that we don't
change it's layout. The ABI of those structs must not change, if anybody
out there was actually subclassing our GObjects.
In libnm 1.34 (commit e46d484fae ('libnm: hide NMSetting types from
public headers')) we moved the structs from headers to internal.
This would have caused a compiler error if anybody was using those
struct definitions. However, we still didn't change the ABI/layout so
that we didn't break users who relied on it (for whatever reason).
It doesn't seem there were any affected user. We waited long enough.
Change internal ABI.
No longer use g_type_class_add_private(). Instead, embed the private
structs directly (_NM_GET_PRIVATE()) or indirectly
(_NM_GET_PRIVATE_PTR()) in the object.
The main benefit is for debugging in the debugger, where we can now
easily find the private data. Previously that was so cumbersome to be
effectively impossible.
It's also the fastest possible way, since NM_SETTING_*_GET_PRIVATE()
literally resolves to "&self->_priv" (plus static asserts and
nm_assert() for type checking).
_NM_GET_PRIVATE() also propagates constness and requires that the
argument is a compatible pointer type (at compile time).
Note that g_type_class_add_private() is also deprecated in glib 2.58 and
replaced by G_ADD_PRIVATE(). For one, we still don't rely on 2.58. Also,
G_ADD_PRIVATE() is a worse solution as it supports a usecase that we
don't care for (public structs in headers). _NM_GET_PRIVATE() is still
faster, works with older glib and most importantly: is better for
debugging as you can find the private data from an object pointer.
For NMSettingIPConfig this is rather awkward, because all direct
properties require a common "klass->private_offset". This was however
the case before this change. Nothing new here. And if you ever touch
this and do something wrong, many unit tests will fail. It's almost
impossible to get wrong, albeit it can be confusing to understand.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1773
In nm_setting_infiniband_get_virtual_interface_name(), no longer try to
detect whether the cached value is still up to date. Instead, as we now
have a fix sized buffer for the name, just always generate the name on
every call. It's simpler.
We have several variants to get the NMSetting from an NMConnection. Some
of them are public API (nm_connection_get_setting(), nm_connection_get_setting_by_name()).
The most efficient way is lookup by NMMetaSettingType. Expose that as
internal API, so it can be used. The NMMetaSettingType is internal, but
it exists because it's a very useful enum. Allow others to make use of
it.
Also, add a static assert which prevents various wrong uses at compile
time, for example
_nm_connection_get_setting_by_metatype(connection, NM_TYPE_SETTING_CONNECTION)
This is the IPv6 equivalent of arp_ip_target option. It requires
arp_interval set and allow the user to specify up to 16 IPv6 addresses
as targets. By default, the list is empty.
Add a new "ovs-port.trunks" property that indicates which VLANs are
trunked by the port.
At ovsdb level the property is just an array of integers; on the
command line, ovs-vsctl accepts ranges and expands them.
In NetworkManager the ovs-port setting stores the trunks directly as a
list of ranges.
Support managing the loopback interface through NM as the users want to
set the proper mtu for loopback interface when forwarding the packets.
Additionally, the IP addresses, DNS, route and routing rules are also
allowed to configure for the loopback connection profiles.
https://bugzilla.redhat.com/show_bug.cgi?id=2060905
These are just general purpose D-Bus utils, based on glib and GDBus.
They fit perfectly to libnm-glib-aux. Move the code.
Also, there is already the file "src/core/nm-dbus-utils.c", having two
files with the same name on our source tree is just confusing.
We have 4 legacy properties ("ipv[46].addresses", "ipv[46].routes") that
got replaced by newer variants ("ipv[46].address-data", "ipv[46].route-data").
When the client side of libnm (_nm_utils_is_manager_process) serializes
those properties, it must only serialize the newer version. That is so
that the forward/backward compatibility works as intended.
Previously, there was the NM_SETTING_PARAM_LEGACY GObject property flag.
That was fine, but not very clear.
For one, the legacy part of those properties is only about D-Bus. In
particular, they are not deprecated in libnm, keyfile, or nmcli. Thus
the name wasn't very clear.
Also, in the meantime we have more elaborate property meta data, that
goes beyond the meta data of the GObject property.
Move NM_SETTING_PARAM_LEGACY to NMSettInfoProperty.to_dbus_only_in_manager_process.
I think, this is a better name. It's also right at
```
_nm_properties_override_gobj(
properties_override,
g_object_class_find_property(G_OBJECT_CLASS(setting_class), NM_SETTING_IP_CONFIG_ROUTES),
NM_SETT_INFO_PROPERT_TYPE_DBUS(NM_G_VARIANT_TYPE("a(ayuayu)"),
.to_dbus_fcn = ip6_routes_to_dbus,
.compare_fcn = _nm_setting_ip_config_compare_fcn_routes,
.from_dbus_fcn = ip6_routes_from_dbus, ),
.to_dbus_only_in_manager_process = TRUE,
.dbus_deprecated = TRUE, );
```
that is, directly at the place where we describe how the D-Bus property behaves.
When an authentication attempt fails, NetworkManager re-requests new secrets
from agents before retrying. This is currently decided outside of the NMSetting
objects. With this change the decision if a re-request of new secrets is really
needed is moved down to the NMSetting implementations.
For the case "802.1x authentication with TLS" a certificate with password is
configured and the assumption is, that this can never be wrong and no re-request
is needed.
NMConnection is an interface, implemented by NMSimpleConnection and
NMRemoteConnection.
For the most part, an NMConnection is only the content of the profile
(the settings). The "path" of the connection refers to the D-Bus path,
and wouldn't really make sense of the NMConnection interface or the
NMSimpleConnection type.
As such, the daemon (which only uses NMConnection and
NMSimpleConnection) never sets the path. Only libnm does.
NMClient uses NMRefString extensively for the D-Bus interface and the
path is already internalized. Take advantage of that. It is very likely,
that we are able to share the path instance in libnm at which point it
makes sense to use NMRefString.
Also, during nm_simple_connection_new_clone(), we can just take another
reference instead of cloning the string.
Bond option values are just strings, however, some of them get
validated to be numbers, etc.
We also have effectively boolean values, like "use-carrier". Internally,
this is not validates as a boolean (_nm_utils_ascii_str_to_bool()) but
instead is an integer of either "0" or "1".
Add a helper function_nm_setting_bond_opt_value_as_intbool() to access
and parse such values.
The bond setting does some minimal validation of the options.
At least for those number typed values, it validates that the
string can be interpreted as a number and is within a certain range.
Add nm_assert() checks to our opt_value_u$SIZE() functions, that the
requested option is validated to be in a range which is sufficiently
narrow to be converted to the requested type. If that were not the case,
we would need some special handling (or question whether the option should
be retrieved as this type).
Currently nm_setting_bond_get_option_normalized() and
nm_setting_bond_get_option_or_default() are identical functions. As the
first one is exposed as public API and has a better name, let's drop the
second one.
All callers of _nm_setting_get_private() got the offset from the
property info. Add a wrapper _nm_setting_get_private_field() that
takes the property info. This way, it can add some assertions.
Several properties like "connection.type" are enum-like and only take a few
known values. We can use a NMRefString to share their instances.
Currently nm_setting_duplicate() does not yet explicitly handle direct properties.
But it should, because it can handle them more efficiently. If it would do that, it
would be very cheap to "copy" a NMRefString. But even with the current implementation
will the result be deduplicated.
We want that our properties have little special cases and follow a
few common behaviors. For example, we have string properties, and those
should mostly behave the same (e.g. by being "direct-string"
properties).
That is already not fully enough, because we have slightly different
behaviors. For example, we have string properties that should have their
whitespace stripped, that should be ascii case down converted, that
should be normalized IP or MAC addresses. So far, that was expressed via
simple fields in NMSettInfoProperty, like NMSettInfoProperty's
direct_set_string_ascii_strdown field.
But that is not enough. In particular, for "wireguard.private-key" we
perform a different kind of normalization (base64 parsing, and taking
care not to leak secret in memory). It seems to special to add a boolean
flag "direct_set_string_wireguard_private_key".
Instead, add a hook that can cover that.
We need a hook, because we want one setter implementation throughout. Commonly,
we have at least two setters: the GObject set_property() and from D-Bus.
Both should call into the same underlying implementation, to avoid code
duplication. For that, the tweaked behavior must be "down", that is at
the deepest point in the call stack where we set the string. That's why
we need the hook. The alternative would be two special implementation
for GObject and D-Bus setters (and in the future we might add setters
from keyfile).