Using plain numbers make it cumbersome to grep for
setting types by priority.
The only downside is, that with the enum values it
is no longer obvious which value has higher or lower
priority.
Also, introduce NM_SETTING_PRIORITY_INVALID. This is what
_nm_setting_type_get_base_type_priority() returns. For the moment
it still has the same numerical value 0 as before. Later, that
shall be distinct from NM_SETTING_PRIORITY_CONNECTION.
In an ideal world, we should not validate connections containing
options not valid for the current bond mode. However adding such
restriction now means that during an upgrade to the new NM version
some connections that were valid before become invalid, possibly
disrupting connectivity.
Instead, consider invalid options as a normalizable error and remove
them during normalization.
Converting the setting to a "canonical" form without invalid options
is important for the connection matching logic, where such invalid
options can cause false mismatches.
When the two base settings are present, use one of higher priority.
This will pick the "bridge" setting when both "bridge" and "bluetooth" are
present for a Bluetooth NAP connection.
We will need multiple base settings for Bluetooth NAP servers: bluetooth and
bridge. We want to identify the device as "bluetooth" to the user, but leave
the Bridge factory handle it.
The "connection.type" is somewhat redundant -- let's keep it for what the user
sees. And identify the actual base setting to pick the right factory by the
actually present setting.
Returning TRUE for zero makes no sense. Obviously, zero is not a power
of two.
Also, the function is used to check whether a number has only one bit
(flag) set, so, an alternative name would be "has-one-bit-set", which
also should return FALSE for zero. All callers didn't really care for
the previous meaning "has-at-most-one-bit-set".
This also avoids the issue of checking (x >= 0), which causes
-Wtype-limits warnings for unsigned types. Which was avoided
by doing (x == 0 || x > 0), which caused -Wlogical-op warning,
which then was avoided (x == 0 || (x > 0 && 1)). Just don't.
We recently added -Wlogical-op in our build process
(commit #41e7fca59762dc928c9d67b555b1409c3477b2b0).
Seems that old versions of gcc (4.8.x) will hit that warning with our
implementation of our "nm_utils_is_power_of_two" and
"test_nm_utils_is_power_of_two_do" macros.
Fool it just adding an always TRUE check.
Use C-style backslash escaping to sanitize non-UTF-8 strings.
The functions are compatible with glib's g_strcompress() and
g_strescape().
The difference is only that g_strescape() escapes all non-printable,
non ASCII character as well, while nm_utils_str_utf8safe_escape()
-- depending on the flags -- preserves valid UTF-8 sequence except
backslash.
The flags allow to optionally escape ASCII control characters and
all non-ASCII (valid UTF-8) characters. But the option to preserve
valid UTF-8 (non-ASCII) characters verbatim, is what distinguishes
from g_strescape().
vpn.data, bond.options, and user.data encode their values directly as
keys in keyfile. However, keys for GKeyFile may not contain characters
like '='.
We need to escape such special characters, otherwise an assertion
is hit on the server:
$ nmcli connection modify "$VPN_NAME" +vpn.data 'aa[=value'
Another example of encountering the assertion is when setting user-data key
with an invalid character "my.this=key=is=causes=a=crash".
I used to use g_strv_length ((char **) p) instead, but that feels
ugly because it g_strv_length() is not designed to operate on
arbitrary pointer arrays.
It is not uncommon that a flags type has also the value 0 mapped,
for example to "unknown" or "none".
In that case, we should not return an empty string, but instead
that zero value.
Also, flags actually have an unsigned type. That isn't a real
problem to cast it to a signed int. But be more careful about
it and use unsigned while handling unsigned values and only
cast to int once.
This adds definition of a set of known route option attributes to
libnm-core and helper functions.
nm_ip_route_attribute_validate() performs the validation of the
attribute type and, in case of a formatted string attribute, of its
content.
nm_ip_route_get_variant_attribute_spec() returns the attribute format
specifier to be passed to nm_utils_parse_variant_attributes(). Since
at the moment NMIPRoute is the only user of NMVariantAttributeSpec and
the type is opaque to users of the library, the struct is extended to
carry some other data useful for validation.
- for nm_utils_enum_to_str(), whenever encounter a numeric value
that has no expression as enum/flag, encode the value numerically.
For enums, encode it as decimal. For flags, encode it as hexadecimal
(with 0x prefix).
Also check that an existing value_nick cannot be wrongly interpreted
as a integer, and if they would, encode them instead as integers only.
- Likewise, in nm_utils_enum_from_str() accept numerical values
and for nm_utils_enum_get_values() return enum nicks that look
like numeric values in their numeric form only.
- In nm_utils_enum_from_str(), don't use g_strsplit(), but clone the
string only once and manipulate it inplace.
- Accept '\n' and '\r' as additional delimiters for flags.
- For consistency, also return an err_token for enum types. If the caller
doesn't care about that, he should simply not pass the out-argument.
While technically it's already possible to implement a fail-over
mechanism using multiple connections (for example, defining a higher
priority DHCP connection with short DHCP timeout and a lower priority
one with static address), in practice this doesn't work well as we try
to autoactivate each connection 4 times before switching to the next
one.
Introduce a connection.autoconnect-retries property that can be used
to change the number of retries. The special value 0 means infinite
and can be used to try the connection forever. A -1 value means the
global configured default, which is equal to 4 unless overridden.
https://bugzilla.gnome.org/show_bug.cgi?id=763524
g_assert() uses G_LIKELY(), which in turn uses _G_BOOLEAN_EXPR().
As glib's version of _G_BOOLEAN_EXPR() uses a local variable
_g_boolean_var_, we cannot nest a G_LIKELY() inside a G_LIKELY(),
or inside a g_assert(), or a g_assert() inside a g_assert().
Workaround that, by redefining the macro.
I already encountered this problem before, when having a nm_assert()
inside a ({...}) block, inside a g_assert(). Then I just avoided that
combination, but this situation is quite easy to encounter.
Since we possibly already link against libjansson, we can also expose some
helper utils which allows nmcli to do basic validation of JSON without
requiring to duplicate the effort of using libjansson.
Also, tighten up the cecks to ensure that we have a JSON object at hand.
We are really interested in that and not of arrays or literals.
crypto_verify_private_key_data() must try to decrypt the key only when
a password is supplied.
Previously the decrypt test always passed because we detected an
unsupported cipher and faked success. Now since version 3.5.4 gnutls
supports PBES1-DES-CBC-MD5 and the key is actually decrypted when a
password is supplied.
Also, don't assert that a wrong password works because we're now able
to actually verify it (only with recent gnutls).
https://bugzilla.gnome.org/show_bug.cgi?id=771623
The core only consider the first address for shared connections, don't
pretend we accept multiple addresses. This change doesn't prevent
supporting multiple addresses in the future.
https://bugzilla.gnome.org/show_bug.cgi?id=763937
Now that we validate the JSON syntax of a team/team-port
configuration, any existing connection with invalid JSON configuration
would fail to load and disappear upon upgrade. Instead, modify the
setting plugins to emit a warning but still load the connection with
empty configuration.
Since commit 7d1709d7f6 ("device: check may_fail when progressing to
IP_CHECK") NM correctly checks the may-fail properties to decide
whether a connection must fail after the completion of IP
configuration. But for ipv4.method=disabled and ipv6.method=ignore the
IP configuration is always considered failed and thus setting
may-fail=no results in a connection that can never succeed.
To prevent such wrong configuration, force may-fail to TRUE for those
methods during connection normalization.
https://bugzilla.redhat.com/show_bug.cgi?id=1334884
For the per-connection settings "ethernet.cloned-mac-address"
and "wifi.cloned-mac-address", and for the per-device setting
"wifi.scan-rand-mac-address", we may generate MAC addresses using
either the "random" or "stable" algorithm.
Add new properties "generate-mac-address-mask" that allow to configure
which bits of the MAC address will be scrambled.
By default, the "random" and "stable" algorithms scamble all bits
of the MAC address, including the OUI part and generate a locally-
administered, unicast address.
By specifying a MAC address mask, we can now configure to perserve
parts of the current MAC address of the device. For example, setting
"FF:FF:FF:00:00:00" will preserve the first 3 octects of the current
MAC address.
One can also explicitly specify a MAC address to use instead of the
current MAC address. For example, "FF:FF:FF:00:00:00 68:F7:28:00:00:00"
sets the OUI part of the MAC address to "68:F7:28" while scrambling
the last 3 octects.
Similarly, "02:00:00:00:00:00 00:00:00:00:00:00" will scamble
all bits of the MAC address, except clearing the second-least
significant bit. Thus, creating a burned-in address, globally
administered.
One can also supply a list of MAC addresses like
"FF:FF:FF:00:00:00 68:F7:28:00:00:00 00:0C:29:00:00:00 ..." in which
case a MAC address is choosen randomly.
To fully scamble the MAC address one can configure
"02:00:00:00:00:00 00:00:00:00:00:00 02:00:00:00:00:00".
which also randomly creates either a locally or globally administered
address.
With this, the following macchanger options can be implemented:
`macchanger --random`
This is the default if no mask is configured.
-> ""
while is the same as:
-> "00:00:00:00:00:00"
-> "02:00:00:00:00:00 02:00:00:00:00:00"
`macchanger --random --bia`
-> "02:00:00:00:00:00 00:00:00:00:00:00"
`macchanger --ending`
This option cannot be fully implemented, because macchanger
uses the current MAC address but also implies --bia.
-> "FF:FF:FF:00:00:00"
This would yields the same result only if the current MAC address
is already a burned-in address too. Otherwise, it has not the same
effect as --ending.
-> "FF:FF:FF:00:00:00 <MAC_ADDR>"
Alternatively, instead of using the current MAC address,
spell the OUI part out. But again, that is not really the
same as macchanger does because you explictly have to name
the OUI part to use.
`machanger --another`
`machanger --another_any`
-> "FF:FF:FF:00:00:00 <MAC_ADDR> <MAC_ADDR> ..."
"$(printf "FF:FF:FF:00:00:00 %s\n" "$(sed -n 's/^\([0-9a-fA-F][0-9a-fA-F]\) \([0-9a-fA-F][0-9a-fA-F]\) \([0-9a-fA-F][0-9a-fA-F]\) .*/\1:\2:\3:00:00:00/p' /usr/share/macchanger/wireless.list | xargs)")"
Extend the "ethernet.cloned-mac-address" and "wifi.cloned-mac-address"
settings. Instead of specifying an explicit MAC address, the additional
special values "permanent", "preserve", "random", "random-bia", "stable" and
"stable-bia" are supported.
"permanent" means to use the permanent hardware address. Previously that
was the default if no explict cloned-mac-address was set. The default is
thus still "permanent", but it can be overwritten by global
configuration.
"preserve" means not to configure the MAC address when activating the
device. That was actually the default behavior before introducing MAC
address handling with commit 1b49f941a6.
"random" and "random-bia" use a randomized MAC address for each
connection. "stable" and "stable-bia" use a generated, stable
address based on some token. The "bia" suffix says to generate a
burned-in address. The stable method by default uses as token the
connection UUID, but the token can be explicitly choosen via
"stable:<TOKEN>" and "stable-bia:<TOKEN>".
On a D-Bus level, the "cloned-mac-address" is a bytestring and thus
cannot express the new forms. It is replaced by the new
"assigned-mac-address" field. For the GObject property, libnm's API,
nmcli, keyfile, etc. the old name "cloned-mac-address" is still used.
Deprecating the old field seems more complicated then just extending
the use of the existing "cloned-mac-address" field, although the name
doesn't match well with the extended meaning.
There is some overlap with the "wifi.mac-address-randomization" setting.
https://bugzilla.gnome.org/show_bug.cgi?id=705545https://bugzilla.gnome.org/show_bug.cgi?id=708820https://bugzilla.gnome.org/show_bug.cgi?id=758301
When comparing settings, nm_setting_compare() performs a complicated
logic, which basically serializes each GObject property to a GVariant
for the D-Bus representation.
That is wrong for example for ipv4.addresses, which don't contain
address labels. That is, the GObject property is called "addresses",
but the D-Bus field "addresses" cannot encode every information
and thus comparison fails. Instead, it would have to look into
"address-data".
Traditionally, we have virtual functions like compare_property() per
NMSetting to do the comparison. That comparison is based on the GObject
properties. I think that is wrong, because we should have a generic
concept of what a property is, independent from GObject properties.
With libnm, we added NMSettingProperty, which indeed is such an
GObject independent representation to define properties.
However, it is not used thoroughly, instead compare_property() is a hack
of special cases, overloads from NMSettingProperty, overloads of
compare_property(), and default behavior based on GParamSpec.
This should be cleaned up.
For now, just hack it by handle the properties with the problems
explicitly.
This new property be used as token to generate stable-ids instead
of the connection's UUID.
Later, this will be used by ipv6.addr-gen-mode=stable-privacy,
ethernet.cloned-mac-address=stable, and wifi.cloned-mac-address=stable
setting. Those generate stable addresses based on the connection's
UUID, but allow to use the stable-id instead.
This allows multiple connections to generate the same addresses
-- on the same machine, because in the above cases a machine
dependant key is also hashed.
The "shared" directory contains files that are possibly used by all components
of NetworkManager repository.
Some of these files are even copied as-is to other projects (VPN plugins, nm-applet)
and used there without modification. Move those files to a separate directory.
By moving them to a common directory, it is clearer that they belong
together. Also, you can easier compare the copied versions to their
original via
$ diff -r ./shared/nm-utils/ /path/to/nm-vpn-plugin/shared/nm-utils/
A failure to g_return*() by default prints a g_critical() with stringifing the
condition. Add a macro NMTST_G_RETURN_MSG() that reproduces that line to more
accurately match the failure message.
Having a gateway defined when never-default=yes causes troubles in
connection matching and anyway makes no sense.
If the combination is found, remove the gateway during the
normalization phase.
https://bugzilla.redhat.com/show_bug.cgi?id=1313091
For internal compilation we want to be able to use deprecated
API without warnings.
Define the version min/max macros to effectively disable deprecation
warnings.
However, don't do it via CFLAGS option in the makefiles, instead hack it
to "nm-default.h". After all, *every* source file that is for internal
compilation needs to include this header as first.