From: Lukasz Stelmach <stlman@poczta.fm>
To: linux-kernel@vger.kernel.org
Cc: David Miller <davem@davemloft.net>,
yoshfuji@linux-ipv6.org, netdev@vger.kernel.org
Subject: Re: [PATCH] Temporary IPv6 address asignment
Date: Mon, 04 May 2009 00:20:51 +0200 [thread overview]
Message-ID: <49FE18C3.7040702@poczta.fm> (raw)
In-Reply-To: <20090503.144758.222061423.davem@davemloft.net>
[-- 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
next parent reply other threads:[~2009-05-03 22:20 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <49FE107A.4020406@poczta.fm>
[not found] ` <20090503.144758.222061423.davem@davemloft.net>
2009-05-03 22:20 ` Lukasz Stelmach [this message]
2009-05-03 22:34 ` [PATCH] Temporary IPv6 address asignment 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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=49FE18C3.7040702@poczta.fm \
--to=stlman@poczta.fm \
--cc=davem@davemloft.net \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=yoshfuji@linux-ipv6.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).