aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2022-09-13 13:25:19 +0100
committerMichael Brown <mcb30@ipxe.org>2022-09-13 13:25:19 +0100
commit8f5fc161436a020ba65d07f91f62d34f4c22db61 (patch)
treedfca92e23db01fdea59aef47e3dbe567eb2d5580
parentbc19aeca5f6c695ad3db0196057d155e4f64584e (diff)
downloadipxe-8f5fc161436a020ba65d07f91f62d34f4c22db61.zip
ipxe-8f5fc161436a020ba65d07f91f62d34f4c22db61.tar.gz
ipxe-8f5fc161436a020ba65d07f91f62d34f4c22db61.tar.bz2
[ipv6] Ignore SLAAC on prefixes with an incompatible prefix length
Experience suggests that routers are often misconfigured to advertise SLAAC even on prefixes that do not have a SLAAC-compatible prefix length. iPXE will currently treat this as an error, resulting in the prefix being ignored completely. Handle this misconfiguration by ignoring the autonomous address flag when the prefix length is unsuitable for SLAAC. Reported-by: Malte Janduda <mail@janduda.net> Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/net/ndp.c36
1 files changed, 25 insertions, 11 deletions
diff --git a/src/net/ndp.c b/src/net/ndp.c
index 75e5316..c8e8eba 100644
--- a/src/net/ndp.c
+++ b/src/net/ndp.c
@@ -789,29 +789,43 @@ static int ndp_prefix_fetch_ip6 ( struct settings *settings, void *data,
container_of ( ndpset->settings.parent, struct net_device,
settings.settings );
struct ndp_prefix_information_option *prefix = prefset->prefix;
- struct in6_addr ip6;
+ struct in6_addr *ip6 = &prefix->prefix;
+ struct in6_addr slaac;
int prefix_len;
+ int rc;
/* Skip dead prefixes */
if ( ! prefix->valid )
return -ENOENT;
/* Construct IPv6 address via SLAAC, if applicable */
- memcpy ( &ip6, &prefix->prefix, sizeof ( ip6 ) );
if ( prefix->flags & NDP_PREFIX_AUTONOMOUS ) {
- prefix_len = ipv6_eui64 ( &ip6, netdev );
- if ( prefix_len < 0 )
- return prefix_len;
- if ( prefix_len != prefix->prefix_len )
- return -EINVAL;
+ memcpy ( &slaac, ip6, sizeof ( slaac ) );
+ prefix_len = ipv6_eui64 ( &slaac, netdev );
+ if ( prefix_len == prefix->prefix_len ) {
+ /* Correctly configured prefix: use SLAAC address */
+ ip6 = &slaac;
+ } else if ( prefix_len < 0 ) {
+ /* Link layer does not support SLAAC */
+ rc = prefix_len;
+ DBGC ( netdev, "NDP %s does not support SLAAC: %s\n",
+ netdev->name, strerror ( rc ) );
+ } else {
+ /* Prefix length incorrect: assume a badly
+ * configured router and ignore SLAAC address.
+ */
+ DBGC ( netdev, "NDP %s ignoring misconfigured SLAAC "
+ "on prefix %s/%d\n", netdev->name,
+ inet6_ntoa ( ip6 ), prefix->prefix_len );
+ }
}
/* Fill in IPv6 address */
- if ( len > sizeof ( ip6 ) )
- len = sizeof ( ip6 );
- memcpy ( data, &ip6, len );
+ if ( len > sizeof ( *ip6 ) )
+ len = sizeof ( *ip6 );
+ memcpy ( data, ip6, len );
- return sizeof ( ip6 );
+ return sizeof ( *ip6 );
}
/**