Summary: | rtadvd: fails to generate error when iface lacks a link-local address | ||||||
---|---|---|---|---|---|---|---|
Product: | Base System | Reporter: | John W. O'Brien <john> | ||||
Component: | standards | Assignee: | Hiroki Sato <hrs> | ||||
Status: | In Progress --- | ||||||
Severity: | Affects Only Me | CC: | hrs, net | ||||
Priority: | --- | ||||||
Version: | 12.1-RELEASE | ||||||
Hardware: | Any | ||||||
OS: | Any | ||||||
See Also: | https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=254445 | ||||||
Attachments: |
|
Description
John W. O'Brien
2020-07-02 00:18:03 UTC
Created attachment 216122 [details]
Reject scope-incompatible IPv6 source address
I have very limited confidence in this patch because I am not sure that I fully understand the surrounding code and have not yet tested it. Its purpose is to more fully illustrate what I think the problem is and a possible solution. Feedback would be warmly welcomed.
Also, I discovered this bug on 12.1-RELEASE-p5. Though I have not attempted to reproduce it on any other version, I expect I could.
I'll take this. It is a valid situation for a unicast communication where a global-scope address is the source address and a link-local-scope address is the destination address though it is not recognized as valid as a Router Advertisement message. Limiting the address selection to the same zone as the destination's is too restrictive. The current implementation prefers a source scope whose scope is larger than the destination's (c.f. Rule 2, Sec. 5, RFC 6724). Even if the source is smaller than the destination, an address is selected in any way. However, upon sending a packet, the network stack will discard the packet due to an error "no destination". So in the situation with src=GUA/dst=LLA, a unicast communication works and it does not against the specifications. Usually it does not happen because every interface has at least one LLA configured (c.f. Sec. 2.1, RFC 4291) and the source address selection algorithm always prefers a smaller scope. For an interface with no LLA, I think NDP does not work in various ways because it (and MLDv2) heavily depends on LLA. It is not limited to Router Advertisement messages. For this reason, FreeBSD configures an EUI-64 LLA by default. There are some scenarios where only GUAs are configured on an interface, however. To prevent rtadvd(8) from sending invalid packets you reported, I think rtadvd(8) should check if the interface has an LLA or not. I believe running rtadvd(8) on an interface with no LLA is a wrong configuration. Please let me know if I understand your report correctly, and comments about my understanding about the issue you pointed out. If the additional check on rtadvd(8) is sufficient, I will work on it. (In reply to Hiroki Sato from comment #3) > It is a valid situation for a unicast communication where a global-scope > address is the source address and a link-local-scope address is the > destination address though it is not recognized as valid as a Router > Advertisement message. Limiting the address selection to the same zone as > the destination's is too restrictive. The current implementation prefers a > source scope whose scope is larger than the destination's (c.f. Rule 2, Sec. > 5, RFC 6724). Even if the source is smaller than the destination, an > address is selected in any way. However, upon sending a packet, the > network stack will discard the packet due to an error "no destination". My understanding of the source selection rules is definitely incomplete, and may also be flawed, so I will gladly defer to you on this matter. > So in the situation with src=GUA/dst=LLA, a unicast communication works > and it does not against the specifications. An aspect of this about which I still harbor uncertainty is the question of whether every usable A->B address pair is also a usable B->A pair, assuming unicast semantics. In the rtadvd(8)/RA case, we enjoy the benefit of multicast semantics, where B->A is invalid regardless of the scopes. It was for that reason, in addition to the above, that I elected to report this against rtadvd(8) instead of against in6_src.c. > Usually it does not happen because every interface has at least one LLA > configured (c.f. Sec. 2.1, RFC 4291) and the source address selection > algorithm always prefers a smaller scope. > > For an interface with no LLA, I think NDP does not work in various ways > because it (and MLDv2) heavily depends on LLA. It is not limited to > Router Advertisement messages. For this reason, FreeBSD configures an > EUI-64 LLA by default. Accepting this as fact implies that there is another bug somewhere. The reason I discovered the rtadvd(8) problem in the first place was through a sequence of steps to create an if_bridge(4) and configure it as a subnet gateway (for multiple VNET jails via epair(4)s) that resulted, unnoticed, in the GUA && !LLA scenario without explicitly disabling AUTO_LINKLOCAL. I have not attempted to reproduce those steps. > There are some scenarios where only GUAs are configured on an interface, > however. To prevent rtadvd(8) from sending invalid packets you reported, > I think rtadvd(8) should check if the interface has an LLA or not. I > believe running rtadvd(8) on an interface with no LLA is a wrong > configuration. I concur with the last statement. If I achieve nothing else with this bug, I want to reduce substantially the time required to troubleshoot the specific scenario I encountered: rtadvd(8) + no LLA = fail immediately and emit an actionable error. > Please let me know if I understand your report correctly, and comments about > my understanding about the issue you pointed out. If the additional check > on rtadvd(8) is sufficient, I will work on it. Yes, that would be sufficient. Thank you very much for your prompt and thorough response. |