[ipxe-devel] [PATCH 4/7] ipv6: Allow manual network configuration
Hannes Reinecke
hare at suse.de
Wed Apr 1 07:26:18 UTC 2015
Not on every system IPv6 autoconfiguration is working properly,
so allow for manual network configuration here.
Note: this configures the global route only. Link-local routes
are configured automatically.
Signed-off-by: Hannes Reinecke <hare at suse.de>
---
src/include/ipxe/dhcpv6.h | 4 +++
src/include/ipxe/ipv6.h | 42 ++++++++++++++++++++++++++
src/include/ipxe/settings.h | 9 ++++++
src/net/ipv6.c | 72 +++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 127 insertions(+)
diff --git a/src/include/ipxe/dhcpv6.h b/src/include/ipxe/dhcpv6.h
index a6527c2..a869a4d 100644
--- a/src/include/ipxe/dhcpv6.h
+++ b/src/include/ipxe/dhcpv6.h
@@ -170,6 +170,10 @@ struct dhcpv6_user_class_option {
/** DHCPv6 bootfile parameters option */
#define DHCPV6_BOOTFILE_PARAM 60
+/** Setting tags */
+#define DHCPV6_EB_GATEWAY 25
+#define DHCPV6_EB_NETMASK 26
+
/** DHCPv6 syslog server option
*
* This option code has not yet been assigned by IANA. Please update
diff --git a/src/include/ipxe/ipv6.h b/src/include/ipxe/ipv6.h
index a2b4c88..c3d36e2 100644
--- a/src/include/ipxe/ipv6.h
+++ b/src/include/ipxe/ipv6.h
@@ -238,6 +238,48 @@ static inline void ipv6_all_routers ( struct in6_addr *addr ) {
addr->s6_addr[15] = 2;
}
+/**
+ * Calculate prefix length from IPv6 netmask
+ *
+ * @v netmask IPv6 address
+ * @ret prefix_len Prefix length
+ */
+static inline int ipv6_prefix_len( struct in6_addr *netmask ) {
+ uint8_t *prefix_mask;
+ int prefix_len = 0;
+
+ /* Translate netmask into prefix length */
+ for ( prefix_mask = netmask->s6_addr;
+ *prefix_mask == 0xff;
+ prefix_mask++ ) {
+ prefix_len += 8;
+ }
+ switch (*prefix_mask) {
+ case 0xfe:
+ prefix_len += 7;
+ break;
+ case 0xfc:
+ prefix_len += 6;
+ break;
+ case 0xf8:
+ prefix_len += 5;
+ break;
+ case 0xf0:
+ prefix_len += 4;
+ break;
+ case 0xe0:
+ prefix_len += 3;
+ break;
+ case 0xc0:
+ prefix_len += 2;
+ break;
+ case 0x80:
+ prefix_len += 1;
+ break;
+ }
+ return prefix_len;
+}
+
extern struct list_head ipv6_miniroutes;
extern struct net_protocol ipv6_protocol __net_protocol;
diff --git a/src/include/ipxe/settings.h b/src/include/ipxe/settings.h
index 45d600b..2b10781 100644
--- a/src/include/ipxe/settings.h
+++ b/src/include/ipxe/settings.h
@@ -74,6 +74,7 @@ struct setting {
#define SETTING_AUTH_EXTRA 12 /**< Authentication additional settings */
#define SETTING_CRYPTO 13 /**< Cryptography settings */
#define SETTING_MISC 14 /**< Miscellaneous settings */
+#define SETTING_IPV6 15 /**< IPv6 settings */
/** @} */
@@ -426,8 +427,16 @@ netmask_setting __setting ( SETTING_IP, netmask );
extern const struct setting
gateway_setting __setting ( SETTING_IP, gateway );
extern const struct setting
+ip6_setting __setting ( SETTING_IPV6, ip6 );
+extern const struct setting
+netmask6_setting __setting ( SETTING_IPV6, netmask6 );
+extern const struct setting
+gateway6_setting __setting ( SETTING_IPV6, gateway6 );
+extern const struct setting
dns_setting __setting ( SETTING_IP_EXTRA, dns );
extern const struct setting
+dns6_setting __setting ( SETTING_IP_EXTRA, dns6 );
+extern const struct setting
hostname_setting __setting ( SETTING_HOST, hostname );
extern const struct setting
domain_setting __setting ( SETTING_IP_EXTRA, domain );
diff --git a/src/net/ipv6.c b/src/net/ipv6.c
index 460f7b7..dd0a888 100644
--- a/src/net/ipv6.c
+++ b/src/net/ipv6.c
@@ -34,6 +34,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/ipstat.h>
#include <ipxe/ndp.h>
#include <ipxe/ipv6.h>
+#include <ipxe/dhcpv6.h>
/** @file
*
@@ -1083,6 +1084,32 @@ int format_ipv6_setting ( const struct setting_type *type __unused,
return snprintf ( buf, len, "%s", inet6_ntoa ( ipv6 ) );
}
+/** IPv6 address setting */
+const struct setting ip6_setting __setting ( SETTING_IPV6, ip6 ) = {
+ .name = "ip6",
+ .description = "IPv6 address",
+ .tag = DHCPV6_IAADDR,
+ .type = &setting_type_ipv6,
+ .scope = &ipv6_scope,
+};
+
+/** IPv6 gateway setting */
+const struct setting gateway6_setting __setting ( SETTING_IPV6, gateway6 ) = {
+ .name = "gateway6",
+ .description = "IPv6 gateway",
+ .tag = DHCPV6_EB_GATEWAY,
+ .type = &setting_type_ipv6,
+ .scope = &ipv6_scope,
+};
+
+/** IPv6 netmask setting */
+const struct setting netmask6_setting __setting ( SETTING_IPV6, netmask6 ) = {
+ .name = "netmask6",
+ .description = "IPv6 netmask",
+ .tag = DHCPV6_EB_NETMASK,
+ .type = &setting_type_ipv6,
+ .scope = &ipv6_scope,
+};
/**
* Destroy IPv6 network device
*
@@ -1108,6 +1135,51 @@ struct net_driver ipv6_driver __net_driver = {
.remove = ipv6_remove,
};
+/**
+ * Update IPv6 routing table based on configured settings
+ *
+ * @ret rc Return status code
+ */
+static int ipv6_update_routes ( void ) {
+ struct net_device *netdev;
+ struct settings *settings;
+ struct in6_addr address, empty;
+ struct in6_addr router, netmask;
+ int prefix_len = 64;
+
+ memset(&empty, 0, sizeof(address));
+ /* Update configured routes for each configured network device */
+ for_each_netdev ( netdev ) {
+ settings = netdev_settings ( netdev );
+ /* Get IPv6 address */
+ memset(&address, 0, sizeof(address));
+ fetch_ipv6_setting ( settings, &ip6_setting, &address );
+ if (!memcmp(&address, &empty, sizeof (address)))
+ continue;
+ /* Update address */
+ ipv6_set_address( netdev, &address );
+ /* Get IPv6 netmask */
+ memset(&netmask, 0, sizeof(netmask));
+ fetch_ipv6_setting( settings, &netmask6_setting, &netmask );
+ if (memcmp(&netmask, &empty, sizeof(netmask)))
+ prefix_len = ipv6_prefix_len( &netmask );
+ /* Get IPv6 router */
+ memset(&router, 0, sizeof(router));
+ fetch_ipv6_setting( settings, &gateway6_setting, &router );
+ if (!memcmp(&router, &empty, sizeof (router)))
+ continue;
+ /* Update routing table */
+ ipv6_set_prefix( netdev, &address, prefix_len, &router );
+ }
+
+ return 0;
+}
+
+/** IPv6 settings applicator */
+struct settings_applicator ipv6_settings_applicator __settings_applicator = {
+ .apply = ipv6_update_routes,
+};
+
/* Drag in objects via ipv6_protocol */
REQUIRING_SYMBOL ( ipv6_protocol );
--
1.8.4.5
More information about the ipxe-devel
mailing list