mirror of https://github.com/ipxe/ipxe.git
[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>pull/56/head
parent
517d234031
commit
c53a209a42
|
@ -38,6 +38,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static struct ipv6conf * ipv6conf_demux ( struct net_device *netdev );
|
||||||
static int
|
static int
|
||||||
ipv6conf_rx_router_advertisement ( struct net_device *netdev,
|
ipv6conf_rx_router_advertisement ( struct net_device *netdev,
|
||||||
struct ndp_router_advertisement_header *radv,
|
struct ndp_router_advertisement_header *radv,
|
||||||
|
@ -341,6 +342,7 @@ ndp_rx_router_advertisement_prefix ( struct net_device *netdev,
|
||||||
struct ndp_prefix_information_option *prefix_opt = &option->prefix;
|
struct ndp_prefix_information_option *prefix_opt = &option->prefix;
|
||||||
struct in6_addr *router = &sin6_src->sin6_addr;
|
struct in6_addr *router = &sin6_src->sin6_addr;
|
||||||
struct in6_addr address;
|
struct in6_addr address;
|
||||||
|
struct ipv6conf *ipv6conf;
|
||||||
int prefix_len;
|
int prefix_len;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -350,14 +352,21 @@ ndp_rx_router_advertisement_prefix ( struct net_device *netdev,
|
||||||
"short at %zd bytes\n", netdev->name, len );
|
"short at %zd bytes\n", netdev->name, len );
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Identify IPv6 configurator, if any */
|
||||||
|
ipv6conf = ipv6conf_demux ( netdev );
|
||||||
DBGC ( netdev, "NDP %s found %sdefault router %s ",
|
DBGC ( netdev, "NDP %s found %sdefault router %s ",
|
||||||
netdev->name, ( radv->lifetime ? "" : "non-" ),
|
netdev->name, ( radv->lifetime ? "" : "non-" ),
|
||||||
inet6_ntoa ( &sin6_src->sin6_addr ) );
|
inet6_ntoa ( &sin6_src->sin6_addr ) );
|
||||||
DBGC ( netdev, "for %s-link %sautonomous prefix %s/%d\n",
|
DBGC ( netdev, "for %s-link %sautonomous prefix %s/%d%s\n",
|
||||||
( ( prefix_opt->flags & NDP_PREFIX_ON_LINK ) ? "on" : "off" ),
|
( ( prefix_opt->flags & NDP_PREFIX_ON_LINK ) ? "on" : "off" ),
|
||||||
( ( prefix_opt->flags & NDP_PREFIX_AUTONOMOUS ) ? "" : "non-" ),
|
( ( prefix_opt->flags & NDP_PREFIX_AUTONOMOUS ) ? "" : "non-" ),
|
||||||
inet6_ntoa ( &prefix_opt->prefix ),
|
inet6_ntoa ( &prefix_opt->prefix ),
|
||||||
prefix_opt->prefix_len );
|
prefix_opt->prefix_len, ( ipv6conf ? "" : " (ignored)" ) );
|
||||||
|
|
||||||
|
/* Do nothing unless IPv6 autoconfiguration is in progress */
|
||||||
|
if ( ! ipv6conf )
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* Ignore off-link prefixes */
|
/* Ignore off-link prefixes */
|
||||||
if ( ! ( prefix_opt->flags & NDP_PREFIX_ON_LINK ) )
|
if ( ! ( prefix_opt->flags & NDP_PREFIX_ON_LINK ) )
|
||||||
|
@ -915,13 +924,10 @@ ipv6conf_rx_router_advertisement ( struct net_device *netdev,
|
||||||
|
|
||||||
/* Identify IPv6 configurator, if any */
|
/* Identify IPv6 configurator, if any */
|
||||||
ipv6conf = ipv6conf_demux ( netdev );
|
ipv6conf = ipv6conf_demux ( netdev );
|
||||||
if ( ! ipv6conf ) {
|
|
||||||
/* Not an error; router advertisements are processed
|
/* Do nothing unless IPv6 autoconfiguration is in progress */
|
||||||
* as a background activity even when no explicit
|
if ( ! ipv6conf )
|
||||||
* autoconfiguration is taking place.
|
|
||||||
*/
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
/* If this is not the first solicited router advertisement, ignore it */
|
/* If this is not the first solicited router advertisement, ignore it */
|
||||||
if ( ! timer_running ( &ipv6conf->timer ) )
|
if ( ! timer_running ( &ipv6conf->timer ) )
|
||||||
|
|
Loading…
Reference in New Issue