* [U-Boot] [RFC PATCH 0/2] Initial IPv6 support
@ 2013-01-16 10:01 Chris Packham
2013-01-16 10:01 ` [U-Boot] [RFC PATCH 1/2] Initial net6.h Chris Packham
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Chris Packham @ 2013-01-16 10:01 UTC (permalink / raw)
To: u-boot
Here's something simple to get started. IP6addr_t is added as a typedef
(for consistency with IPaddr_t). I ended up borrowing and adapting the
vsprintf code from Linux.
Here is an example of the printf formatting
With this code
IP6addr_t addr6 = {.u6_addr16[0] = 0x3ffe,
.u6_addr16[1] = 0x1234,
.u6_addr16[7] = 0x0001};
IPaddr_t addr4 = 0x7f000001;
printf("addr6=%pi6\n", &addr6);
printf("addr6=%pI6\n", &addr6);
printf("addr6=%pI6c\n", &addr6);
printf("addr=%pI4\n", &addr4);
We get the output
addr6=3ffe1234000000000000000000000001
addr6=3ffe:1234:0000:0000:0000:0000:0000:0001
addr6=3ffe:1234::1
addr4=127.0.0.1
My work so far on this has raised a few 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
*.
(note on my split personality, I use a gmail account to post to the
u-boot mailing list but since this work is being done as part of my
$dayjob the author and s-o-b are using my work email address)
#####################################################################################
Scanned by MailMarshal - M86 Security's comprehensive email content security solution.
#####################################################################################
^ permalink raw reply [flat|nested] 5+ messages in thread
* [U-Boot] [RFC PATCH 1/2] Initial net6.h
2013-01-16 10:01 [U-Boot] [RFC PATCH 0/2] Initial IPv6 support Chris Packham
@ 2013-01-16 10:01 ` Chris Packham
2013-01-16 22:37 ` Kim Phillips
2013-01-16 10:01 ` [U-Boot] [RFC PATCH 2/2] lib/vsprintf.c: add IPv6 compressed format %pI6c Chris Packham
2013-01-16 10:18 ` [U-Boot] [RFC PATCH 0/2] Initial IPv6 support Chris Packham
2 siblings, 1 reply; 5+ messages in thread
From: Chris Packham @ 2013-01-16 10:01 UTC (permalink / raw)
To: u-boot
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).
Cc: Joe Hershberger <joe.hershberger@gmail.com>
Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
---
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..2ef7405
--- /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.
+ */
+
+typedef union ip6addr_t {
+ __u8 u6_addr8[16];
+ __u16 u6_addr16[8];
+ __u32 u6_addr32[4];
+} IP6addr_t;
+
+/**
+ * struct ipv6hdr - Internet Protocol V6 (IPv6) header.
+ *
+ * IPv6 packet header as defined in RFC xxxx.
+ *
+ * BEWARE, it is incorrect. The first 4 bits of flow_lbl
+ * are glued to priority now, forming "class".
+ */
+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];
+ __u16 payload_len;
+ __u8 nexthdr;
+ __u8 hop_limit;
+ IP6addr_t saddr;
+ IP6addr_t daddr;
+};
+
--
1.7.12.rc2.16.g034161a
#####################################################################################
Scanned by MailMarshal - M86 Security's comprehensive email content security solution.
#####################################################################################
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [U-Boot] [RFC PATCH 2/2] lib/vsprintf.c: add IPv6 compressed format %pI6c
2013-01-16 10:01 [U-Boot] [RFC PATCH 0/2] Initial IPv6 support Chris Packham
2013-01-16 10:01 ` [U-Boot] [RFC PATCH 1/2] Initial net6.h Chris Packham
@ 2013-01-16 10:01 ` Chris Packham
2013-01-16 10:18 ` [U-Boot] [RFC PATCH 0/2] Initial IPv6 support Chris Packham
2 siblings, 0 replies; 5+ messages in thread
From: Chris Packham @ 2013-01-16 10:01 UTC (permalink / raw)
To: u-boot
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.
Cc: Joe Hershberger <joe.hershberger@gmail.com>
Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
---
lib/vsprintf.c | 148 +++++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 128 insertions(+), 20 deletions(-)
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 3c432f8..ae992dc 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,112 @@ 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));
+
+/* TODO: v4 mapped detection. Might be overkill for a bootloader */
+#if 0
+ useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6);
+#else
+ useIPv4 = 0;
+#endif
+
+ 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 +548,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 +568,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 +590,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 +622,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);
--
1.7.12.rc2.16.g034161a
#####################################################################################
Scanned by MailMarshal - M86 Security's comprehensive email content security solution.
#####################################################################################
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [U-Boot] [RFC PATCH 0/2] Initial IPv6 support
2013-01-16 10:01 [U-Boot] [RFC PATCH 0/2] Initial IPv6 support Chris Packham
2013-01-16 10:01 ` [U-Boot] [RFC PATCH 1/2] Initial net6.h Chris Packham
2013-01-16 10:01 ` [U-Boot] [RFC PATCH 2/2] lib/vsprintf.c: add IPv6 compressed format %pI6c Chris Packham
@ 2013-01-16 10:18 ` Chris Packham
2 siblings, 0 replies; 5+ messages in thread
From: Chris Packham @ 2013-01-16 10:18 UTC (permalink / raw)
To: u-boot
On 01/16/2013 11:01 PM, Chris Packham wrote:
<snip>
> #####################################################################################
> Scanned by MailMarshal - M86 Security's comprehensive email content security solution.
> #####################################################################################
Ick. Where did that come from?
^ permalink raw reply [flat|nested] 5+ messages in thread
* [U-Boot] [RFC PATCH 1/2] Initial net6.h
2013-01-16 10:01 ` [U-Boot] [RFC PATCH 1/2] Initial net6.h Chris Packham
@ 2013-01-16 22:37 ` Kim Phillips
0 siblings, 0 replies; 5+ messages in thread
From: Kim Phillips @ 2013-01-16 22:37 UTC (permalink / raw)
To: u-boot
On Wed, 16 Jan 2013 23:01:26 +1300
Chris Packham <judge.packham@gmail.com> wrote:
> +typedef union ip6addr_t {
> + __u8 u6_addr8[16];
> + __u16 u6_addr16[8];
__be16, for use with sparse.
> + __u32 u6_addr32[4];
__be32
> +} IP6addr_t;
Kim
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2013-01-16 22:37 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-01-16 10:01 [U-Boot] [RFC PATCH 0/2] Initial IPv6 support Chris Packham
2013-01-16 10:01 ` [U-Boot] [RFC PATCH 1/2] Initial net6.h Chris Packham
2013-01-16 22:37 ` Kim Phillips
2013-01-16 10:01 ` [U-Boot] [RFC PATCH 2/2] lib/vsprintf.c: add IPv6 compressed format %pI6c Chris Packham
2013-01-16 10:18 ` [U-Boot] [RFC PATCH 0/2] Initial IPv6 support Chris Packham
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox