platform: use IFA_F_NOPREFIXROUTE flag for IPv4 addresses

For IPv6 addresses we use IFA_F_NOPREFIXROUTE for a long time.
If we detect that kernel does not support the flag (for IPv6), we
add addresses as /128 to prevent kernel from adding an onlink route.
We add IPv6 device routes explicitly, whenever needed according
to the onlink RA flag.

For IPv4, we also don't want the route added by kernel. The reason is
that is has an undesired metric of zero. However, usually we want the route
to have a different metric. The complicated part is that kernel does
not add the route immediately but sometimes later. For that we have
nm_platform_ip4_dev_route_blacklist_set() (previously that was
nm_route_manager_ip4_route_register_device_route_purge_list()). It
watches the interface and when a registered device route shows up,
it deletes it.

The better solution is to use the IFA_F_NOPREFIXROUTE flag to prevent
the creation of the route in the first place. It was added for IPv4 to
kernel in commit 7b1311807f3d3eb8bef3ccc53127838b3bea3771, October 2015.

Contrary to IPv6, we cannot (easily) detect whether kernel supports IFA_F_NOPREFIXROUTE
for IPv4 routes. Hence keep nm_platform_ip4_dev_route_blacklist_set() for older
kernels.
This commit is contained in:
Thomas Haller 2017-08-17 17:20:14 +02:00
parent 2f83894498
commit fec80e7473

View file

@ -3262,6 +3262,7 @@ nm_platform_ip4_address_sync (NMPlatform *self,
guint i, j, len;
NMPLookup lookup;
guint32 lifetime, preferred;
guint32 ifa_flags;
_CHECK_SELF (self, klass, FALSE);
@ -3380,6 +3381,10 @@ delete_and_next:
if (!known_addresses)
return TRUE;
ifa_flags = nm_platform_check_support_kernel_extended_ifa_flags (self)
? IFA_F_NOPREFIXROUTE
: 0;
/* Add missing addresses */
for (i = 0; i < known_addresses->len; i++) {
const NMPObject *o;
@ -3396,7 +3401,8 @@ delete_and_next:
if (!nm_platform_ip4_address_add (self, ifindex, known_address->address, known_address->plen,
known_address->peer_address, lifetime, preferred,
0, known_address->label))
ifa_flags,
known_address->label))
goto delete_and_next2;
continue;
@ -3950,8 +3956,8 @@ _ip4_dev_route_blacklist_schedule (NMPlatform *self)
* @ip4_dev_route_blacklist:
*
* When adding an IP address, kernel automatically adds a device route.
* This can be suppressed via the IFA_F_NOPREFIXROUTE address flag. For IPv6
* addresses, we require kernel support for IFA_F_NOPREFIXROUTE and always
* This can be suppressed via the IFA_F_NOPREFIXROUTE address flag. For proper
* IPv6 support, we require kernel support for IFA_F_NOPREFIXROUTE and always
* add the device route manually.
*
* For IPv4, this flag is rather new and we don't rely on it yet. We want to use