The "shared" directory is used by libnm-core, it should thus only depend on
code that is in the "shared" directory. Otherwise there is a circular
dependency, and meson's subdir() does not work nicely.
Also, libnm-core is really part of (and also an extension of) libnm-core,
so it belongs there.
I guess, the original idea was that this is also an extension for libnm,
so another project could take these utility functions (by copying them
into their source tree) and use them. That is still possible, it's
just that the sources are no longer under the shared directory.
Also add a readme to explain the non-obvious meaning of these files.
Originally, these files were part of libnm-core and linked together.
However, that is a licensing violation, because the code is GPL-2.0+
licensed, while libnm-core also gets linked with libnm (it must thus
be LGPL-2.1+). The original intent behind moving the code to "shared/"
was to avoid the licensing issue, but also to prepare when we would add
a separate, GPL licensed libnm-keyfile. However, currently we hope to
be able to relicense the code, so that it actually could be exposed as
part of libnm. This is work in progress at ([1]).
[1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/ ## 517
Anyway, the current directory layout is problematic. libnm-keyfile
depends on libnm-core, while libnm-core depends on code under shared.
That means, there is a circular dependency and meson's subdir() does
not work well.
Move the code.
When a device is not marked as unmanaged, but also not actively managed
by NetworkManager, then NetworkManager will generate an in-memory
profile to represent the active state, if the device is up and
configured (with an IP address).
Such profiles are commonly named like "eth0", and they are utterly
confusing to users, because they look as if NetworkManager actually
manages the device, when it really just shows that somebody else configures
the device.
We should express this better in the UI, hence add flags to indicate
that.
In practice, such profiles are UNSAVED, NM_GENERATED, and VOLATILE. But
add an explicit flag to represent that.
https://bugzilla.redhat.com/show_bug.cgi?id=1816202
The 'peer' property of ovs-patch is inserted into the 'options' column
of the ovsdb 'Interface' table. The ovs-vswitchd.conf.db man page says
about it:
options : peer: optional string
The name of the Interface for the other side of the patch. The
named Interface’s own peer option must specify this Interface’s
name. That is, the two patch interfaces must have reversed name
and peer values.
Therefore, it is wrong to validate the peer property as an IP address
and document it as such.
Fixes: d4a7fe4679 ('libnm-core: add ovs-patch setting')
Commit 37e7fa38c2 ("nm-supplicant-interface: enable OWE security
when transition mode is available") adds the OWE security flag in
case a valid OWE transtition mode IE is present on the beacon.
It also removes the OWE security flag in case the Iinformation elements
of a beacon are updated and a OWE transition mode IE can't be found.
When a pure OWE AP updates it's Information Elements (e.g. BSS Load
Element), the OWE security flag is falsely removed.
Introduce a new NM_802_11_AP_SEC_KEY_MGMT_OWE_TM security flag and use
it exclusively for OWE transition mode. Don't use the
M_802_11_AP_SEC_KEY_MGMT_OWE security flag on transition-mode APs.
Signed-off-by: David Bauer <mail@david-bauer.net>
nm_keyfile_read() and nm_keyfile_write() will be public API.
As such, it must be flexible and extendible for future needs.
There is already the handler callback that fully solves this
(e.g. a future handler event could request whether a certain
behavior is enabled or not).
As additional possibility for future extension, add a flags
argument. Currently no flags are implemented.
On Debian sid, libnss3-dev (2:3.53-1) causes a compiler warning:
In file included from ../libnm-core/nm-crypto-nss.c:13:
/usr/include/nss/pk11pub.h:951:1: error: function declaration isn't a prototype [-Werror=strict-prototypes]
951 | int SECMOD_GetSystemFIPSEnabled();
| ^~~
Iterating the hash gives the entries in undefined order. That
means, when validation would fail for more than one option,
then the error message arbitrarily points out one or the other.
Instead, process the entries in a defined order.
Note that nm_setting_ethtool_set_coalesce() used to coerce
"coalesce-adaptive-[rt]x" values to 0 or 1. The alternative
API doesn't do that. But so does nm_setting_option_set()
not tell you whether the value you set is valid. That is
not the options of the setters, for that we have verify().
More general purpose API for generic options of settings.
The predicate function is also nicely usable via bindings.
One question is about the form of the predicate. In this case,
it is convenient to pass nm_ethtool_optname_is_coalesce(). On the
other hand, it's not very flexible as it does not accept a user
data argument. Use NMUtilsPredicateStr here, which is not flexible
but convenient for where it's used.
NMSettingEthtool is implemented using "gendata", meaning a hash
of GVariant. This is different from most other settings that have
properties implemented as GObject properties. There are two reasons
for this approach:
- The setting is transferred via D-Bus as "a{sv}" dictionary.
By unpacking the dictionary into GObject properties, the setting
cannot handle unknown properties. To be forward compatible (and
due to sloppy programming), unknown dictionary keys are silently
ignored when parsing a NMSetting. That is error prone and also
prevents settings to be treated loss-less.
Instead, we should at first accept all values from the dictionary.
Only in a second step, nm_connection_verify() rejects invalid settings
with an error reason. This way, the user can create a NMSetting,
but in a separate step handle if the setting doesn't verify.
"gendata" solves this by tracking the full GVariant dictionary.
This is still not entirely lossless, because multiple keys are
combined.
This is for example interesting if an libnm client fetches a connection
from a newer NetworkManager version. Now the user can modify the
properties that she knows about, while leaving all unknown
properties (from newer versions) in place.
- the approach aims to reduce the necessary boiler plate to create
GObject properties. Adding a new property should require less new code.
This approach was always be intended to be suitable for all settings, not only
NMSettingEthtool. We should not once again try to add API like
nm_setting_ethtool_set_feature(), nm_setting_ethtool_set_coalesce(), etc.
Note that the option name already fully encodes whether it is a feature,
a coalesce option, or whatever. We should not have
"nm_setting_set_$SUB_GROUP (setting, $ONE_NAME_FROM_GROUP)" API, but
simply "nm_setting_option_set (setting, $OPTION)" accessors.
Also, when parsing a NMSettingEthtool from a GVariant, then a feature
option can be any kind of variant. Only nm_setting_verify() rejects
variants of the wrong type. As such, nm_setting_option_set*() also
doesn't validate whether the variant type matches the option. Of course,
if you set a value of wrong type, verify() will reject the setting.
Add new general purpose API for this and expose it for NMSetting.
We are going to expose some of this API in libnm.
The name "gendata" (for "generic data") is not very suited. Instead,
call the public API nm_setting_option_*(). This also brings no naming
conflict, because currently no API exists with such naming.
Rename the internal API, so that it matches the API that we are going
to expose next.
This was intended for when the gendata hash should be converted
to/from a GValue/GHashTable. This would have been used, if
we also would have added a GObject property that exposes
the hash. But that was never done (at least not for NMSettingEthtool
and not yet).
This code is not used. If you ever need it, revert the patch
or implement it anew.
This function is not used nor does it seem useful.
Either you only need the names (nm_setting_gendata_get_all_names())
or you need the names and values together (_nm_setting_gendata_get_all()).
Getting the values without knowing the corresponding name makes
little sense. If you need it, call _nm_setting_gendata_get_all()
instead.
Don't duplicate the code that maps the option to the variant type.
Also, only resolve the name to NMEthtoolID once. Multiple calls
to nm_ethtool_optname_is_*() unnecessarily need to convert the
string to the ethtool id multiple times.
This will be used for nm_setting_option_clear_by_name(), to
filter based on a name. But it is a general purpose typedef
for a predicate, not tied to NMSetting or option.
The filter function in nm_setting_gendata_clear_all() is useful
for when you want to only clear values according to a predicate,
if no such function is supplied all values will be cleared.
https://bugzilla.redhat.com/show_bug.cgi?id=1614700
UBSan marks these:
libnm-core/tests/test-setting.c:2146:2: runtime error: left shift of 65521 by 16 places cannot be represented in type 'int'
#0 0x561739bed935 in test_tc_config_qdisc libnm-core/tests/test-setting.c:2146
By passing as length of the MAC addresses -1 for both arguments, one
could get through to compare empty strings, NULL, and addresses longer
than the maximum. Such addresses are not valid, and they should never
compare equal (not even to themselves).
This is a change in behavior of public API, but it never made sense to
claim two addresses are equal, when they are not even valid addresses.
Also, avoid undefined behavior with "NULL, -1, NULL, -1" arguments,
where we would call memcmp() with zero length and NULL arguments.
UBSan flags that too.
When parsing user input if is often convenient to allow stripping whitespace.
Especially with escaped strings, the user could still escape the whitespace,
if the space should be taken literally.
Add support for that to nm_utils_buf_utf8safe_unescape().
Note that this is not the same as calling g_strstrip() before/after
unescape. That is, because nm_utils_buf_utf8safe_unescape() correctly
preserves escaped whitespace. If you call g_strstrip() before/after
the unescape, you don't know whether the whitespace is escaped.