Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FS#1462 - odhcp6c fails to renew and rebind addresses #6474

Closed
openwrt-bot opened this issue Mar 30, 2018 · 7 comments
Closed

FS#1462 - odhcp6c fails to renew and rebind addresses #6474

openwrt-bot opened this issue Mar 30, 2018 · 7 comments
Labels

Comments

@openwrt-bot
Copy link

clefru:

odhcp6c sents all its packets to [[https://github.com/openwrt/odhcp6c/blob/33a2ba1c14eb5447326945c120e0b64a587ed151/src/dhcpv6.c#L499|ff02::1:2]]. However a trace captured from my wan interface shows that the source-IP and dest-IP are completely changed for the RENEW message, hence ignored by the DHCP server, effectively crippling DHCPv6. See attached screenshot of wireshark for the failed conversation, where the RENEW messages are not sent to ff02::1:2, but to some random public address.

While I can understand that there are routing tables and preferred egress addresses that can make the public IP be preferred over the link local IP (used in the beginning of the conversation), but what leads to mangling of ff02::1:2 into something public is beyond me.

This breaks IPv6 support after initial assignment. As seen in the wireshark trace, despite a response from my ISP dhcp server, odhcp6c ignores it, and keeps retrying.

OpenWrt SNAPSHOT, r6565-fd588db

@openwrt-bot
Copy link
Author

dedeckeh:

Can you attach the wireshark traces so I can check the contents of the DHCPv6 messages exchanged between server and client ?

@openwrt-bot
Copy link
Author

clefru:

Thanks Hans for the fast feedback. I attached the pcap trace you requested. Let me note however:

  1. I was reading outdated sources on github. Reading the odhcp6c sources from git.openwrt.org shows that it very well can use different address than the broadcast address for the RENEW message.

  2. My upstream DHCPv6 sets the "unicast" option[1] in the reply, which allows for odhcp6c to respond directly to this unicast address. However, it looks my ISP does not respond to DHCPv6 on that public address. I think that my ISP should set the link-local addr here, that it used to reply in the beginning of the conversation, and not a public routable internet address. So I think that it's my ISPs fault not to respond to RENEW.

  3. What's open here for investigation is why odhcp6c keeps retrying the REBIND messages. In my log I can see:

Sun Apr 1 11:08:10 2018 daemon.notice odhcp6c[28904]: Send REBIND message (elapsed 0ms, rc 0)
Sun Apr 1 11:08:10 2018 daemon.notice odhcp6c[28904]: Got a valid reply after 312ms
Sun Apr 1 11:08:20 2018 daemon.notice odhcp6c[28904]: Send REBIND message (elapsed 10240ms, rc 1)
Sun Apr 1 11:08:22 2018 daemon.notice odhcp6c[28904]: Got a valid reply after 11590ms
Sun Apr 1 11:08:41 2018 daemon.notice odhcp6c[28904]: Send REBIND message (elapsed 30720ms, rc 2)
Sun Apr 1 11:08:44 2018 daemon.notice odhcp6c[28904]: Got a valid reply after 33687ms
Sun Apr 1 11:09:20 2018 daemon.notice odhcp6c[28904]: Send REBIND message (elapsed 69760ms, rc 3)
Sun Apr 1 11:09:22 2018 daemon.notice odhcp6c[28904]: Got a valid reply after 71977ms
Sun Apr 1 11:10:39 2018 daemon.notice odhcp6c[28904]: Send REBIND message (elapsed 148480ms, rc 4)

The DHCPv6 replies on the wire indicate status code = 0 (success), so I am unclear what odhcp6c rejects about the replies. Reading more odhcp6c source code didn't make me any wiser, as there are just too many moving parts to make an informed guess where this goes wrong. I'll probably have to compile my own odhcp6c with a bunch of instrumentation thrown in.

Unless you see something obviously wrong, feel free to ignore this ticket as the root cause is my ISP's unresponsive unicast address.

[1] https://tools.ietf.org/html/rfc3315#section-22.12

@openwrt-bot
Copy link
Author

dedeckeh:

Thanks for including the wireshark traces; odhcp6c keeps sending rebind messages because the IA_PREFIX (2a02:168:96b7/48) is not included in the reply message by the DHCPv6 server as it only includes IA_PREFIX option.
As a result it keeps sending REBIND messages till the IA_PREFIX lifetime expires; there's no clear indication why the server does not rebind IA_PREFIX as no status message is included

@openwrt-bot
Copy link
Author

dedeckeh:

You could set defaultreqopts to 0 in uci network; than odhcp6c will only request the options specified in the reqopts uci option and thus will not request by default for the server unicast option. I would expect the DHCPv6 server will not return the server unicast option and as a result renew messages will be sent to the all DHCPv6 relay address

@openwrt-bot
Copy link
Author

clefru:

Thanks Hans for your feedback, and looking through my trace!

Would you consider this trunked upstream reply an RFC violation? From [[http://https://tools.ietf.org/html/rfc3633#page-15|RFC 3633]] 12.2:

"The delegating router MUST include an IA_PD Prefix option or options (in an IA_PD option) in Reply messages sent to a requesting router."

This does not seem to fulfilled by the delegating router as zero IA_PD Prefix options are included with the IA_PD option. I will contact my ISP about that.

However, that doesn't mean that T1=T2s are inappropriately set in the reply, because in the RFC right above the quoted section we also have: "the delegating router MAY send a Reply message to the requesting router containing the IA_PD with the lifetimes of the prefixes in the IA_PD set to zero". From that I read that REBIND replies with IA_PD having T1=T2=0 are valid.

This case isn't handled so well by odhcp6c as it will loop in REBIND forever. Shouldn't it go back to Solicitation eventually?

Sidenote: Your suggested "set defaultsreqopts 0" trick did not work for me although my odhpc6 gets correctly launched with the "-R" flag. Reason being my upstream DHCP server sets the unicast option, even when not requested in the reply and odhcp6c happily parses and accepts it. As I have now set up a build environment for odhcp6c now, I just removed the unicast flag handling from my binary.

@openwrt-bot
Copy link
Author

dedeckeh:

odhcp6c handles the case where the lifetime is set to zero; see https://git.openwrt.org/?p=project/odhcp6c.git;a=blob;f=src/odhcp6c.c;h=48e3dee1cea2c9545e03583e9dab5578698d20bf;hb=HEAD#l744. It will remove the entry if the lifetime is set to 0 and if no statefull address/prefix entries are left it will switch to sending solicit messages.
But in this particular case the DHCPv6 server is not sending an IA_PREFIX in the reply which means it has to follow the following requirement from RFC3315

When the client receives a Reply message in response to a Renew or Rebind message, the client examines each IA independently. For each IA in the original Renew or Rebind message, the client:
  • sends a Request message if the IA contained a Status Code option
    with the NoBinding status (and does not send any additional
    Renew/Rebind messages)

  • sends a Renew/Rebind if the IA is not in the Reply message

  • otherwise accepts the information in the IA

@openwrt-bot
Copy link
Author

clefru:

Thanks for detailed analysis, Hans. From RFC 3315/Sec. 18.1.4 "Creation and Transmission of Rebind Messages":

The message exchange is terminated when the valid lifetimes of all the addresses assigned to the IA expire (see section 10), at which time the client has several alternative actions to choose from; for example:
  • The client may choose to use a Solicit message to locate a new
    DHCP server and send a Request for the expired IA to the new
    server.

  • The client may have other addresses in other IAs, so the client
    may choose to discard the expired IA and use the addresses in the
    other IAs.

I would argue that this gives justification for having the client give up on the rebind conversation, as some timeout should eventually be hit. I am not going to argue this further, as I don't feel qualified. It just feels odd that this is not self-healing and I have to restart the DHCP client when it degenerates.

Thanks again for your remarks. I'll report this to my ISP.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant