The code never set "iface_get_config->cidr_addr", despite
setting "cidr_prefix" and "has_cidr". As a result, cloud-setup
would think that the subnet is "0.0.0.0/$PLEN", and calculate
the gateway as "0.0.0.1".
As a result it would add a default route to table 30400 via 0.0.0.1,
which is obviously wrong.
How to detect the right gateway? Let's try obtain the subnet also via
the meta data. That seems mostly correct, except that we only access
subnet at index 0. What if there are multiple ones? I don't know.
https://bugzilla.redhat.com/show_bug.cgi?id=1912236
(cherry picked from commit c2629f72b0)
Background
==========
Imagine you run a container on your machine. Then the routing table
might look like:
default via 10.0.10.1 dev eth0 proto dhcp metric 100
10.0.10.0/28 dev eth0 proto kernel scope link src 10.0.10.5 metric 100
[...]
10.42.0.0/24 via 10.42.0.0 dev flannel.1 onlink
10.42.1.2 dev cali02ad7e68ce1 scope link
10.42.1.3 dev cali8fcecf5aaff scope link
10.42.2.0/24 via 10.42.2.0 dev flannel.1 onlink
10.42.3.0/24 via 10.42.3.0 dev flannel.1 onlink
That is, there are another interfaces with subnets and specific routes.
If nm-cloud-setup now configures rules:
0: from all lookup local
30400: from 10.0.10.5 lookup 30400
32766: from all lookup main
32767: from all lookup default
and
default via 10.0.10.1 dev eth0 table 30400 proto static metric 10
10.0.10.1 dev eth0 table 30400 proto static scope link metric 10
then these other subnets will also be reached via the default route.
This container example is just one case where this is a problem. In
general, if you have specific routes on another interface, then the
default route in the 30400+ table will interfere badly.
The idea of nm-cloud-setup is to automatically configure the network for
secondary IP addresses. When the user has special requirements, then
they should disable nm-cloud-setup and configure whatever they want.
But the container use case is popular and important. It is not something
where the user actively configures the network. This case needs to work better,
out of the box. In general, nm-cloud-setup should work better with the
existing network configuration.
Change
======
Add new routing tables 30200+ with the individual subnets of the
interface:
10.0.10.0/24 dev eth0 table 30200 proto static metric 10
[...]
default via 10.0.10.1 dev eth0 table 30400 proto static metric 10
10.0.10.1 dev eth0 table 30400 proto static scope link metric 10
Also add more important routing rules with priority 30200+, which select
these tables based on the source address:
30200: from 10.0.10.5 lookup 30200
These will do source based routing for the subnets on these
interfaces.
Then, add a rule with priority 30350
30350: lookup main suppress_prefixlength 0
which processes the routes from the main table, but ignores the default
routes. 30350 was chosen, because it's in between the rules 30200+ and
30400+, leaving a range for the user to configure their own rules.
Then, as before, the rules 30400+ again look at the corresponding 30400+
table, to find a default route.
Finally, process the main table again, this time honoring the default
route. That is for packets that have a different source address.
This change means that the source based routing is used for the
subnets that are configured on the interface and for the default route.
Whereas, if there are any more specific routes in the main table, they will
be preferred over the default route.
Apparently Amazon Linux solves this differently, by not configuring a
routing table for addresses on interface "eth0". That might be an
alternative, but it's not clear to me what is special about eth0 to
warrant this treatment. It also would imply that we somehow recognize
this primary interface. In practise that would be doable by selecting
the interface with "iface_idx" zero.
Instead choose this approach. This is remotely similar to what WireGuard does
for configuring the default route ([1]), however WireGuard uses fwmark to match
the packets instead of the source address.
[1] https://www.wireguard.com/netns/#improved-rule-based-routing
(cherry picked from commit fe80b2d1ec)
(cherry picked from commit 58e58361bd)
The table number is chosen as 30400 + iface_idx. That is, the range is
limited and we shouldn't handle more than 100 devices. Add a check for
that and error out.
(cherry picked from commit b68d694b78)
(cherry picked from commit 292233e16e)
The routes/rules that are configured are independent of the
order in which we process the devices. That is, because they
use the "iface_idx" for cases where there is ambiguity.
Still, it feels nicer to always process them in a defined order.
(cherry picked from commit a95ea0eb29)
(cherry picked from commit 6302cd416d)
Sorted by iface_idx. The iface_idx is probably something useful and
stable, provided by the provider. E.g. it's the order in which
interfaces are exposed on the meta data.
(cherry picked from commit 1c5cb9d3c2)
(cherry picked from commit 0a2ed62703)
get-config() gives a NMCSProviderGetConfigResult structure, and the
main part of data is the GHashTable of MAC addresses and
NMCSProviderGetConfigIfaceData instances.
Let NMCSProviderGetConfigIfaceData also have a reference to the MAC
address. This way, I'll be able to create a (sorted) list of interface
datas, that also contain the MAC address.
(cherry picked from commit ec56fe60fb)
(cherry picked from commit cc289e5369)
nm-cloud-setup automatically configures the network. That may conflict
with what the user wants. In case the user configures some specific
setup, they are encouraged to disable nm-cloud-setup (and its
automatism).
Still, what we do by default matters, and should play as well with
user's expectations. Configuring policy routing and a higher priority
table (30400+) that hijacks the traffic can cause problems.
If the system only has one IPv4 address and one interface, then there
is no point in configuring policy routing at all. Detect that, and skip
the change in that case.
Note that of course we need to handle the case where previously multiple
IP addresses were configured and an update gives only one address. In
that case we need to clear the previously configured rules/routes. The
patch achieves this.
(cherry picked from commit 5f047968d7)
(cherry picked from commit 8bc8a0f56b)
nm-cloud-setup automatically detects routes, addresses and rules and configures them
on the device using the emphermal Reapply() API. That is, it does not modify the
existing profile (on disk), but changes the runtime configuration only.
As such, it used to wipe otherwise statically configured IP addresses, routes and
rules. That seems unnecessary. Let's keep the configuration from the (persistent)
configuration.
There is of course the problem that nm-cloud-setup doesn't really
understand the existing IP configuration, and it can only hope that
it can be meaningfully combined with what nm-cloud-setup wants to
configure. This should cover most simple cases, for more complex setups,
the user probably should disable nm-cloud-setup and configure the
network explicitly to their liking.
https://bugzilla.redhat.com/show_bug.cgi?id=1971527https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/893
(cherry picked from commit 4201ee5119)
(cherry picked from commit 9541b0bea4)
Now that we return a struct from get_config(), we can have system-wide
properties returned.
Let it count and cache the number of valid iface_datas.
Currently that is not yet used, but it will be.
(cherry picked from commit a3cd66d3fa)
(cherry picked from commit e74375fc3b)
Returning a struct seems easier to understand, because then the result
is typed.
Also, we might return additional results, which are system wide and not
per-interface.
(cherry picked from commit 323e182768)
(cherry picked from commit c94b1c43d4)
This fixes commit 21c8a6b20e ('libnm-core, all: merge IPv4 and IPv6
address/route types'), which introduced this API but didn't export it
in the library. In practice this API is thus only usable since 1.32.0.
(cherry picked from commit 05f2a0b024)
(cherry picked from commit eea912dfb3)
If the kernel command-line doesn't contain an explict ip=$method,
currently the generator creates connections with both IPv4 and IPv6
set to 'auto', and both allowed to fail.
Since NM is run in configure-and-quit mode in the initrd, NM can get
an IPv4 address or an IPv6 one (or both) depending on which address
family is quicker to complete. This unpredictable behavior is not
present in the legacy module, which always does IPv4 only by default.
Set a required-timeout of 20 seconds for IPv4, so that NM will
preferably get an IPv4, or will fall back to IPv6.
See also: https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/729
(cherry picked from commit 0a18e97345)
(cherry picked from commit 1b9cf8c513)
Change the logic in check_ip_state() to delay the connection ACTIVATED
state if an address family is pending and its required-timeout has not
expired.
(cherry picked from commit 35cccc41cb)
(cherry picked from commit 51e5df275c)
Add a new property to specify the minimum time interval in
milliseconds for which dynamic IP configuration should be tried before
the connection succeeds.
This property is useful for example if both IPv4 and IPv6 are enabled
and are allowed to fail. Normally the connection succeeds as soon as
one of the two address families completes; by setting a required
timeout for e.g. IPv4, one can ensure that even if IP6 succeeds
earlier than IPv4, NetworkManager waits some time for IPv4 before the
connection becomes active.
(cherry picked from commit cb5960cef7)
(cherry picked from commit 08ce20481c)
Coverity wrongly think there is a use after free in the test:
Error: USE_AFTER_FREE (CWE-416): [#def559] [important]
NetworkManager-1.31.90/src/libnm-glib-aux/tests/test-shared-general.c:1305: alias: Assigning: "s1" = "_s". Now both point to the same storage.
NetworkManager-1.31.90/src/libnm-glib-aux/tests/test-shared-general.c:1324: freed_arg: "g_source_unref" frees "s1".
NetworkManager-1.31.90/src/libnm-glib-aux/tests/test-shared-general.c:1330: deref_after_free: Dereferencing freed pointer "s1".
# 1328| s2 = nm_g_source_sentinel_get(0);
# 1329| g_assert(s2 == s1);
# 1330|-> g_assert_cmpint(g_atomic_int_get(&s1->ref_count), >=, 1);
# 1331| }
# 1332| }
Rework the code in the hope to avoid the false warning.
(cherry picked from commit 7825609f1f)
(cherry picked from commit c47c823c9d)
This helper is useful to get a dummy GSource instance that can be
refed, unrefed and destroyed. It can act as a replacement for
a timeout source with infinite timeout.
(cherry picked from commit ce7c28c514)
Fixes: b01a453ca2 ('core: add nm_utils_random_bytes() and use getrandom()')
(cherry picked from commit c127e1becc)
(cherry picked from commit 3de83dd25c)
The previous implementation was just wrong.
Fixes: e1ca3bf7ed ('shared: add nm_strerror_native() to replace strerror() and g_strerror()')
(cherry picked from commit 5bc39d9783)
(cherry picked from commit 963c395cc2)
For the umpteenth time: it is not ifcfg-rh writers decision to decide
what are valid configurations and only persist settings based on
some other settings.
If s390-options would only be allowed together with subchannels, then
this is alone nm_connection_verify()'s task to ensure.
Reproduce with
$ nmcli connection add type ethernet autoconnect no con-name zz ethernet.s390-options bridge_role=primary
Related: https://bugzilla.redhat.com/show_bug.cgi?id=1935842
Fixes: 16bccfd672 ('core: handle s390 options more cleanly')
(cherry picked from commit d391f20730)
(cherry picked from commit b425793d90)
_nm_thread_local is very neat, but when we allocate resources
we need to make sure that they are destroyed when the thread
exits.
We can use pthread_setspecific() for that, but using it is cumbersome.
Add a helper function to make that simpler.
Also, the number of possible pthread_key_t keys is limited. With this
way, we only need one key in total.
(cherry picked from commit bec4a40437)
(cherry picked from commit e83aad1972)
If a prefix delegation is needed, currently NM restarts DHCPv6 on the
device with default route, but only if DHCPv6 was already running.
Allow the device to start DHCPv6 for a PD even if it was running
without DHCPv6.
See also: https://github.com/coreos/fedora-coreos-tracker/issues/888
(cherry picked from commit 62869621bd)
(cherry picked from commit 75b8ced29a)