FS#43183 - [netctl] stateless dhcpv6: dhclient fails with "no link-local address"

Attached to Project: Arch Linux
Opened by Heiner Kallweit (kalle) - Sunday, 21 December 2014, 15:50 GMT
Last edited by Jouke Witteveen (jouke) - Tuesday, 13 January 2015, 10:58 GMT
Task Type Bug Report
Category Arch Projects
Status Closed
Assigned To Jouke Witteveen (jouke)
Architecture All
Severity Low
Priority Normal
Reported Version
Due in Version Undecided
Due Date Undecided
Percent Complete 100%
Votes 0
Private No

Details

I use stateless DHCPv6 and face issues with dhclient to get nameserver info.
The network profile includes IP6=dhcp-noaddr.
dhclient complains about "no link-local address" and doesn't fetch infos from the DHCPv6 server.

It seems like dhclient needs a link-local IPv6 address, else it just stops with an error.
At the time when dhclient is called the respective interface is up but no link-local address exists yet.
Adding a "sleep 5" before dhcp_call in /usr/lib/network/ip helped, the more sophisticated way would
be to wait for a non-tentative link-local address being present.

Adding the following two timeout_wait lines fixed the issue for me.

case "$IP6" in
dhcp|dhcp-noaddr)
timeout_wait 10 '[[ -n "$(ip -6 addr show dev "$Interface" scope link)" ]]'
timeout_wait 10 '[[ -z "$(ip -6 addr show dev "$Interface" scope link tentative)" ]]'
dhcp_call "${DHCP6Client:-dhclient}" start 6 ${IP6:5} || return
;;
This task depends upon

Closed by  Jouke Witteveen (jouke)
Tuesday, 13 January 2015, 10:58 GMT
Reason for closing:  Fixed
Additional comments about closing:  4892bac
Comment by Jouke Witteveen (jouke) - Sunday, 21 December 2014, 21:18 GMT
You must have a fast system! Do you know what initialization state of the interface we should wait for before calling upon dhclient? Does it work correctly with dhcpcd? If the latter is the case, it might be easier to fix the problem in dhclient by waiting until the initialization is sufficiently completed there.
Comment by Heiner Kallweit (kalle) - Sunday, 21 December 2014, 22:48 GMT
Well, the system is a mini-pc (IMX.6 ARM based running at 1.2GHz). It's quite fast for the little power it consumes but it's not a performance giant.
The first timeout_wait (from IFF_UP until link-local address shows up in "tentative" state) takes 2.8s here and the second one 1.8s (until link-local address leaves "tentative" state and is usable).
When dhclient is called in the original script not even IFF_LOWER_UP is set yet.

IMHO just checking the interface state is not sufficient as things like DAD status of an address are not reflected in the interface status.
Therefore I see no other way than checking for a usable link-local address.
However my workaround might not be the final solution as it doesn't consider corner cases like failed DAD.

I didn't check dhcpcd but I'd expect the same behavior as each dhcp client needs a source address for sending DHCP requests.

By the way: I'm a little astonished that nobody else stumbled across this yet. Are so few people using DHCPv6 or is my case so special?
Comment by Heiner Kallweit (kalle) - Monday, 22 December 2014, 18:51 GMT
I tested a little bit more ..

The 2.8s for the first timeout_wait are caused by my setting "SkipNoCarrier=yes".
If SkipNoCarrier is not set or set to "no" then connections/ethernet/ethernet_up() waits for the carrier already.
Still the second timeout_wait is needed to wait for DAD to be completed.

To cite from kernel's net/ipv6/addrconf.c:
A tentative address is not considered "assigned to an interface" in the traditional sense, unless it is also flagged as optimistic.
Comment by Jouke Witteveen (jouke) - Tuesday, 06 January 2015, 13:12 GMT
According to section 18.1.8 of RFC 3315 (DHCPv6), the DHCPv6 client is responsible for handling DAD on its leases. Hence netctl should only be concerned with DAD on the link-local address in case of IP6=dhcp*.

Could you test the attached patch?
   ip.patch (1.9 KiB)

Loading...