From: Roy Marples Date: Tue, 12 Nov 2013 17:30:43 +0000 (+0000) Subject: Implement RFC4242, Information Refresh Time Option for DHCPv6. X-Git-Tag: v6.2.0~56 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3985931e451e9a3ddac4e58c65f76c9f0ebaa3be;p=thirdparty%2Fdhcpcd.git Implement RFC4242, Information Refresh Time Option for DHCPv6. --- diff --git a/dhcp6.c b/dhcp6.c index 196529f0..a562b734 100644 --- a/dhcp6.c +++ b/dhcp6.c @@ -1091,10 +1091,12 @@ dhcp6_startconfirm(struct interface *ifp) } static void -dhcp6_startinform(struct interface *ifp) +dhcp6_startinform(void *arg) { + struct interface *ifp; struct dhcp6_state *state; + ifp = arg; state = D6_STATE(ifp); if (state->new == NULL || ifp->options->options & DHCPCD_DEBUG) syslog(LOG_INFO, "%s: requesting DHCPv6 information", @@ -1975,6 +1977,7 @@ dhcp6_handledata(__unused void *arg) struct ipv6_addr *ap; uint8_t has_new; int error; + uint32_t u32; len = recvmsg(sock, &rcvhdr, 0); if (len == -1) { @@ -2077,9 +2080,20 @@ dhcp6_handledata(__unused void *arg) op = dhcp6_get_op(r->type); switch(r->type) { case DHCP6_REPLY: - if (state->state == DH6S_INFORM) - break; switch(state->state) { + case DH6S_INFORM: + /* RFC4242 */ + o = dhcp6_getoption(D6_OPTION_INFO_REFRESH_TIME, + r, len); + if (o == NULL || ntohs(o->len) != sizeof(u32)) + state->renew = IRT_DEFAULT; + else { + memcpy(&u32, D6_COPTION_DATA(o), sizeof(u32)); + state->renew = ntohl(u32); + if (state->renew < IRT_MINIMUM) + state->renew = IRT_MINIMUM; + } + break; case DH6S_CONFIRM: error = dhcp6_checkstatusok(ifp, r, NULL, len); /* If we got an OK status the chances are that we @@ -2095,7 +2109,7 @@ dhcp6_handledata(__unused void *arg) break; case DH6S_DISCOVER: if (has_option_mask(ifo->requestmask6, - D6_OPTION_RAPID_COMMIT) && + D6_OPTION_RAPID_COMMIT) && dhcp6_getoption(D6_OPTION_RAPID_COMMIT, r, len)) state->state = DH6S_REQUEST; else @@ -2172,7 +2186,6 @@ recv: eloop_timeout_delete(NULL, ifp); switch(state->state) { case DH6S_INFORM: - state->renew = 0; state->rebind = 0; state->expire = ND6_INFINITE_LIFETIME; state->lowpl = ND6_INFINITE_LIFETIME; @@ -2189,6 +2202,7 @@ recv: case DH6S_REBIND: if (state->reason == NULL) state->reason = "REBIND6"; + /* FALLTHROUGH */ case DH6S_CONFIRM: if (state->reason == NULL) state->reason = "REBOOT6"; @@ -2229,7 +2243,8 @@ recv: state->state = DH6S_BOUND; if (state->renew && state->renew != ND6_INFINITE_LIFETIME) eloop_timeout_add_sec(state->renew, - dhcp6_startrenew, ifp); + state->state == DH6S_INFORMED ? + dhcp6_startinform : dhcp6_startrenew, ifp); if (state->rebind && state->rebind != ND6_INFINITE_LIFETIME) eloop_timeout_add_sec(state->rebind, dhcp6_startrebind, ifp); @@ -2239,7 +2254,11 @@ recv: if (ifp->options->ia_type == D6_OPTION_IA_PD) dhcp6_delegate_prefix(ifp); ipv6nd_probeaddrs(&state->addrs); - if (state->renew || state->rebind) + if (state->state == DH6S_INFORMED) + syslog(has_new ? LOG_INFO : LOG_DEBUG, + "%s: refresh in %"PRIu32" seconds", + ifp->name, state->renew); + else if (state->renew || state->rebind) syslog(has_new ? LOG_INFO : LOG_DEBUG, "%s: renew in %"PRIu32" seconds," " rebind in %"PRIu32" seconds", @@ -2364,10 +2383,13 @@ dhcp6_start1(void *arg) add_option_mask(ifo->requestmask6, D6_OPTION_FQDN); } - if (state->state == DH6S_INFORM) + if (state->state == DH6S_INFORM) { + add_option_mask(ifo->requestmask6, D6_OPTION_INFO_REFRESH_TIME); dhcp6_startinform(ifp); - else + } else { + del_option_mask(ifo->requestmask6, D6_OPTION_INFO_REFRESH_TIME); dhcp6_startinit(ifp); + } } int diff --git a/dhcp6.h b/dhcp6.h index 8df68a7c..9cdc56f6 100644 --- a/dhcp6.h +++ b/dhcp6.h @@ -142,6 +142,10 @@ struct dhcp6_status { #define REC_MAX_RC 8 #define HOP_COUNT_LIMIT 32 +/* RFC4242 3.1 */ +#define IRT_DEFAULT 86400 +#define IRT_MINIMUM 600 + #define DHCP6_RAND_MIN -100 #define DHCP6_RAND_MAX 100 diff --git a/dhcpcd.8.in b/dhcpcd.8.in index 8edd662b..f491e372 100644 --- a/dhcpcd.8.in +++ b/dhcpcd.8.in @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd September 12, 2013 +.Dd November 12, 2013 .Dt DHCPCD 8 .Os .Sh NAME @@ -646,9 +646,9 @@ running on the .Xr resolvconf 8 .Sh STANDARDS RFC\ 951 RFC\ 1534 RFC\ 2131, RFC\ 2132, RFC\ 2855, RFC\ 3004, RFC\ 3315, -RFC\ 3361, RFC\ 3633, RFC\ 3396, RFC\ 3397, RFC\ 3442, RFC\ 3927, RFC\ 4039 -RFC\ 4075, RFC\ 4361, RFC\ 4390, RFC\ 4702, RFC\ 4704, RFC\ 4861, RFC\ 4833, -RFC\ 5227, RFC\ 5942, RFC\ 5969, RFC\ 6106. +RFC\ 3361, RFC\ 3633, RFC\ 3396, RFC\ 3397, RFC\ 3442, RFC\ 3927, RFC\ 4039, +RFC\ 4075, RFC\ 4242, RFC\ 4361, RFC\ 4390, RFC\ 4702, RFC\ 4704, RFC\ 4861, +RFC\ 4833, RFC\ 5227, RFC\ 5942, RFC\ 5969, RFC\ 6106. .Sh AUTHORS .An Roy Marples Aq Mt roy@marples.name .Sh BUGS