When adding a link, the Linux platform implementation raises the
link-changed signal synchronously. Fix the fake platform to behave identically
and also fix all the tests.
This also fixes the Linux platform tests for the most part because now the
test functions (and fake platform) behave like the Linux system
implementation.
https://bugzilla.gnome.org/show_bug.cgi?id=706293
Co-Authored-By: Thomas Haller <thaller@redhat.com>
Signed-off-by: Thomas Haller <thaller@redhat.com>
Add an additional address parameter to link_add/bridge_add, to set the
MAC address of software devices.
https://bugzilla.gnome.org/show_bug.cgi?id=729844
Signed-off-by: Thomas Haller <thaller@redhat.com>
This compares two addresses and returns which one has a longer
remaining life (i.e. a later expiry timestamp).
Signed-off-by: Thomas Haller <thaller@redhat.com>
Before platform raised 3 signals for each object type. Combine
them into one and add a new parameter @change_type to distinguish
between the change type.
Signed-off-by: Thomas Haller <thaller@redhat.com>
Since vxlan is new-ish, and vxlan IPv6 support in particular has only
been in the kernel since 3.11, we include our own copy of the vxlan
netlink constants rather than depending on the installed headers.
Also assert inside of sysctl_get() that we read the expected file
locations. Especially because now we might log the content of these
files.
Signed-off-by: Thomas Haller <thaller@redhat.com>
Remove the "silent_on_error" flag from nm_platform_sysctl_get(), and
make both get() and set() log at debug level on ENOENT and error level
on all other errors, always.
Also ensure that we don't sometimes write "failed to set 'x' to 'y':
Success" when a partial write occurs.
Before, nm_platform_ip4_address_exists(), et al. look into the cache to see
whether the address/route already exists and returned an error if it
did.
Change the semantic of the delete functions, to return success in case of
"nothing to delete". Also always try to delete the object in the
kernel. The reason is, that the cache might be out of date and the
caller really wants to delete it. So, to be sure, we always delete.
In most cases the object is actually in the cache (because that is
how the caller came to know that such an object might exist).
In those cases, the lookup was not useful either, because the object
was actually cached.
Signed-off-by: Thomas Haller <thaller@redhat.com>
Also, change the logging of nm_platform_ip._address_delete()
to log what we are about to do, *before* checking for existing
addresses.
Signed-off-by: Thomas Haller <thaller@redhat.com>
The kernel adds a new capability to allow user space to manage
temporary IPv6 addresses. We need to detect this capability
to act differently, depending on whether NM has an older kernel
at hand.
This capability got introduced together when extending the
ifa_flags to 32 bit. So, we can check the netlink message,
whether we have such an nl attribute at hand.
Signed-off-by: Thomas Haller <thaller@redhat.com>
The kernel and libnl adds two new flags IFA_F_MANAGETEMPADDR
and IFA_F_NOPREFIXROUTE. Older versions of libnl do not recognize
this flag, so add a workaround to nm_platform_ip6_address_to_string()
to show "mngtmpaddr" and "noprefixroute", respectively.
Also, add function nm_platform_check_support_libnl_extended_ifa_flags()
that checks whether libnl supports extended ifa_flags that were
added recently.
Extended flags and the two ifa-flags above were added to libnl in close
succession.
Signed-off-by: Thomas Haller <thaller@redhat.com>
In some cases, an error when reading the sysctl value can be expected.
In this case, we want to suppress the error message
Signed-off-by: Thomas Haller <thaller@redhat.com>
A gateway route can only be added, if there exists a device route
for that gateway. Therefore, nm_platform_ip4_route_sync() and
nm_platform_ip6_route_sync() has to add the device routes first,
before adding gateway routes.
Note: usually for all configured addresses, there is also a device
route for the subnet added by the kernel. This means, NM must first
configure the addresses before route_sync, so that these implicit device
routes already exist -- this is however already done correctly.
Signed-off-by: Thomas Haller <thaller@redhat.com>
If a route already exists that matches the network, prefix, gateway,
and metric of a route NM would like to add, don't try to overwrite
the route.
Unlike IP addresses, the kernel doesn't update the details, it
appears to completely replace that route, which might screw up
external tools that added the route originally.
One example of this is IPSec via openswan/libreswan. They add the
routes to the kernel upon connection, and if NM replaces those routes,
IPSec no longer works. While this may be due to kernel bugs or
bad handling of route replacement, there's no reason for NM to touch
routes that it wouldn't materially change anyway.
(yes, we could perhaps use NLM_F_REPLACE in add_kernel_object() only
when we really wanted to replace something, but why ask the kernel
to do the work when it's not required anyway?)
Two issues:
1) routes added by external programs or by users with /sbin/ip should not
be modified, but NetworkManager was always changing those routes' metrics
to match the device priority. This caused the nm_platform_ipX_route_sync()
functions to remove the original, external route (due to mismatched metric)
and re-add the route with the NetworkManager specified metric. Fix that
by not touching routes which came from the kernel.
2) Static routes (from persistent connections) that specified a metric were
getting their metric overwritten with the NetworkManager device priority.
Stop doing that.
Since the platform no longer defaults the metric to 1024, callers of
nm_platform_ip4_route_add() (like NMPolicy's default route handling)
must do that themselves, if they desire this behavior.
Tag addresses and routes with their source. We'll use this later to do
(or not do) operations based on where the item came from.
One thing to note is that when synchronizing items with the kernel, all
items are read as source=KERNEL even when they originally came from
NetworkManager, since the kernel has no way of providing this source
information. This requires the source 'priority', which
nm_ip*_config_add_address() and nm_ip*_config_add_route() must respect
to ensure that NM-owned routes don't have their source overwritten
when merging various IP configs in ip*_config_merge_and_apply().
Also of note is that memcmp() can no longer be used to compare
addresses/routes in nm-platform.c, but this had problems before
anyway with ifindex, so that workaround from nm_platform_ip4_route_sync()
can be removed.
https://bugzilla.gnome.org/show_bug.cgi?id=722843https://bugzilla.redhat.com/show_bug.cgi?id=1005416
The sysctl values in the kernel (for those values for which
nm_platform_sysctl_get_uint() is currently used) are defined as s32.
Change nm_platform_sysctl_get_uint() to nm_platform_sysctl_get_int32()
and ensure, that a matching integer type is used thoroughly.
Signed-off-by: Thomas Haller <thaller@redhat.com>
In the migration to NMPlatform, support for ptp/peer addresses was
accidentally dropped. This broke OpenVPN configurations using 'p2p'
topology, which send a different peer address than the local address
for tunX, plus the server may also push routes that use the peer
address as the next hop. NetworkManager was unable to add these
routes, because the kernel had no idea how to talk to the peer,
because the peer's address was not assigned to any interface or
reachable over any routes.
Partly based on a patch from Dan Williams.
These are (most likely) only warnings and not severe bugs.
Some of these changes are mostly made to get a clean run of
Coverity without any warnings.
Error found by running Coverity scan
https://bugzilla.redhat.com/show_bug.cgi?id=1025894
Co-Authored-By: Jiří Klimeš <jklimes@redhat.com>
Signed-off-by: Thomas Haller <thaller@redhat.com>
Slaves should get sorted after their masters so that when generating
connections, the NMManager knows about the masters already.
The convoluted logic here is to ensure that:
1) the kernel doesn't pass bad information that causes NM to crash
or infinite loop
2) that with complicated parent/child relationships (like a VLAN interface
with a parent that is also a slave), children always get sorted after
*all* of their ancestors. The previous code was only sorting children
after their immediate parent/master's ifindex, but not actually after
the parent in the returned list.
The NMPlatformIP[46]Address and NMPlatformIP[46]Route structs have a
field 'dev'. Before this field was always printed in the *_to_string
functions and a missing device was signaled as ' dev -'.
This had the advantage, that the output contained the same fields
regardless whether there was a device set or not.
Change it, not to print the device if it is not set. This has the
advantage, that it looks better in the logfiles.
Signed-off-by: Thomas Haller <thaller@redhat.com>
Use the new kernel physical_port_id interface property to recognize
when two devices are just virtual devices sharing the same physical
port, and refuse to bond/team multiple slaves on the same port.
New functions to compare two instances of NMPlatformIP4Address, NMPlatformIP6Address,
NMPlatformIP4Route, NMPlatformIP6Route, respectively.
These functions return -1, 0 or 1 as result of the comparison. This is similar to
strcmp with the additional restriction, that only one of these 3 values will be
returned.
Signed-off-by: Thomas Haller <thaller@redhat.com>
Add *_to_string functions for address (ip4 and ip6) and
route (ip4 and ip6). Also refactor the previously existing
nm_platform_ip4_route_to_string function.
The to_string function returns a pointer to an internal
buffer. Also update log_* functions to make use of the new
to_string functions.
Signed-off-by: Thomas Haller <thaller@redhat.com>