Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dhcpv6 alternative address #12

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/dhcp-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
39 changes: 28 additions & 11 deletions src/rfc3315.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) */
Expand Down Expand Up @@ -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
Expand All @@ -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;
}
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
{
Expand Down