[Dnsmasq-discuss] Bunch of small fixes in DHCPv6
During my testing several issues were found in implementation of dhcpv6, so I submit here patch with the fixes. Issues are: - there is no need to check server-id matching for REBIND request as of ch. 15.7 RFC 3315 - when client tries to DECLINE with an unknown IAID that should not have a binding we must answer with 'success' result in global section anyway - when client tries to CONFIRM with wrong address server must not send reply as of ch 18.2.2 RFC 3315 - possibly typo (?) in not setting reply type to DHCPREPLY sometimes leads to maiformed answer -- Best regards, Ilya Ponetaev D-Link Corp. diff --git a/src/rfc3315.c b/src/rfc3315.c index 364277d..8425f93 100644 --- a/src/rfc3315.c +++ b/src/rfc3315.c @@ -313,8 +313,8 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_ else if (msg_type != DHCP6IREQ) return 0; - /* server-id must match except for SOLICIT and CONFIRM messages */ - if (msg_type != DHCP6SOLICIT msg_type != DHCP6CONFIRM msg_type != DHCP6IREQ + /* server-id must match except for SOLICIT, CONFIRM and REBIND messages */ + if (msg_type != DHCP6SOLICIT msg_type != DHCP6CONFIRM msg_type != DHCP6REBIND msg_type != DHCP6IREQ (!(opt = opt6_find(state-packet_options, state-end, OPTION6_SERVER_ID, 1)) || opt6_len(opt) != daemon-duid_len || memcmp(opt6_ptr(opt, 0), daemon-duid, daemon-duid_len) != 0)) @@ -327,7 +327,8 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_ if (is_unicast (msg_type == DHCP6REQUEST || msg_type == DHCP6RENEW || msg_type == DHCP6RELEASE || msg_type == DHCP6DECLINE)) -{ +{ + *outmsgtypep = DHCP6REPLY; o1 = new_opt6(OPTION6_STATUS_CODE); put_opt6_short(DHCP6USEMULTI); put_opt6_string(Use multicast); @@ -1039,6 +1040,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_ case DHCP6CONFIRM: { + int is_addr_requested = 0; /* set reply message type */ *outmsgtypep = DHCP6REPLY; @@ -1062,11 +1064,22 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_ end_opt6(o1); return 1; } + else + { + ++is_addr_requested; + } log6_quiet(state, DHCPREPLY, req_addr, state-hostname); } } + /* + * There is no valid addresses in request, + * silently drop CONFIRM as of RFC 3315 Section 18.2.2 + */ + if (0 == is_addr_requested) + return 0; + o1 = new_opt6(OPTION6_STATUS_CODE); put_opt6_short(DHCP6SUCCESS ); put_opt6_string(_(all addresses still on link)); @@ -1232,6 +1245,13 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_ } } + /* + * Me must anwser with 'success' in global section anyway + */ + o1 = new_opt6(OPTION6_STATUS_CODE); + put_opt6_short(DHCP6SUCCESS); + put_opt6_string(_(success)); + end_opt6(o1); break; } ___ Dnsmasq-discuss mailing list Dnsmasq-discuss@lists.thekelleys.org.uk http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss
Re: [Dnsmasq-discuss] Adding Route Information Option to prefixes in RA
Hi Simon, just stumbled upon this and wanted to add some notes about that because I have some experience with RIOs from OpenWrt already. If you want to send RIOs because you want to be compliant with RFC 6204/7084 you should send them with the prefix that was delegated to the router running dnsmasq not the prefix that was actually assigned to the interface (i.e. if you get a /56 from the ISP you should announce the /56 as RIO and a /64 out of that as PIO to make it work). In addition and what is probably more critical here: some client implementations don't handle PIOs and RIOs for the same prefix very well (at least with the most-common prefix-size of /64 that is) and it might in some extreme cases even lead to disrupted connectivity between hosts. Since I had the fun to debug such a case and want to spare you the trouble you might want to have a look at this lengthy thread: https://dev.openwrt.org/ticket/17396 Cheers, Steven ___ Dnsmasq-discuss mailing list Dnsmasq-discuss@lists.thekelleys.org.uk http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss
Re: [Dnsmasq-discuss] Adding Route Information Option to prefixes in RA
Hi Thanks for valuable information, but just as addition: can you point to definite broken implementations which is unable to handle PIO and RIO for the same prefix? I can try to test and reproduce it. And what exactly do you mean under same prefix: with same length (for ex. /64) or nested (for ex. bunch of /64 in one /48)? Thanks in advance. On 09/10/2014 05:52 PM, Steven Barth wrote: Hi Simon, just stumbled upon this and wanted to add some notes about that because I have some experience with RIOs from OpenWrt already. If you want to send RIOs because you want to be compliant with RFC 6204/7084 you should send them with the prefix that was delegated to the router running dnsmasq not the prefix that was actually assigned to the interface (i.e. if you get a /56 from the ISP you should announce the /56 as RIO and a /64 out of that as PIO to make it work). In addition and what is probably more critical here: some client implementations don't handle PIOs and RIOs for the same prefix very well (at least with the most-common prefix-size of /64 that is) and it might in some extreme cases even lead to disrupted connectivity between hosts. Since I had the fun to debug such a case and want to spare you the trouble you might want to have a look at this lengthy thread: https://dev.openwrt.org/ticket/17396 Cheers, Steven ___ Dnsmasq-discuss mailing list Dnsmasq-discuss@lists.thekelleys.org.uk http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss -- Best regards, Ilya Ponetaev D-Link Corp. ___ Dnsmasq-discuss mailing list Dnsmasq-discuss@lists.thekelleys.org.uk http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss
Re: [Dnsmasq-discuss] Adding Route Information Option to prefixes in RA
Hi Ilya, please see the link to the OpenWrt ticket in my last mail which goes about what happens in detail. I don't remember if the user actually posted what OS the host ran on but it seemed to be some kind of server so probably something linux/unix? To summarize the issue since the ticket thread is a bit lengthy: The RIO and the PIO were identical let's say 2001:db8::/64 which lead to two routes being created in the host's routing table. One route saying 2001:db8::/64 is on-link (PIO) and one route saying 2001:db8::/64 is off-link and should be reached via the router sending the RA (RIO). Now the host in question preferred the off-link route over the on-link route so when it tried to send packages to an other host in 2001:db8::/64 it sent them to the router instead of doing neighbor discovery and sending it directly on-link. Now the router sending the RA in-turn disagreed about it being the one who should forward the package and replied with an ICMPv6-redirect saying: send directly to the other host, but it seems this redirect was ignored. Since this should only happen when RIO and PIO are both /64 (and on-link flag is set for the PIO) my work-around in OpenWrt was to simply not send the RIO when PIO and RIO would be identical which solved the problem for the user. Obviously if RIO and PIO have different sizes this shouldn't matter. As a side note: since afaik Windows is about the only system to support and enable RIOs by default and Linux kernel-defaults are to ignore RIOs with prefix-length != 0 and Apple not implementing RIO support at all we could get in more trouble once more platforms enable RIO-handling by default and maybe emitting the same behavior as this host. I didn't bother to search the RFCs for what is the correct behaviour in case identical RIOs and PIOs exist. Cheers, Steven ___ Dnsmasq-discuss mailing list Dnsmasq-discuss@lists.thekelleys.org.uk http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss
Re: [Dnsmasq-discuss] Adding Route Information Option to prefixes in RA
On 10/09/14 15:41, Steven Barth wrote: Since this should only happen when RIO and PIO are both /64 (and on-link flag is set for the PIO) my work-around in OpenWrt was to simply not send the RIO when PIO and RIO would be identical which solved the problem for the user. Obviously if RIO and PIO have different sizes this shouldn't matter. As a side note: since afaik Windows is about the only system to support and enable RIOs by default and Linux kernel-defaults are to ignore RIOs with prefix-length != 0 and Apple not implementing RIO support at all we could get in more trouble once more platforms enable RIO-handling by default and maybe emitting the same behavior as this host. I didn't bother to search the RFCs for what is the correct behaviour in case identical RIOs and PIOs exist. Focusing on the current dnsmasq code, I guess the take-home message here is that we're probably better off to revert the code which adds RIOs, for now, as the only RIOs we're sending are exactly the ones which Steven suggests should be suppressed. Should probably re-visit the issue of more general support for RIO in the next release. Is that reasonable? Cheers, Simon. ___ Dnsmasq-discuss mailing list Dnsmasq-discuss@lists.thekelleys.org.uk http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss