Opened 13 years ago
Last modified 4 years ago
#8316 assigned enhancement
Haiku needs IPv6 link scope Auto Configuration
Reported by: | kallisti5 | Owned by: | nobody |
---|---|---|---|
Priority: | normal | Milestone: | Unscheduled |
Component: | Network & Internet/IPv6 | Version: | R1/Development |
Keywords: | local scope | Cc: | |
Blocked By: | Blocking: | ||
Platform: | All |
Description (last modified by )
Haiku needs to generate a link scope address on all interfaces when the ipv6 module is present.
Here is an example from Linux:
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 14:da:e9:51:54:22 brd ff:ff:ff:ff:ff:ff inet 10.10.10.162/24 brd 10.10.10.255 scope global eth0 inet6 fe80::16da:e9ff:fe51:5422/64 scope link valid_lft forever preferred_lft forever
Attachments (1)
Change History (21)
comment:1 by , 13 years ago
Description: | modified (diff) |
---|
comment:2 by , 13 years ago
comment:3 by , 13 years ago
Most of this should already be implemented, see http://cgit.haiku-os.org/haiku/tree/src/servers/net/AutoconfigLooper.cpp#n123 and following.
comment:4 by , 13 years ago
Wasn't aware that was implemented.. nice job.
All that code depends on INET6 being defined... however grepping through the Haiku tree doesn't result in any spots we define INET6. Is this on purpose?
comment:5 by , 13 years ago
I assume that Atis didn't want to break existing code for his in-progress work on IPv6. Since no one had the time to work on IPv6 in the mean time, no one bothered to remove those defines (I don't think it makes much sense to make that optional; the headers are always there, anyway).
comment:6 by , 13 years ago
Ahh..
It's commented out in the net server jam file:
http://cgit.haiku-os.org/haiku/tree/src/servers/net/Jamfile#n13
Also, while the rest of the checks are #ifdef INET6, the following is a plain if...
http://cgit.haiku-os.org/haiku/tree/src/servers/net/NetServer.cpp#n108
comment:7 by , 13 years ago
Let me go ahead and remove those #ifdef's as well as the commented out define in the Jamfile.
I'll give it a quick compile and see if we get a stable local ipv6 address... If so committing them out and closing this issue sounds like a resolution to me.
I'll give you an hour before making any changes upstream in case you have other plans. I don't wanna step on your toes.
comment:8 by , 13 years ago
Huh? I have a hard time remembering my last commit ;-) Please just go ahead, if you have the time to test it, my toes certainly don't mind.
comment:9 by , 13 years ago
Jeesh.
This change turned from a little fix to a rewrite *real* quick.
Attaching the work I have so far...
This *almost* works, however I am still getting a strange IPv6 address.
I moved the ConfigLinkLocal call to NetServer from the looper... It seemed like a bad place for LinkLocal. (as the looper is only called on autoconfig == true)
always setting up a linklocal address is a good idea because it's not your primary ipv6 address. (ipv6 router advertisement or DHCPv6 would be a good fit for the looper however)
comment:10 by , 13 years ago
patch: | 0 → 1 |
---|
comment:11 by , 13 years ago
committed a much different solution in hrev43721 :)
I think we need to add a few routes as well.. but I have *no* idea what their source + destination should be.
At the moment pinging ::1 doesn't even work though... so testing the actual connectivity is hard.
comment:12 by , 13 years ago
That used to work at some point, though. Dunno what is going wrong now. Does the loopback interface has an IPv6 address?
follow-up: 19 comment:13 by , 13 years ago
Yeah, there is a ::1 address assigned to loopback with a strange prefix length:
inet6 addr: ::1, Prefix Length: 2147512363
there are 0 IPv6 routes though on the system... Maybe digging around would turn up a disabled route setup somewhere?
comment:14 by , 13 years ago
My linux machine shows a prefix of 128.
Another question is address scope, it doesn't seem like we have have scope flags for each interface IP. (Scope: link (fe80::), Scope: host(::1), Scope: global(anything else))
The scope is probably the last todo.. we just have to worry about everything breaking when everyone starts using AAAA records.
comment:15 by , 13 years ago
bah. that ::1 was a false positive. I was playing with the new network preflet a while back and I added it through that.
current systems don't spin up a loopback for ipv6.
I've dropped code into the network kit to add a loopback ::1, testing now.
comment:16 by , 10 years ago
Milestone: | R1 → Unscheduled |
---|
Moving IPv6 related tickets out of R1 milestone.
comment:17 by , 8 years ago
patch: | 1 → 0 |
---|
comment:18 by , 8 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:19 by , 4 years ago
Replying to kallisti5:
Yeah, there is a ::1 address assigned to loopback with a strange prefix length:
inet6 addr: ::1, Prefix Length: 2147512363
While I didn't experience this with the loopback address, I did experience this with link local addresses. I had been experimenting locally with hrev45736 reverted to see how the system performed, and I did observe strange prefix lengths on the IPv6 link local addresses.
Though there might be more than one instance of this bug, one bug I found was in net_server's NetServer::_ConfigureIPv6LinkLocal()
, where it generates the link local addresses like this:
BNetworkAddress localLinkAddress(addressRaw, 0); BNetworkAddress localLinkMask("ffff:ffff:ffff:ffff::"); // 64 BNetworkAddress localLinkBroadcast("fe80::ffff:ffff:ffff:ffff"); // ... BNetworkInterfaceAddress interfaceAddress; interfaceAddress.SetAddress(localLinkAddress); interfaceAddress.SetMask(localLinkMask); interfaceAddress.SetBroadcast(localLinkMask); interface.AddAddress(interfaceAddress);
I was curious whether this was working as expected, so I dumped the hex contents of the sockaddr of each of the address/mask/broadcast addresses, and I found that they were not working as expected:
Address (hex): fe 80 00 00 00 00 00 00 a6 c3 f0 ff fe 67 94 90 Mask (hex): e0 02 73 41 cb 7f 00 00 00 0d 73 41 cb 7f 00 00 <-- random contents each time Broadcast (hex): 66 65 64 32 3a 35 35 37 19 00 00 00 00 00 00 00 <-- random contents each time
The random contents suggested uninitialised memory. After further digging I found that BNetworkAddress tries to resolve the string address by calling BNetworkAddressResolver, which was in turn failing (BNetworkAddress::SetTo was returning error, but the constructor ignores the error).
I observed that BNetworkAddressResolver only failed on a fresh boot. After a link local address (with invalid, random mask) was added, subsequent calls to BNetworkAddress localLinkMask("ffff:ffff:ffff:ffff::");
worked as expected.
This suggested the resolver library was failing to resolve IPv6 addresses if no IPv6 addresses are present. Given net_server's job is to add IPv6 addresses in the first place before any exist, this is quite the Catch-22.
I see the following options for solving the problem:
- Pass the
B_UNCONFIGURED_ADDRESS_FAMILIES
flag to the BNetworkAddress in NetServer::_ConfigureIPv6LinkLocal. It appears this tells the resolver to resolve IPv6 addresses regardless of whether it thinks IPv6 is available on the system (which on first boot, it is not yet). - Modify the _ConfigureIPv6LinkLocal function to create the localLinkMask / localLinkBroadcast by passing an
in6_addr
structure, not aconst char *
, avoiding the BNetworkAddressResolver altogether. This means no string parsing is needed at all, which is more robust. - Populate the localLinkMask by calling
BNetworkAddress::SetToMask(AF_INET6, 64)
, which is designed for this use case. However this only works for the mask, not broadcast address. That said, I don't know whether the broadcast address is used for anything? (I know it doesn't make sense in IPv6, but does anything in the kernel rely on it? Can it be zeroed out?) - Introduce a mode on the BNetworkAddressResolver or BNetworkAddress which only uses
inet_pton()
rather thangetaddrinfo()
. While this is less useful for a generic BNetworkAddress, it is suitable for low-level network config, which net_server does qualify for. - There might be other options I haven't thought of yet.
I'm going to assume Option 1 is preferable (fewest changes required) and prepare a patch for that, but of course there is a lot more work needed to get IPv6 usable so I'd need additional feedback as to whether we think we are ready to uncomment the call to _ConfigureIPv6LinkLocal.
comment:20 by , 4 years ago
I don't know if we are ready to uncomment that call yet, no. I think there are still easily reproducible KDLs in the IPv6 kernel stack (check the relevant components on the bugtracker).
ftp://ftp.rfc-editor.org/in-notes/rfc3513.txt
Implementation notes:
IPv6 link scope addresses are based on the MAC address of the card.
Once we have the local link address, we must then perform an ICMPv6 ping to ensure it's available. (Duplicate Address Detection (DAD))
You can find more plain-english descriptions here: http://www.cisco.com/web/about/ac123/ac147/archived_issues/ipj_7-2/ipv6_autoconfig.html