]>
Commit | Line | Data |
---|---|---|
2532c0bb CW |
1 | From stable-bounces@linux.kernel.org Thu Jan 4 17:14:44 2007 |
2 | Date: Thu, 04 Jan 2007 17:07:34 -0800 (PST) | |
3 | Message-Id: <20070104.170734.94556619.davem@davemloft.net> | |
4 | To: stable@kernel.org | |
5 | From: David Miller <davem@davemloft.net> | |
6 | Cc: bunk@stusta.de | |
7 | Subject: IPV4/IPV6: Fix inet{,6} device initialization order. | |
8 | ||
9 | From: David L Stevens <dlstevens@us.ibm.com> | |
10 | ||
11 | It is important that we only assign dev->ip{,6}_ptr | |
12 | only after all portions of the inet{,6} are setup. | |
13 | ||
14 | Otherwise we can receive packets before the multicast | |
15 | spinlocks et al. are initialized. | |
16 | ||
17 | Signed-off-by: David L Stevens <dlstevens@us.ibm.com> | |
18 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
19 | Signed-off-by: Chris Wright <chrisw@sous-sol.org> | |
20 | --- | |
21 | commit 30c4cf577fb5b68c16e5750d6bdbd7072e42b279 | |
22 | ||
23 | net/ipv4/devinet.c | 5 +++-- | |
24 | net/ipv6/addrconf.c | 4 ++-- | |
25 | 2 files changed, 5 insertions(+), 4 deletions(-) | |
26 | ||
27 | --- linux-2.6.19.1.orig/net/ipv4/devinet.c | |
28 | +++ linux-2.6.19.1/net/ipv4/devinet.c | |
29 | @@ -165,9 +165,8 @@ struct in_device *inetdev_init(struct ne | |
30 | NET_IPV4_NEIGH, "ipv4", NULL, NULL); | |
31 | #endif | |
32 | ||
33 | - /* Account for reference dev->ip_ptr */ | |
34 | + /* Account for reference dev->ip_ptr (below) */ | |
35 | in_dev_hold(in_dev); | |
36 | - rcu_assign_pointer(dev->ip_ptr, in_dev); | |
37 | ||
38 | #ifdef CONFIG_SYSCTL | |
39 | devinet_sysctl_register(in_dev, &in_dev->cnf); | |
40 | @@ -176,6 +175,8 @@ struct in_device *inetdev_init(struct ne | |
41 | if (dev->flags & IFF_UP) | |
42 | ip_mc_up(in_dev); | |
43 | out: | |
44 | + /* we can receive as soon as ip_ptr is set -- do this last */ | |
45 | + rcu_assign_pointer(dev->ip_ptr, in_dev); | |
46 | return in_dev; | |
47 | out_kfree: | |
48 | kfree(in_dev); | |
49 | --- linux-2.6.19.1.orig/net/ipv6/addrconf.c | |
50 | +++ linux-2.6.19.1/net/ipv6/addrconf.c | |
51 | @@ -413,8 +413,6 @@ static struct inet6_dev * ipv6_add_dev(s | |
52 | if (netif_carrier_ok(dev)) | |
53 | ndev->if_flags |= IF_READY; | |
54 | ||
55 | - /* protected by rtnl_lock */ | |
56 | - rcu_assign_pointer(dev->ip6_ptr, ndev); | |
57 | ||
58 | ipv6_mc_init_dev(ndev); | |
59 | ndev->tstamp = jiffies; | |
60 | @@ -425,6 +423,8 @@ static struct inet6_dev * ipv6_add_dev(s | |
61 | NULL); | |
62 | addrconf_sysctl_register(ndev, &ndev->cnf); | |
63 | #endif | |
64 | + /* protected by rtnl_lock */ | |
65 | + rcu_assign_pointer(dev->ip6_ptr, ndev); | |
66 | return ndev; | |
67 | } | |
68 |