[PATCH] Use /128 as prefix length for IA_NA assignments



DHCPv6 IA_NA assignments do not contain a prefix length, they are for a
single address (/128) only. However, the ISC DHCPv6 client incorrectly
assumes IA_NA assignments come with a implicit prefix length of /64, and
passes this incorrect information on to NetworkManager, which adds this
prefix as a on-link route. This will cause communication failures in
certain networks, for example NBMA networks, and in organisations using
longer prefix lengths than /64 for their LANs. For more discussion
regarding this problem, see RFC 5942 section 5.

This patch makes NM ignore the false prefix length attribute provided by
the ISC DHCPv6 client, instead setting it to a /128 (single address) in
all cases. Note that this does not preclude an on-link prefix from being
added by NM if it is being advertised in the correct way, i.e., by
including a Prefix Information Option with the L flag set in an ICMPv6
Router Advertisement.

Fixes: bgo #656610, debian #661885

For what it's worth I've also sent a patch to ISC to change the hard-
coded implicit prefix length value from /64 to /128 in [ISC-Bugs #29468].
---
 src/dhcp-manager/nm-dhcp-client.c |   26 ++++++--------------------
 1 files changed, 6 insertions(+), 20 deletions(-)

diff --git a/src/dhcp-manager/nm-dhcp-client.c b/src/dhcp-manager/nm-dhcp-client.c
index f6fec0a..6a4b5ea 100644
--- a/src/dhcp-manager/nm-dhcp-client.c
+++ b/src/dhcp-manager/nm-dhcp-client.c
@@ -1244,7 +1244,12 @@ ip6_options_to_config (NMDHCPClient *self)
 		}
 
 		nm_ip6_address_set_address (addr, &tmp_addr);
-		nm_log_info (LOGD_DHCP6, "  address %s", str);
+		/* DHCPv6 IA_NA assignments are single address only */
+		nm_ip6_address_set_prefix (addr, (guint32) 128);
+		nm_log_info (LOGD_DHCP6, "  address %s/128", str);
+
+		nm_ip6_config_take_address (ip6_config, addr);
+		addr = NULL;
 	} else {
 		/* No address in managed mode is a hard error */
 		if (priv->info_only == FALSE)
@@ -1255,25 +1260,6 @@ ip6_options_to_config (NMDHCPClient *self)
 		addr = NULL;
 	}
 
-	/* Only care about prefix if we got an address */
-	if (addr) {
-		str = g_hash_table_lookup (priv->options, "new_ip6_prefixlen");
-		if (str) {
-			long unsigned int prefix;
-
-			errno = 0;
-			prefix = strtoul (str, NULL, 10);
-			if (errno != 0 || prefix > 128)
-				goto error;
-
-			nm_ip6_address_set_prefix (addr, (guint32) prefix);
-			nm_log_info (LOGD_DHCP6, "  prefix %lu", prefix);
-		}
-
-		nm_ip6_config_take_address (ip6_config, addr);
-		addr = NULL;
-	}
-
 	str = g_hash_table_lookup (priv->options, "new_host_name");
 	if (str)
 		nm_log_info (LOGD_DHCP6, "  hostname '%s'", str);
-- 
1.7.7.6



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]