]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Implement RFC4242, Information Refresh Time Option for DHCPv6.
authorRoy Marples <roy@marples.name>
Tue, 12 Nov 2013 17:30:43 +0000 (17:30 +0000)
committerRoy Marples <roy@marples.name>
Tue, 12 Nov 2013 17:30:43 +0000 (17:30 +0000)
dhcp6.c
dhcp6.h
dhcpcd.8.in

diff --git a/dhcp6.c b/dhcp6.c
index 196529f0a0b72be3e100f6803f97bcba4ba05c2a..a562b73495ad1157de4f87883205bd9ea310674d 100644 (file)
--- 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 8df68a7ccabacd9e7ff88a95e9b199077ab89a61..9cdc56f6d42de415735034d15bcf9ed5e6e35ddd 100644 (file)
--- 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
 
index 8edd662b2d3b3292ec93ff354338eed799ab1d5c..f491e3720fc93b873c0446e8e826c32a09149e8d 100644 (file)
@@ -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