summaryrefslogtreecommitdiff
path: root/dnsmasq-2.86-alternative-lease.patch
diff options
context:
space:
mode:
Diffstat (limited to 'dnsmasq-2.86-alternative-lease.patch')
-rw-r--r--dnsmasq-2.86-alternative-lease.patch107
1 files changed, 107 insertions, 0 deletions
diff --git a/dnsmasq-2.86-alternative-lease.patch b/dnsmasq-2.86-alternative-lease.patch
new file mode 100644
index 0000000..e51d2b3
--- /dev/null
+++ b/dnsmasq-2.86-alternative-lease.patch
@@ -0,0 +1,107 @@
+From 268080fc19990711a1d1e1acd68a50aa2f6cb5fb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
+Date: Fri, 17 Sep 2021 20:12:21 +0200
+Subject: [PATCH] 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 5c2ff97..d1534ad 100644
+--- a/src/rfc3315.c
++++ b/src/rfc3315.c
+@@ -614,7 +614,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+
+ 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;
+@@ -697,6 +697,8 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+ get_context_tag(state, c);
+ address_assigned = 1;
+ }
++ else
++ ia_invalid++;
+ }
+
+ /* Suggest configured address(es) */
+@@ -782,11 +784,26 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+ 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
+@@ -795,7 +812,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+ 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;
+ }
+ }
+@@ -831,7 +848,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+ /* 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);
+@@ -861,11 +878,11 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
+ }
+ 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.31.1
+