[ipxe-devel] [PATCH 3/7] ipv6: Update link-local route when configuring network device

Hannes Reinecke hare at suse.de
Wed Apr 1 07:26:17 UTC 2015


The IPv6 link-local address is generated during probing.
So if the link-local address of the hardware is changed
later on the IPv6 link-local address will become incorrect.
So we should set the link-local route for IPv6 before
before the network configuration is started; this way
we will always have a correct link-local address.

Signed-off-by: Hannes Reinecke <hare at suse.de>
---
 src/include/ipxe/ipv6.h |  1 +
 src/net/ipv6.c          | 68 ++++++++++++++++++++++++++-----------------------
 src/net/ndp.c           |  6 +++++
 3 files changed, 43 insertions(+), 32 deletions(-)

diff --git a/src/include/ipxe/ipv6.h b/src/include/ipxe/ipv6.h
index b500382..a2b4c88 100644
--- a/src/include/ipxe/ipv6.h
+++ b/src/include/ipxe/ipv6.h
@@ -252,5 +252,6 @@ extern int parse_ipv6_setting ( const struct setting_type *type,
 extern int format_ipv6_setting ( const struct setting_type *type,
 				 const void *raw, size_t raw_len, char *buf,
 				 size_t len );
+extern int ipv6_ll_route ( struct net_device *netdev );
 
 #endif /* _IPXE_IPV6_H */
diff --git a/src/net/ipv6.c b/src/net/ipv6.c
index c5bead1..460f7b7 100644
--- a/src/net/ipv6.c
+++ b/src/net/ipv6.c
@@ -196,6 +196,42 @@ static struct ipv6_miniroute * ipv6_add_miniroute ( struct net_device *netdev,
 }
 
 /**
+ * Add IPv6 link-local routing table entry
+ *
+ * @v netdev		Network device
+ * @ret miniroute	Routing table entry, or NULL on failure
+ */
+int ipv6_ll_route ( struct net_device *netdev ) {
+	struct ipv6_miniroute *miniroute;
+	struct in6_addr address;
+	int prefix_len;
+	int rc;
+
+	/* Construct link-local address from EUI-64 as per RFC 2464 */
+	memset ( &address, 0, sizeof ( address ) );
+	prefix_len = ipv6_link_local ( &address, netdev );
+	if ( prefix_len < 0 ) {
+		rc = prefix_len;
+		DBGC ( netdev, "IPv6 %s could not construct link-local "
+		       "address: %s\n", netdev->name, strerror ( rc ) );
+		return rc;
+	}
+
+	/* Check if miniroute already exists */
+	miniroute = ipv6_miniroute ( netdev, &address );
+	if ( miniroute )
+		return 0;
+
+	/* Create link-local address for this network device */
+	miniroute = ipv6_add_miniroute ( netdev, &address, prefix_len,
+					 IPV6_HAS_ADDRESS );
+	if ( ! miniroute )
+		return -ENOMEM;
+
+	return 0;
+}
+
+/**
  * Define IPv6 on-link prefix
  *
  * @v netdev		Network device
@@ -1048,37 +1084,6 @@ int format_ipv6_setting ( const struct setting_type *type __unused,
 }
 
 /**
- * Create IPv6 network device
- *
- * @v netdev		Network device
- * @ret rc		Return status code
- */
-static int ipv6_probe ( struct net_device *netdev ) {
-	struct ipv6_miniroute *miniroute;
-	struct in6_addr address;
-	int prefix_len;
-	int rc;
-
-	/* Construct link-local address from EUI-64 as per RFC 2464 */
-	memset ( &address, 0, sizeof ( address ) );
-	prefix_len = ipv6_link_local ( &address, netdev );
-	if ( prefix_len < 0 ) {
-		rc = prefix_len;
-		DBGC ( netdev, "IPv6 %s could not construct link-local "
-		       "address: %s\n", netdev->name, strerror ( rc ) );
-		return rc;
-	}
-
-	/* Create link-local address for this network device */
-	miniroute = ipv6_add_miniroute ( netdev, &address, prefix_len,
-					 IPV6_HAS_ADDRESS );
-	if ( ! miniroute )
-		return -ENOMEM;
-
-	return 0;
-}
-
-/**
  * Destroy IPv6 network device
  *
  * @v netdev		Network device
@@ -1100,7 +1105,6 @@ static void ipv6_remove ( struct net_device *netdev ) {
 /** IPv6 network device driver */
 struct net_driver ipv6_driver __net_driver = {
 	.name = "IPv6",
-	.probe = ipv6_probe,
 	.remove = ipv6_remove,
 };
 
diff --git a/src/net/ndp.c b/src/net/ndp.c
index e62f7d5..e576e45 100644
--- a/src/net/ndp.c
+++ b/src/net/ndp.c
@@ -983,11 +983,17 @@ static struct interface_descriptor ipv6conf_dhcp_desc =
  */
 int start_ipv6conf ( struct interface *job, struct net_device *netdev ) {
 	struct ipv6conf *ipv6conf;
+	int rc;
 
 	/* Allocate and initialise structure */
 	ipv6conf = zalloc ( sizeof ( *ipv6conf ) );
 	if ( ! ipv6conf )
 		return -ENOMEM;
+
+	rc = ipv6_ll_route( netdev );
+	if (rc)
+		return -ENOMEM;
+
 	ref_init ( &ipv6conf->refcnt, ipv6conf_free );
 	intf_init ( &ipv6conf->job, &ipv6conf_job_desc, &ipv6conf->refcnt );
 	intf_init ( &ipv6conf->dhcp, &ipv6conf_dhcp_desc, &ipv6conf->refcnt );
-- 
1.8.4.5




More information about the ipxe-devel mailing list