Otherwise we assert in _nm_utils_strv_to_slist() when setting a property,
using the code like:
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (param_spec));
g_param_value_set_default (param_spec, &value);
g_object_set_property (G_OBJECT (setting), prop, &value);
e.g:
nmcli con mod my_profile eth.mac-address-blacklist "02:14:20:e6:16:83"
(changed by commit 6a4127cfa0)
g_strsplit_set() puts empty strings ("") into the resulting string array when
a delimiter character appears as the first or last character in the string or
when there are adjacent delimiter characters. However, this is not what is
useful in most cases.
Before, _nm_setting_to_dbus() would return NULL instead of an empty
hash. This would be the case, if all properties are default.
When exporting connections via DBUS, we eventually call
_nm_setting_to_dbus() to convert the connection into a hash of hashes.
By _nm_setting_to_hash() converting empty hashes to NULL, the setting
is missing. Not returning empty hashes means that to_dbus() and
new_from_dbus() don't make a valid round-trip conversion.
Fix that by always returning a hash from _nm_setting_to_dbus()
https://bugzilla.gnome.org/show_bug.cgi?id=735255
See-also: 4d32618264
Signed-off-by: Thomas Haller <thaller@redhat.com>
Use G_TYPE_PTR_ARRAY for GPtrArray-of-NMObject-valued properties,
because it has better introspection/bindings support.
As with the strdict change in libnm-core, we need to manually copy the
array in get_property() implementations, to preserve the standard
semantics that get_property() returns a copy, not the internal array.
(This patch also changes those properties so that they are always
non-NULL until dispose(); previously some of them could be either NULL
or 0-length at different times.)
Change NMSettingDCB's guint-array properties to G_TYPE_ARRAY, with
annotations indicating the element type.
Since DBUS_TYPE_G_UINT_ARRAY was already represented as a GArray, this
does not require any changes anywhere else.
Change all DBUS_TYPE_G_UCHAR_ARRAY properties to G_TYPE_BYTES, and
update corresponding APIs. Notably, this means they are now refcounted
rather than being copied.
Update the rest of NM for the changes. The daemon still converts SSIDs
to GByteArrays internally, because changing it to use GBytes has lots
of trickle-down effects. It can possibly be changed later.
APIs that take arbitrary data should take it in the form of a pointer
and length, not a GByteArray, so that you can use them regardless of
what format you have the data in (GByteArray, GBytes, plain array,
etc).
Make the :addresses and :routes properties be GPtrArrays of
NMIP4Address, etc, rather than just reflecting the D-Bus data.
Make the :dns properties be arrays of strings rather than arrays of
binary IP addresses (and update the corresponding APIs as well).
Change all DBUS_TYPE_G_MAP_OF_STRING properties to G_TYPE_HASH_TABLE,
with annotations indicating they are string->string. Not much outside
libnm-core needs to changed for this, since DBUS_TYPE_G_MAP_OF_STRING
was already represented as a hash table.
(One change needed within libnm-core is that we now need to copy the
hash tables in get_property(), or else the caller will receive a
reffed copy of the object's own hash table, which we don't want.)
Change all DBUS_TYPE_G_LIST_OF_STRING and DBUS_TYPE_G_ARRAY_OF_STRING
properties to G_TYPE_STRV, and update everything accordingly.
(This doesn't actually require using
_nm_setting_class_transform_property(); dbus-glib is happy to transform
between 'as' and G_TYPE_STRV.)
Make all mac-address properties (including NMSettingBluetooth:bdaddr,
NMSettingOlpcMesh:dhcp-anycast-addr, and NMSettingWireless:bssid) be
strings, using _nm_setting_class_transform_property() to handle
translating to/from binary form when dealing with D-Bus.
Update everything accordingly for the change, and also add a test for
transformed setting properties to test-general.
Add a new kind of setting property override, for indicating that a
property exists in both the NMSetting and the D-Bus representation,
but in different formats, requiring conversion from one to the other.
Also, if a property is transformable, then compare the transformed
forms in nm_setting_compare() (since the D-Bus property types have
more metadata built-in).
NMParamSpecSpecialized existed basically to provide a version of
GParamSpecBoxed that could compare dbus-glib-valued properties
correctly.
However, g_param_values_cmp() was only used by NM directly in one
place (NMSetting's compare_property()), and we don't actually need to
indirect through GParamSpec there; we could just call
NMParamSpecSpecialized's value-comparison function directly.
So, change all NMParamSpecSpecialized properties to GParamSpecBoxed,
rename the _gvalues_compare() function it used to
"nm_property_compare()", and use that from NMSetting.
(g_param_values_cmp() also gets used internally by
g_param_value_defaults(), but all NMParamSpecSpecialized properties
have a default value of NULL, so GParamSpecBoxed's pointer-equality
check will do the job just fine there.)
Make the formerly-nm-param-spec-specialized test compile (fix use of
inet_pton), and pass (include the mandatory "gateway" element in the
IPv6 addresses), make it use gtestutils and g_assert (so it actually
fails when it fails), and test a few more cases.
Remove the virtual :interface-name properties and their getters, and
use property overrides to do backward-compat handling when
serializing/deserializing.
Now when constructing an NMConnection from a hash, if the virtual
property is set and the NMSettingConnection property isn't, then the
override for NMSettingConnection:interface-name will set that property
to the value of the virtual interface-name. And when converting an
NMConnection to a hash, the overrides for the virtual properties will
return the value of NMSettingConnection:interface-name.
Simplify the use of _nm_register_setting() by having it splice
together various symbol names itself rather than requiring them to be
specified explicitly, and extend it to also ensure that the type's
corresponding error type is registered (allowing one to find it via
g_type_from_name() if necessary).
Add a method to determine if a connection applies to a virtual device.
Perhaps eventually the logic should be spread across the NMSetting
classes, but for now it's better off having it in NMConnection than
once in NMManager and once in nmcli.
The virtual :interface-name properties (eg,
NMDeviceBond:interface-name) are deprecated in favor of
NMSettingConnection:interface-name, and nm_connection_verify() ensures
that their values are kept in sync. So (a) there is no need to set
those properties when we can just set
NMSettingConnection:interface-name instead, and (b) we can replace any
calls to the setting-specific get_interface_name() methods with
nm_connection_get_interface_name() or
nm_setting_connection_get_interface_name().
Since we enforce the fact that bond, bridge, team, and vlan
interface-name properties match NMSettingConnection:interface-name,
nm_connection_get_virtual_iface_name() can be replaced with
nm_connection_get_interface_name() basically everywhere.
The one place this doesn't work is with InfiniBand partitions (where
get_virtual_iface_name() was actually computing the name), but for the
most part we only need to care about the interface names of InfiniBand
partitions in places where we also already need to do some other
InfiniBand-specific handling as well, so we can use an
InfiniBand-specific method
(nm_setting_infiniband_get_virtual_interface_name()) to get it.
(Also, while updating nm_device_get_virtual_device_description(), fix
it to handle InfiniBand partitions too.)
Drop the NMSetting properties that were marked deprecated in
libnm-util in 0.9.10, but use nm_setting_class_add_dbus_property() to
deal with them appropriately when serializing/deserializing.
Add _nm_setting_class_add_dbus_only_property(), for declaring
properties that appear in the D-Bus serialization, but which don't
correspond to GObject properties.
Since some property overrides will require examining settings other
than the setting that they are on (eg, the value of
802-11-wireless.security depends on whether an
NMSettingWirelessSecurity setting is present, and
NMSettingConnection:interface-name might sometimes be set from, eg,
bond.interface-name), we also update _nm_setting_to_dbus() to take the
full NMConnection as an argument, and _nm_setting_new_from_dbus() to
take the full connection hash.
Additionally, with some deprecated properties, we'll want to validate
them on construction, but we don't need to keep the value around after
that. So allow _nm_setting_new_from_dbus() to return a verification
error directly, so we don't need to store the value until the verify()
call.
On failure, nm_connection_replace_settings() would leave the
connection in an undefined state. Fix it so that either (a) the
settings are replaced and the resulting connection is valid and we
return TRUE, or (b) the connection is untouched and we return FALSE
and an error. (And add a test case for this.)
Reorganize _nm_setting_new_from_dbus() to create an empty NMSetting
first and then set each of its properties, rather than passing all of
the properties to g_object_newv(). We don't need to pass them at
construct time since no NMSetting properties are CONSTRUCT_ONLY, and
organizing the function this way is a prereq for some later
functionality (being able to run code when a property *isn't* present
in the hash).
Rename nm_connection_to_hash() to nm_connection_to_dbus(), and
nm_connection_new_from_hash() to nm_connection_new_from_dbus(). In
addition to clarifying that this is specifically the D-Bus
serialization format, these names will also work better in the
GDBus-based future where the serialization format is GVariant, not
GHashTable.
Also, move NMSettingHashFlags to nm-connection.h, and rename it
NMConnectionSerializationFlags.
Make nm_setting_to_hash() and nm_setting_new_from_hash() private, and
remove the public nm_setting_update_secrets() wrapper around the
existing private _nm_setting_update_secrets().
These functions should really only be called from the corresponding
NMConnection-level methods, and in particular, with certain
compatibility properties in the future, we will need to consider the
entire connection all at once when setting properties, so it won't
make sense to serialize/deserialize a single setting in isolation.
g_object_class_list_properties() can't return NULL if called
correctly.
Also remove two failed attempts to use g_value_transform():
nm_setting_new_from_hash() was transforming src_value to its own type
(rather than to param_spec->value_type, which was presumably
intended), so it was a no-op (in addition to being unnecessary anyway,
since GObject will attempt to transform the value internally if
needed). And update_one_secret() was calling g_value_transform() on an
uninitialized GValue, so it would have always hit a
g_return_val_if_fail() in g_value_transform() if that code was ever
reached (which apparently it wasn't).
verify() used to modify interface-name of the base settings. This is
discouraged, because verify() should not touch the connection.
For libnm-core we can change behavior and only modify the connection
in normalize().
Also, be more strict not to verify() sucessfully on invalid
interface-name.
Signed-off-by: Thomas Haller <thaller@redhat.com>
When calling nm_setting_verify() without providing any settings in @all_settings,
we assume that the setting on its own might be valid.
Only when checked together with all settings, we want to consider the setting
in the full context. nm_connection_verify() ensures to pass on a list of settings.
Signed-off-by: Thomas Haller <thaller@redhat.com>
Previously, NMSettingInfiniband:verify() silently modifies the
setting for invalid MTU. verify() should not do that.
For libnm-core we can change behavior and implement normalization
of MTU. This changes behavior for NMSettingInfiniband:verify() so
that MTU gets no longer fixed by verify() alone. Instead verify()
fails with a verification error.
Due the possibility to normalize the MTU, NM still can receive
invalid settings and fix it.
For libnm-core we don't change behavior, merely add a code comment.
Signed-off-by: Thomas Haller <thaller@redhat.com>
We would expect that attempts to normalize a connection
are successful as verify() indicates. This way, a connection
is not modified if it cannot be fixed, and a connection will
be valid and modified after attempts to normalization.
However, there might be subtle, unexpected ways how this can fail.
For example, if NMSettingConnection:verify() detects a missing base type
setting, it returns NORMALIZABLE_ERROR if it finds a valid
NMSettingConnection:type. Normalization then adds an empty, default
setting. However, a new verify() might fail due to other reasons.
This would be a bug in NMSettingConnection:verify() which must not
indicate that it is able to normalize the connection, when it actually
is unable to do so.
Such bugs need fixing, but the code should be more robust to this case
because there might be complex, unanticipated situations.
Especially since NM relies on having a valid connection after normalize(),
so a strict error-out behavior is important.
Signed-off-by: Thomas Haller <thaller@redhat.com>
nm_connection_normalize() can now detect the 'type' property
based on existing base settings.
It can also create a (default) base setting.
Signed-off-by: Thomas Haller <thaller@redhat.com>
Some NMSettingConnection:slave-type types require a matching slave #NMSetting.
Add normalization of either the 'slave-type' property or the slave-setting.
Also be more strict in NMSettingConnection:verify() to enforce an
existing slave-setting depending on the slave-type.
Signed-off-by: Thomas Haller <thaller@redhat.com>
Partly it was already there. This makes NMSettingConnection:verify() stricter
then before, but validates the same as of NMConnection:_nm_connection_verify().
Signed-off-by: Thomas Haller <thaller@redhat.com>
When removing/replacing a NMSetting in an NMConnection, we have
to disconnect setting_changed_cb() from the "notify" signal.
Signed-off-by: Thomas Haller <thaller@redhat.com>
In general, we don't set errors if passing a completely invalid @self
pointer to a method. We usually also don't set the error argument
when asserting. So, just drop it.
Signed-off-by: Thomas Haller <thaller@redhat.com>
This is an utility function that can be called during verify()
to find an NMSetting from @all_settings.
This is especially useful for looking up the NMSettingConnection
which usually is present. So just get it quickly. In the unexpected
case that it is missing, it sets @error and we can return.
Signed-off-by: Thomas Haller <thaller@redhat.com>
As NM_SETTING_SECRET_FLAGS_ALL is used in libnm/nm-vpn-plugin-utils.c,
it is exposed as internal API and should be declared in
nm-core-internal.h.
Signed-off-by: Thomas Haller <thaller@redhat.com>
Add a header file to expose private utility functions from libnm-core
that can be used by NetworkManager (core) and libnm.so. The header
is also used to give privileged access to libnm-core. Since NM links
statically, these functions are not exported and not part of public ABI.
This also removes the NM_UTILS_PRIVATE_CALL() macro and libnm.so no
longer exports nm_utils_get_private().
Before, this functionality was partly declared in nm-utils-private.h.
This was wrong because nm-utils-private.h is for functionality
entirely private to libnm-core.
Signed-off-by: Thomas Haller <thaller@redhat.com>