Hello, On Wed, Sep 28, 2016, at 08:57, Maciej Żenczykowski wrote: > From: Maciej Żenczykowski <m...@google.com> > > This implements: > https://tools.ietf.org/html/rfc7559 > > Backoff is performed according to RFC3315 section 14: > https://tools.ietf.org/html/rfc3315#section-14 > > We allow setting /proc/sys/net/ipv6/conf/*/router_solicitations > to a negative value meaning an unlimited number of retransmits, > and we make this the new default (inline with the RFC). > > We also add a new setting: > /proc/sys/net/ipv6/conf/*/router_solicitation_max_interval > defaulting to 1 hour (per RFC recommendation). > > Signed-off-by: Maciej Żenczykowski <m...@google.com> > --- > include/linux/ipv6.h | 1 + > include/net/addrconf.h | 3 ++- > include/net/if_inet6.h | 1 + > include/uapi/linux/ipv6.h | 1 + > net/ipv6/addrconf.c | 51 > ++++++++++++++++++++++++++++++++++++++++------- > 5 files changed, 49 insertions(+), 8 deletions(-) > > diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h > index c6dbcd84a2c7..7e9a789be5e0 100644 > --- a/include/linux/ipv6.h > +++ b/include/linux/ipv6.h > @@ -18,6 +18,7 @@ struct ipv6_devconf { > __s32 dad_transmits; > __s32 rtr_solicits; > __s32 rtr_solicit_interval; > + __s32 rtr_solicit_max_interval; > __s32 rtr_solicit_delay; > __s32 force_mld_version; > __s32 mldv1_unsolicited_report_interval; > diff --git a/include/net/addrconf.h b/include/net/addrconf.h > index 9826d3a9464c..f2d072787947 100644 > --- a/include/net/addrconf.h > +++ b/include/net/addrconf.h > @@ -1,8 +1,9 @@ > #ifndef _ADDRCONF_H > #define _ADDRCONF_H > > -#define MAX_RTR_SOLICITATIONS 3 > +#define MAX_RTR_SOLICITATIONS -1 /* unlimited */ > #define RTR_SOLICITATION_INTERVAL (4*HZ) > +#define RTR_SOLICITATION_MAX_INTERVAL (3600*HZ) /* 1 hour */ > > #define MIN_VALID_LIFETIME (2*3600) /* 2 hours */ > > diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h > index 1c8b6820b694..515352c6280a 100644 > --- a/include/net/if_inet6.h > +++ b/include/net/if_inet6.h > @@ -201,6 +201,7 @@ struct inet6_dev { > struct ipv6_devstat stats; > > struct timer_list rs_timer; > + __s32 rs_interval; /* in jiffies */ > __u8 rs_probes; > > __u8 addr_gen_mode; > diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h > index 395876060f50..8c2772340c3f 100644 > --- a/include/uapi/linux/ipv6.h > +++ b/include/uapi/linux/ipv6.h > @@ -177,6 +177,7 @@ enum { > DEVCONF_DROP_UNICAST_IN_L2_MULTICAST, > DEVCONF_DROP_UNSOLICITED_NA, > DEVCONF_KEEP_ADDR_ON_DOWN, > + DEVCONF_RTR_SOLICIT_MAX_INTERVAL, > DEVCONF_MAX > }; > > diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c > index 2f1f5d439788..49bee9bc5ff3 100644 > --- a/net/ipv6/addrconf.c > +++ b/net/ipv6/addrconf.c > @@ -112,6 +112,27 @@ static inline u32 cstamp_delta(unsigned long cstamp) > return (cstamp - INITIAL_JIFFIES) * 100UL / HZ; > } > > +static inline s32 rfc3315_s14_backoff_init(s32 irt) > +{ > + /* multiply 'initial retransmission time' by 0.9 .. 1.1 */ > + u64 tmp = (900000 + prandom_u32() % 200001) * (u64)irt; > + do_div(tmp, 1000000); > + return (s32)tmp; > +} > + > +static inline s32 rfc3315_s14_backoff_update(s32 rt, s32 mrt) > +{ > + /* multiply 'retransmission timeout' by 1.9 .. 2.1 */ > + u64 tmp = (1900000 + prandom_u32() % 200001) * (u64)rt; > + do_div(tmp, 1000000); > + if ((s32)tmp > mrt) { > + /* multiply 'maximum retransmission time' by 0.9 .. 1.1 > */ > + tmp = (900000 + prandom_u32() % 200001) * (u64)mrt; > + do_div(tmp, 1000000);
Could you use msecs_to_jiffies here to make the units more clear like I proposed in the last mail? Or is there a reason not to? Bye, Hannes