From c0d2ad580748a7305bdf882911be3d2a18b6cfc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20=C5=A0imerda?= Date: Wed, 30 May 2012 15:02:51 +0200 Subject: [PATCH] ip6: pad RDNSS and DNSSL lifetimes to a minimum lifetime value (rh #753482) RFC 6106 says, section 5.1 says: In order to provide fixed hosts with stable DNS service and allow mobile hosts to prefer local RDNSSes to remote RDNSSes, the value of Lifetime SHOULD be bounded as MaxRtrAdvInterval <= Lifetime <= 2*MaxRtrAdvInterval I have reported and repeatedly confirmed that values in this interval trigger frequent RDNSS expiration on unreliable links such as 802.11 wifi. Wireless links *do* have packet loss and actually have a *much* worse multicast packet loss than unicast. And regular router advertisements are sent as multicast packets (in multicast frames). In case of RDNSS expiration, NetworkManager tears down the whole connection. That of course affects IPv4 networking as well as IPv6. In a typical wireless network with radvd serving RDNSS it leads to dropping network connection every ~10 minutes. This commit improves the previous hack in 0b8ee13 by enforcing a minimum lifetime of two hours (7200 seconds), which is four times the maximum allowed value for MaxRtrAdvInterval (see below). We could use AdvDefaultLifetime instead (as suggested by tore_ on IRC) but it doesn't seem to be accessible through netlink. RFC 4861 Neighbor Discovery for IP version 6 (IPv6): MaxRtrAdvInterval The maximum time allowed between sending unsolicited multicast Router Advertisements from the interface, in seconds. MUST be no less than 4 seconds and no greater than 1800 seconds. This solution is not recommended by any RFC (and is in fact against RFC 6106) but it's the easiest hack to fix the problem until IETF takes action. My original posting to IETF can be found here: http://www.ietf.org/mail-archive/web/ipv6/current/msg15816.html --- src/ip6-manager/nm-ip6-manager.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/ip6-manager/nm-ip6-manager.c b/src/ip6-manager/nm-ip6-manager.c index 7d58e29684..2b2f49ee24 100644 --- a/src/ip6-manager/nm-ip6-manager.c +++ b/src/ip6-manager/nm-ip6-manager.c @@ -748,7 +748,9 @@ process_nduseropt_rdnss (NMIP6Device *device, struct nd_opt_hdr *opt) */ server.expires = ntohl (rdnss_opt->nd_opt_rdnss_lifetime); if (server.expires > 0) - server.expires += now + 10; + if (server.expires < 7200) + server.expires = 7200; + server.expires += now; for (addr = (struct in6_addr *) (rdnss_opt + 1); opt_len >= 2; addr++, opt_len -= 2) { char buf[INET6_ADDRSTRLEN + 1]; @@ -879,7 +881,9 @@ process_nduseropt_dnssl (NMIP6Device *device, struct nd_opt_hdr *opt) */ domain.expires = ntohl (dnssl_opt->nd_opt_dnssl_lifetime); if (domain.expires > 0) - domain.expires += now + 10; + if (domain.expires < 7200) + domain.expires = 7200; + domain.expires += now; while (opt_len) { const char *domain_str;