Hi,
I am attaching a change, which has been part of RHEL/CentOS Stream 9 for
some while [1]. It fixes the problem with DHCPv6 only requests, which on
some situations fail to provide an address. This change is older than
related change, which attempted to solve similar issue on IPv4 too. It
works by offering a different (free) IPv6 address to client, than he
originally asked for. It is a simple change, but tested clients worked
with it. Accompanied by related change to add client-arch tag support
also for DHCPv6 [2]. It were created to solve rh bug #2002871 [3], of
which most of communication is unfortunately RH internal only. Parent
bug [4] has a bit more background visible to public. But no regressions
were reported after this change and it has improved a situation in
openstack. I haven't found my attempt to offer it here, but maybe I just
failed my search. If it were refused already, kindly point me to correct
thread. It improves iPXE booting of multiple machines on the same host
concurrently.
Cheers,
Petr
1.
https://gitlab.com/redhat/centos-stream/rpms/dnsmasq/-/blob/c9s/dnsmasq-2.86-alternative-lease.patch
2.
https://gitlab.com/redhat/centos-stream/rpms/dnsmasq/-/blob/c9s/dnsmasq-2.86-dhcpv6-client-arch.patch
3. https://bugzilla.redhat.com/show_bug.cgi?id=2002871
4. https://bugzilla.redhat.com/show_bug.cgi?id=1998448
--
Petr Menšík
Software Engineer, RHEL
Red Hat, http://www.redhat.com/
PGP: DFCF908DB7C87E8E529925BC4931CA5B6C9FC5CB
From 21b92ff46aa887da6f2eb85e5cf39253deb61d80 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemen...@redhat.com>
Date: Wed, 22 Sep 2021 14:54:01 +0200
Subject: [PATCH 2/2] Add support for option6 names of RFC 5970
Client Network Interface Identifier and Client System Architecture Type
options were not understood by dnsmasq. Add it to supported option
types.
---
src/dhcp-common.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/dhcp-common.c b/src/dhcp-common.c
index bc6d95e..ca0f967 100644
--- a/src/dhcp-common.c
+++ b/src/dhcp-common.c
@@ -725,6 +725,8 @@ static const struct opttab_t opttab6[] = {
{ "ntp-server", 56, 0 /* OT_ADDR_LIST | OT_RFC1035_NAME */ },
{ "bootfile-url", 59, OT_NAME },
{ "bootfile-param", 60, OT_CSTRING },
+ { "client-arch", 61, 2 | OT_DEC }, /* RFC 5970 */
+ { "client-interface-id", 62, 1 | OT_DEC }, /* RFC 5970 */
{ NULL, 0, 0 }
};
#endif
--
2.37.3
From 6fea19991eba45bf72c10fa30516d6d58f22cf47 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemen...@redhat.com>
Date: Fri, 17 Sep 2021 20:12:21 +0200
Subject: [PATCH 1/2] Offer alternative DHCPv6 address if requested is taken
In some cases multiple requests might arrive from single DUID. It may
happen just one address is offered to different IAID requests. When
the first request confirms lease, another would be offered alternative
address instead of address in use error.
Includes check on such Rapid commit equivalents and returns NotOnLink
error, required by RFC 8145, if requested address were not on any
supported prefix.
---
src/rfc3315.c | 39 ++++++++++++++++++++++++++++-----------
1 file changed, 28 insertions(+), 11 deletions(-)
diff --git a/src/rfc3315.c b/src/rfc3315.c
index 8754481..bd7c40f 100644
--- a/src/rfc3315.c
+++ b/src/rfc3315.c
@@ -615,7 +615,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu
case DHCP6SOLICIT:
{
- int address_assigned = 0;
+ int address_assigned = 0, ia_invalid = 0;
/* tags without all prefix-class tags */
struct dhcp_netid *solicit_tags;
struct dhcp_context *c;
@@ -698,6 +698,8 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu
get_context_tag(state, c);
address_assigned = 1;
}
+ else
+ ia_invalid++;
}
/* Suggest configured address(es) */
@@ -783,11 +785,26 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu
tagif = add_options(state, 0);
}
else
- {
+ {
+ char *errmsg;
/* no address, return error */
o1 = new_opt6(OPTION6_STATUS_CODE);
- put_opt6_short(DHCP6NOADDRS);
- put_opt6_string(_("no addresses available"));
+ if (state->lease_allocate && ia_invalid)
+ {
+ /* RFC 8415, Section 18.3.2:
+ If any of the prefixes of the included addresses are not
+ appropriate for the link to which the client is connected,
+ the server MUST return the IA to the client with a Status
+ Code option with the value NotOnLink. */
+ put_opt6_short(DHCP6NOTONLINK);
+ errmsg = _("not on link");
+ }
+ else
+ {
+ put_opt6_short(DHCP6NOADDRS);
+ errmsg = _("no addresses available");
+ }
+ put_opt6_string(errmsg);
end_opt6(o1);
/* Some clients will ask repeatedly when we're not giving
@@ -796,7 +813,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu
for (c = state->context; c; c = c->current)
if (!(c->flags & CONTEXT_RA_STATELESS))
{
- log6_packet(state, state->lease_allocate ? "DHCPREPLY" : "DHCPADVERTISE", NULL, _("no addresses available"));
+ log6_packet(state, state->lease_allocate ? "DHCPREPLY" : "DHCPADVERTISE", NULL, errmsg);
break;
}
}
@@ -832,7 +849,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu
/* If we get a request with an IA_*A without addresses, treat it exactly like
a SOLICT with rapid commit set. */
save_counter(start);
- goto request_no_address;
+ goto request_no_address;
}
o = build_ia(state, &t1cntr);
@@ -862,11 +879,11 @@ static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbu
}
else if (!check_address(state, &req_addr))
{
- /* Address leased to another DUID/IAID */
- o1 = new_opt6(OPTION6_STATUS_CODE);
- put_opt6_short(DHCP6UNSPEC);
- put_opt6_string(_("address in use"));
- end_opt6(o1);
+ /* Address leased to another DUID/IAID.
+ Find another address for the client, treat it exactly like
+ a SOLICT with rapid commit set. */
+ save_counter(start);
+ goto request_no_address;
}
else
{
--
2.37.3
_______________________________________________
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss