Handle DHCPREBIND requests in the DHCPv6 server.

Patch by srk, based on submitted patch from liaichun@huawei.com
This commit is contained in:
Simon Kelley
2021-04-09 15:19:28 +01:00
parent fe9c966a49
commit d55e2d086d
2 changed files with 48 additions and 18 deletions

View File

@@ -1,3 +1,9 @@
version 2.86
Handle DHCPREBIND requests in the DHCPv6 server code.
Thanks to Aichun Li for spotting this ommision, and the initial
patch.
version 2.85 version 2.85
Fix problem with DNS retries in 2.83/2.84. Fix problem with DNS retries in 2.83/2.84.
The new logic in 2.83/2.84 which merges distinct requests The new logic in 2.83/2.84 which merges distinct requests

View File

@@ -919,11 +919,14 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
case DHCP6RENEW: case DHCP6RENEW:
case DHCP6REBIND:
{ {
int address_assigned = 0;
/* set reply message type */ /* set reply message type */
*outmsgtypep = DHCP6REPLY; *outmsgtypep = DHCP6REPLY;
log6_quiet(state, "DHCPRENEW", NULL, NULL); log6_quiet(state, msg_type == DHCP6RENEW ? "DHCPRENEW" : "DHCPREBIND", NULL, NULL);
for (opt = state->packet_options; opt; opt = opt6_next(opt, state->end)) for (opt = state->packet_options; opt; opt = opt6_next(opt, state->end))
{ {
@@ -952,24 +955,35 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA, state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA,
state->iaid, &req_addr))) state->iaid, &req_addr)))
{ {
/* If the server cannot find a client entry for the IA the server if (msg_type == DHCP6REBIND)
returns the IA containing no addresses with a Status Code option set {
to NoBinding in the Reply message. */ /* When rebinding, we can create a lease if it doesn't exist. */
save_counter(iacntr); lease = lease6_allocate(&req_addr, state->ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA);
t1cntr = 0; if (lease)
lease_set_iaid(lease, state->iaid);
log6_packet(state, "DHCPREPLY", &req_addr, _("lease not found")); else
break;
o1 = new_opt6(OPTION6_STATUS_CODE); }
put_opt6_short(DHCP6NOBINDING); else
put_opt6_string(_("no binding found")); {
end_opt6(o1); /* If the server cannot find a client entry for the IA the server
returns the IA containing no addresses with a Status Code option set
preferred_time = valid_time = 0; to NoBinding in the Reply message. */
break; save_counter(iacntr);
t1cntr = 0;
log6_packet(state, "DHCPREPLY", &req_addr, _("lease not found"));
o1 = new_opt6(OPTION6_STATUS_CODE);
put_opt6_short(DHCP6NOBINDING);
put_opt6_string(_("no binding found"));
end_opt6(o1);
preferred_time = valid_time = 0;
break;
}
} }
if ((this_context = address6_available(state->context, &req_addr, tagif, 1)) || if ((this_context = address6_available(state->context, &req_addr, tagif, 1)) ||
(this_context = address6_valid(state->context, &req_addr, tagif, 1))) (this_context = address6_valid(state->context, &req_addr, tagif, 1)))
{ {
@@ -1000,6 +1014,8 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
if (preferred_time == 0) if (preferred_time == 0)
message = _("deprecated"); message = _("deprecated");
address_assigned = 1;
} }
else else
{ {
@@ -1022,10 +1038,18 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
end_ia(t1cntr, min_time, 1); end_ia(t1cntr, min_time, 1);
end_opt6(o); end_opt6(o);
} }
if (!address_assigned && msg_type == DHCP6REBIND)
{
/* can't create lease for any address, return error */
o1 = new_opt6(OPTION6_STATUS_CODE);
put_opt6_short(DHCP6NOADDRS);
put_opt6_string(_("no addresses available"));
end_opt6(o1);
}
tagif = add_options(state, 0); tagif = add_options(state, 0);
break; break;
} }
case DHCP6CONFIRM: case DHCP6CONFIRM: