netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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


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