tasklwIP - A Lightweight TCP/IP stack - Tasks: task #12722, Improve IPv4/v6 address handling

 
 

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

task #12722: Improve IPv4/v6 address handling

Submitter:  Simon Goldschmidt <goldsimon>
Submitted:  Sat 29 Jun 2013 08:11:41 PM UTC
   
 
Category:  IPv6 Should Start On:  Sat 29 Jun 2013 12:00:00 AM UTC
Should be Finished on:  Sat 29 Jun 2013 12:00:00 AM UTC Priority:  5 - Normal
Status:  Done Privacy:  Public
Assigned to:  goldsimon Percent Complete:  100%
Open/Closed:  Closed Planned Release:  1.5.0 beta1
Effort:  0.00

Jump to the original submission

Thu 09 Apr 2015 08:29:23 PM UTC, comment #10: 

Should be done now. Maybe I missed some things...

At least SNMP might really be improved as it currently cannot handle IPv6 addresses in the MIB.

Simon Goldschmidt <goldsimon>
Group administrator
Mon 30 Mar 2015 04:10:33 PM UTC, comment #9: 

this would be amazing... I'm really busy with work now but I'll try to test it if it helps.

Ivan Delamer <idelamer>
Group Member
Sun 29 Mar 2015 08:14:03 PM UTC, comment #8: 

I'm currently working on this but it's much more work than I thought: to finally get the code clean, I'm removing the whole 'ipX' idea. Instead, ip_addr_t shall be the universal address type, visible to the APIs. Plus I'm planning to rename all IPv4 functions from 'ip_*' to 'ip4_*' and renaming the version-wrapper-defines to 'ip_*'.

Dedicated IPv4 addresses get a new type 'ip4_address_t' and are handled in specific cases only (IPv4 code and related protocols like AutoIP, DHCP, ARP).

The benefit is that (correctly written) applications don't need to be rewritten: address initialization macros stay like they are, they just also initialize the 'type' field. Plus we get an IPv6-only stack 'for free', almost.

The downside is that there are some (rare) cases where old applications/ports need to be upgraded (where IPv4 addresses are needed, e.g. netif address initialization). However, unless LWIP_IPV6 is enabled, things should still work...

Since this is the last real blocker for 1.5.0 (isn't it?), I hope to finish it in the next days...

Simon Goldschmidt <goldsimon>
Group administrator
Thu 05 Mar 2015 06:42:50 PM UTC, comment #7: 

I agree about adding a version field to ipX_addr_t, this is what sockaddr, sockaddr_in, sockaddr_in6 do with the sa_family_t field, which is always the first one:

struct sockaddr {
    unsigned short sa_family;    /* address family, AF_xxx */
    …
};

struct sockaddr_in {
    sa_family_t    sin_family;   /* address family: AF_INET */
    …
}

struct sockaddr_in6 {
    sa_family_t     sin6_family; /* address family: AF_INET6 */
    …
}

Sylvain Rochet <gradator>
Group Member
Wed 04 Mar 2015 08:51:23 PM UTC, comment #6: 


> My initial vote is for adding a version field to ipX_addr_t


As that's what I thought, too, I'll see if I find the time to do that change.

Once ipX_addr_t is more than just a union of ip_addr_t/ip6_addr_t, adding IPv6 scope should not require port-breaking changes as well.

Simon Goldschmidt <goldsimon>
Group administrator
Wed 04 Mar 2015 08:39:39 PM UTC, comment #5: 

bump (so we can discuss in this context vs. email list)

My initial vote is for adding a version field to ipX_addr_t

Maybe we can make that version field conditional to LWIP_IP6, so that address structs don't grow in size for IPv4-only systems.

Ivan Delamer <idelamer>
Group Member
Wed 03 Jul 2013 03:20:54 PM UTC, comment #4: 

PCBs have the isipv6 member, we can use the same macros we use in tcp/udp code to handle addresses.

Or for example if this application will only support IPv4 we can just make it

char* ipa = ip_ntoa(ipX_2_ip(&pcb->local_ip));

or

char* ipa = ip_ntoa(((ip_addr_t*))&pcb->local_ip);

Ivan Delamer <idelamer>
Group Member
Wed 03 Jul 2013 03:01:20 PM UTC, comment #3: 

What drove me to start this task was that the smtp example application does not compile with IPv6 enabled because of this code:

char* ipa = ip_ntoa(&pcb->local_ip);

If 'pcb->local_ip' would include information about the address type, then 'ip_ntoa()' could work on both versions (instead of only IPv4 as it is now).

How would you suggest to solve this problem when upgrading an existing application to support IPv6 as well?

Simon Goldschmidt <goldsimon>
Group administrator
Tue 02 Jul 2013 03:59:06 PM UTC, comment #2: 

This is a good discussion and I think there is no straightforward answer.

From an application point of view, I find 2 cases:
1) Applications that use both ip4 and ip6 addresses: this works well now, as each address is assigned to a separate variable of the corresponding type.

2) Applications that use either one ip4 or one ip6 address: I find myself reusing the pattern of having one variable for each type, and if I use ip6 I set ip4 to 0.0.0.0, or if I use ip4 I set ip6 to ::

So in case (2) it would be useful to have the unified struct with extra byte for version, although memory use in a 32-bit system is the same (16 + 1 rounded up to 20 for a single struct, or 16 + 4 for 2 structs)

For LwIP internals, I think having 2 separate structs works well. Keeing track of IP version in the PCB has been sufficient I think. And I think that byte can be used in more ways to implement different scenarios (e.g. listen in either IPv4 or IPv6)

The other option we can look at, especially for applications, is using socket addresses (which keep track of version) and have some macros for converting to ip4_addr_t or ip6_addr_t. This way we don't need to invent a new struct and we can keep the best of both worlds.

Ivan Delamer <idelamer>
Group Member
Sat 29 Jun 2013 08:12:18 PM UTC, comment #1: 

Forgot: this change would greatly help adapting contrib applications to use IPv6

Simon Goldschmidt <goldsimon>
Group administrator
Sat 29 Jun 2013 08:11:41 PM UTC, original submission:  

One thing I'm still not happy with in integrating IPv6 is the ipX_addr_t implementation. As a union, it covers both IPv4 and IPv6 addresses but once you have it detached from its pcb, you can't tell wether it is v4 or v6.

When introducing ipX_addr_t, I did that to save space, but I don't think it's worth the effort: it's currently 16 bytes and adding 1 extra byte at the end, it would be 17 bytes, or 20 bytes where alignment follows in structs.

Summed up, this means that we need more memory, but I think systems implementing IPv6 don't count memory in bytes but rather KBytes, anyway, or am I wrong?

Simon Goldschmidt <goldsimon>
Group administrator

 

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

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by gradator (Posted a comment)
  • -email is unavailable- added by idelamer (Posted a comment)
  • -email is unavailable- added by goldsimon (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 5 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2015-04-09 goldsimon StatusNone Done
        Percent Complete0% 100%
        Assigned toNone goldsimon
        Open/ClosedOpen Closed
    2013-06-29 goldsimon Planned ReleaseNone 1.5.0 beta1

    Back to the top

    Powered by Savane 3.15-e6e5.
    Corresponding source code