summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Dedecker2020-03-28 19:47:18 +0000
committerHans Dedecker2020-03-28 19:57:25 +0000
commitf575351cbb3defc0bf52680c9082912a6c264374 (patch)
treea9148e4a8c28455d989c753d40e161471fe2f853
parent49305e6847efa43e008d0bebdc176e1833120947 (diff)
downloadodhcp6c-f575351cbb3defc0bf52680c9082912a6c264374.tar.gz
ra: fix sending router solicitations
Only stop sending router solicitations when a RA is received with a valid router lifetime as specified in RFC4861 §6.3.7 Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
-rw-r--r--src/ra.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/src/ra.c b/src/ra.c
index 898f449..337c0bd 100644
--- a/src/ra.c
+++ b/src/ra.c
@@ -377,6 +377,9 @@ bool ra_process(void)
.msg_controllen = sizeof(cmsg_buf),
.msg_flags = 0
};
+ struct icmpv6_opt *opt;
+ uint32_t router_valid;
+ int hlim = 0;
ssize_t len = recvmsg(sock, &msg, MSG_DONTWAIT);
if (len <= 0)
@@ -385,7 +388,6 @@ bool ra_process(void)
if (IN6_IS_ADDR_UNSPECIFIED(&lladdr))
continue;
- int hlim = 0;
for (struct cmsghdr *ch = CMSG_FIRSTHDR(&msg); ch != NULL;
ch = CMSG_NXTHDR(&msg, ch))
if (ch->cmsg_level == IPPROTO_IPV6 &&
@@ -395,17 +397,24 @@ bool ra_process(void)
if (!ra_icmpv6_valid(&from, hlim, buf, len))
continue;
- // Stop sending solicits
- if (rs_attempt > 0) {
- alarm(0);
- rs_attempt = 0;
- }
-
if (!found) {
odhcp6c_expire();
found = true;
}
- uint32_t router_valid = ntohs(adv->nd_ra_router_lifetime);
+
+ router_valid = ntohs(adv->nd_ra_router_lifetime);
+
+ /* RFC4861 §6.3.7
+ * Once the host sends a Router Solicitation, and receives a valid
+ * Router Advertisement with a non-zero Router Lifetime, the host MUST
+ * desist from sending additional solicitations on that interface
+ * Moreover, a host SHOULD send at least one solicitation in the case
+ * where an advertisement is received prior to having sent a solicitation.
+ */
+ if (rs_attempt > 0 && router_valid > 0) {
+ alarm(0);
+ rs_attempt = 0;
+ }
// Parse default route
entry->target = any;
@@ -428,7 +437,6 @@ bool ra_process(void)
changed |= ra_set_retransmit(ntohl(adv->nd_ra_retransmit));
// Evaluate options
- struct icmpv6_opt *opt;
icmpv6_for_each_option(opt, &adv[1], &buf[len]) {
if (opt->type == ND_OPT_MTU) {
uint32_t *mtu = (uint32_t*)&opt->data[2];