aboutsummaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2013-10-23 14:00:12 +0100
committerMichael Brown <mcb30@ipxe.org>2013-10-23 14:07:57 +0100
commit33652880a7b5881d3f2181fea94bed2ba525d44b (patch)
tree0dc21f0a479a0865155a21866e0a2d3cdcb9291f /src/include
parent2dca2e6ade6ed89029b2812a0a6f07276cdace76 (diff)
downloadipxe-33652880a7b5881d3f2181fea94bed2ba525d44b.zip
ipxe-33652880a7b5881d3f2181fea94bed2ba525d44b.tar.gz
ipxe-33652880a7b5881d3f2181fea94bed2ba525d44b.tar.bz2
[ipv6] Support stateless address autoconfiguration (SLAAC)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/include')
-rw-r--r--src/include/ipxe/ipv6.h27
-rw-r--r--src/include/ipxe/ndp.h67
2 files changed, 76 insertions, 18 deletions
diff --git a/src/include/ipxe/ipv6.h b/src/include/ipxe/ipv6.h
index f404ba6..6a9aa60 100644
--- a/src/include/ipxe/ipv6.h
+++ b/src/include/ipxe/ipv6.h
@@ -173,20 +173,18 @@ struct ipv6_miniroute {
};
/**
- * Construct link-local address (via EUI-64)
+ * Construct local IPv6 address via EUI-64
*
- * @v addr Address to construct
+ * @v addr Prefix to be completed
* @v netdev Network device
* @ret prefix_len Prefix length, or negative error
*/
-static inline int ipv6_link_local ( struct in6_addr *addr,
- struct net_device *netdev ) {
+static inline int ipv6_eui64 ( struct in6_addr *addr,
+ struct net_device *netdev ) {
struct ll_protocol *ll_protocol = netdev->ll_protocol;
const void *ll_addr = netdev->ll_addr;
int rc;
- memset ( addr, 0, sizeof ( *addr ) );
- addr->s6_addr16[0] = htons ( 0xfe80 );
if ( ( rc = ll_protocol->eui64 ( ll_addr, &addr->s6_addr[8] ) ) != 0 )
return rc;
addr->s6_addr[8] ^= 0x02;
@@ -194,6 +192,21 @@ static inline int ipv6_link_local ( struct in6_addr *addr,
}
/**
+ * Construct link-local address via EUI-64
+ *
+ * @v addr Address to construct
+ * @v netdev Network device
+ * @ret prefix_len Prefix length, or negative error
+ */
+static inline int ipv6_link_local ( struct in6_addr *addr,
+ struct net_device *netdev ) {
+
+ memset ( addr, 0, sizeof ( *addr ) );
+ addr->s6_addr16[0] = htons ( 0xfe80 );
+ return ipv6_eui64 ( addr, netdev );
+}
+
+/**
* Construct solicited-node multicast address
*
* @v addr Address to construct
@@ -214,5 +227,7 @@ extern struct list_head ipv6_miniroutes;
extern struct net_protocol ipv6_protocol __net_protocol;
extern int ipv6_has_addr ( struct net_device *netdev, struct in6_addr *addr );
+extern int ipv6_slaac ( struct net_device *netdev, struct in6_addr *prefix,
+ unsigned int prefix_len, struct in6_addr *router );
#endif /* _IPXE_IPV6_H */
diff --git a/src/include/ipxe/ndp.h b/src/include/ipxe/ndp.h
index 92f6da5..4edd96a 100644
--- a/src/include/ipxe/ndp.h
+++ b/src/include/ipxe/ndp.h
@@ -15,19 +15,68 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/icmpv6.h>
#include <ipxe/neighbour.h>
-/** An NDP option */
-struct ndp_option {
+/** An NDP option header */
+struct ndp_option_header {
/** Type */
uint8_t type;
/** Length (in blocks of 8 bytes) */
uint8_t blocks;
- /** Value */
- uint8_t value[0];
} __attribute__ (( packed ));
/** NDP option block size */
#define NDP_OPTION_BLKSZ 8
+/** NDP source link-layer address option */
+#define NDP_OPT_LL_SOURCE 1
+
+/** NDP target link-layer address option */
+#define NDP_OPT_LL_TARGET 2
+
+/** NDP source or target link-layer address option */
+struct ndp_ll_addr_option {
+ /** NDP option header */
+ struct ndp_option_header header;
+ /** Link-layer address */
+ uint8_t ll_addr[0];
+} __attribute__ (( packed ));
+
+/** NDP prefix information option */
+#define NDP_OPT_PREFIX 3
+
+/** NDP prefix information */
+struct ndp_prefix_information_option {
+ /** NDP option header */
+ struct ndp_option_header header;
+ /** Prefix length */
+ uint8_t prefix_len;
+ /** Flags */
+ uint8_t flags;
+ /** Valid lifetime */
+ uint32_t valid;
+ /** Preferred lifetime */
+ uint32_t preferred;
+ /** Reserved */
+ uint32_t reserved;
+ /** Prefix */
+ struct in6_addr prefix;
+} __attribute__ (( packed ));
+
+/** NDP on-link flag */
+#define NDP_PREFIX_ON_LINK 0x80
+
+/** NDP autonomous address configuration flag */
+#define NDP_PREFIX_AUTONOMOUS 0x40
+
+/** An NDP option */
+union ndp_option {
+ /** Option header */
+ struct ndp_option_header header;
+ /** Source or target link-layer address option */
+ struct ndp_ll_addr_option ll_addr;
+ /** Prefix information option */
+ struct ndp_prefix_information_option prefix;
+} __attribute__ (( packed ));
+
/** An NDP neighbour solicitation or advertisement header */
struct ndp_neighbour_header {
/** ICMPv6 header */
@@ -39,7 +88,7 @@ struct ndp_neighbour_header {
/** Target address */
struct in6_addr target;
/** Options */
- struct ndp_option option[0];
+ union ndp_option option[0];
} __attribute__ (( packed ));
/** NDP router flag */
@@ -66,7 +115,7 @@ struct ndp_router_advertisement_header {
/** Retransmission timer */
uint32_t retransmit;
/** Options */
- struct ndp_option option[0];
+ union ndp_option option[0];
} __attribute__ (( packed ));
/** NDP managed address configuration */
@@ -85,12 +134,6 @@ union ndp_header {
struct ndp_router_advertisement_header radv;
} __attribute__ (( packed ));
-/** NDP source link-layer address option */
-#define NDP_OPT_LL_SOURCE 1
-
-/** NDP target link-layer address option */
-#define NDP_OPT_LL_TARGET 2
-
extern struct neighbour_discovery ndp_discovery;
/**