From: Roy Marples Date: Sat, 3 May 2014 19:53:22 +0000 (+0000) Subject: Respect RFC4861 MAX_RTR_SOLICITATION_DELAY as specified in section 6.3.7. X-Git-Tag: v6.4.0~69 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6e6e06af143ff0533ee481852a7b28e67bfd9eae;p=thirdparty%2Fdhcpcd.git Respect RFC4861 MAX_RTR_SOLICITATION_DELAY as specified in section 6.3.7. --- diff --git a/ipv6nd.c b/ipv6nd.c index 09b7ccc2..fade521a 100644 --- a/ipv6nd.c +++ b/ipv6nd.c @@ -1494,15 +1494,17 @@ ipv6nd_handledata(void *arg) icp->icmp6_type, icp->icmp6_code, ctx->sfrom); } -int -ipv6nd_startrs(struct interface *ifp) +static int +ipv6nd_startrs1(void *arg) { + struct interface *ifp = arg; struct rs_state *state; + struct timeval tv; syslog(LOG_INFO, "%s: soliciting an IPv6 router", ifp->name); if (ipv6nd_open(ifp->ctx) == -1) { syslog(LOG_ERR, "%s: ipv6nd_open: %m", __func__); - return -1; + return; } eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); @@ -1513,7 +1515,7 @@ ipv6nd_startrs(struct interface *ifp) state = RS_STATE(ifp); if (state == NULL) { syslog(LOG_ERR, "%s: %m", __func__); - return -1; + return; } } @@ -1522,10 +1524,25 @@ ipv6nd_startrs(struct interface *ifp) ipv6nd_makersprobe(ifp); if (state->rs == NULL) { syslog(LOG_ERR, "%s: ipv6ns_makersprobe: %m", __func__); - return -1; + return; } state->rsprobes = 0; ipv6nd_sendrsprobe(ifp); - return 0; +} + +void +ipv6nd_startrs(struct interface *ifp) +{ + struct timeval tv; + + tv.tv_sec = 0; + tv.tv_usec = (suseconds_t)(arc4random() % + (MAX_RTR_SOLICITATION_DELAY * 1000000)); + timernorm(&tv); + syslog(LOG_DEBUG, + "%s: delaying IPv6 router solictation for %0.1f seconds", + ifp->name, timeval_to_double(&tv)); + eloop_timeout_add_tv(ifp->ctx->eloop, &tv, ipv6nd_startrs1, ifp); + return; } diff --git a/ipv6nd.h b/ipv6nd.h index a5eff3be..8c606919 100644 --- a/ipv6nd.h +++ b/ipv6nd.h @@ -75,15 +75,16 @@ struct rs_state { #define RS_STATE(a) ((struct rs_state *)(ifp)->if_data[IF_DATA_IPV6ND]) -#define MAX_UNICAST_SOLICIT 3 /* 3 transmissions */ +#define MAX_RTR_SOLICITATION_DELAY 1 /* seconds */ +#define MAX_UNICAST_SOLICIT 3 /* 3 transmissions */ -#define MAX_REACHABLE_TIME 3600000 /* milliseconds */ -#define REACHABLE_TIME 30000 /* milliseconds */ -#define RETRANS_TIMER 1000 /* milliseconds */ -#define DELAY_FIRST_PROBE_TIME 5 /* seconds */ +#define MAX_REACHABLE_TIME 3600000 /* milliseconds */ +#define REACHABLE_TIME 30000 /* milliseconds */ +#define RETRANS_TIMER 1000 /* milliseconds */ +#define DELAY_FIRST_PROBE_TIME 5 /* seconds */ #ifdef INET6 -int ipv6nd_startrs(struct interface *); +void ipv6nd_startrs(struct interface *); ssize_t ipv6nd_env(char **, const char *, const struct interface *); int ipv6nd_addrexists(struct dhcpcd_ctx *, const struct ipv6_addr *); void ipv6nd_freedrop_ra(struct ra *, int);