core/rdisc: add autoconf addresses as /64 (instead of /128)

This feature needs support from the kernel and libnl.

If there is no system support, NM acts as before, adding the
autoconf address as /128. It does so, to prevent the kernel
from adding a route for this prefix. With system support, we
add the address as /64 and set the flag IFA_F_NOPREFIXROUTE.

https://bugzilla.redhat.com/show_bug.cgi?id=1044590
https://bugzilla.redhat.com/show_bug.cgi?id=1045118

Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:
Thomas Haller 2014-01-03 17:03:35 +01:00
parent 7841f9ea0a
commit 39cbe772a6

View file

@ -36,6 +36,7 @@
#include <arpa/inet.h>
#include <fcntl.h>
#include <linux/if.h>
#include <netlink/route/addr.h>
#include "libgsystem.h"
#include "nm-glib-compat.h"
@ -74,6 +75,11 @@
#include "nm-device-bond.h"
#include "nm-device-team.h"
/* workaround for older libnl version, that does not define this flag. */
#ifndef IFA_F_NOPREFIXROUTE
#define IFA_F_NOPREFIXROUTE 0x200
#endif
static void impl_device_disconnect (NMDevice *device, DBusGMethodInvocation *context);
#include "nm-device-glue.h"
@ -3313,6 +3319,25 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *device
NMConnection *connection;
int i;
NMDeviceStateReason reason;
static int system_support = -1;
guint ifa_flags;
if (system_support == -1) {
/*
* Check, if both libnl and the kernel are recent enough,
* to help user space handling RA. If it's not supported,
* we must add autoconf addresses as /128.
* The reason for /128 is to prevent the kernel from adding
* a prefix route for this address.
**/
system_support = nm_platform_check_support_libnl_extended_ifa_flags () &&
nm_platform_check_support_kernel_extended_ifa_flags ();
}
/* without system_support, this flag will be ignored.
* Still, we set it (why not?).
**/
ifa_flags = IFA_F_NOPREFIXROUTE;
g_return_if_fail (priv->act_request);
connection = nm_device_get_connection (device);
@ -3346,11 +3371,12 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *device
memset (&address, 0, sizeof (address));
address.address = discovered_address->address;
address.plen = 128;
address.plen = system_support ? 64 : 128;
address.timestamp = discovered_address->timestamp;
address.lifetime = discovered_address->lifetime;
address.preferred = discovered_address->preferred;
address.source = NM_PLATFORM_SOURCE_RDISC;
address.flags = ifa_flags;
nm_ip6_config_add_address (priv->ac_ip6_config, &address);
}