* Re: [PATCH] Temporary IPv6 address asignment [not found] ` <20090503.144758.222061423.davem@davemloft.net> @ 2009-05-03 22:20 ` Lukasz Stelmach 2009-05-03 22:34 ` David Miller 0 siblings, 1 reply; 7+ messages in thread From: Lukasz Stelmach @ 2009-05-03 22:20 UTC (permalink / raw) To: linux-kernel; +Cc: David Miller, yoshfuji, netdev [-- Attachment #1: Type: text/plain, Size: 12600 bytes --] -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 David Miller pisze: > From: Lukasz Stelmach <stlman@poczta.fm> > Date: Sun, 03 May 2009 23:45:30 +0200 > >> -----BEGIN PGP SIGNED MESSAGE----- >> Hash: SHA1 >> >> Greetings. >> >> I discovered recently and fixed some problems with IPv6 temporary >> address asignment. I have described the problem at >> http://bugzilla.kernel.org as bugs #13208 and #13221. >> >> http://bugzilla.kernel.org/show_bug.cgi?id=13208 >> http://bugzilla.kernel.org/show_bug.cgi?id=13221 >> >> The patch is available at: >> >> http://bugzilla.kernel.org/attachment.cgi?id=21201 > > Nobody is going to look at this unless you post the patch > with description and proper signoffs with netdev@vger.kernel.org > CC:'d The description is in the patch, and a sign-off too. But all righ. - -----CUT HERE----- A fixed mechanism to create and recreate temporary addresses, even for very short preferred lifetimes. A new RFC-compliant DESYNC_FACTOR implemented as a sysctl variable desync_factor which is assigned a random value each time max_desync_factor is written to. Each interface has its own desync_factor and max_desync_factor. Writes to default/max_desync_factor influence only default values. Writes to all/max_desync_factor influence "all" and default values but not values of running interfaces. The patch fixes issues described in bugs #13208 and #13221 at http://bugzilla.kernel.org. Signed-off-by: Łukasz Stelmach <stlman@poczta.fm> diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 476d946..fa45ad2 100644 - --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -146,6 +146,7 @@ struct ipv6_devconf { __s32 temp_prefered_lft; __s32 regen_max_retry; __s32 max_desync_factor; + __s32 desync_factor; #endif __s32 max_addresses; __s32 accept_ra_defrtr; @@ -188,6 +189,7 @@ enum { DEVCONF_TEMP_PREFERED_LFT, DEVCONF_REGEN_MAX_RETRY, DEVCONF_MAX_DESYNC_FACTOR, + DEVCONF_DESYNC_FACTOR, DEVCONF_MAX_ADDRESSES, DEVCONF_FORCE_MLD_VERSION, DEVCONF_ACCEPT_RA_DEFRTR, diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index e76d3b2..951ba2c 100644 - --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -570,15 +570,16 @@ enum { NET_IPV6_TEMP_PREFERED_LFT=13, NET_IPV6_REGEN_MAX_RETRY=14, NET_IPV6_MAX_DESYNC_FACTOR=15, - - NET_IPV6_MAX_ADDRESSES=16, - - NET_IPV6_FORCE_MLD_VERSION=17, - - NET_IPV6_ACCEPT_RA_DEFRTR=18, - - NET_IPV6_ACCEPT_RA_PINFO=19, - - NET_IPV6_ACCEPT_RA_RTR_PREF=20, - - NET_IPV6_RTR_PROBE_INTERVAL=21, - - NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, - - NET_IPV6_PROXY_NDP=23, - - NET_IPV6_ACCEPT_SOURCE_ROUTE=25, + NET_IPV6_DESYNC_FACTOR=16, + NET_IPV6_MAX_ADDRESSES=17, + NET_IPV6_FORCE_MLD_VERSION=18, + NET_IPV6_ACCEPT_RA_DEFRTR=19, + NET_IPV6_ACCEPT_RA_PINFO=20, + NET_IPV6_ACCEPT_RA_RTR_PREF=21, + NET_IPV6_RTR_PROBE_INTERVAL=22, + NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=23, + NET_IPV6_PROXY_NDP=24, + NET_IPV6_ACCEPT_SOURCE_ROUTE=26, __NET_IPV6_MAX }; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index a8218bc..1b746ee 100644 - --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -116,8 +116,6 @@ static inline void addrconf_sysctl_unregister(struct inet6_dev *idev) static int __ipv6_regen_rndid(struct inet6_dev *idev); static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr); static void ipv6_regen_rndid(unsigned long data); - - - -static int desync_factor = MAX_DESYNC_FACTOR * HZ; #endif static int ipv6_generate_eui64(u8 *eui, struct net_device *dev); @@ -172,6 +170,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = { .temp_prefered_lft = TEMP_PREFERRED_LIFETIME, .regen_max_retry = REGEN_MAX_RETRY, .max_desync_factor = MAX_DESYNC_FACTOR, + .desync_factor = MAX_DESYNC_FACTOR / 2, #endif .max_addresses = IPV6_MAX_ADDRESSES, .accept_ra_defrtr = 1, @@ -206,6 +205,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { .temp_prefered_lft = TEMP_PREFERRED_LIFETIME, .regen_max_retry = REGEN_MAX_RETRY, .max_desync_factor = MAX_DESYNC_FACTOR, + .desync_factor = MAX_DESYNC_FACTOR / 2, #endif .max_addresses = IPV6_MAX_ADDRESSES, .accept_ra_defrtr = 1, @@ -831,11 +831,13 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) } #ifdef CONFIG_IPV6_PRIVACY - -static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *ift) +static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, + struct inet6_ifaddr *ift, + unsigned long now) { struct inet6_dev *idev = ifp->idev; struct in6_addr addr, *tmpaddr; - - unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp; + unsigned long tmp_prefered_lft, tmp_valid_lft; unsigned long regen_advance; int tmp_plen; int ret = 0; @@ -890,11 +892,9 @@ retry: idev->cnf.temp_valid_lft); tmp_prefered_lft = min_t(__u32, ifp->prefered_lft, - - idev->cnf.temp_prefered_lft - desync_factor / HZ); + idev->cnf.temp_prefered_lft - idev->cnf.desync_factor); tmp_plen = ifp->prefix_len; max_addresses = idev->cnf.max_addresses; - - tmp_cstamp = ifp->cstamp; - - tmp_tstamp = ifp->tstamp; spin_unlock_bh(&ifp->lock); regen_advance = idev->cnf.regen_max_retry * @@ -938,8 +938,7 @@ retry: ift->ifpub = ifp; ift->valid_lft = tmp_valid_lft; ift->prefered_lft = tmp_prefered_lft; - - ift->cstamp = tmp_cstamp; - - ift->tstamp = tmp_tstamp; + ift->cstamp = ift->tstamp = now; spin_unlock_bh(&ift->lock); addrconf_dad_start(ift, 0); @@ -1388,7 +1387,7 @@ static void addrconf_dad_stop(struct inet6_ifaddr *ifp) if (ifpub) { in6_ifa_hold(ifpub); spin_unlock_bh(&ifp->lock); - - ipv6_create_tempaddr(ifpub, ifp); + ipv6_create_tempaddr(ifpub, ifp, jiffies); in6_ifa_put(ifpub); } else { spin_unlock_bh(&ifp->lock); @@ -1624,7 +1623,8 @@ static void ipv6_regen_rndid(unsigned long data) expires = jiffies + idev->cnf.temp_prefered_lft * HZ - - - idev->cnf.regen_max_retry * idev->cnf.dad_transmits * idev->nd_parms->retrans_time - desync_factor; + idev->cnf.regen_max_retry * idev->cnf.dad_transmits * idev->nd_parms->retrans_time - + idev->cnf.desync_factor * HZ; if (time_before(expires, jiffies)) { printk(KERN_WARNING "ipv6_regen_rndid(): too short regeneration interval; timer disabled for %s.\n", @@ -1971,7 +1971,7 @@ ok: * also create a new temporary address. */ read_unlock_bh(&in6_dev->lock); - - ipv6_create_tempaddr(ifp, NULL); + ipv6_create_tempaddr(ifp, NULL, jiffies); } else { read_unlock_bh(&in6_dev->lock); } @@ -2809,6 +2809,11 @@ static void addrconf_dad_timer(unsigned long data) read_unlock_bh(&idev->lock); addrconf_dad_completed(ifp); + /* + * Required to expire properly temporary addresses + * with preferred lifetimes < ADDR_CHECK_FREQUENCY + */ + addrconf_verify(0); goto out; } @@ -3121,7 +3126,7 @@ restart: spin_lock(&ifpub->lock); ifpub->regen_count = 0; spin_unlock(&ifpub->lock); - - ipv6_create_tempaddr(ifpub, ifp); + ipv6_create_tempaddr(ifpub, ifp, now); in6_ifa_put(ifpub); in6_ifa_put(ifp); goto restart; @@ -3638,6 +3643,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, array[DEVCONF_TEMP_PREFERED_LFT] = cnf->temp_prefered_lft; array[DEVCONF_REGEN_MAX_RETRY] = cnf->regen_max_retry; array[DEVCONF_MAX_DESYNC_FACTOR] = cnf->max_desync_factor; + array[DEVCONF_DESYNC_FACTOR] = cnf->desync_factor; #endif array[DEVCONF_MAX_ADDRESSES] = cnf->max_addresses; array[DEVCONF_ACCEPT_RA_DEFRTR] = cnf->accept_ra_defrtr; @@ -3935,6 +3941,43 @@ static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) } #ifdef CONFIG_SYSCTL +#ifdef CONFIG_IPV6_PRIVACY +static int addrconf_sysctl_desync(ctl_table *ctl, int write, + struct file *filp, void __user *buffer, + size_t *lenp, loff_t *ppos) +{ + int ret; + + ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); + + if (write) { + __s32 df; + int *valp = ctl->data; + struct ipv6_devconf *all, *dflt; + struct inet6_dev *idev = ctl->extra1; + struct net *net = ctl->extra2; + all = net->ipv6.devconf_all; + dflt = net->ipv6.devconf_dflt; + + get_random_bytes(&df, sizeof(df)); + /* The global abs() casts to int. */; + df = ((df) < 0 ? -(df) : df) % (*valp) + + /* XXX How about some locking? */ + if(idev) + idev->cnf.desync_factor = df; + else if (valp == &dflt->max_desync_factor) + dflt->desync_factor = df; + else if (valp == &all->max_desync_factor) { + all->desync_factor = df; + dflt->max_desync_factor = all->max_desync_factor; + dflt->desync_factor = df; + } + + } + return ret; +} +#endif static int addrconf_sysctl_forward(ctl_table *ctl, int write, struct file * filp, @@ -4124,6 +4167,14 @@ static struct addrconf_sysctl_table .data = &ipv6_devconf.max_desync_factor, .maxlen = sizeof(int), .mode = 0644, + .proc_handler = addrconf_sysctl_desync, + }, + { + .ctl_name = NET_IPV6_DESYNC_FACTOR, + .procname = "desync_factor", + .data = &ipv6_devconf.desync_factor, + .maxlen = sizeof(int), + .mode = 0444, .proc_handler = proc_dointvec, }, #endif @@ -4449,6 +4500,11 @@ int __init addrconf_init(void) rtnl_unlock(); if (err) goto errlo; +#ifdef CONFIG_IPV6_PRIVACY + get_random_bytes(&ipv6_devconf.desync_factor, sizeof(ipv6_devconf.desync_factor)); + ipv6_devconf.desync_factor = abs(ipv6_devconf.desync_factor) % ipv6_devconf.max_desync_factor; + ipv6_devconf_dflt.desync_factor = ipv6_devconf.desync_factor; +#endif register_netdevice_notifier(&ipv6_dev_notf); - -----CUT HERE----- - -- Było mi bardzo miło. Czwarta pospolita klęska, [...] >Łukasz< Już nie katolicka lecz złodziejska. (c)PP -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.11 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iEYEARECAAYFAkn+GMMACgkQNdzY8sm9K9zimACcC6NfOGMzd0vqB9J/QXrc6q0P h6oAmgKP7sG+/h0JkdjVEeLbbyDgHH/s =CryG -----END PGP SIGNATURE----- ---------------------------------------------------------------------- Gotowka na koncie. Otworz konto direct i wez podwojny limit. http://link.interia.pl/f2145 [-- Attachment #2: stlman.vcf --] [-- Type: text/x-vcard, Size: 177 bytes --] begin:vcard fn;quoted-printable:=C5=81ukasz Stelmach n;quoted-printable:Stelmach;=C5=81ukasz email;internet:stlman@poczta.fm x-mozilla-html:FALSE version:2.1 end:vcard ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Temporary IPv6 address asignment 2009-05-03 22:20 ` [PATCH] Temporary IPv6 address asignment Lukasz Stelmach @ 2009-05-03 22:34 ` David Miller 2009-05-03 22:45 ` Lukasz Stelmach 0 siblings, 1 reply; 7+ messages in thread From: David Miller @ 2009-05-03 22:34 UTC (permalink / raw) To: stlman; +Cc: linux-kernel, yoshfuji, netdev From: Lukasz Stelmach <stlman@poczta.fm> Date: Mon, 04 May 2009 00:20:51 +0200 > The description is in the patch, and a sign-off too. But all righ. Patch is corrupted by your email client, tabs have been converted into spaces. Also, unnecessary leading spaces in front of your signoff. Please fix this up and make a fresh submission of your patch to netdev@vger.kernel.org Thank you. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Temporary IPv6 address asignment 2009-05-03 22:34 ` David Miller @ 2009-05-03 22:45 ` Lukasz Stelmach 2009-05-03 23:58 ` Eric W. Biederman 2009-05-04 10:57 ` YOSHIFUJI Hideaki / 吉藤英明 0 siblings, 2 replies; 7+ messages in thread From: Lukasz Stelmach @ 2009-05-03 22:45 UTC (permalink / raw) To: David Miller; +Cc: linux-kernel, yoshfuji, netdev [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain; charset=UTF-8, Size: 9136 bytes --] David Miller pisze: > Please fix this up and make a fresh submission of your patch to > netdev@vger.kernel.org -----CUT HERE----- A fixed mechanism to create and recreate temporary addresses, even for very short preferred lifetimes. A new RFC-compliant DESYNC_FACTOR implemented as a sysctl variable desync_factor which is assigned a random value each time max_desync_factor is written to. Each interface has its own desync_factor and max_desync_factor. Writes to default/max_desync_factor influence only default values. Writes to all/max_desync_factor influence "all" and default values but not values of running interfaces. The patch fixes issues described in bugs #13208 and #13221 at http://bugzilla.kernel.org. Signed-off-by: Åukasz Stelmach <stlman@poczta.fm> diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 476d946..fa45ad2 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -146,6 +146,7 @@ struct ipv6_devconf { __s32 temp_prefered_lft; __s32 regen_max_retry; __s32 max_desync_factor; + __s32 desync_factor; #endif __s32 max_addresses; __s32 accept_ra_defrtr; @@ -188,6 +189,7 @@ enum { DEVCONF_TEMP_PREFERED_LFT, DEVCONF_REGEN_MAX_RETRY, DEVCONF_MAX_DESYNC_FACTOR, + DEVCONF_DESYNC_FACTOR, DEVCONF_MAX_ADDRESSES, DEVCONF_FORCE_MLD_VERSION, DEVCONF_ACCEPT_RA_DEFRTR, diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index e76d3b2..951ba2c 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -570,15 +570,16 @@ enum { NET_IPV6_TEMP_PREFERED_LFT=13, NET_IPV6_REGEN_MAX_RETRY=14, NET_IPV6_MAX_DESYNC_FACTOR=15, - NET_IPV6_MAX_ADDRESSES=16, - NET_IPV6_FORCE_MLD_VERSION=17, - NET_IPV6_ACCEPT_RA_DEFRTR=18, - NET_IPV6_ACCEPT_RA_PINFO=19, - NET_IPV6_ACCEPT_RA_RTR_PREF=20, - NET_IPV6_RTR_PROBE_INTERVAL=21, - NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, - NET_IPV6_PROXY_NDP=23, - NET_IPV6_ACCEPT_SOURCE_ROUTE=25, + NET_IPV6_DESYNC_FACTOR=16, + NET_IPV6_MAX_ADDRESSES=17, + NET_IPV6_FORCE_MLD_VERSION=18, + NET_IPV6_ACCEPT_RA_DEFRTR=19, + NET_IPV6_ACCEPT_RA_PINFO=20, + NET_IPV6_ACCEPT_RA_RTR_PREF=21, + NET_IPV6_RTR_PROBE_INTERVAL=22, + NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=23, + NET_IPV6_PROXY_NDP=24, + NET_IPV6_ACCEPT_SOURCE_ROUTE=26, __NET_IPV6_MAX }; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index a8218bc..1b746ee 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -116,8 +116,6 @@ static inline void addrconf_sysctl_unregister(struct inet6_dev *idev) static int __ipv6_regen_rndid(struct inet6_dev *idev); static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr); static void ipv6_regen_rndid(unsigned long data); - -static int desync_factor = MAX_DESYNC_FACTOR * HZ; #endif static int ipv6_generate_eui64(u8 *eui, struct net_device *dev); @@ -172,6 +170,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = { .temp_prefered_lft = TEMP_PREFERRED_LIFETIME, .regen_max_retry = REGEN_MAX_RETRY, .max_desync_factor = MAX_DESYNC_FACTOR, + .desync_factor = MAX_DESYNC_FACTOR / 2, #endif .max_addresses = IPV6_MAX_ADDRESSES, .accept_ra_defrtr = 1, @@ -206,6 +205,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { .temp_prefered_lft = TEMP_PREFERRED_LIFETIME, .regen_max_retry = REGEN_MAX_RETRY, .max_desync_factor = MAX_DESYNC_FACTOR, + .desync_factor = MAX_DESYNC_FACTOR / 2, #endif .max_addresses = IPV6_MAX_ADDRESSES, .accept_ra_defrtr = 1, @@ -831,11 +831,13 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) } #ifdef CONFIG_IPV6_PRIVACY -static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *ift) +static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, + struct inet6_ifaddr *ift, + unsigned long now) { struct inet6_dev *idev = ifp->idev; struct in6_addr addr, *tmpaddr; - unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp; + unsigned long tmp_prefered_lft, tmp_valid_lft; unsigned long regen_advance; int tmp_plen; int ret = 0; @@ -890,11 +892,9 @@ retry: idev->cnf.temp_valid_lft); tmp_prefered_lft = min_t(__u32, ifp->prefered_lft, - idev->cnf.temp_prefered_lft - desync_factor / HZ); + idev->cnf.temp_prefered_lft - idev->cnf.desync_factor); tmp_plen = ifp->prefix_len; max_addresses = idev->cnf.max_addresses; - tmp_cstamp = ifp->cstamp; - tmp_tstamp = ifp->tstamp; spin_unlock_bh(&ifp->lock); regen_advance = idev->cnf.regen_max_retry * @@ -938,8 +938,7 @@ retry: ift->ifpub = ifp; ift->valid_lft = tmp_valid_lft; ift->prefered_lft = tmp_prefered_lft; - ift->cstamp = tmp_cstamp; - ift->tstamp = tmp_tstamp; + ift->cstamp = ift->tstamp = now; spin_unlock_bh(&ift->lock); addrconf_dad_start(ift, 0); @@ -1388,7 +1387,7 @@ static void addrconf_dad_stop(struct inet6_ifaddr *ifp) if (ifpub) { in6_ifa_hold(ifpub); spin_unlock_bh(&ifp->lock); - ipv6_create_tempaddr(ifpub, ifp); + ipv6_create_tempaddr(ifpub, ifp, jiffies); in6_ifa_put(ifpub); } else { spin_unlock_bh(&ifp->lock); @@ -1624,7 +1623,8 @@ static void ipv6_regen_rndid(unsigned long data) expires = jiffies + idev->cnf.temp_prefered_lft * HZ - - idev->cnf.regen_max_retry * idev->cnf.dad_transmits * idev->nd_parms->retrans_time - desync_factor; + idev->cnf.regen_max_retry * idev->cnf.dad_transmits * idev->nd_parms->retrans_time - + idev->cnf.desync_factor * HZ; if (time_before(expires, jiffies)) { printk(KERN_WARNING "ipv6_regen_rndid(): too short regeneration interval; timer disabled for %s.\n", @@ -1971,7 +1971,7 @@ ok: * also create a new temporary address. */ read_unlock_bh(&in6_dev->lock); - ipv6_create_tempaddr(ifp, NULL); + ipv6_create_tempaddr(ifp, NULL, jiffies); } else { read_unlock_bh(&in6_dev->lock); } @@ -2809,6 +2809,11 @@ static void addrconf_dad_timer(unsigned long data) read_unlock_bh(&idev->lock); addrconf_dad_completed(ifp); + /* + * Required to expire properly temporary addresses + * with preferred lifetimes < ADDR_CHECK_FREQUENCY + */ + addrconf_verify(0); goto out; } @@ -3121,7 +3126,7 @@ restart: spin_lock(&ifpub->lock); ifpub->regen_count = 0; spin_unlock(&ifpub->lock); - ipv6_create_tempaddr(ifpub, ifp); + ipv6_create_tempaddr(ifpub, ifp, now); in6_ifa_put(ifpub); in6_ifa_put(ifp); goto restart; @@ -3638,6 +3643,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, array[DEVCONF_TEMP_PREFERED_LFT] = cnf->temp_prefered_lft; array[DEVCONF_REGEN_MAX_RETRY] = cnf->regen_max_retry; array[DEVCONF_MAX_DESYNC_FACTOR] = cnf->max_desync_factor; + array[DEVCONF_DESYNC_FACTOR] = cnf->desync_factor; #endif array[DEVCONF_MAX_ADDRESSES] = cnf->max_addresses; array[DEVCONF_ACCEPT_RA_DEFRTR] = cnf->accept_ra_defrtr; @@ -3935,6 +3941,43 @@ static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) } #ifdef CONFIG_SYSCTL +#ifdef CONFIG_IPV6_PRIVACY +static int addrconf_sysctl_desync(ctl_table *ctl, int write, + struct file *filp, void __user *buffer, + size_t *lenp, loff_t *ppos) +{ + int ret; + + ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); + + if (write) { + __s32 df; + int *valp = ctl->data; + struct ipv6_devconf *all, *dflt; + struct inet6_dev *idev = ctl->extra1; + struct net *net = ctl->extra2; + all = net->ipv6.devconf_all; + dflt = net->ipv6.devconf_dflt; + + get_random_bytes(&df, sizeof(df)); + /* The global abs() casts to int. */; + df = ((df) < 0 ? -(df) : df) % (*valp) + + /* XXX How about some locking? */ + if(idev) + idev->cnf.desync_factor = df; + else if (valp == &dflt->max_desync_factor) + dflt->desync_factor = df; + else if (valp == &all->max_desync_factor) { + all->desync_factor = df; + dflt->max_desync_factor = all->max_desync_factor; + dflt->desync_factor = df; + } + + } + return ret; +} +#endif static int addrconf_sysctl_forward(ctl_table *ctl, int write, struct file * filp, @@ -4124,6 +4167,14 @@ static struct addrconf_sysctl_table .data = &ipv6_devconf.max_desync_factor, .maxlen = sizeof(int), .mode = 0644, + .proc_handler = addrconf_sysctl_desync, + }, + { + .ctl_name = NET_IPV6_DESYNC_FACTOR, + .procname = "desync_factor", + .data = &ipv6_devconf.desync_factor, + .maxlen = sizeof(int), + .mode = 0444, .proc_handler = proc_dointvec, }, #endif @@ -4449,6 +4500,11 @@ int __init addrconf_init(void) rtnl_unlock(); if (err) goto errlo; +#ifdef CONFIG_IPV6_PRIVACY + get_random_bytes(&ipv6_devconf.desync_factor, sizeof(ipv6_devconf.desync_factor)); + ipv6_devconf.desync_factor = abs(ipv6_devconf.desync_factor) % ipv6_devconf.max_desync_factor; + ipv6_devconf_dflt.desync_factor = ipv6_devconf.desync_factor; +#endif register_netdevice_notifier(&ipv6_dev_notf); -----CUT HERE----- -- ByÅo mi bardzo miÅo. Czwarta pospolita klÄska, [...] >Åukasz< Już nie katolicka lecz zÅodziejska. (c)PP ---------------------------------------------------------------------- Dzwonki na komorkê! Sprawdz >> http://link.interia.pl/f2152 [-- Attachment #2: stlman.vcf --] [-- Type: text/x-vcard, Size: 177 bytes --] begin:vcard fn;quoted-printable:=C5=81ukasz Stelmach n;quoted-printable:Stelmach;=C5=81ukasz email;internet:stlman@poczta.fm x-mozilla-html:FALSE version:2.1 end:vcard ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] Temporary IPv6 address asignment 2009-05-03 22:45 ` Lukasz Stelmach @ 2009-05-03 23:58 ` Eric W. Biederman 2009-05-04 0:21 ` David Miller 2009-05-04 10:57 ` YOSHIFUJI Hideaki / 吉藤英明 1 sibling, 1 reply; 7+ messages in thread From: Eric W. Biederman @ 2009-05-03 23:58 UTC (permalink / raw) To: Lukasz Stelmach; +Cc: David Miller, linux-kernel, yoshfuji, netdev Lukasz Stelmach <stlman@poczta.fm> writes: I don't know about the rest of your patch the sysctl hunks are wrong. > diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h > index e76d3b2..951ba2c 100644 > --- a/include/linux/sysctl.h > +++ b/include/linux/sysctl.h > @@ -570,15 +570,16 @@ enum { > NET_IPV6_TEMP_PREFERED_LFT=13, > NET_IPV6_REGEN_MAX_RETRY=14, > NET_IPV6_MAX_DESYNC_FACTOR=15, > - NET_IPV6_MAX_ADDRESSES=16, > - NET_IPV6_FORCE_MLD_VERSION=17, > - NET_IPV6_ACCEPT_RA_DEFRTR=18, > - NET_IPV6_ACCEPT_RA_PINFO=19, > - NET_IPV6_ACCEPT_RA_RTR_PREF=20, > - NET_IPV6_RTR_PROBE_INTERVAL=21, > - NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, > - NET_IPV6_PROXY_NDP=23, > - NET_IPV6_ACCEPT_SOURCE_ROUTE=25, > + NET_IPV6_DESYNC_FACTOR=16, > + NET_IPV6_MAX_ADDRESSES=17, > + NET_IPV6_FORCE_MLD_VERSION=18, > + NET_IPV6_ACCEPT_RA_DEFRTR=19, > + NET_IPV6_ACCEPT_RA_PINFO=20, > + NET_IPV6_ACCEPT_RA_RTR_PREF=21, > + NET_IPV6_RTR_PROBE_INTERVAL=22, > + NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=23, > + NET_IPV6_PROXY_NDP=24, > + NET_IPV6_ACCEPT_SOURCE_ROUTE=26, > __NET_IPV6_MAX > }; These are numbers used in the kernel sysctl binary ABI. You just changed them breaking the ABI, when you put NET_IPV6_DESYNC_FACTOR in the middle. > @@ -4124,6 +4167,14 @@ static struct addrconf_sysctl_table > .data = &ipv6_devconf.max_desync_factor, > .maxlen = sizeof(int), > .mode = 0644, > + .proc_handler = addrconf_sysctl_desync, > + }, > + { > + .ctl_name = NET_IPV6_DESYNC_FACTOR, > + .procname = "desync_factor", > + .data = &ipv6_devconf.desync_factor, > + .maxlen = sizeof(int), > + .mode = 0444, > .proc_handler = proc_dointvec, }, The sysctl binary abi is currently frozen and deprecated. Which means you should set .ctl_name = CTL_UNNUMBERED or simply omit ctl_name on new sysctl entries. Eric ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Temporary IPv6 address asignment 2009-05-03 23:58 ` Eric W. Biederman @ 2009-05-04 0:21 ` David Miller 0 siblings, 0 replies; 7+ messages in thread From: David Miller @ 2009-05-04 0:21 UTC (permalink / raw) To: ebiederm; +Cc: stlman, linux-kernel, yoshfuji, netdev From: ebiederm@xmission.com (Eric W. Biederman) Date: Sun, 03 May 2009 16:58:02 -0700 > These are numbers used in the kernel sysctl binary ABI. You just > changed them breaking the ABI, when you put NET_IPV6_DESYNC_FACTOR in > the middle. In fact adding new sysctl values are totally verbotten these days. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Temporary IPv6 address asignment 2009-05-03 22:45 ` Lukasz Stelmach 2009-05-03 23:58 ` Eric W. Biederman @ 2009-05-04 10:57 ` YOSHIFUJI Hideaki / 吉藤英明 1 sibling, 0 replies; 7+ messages in thread From: YOSHIFUJI Hideaki / 吉藤英明 @ 2009-05-04 10:57 UTC (permalink / raw) To: stlman; +Cc: davem, linux-kernel, netdev, yoshfuji In article <49FE1E71.6090500@poczta.fm> (at Mon, 04 May 2009 00:45:05 +0200), Lukasz Stelmach <stlman@poczta.fm> says: > @@ -188,6 +189,7 @@ enum { > DEVCONF_TEMP_PREFERED_LFT, > DEVCONF_REGEN_MAX_RETRY, > DEVCONF_MAX_DESYNC_FACTOR, > + DEVCONF_DESYNC_FACTOR, > DEVCONF_MAX_ADDRESSES, > DEVCONF_FORCE_MLD_VERSION, > DEVCONF_ACCEPT_RA_DEFRTR, (In addition to the issue regarding sysctl,) please do not add new DEVCONF_xxx enum in the middle. --yoshfuji ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] Temporary IPv6 address asignment (v.1.1) [not found] <49FE107A.4020406@poczta.fm> [not found] ` <20090503.144758.222061423.davem@davemloft.net> @ 2009-05-04 13:30 ` Lukasz Stelmach 1 sibling, 0 replies; 7+ messages in thread From: Lukasz Stelmach @ 2009-05-04 13:30 UTC (permalink / raw) To: LKML; +Cc: netdev, davem, yoshfuji, ebiederm [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain; charset=UTF-8, Size: 7985 bytes --] A fixed mechanism to create and recreate temporary addresses, even for very short preferred lifetimes. A new RFC-compliant DESYNC_FACTOR implemented as a sysctl variable desync_factor which is assigned a random value each time max_desync_factor is written to. Each interface has its own desync_factor and max_desync_factor. Writes to default/max_desync_factor influence only default values. Writes to all/max_desync_factor influence "all" and default values but not values of running interfaces. The patch fixes issues described in bugs #13208 and #13221 at http://bugzilla.kernel.org. Signed-off-by: Åukasz Stelmach <stlman@poczta.fm> diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 476d946..678687d 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -146,6 +146,7 @@ struct ipv6_devconf { __s32 temp_prefered_lft; __s32 regen_max_retry; __s32 max_desync_factor; + __s32 desync_factor; #endif __s32 max_addresses; __s32 accept_ra_defrtr; @@ -201,6 +202,7 @@ enum { DEVCONF_MC_FORWARDING, DEVCONF_DISABLE_IPV6, DEVCONF_ACCEPT_DAD, + DEVCONF_DESYNC_FACTOR, DEVCONF_MAX }; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index a8218bc..c883064 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -116,8 +116,6 @@ static inline void addrconf_sysctl_unregister(struct inet6_dev *idev) static int __ipv6_regen_rndid(struct inet6_dev *idev); static int __ipv6_try_regen_rndid(struct inet6_dev *idev, struct in6_addr *tmpaddr); static void ipv6_regen_rndid(unsigned long data); - -static int desync_factor = MAX_DESYNC_FACTOR * HZ; #endif static int ipv6_generate_eui64(u8 *eui, struct net_device *dev); @@ -172,6 +170,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = { .temp_prefered_lft = TEMP_PREFERRED_LIFETIME, .regen_max_retry = REGEN_MAX_RETRY, .max_desync_factor = MAX_DESYNC_FACTOR, + .desync_factor = MAX_DESYNC_FACTOR / 2, #endif .max_addresses = IPV6_MAX_ADDRESSES, .accept_ra_defrtr = 1, @@ -206,6 +205,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { .temp_prefered_lft = TEMP_PREFERRED_LIFETIME, .regen_max_retry = REGEN_MAX_RETRY, .max_desync_factor = MAX_DESYNC_FACTOR, + .desync_factor = MAX_DESYNC_FACTOR / 2, #endif .max_addresses = IPV6_MAX_ADDRESSES, .accept_ra_defrtr = 1, @@ -831,11 +831,13 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) } #ifdef CONFIG_IPV6_PRIVACY -static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *ift) +static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, + struct inet6_ifaddr *ift, + unsigned long now) { struct inet6_dev *idev = ifp->idev; struct in6_addr addr, *tmpaddr; - unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp; + unsigned long tmp_prefered_lft, tmp_valid_lft; unsigned long regen_advance; int tmp_plen; int ret = 0; @@ -890,11 +892,9 @@ retry: idev->cnf.temp_valid_lft); tmp_prefered_lft = min_t(__u32, ifp->prefered_lft, - idev->cnf.temp_prefered_lft - desync_factor / HZ); + idev->cnf.temp_prefered_lft - idev->cnf.desync_factor); tmp_plen = ifp->prefix_len; max_addresses = idev->cnf.max_addresses; - tmp_cstamp = ifp->cstamp; - tmp_tstamp = ifp->tstamp; spin_unlock_bh(&ifp->lock); regen_advance = idev->cnf.regen_max_retry * @@ -938,8 +938,7 @@ retry: ift->ifpub = ifp; ift->valid_lft = tmp_valid_lft; ift->prefered_lft = tmp_prefered_lft; - ift->cstamp = tmp_cstamp; - ift->tstamp = tmp_tstamp; + ift->cstamp = ift->tstamp = now; spin_unlock_bh(&ift->lock); addrconf_dad_start(ift, 0); @@ -1388,7 +1387,7 @@ static void addrconf_dad_stop(struct inet6_ifaddr *ifp) if (ifpub) { in6_ifa_hold(ifpub); spin_unlock_bh(&ifp->lock); - ipv6_create_tempaddr(ifpub, ifp); + ipv6_create_tempaddr(ifpub, ifp, jiffies); in6_ifa_put(ifpub); } else { spin_unlock_bh(&ifp->lock); @@ -1624,7 +1623,8 @@ static void ipv6_regen_rndid(unsigned long data) expires = jiffies + idev->cnf.temp_prefered_lft * HZ - - idev->cnf.regen_max_retry * idev->cnf.dad_transmits * idev->nd_parms->retrans_time - desync_factor; + idev->cnf.regen_max_retry * idev->cnf.dad_transmits * idev->nd_parms->retrans_time - + idev->cnf.desync_factor * HZ; if (time_before(expires, jiffies)) { printk(KERN_WARNING "ipv6_regen_rndid(): too short regeneration interval; timer disabled for %s.\n", @@ -1971,7 +1971,7 @@ ok: * also create a new temporary address. */ read_unlock_bh(&in6_dev->lock); - ipv6_create_tempaddr(ifp, NULL); + ipv6_create_tempaddr(ifp, NULL, jiffies); } else { read_unlock_bh(&in6_dev->lock); } @@ -2809,6 +2809,11 @@ static void addrconf_dad_timer(unsigned long data) read_unlock_bh(&idev->lock); addrconf_dad_completed(ifp); + /* + * Required to expire properly temporary addresses + * with preferred lifetimes < ADDR_CHECK_FREQUENCY + */ + addrconf_verify(0); goto out; } @@ -3121,7 +3126,7 @@ restart: spin_lock(&ifpub->lock); ifpub->regen_count = 0; spin_unlock(&ifpub->lock); - ipv6_create_tempaddr(ifpub, ifp); + ipv6_create_tempaddr(ifpub, ifp, now); in6_ifa_put(ifpub); in6_ifa_put(ifp); goto restart; @@ -3638,6 +3643,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, array[DEVCONF_TEMP_PREFERED_LFT] = cnf->temp_prefered_lft; array[DEVCONF_REGEN_MAX_RETRY] = cnf->regen_max_retry; array[DEVCONF_MAX_DESYNC_FACTOR] = cnf->max_desync_factor; + array[DEVCONF_DESYNC_FACTOR] = cnf->desync_factor; #endif array[DEVCONF_MAX_ADDRESSES] = cnf->max_addresses; array[DEVCONF_ACCEPT_RA_DEFRTR] = cnf->accept_ra_defrtr; @@ -3935,6 +3941,43 @@ static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) } #ifdef CONFIG_SYSCTL +#ifdef CONFIG_IPV6_PRIVACY +static int addrconf_sysctl_desync(ctl_table *ctl, int write, + struct file *filp, void __user *buffer, + size_t *lenp, loff_t *ppos) +{ + int ret; + + ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); + + if (write) { + __s32 df; + int *valp = ctl->data; + struct ipv6_devconf *all, *dflt; + struct inet6_dev *idev = ctl->extra1; + struct net *net = ctl->extra2; + all = net->ipv6.devconf_all; + dflt = net->ipv6.devconf_dflt; + + get_random_bytes(&df, sizeof(df)); + /* The global abs() casts to int. */; + df = ((df) < 0 ? -(df) : df) % (*valp) + + /* XXX How about some locking? */ + if(idev) + idev->cnf.desync_factor = df; + else if (valp == &dflt->max_desync_factor) + dflt->desync_factor = df; + else if (valp == &all->max_desync_factor) { + all->desync_factor = df; + dflt->max_desync_factor = all->max_desync_factor; + dflt->desync_factor = df; + } + + } + return ret; +} +#endif static int addrconf_sysctl_forward(ctl_table *ctl, int write, struct file * filp, @@ -4124,6 +4167,14 @@ static struct addrconf_sysctl_table .data = &ipv6_devconf.max_desync_factor, .maxlen = sizeof(int), .mode = 0644, + .proc_handler = addrconf_sysctl_desync, + }, + { + .ctl_name = CTL_UNNUMBERED, + .procname = "desync_factor", + .data = &ipv6_devconf.desync_factor, + .maxlen = sizeof(int), + .mode = 0444, .proc_handler = proc_dointvec, }, #endif @@ -4449,6 +4500,11 @@ int __init addrconf_init(void) rtnl_unlock(); if (err) goto errlo; +#ifdef CONFIG_IPV6_PRIVACY + get_random_bytes(&ipv6_devconf.desync_factor, sizeof(ipv6_devconf.desync_factor)); + ipv6_devconf.desync_factor = abs(ipv6_devconf.desync_factor) % ipv6_devconf.max_desync_factor; + ipv6_devconf_dflt.desync_factor = ipv6_devconf.desync_factor; +#endif register_netdevice_notifier(&ipv6_dev_notf); -- ByÅo mi bardzo miÅo. Czwarta pospolita klÄska, [...] >Åukasz< Już nie katolicka lecz zÅodziejska. (c)PP ---------------------------------------------------------------------- Dzwonki na komorkê! Sprawdz >> http://link.interia.pl/f2152 [-- Attachment #2: stlman.vcf --] [-- Type: text/x-vcard, Size: 177 bytes --] begin:vcard fn;quoted-printable:=C5=81ukasz Stelmach n;quoted-printable:Stelmach;=C5=81ukasz email;internet:stlman@poczta.fm x-mozilla-html:FALSE version:2.1 end:vcard ^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2009-05-04 13:30 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <49FE107A.4020406@poczta.fm>
[not found] ` <20090503.144758.222061423.davem@davemloft.net>
2009-05-03 22:20 ` [PATCH] Temporary IPv6 address asignment Lukasz Stelmach
2009-05-03 22:34 ` David Miller
2009-05-03 22:45 ` Lukasz Stelmach
2009-05-03 23:58 ` Eric W. Biederman
2009-05-04 0:21 ` David Miller
2009-05-04 10:57 ` YOSHIFUJI Hideaki / 吉藤英明
2009-05-04 13:30 ` [PATCH] Temporary IPv6 address asignment (v.1.1) Lukasz Stelmach
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).