Commit 71e27da9 authored by Herbert Xu's avatar Herbert Xu Committed by David S. Miller

[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: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 31be3085
...@@ -59,6 +59,11 @@ static inline void ipv4_devconf_set(struct in_device *in_dev, int index, ...@@ -59,6 +59,11 @@ static inline void ipv4_devconf_set(struct in_device *in_dev, int index,
in_dev->cnf.data[index] = val; in_dev->cnf.data[index] = val;
} }
static inline void ipv4_devconf_setall(struct in_device *in_dev)
{
bitmap_fill(in_dev->cnf.state, __NET_IPV4_CONF_MAX - 1);
}
#define IN_DEV_CONF_GET(in_dev, attr) \ #define IN_DEV_CONF_GET(in_dev, attr) \
ipv4_devconf_get((in_dev), NET_IPV4_CONF_ ## attr) ipv4_devconf_get((in_dev), NET_IPV4_CONF_ ## attr)
#define IN_DEV_CONF_SET(in_dev, attr, val) \ #define IN_DEV_CONF_SET(in_dev, attr, val) \
...@@ -125,7 +130,6 @@ extern struct net_device *ip_dev_find(__be32 addr); ...@@ -125,7 +130,6 @@ extern struct net_device *ip_dev_find(__be32 addr);
extern int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b); extern int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b);
extern int devinet_ioctl(unsigned int cmd, void __user *); extern int devinet_ioctl(unsigned int cmd, void __user *);
extern void devinet_init(void); extern void devinet_init(void);
extern struct in_device *inetdev_init(struct net_device *dev);
extern struct in_device *inetdev_by_index(int); extern struct in_device *inetdev_by_index(int);
extern __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope); extern __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope);
extern __be32 inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, int scope); extern __be32 inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, int scope);
......
...@@ -147,7 +147,7 @@ void in_dev_finish_destroy(struct in_device *idev) ...@@ -147,7 +147,7 @@ void in_dev_finish_destroy(struct in_device *idev)
} }
} }
struct in_device *inetdev_init(struct net_device *dev) static struct in_device *inetdev_init(struct net_device *dev)
{ {
struct in_device *in_dev; struct in_device *in_dev;
...@@ -404,13 +404,11 @@ static int inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa) ...@@ -404,13 +404,11 @@ static int inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa)
ASSERT_RTNL(); ASSERT_RTNL();
if (!in_dev) {
in_dev = inetdev_init(dev);
if (!in_dev) { if (!in_dev) {
inet_free_ifa(ifa); inet_free_ifa(ifa);
return -ENOBUFS; return -ENOBUFS;
} }
} ipv4_devconf_setall(in_dev);
if (ifa->ifa_dev != in_dev) { if (ifa->ifa_dev != in_dev) {
BUG_TRAP(!ifa->ifa_dev); BUG_TRAP(!ifa->ifa_dev);
in_dev_hold(in_dev); in_dev_hold(in_dev);
...@@ -519,13 +517,12 @@ static struct in_ifaddr *rtm_to_ifaddr(struct nlmsghdr *nlh) ...@@ -519,13 +517,12 @@ static struct in_ifaddr *rtm_to_ifaddr(struct nlmsghdr *nlh)
} }
in_dev = __in_dev_get_rtnl(dev); in_dev = __in_dev_get_rtnl(dev);
if (in_dev == NULL) {
in_dev = inetdev_init(dev);
if (in_dev == NULL) { if (in_dev == NULL) {
err = -ENOBUFS; err = -ENOBUFS;
goto errout; goto errout;
} }
}
ipv4_devconf_setall(in_dev);
ifa = inet_alloc_ifa(); ifa = inet_alloc_ifa();
if (ifa == NULL) { if (ifa == NULL) {
......
...@@ -152,9 +152,11 @@ struct net_device *ipmr_new_tunnel(struct vifctl *v) ...@@ -152,9 +152,11 @@ struct net_device *ipmr_new_tunnel(struct vifctl *v)
dev->flags |= IFF_MULTICAST; dev->flags |= IFF_MULTICAST;
in_dev = __in_dev_get_rtnl(dev); in_dev = __in_dev_get_rtnl(dev);
if (in_dev == NULL && (in_dev = inetdev_init(dev)) == NULL) if (in_dev == NULL)
goto failure; goto failure;
IN_DEV_CONF_SET(in_dev, RP_FILTER, 0);
ipv4_devconf_setall(in_dev);
IPV4_DEVCONF(in_dev->cnf, RP_FILTER) = 0;
if (dev_open(dev)) if (dev_open(dev))
goto failure; goto failure;
...@@ -218,10 +220,15 @@ static struct net_device *ipmr_reg_vif(void) ...@@ -218,10 +220,15 @@ static struct net_device *ipmr_reg_vif(void)
} }
dev->iflink = 0; dev->iflink = 0;
if ((in_dev = inetdev_init(dev)) == NULL) rcu_read_lock();
if ((in_dev = __in_dev_get_rcu(dev)) == NULL) {
rcu_read_unlock();
goto failure; goto failure;
}
IN_DEV_CONF_SET(in_dev, RP_FILTER, 0); ipv4_devconf_setall(in_dev);
IPV4_DEVCONF(in_dev->cnf, RP_FILTER) = 0;
rcu_read_unlock();
if (dev_open(dev)) if (dev_open(dev))
goto failure; goto failure;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment