diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 35103e54fa..50440d09dd 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "libgsystem.h" #include "nm-glib-compat.h" @@ -74,6 +75,14 @@ #include "nm-device-bond.h" #include "nm-device-team.h" +/* workaround for older libnl version, that does not define these flags. */ +#ifndef IFA_F_MANAGETEMPADDR +#define IFA_F_MANAGETEMPADDR 0x100 +#endif +#ifndef IFA_F_NOPREFIXROUTE +#define IFA_F_NOPREFIXROUTE 0x200 +#endif + static void impl_device_disconnect (NMDevice *device, DBusGMethodInvocation *context); #include "nm-device-glue.h" @@ -276,6 +285,7 @@ typedef struct { NMRDisc * rdisc; gulong rdisc_config_changed_sigid; + NMSettingIP6ConfigPrivacy rdisc_use_tempaddr; /* IP6 config from autoconf */ NMIP6Config * ac_ip6_config; @@ -477,6 +487,21 @@ restore_ip6_properties (NMDevice *self) } } +static gint32 +sysctl_get_ipv6_max_addresses (const char *dev) +{ + gint32 max_addresses = 16; + char *path; + + g_return_val_if_fail (dev && *dev, max_addresses); + + path = g_strdup_printf ("/proc/sys/net/ipv6/conf/%s/max_addresses", dev); + max_addresses = nm_platform_sysctl_get_int32 (path, max_addresses); + g_free (path); + + return max_addresses; +} + /* * Get driver info from SIOCETHTOOL ioctl() for 'iface' * Returns driver and firmware versions to 'driver_version and' 'firmware_version' @@ -3291,6 +3316,53 @@ linklocal6_start (NMDevice *self) static void dhcp6_cleanup (NMDevice *self, gboolean stop, gboolean release); +static void +print_support_extended_ifa_flags (NMSettingIP6ConfigPrivacy use_tempaddr) +{ + static gint8 warn = 0; + static gint8 s_libnl = -1, s_kernel; + + if (warn >= 2) + return; + + if (s_libnl == -1) { + s_libnl = !!nm_platform_check_support_libnl_extended_ifa_flags (); + s_kernel = !!nm_platform_check_support_kernel_extended_ifa_flags (); + + if (s_libnl && s_kernel) { + nm_log_dbg (LOGD_IP6, "kernel and libnl support extended IFA_FLAGS (needed by NM for IPv6 private addresses)"); + warn = 2; + return; + } + } + + if ( use_tempaddr != NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR + && use_tempaddr != NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR) { + if (warn == 0) { + nm_log_dbg (LOGD_IP6, "%s%s%s %s not support extended IFA_FLAGS (needed by NM for IPv6 private addresses)", + !s_kernel ? "kernel" : "", + !s_kernel && !s_libnl ? " and " : "", + !s_libnl ? "libnl" : "", + !s_kernel && !s_libnl ? "do" : "does"); + warn = 1; + } + return; + } + + if (!s_libnl && !s_kernel) { + nm_log_warn (LOGD_IP6, "libnl and the kernel do not support extended IFA_FLAGS needed by NM for " + "IPv6 private addresses. This feature is not available"); + } else if (!s_libnl) { + nm_log_warn (LOGD_IP6, "libnl does not support extended IFA_FLAGS needed by NM for " + "IPv6 private addresses. This feature is not available"); + } else if (!s_kernel) { + nm_log_warn (LOGD_IP6, "The kernel does not support extended IFA_FLAGS needed by NM for " + "IPv6 private addresses. This feature is not available"); + } + + warn = 2; +} + static void rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *device) { @@ -3298,6 +3370,28 @@ 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 have no ipv6-privacy and must add autoconf addresses + * as /128. The reason for the /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, these flags will be ignored. + * Still, we set them (why not?). + **/ + ifa_flags = IFA_F_NOPREFIXROUTE; + if (priv->rdisc_use_tempaddr == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR + || priv->rdisc_use_tempaddr == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR) + ifa_flags |= IFA_F_MANAGETEMPADDR; g_return_if_fail (priv->act_request); connection = nm_device_get_connection (device); @@ -3320,17 +3414,23 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *device /* Rebuild address list from router discovery cache. */ nm_ip6_config_reset_addresses (priv->ac_ip6_config); + /* rdisc->addresses contains at most max_addresses entries. + * This is different from what the kernel does, which + * also counts static and temporary addresses when checking + * max_addresses. + **/ for (i = 0; i < rdisc->addresses->len; i++) { NMRDiscAddress *discovered_address = &g_array_index (rdisc->addresses, NMRDiscAddress, i); NMPlatformIP6Address address; 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); } @@ -3412,7 +3512,7 @@ rdisc_config_changed (NMRDisc *rdisc, NMRDiscConfigMap changed, NMDevice *device } static gboolean -addrconf6_start (NMDevice *self) +addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMConnection *connection; @@ -3428,12 +3528,16 @@ addrconf6_start (NMDevice *self) priv->ac_ip6_config = NULL; } - priv->rdisc = nm_lndp_rdisc_new (nm_device_get_ip_ifindex (self), ip_iface); + priv->rdisc = nm_lndp_rdisc_new (nm_device_get_ip_ifindex (self), ip_iface, + sysctl_get_ipv6_max_addresses (ip_iface)); if (!priv->rdisc) { nm_log_err (LOGD_IP6, "(%s): failed to start router discovery.", ip_iface); return FALSE; } + priv->rdisc_use_tempaddr = use_tempaddr; + print_support_extended_ifa_flags (use_tempaddr); + /* ensure link local is ready... */ ret = linklocal6_start (self); if (ret == NM_ACT_STAGE_RETURN_SUCCESS) @@ -3480,10 +3584,23 @@ addrconf6_cleanup (NMDevice *self) /******************************************/ +static NMSettingIP6ConfigPrivacy +use_tempaddr_clamp (NMSettingIP6ConfigPrivacy use_tempaddr) +{ + switch (use_tempaddr) { + case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED: + case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR: + case NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR: + return use_tempaddr; + default: + return NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN; + } +} + /* Get net.ipv6.conf.default.use_tempaddr value from /etc/sysctl.conf or * /lib/sysctl.d/sysctl.conf */ -static int +static NMSettingIP6ConfigPrivacy ip6_use_tempaddr (void) { char *contents = NULL; @@ -3491,12 +3608,13 @@ ip6_use_tempaddr (void) char *sysctl_data = NULL; GKeyFile *keyfile; GError *error = NULL; - int tmp, ret = -1; + gint tmp; + NMSettingIP6ConfigPrivacy ret = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN; /* Read file contents to a string. */ if (!g_file_get_contents ("/etc/sysctl.conf", &contents, NULL, NULL)) if (!g_file_get_contents ("/lib/sysctl.d/sysctl.conf", &contents, NULL, NULL)) - return -1; + return NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN; /* Prepend a group so that we can use GKeyFile parser. */ sysctl_data = g_strdup_printf ("%s%s", group_name, contents); @@ -3507,7 +3625,7 @@ ip6_use_tempaddr (void) tmp = g_key_file_get_integer (keyfile, "forged_group", "net.ipv6.conf.default.use_tempaddr", &error); if (error == NULL) - ret = tmp; + ret = use_tempaddr_clamp (tmp); done: g_free (contents); @@ -3544,7 +3662,6 @@ act_stage3_ip6_config_start (NMDevice *self, NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; NMConnection *connection; const char *method; - int conf_use_tempaddr; NMSettingIP6ConfigPrivacy ip6_privacy = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN; const char *ip6_privacy_str = "0\n"; GSList *slaves; @@ -3596,8 +3713,21 @@ act_stage3_ip6_config_start (NMDevice *self, /* Re-enable IPv6 on the interface */ nm_platform_sysctl_set (priv->ip6_disable_ipv6_path, "0"); + /* Enable/disable IPv6 Privacy Extensions. + * If a global value is configured by sysadmin (e.g. /etc/sysctl.conf), + * use that value instead of per-connection value. + */ + ip6_privacy = ip6_use_tempaddr (); + if (ip6_privacy == NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN) { + NMSettingIP6Config *s_ip6 = nm_connection_get_setting_ip6_config (connection); + + if (s_ip6) + ip6_privacy = nm_setting_ip6_config_get_ip6_privacy (s_ip6); + } + ip6_privacy = use_tempaddr_clamp (ip6_privacy); + if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0) { - if (!addrconf6_start (self)) { + if (!addrconf6_start (self, ip6_privacy)) { /* IPv6 might be disabled; allow IPv4 to proceed */ ret = NM_ACT_STAGE_RETURN_STOP; } else @@ -3625,21 +3755,6 @@ act_stage3_ip6_config_start (NMDevice *self, /* Other methods (shared) aren't implemented yet */ - /* Enable/disable IPv6 Privacy Extensions. - * If a global value is configured by sysadmin (e.g. /etc/sysctl.conf), - * use that value instead of per-connection value. - */ - conf_use_tempaddr = ip6_use_tempaddr (); - if (conf_use_tempaddr >= 0) - ip6_privacy = conf_use_tempaddr; - else { - NMSettingIP6Config *s_ip6 = nm_connection_get_setting_ip6_config (connection); - - if (s_ip6) - ip6_privacy = nm_setting_ip6_config_get_ip6_privacy (s_ip6); - } - ip6_privacy = CLAMP (ip6_privacy, NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR); - switch (ip6_privacy) { case NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN: case NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED: diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index f6510eca79..d99cb1d580 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -67,6 +67,8 @@ typedef struct { GUdevClient *udev_client; GHashTable *udev_devices; + + int support_kernel_extended_ifa_flags; } NMLinuxPlatformPrivate; #define NM_LINUX_PLATFORM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_LINUX_PLATFORM, NMLinuxPlatformPrivate)) @@ -429,6 +431,45 @@ ethtool_get_stringset_index (const char *ifname, int stringset_id, const char *s /******************************************************************/ +static void +_check_support_kernel_extended_ifa_flags_init (NMLinuxPlatformPrivate *priv, struct nl_msg *msg) +{ + struct nlmsghdr *msg_hdr = nlmsg_hdr (msg); + + g_return_if_fail (priv->support_kernel_extended_ifa_flags == 0); + g_return_if_fail (msg_hdr->nlmsg_type == RTM_NEWADDR); + + /* the extended address flags are only set for AF_INET6 */ + if (((struct ifaddrmsg *) nlmsg_data (msg_hdr))->ifa_family != AF_INET6) + return; + + /* see if the nl_msg contains the IFA_FLAGS attribute. If it does, + * we assume, that the kernel supports extended flags, IFA_F_MANAGETEMPADDR + * and IFA_F_NOPREFIXROUTE (they were added together). + **/ + priv->support_kernel_extended_ifa_flags = + nlmsg_find_attr (msg_hdr, sizeof (struct ifaddrmsg), 8 /* IFA_FLAGS */) + ? 1 : -1; +} + +static gboolean +check_support_kernel_extended_ifa_flags (NMPlatform *platform) +{ + NMLinuxPlatformPrivate *priv; + + g_return_val_if_fail (NM_IS_LINUX_PLATFORM (platform), FALSE); + + priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); + + if (priv->support_kernel_extended_ifa_flags == 0) { + g_warn_if_reached (); + priv->support_kernel_extended_ifa_flags = -1; + } + + return priv->support_kernel_extended_ifa_flags > 0; +} + + /* Object type specific utilities */ static const char * @@ -1224,6 +1265,14 @@ event_notification (struct nl_msg *msg, gpointer user_data) int nle; event = nlmsg_hdr (msg)->nlmsg_type; + + if (priv->support_kernel_extended_ifa_flags == 0 && event == RTM_NEWADDR) { + /* if kernel support for extended ifa flags is still undecided, use the opportunity + * now and use @msg to decide it. This saves a blocking net link request. + **/ + _check_support_kernel_extended_ifa_flags_init (priv, msg); + } + nl_msg_parse (msg, ref_object, &object); g_return_val_if_fail (object, NL_OK); @@ -2806,6 +2855,12 @@ setup (NMPlatform *platform) g_list_free (devices); g_object_unref (enumerator); + /* request all IPv6 addresses (hopeing that there is at least one), to check for + * the IFA_FLAGS attribute. */ + nle = nl_rtgen_request (priv->nlh_event, RTM_GETADDR, AF_INET6, NLM_F_DUMP); + if (nle != 0) + nm_log_warn (LOGD_PLATFORM, "Netlink error: requesting RTM_GETADDR failed with %s", nl_geterror (nle)); + return TRUE; } @@ -2910,4 +2965,6 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass) platform_class->ip6_route_delete = ip6_route_delete; platform_class->ip4_route_exists = ip4_route_exists; platform_class->ip6_route_exists = ip6_route_exists; + + platform_class->check_support_kernel_extended_ifa_flags = check_support_kernel_extended_ifa_flags; } diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 44d50c2dca..79eb06523a 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -31,6 +31,14 @@ #include "nm-logging.h" #include "nm-enum-types.h" +/* workaround for older libnl version, that does not define these flags. */ +#ifndef IFA_F_MANAGETEMPADDR +#define IFA_F_MANAGETEMPADDR 0x100 +#endif +#ifndef IFA_F_NOPREFIXROUTE +#define IFA_F_NOPREFIXROUTE 0x200 +#endif + #define debug(...) nm_log_dbg (LOGD_PLATFORM, __VA_ARGS__) #define NM_PLATFORM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_PLATFORM, NMPlatformPrivate)) @@ -196,6 +204,33 @@ reset_error (void) platform->error = NM_PLATFORM_ERROR_NONE; } +#define IFA_F_MANAGETEMPADDR_STR "mngtmpaddr" +#define IFA_F_NOPREFIXROUTE_STR "noprefixroute" +gboolean +nm_platform_check_support_libnl_extended_ifa_flags () +{ + static int supported = -1; + + /* support for extended ifa-flags was added together + * with the IFA_F_MANAGETEMPADDR flag. So, check if libnl + * is able to parse this flag. */ + if (supported == -1) + supported = rtnl_addr_str2flags (IFA_F_MANAGETEMPADDR_STR) == IFA_F_MANAGETEMPADDR; + + return supported; +} + +gboolean +nm_platform_check_support_kernel_extended_ifa_flags () +{ + g_return_val_if_fail (NM_IS_PLATFORM (platform), FALSE); + + if (!klass->check_support_kernel_extended_ifa_flags) + return FALSE; + + return klass->check_support_kernel_extended_ifa_flags (platform); +} + /******************************************************************/ /** @@ -1842,7 +1877,22 @@ nm_platform_ip6_address_to_string (const NMPlatformIP6Address *address) s_dev = address->ifindex > 0 ? nm_platform_link_get_name (address->ifindex) : NULL; str_dev = s_dev ? g_strconcat (" dev ", s_dev, NULL) : NULL; - rtnl_addr_flags2str(address->flags, s_flags, sizeof(s_flags)); + rtnl_addr_flags2str(address->flags, s_flags, sizeof (s_flags)); + + /* There are two recent flags IFA_F_MANAGETEMPADDR and IFA_F_NOPREFIXROUTE. + * If libnl does not yet support them, add them by hand. + * These two flags were introduced together with the extended ifa_flags, + * so, check for that. + **/ + if ((address->flags && IFA_F_MANAGETEMPADDR) & !nm_platform_check_support_libnl_extended_ifa_flags ()) { + strncat (s_flags, s_flags[0] ? "," IFA_F_MANAGETEMPADDR_STR : IFA_F_MANAGETEMPADDR_STR, + sizeof (s_flags) - strlen (s_flags) - 1); + } + if ((address->flags && IFA_F_NOPREFIXROUTE) & !nm_platform_check_support_libnl_extended_ifa_flags ()) { + strncat (s_flags, s_flags[0] ? "," IFA_F_NOPREFIXROUTE_STR : IFA_F_NOPREFIXROUTE_STR, + sizeof (s_flags) - strlen (s_flags) - 1); + } + str_flags = s_flags[0] ? g_strconcat (" flags ", s_flags, NULL) : NULL; g_snprintf (buffer, sizeof (buffer), "%s/%d lft %u pref %u time %u%s%s%s src %s", diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 6ccaac79e9..a219a3794c 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -323,6 +323,8 @@ typedef struct { gboolean (*ip6_route_delete) (NMPlatform *, int ifindex, struct in6_addr network, int plen, int metric); gboolean (*ip4_route_exists) (NMPlatform *, int ifindex, in_addr_t network, int plen, int metric); gboolean (*ip6_route_exists) (NMPlatform *, int ifindex, struct in6_addr network, int plen, int metric); + + gboolean (*check_support_kernel_extended_ifa_flags) (NMPlatform *); } NMPlatformClass; /* NMPlatform signals @@ -465,6 +467,9 @@ int nm_platform_ip6_address_cmp (const NMPlatformIP6Address *a, const NMPlatform int nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route *b); int nm_platform_ip6_route_cmp (const NMPlatformIP6Route *a, const NMPlatformIP6Route *b); +gboolean nm_platform_check_support_libnl_extended_ifa_flags (void); +gboolean nm_platform_check_support_kernel_extended_ifa_flags (void); + #define auto_g_free __attribute__((cleanup(put_g_free))) static void __attribute__((unused)) put_g_free (void *ptr) diff --git a/src/rdisc/nm-fake-rdisc.c b/src/rdisc/nm-fake-rdisc.c index f39c5a208c..38faa5078a 100644 --- a/src/rdisc/nm-fake-rdisc.c +++ b/src/rdisc/nm-fake-rdisc.c @@ -36,7 +36,7 @@ G_DEFINE_TYPE (NMFakeRDisc, nm_fake_rdisc, NM_TYPE_RDISC) /******************************************************************/ NMRDisc * -nm_fake_rdisc_new (int ifindex, const char *ifname) +nm_fake_rdisc_new (int ifindex, const char *ifname, gint32 max_addresses) { NMRDisc *rdisc = g_object_new (NM_TYPE_FAKE_RDISC, NULL); @@ -44,6 +44,7 @@ nm_fake_rdisc_new (int ifindex, const char *ifname) rdisc->ifindex = ifindex; rdisc->ifname = g_strdup (ifname); + rdisc->max_addresses = max_addresses; return rdisc; } diff --git a/src/rdisc/nm-fake-rdisc.h b/src/rdisc/nm-fake-rdisc.h index 248283b22b..cff9ee4494 100644 --- a/src/rdisc/nm-fake-rdisc.h +++ b/src/rdisc/nm-fake-rdisc.h @@ -44,6 +44,6 @@ typedef struct { GType nm_fake_rdisc_get_type (void); -NMRDisc *nm_fake_rdisc_new (int ifindex, const char *ifname); +NMRDisc *nm_fake_rdisc_new (int ifindex, const char *ifname, gint32 max_addressses); #endif /* NM_FAKE_RDISC_H */ diff --git a/src/rdisc/nm-lndp-rdisc.c b/src/rdisc/nm-lndp-rdisc.c index 04b52067fc..e7124f1b7a 100644 --- a/src/rdisc/nm-lndp-rdisc.c +++ b/src/rdisc/nm-lndp-rdisc.c @@ -48,7 +48,7 @@ G_DEFINE_TYPE (NMLNDPRDisc, nm_lndp_rdisc, NM_TYPE_RDISC) /******************************************************************/ NMRDisc * -nm_lndp_rdisc_new (int ifindex, const char *ifname) +nm_lndp_rdisc_new (int ifindex, const char *ifname, gint32 max_addresses) { NMRDisc *rdisc; NMLNDPRDiscPrivate *priv; @@ -59,6 +59,7 @@ nm_lndp_rdisc_new (int ifindex, const char *ifname) rdisc->ifindex = ifindex; rdisc->ifname = g_strdup (ifname); + rdisc->max_addresses = max_addresses; priv = NM_LNDP_RDISC_GET_PRIVATE (rdisc); error = ndp_open (&priv->ndp); @@ -113,6 +114,13 @@ add_address (NMRDisc *rdisc, const NMRDiscAddress *new) } } + /* we create at most max_addresses autoconf addresses. This is different from + * what the kernel does, because it considers *all* addresses (including + * static and other temporary addresses). + **/ + if (rdisc->max_addresses && rdisc->addresses->len >= rdisc->max_addresses) + return FALSE; + g_array_insert_val (rdisc->addresses, i, *new); return TRUE; } diff --git a/src/rdisc/nm-lndp-rdisc.h b/src/rdisc/nm-lndp-rdisc.h index eb6a1df6d9..30d53db409 100644 --- a/src/rdisc/nm-lndp-rdisc.h +++ b/src/rdisc/nm-lndp-rdisc.h @@ -44,6 +44,6 @@ typedef struct { GType nm_lndp_rdisc_get_type (void); -NMRDisc *nm_lndp_rdisc_new (int ifindex, const char *ifname); +NMRDisc *nm_lndp_rdisc_new (int ifindex, const char *ifname, gint32 max_addresses); #endif /* NM_LNDP_RDISC_H */ diff --git a/src/rdisc/nm-rdisc.h b/src/rdisc/nm-rdisc.h index 75262d862b..4690a5f5e7 100644 --- a/src/rdisc/nm-rdisc.h +++ b/src/rdisc/nm-rdisc.h @@ -106,6 +106,7 @@ typedef struct { int ifindex; char *ifname; GBytes *lladdr; + gint32 max_addresses; NMRDiscDHCPLevel dhcp_level; GArray *gateways; diff --git a/src/rdisc/tests/rdisc.c b/src/rdisc/tests/rdisc.c index fc6e86be08..6a0591af54 100644 --- a/src/rdisc/tests/rdisc.c +++ b/src/rdisc/tests/rdisc.c @@ -12,7 +12,7 @@ main (int argc, char **argv) { GMainLoop *loop; NMRDisc *rdisc; - NMRDisc *(*new) (int ifindex, const char *ifname) = nm_lndp_rdisc_new; + NMRDisc *(*new) (int ifindex, const char *ifname, gint32 max_addresses) = nm_lndp_rdisc_new; int ifindex = 1; char ifname[IF_NAMESIZE]; char mac[6] = { 0x02, 0xaa, 0xbb, 0xcc, 0xdd, 0xee }; @@ -34,7 +34,7 @@ main (int argc, char **argv) } } - rdisc = new (ifindex, ifname); + rdisc = new (ifindex, ifname, 0); if (!rdisc) return EXIT_FAILURE;