We encounter the same enum in 3 forms:
- NMNDiscPreference in NetworkManager
- "enum ndp_route_preference" in <ndp.h>
- ICMPV6_ROUTER_PREF_* in <linux/icmpv6.h>
Move our enum to nm-core-utils.h, so that it can be used
by platform code as well (platform code should not include
ndisc/nm-ndisc.h).
Also, NMNDiscPreference was not numerically identical to their
native values (meaning: it shuffled the names and numbers).
Make them all numerically equal, so that they can be used in
the same context.
This means, while previously we could compare NMNDiscPreference
directly according to their priority, we now need _preference_to_priority().
On the other hand, we could omit translate_preference() -- but actually,
we still have _route_preference_coerce() because pref comes from libndp
and is thus untrusted. We still have to range check it.
- merge the IPv4 and IPv6 implementations. They are for the most
part identical. Also, they are independent of NMIP4Config/NMIP6Config.
- parse the entire file at once. Don't parse it twice, once for the
name servers and once for the options. This also avoids loading
/etc/resolv.conf twice, as it would be done before.
Allow passing a pretty name for the zero flag 0, like "none".
Also, don't require flags to be power-of-two. Instead, allow names for
multiple flags. For example an "all" name. By specifying multi-value
flags first, their nick will be supersede the more specific flags.
Probably it doesn't make sense in usual cases, but nm_utils_flags2str()
should prevent such use.
This will make us stop worry how relevant are chunks of compat code with
older kernels when deciding whether it's worth supporting/testing them.
As if we actually were testing old kernels.
For convenience, to clear the address inplace, allow to leave @src NULL,
instead of requiring to set @src to @dst.
The only problem is, if you make use of this extended behavior and later backport
the use to an older branch, ensure that you cherry-pick this commit too.
That is easy to miss, but you are testing the backport, right?
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.
The dad_counter is hashed into the resulting address. Since we
want the hashing to be independent of the architecture, we always
hash 32 bit of dad_counter. Make the dad_counter argument of
type guint32 for consistency.
In practice this has no effect because:
- for all our (current!) architectues, guint is the same as
guint32.
- all callers of nm_utils_ipv6_addr_set_stable_privacy() keep
their dad-counter argument as guint8, so they never even pass
numbers larger then 255.
- nm_utils_ipv6_addr_set_stable_privacy() limits dad_counter
further against RFC7217_IDGEN_RETRIES.
(cherry picked from commit 951e5f5bf8)
https://tools.ietf.org/html/rfc7217 says:
The resulting Interface Identifier SHOULD be compared against the
reserved IPv6 Interface Identifiers [RFC5453] [IANA-RESERVED-IID]
and against those Interface Identifiers already employed in an
address of the same network interface and the same network
prefix. In the event that an unacceptable identifier has been
generated, this situation SHOULD be handled in the same way as
the case of duplicate addresses (see Section 6).
In case of conflict, this suggests to create a new address incrementing
the DAD counter, etc. Don't do that. If we generate an address of the
reserved region, just rehash it right away. Note that the actual address
anyway appears random, so this re-hashing is just as good as incrementing
the DAD counter and going through the entire process again.
Note that now we no longer generate certain addresses like we did
previously. But realize that we now merely reject (1 + 16777216 + 128)
addresses out of 2^64. So, the likelyhood of of a user accidentally
generating an address that is suddenly rejected is in the order of
10e-13 (1 / 1,099,503,173,697). Which is not astronomically, but still
extreeeemely unlikely.
Also, the whole process is anyway build on the idea that somebody else
might generate conflicting addresses (DAD). It means, there was always
the extremely tiny chance that the address you generated last time is
suddenly taken by somebody else. So, this change appears to a user
like these reserved addresses are now claimed by another (non existing)
host and a different address gets generated -- business as usual, as
far as SLAAC is concerned.
(cherry picked from commit f15c4961ad)
nm_utils_exp10() is a better name, because it reminds of the function
exp10() from <math.h> which has a similar purpose (but whose argument
is double, not gint16).
We need a distinction between external activations and assuming
connections. The former shall have the meaning of devices that are
*not* managed by NetworkManager, the latter are configurations that
are gracefully taken over after restart (but fully managed).
Express that in the activation-type of the active connection.
Also, no longer use the settings NM_SETTINGS_CONNECTION_FLAGS_VOLATILE
flag to determine whether an assumed connection is "external". These
concepts are entirely orthogonal (although in pratice, external
activations are in-memory and flagged as volatile, but the inverse
is not necessarily true).
Also change match_connection_filter() to consider all connections.
Later, we only call nm_utils_match_connection() for the connection
we want to assume -- which will be a regular settings connection,
not a generated one.
NMPolicy's auto_activate_device() wants to sort by autoconnect-priority,
nm_utils_cmp_connection_by_autoconnect_priority() but fallback to the default
nm_settings_connection_cmp_default(), which includes the timestamp.
Extend nm_settings_connection_cmp_default() to consider the
autoconnect-priority as well. Thus change behavior so that
nm_settings_connection_cmp_default() is the sort order that
auto_activate_device() wants. That makes sense, as
nm_settings_connection_cmp_default() already considered the
ability to autoconnect as first. Hence, it should also honor
the autoconnect priority.
When doing that, rename nm_settings_connection_cmp_default()
to nm_settings_connection_cmp_autoconnect_priority().
Have a proper cmp() function and a wrapper *_p_with_data() that can be
used for g_qsort_with_data().
Thus, establish a naming scheme (*_p_with_data()) for these compare
wrappers that we need all over the place. Note, we also have
nm_strcmp_p_with_data() for the same reason and later more such
functions will follow.
It's not used anymore. Which is a good thing, because if it was used
we'd have to get rid of the uses.
It did accept a whitespace separated string for an argument, which is
never useful for us; it indicated error either on g_spawn_sync()
failure or an error status code of the program spawned, but only set the
error in the former case which had let to errors.
The would would be a bit nicer place without it.
(But not much)
Changes:
- match_device_s390_subchannels_parse() should accept un-initialized
arguments a,b,c, as they are striclty output arguments (without
transfering ownership).
- the output arguments should be set if (and only if) the function
succeeds. That is, move assigning the output arguments to the end.
- increase the BUFSIZE. It's unclear why choosing 10. Probably that
was already sufficient as a subchannel looks like
"0.0.f5f0,0.0.f5f1,0.0.f5f2". Still, increase it to be ample.
If we want to restrict the parsing based on the lenght of the input,
that should be done explicitly (but that seems not desirable).
- use _nm_utils_ascii_str_to_int64() which checks that the range
of the values fits in guint32.
It seems wrong that match_device_s390_subchannels_eval() only compares
the first of up to three subchannels. But leave it as is for now.
(cherry picked from commit 419151a19e)
When searching for "*", we still need to check for higher priority
"except:" matches. But don't duplicate the search loop and just
proceed with the regular searched.
It already has the "if (!except && match == NM_MATCH_SPEC_MATCH)" which
short-cuts the search.
(cherry picked from commit 9fff9f501a)
Instead of passing on invdividual arguments for the match, create
a MatchDeviceData structure and pass it on.
This reduces the number of arguments and extending it later should
be easier. Also, lazily parse the hardware address as needed.
(cherry picked from commit b0aaff86b6)
Previously, we would have different functions like
- nm_match_spec_device_type()
- nm_match_spec_hwaddr()
- nm_match_spec_s390_subchannels()
- nm_match_spec_interface_name()
which all would handle one type of match-spec.
So, to get the overall result whether the arguments
match or not, nm_device_spec_match_list() had to stich
them together and iterate the list multiple times.
Refactor the code to have one nm_match_spec_device()
function that gets all relevant paramters.
The upside is:
- the logic how to evaluate the match-spec is all at one place
(match_device_eval()) instead of spread over multiple
functions.
- It requires iterating the list at most twice. Twice, because
we do a fast pre-search for "*".
One downside could be, that we have to pass all 4 arguments
for the evaluation, even if the might no be needed. That is,
because "nm-core-utils.c" shall be independend from NMDevice, it
cannot receive a device instance to get the parameters as needed.
As we would add new match-types, the argument list would grow.
However, all arguments are cached and fetching them from the
device's private data is very cheap.
(cherry picked from commit b957403efd)
Usecase: when connecting to a public Wi-Fi with MAC address randomization
("wifi.cloned-mac-address=random") you get on every re-connect a new
IP address due to the changing MAC address.
"wifi.cloned-mac-address=stable" is the solution for that. But that
means, every time when reconnecting to this network, the same ID will
be reused. We want an ID that is stable for a while, but at a later
point a new ID should e generated when revisiting the Wi-Fi network.
Extend the stable-id to become dynamic and support templates/substitutions.
Currently supported is "${CONNECTION}", "${BOOT}" and "${RANDOM}".
Any unrecognized pattern is treated verbaim/untranslated.
"$$" is treated special to allow escaping the '$' character. This allows
the user to still embed verbatim '$' characters with the guarantee that
future versions of NetworkManager will still generate the same ID.
Of course, a user could just avoid '$' in the stable-id unless using
it for dynamic substitutions.
Later we might want to add more recognized substitutions. For example, it
could be useful to generate new IDs based on the current time. The ${} syntax
is extendable to support arguments like "${PERIODIC:weekly}".
Also allow "connection.stable-id" to be set as global default value.
Previously that made no sense because the stable-id was static
and is anyway strongly tied to the identity of the connection profile.
Now, with dynamic stable-ids it gets much more useful to specify
a global default.
Note that pre-existing stable-ids don't change and still generate
the same addresses -- unless they contain one of the new ${} patterns.
We require a network-id. Assert that it is set.
Also, we encode the stable-id as uint8. Thus, add
an assertion that we don't use more then 254 IDs.
If we ever make use of stable-type 255, we must extend
the encoding to allow for more values. The assertion
is there to catch that.
A reimplementation of g_file_get_contents() to overcome two limitations:
- nm_utils_file_get_contents() accepts a @dirfd argument to open the
file relative using openat().
- nm_utils_fd_get_contents() allows to read the content from a file
filedescriptor.
- both support a max_length argument, to fail gracefully if we
get tricked into loading a huge file.
Moving the PPP manager to a separate plugin that is loaded when needed
has the advantage of slightly reducing memory footprint and makes it
possible to install the PPP support only where needed.
https://bugzilla.gnome.org/show_bug.cgi?id=773482
We use the lifetime of 0 to indicate permanent addresses while
DHCP uses that lifetime to indicate the addresses should be removed.
Use the presence of a timestamp to differentiate the two.
dhclient[10867]: XMT: Rebind on wls1, interval 1030ms.
dhclient[10867]: RCV: Reply message on wls1 from fe80::21e:8cff:feec:3ca2.
NetworkManager[10481]: <info> [1478020967.7634] dhcp6 (wls1): valid_lft 0
NetworkManager[10481]: <info> [1478020967.7634] dhcp6 (wls1): preferred_lft 0
NetworkManager[10481]: <info> [1478020967.7636] dhcp6 (wls1): address fd25:d463:2f14::927
NetworkManager[10481]: <info> [1478020967.7636] dhcp6 (wls1): nameserver 'fe80::21e:8cff:feec:3ca2'
NetworkManager[10481]: <info> [1478020967.7637] dhcp (wls1): domain search 'venom.'
NetworkManager[10481]: <info> [1478020967.7637] dhcp6 (wls1): state changed unknown -> bound, event ID="fa💿2c:86|1478020967"
NetworkManager[10481]: ((src/nm-core-utils.c:3521)): assertion '<dropped>' failed
_nm_utils_hwaddr_length() did a validation of the string
and returned the length of the address. In all cases where
we were interested in that, we also either want to validate
the address, get the address in binary form, or canonicalize
the address.
We can avoid these duplicate checks, by using _nm_utils_hwaddr_aton()
which both does the parsing and returning the length.