aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2007-06-05 02:36:06 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-06-07 16:39:26 -0400
commit71e27da9618b5f4d525ec821def83991da20429f (patch)
tree521645ee5c7e43cc0de100bc4425668e078d92f9
parent31be308541e990592a2d0a3e77e8e51bd0cea0e0 (diff)
[IPV4]: Restore old behaviour of default config values
Previously inet devices were only constructed when addresses are added (or rarely in ipmr). Therefore the default config values they get are the ones at the time of these operations. Now that we're creating inet devices earlier, this changes the behaviour of default config values in an incompatible way (see bug #8519). This patch creates a compromise by setting the default values at the same point as before but only for those that have not been explicitly set by the user since the inet device's creation. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/inetdevice.h6
-rw-r--r--net/ipv4/devinet.c19
-rw-r--r--net/ipv4/ipmr.c15
3 files changed, 24 insertions, 16 deletions
diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
index 40adefdfe5d1..ae04901aa09a 100644
--- a/include/linux/inetdevice.h
+++ b/include/linux/inetdevice.h
@@ -59,6 +59,11 @@ static inline void ipv4_devconf_set(struct in_device *in_dev, int index,
59 in_dev->cnf.data[index] = val; 59 in_dev->cnf.data[index] = val;
60} 60}
61 61
62static inline void ipv4_devconf_setall(struct in_device *in_dev)
63{
64 bitmap_fill(in_dev->cnf.state, __NET_IPV4_CONF_MAX - 1);
65}
66
62#define IN_DEV_CONF_GET(in_dev, attr) \ 67#define IN_DEV_CONF_GET(in_dev, attr) \
63 ipv4_devconf_get((in_dev), NET_IPV4_CONF_ ## attr) 68 ipv4_devconf_get((in_dev), NET_IPV4_CONF_ ## attr)
64#define IN_DEV_CONF_SET(in_dev, attr, val) \ 69#define IN_DEV_CONF_SET(in_dev, attr, val) \
@@ -125,7 +130,6 @@ extern struct net_device *ip_dev_find(__be32 addr);
125extern int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b); 130extern int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b);
126extern int devinet_ioctl(unsigned int cmd, void __user *); 131extern int devinet_ioctl(unsigned int cmd, void __user *);
127extern void devinet_init(void); 132extern void devinet_init(void);
128extern struct in_device *inetdev_init(struct net_device *dev);
129extern struct in_device *inetdev_by_index(int); 133extern struct in_device *inetdev_by_index(int);
130extern __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope); 134extern __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope);
131extern __be32 inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, int scope); 135extern __be32 inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, int scope);
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index e19734795a7b..354e800be18d 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -147,7 +147,7 @@ void in_dev_finish_destroy(struct in_device *idev)
147 } 147 }
148} 148}
149 149
150struct in_device *inetdev_init(struct net_device *dev) 150static struct in_device *inetdev_init(struct net_device *dev)
151{ 151{
152 struct in_device *in_dev; 152 struct in_device *in_dev;
153 153
@@ -405,12 +405,10 @@ static int inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa)
405 ASSERT_RTNL(); 405 ASSERT_RTNL();
406 406
407 if (!in_dev) { 407 if (!in_dev) {
408 in_dev = inetdev_init(dev); 408 inet_free_ifa(ifa);
409 if (!in_dev) { 409 return -ENOBUFS;
410 inet_free_ifa(ifa);
411 return -ENOBUFS;
412 }
413 } 410 }
411 ipv4_devconf_setall(in_dev);
414 if (ifa->ifa_dev != in_dev) { 412 if (ifa->ifa_dev != in_dev) {
415 BUG_TRAP(!ifa->ifa_dev); 413 BUG_TRAP(!ifa->ifa_dev);
416 in_dev_hold(in_dev); 414 in_dev_hold(in_dev);
@@ -520,13 +518,12 @@ static struct in_ifaddr *rtm_to_ifaddr(struct nlmsghdr *nlh)
520 518
521 in_dev = __in_dev_get_rtnl(dev); 519 in_dev = __in_dev_get_rtnl(dev);
522 if (in_dev == NULL) { 520 if (in_dev == NULL) {
523 in_dev = inetdev_init(dev); 521 err = -ENOBUFS;
524 if (in_dev == NULL) { 522 goto errout;
525 err = -ENOBUFS;
526 goto errout;
527 }
528 } 523 }
529 524
525 ipv4_devconf_setall(in_dev);
526
530 ifa = inet_alloc_ifa(); 527 ifa = inet_alloc_ifa();
531 if (ifa == NULL) { 528 if (ifa == NULL) {
532 /* 529 /*
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index d570d3ad40a9..d96582acdf69 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -152,9 +152,11 @@ struct net_device *ipmr_new_tunnel(struct vifctl *v)
152 dev->flags |= IFF_MULTICAST; 152 dev->flags |= IFF_MULTICAST;
153 153
154 in_dev = __in_dev_get_rtnl(dev); 154 in_dev = __in_dev_get_rtnl(dev);
155 if (in_dev == NULL && (in_dev = inetdev_init(dev)) == NULL) 155 if (in_dev == NULL)
156 goto failure; 156 goto failure;
157 IN_DEV_CONF_SET(in_dev, RP_FILTER, 0); 157
158 ipv4_devconf_setall(in_dev);
159 IPV4_DEVCONF(in_dev->cnf, RP_FILTER) = 0;
158 160
159 if (dev_open(dev)) 161 if (dev_open(dev))
160 goto failure; 162 goto failure;
@@ -218,10 +220,15 @@ static struct net_device *ipmr_reg_vif(void)
218 } 220 }
219 dev->iflink = 0; 221 dev->iflink = 0;
220 222
221 if ((in_dev = inetdev_init(dev)) == NULL) 223 rcu_read_lock();
224 if ((in_dev = __in_dev_get_rcu(dev)) == NULL) {
225 rcu_read_unlock();
222 goto failure; 226 goto failure;
227 }
223 228
224 IN_DEV_CONF_SET(in_dev, RP_FILTER, 0); 229 ipv4_devconf_setall(in_dev);
230 IPV4_DEVCONF(in_dev->cnf, RP_FILTER) = 0;
231 rcu_read_unlock();
225 232
226 if (dev_open(dev)) 233 if (dev_open(dev))
227 goto failure; 234 goto failure;