Browse Source

[ipv6] Perform SLAAC only during autoconfiguration

We currently perform IPv6 stateless address autoconfiguration (SLAAC)
in response to any router advertisement with the relevant flags set.
This can result in the local IPv6 source address changing midway
through a TCP connection, since our connections bind only to a local
port number and do not store a local network address.

In addition, this behaviour for SLAAC is inconsistent with that for
DHCPv4 and stateful DHCPv6, both of which will be performed only as a
result of an explicit autoconfiguration action (e.g. via the default
autoboot sequence, or the "ifconf" command).

Fix by ignoring router advertisements arriving outside the context of
an ongoing autoconfiguration attempt.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 8 years ago
parent
commit
c53a209a42
1 changed files with 14 additions and 8 deletions
  1. 14
    8
      src/net/ndp.c

+ 14
- 8
src/net/ndp.c View File

@@ -38,6 +38,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
38 38
  *
39 39
  */
40 40
 
41
+static struct ipv6conf * ipv6conf_demux ( struct net_device *netdev );
41 42
 static int
42 43
 ipv6conf_rx_router_advertisement ( struct net_device *netdev,
43 44
 				   struct ndp_router_advertisement_header *radv,
@@ -341,6 +342,7 @@ ndp_rx_router_advertisement_prefix ( struct net_device *netdev,
341 342
 	struct ndp_prefix_information_option *prefix_opt = &option->prefix;
342 343
 	struct in6_addr *router = &sin6_src->sin6_addr;
343 344
 	struct in6_addr address;
345
+	struct ipv6conf *ipv6conf;
344 346
 	int prefix_len;
345 347
 	int rc;
346 348
 
@@ -350,14 +352,21 @@ ndp_rx_router_advertisement_prefix ( struct net_device *netdev,
350 352
 		       "short at %zd bytes\n", netdev->name, len );
351 353
 		return -EINVAL;
352 354
 	}
355
+
356
+	/* Identify IPv6 configurator, if any */
357
+	ipv6conf = ipv6conf_demux ( netdev );
353 358
 	DBGC ( netdev, "NDP %s found %sdefault router %s ",
354 359
 	       netdev->name, ( radv->lifetime ? "" : "non-" ),
355 360
 	       inet6_ntoa ( &sin6_src->sin6_addr ) );
356
-	DBGC ( netdev, "for %s-link %sautonomous prefix %s/%d\n",
361
+	DBGC ( netdev, "for %s-link %sautonomous prefix %s/%d%s\n",
357 362
 	       ( ( prefix_opt->flags & NDP_PREFIX_ON_LINK ) ? "on" : "off" ),
358 363
 	       ( ( prefix_opt->flags & NDP_PREFIX_AUTONOMOUS ) ? "" : "non-" ),
359 364
 	       inet6_ntoa ( &prefix_opt->prefix ),
360
-	       prefix_opt->prefix_len );
365
+	       prefix_opt->prefix_len, ( ipv6conf ? "" : " (ignored)" ) );
366
+
367
+	/* Do nothing unless IPv6 autoconfiguration is in progress */
368
+	if ( ! ipv6conf )
369
+		return 0;
361 370
 
362 371
 	/* Ignore off-link prefixes */
363 372
 	if ( ! ( prefix_opt->flags & NDP_PREFIX_ON_LINK ) )
@@ -915,13 +924,10 @@ ipv6conf_rx_router_advertisement ( struct net_device *netdev,
915 924
 
916 925
 	/* Identify IPv6 configurator, if any */
917 926
 	ipv6conf = ipv6conf_demux ( netdev );
918
-	if ( ! ipv6conf ) {
919
-		/* Not an error; router advertisements are processed
920
-		 * as a background activity even when no explicit
921
-		 * autoconfiguration is taking place.
922
-		 */
927
+
928
+	/* Do nothing unless IPv6 autoconfiguration is in progress */
929
+	if ( ! ipv6conf )
923 930
 		return 0;
924
-	}
925 931
 
926 932
 	/* If this is not the first solicited router advertisement, ignore it */
927 933
 	if ( ! timer_running ( &ipv6conf->timer ) )

Loading…
Cancel
Save