It's ugly to modify the global behavior of glib to convert between
types. Instead, _get_fcn_gobject_impl() is perfectly capable to implement
converting a strv array to string.
"ipv4.dns-options" and "ipv6.dns-options" are special, in that they can
be either unset/default or an empty list of options. That means, nmcli
must treat these two options differently.
For the (terse) getter, it returns "" for default and " " for empty.
The setter must likewise support and distingish between these two cases.
Cleanup the handling of such options. This only applies to properties of
type "multilist". Hence, add multilist.clear_emptyunset_fcn() handler
that indicates that the property is of that kind.
Try:
nmcli connection modify "$PROFILE" ipv4.dns-options ''
nmcli connection modify "$PROFILE" ipv4.dns-options ' '
and compare the output:
nmcli connection show "$PROFILE" | sed -n '/ipv4.dns-options/ s/.*/<\0>/p'
nmcli -t connection show "$PROFILE" | sed -n '/ipv4.dns-options/ s/.*/<\0>/p'
nmcli -o connection show "$PROFILE" | sed -n '/ipv4.dns-options/ s/.*/<\0>/p'
The link-watcher properties are not expected to contain any special values
that require escaping. Hence, change the tokenizing from plain splitting
at ',' to escaped-tokens style is likely to not affect any existing
setups.
Still, all our properties should be handled the same way (including a
tokenizing which allows escaping to represent every possible value).
to/from string functions are useful. We should be able to reuse them.
Move them to their own location.
Also, it moves independent code out of "clients/common/nm-meta-setting-desc.c"
which is already one of the largest source files we have.
Also, it makes the code unit-testable, which is obviously required
as the code has bugs.
"libnm-core" implements common functionality for "NetworkManager" and
"libnm".
Note that clients like "nmcli" cannot access the internal API provided
by "libnm-core". So, if nmcli wants to do something that is also done by
"libnm-core", , "libnm", or "NetworkManager", the code would have to be
duplicated.
Instead, such code can be in "libnm-libnm-core-{intern|aux}.la".
Note that:
0) "libnm-libnm-core-intern.la" is used by libnm-core itsself.
On the other hand, "libnm-libnm-core-aux.la" is not used by
libnm-core, but provides utilities on top of it.
1) they both extend "libnm-core" with utlities that are not public
API of libnm itself. Maybe part of the code should one day become
public API of libnm. On the other hand, this is code for which
we may not want to commit to a stable interface or which we
don't want to provide as part of the API.
2) "libnm-libnm-core-intern.la" is statically linked by "libnm-core"
and thus directly available to "libnm" and "NetworkManager".
On the other hand, "libnm-libnm-core-aux.la" may be used by "libnm"
and "NetworkManager".
Both libraries may be statically linked by libnm clients (like
nmcli).
3) it must only use glib, libnm-glib-aux.la, and the public API
of libnm-core.
This is important: it must not use "libnm-core/nm-core-internal.h"
nor "libnm-core/nm-utils-private.h" so the static library is usable
by nmcli which couldn't access these.
Note that "shared/nm-meta-setting.c" is an entirely different case,
because it behaves differently depending on whether linking against
"libnm-core" or the client programs. As such, this file must be compiled
twice.
(cherry picked from commit af07ed01c0)
From the files under "shared/nm-utils" we build an internal library
that provides glib-based helper utilities.
Move the files of that basic library to a new subdirectory
"shared/nm-glib-aux" and rename the helper library "libnm-core-base.la"
to "libnm-glib-aux.la".
Reasons:
- the name "utils" is overused in our code-base. Everything's an
"utils". Give this thing a more distinct name.
- there were additional files under "shared/nm-utils", which are not
part of this internal library "libnm-utils-base.la". All the files
that are part of this library should be together in the same
directory, but files that are not, should not be there.
- the new name should better convey what this library is and what is isn't:
it's a set of utilities and helper functions that extend glib with
funcitonality that we commonly need.
There are still some files left under "shared/nm-utils". They have less
a unifying propose to be in their own directory, so I leave them there
for now. But at least they are separate from "shared/nm-glib-aux",
which has a very clear purpose.
(cherry picked from commit 80db06f768)
There should be little difference here, because the priority list is
(and was) never serialized with special characters like backslashes or
delimiters that require escaping.
Likewise, no working code actually tried to set such characters.
Still, drop the plain VALUE_STRSPLIT_MODE_STRIPPED and use
VALUE_STRSPLIT_MODE_ESCAPED_TOKENS_WITH_SPACES instead. We should have
a small set of modes that we use for splitting strings.
(cherry picked from commit 7f01da917e)
- merge the pointless helper function vlan_priorities_to_string()
into the only caller _get_fcn_vlan_xgress_priority_map().
- minor cleanups, like setting out-is-default if num==0, not
based on whether we have a non-empty string. There is not difference
in practice, because nm_setting_vlan_get_priority() never fails.
Hence they are identical. But nm_setting_vlan_get_priority() has
an API that allows it to fail, so we should declare the default
depending on the number of vlan priorities.
- don't allocate the temporary GString instance if we won't need it.
- only append the delimiter if needed, and not truncate it afterwards.
It might have even worse performance this way, but it feels more
correct to me.
- also cache the result of nm_setting_vlan_get_num_priorities().
NMSettingVlan's implementation is horrible and uses a GSList to
track the list of priorities. This makes it relatively expensive
to call get-num-priorities repeatedly (and pointless).
(cherry picked from commit bbfd366805)
the only change in behaviour is for VALUE_STRSPLIT_MODE_MULTILIST.
Previously, we would split at " \t,", now we will also split at
the white space characters "\n\r\f".
(cherry picked from commit 7a92fb6bf4)
We had %VALUE_STRSPLIT_MODE_MULTILIST_WITH_ESCAPE, which was used
by "match.interface-names". This uses nm_utils_strsplit_set_full()
with %NM_UTILS_STRSPLIT_SET_FLAGS_ALLOW_ESCAPING and
_nm_utils_unescape_plain().
We want eventually to use nm_utils_escaped_tokens_split() everywhere.
We already have %VALUE_STRSPLIT_MODE_ESCAPED_TOKENS, which splits the
list at ',' (and strips whitespaces at the around the delimiter). That
differs from what %VALUE_STRSPLIT_MODE_MULTILIST_WITH_ESCAPE did, which
also considered whitespace a delimiter.
So, we need a new mode %VALUE_STRSPLIT_MODE_ESCAPED_TOKENS_WITH_SPACES
which replaces the previous mode.
Note that the previous implementation did almost the same thing. In
fact, I cannot imagine examples where they behaved differently, but
my feeling is that there might be some edge cases where this changes
behavior.
(cherry picked from commit 6093f49304)
The reminder of the function only does (something akin to) g_strstrip().
As we split the strings are spaces to begin with, there is nothing to
strip and we can return right away.
(cherry picked from commit b74d9a0bd5)
When splitting (and concatenating) list-typed properties,
we really should use nm_utils_escaped_tokens_split()
and nm_utils_escaped_tokens_escape*().
Make that the default, and mark all properties to opt-in to the
legacy behavior.
(cherry picked from commit 5a71592087)
The modes VALUE_STRSPLIT_MODE_OBJLIST* and VALUE_STRSPLIT_MODE_MULTILIST* are
different. We must use the right mode.
For example, _get_fcn_match_interface_name() concatenates the interface-names
with space. So, the tokenizer of the setter must also use space as delimiter.
VALUE_STRSPLIT_MODE_MULTILIST_WITH_ESCAPE does that correctly,
VALUE_STRSPLIT_MODE_OBJLIST_WITH_ESCAPE does not.
(cherry picked from commit 758bf32640)
In some cases it is convenient to specify ranges of bridge vlans, as
already supported by iproute2 and natively by kernel. With this commit
it becomes possible to add a range in this way:
nmcli connection modify eth0-slave +bridge-port.vlans "100-200 untagged"
vlan ranges can't be PVIDs because only one PVID vlan can exist.
https://bugzilla.redhat.com/show_bug.cgi?id=1652910
(cherry picked from commit 7093515777)
Optimally, all list types properties in nmcli support proper escaping.
For that, we should use nm_utils_escaped_tokens_*() API.
For now, just change that for policy routes. They were just added recently,
so no change in behavior of released API.
(cherry picked from commit d59f046bb6)
nmcli supports list options (optlist and multilist properties).
These commonly are individual items, concatenated by a delimiter.
It should be generally possibly to express every value. That means, we
need some for of escaping mechanism for delimiters.
Currently this is all inconsistent or no escaping is supported. I intend
to fix that (which will be a change in behavior).
For now, just add yet another style of tokenzing/concatenating list
items in nmcli. This is the style to replace all other styles.
(cherry picked from commit ba956bd499)
Before:
# nmcli c modify eth666 tc.qdiscs root
Error: failed to modify tc.qdiscs: '(null)' is not a valid kind The valid syntax is: '[root | parent <handle>] [handle <handle>] <qdisc>'.
After:
# nmcli c modify eth666 tc.qdiscs root
Error: failed to modify tc.qdiscs: kind is missing. The valid syntax is: '[root | parent <handle>] [handle <handle>] <kind>'.
There is no reason to validate only in certain cases. Either we
validate, or we don't (always the same).
This is a change in behavior, but the cases should be sensible.
Most GObject properties default to FALSE/NULL/0. In that case, there
is no difference between setting the default or clearing the value.
During
if (_SET_FCN_DO_RESET_DEFAULT (property_info, modifier, value))
return _gobject_property_reset_default (setting, property_info->property_name);
it is correct to reset the default.
However for list-typed properties, we want to clear the list. So,
it should be
if (_SET_FCN_DO_SET_ALL (modifier, value))
_gobject_property_reset (setting, property_info->property_name, FALSE);
The VFs already can be parsed as plain number (to indicate the
ifindex). We should not also support accepting the plain number
as index to be removed.
Fixes: a2f12994b7 ('cli: add support for configuring SR-IOV')
$ nmcli connection modify "$PROFILE" -ipv4.addresses 1,3
Already before, nmcli would support removing items by index. But only
one number was supported.
- indexes are zero based (as before).
- duplicate indexes or indexes out of bounds are silently ignored.
Maybe certain properties should not support removal by index.
Use new ValueStrsplitMode "VALUE_STRSPLIT_MODE_STRIPPED".
Note that this is not exactly what we did before. For example, empty
tokens are now silently removed.
Also, we accept now whitespace as separators.
Have one function that gets all the nonesense right. "nonesense", because
we have inconsistent behaviors, and the function is supposed to help with
that.
set_fcn() and remove_fcn() are strongly related. They should accept
arguments in the same format, hence the parsing of the arguments should
be done at one place.
In fact, previously the parsing was separate, leading to ugly
inconsistencies:
$ nmcli connection modify "$PROFILE" +vpn.data x=y
$ nmcli connection modify "$PROFILE" -vpn.data x=y
Error: failed to remove a value from vpn.data: invalid option 'x=y'.
or
$ nmcli connection modify "$PROFILE" +ipv4.addresses 192.168.1.5/24,192.168.2.5/24
$ nmcli connection modify "$PROFILE" -ipv4.addresses 192.168.1.5/24,192.168.2.5/24
Error: failed to remove a value from ipv4.addresses: invalid prefix '24,192.168.2.5/24'; <1-32> allowed.
Let set_fcn() handle set-default, set-all, add, and subtract.
Previously, set_fcn() could only append values. Now, pass on the modifier
so that it may append, set all, or reset the default.
These operations are strongly related and should be handled by the same
set_fcn() function.