This is the same we already did for nm-platform addresses in commit
68c3e1153c. It will help to avoid various
issues and is also a step towards support for route lifetimes.
It appears the kernel does not send notifications via netlink if the
default route is removed in some cases. This causes the platform
route cache to become stale, and thus when the default route is
reset by NM the platform thinks the route already exists, and does
not add it. But the route doesn't exist, becuase the kernel silently
removed it without telling anyone.
Fix that with a big hammer by flushing/refilling the route cache when
devices are deactivated (deletion of their addresses causes the default
route to be removed by the kernel) and when the default route is
updated by NM itself.
Pavel: if we find a more granular method, we should probably revert
this as the cache refill can be expensive.
The nm_platform_ip[46]_address_sync() functions no longer use
nm_platform_ip[46]_address_exists() to avoid adding already
existing addresses. That means nm_platform_ip[46]_address_add()
is now called for *all* commited addresses and the lifetimes
are thus always updated.
Because of that, nm_platform_ip[46]_address_add() had to be modified to
accept existing addresses and update their lifetimes when appropriate.
https://bugzilla.gnome.org/show_bug.cgi?id=705102
Addresses in the platform cache will have timestamp/lifetime/preferred set,
but addresses to be added or removed (like new IP config from DHCP renewal
or new RAs) won't have these set, since they only get set when the address
is actually added to the kernel. So when syncing addresses, we can't look
at any of these items or nothing matches, and all existing addresses get
removed.
https://bugzilla.gnome.org/show_bug.cgi?id=705102
When link goes !IFF_UP by internal or external action, we need to delete
related routes from the route cache. The same is done for both addresses
and routes upon link removal.
https://bugzilla.gnome.org/show_bug.cgi?id=704770
This (together with a patch adding src/platform/Makefile.am) allows for
a workflow where your working directory is src/platform and all tests
and testing tools are rebuilt with your src/platform modifications.
The route metric is one of the object's key attributes and therefore
cannot be left to be chosen by the kernel. Instead, it must always be
specified explicitly. This matches the architecture of libnl3 and the
current API provided by nm-platform.
Current versions of libnl3 use nl_addr_get_len() instead of
nl_addr_get_prefixlen() to determine the default route. Therefore we're
employing a workaround that sets the address length to zero for default
routes.
Unfortunately this workaround causes nl_addr to have wrong address size,
which in turn requires another workaround in init_ip4_route() as well as
init_ip6_route() to cope with the inconsistency.
Even though this solution is very very ugly, we didn't find a better
one. Not calling rtnl_route_set_dst() didn't solve the problem. Thomas
Graf promised to fix the libnl problem upstream. When bumping dependency
to a version that does this correctly, the workarounds can be removed.
With the move of udev logic into the Linux platform class, the
link-added signals are asynchronous, that is they are not emitted
during the call to nm_platform_*_add(), but after that call has
returned. The Fake implementation still emitted them synchronously,
which broke the testcases. Convert the Fake implementation to emit
link-added signals asynchronously and update the testcases to handle
this.
Since the platform started using udev for link-added signals, we need
to run the glib mainloop to wait for the udev signals to come in,
instead of expecting them to be emitted immediately.