patchlwIP - A Lightweight TCP/IP stack - Patches: patch #7409, IPv6 support for LwIP 1.4.0RC1

 
 

You are not allowed to post comments on this tracker with your current authentication level.

patch #7409: IPv6 support for LwIP 1.4.0RC1

Submitter:  Ivan Delamer <idelamer>
Submitted:  Thu 09 Dec 2010 07:37:23 PM UTC
   
 
Category:  None Priority:  5 - Normal
Status:  Done Privacy:  Public
Assigned to:  idelamer Open/Closed:  Closed
Planned Release:  None

Jump to the original submission

Wed 26 Oct 2011 10:06:14 PM UTC, comment #34: 

IPv6 is integrated into GIT HEAD, no longer need for this patch.

Ivan Delamer <idelamer>
Group Member
Thu 09 Jun 2011 10:05:04 AM UTC, comment #33: 

I'm working on IPv6 code again.

First of all, nice work Simon on ipX_ macros, it really cleaned the code up!

I'll be working on some improvements and optimizations, also adding support for sending RA messages (if IP6_FWD is enabled).

One thing we need to discuss is, how are we going to specify an interface identifier for link-local addresses. e.g. in Windows you will see FE80::1234%1 and FE80::5678%2 to refer to link-local addresses on interfaces 1 and 2. Currently we can choose the outgoing netif by matching a source address to an address for the netif. But if two netifs have identical LL addresses (which is not unheard of) then we have a problem.

I only have a very poor idea, but it is better than no idea: use unused bytes in the LL address to specify an interface index. e.g. FE80::1%2 would become FE80:2::1. This would be internal to the stack and the 2 would be cleaned up before passing to the user.

Any other ideas?

Ivan Delamer <idelamer>
Group Member
Sun 05 Jun 2011 08:18:14 PM UTC, comment #32: 

Update: the increasement in ip.c comes from ip_input, which has some code added due to the facts that:

a) current_ip_header_tot_len has been introduced, but that means the code where this is used gets smaller and
b) the input functions are now called with p->payload==next-header, not ip-header. This also means code has been moved, not added.

Overall, I cannot see (code-) size increasement (in the raw API code).

I'll hope to find the time soon to check socket and netconn code as well as .data section size.

Simon Goldschmidt <goldsimon>
Group administrator
Sun 05 Jun 2011 06:18:57 PM UTC, comment #31: 

For my application, lwIP is 26 bytes smaller with LWIP_IPV6 than1,4,0 from the downloaded ZIP file. However, that only includes the raw API without PPP, so I have no idea about sockets or netconn, yet. Also, I only compared the ".text" (code) section for now. BTW: compiled with gcc version 3.4.1 (Altera NIOS II 5.0 b73).

The only files that actually got bigger are ip.c (+ 176 bytes) and netif.c (+ 8 bytes). I'll dig into ip.c to see what's increasing it.

Simon Goldschmidt <goldsimon>
Group administrator
Wed 01 Jun 2011 05:18:51 PM UTC, comment #30: 

For my application, CVS HEAD with LWIP_IPV6 = 0 is 4896 bytes (0x1320) larger than STABLE-1_4_0.  There are no changes besides the 2 lwIP libs linked in.  The lwipopts.h are identical.

Bill Auerbach <billauerbach>
Wed 01 Jun 2011 05:17:37 PM UTC, comment #29: 


> Maybe the IPv6 #includes could be #include ../ip6/filename.h so
> an additional search path isn't needed in the build?


That would be a good idea. I think we already talked about this some time, didn't we? It would mean moving and/or renaming files, but since we just added a bunch of files, it would be a good moment to do so.

I'm surprised by the decrease of performance you found. I thought I had converted everything to macros that do nothing if IPv6 is turned off. I'll have to look at the assembly to see if this worked like I expected it to. However, I still did not find the time to run it on my hardware, only on win32, yet.

I'd love to create an iperf server for the lwIP raw API so that we could use iperf to measure performance. At the moment, I don't have anything to measure this.

Simon Goldschmidt <goldsimon>
Group administrator
Wed 01 Jun 2011 02:51:18 PM UTC, comment #28: 

Yeah, sorry, we're good. I had a bad #include search path. :-(

Maybe the IPv6 #includes could be #include ../ip6/filename.h so an additional search path isn't needed in the build?

Things run well with LWIP_IPV6 = 0.  I see somewhere in the ballpark of a 5% reduction in TCP receive speed. I don't know if this makes sense since I thought LWIP_IPV6 removes all of the code.  Is there more function calls with LWIP_IPV6 = 0?  Perhaps macros can be used to "do nothing" in those cases?

I will set LWIP_IPV6 to 1 and test with IPv4 addresses.  I'm unsure how to test IPv6 addresses.  As you know I'm quick to test performance so if there is anything you want tested let me know.

Bill Auerbach <billauerbach>
Wed 01 Jun 2011 05:25:01 AM UTC, comment #27: 

That's strange, my tests didn't show any errors. However, I only was able to test TCP servers (netconn and raw API), I didn't have any UDP software at hand. I'll give it a try on a product running both TCP and UDP.

Simon Goldschmidt <goldsimon>
Group administrator
Tue 31 May 2011 02:53:37 PM UTC, comment #26: 

Thought I'd post status of this build.  My application built the same way as I've been doing it with 1.4 (same lwipopts.h plus IPv6 additions to this file) does not run with this IPv6 build with LWIP_IPv6 = 0 or = 1.

I will start to debug where things go south with IPv6 = 0.  From first preview it appears as if the first ARP request from the PC is not being replied to.

My app uses UDP (unicast and broadcast), TCP, NO_SYS=1, and static IP (LWIP_DHCP=0).

Bill Auerbach <billauerbach>
Sat 28 May 2011 09:43:38 AM UTC, comment #25: 


> Sorry, I'm trying different builds and things come up...


No, that's great. I keep missing differne build configurations and that's how the compilation errors slip in.

All these configuration options are killing me! I think I could need an automated build script buildin all the different configuration option permutations...

Anyway, comments #21 to #24 should be fixed now, thanks for the help!

Simon Goldschmidt <goldsimon>
Group administrator
Fri 27 May 2011 06:26:16 PM UTC, comment #24: 

Sorry, I'm trying different builds and things come up...

3 or 4 occurrences of pcb->isipv6 need changes to PCB_ISIPV6(pcb).

In ip.h the #else // IPv6 should be:


#define ipX_route_get_local_ipX(isipv6, src, dest, netif, ipXaddr) do { \
  (netif) = ipX_route(isipv6, src, dest); \
  (ipXaddr) = ip_netif_get_local_ipX(netif); \
}while(0)


Bill Auerbach <billauerbach>
Fri 27 May 2011 05:47:05 PM UTC, comment #23: 

And in udp_sendto_chksum:


Not this:

#if LWIP_IPV6
    if (pcb->isipv6) {
      dst_ip_route = &pcb->local_ip;
    } else
#endif /* LWIP_IPV6 */
#if LWIP_IGMP
    {
      dst_ip_route = ip_2_ipX(&pcb->multicast_ip);
    }
#endif /* LWIP_IGMP */

but this (else moved):

#if LWIP_IPV6
    if (pcb->isipv6) {
      dst_ip_route = &pcb->local_ip;
    }
#endif /* LWIP_IPV6 */
#if LWIP_IGMP
    else {
      dst_ip_route = ip_2_ipX(&pcb->multicast_ip);
    }
#endif /* LWIP_IGMP */


Bill Auerbach <billauerbach>
Fri 27 May 2011 05:23:03 PM UTC, comment #22: 

There are syntax errors on:

#define ip_2_ipX(ip_addr_t ipaddr)    ((ipX_addr_t)ipaddr)
#define ip6_2_ipX(ip6_addr_t ip6addr) ((ipX_addr_t)ip6addr)

Bill Auerbach <billauerbach>
Thu 26 May 2011 04:36:15 PM UTC, comment #21: 

It should be ip6_route(pcb->local_ip, pcb->remote_ip)

I think the first case was an old workaround that I forgot to change back.

By the way, I will be finishing a project sometime next week and then I will return to contributing to IPv6 support. Looking forward to playing with the improved code. Thanks Simon!

Ivan Delamer <idelamer>
Group Member
Thu 26 May 2011 03:41:46 PM UTC, comment #20: 

Ivan, I noted that the ipv6 routing code is used differently in 2 places:

- tcp_connect (if pcb->local_ip is-any) calls ip6_route(pcb->remote_ip, pcb->remote_ip) while

- tcp_output_segment does the same but calls ip6_route(pcb->local_ip, pcb->remote_ip)

Which of the 2 is correct?

Simon Goldschmidt <goldsimon>
Group administrator
Wed 25 May 2011 05:50:01 PM UTC, comment #19: 

Oh, I forgot to add this list of what I've also changed:

- added support for tcp listen pcbs that accept both IP versions
- combined IPv4 and IPv6 versions of checksum
- added ip.h/ip_addr.h for compatibility defines
- IPv6 checksum code is also ifdef'd out with CHECKSUM_GEN_TCP etc.: this is used for hardware checksum offloading!

Simon Goldschmidt <goldsimon>
Group administrator
Wed 25 May 2011 05:27:54 PM UTC, comment #18: 

Done.
Unfortunately, I couldn't test netconn and sockets yet. I'll start with netconn today, but sockets might take a while...

Now what's missing (and on my todo list) is to combine the ip_frag/reass code and that would be it.

Simon Goldschmidt <goldsimon>
Group administrator
Wed 25 May 2011 04:42:16 AM UTC, comment #17: 

Even the pcbs should not be changed with IPv6 disabled. The output should be exactly the same as before (not like 1.4.0RC1, since there were other changes since then). That's what I'm working on, currently, but it doesn't compile cleanly, yet.

Simon Goldschmidt <goldsimon>
Group administrator
Tue 24 May 2011 10:42:05 PM UTC, comment #16: 

The only change is to the pcb structs. If you don't use PCBs from your application (e.g. you use netconn api) then everything else is the same.

Ivan Delamer <idelamer>
Group Member
Tue 24 May 2011 08:25:06 PM UTC, comment #15: 

With IPv6 disabled, do we have the same output as 1.4.0RC1 (pre IPv6)?

Bill Auerbach <billauerbach>
Tue 24 May 2011 08:12:08 PM UTC, comment #14: 

Just a small status update: I'm still at cleaning up the code. I'm nearly done, currently at fixing compilation with IPv6 disabled, then I'll check it in (few days left only :-)

Simon Goldschmidt <goldsimon>
Group administrator
Wed 18 May 2011 05:55:47 PM UTC, comment #13: 

There are a few things that I'm ready to add, such as support of IPv6 router mode (send RA ICMPv6 messages), and several optimizations. However, I think the priority is having the code up to LwIP standards in terms of eliminating #ifs and combining code.

Simon, I think the best scenario is if you take the lead in setting the style, then I can follow your example.

Once we are happy with how the code looks, I can add the new features.

TCP, UDP and RAW are fairly well tested using the Netconn, but the socket API has gone through very little testing. I don't use sockets so if you have a test application to run it through, it would be great.

You can also perhaps looks at s_addr, sin_addr, and sin6_addr one how to have a single addr struct for v4 and v6. Would it make sense to "standardize" socket addresses accross the stack?

Ivan Delamer <idelamer>
Group Member
Tue 17 May 2011 07:50:56 PM UTC, comment #12: 

Just found the time to test and check in the patch after applying it to 1.4.0 final (only small modifications were needed).

There's a lot to improve (combine code and improve code readability: we added a lot of #ifdefs for conditional IPv6 - which for me is a good reason to combine the code, too).

My local tests were running fine, although unfortunately, I don't have IPv6 internet, only local network. Plus I only tested the TCP pcb API, so I cannot comment on RAW, UDP and netconn/socket APIs.

I'll continue working on this (combining code and maybe more), so I would be happy if we could discuss changes/improvements here. While combining code, I'll see if combining IP-address structs is a way to go (currently, there are portability problems for some of applications: I have to change APPs which use pcb->ipaddr)...

Anyway, in comparison to the patch, these changes are only small efforts, so I have to say a big thanks to Ivan again: without you, we would have to wait another while for IPv6 support!

Simon Goldschmidt <goldsimon>
Group administrator
Sun 15 May 2011 07:21:46 PM UTC, comment #11: 

ip6_frag is inspired by ip_frag, so some of the code is similar. The queueing and recombining of packets is quite similar. However, there are differences in processing since in v6 the fragment information is contained in an option. Some IPv6 options are present in every fragment (called the unfragmentable part) and other options+payload are fragmented. So the header processing and fragment merging is a bit different.

Perhaps there could be some generic functions for the fragment queueing and merging code, but I'm not sure how much would be saved.

Ivan Delamer <idelamer>
Group Member
Sun 15 May 2011 06:36:34 PM UTC, comment #10: 

You wouldn't need the full space for an IPv6 address everywhere, only in places where the protocol type is unknown. In other places, 8 bytes mi be enough.

Application compatibility is also my concern. However, not only backwards compatibility, but also to make it easy for existing applications to just use IPv6. This is why I think that at least the receive callback functions as well as the connect functions etc. should be the same for both versions.

A to the netif->output function, you're probably right.

I already haver the patch applied. I'm also working on macros to reduce the ifdefs.

I'll first check in your version without combining the addresses. After that, I'll combine them locally and I'll have a look how best to achieve application compatibility.

BTW, can ip_frag be combined for the two versions? It looks quite equal to the IPv4 implementation...

Simon Goldschmidt <goldsimon>
Group administrator
Sun 15 May 2011 04:25:41 PM UTC, comment #9: 

Simon,

You bring up soem very good points. These came up when I was coding. Luckily, this can be implemented in several ways. I'll explain the reasons why it was done like this, but I think either way is almost as good.

1) One struct with v4/v6 flag, versus v4 struct and v6 struct. PArt of the reason I went with two structs is memory, like you point out. In 32-bit-aligned architectures, a v4 address becomes 20 bytes. I'm also worried about the impact that changing this would have on current applications. I went with lesser impact to applications and larger impact to the stack. It can also be reversed.

I also think that with the current approach, there is plenty of room to optimize duplicate code. Right now I'm counting on the compiler optimize to work it out.

As for netif->output, I don't think there is a way around having 2 functions for v4 and v6. For v6 there is some extra information needed. Also, v4 will usually go through ARP and v6 will go through ND. So we either have one netif->output that then switches to ARP/ND, or we already do that ourselves and save a step (and stack).

2) I agree that IPv6 adds a lot of #ifs. I'm not particularly creative with macros, but I think that would be the way to go to make the code more compact and legible.

If you think it would help, I can update the patch so that we can apply it to 1.4.0, it might take a couple of days since I have to book the time for this.

Cheers
Ivan

Ivan Delamer <idelamer>
Group Member
Sat 14 May 2011 10:52:18 PM UTC, comment #8: 

Ivan, first of all, thanks for this excellent work!

However, after applying the patch to CVS head (of course it does not apply cleanly since head has changed since december), I think there are some changes I want to discuss before committing this:

1) There is duplicate code in many places because of the different IP protocol versions. In my opinion, adding IPv6 support should not have an influence on the transport protocols, for example.

To 'fix' this, I would suggest to change 'ip_addr_t' to a struct that has a 'version type' at the beginning, so that everyone getting an ip_addr_t var can check which version it is. OK, this does add code (and RAM) size, but it's so much easier to code (both for the stack and for applications). Also, an application does not have to be changed - only recompiled - unless it relies on ip_addr_t being an u32_t...

This would also fix duplicate netif->output functions, duplicate recv/connect/etc. functions in the transport protocols.

Of course, the downside is that a simple IPv4 address would be 8 bytes (including alignment) instead of 4 bytes, but for pure IPv4 configurations, this could be avoided using macros.

In my opinion, this would not have a negative impact on function calls, as the address is passed down as a pointer and the only change would be that the protocol decision (the 'if ipv6') would be moved down in the call stack (instead of calling tcp_rst() or tcp_rst_ip6() based on 'if ipv6', we would call tcp_rst(), which then would call ip_output() or ip6_output() based on the 'if'ipv6' check).

2) For things where combining the address doesn't work or help, I'd introduce a 'compatibility' header that defines frequently used functions common to v4 and v6 as macros so that the rest of the code is more readable. We already have too many #if clauses cluttering the code, I don't want that to grow more if we can avoid it...


This would also keep the diff adding v6-support smaller than the current patch.

I'll begin working on this tomorrow and will directly commit a version implementing this (if I find the time, that is).


Oh, and another thing: should we support TCP PCBs listening for ANY address (v4 & v6) (which does not yet work with the patch)?

Simon Goldschmidt <goldsimon>
Group administrator
Fri 13 May 2011 04:44:52 PM UTC, comment #7: 

I will starting using it immediately in development to get some mileage under its belt.  Hopefully I'll find that it can be turned on and off with little (or no?) changes to an application.

Bill Auerbach <billauerbach>
Fri 13 May 2011 08:34:41 AM UTC, comment #6: 

If we don't think it breaks anything else then I agree: lets get it checked in so we can work on it.

Kieran Mansley <kieranm>
Group Member
Fri 13 May 2011 07:36:23 AM UTC, comment #5: 

I didn't have time to have a detailed look at this, however, I'd like to review it and check it in, if only to have a working IPv6 version which we can then change as it suits us.

Anyone against me checking this in the next days or so (that is, if it doesn't influence the non-IPv6 code too much)?

Simon Goldschmidt <goldsimon>
Group administrator
Mon 24 Jan 2011 02:21:48 PM UTC, comment #4: 

As of RFC4443 4.2 An Echo Reply SHOULD be sent in response to an Echo Request message sent to an IPv6 multicast or anycast address.
icmp6_input function of icmp6.c should rather not check
if (ip6_addr_ismulticast(ip6_current_dest_addr()))
to drop packets.

Lwip should join linklocal multicast group,
nd6_tmr function of nd6.c may have
ip6_addr_set_allnodes_linklocal(&multicast_address);
mld6_joingroup(netif_ip6_addr(netif, i), &multicast_address);
just like joining solicited node multicast group.

-Deleted Account- <kudatk>
Tue 18 Jan 2011 10:27:18 PM UTC, comment #3: 

New IPv6 patch version, includes a number of fixes and improvements contributed by Brad Giffel:
tcp.c, tcp_out.c, udp.c : Missing conditionals to remove IPv6 specific code
udp.c : References to 'iphdr' replaced with 'ip_current_header()'
stats.c, stats.h : Missing code to display IPv6 related stats
tcp_in.c : Simple typo
ip6.c, ip6_addr.h : Added casts to eliminate printf argument type checks
init.c : Fixed MEMP_NUM_SYS_TIMEOUT calculation
ip6_frag.c, nd6.c : Casts added to eliminate pointer arithmetic warnings
mld6.c : Should compile only if LWIP_IPV6_MLD is defined, not LWIP_IPV6

(file #22449)

Ivan Delamer <idelamer>
Group Member
Fri 17 Dec 2010 10:59:38 PM UTC, comment #2: 

Sorry, the previous patch also includes:
- Stateless address autoconfiguration
- IPv6 statistics
- IPv6 debug messages

Ivan Delamer <idelamer>
Group Member
Fri 17 Dec 2010 10:57:42 PM UTC, comment #1: 

Patch Update (the new patch includes all previous IPv6 patches).

The new version includes:
- Support for IPv6 fragmentation and reassembly
- IPv6 (AF_INET6) Sockets
- Multiple TODOs implemented, several bug fixes

(file #22221)

Ivan Delamer <idelamer>
Group Member
Thu 09 Dec 2010 07:37:23 PM UTC, original submission:  

This patch adds support for IPv6 to LwIP 1.4.0RC1.

It is a work in progress.

The following features are implemented:

- IPv6 layer
- Support in TCP/UDP/RAW
- Support in API
- ICMPv6 Echo request/reply
- Neighbor discovery ("ARP for IPv6")
- Multicast Listener Discovery
- Ethernet IF for IPv6

What is not implemented yet:
- IPv6 options processing
- IPv6 fragmentation and reassembly
- Stateless address autoconfiguration
- DHCPv6
- DNS
- Sockets
- SNMP
- Many debug messages and statistics
- Non-ethernet IFs

Ivan Delamer <idelamer>
Group Member

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attached Files
file #23924:  0003-lwip-unix-port-create-ipv6-linklocal-address.patch added by rahul_g (2KiB - text/x-patch - lwip unix port: Create ipv6 linklocal address )
file #23923:  0002-create-ipv6-linklocal-address.patch added by rahul_g (529B - text/x-patch - lwip-unix-port-create-ipv6-linklocal-address)
file #23782:  0001-lwip-unix-port-filter-ipv6-and-ip6output.patch added by rahul_g (1KiB - text/x-patch - Accept IPv6 packets Assign output_ip6 function)
file #22449:  2011-01-18 IPv6 for LwIP 1_4_0_RC1 patch.zip added by idelamer (81KiB - application/x-zip-compressed)
file #22221:  2010-12-17 IPv6 for LwIP 1_4_0_RC2 patch.zip added by idelamer (80KiB - application/x-zip-compressed - IPv6 patch, updated 2010-12-17 (includes 2010-12-09 patch))

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by rahul_g (Updated the item)
  • -email is unavailable- added by billauerbach (Posted a comment)
  • -email is unavailable- added by kieranm (Posted a comment)
  • -email is unavailable- added by goldsimon (Posted a comment)
  • -email is unavailable- added by kudatk (Posted a comment)
  • -email is unavailable- added by idelamer (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

     

    Follow 8 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2011-10-26 idelamer StatusIn Progress Done
        Open/ClosedOpen Closed
    2011-09-02 rahul_g Attached File- Added 0003-lwip-unix-port-create-ipv6-linklocal-address.patch, #23924
    2011-09-02 rahul_g Attached File- Added 0002-create-ipv6-linklocal-address.patch, #23923
    2011-08-11 rahul_g Attached File- Added 0001-lwip-unix-port-filter-ipv6-and-ip6output.patch, #23782
    2011-01-18 idelamer Attached File- Added 2011-01-18 IPv6 for LwIP 1_4_0_RC1 patch.zip, #22449
    2010-12-17 idelamer Attached File- Added 2010-12-17 IPv6 for LwIP 1_4_0_RC2 patch.zip, #22221
    2010-12-09 idelamer Attached File- Added 2010-12-09 IPv6 for LwIP 1_4_0_RC2 patch.txt, #22167

    Back to the top

    Powered by Savane 3.13-4448.
    Corresponding source code