[U-Boot] [RFC PATCH v2 0/5] Initial IPv6 support

From: Chris Packham chris.packham@alliedtelesis.co.nz
This series so far covers the introduction of a IP6addr_t and printing/parsing of addresses. I have a patch for testing these basic things which I haven't included in this series yet. Is there a unittest facility for u-boot I should be using?
A few open questions
1) Presumably the majority of the actual V6 code would be included by a config option (CONFIG_IPV6). How far should I take that? Should the vsprintf code be conditional?
2) Our current out of tree code parallels net.c and net.h. Should I continue this for the final version or integrate it into net.[ch].
3) rxhand_f currently takes an IPaddr_t. I haven't looked at the usage of this yet but to support V6 this may need to be a new union or a void *.
Changes in v2: -use __be16/__be32 -add ipv6_addr_v4mapped and ipv6_addr_is_isatap inline functions -Add support for printing mapped and ISATAP addresses
Chris Packham (5): Initial net6.h lib/vsprintf.c: add IPv6 compressed format %pI6c lib/net_utils.c: make string_to_ip stricter lib/net_utils.c: add string_to_ip6 common.h: add getenv_IP6addr
include/common.h | 6 +++ include/net6.h | 59 +++++++++++++++++++++++ lib/net_utils.c | 117 ++++++++++++++++++++++++++++++++++++++++++++- lib/vsprintf.c | 143 +++++++++++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 304 insertions(+), 21 deletions(-) create mode 100644 include/net6.h

From: Chris Packham chris.packham@alliedtelesis.co.nz
Has the definition of an IPv6 address and IPv6 header. It may make sense to separate the v4 support from net.h (or to include this in net.h).
Signed-off-by: Chris Packham chris.packham@alliedtelesis.co.nz
--- Changes in v2: -use __be16/__be32 -add ipv6_addr_v4mapped and ipv6_addr_is_isatap inline functions
include/net6.h | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 include/net6.h
diff --git a/include/net6.h b/include/net6.h new file mode 100644 index 0000000..03bccb2 --- /dev/null +++ b/include/net6.h @@ -0,0 +1,43 @@ +/** + * Simple IPv6 network layer implementation. + * + * Based and/or adapted from the IPv4 network layer in net.[hc] + * + * (C) Copyright 2013 Allied Telesis Labs NZ + * + * This file is released under the terms of GPL v2 and any later version. + * See the file COPYING in the root directory of the source tree for details. + */ +#ifndef __NET6_H__ +#define __NET6_H__ + +typedef union ip6addr_t { + __u8 u6_addr8[16]; + __be16 u6_addr16[8]; + __be32 u6_addr32[4]; +} IP6addr_t; + +/** + * struct ipv6hdr - Internet Protocol V6 (IPv6) header. + * + * IPv6 packet header as defined in RFC 2460. + */ +struct ip6_hdr { +#if defined(__LITTLE_ENDIAN_BITFIELD) + __u8 priority:4, + version:4; +#elif defined(__BIG_ENDIAN_BITFIELD) + __u8 version:4, + priority:4; +#else +#error "Please fix <asm/byteorder.h>" +#endif + __u8 flow_lbl[3]; + __be16 payload_len; + __u8 nexthdr; + __u8 hop_limit; + IP6addr_t saddr; + IP6addr_t daddr; +}; + +#endif /* __NET6_H__ */

On Fri, 18 Jan 2013 14:35:28 +1300 Chris Packham judge.packham@gmail.com wrote:
From: Chris Packham chris.packham@alliedtelesis.co.nz
Has the definition of an IPv6 address and IPv6 header. It may make sense to separate the v4 support from net.h (or to include this in net.h).
Signed-off-by: Chris Packham chris.packham@alliedtelesis.co.nz
Reviewed-by: Kim Phillips kim.phillips@freescale.com
NOTICE: This message contains privileged and confidential information intended only for the use of the addressee named above. If you are not the intended recipient of this message you are hereby notified that you must not disseminate, copy or take any action in reliance on it. If you have received this message in error please notify Allied Telesis Labs Ltd immediately. Any views expressed in this message are those of the individual sender, except where the sender has the authority to issue and specifically states them to be the views of Allied Telesis Labs.
get rid of this message; this is a public forum.
Kim

From: Chris Packham chris.packham@alliedtelesis.co.nz
Add support for "human friendly" IPv6 address representations as specified in http://tools.ietf.org/html/draft-ietf-6man-text-addr-representation-00
This code has been adapted from Linux kernel with minimal modification.
Signed-off-by: Chris Packham chris.packham@alliedtelesis.co.nz
--- Changes in v2: -Add support for printing mapped and ISATAP addresses
include/net6.h | 13 ++++++ lib/vsprintf.c | 143 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 136 insertions(+), 20 deletions(-)
diff --git a/include/net6.h b/include/net6.h index 03bccb2..bdb4326 100644 --- a/include/net6.h +++ b/include/net6.h @@ -40,4 +40,17 @@ struct ip6_hdr { IP6addr_t daddr; };
+/* ::ffff:0:0/96 is reserved for v4 mapped addresses */ +static inline int ipv6_addr_v4mapped(const IP6addr_t *a) +{ + return (a->u6_addr32[0] | a->u6_addr32[1] | + (a->u6_addr32[2] ^ htonl(0x0000ffff))) == 0; +} + +/* Intra-Site Automatic Tunnel Addressing Protocol Address */ +static inline int ipv6_addr_is_isatap(const IP6addr_t *a) +{ + return (a->u6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE); +} + #endif /* __NET6_H__ */ diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 3c432f8..21d9f2a 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -23,6 +23,7 @@ #endif
#include <div64.h> +#include <net6.h> #define noinline __attribute__((noinline))
/* some reluctance to put this into a new limits.h, so it is here */ @@ -276,6 +277,7 @@ static noinline char *put_dec(char *buf, u64 num) #define LEFT 16 /* left justified */ #define SMALL 32 /* Must be 32 == 0x20 */ #define SPECIAL 64 /* 0x */ +#define COMPRESSED 128 /* use compressed format */
#ifdef CONFIG_SYS_VSNPRINTF /* @@ -430,12 +432,107 @@ static char *mac_address_string(char *buf, char *end, u8 *addr, int field_width, flags & ~SPECIAL); }
-static char *ip6_addr_string(char *buf, char *end, u8 *addr, int field_width, - int precision, int flags) +static char *ip4_string(char *p, u8 *addr) +{ + char temp[3]; /* hold each IP quad in reverse order */ + int i, digits; + + for (i = 0; i < 4; i++) { + digits = put_dec_trunc(temp, addr[i]) - temp; + /* reverse the digits in the quad */ + while (digits--) + *p++ = temp[digits]; + if (i != 3) + *p++ = '.'; + } + *p = '\0'; + + return p; +} + +static char *ip6_compressed_string(char *p, u8 *addr) +{ + int i, j, range; + unsigned char zerolength[8]; + int longest = 1; + int colonpos = -1; + u16 word; + u8 hi, lo; + int needcolon = 0; + int useIPv4; + IP6addr_t in6; + + memcpy(&in6, addr, sizeof(IP6addr_t)); + + useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6); + + memset(zerolength, 0, sizeof(zerolength)); + + if (useIPv4) + range = 6; + else + range = 8; + + /* find position of longest 0 run */ + for (i = 0; i < range; i++) { + for (j = i; j < range; j++) { + if (in6.u6_addr16[j] != 0) + break; + zerolength[i]++; + } + } + for (i = 0; i < range; i++) { + if (zerolength[i] > longest) { + longest = zerolength[i]; + colonpos = i; + } + } + if (longest == 1) /* don't compress a single 0 */ + colonpos = -1; + + /* emit address */ + for (i = 0; i < range; i++) { + if (i == colonpos) { + if (needcolon || i == 0) + *p++ = ':'; + *p++ = ':'; + needcolon = 0; + i += longest - 1; + continue; + } + if (needcolon) { + *p++ = ':'; + needcolon = 0; + } + /* hex u16 without leading 0s */ + word = ntohs(in6.u6_addr16[i]); + hi = word >> 8; + lo = word & 0xff; + if (hi) { + if (hi > 0x0f) + p = pack_hex_byte(p, hi); + else + *p++ = hex_asc_lo(hi); + p = pack_hex_byte(p, lo); + } else if (lo > 0x0f) + p = pack_hex_byte(p, lo); + else + *p++ = hex_asc_lo(lo); + needcolon = 1; + } + + if (useIPv4) { + if (needcolon) + *p++ = ':'; + p = ip4_string(p, &in6.u6_addr8[12]); + } + *p = '\0'; + + return p; +} + +static char *ip6_string(char *p, u8 *addr, int flags) { - /* (8 * 4 hex digits), 7 colons and trailing zero */ - char ip6_addr[8 * 5]; - char *p = ip6_addr; int i;
for (i = 0; i < 8; i++) { @@ -446,6 +543,19 @@ static char *ip6_addr_string(char *buf, char *end, u8 *addr, int field_width, } *p = '\0';
+ return p; +} + +static char *ip6_addr_string(char *buf, char *end, u8 *addr, int field_width, + int precision, int flags) +{ + char ip6_addr[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")]; + + if (flags & COMPRESSED) + ip6_compressed_string(ip6_addr, addr); + else + ip6_string(ip6_addr, addr, flags); + return string(buf, end, ip6_addr, field_width, precision, flags & ~SPECIAL); } @@ -453,21 +563,9 @@ static char *ip6_addr_string(char *buf, char *end, u8 *addr, int field_width, static char *ip4_addr_string(char *buf, char *end, u8 *addr, int field_width, int precision, int flags) { - /* (4 * 3 decimal digits), 3 dots and trailing zero */ - char ip4_addr[4 * 4]; - char temp[3]; /* hold each IP quad in reverse order */ - char *p = ip4_addr; - int i, digits; + char ip4_addr[sizeof("255.255.255.255")];
- for (i = 0; i < 4; i++) { - digits = put_dec_trunc(temp, addr[i]) - temp; - /* reverse the digits in the quad */ - while (digits--) - *p++ = temp[digits]; - if (i != 3) - *p++ = '.'; - } - *p = '\0'; + ip4_string(ip4_addr, addr);
return string(buf, end, ip4_addr, field_width, precision, flags & ~SPECIAL); @@ -487,6 +585,8 @@ static char *ip4_addr_string(char *buf, char *end, u8 *addr, int field_width, * decimal for v4 and colon separated network-order 16 bit hex for v6) * - 'i' [46] for 'raw' IPv4/IPv6 addresses, IPv6 omits the colons, IPv4 is * currently the same + * - 'I6c' for IPv6 addresses printed as specified by + * http://tools.ietf.org/html/rfc5952 * * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 * function pointers are really function descriptors, which contain a @@ -517,9 +617,12 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, flags |= SPECIAL; /* Fallthrough */ case 'I': - if (fmt[1] == '6') + if (fmt[1] == '6') { + if (fmt[2] == 'c') + flags |= COMPRESSED; return ip6_addr_string(buf, end, ptr, field_width, precision, flags); + } if (fmt[1] == '4') return ip4_addr_string(buf, end, ptr, field_width, precision, flags);

From: Chris Packham chris.packham@alliedtelesis.co.nz
Previously values greater than 255 were implicitly truncated. Add some stricter checking to reject addresses with components >255.
With the input "1234192.168.1.1" the old behaviour would truncate the address to 192.168.1.1. New behaviour rejects the string outright and returns 0, which for the purposes of IP addresses can be considered an error.
Signed-off-by: Chris Packham chris.packham@alliedtelesis.co.nz --- Changes in v2: None
lib/net_utils.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/net_utils.c b/lib/net_utils.c index b425a68..2b20ccb 100644 --- a/lib/net_utils.c +++ b/lib/net_utils.c @@ -39,8 +39,9 @@ IPaddr_t string_to_ip(const char *s)
for (addr=0, i=0; i<4; ++i) { ulong val = s ? simple_strtoul(s, &e, 10) : 0; + if (val > 255) + return 0; addr <<= 8; - addr |= (val & 0xFF); if (s) { s = (*e) ? e+1 : e; }

From: Chris Packham chris.packham@alliedtelesis.co.nz
string_to_ip6 parses an IPv6 address from a string. Parsing v6 addresses is a bit more complicated than parsing v4 because there are a number of different formats that can be used.
Signed-off-by: Chris Packham chris.packham@alliedtelesis.co.nz
--- I'm sure the parsing can be better and done in less code with only a single pass but I haven't yet figured it out. The main problem is that "::" can represent a variable number of contiguous "0000:" so when parsing "::" we can't tell how many half words to skip.
Changes in v2: None
include/net6.h | 3 ++ lib/net_utils.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+)
diff --git a/include/net6.h b/include/net6.h index bdb4326..55ab187 100644 --- a/include/net6.h +++ b/include/net6.h @@ -53,4 +53,7 @@ static inline int ipv6_addr_is_isatap(const IP6addr_t *a) return (a->u6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE); }
+/* Convert a string to an ipv6 address */ +extern int string_to_ip6(const char *s, IP6addr_t *addr); + #endif /* __NET6_H__ */ diff --git a/lib/net_utils.c b/lib/net_utils.c index 2b20ccb..a8de103 100644 --- a/lib/net_utils.c +++ b/lib/net_utils.c @@ -27,6 +27,8 @@ */
#include <common.h> +#include <net6.h> +#include <linux/ctype.h>
IPaddr_t string_to_ip(const char *s) { @@ -49,3 +51,116 @@ IPaddr_t string_to_ip(const char *s)
return (htonl(addr)); } + +/** + * Parses an IP6addr_t from the given string. IPv6 address parsing is a bit + * more complicated than v4 due to the flexible format and some of the special + * cases (e.g. v4 mapped). + * + * Examples of valid strings: + * 2001:db8::0:1234:1 + * 2001:0db8:0000:0000:0000:0000:1234:0001 + * ::1 + * ::ffff:192.168.1.1 + * + * Examples of invalid strings + * 2001:db8::0::0 (:: can only appear once) + * 2001:db8:192.168.1.1::1 (v4 part can only appear at the end) + * 192.168.1.1 (we don't implicity map v4) + */ +int string_to_ip6(const char *strpt, IP6addr_t *addrpt) +{ + IP6addr_t *in6_val = addrpt; + int colon_count = 0; + int found_double_colon = 0; + int xstart = 0; /* first zero (double colon) */ + int len = 7; /* numbers of zero words the double colon represents */ + int i; + const char *s = strpt; + + if (strpt == NULL) + return 0; + + /* First pass, verify the syntax and locate the double colon */ + for (;;) { + while (isxdigit((int)*s)) + s++; + if (*s == '\0') + break; + if (*s != ':') { + if (*s == '.' && len >= 2) { + while (s != strpt && *(s-1) != ':') + --s; + if (string_to_ip(s) != 0) { + len -= 2; + break; + } + } + /* This could be a valid address */ + break; + } + if (s == strpt) { + /* The address begins with a colon */ + if (*++s != ':') + /* Must start with a double colon or a number */ + goto out_err; + } else { + s++; + if (found_double_colon) + len--; + else + xstart++; + } + + if (*s == ':') { + if (found_double_colon) + /* Two double colons are not allowed */ + goto out_err; + found_double_colon = 1; + len -= xstart; + s++; + } + + if (++colon_count == 7) + /* Found all colons */ + break; + } + + if (colon_count == 0 || colon_count > 7) + goto out_err; + if (*--s == ':') + len++; + + /* Second pass, read the address */ + s = strpt; + for (i = 0; i < 8; i++) { + int val = 0; + char *end; + + if (found_double_colon && i >= xstart && i < xstart + len) { + addrpt->u6_addr16[i] = 0; + continue; + } + while (*s == ':') + s++; + + if (i == 6 && isdigit((int)*s)) { + IPaddr_t v4 = string_to_ip(s); + if (v4 != 0) { + /* Ending with :IPv4-address */ + addrpt->u6_addr32[3] = v4; + break; + } + } + + val = simple_strtoul(s, &end, 16); + if (*end != '\0' && *end != ':') + goto out_err; + addrpt->u6_addr16[i] = htons(val); + s = end; + } + return 0; + +out_err: + return -1; +}

From: Chris Packham chris.packham@alliedtelesis.co.nz
Analogous to getenv_IPaddr but for IPv6. This allows the caller to get an IP6addr_t from an environment variable.
Signed-off-by: Chris Packham chris.packham@alliedtelesis.co.nz --- Changes in v2: None
include/common.h | 6 ++++++ lib/net_utils.c | 1 - 2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/include/common.h b/include/common.h index 2f2578b..41c5fb2 100644 --- a/include/common.h +++ b/include/common.h @@ -833,6 +833,12 @@ static inline IPaddr_t getenv_IPaddr(char *var) return string_to_ip(getenv(var)); }
+#include <net6.h> +static inline int getenv_IP6addr(char *var, IP6addr_t *a) +{ + return string_to_ip6(getenv(var), a); +} + /* * CONSOLE multiplexing. */ diff --git a/lib/net_utils.c b/lib/net_utils.c index a8de103..44c414f 100644 --- a/lib/net_utils.c +++ b/lib/net_utils.c @@ -27,7 +27,6 @@ */
#include <common.h> -#include <net6.h> #include <linux/ctype.h>
IPaddr_t string_to_ip(const char *s)

Hi Chris,
On Fri, 18 Jan 2013 14:35:27 +1300, Chris Packham judge.packham@gmail.com wrote:
From: Chris Packham chris.packham@alliedtelesis.co.nz
This series so far covers the introduction of a IP6addr_t and printing/parsing of addresses.
As a general comment, I heartily welcome IPv6 support (even though I suspect there is quite a lot to be done on it, if only configuration), but I wonder how this fits in with the general line of not adding dead code in U-Boot. Will we make an exception for IPv6 and accept this RFC once it is officially submitted? Or do we collect small, reviewable RFCs for various IPv6 aspects but apply them in one go? Or do we create a branch or tree where IPv6 will get integrated step by step until solid enough for mainline inclusion? Or was this decided already and I missed it?
Amicalement,

On 01/18/2013 09:20 PM, Albert ARIBAUD wrote:
Hi Chris,
On Fri, 18 Jan 2013 14:35:27 +1300, Chris Packham judge.packham@gmail.com wrote:
From: Chris Packham chris.packham@alliedtelesis.co.nz
This series so far covers the introduction of a IP6addr_t and printing/parsing of addresses.
As a general comment, I heartily welcome IPv6 support (even though I suspect there is quite a lot to be done on it, if only configuration), but I wonder how this fits in with the general line of not adding dead code in U-Boot. Will we make an exception for IPv6 and accept this RFC once it is officially submitted? Or do we collect small, reviewable RFCs for various IPv6 aspects but apply them in one go? Or do we create a branch or tree where IPv6 will get integrated step by step until solid enough for mainline inclusion? Or was this decided already and I missed it?
Amicalement,
Good question. Basically we have some out of tree code that implements a basic IPv6 stack. I'm drip feeding the code in pieces to avoid just dumping it on people and because the current code wouldn't meet u-boot's standards.
Putting my IPv6 promoter hat on I hope that it won't stay dead for long :)
Personally I'm happy to have a long running series and periodically send updates to the list. I have a repository on github[1] which has an ipv6 branch collecting my changes if anyone wants to pull it down for their own testing. If we want to apply some of the simple stuff early that's fine by me.
Regards, Chris -- [1] git://github.com/cpackham/u-boot.git

Dear Chris,
In message 50F91851.5050003@gmail.com you wrote:
Good question. Basically we have some out of tree code that implements a basic IPv6 stack. I'm drip feeding the code in pieces to avoid just dumping it on people and because the current code wouldn't meet u-boot's standards.
Can you please go into abit more detail which exact services this implements, and how?
Last time I checked (about 2 years ago) there was no officially agreed-on standard for example how network booting should be done in IPv6.
There used to be a document how TFTP could handle IPv6 addresses at http://datatracker.ietf.org/idtracker/draft-evans-tftp-address-options/comme... but this apears to be gone now. The proposal was rejected by then, and the comments ("I do recommend the transition to a better transport protocol.") sounded as if the IETF would like to abandon TFTp under IPv6.
I found links for DHCPv6, for example http://tools.ietf.org/html/draft-ietf-dhc-dhcpv6-opt-netboot-00 but no read standard for a bootstrap protocol. Some documents indicated it might be based on iSCSI - but that would be quite complex; see http://tools.ietf.org/html/rfc4173 http://tools.ietf.org/agenda/72/slides/dhc-12.pdf
So what exactly are you targeting for?
Putting my IPv6 promoter hat on I hope that it won't stay dead for long :)
Thanks, appreciated!
Personally I'm happy to have a long running series and periodically send updates to the list. I have a repository on github[1] which has an ipv6 branch collecting my changes if anyone wants to pull it down for their own testing. If we want to apply some of the simple stuff early that's fine by me.
I see no problem with handling this as a branch (for example in the u-boot-net or u-boot-testing repositories). This should probably be decided by Joe Hershberger, though.
Best regards,
Wolfgang Denk

On Fri, Jan 18, 2013 at 4:44 AM, Wolfgang Denk wd@denx.de wrote:
Dear Chris,
In message 50F91851.5050003@gmail.com you wrote:
Personally I'm happy to have a long running series and periodically send updates to the list. I have a repository on github[1] which has an ipv6 branch collecting my changes if anyone wants to pull it down for their own testing. If we want to apply some of the simple stuff early that's fine by me.
I see no problem with handling this as a branch (for example in the u-boot-net or u-boot-testing repositories). This should probably be decided by Joe Hershberger, though.
I'm fine with hosting these changes as a branch in the u-boot-net repo.
-Joe

On 01/19/2013 07:41 AM, Joe Hershberger wrote:
On Fri, Jan 18, 2013 at 4:44 AM, Wolfgang Denk wd@denx.de wrote:
Dear Chris,
In message 50F91851.5050003@gmail.com you wrote:
Personally I'm happy to have a long running series and periodically send updates to the list. I have a repository on github[1] which has an ipv6 branch collecting my changes if anyone wants to pull it down for their own testing. If we want to apply some of the simple stuff early that's fine by me.
I see no problem with handling this as a branch (for example in the u-boot-net or u-boot-testing repositories). This should probably be decided by Joe Hershberger, though.
I'm fine with hosting these changes as a branch in the u-boot-net repo.
-Joe
Sounds good to me. I wouldn't go creating it just yet as I'm re-rolling patches frequently. Once the initial round of development and review has settled down then having the code on a more public branch for people to test with would be good.

On 01/18/2013 11:44 PM, Wolfgang Denk wrote:
Dear Chris,
In message 50F91851.5050003@gmail.com you wrote:
Good question. Basically we have some out of tree code that implements a basic IPv6 stack. I'm drip feeding the code in pieces to avoid just dumping it on people and because the current code wouldn't meet u-boot's standards.
Can you please go into abit more detail which exact services this implements, and how?
TFTP over IPv6 as well as PING6. Our use case is just static address configuration but using link-local addresses should be doable. I was thinking it wouldn't be to hard to implement something to generate a global IPv6 address based on the eui-64 of the device.
Last time I checked (about 2 years ago) there was no officially agreed-on standard for example how network booting should be done in IPv6.
There used to be a document how TFTP could handle IPv6 addresses at http://datatracker.ietf.org/idtracker/draft-evans-tftp-address-options/comme... but this apears to be gone now. The proposal was rejected by then, and the comments ("I do recommend the transition to a better transport protocol.") sounded as if the IETF would like to abandon TFTp under IPv6.
For TFTP it's just a matter of which addresses the server binds to, and whether the CLI accepts IPv6 addresses. I think we had a patch for tftp-hpa floating around which was only a few lines. I'm not sure it's even needed these days.
I found links for DHCPv6, for example http://tools.ietf.org/html/draft-ietf-dhc-dhcpv6-opt-netboot-00 but no read standard for a bootstrap protocol. Some documents indicated it might be based on iSCSI - but that would be quite complex; see http://tools.ietf.org/html/rfc4173 http://tools.ietf.org/agenda/72/slides/dhc-12.pdf
DHCPv6 has come along way. At least in terms of address assignment and interop with other IPv6 auto-configuration mechanisms. I'm not sure about the bootstrap side of things though.
So what exactly are you targeting for?
A fairly narrow use-case initially - TFTP with a statically configured IPv6 address.
At $dayjob we have just added DHCPv6 to our Linux based switches (based on ISC dhcpd). I wasn't personally involved but it's something we might be able to help with if there was demand.
Putting my IPv6 promoter hat on I hope that it won't stay dead for long :)
Thanks, appreciated!
Personally I'm happy to have a long running series and periodically send updates to the list. I have a repository on github[1] which has an ipv6 branch collecting my changes if anyone wants to pull it down for their own testing. If we want to apply some of the simple stuff early that's fine by me.
I see no problem with handling this as a branch (for example in the u-boot-net or u-boot-testing repositories). This should probably be decided by Joe Hershberger, though.
Best regards,
Wolfgang Denk

Hi Chris,
On Sun, 20 Jan 2013 22:44:39 +1300, Chris Packham judge.packham@gmail.com wrote:
TFTP over IPv6 as well as PING6. Our use case is just static address configuration but using link-local addresses should be doable. I was thinking it wouldn't be to hard to implement something to generate a global IPv6 address based on the eui-64 of the device.
[...]
Any chance IPv6 autoconfiguration RS/RA support is in the pipe? My provider here uses RAs.
Amicalement,

On Mon, Jan 21, 2013 at 10:00 AM, Albert ARIBAUD albert.u.boot@aribaud.netwrote:
Hi Chris,
On Sun, 20 Jan 2013 22:44:39 +1300, Chris Packham judge.packham@gmail.com wrote:
TFTP over IPv6 as well as PING6. Our use case is just static address configuration but using link-local addresses should be doable. I was thinking it wouldn't be to hard to implement something to generate a global IPv6 address based on the eui-64 of the device.
[...]
Any chance IPv6 autoconfiguration RS/RA support is in the pipe? My provider here uses RAs.
Amicalement,
Albert.
Should be doable. RS/RA is a lot easier than DHCPv6 because we have to support neighbour solicitation anyway so router solicitation and the prefix delegation part shouldn't be much more work.

Hi Wolfgang,
A a few more specific answers to your questions
On Sun, Jan 20, 2013 at 10:44 PM, Chris Packham judge.packham@gmail.comwrote:
On 01/18/2013 11:44 PM, Wolfgang Denk wrote:
Dear Chris,
Last time I checked (about 2 years ago) there was no officially agreed-on standard for example how network booting should be done in IPv6.
There used to be a document how TFTP could handle IPv6 addresses at
http://datatracker.ietf.org/idtracker/draft-evans-tftp-address-options/comme...
but this apears to be gone now. The proposal was rejected by then, and the comments ("I do recommend the transition to a better transport protocol.") sounded as if the IETF would like to abandon TFTp under IPv6.
For TFTP it's just a matter of which addresses the server binds to, and whether the CLI accepts IPv6 addresses. I think we had a patch for tftp-hpa floating around which was only a few lines. I'm not sure it's even needed these days.
As long as the bind is done with AF_UNSPEC then it will listen to either v4 or v6. You can explicitly force v4 or v6 by using AF_INET or AF_INET6. A modern version of tftp-hpa supports both AF_UNSPEC and AF_INET6. The IPv6 stack shouldn't care what application is being run over it. It's just udp as far as the stack is concerned.
I found links for DHCPv6, for example http://tools.ietf.org/html/draft-ietf-dhc-dhcpv6-opt-netboot-00 but no read standard for a bootstrap protocol. Some documents indicated it might be based on iSCSI - but that would be quite complex; see http://tools.ietf.org/html/rfc4173 http://tools.ietf.org/agenda/72/slides/dhc-12.pdf
DHCPv6 has come along way. At least in terms of address assignment and interop with other IPv6 auto-configuration mechanisms. I'm not sure about the bootstrap side of things though.
RFC5970[1] details network boot options for DHCPv6 (I think it's the ratified version of the draft you linked to). Basically this allows the server to specify a URL for the boot file which presumably could be something like tftp://[2001:db8::1]/uImage. Looks like the standard also covers passing kernel parameters and dealing with different architectures.
I'm not sure which, if any, dhcp6 server implementations support this RFC but it looks like the standards exist.
Thanks, Chris -- [1] - http://tools.ietf.org/html/rfc5970

Dear Chris,
In message CAFOYHZDN3sB56ZF3jx28y3opJhhU4uqyA-91vdhOU9DRwDN8Jw@mail.gmail.com you wrote:
RFC5970[1] details network boot options for DHCPv6 (I think it's the ratified version of the draft you linked to). Basically this allows the server to specify a URL for the boot file which presumably could be something like tftp://[2001:db8::1]/uImage. Looks like the standard also covers passing kernel parameters and dealing with different architectures.
I'm not sure which, if any, dhcp6 server implementations support this RFC but it looks like the standards exist.
Thanks, Chris -- [1] - http://tools.ietf.org/html/rfc5970
I see. Thanks for the update!
Best regards,
Wolfgang Denk

Dear Albert ARIBAUD,
In message 20130118092041.0c827374@lilith you wrote:
This series so far covers the introduction of a IP6addr_t and printing/parsing of addresses.
As a general comment, I heartily welcome IPv6 support (even though I
Me too! :-)
but I wonder how this fits in with the general line of not adding dead code in U-Boot. Will we make an exception for IPv6 and accept this RFC once it is officially submitted? Or do we collect small, reviewable RFCs for various IPv6 aspects but apply them in one go? Or do we create a branch or tree where IPv6 will get integrated step by step until solid enough for mainline inclusion? Or was this decided already and I missed it?
My understanding was that this patch set was for reviewing purposes only (hence RFC). Your dead code hint is absolutely correct: for integration into mainline we need users of the code, i. e. for example DHCP and TFTP support...
Best regards,
Wolfgang Denk

Dear Chris,
In message 1358472932-32083-1-git-send-email-judge.packham@gmail.com you wrote:
This series so far covers the introduction of a IP6addr_t and printing/parsing of addresses. I have a patch for testing these basic things which I haven't included in this series yet. Is there a unittest facility for u-boot I should be using?
We use the DUTS ([1], [2]) for all kind of test cases (but note that I don't claim it's easy to get started with it).
[1] http://www.denx.de/wiki/DUTS/DUTSDocs [2] http://git.denx.de/?p=duts.git
A few open questions
- Presumably the majority of the actual V6 code would be included by a
config option (CONFIG_IPV6). How far should I take that? Should the vsprintf code be conditional?
Yes, please.
- Our current out of tree code parallels net.c and net.h. Should I
continue this for the final version or integrate it into net.[ch].
This depends - if such integration can be done nicely, i. e. without too many new #ifdef's, then yes, please.
- rxhand_f currently takes an IPaddr_t. I haven't looked at the usage
of this yet but to support V6 this may need to be a new union or a void *.
What exactly is the question here?
Best regards,
Wolfgang Denk

On 01/18/2013 11:23 PM, Wolfgang Denk wrote:
Dear Chris,
In message 1358472932-32083-1-git-send-email-judge.packham@gmail.com you wrote:
This series so far covers the introduction of a IP6addr_t and printing/parsing of addresses. I have a patch for testing these basic things which I haven't included in this series yet. Is there a unittest facility for u-boot I should be using?
We use the DUTS ([1], [2]) for all kind of test cases (but note that I don't claim it's easy to get started with it).
[1] http://www.denx.de/wiki/DUTS/DUTSDocs [2] http://git.denx.de/?p=duts.git
A few open questions
- Presumably the majority of the actual V6 code would be included by a
config option (CONFIG_IPV6). How far should I take that? Should the vsprintf code be conditional?
Yes, please.
- Our current out of tree code parallels net.c and net.h. Should I
continue this for the final version or integrate it into net.[ch].
This depends - if such integration can be done nicely, i. e. without too many new #ifdef's, then yes, please.
- rxhand_f currently takes an IPaddr_t. I haven't looked at the usage
of this yet but to support V6 this may need to be a new union or a void *.
What exactly is the question here?
The POSIX solution for this is to use sockaddr which encompasses both v4 and v6 addresses (as well as other socket types). Do we want to add a wrapper type or just work with void *?
I also need to look at things that implement a rxhand_f just to see what they do with the IPaddr_t.
Best regards,
Wolfgang Denk

Dear Chris,
In message 50FBB7EA.10601@gmail.com you wrote:
The POSIX solution for this is to use sockaddr which encompasses both v4 and v6 addresses (as well as other socket types). Do we want to add a wrapper type or just work with void *?
Without checking for implications for the implementation I would say that we should avoid void * and rather allow for better type checking.
Best regards,
Wolfgang Denk
participants (6)
-
Albert ARIBAUD
-
Chris Packham
-
Joe Hershberger
-
Kim Phillips
-
Sergey Lapin
-
Wolfgang Denk