* 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).