static void dhcp6_failinform(void *);
static void dhcp6_recvaddr(void *, unsigned short);
static void dhcp6_startdecline(struct interface *);
+static void dhcp6_startrequest(struct interface *);
#ifdef SMALL
#define dhcp6_hasprefixdelegation(a) (0)
dhcp6_sendmessage(arg, dhcp6_sendinform);
}
+static void
+dhcp6_senddiscover2(void *arg)
+{
+
+ dhcp6_sendmessage(arg, dhcp6_senddiscover2);
+}
+
+static void
+dhcp6_senddiscover1(void *arg)
+{
+ /*
+ * So the initial RT has elapsed.
+ * If we have any ADVERTs we can now REQUEST them.
+ * RFC 8415 15 and 18.2.1
+ */
+ struct interface *ifp = arg;
+ struct dhcp6_state *state = D6_STATE(ifp);
+
+ if (state->recv == NULL || state->recv->type != DHCP6_ADVERTISE)
+ dhcp6_sendmessage(arg, dhcp6_senddiscover2);
+ else
+ dhcp6_startrequest(ifp);
+}
+
static void
dhcp6_senddiscover(void *arg)
{
+ struct interface *ifp = arg;
+ struct dhcp6_state *state = D6_STATE(ifp);
- dhcp6_sendmessage(arg, dhcp6_senddiscover);
+ dhcp6_sendmessage(arg,
+ state->IMD != 0 ? dhcp6_senddiscover : dhcp6_senddiscover1);
}
static void
#endif
}
-
static void
dhcp6_startrequest(struct interface *ifp)
{
valid_op = false;
break;
}
+ if (state->recv_len && state->recv->type == DHCP6_ADVERTISE) {
+ /* We already have an advertismemnt.
+ * RFC 8415 says we have to wait for the IRT to elapse.
+ * To keep the same behaviour we won't do anything with
+ * this. In the future we should make a lists of
+ * ADVERTS and pick the "best" one. */
+ logdebugx("%s: discarding ADVERTISMENT from %s",
+ ifp->name, sfrom);
+ return;
+ }
/* RFC7083 */
o = dhcp6_findmoption(r, len, D6_OPTION_SOL_MAX_RT, &ol);
if (o && ol == sizeof(uint32_t)) {
else
loginfox("%s: ADV %s from %s",
ifp->name, ia->saddr, sfrom);
- dhcp6_startrequest(ifp);
+ // We will request when the IRT elapses
return;
}