aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;