On 9/16/21 21:32, Petr Menšík wrote:
Hi!

There is also bug on Red Hat bugzilla [1] for this issue, which contains
a bit more comments about it.

I would make short summary here. The problem is client on the same
machine with the same DUID and mac address requests IPv6. Before it
processes Advertisement, it requests IPv6 again, this time with
different IAID.

So there are two different request, the only difference are IAID and
requested options set. Now if the second request gets processed first,
it assigns lease first. Consider --dhcp-sequential-ip is in use.
Then first request processes advertisement and attempts to request the
same IP.
Now it would fail.

How should it react according to RFC 8415 [2]? In current situation,
dnsmasq responds with No address available error. Could it instead
respond with different address? How should the server and the client
behave, when advertised address is no longer available? Is it broken on
both sides?

I think Petr may be on to something with "Could it instead respond with a different address?". It seems this is ok based on rfc8415 18.3.2 [1] which states the following:
"""
   The server MAY assign different addresses and/or delegated prefixes
   to an IA than those included within the IA of the client's Request
   message.
"""

With the below patch I got dnsmasq to reply with a new address to the request with the already leased address. This makes dnsmasq behave similar to kea-dhcp6, see Bugzilla comments #36 and #41 [2][3] which also contain a pcap files.

I tested this with both static and dynamic configuration, "sequential-ip" enabled, and it seems to work.

If I change the 'dhcp-host' entry in the static config to contain just *one* address, it fails as expected with: option: 13 status 2 address unavailable
  option: 13 status  2 no addresses available


I tested with the following configurations ...

Static config:
--------------
log-dhcp
port=0
dhcp-range=set:range0,2001::,static,64,10m
dhcp-host=00:84:ed:01:00:10,tag:dhcpv6,client.localdomain,[2001::20],[2001::21],[2001::22],[2001::23]
dhcp-sequential-ip
# dhcpv6s for Client System Architecture Type (61)
dhcp-match=set:efi6,option6:61,0007
dhcp-match=set:efi6,option6:61,0009
dhcp-match=set:efi6,option6:61,0011
dhcp-option=tag:efi6,option6:bootfile-url,tftp://[2001::2]/shimx64.efi

Dynamic config with sequential-ip:
---------------------------------
log-dhcp
port=0

dhcp-range=set:range0,2001::10,2001::100,64,10m
dhcp-sequential-ip
# dhcpv6s for Client System Architecture Type (61)
dhcp-match=set:efi6,option6:61,0007
dhcp-match=set:efi6,option6:61,0009
dhcp-match=set:efi6,option6:61,0011
dhcp-option=tag:efi6,option6:bootfile-url,tftp://[2001::2]/shimx64.efi



Regards,
Harald

[1] https://datatracker.ietf.org/doc/html/rfc8415#section-18.3.2
[2] https://bugzilla.redhat.com/show_bug.cgi?id=1998448#c36
[3] https://bugzilla.redhat.com/show_bug.cgi?id=1998448#c41
diff --git a/src/rfc3315.c b/src/rfc3315.c
index 5c2ff97..7c218f7 100644
--- a/src/rfc3315.c
+++ b/src/rfc3315.c
@@ -847,7 +847,16 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
 		memcpy(&req_addr, opt6_ptr(ia_option, 0), IN6ADDRSZ);
 		
 		if ((c = address6_valid(state->context, &req_addr, tagif, 1)))
-		  config_ok = (config_implies(config, c, &req_addr) != NULL);
+		  if (check_address(state, &req_addr)) {
+		    config_ok = (config_implies(config, c, &req_addr) != NULL);
+		  }
+		  else {
+			/* If the address is already leased to another DUID/IAID, treat it like
+			   a SOLICIT with rapid commit set. I.e try to assign a different address
+			   if available. */
+			 save_counter(start);
+			 goto request_no_address;
+		  }
 		
 		if ((dynamic = address6_available(state->context, &req_addr, tagif, 1)) || c)
 		  {
_______________________________________________
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss

Reply via email to