Skip to content

Commit fdeb8c7

Browse files
committed
DHCP6: Discard less preferred ADVERTISMENTs until IRT
If we get a preference value of 255 then request immediately. More RFC 8415 18.2.1 support, inspired by #376.
1 parent 2870767 commit fdeb8c7

File tree

1 file changed

+28
-17
lines changed

1 file changed

+28
-17
lines changed

src/dhcp6.c

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3302,7 +3302,7 @@ dhcp6_recvif(struct interface *ifp, const char *sfrom,
33023302
size_t i;
33033303
const char *op;
33043304
struct dhcp6_state *state;
3305-
uint8_t *o;
3305+
uint8_t *o, preference = 0;
33063306
uint16_t ol;
33073307
const struct dhcp_opt *opt;
33083308
const struct if_options *ifo;
@@ -3464,16 +3464,24 @@ dhcp6_recvif(struct interface *ifp, const char *sfrom,
34643464
valid_op = false;
34653465
break;
34663466
}
3467+
3468+
o = dhcp6_findmoption(r, len, D6_OPTION_PREFERENCE, &ol);
3469+
if (o && ol == sizeof(uint8_t))
3470+
preference = *o;
3471+
3472+
/* If we already have an advertisement check that this one
3473+
* has a higher preference value. */
34673474
if (state->recv_len && state->recv->type == DHCP6_ADVERTISE) {
3468-
/* We already have an advertismemnt.
3469-
* RFC 8415 says we have to wait for the IRT to elapse.
3470-
* To keep the same behaviour we won't do anything with
3471-
* this. In the future we should make a lists of
3472-
* ADVERTS and pick the "best" one. */
3473-
logdebugx("%s: discarding ADVERTISEMENT from %s",
3474-
ifp->name, sfrom);
3475-
return;
3475+
o = dhcp6_findmoption(state->recv, state->recv_len,
3476+
D6_OPTION_PREFERENCE, &ol);
3477+
if (o && ol == sizeof(uint8_t) && *o >= preference) {
3478+
logdebugx(
3479+
"%s: discarding ADVERTISEMENT from %s (%u)",
3480+
ifp->name, sfrom, preference);
3481+
return;
3482+
}
34763483
}
3484+
34773485
/* RFC7083 */
34783486
o = dhcp6_findmoption(r, len, D6_OPTION_SOL_MAX_RT, &ol);
34793487
if (o && ol == sizeof(uint32_t)) {
@@ -3592,16 +3600,19 @@ dhcp6_recvif(struct interface *ifp, const char *sfrom,
35923600
if (ia == NULL)
35933601
ia = TAILQ_FIRST(&state->addrs);
35943602
if (ia == NULL)
3595-
loginfox("%s: ADV (no address) from %s",
3596-
ifp->name, sfrom);
3603+
loginfox("%s: ADV (no address) from %s (%u)",
3604+
ifp->name, sfrom, preference);
35973605
else
3598-
loginfox("%s: ADV %s from %s",
3599-
ifp->name, ia->saddr, sfrom);
3600-
if (state->RTC > 1) {
3601-
// IRT already elapsed, initiate request
3606+
loginfox("%s: ADV %s from %s (%u)",
3607+
ifp->name, ia->saddr, sfrom, preference);
3608+
3609+
/*
3610+
* RFC 8415 18.2.1 says we must collect until ADVERTISEMENTs
3611+
* until we get one with a preference of 255 or
3612+
* the initial RT has elpased.
3613+
*/
3614+
if (preference == 255 || state->RTC > 1)
36023615
dhcp6_startrequest(ifp);
3603-
}
3604-
// We will request when the IRT elapses
36053616
return;
36063617
}
36073618

0 commit comments

Comments
 (0)