All of lore.kernel.org
 help / color / mirror / Atom feed
* [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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.