|
@@ -168,6 +168,8 @@ static struct in_device *inetdev_init(struct net_device *dev)
|
|
in_dev->dev = dev;
|
|
in_dev->dev = dev;
|
|
if ((in_dev->arp_parms = neigh_parms_alloc(dev, &arp_tbl)) == NULL)
|
|
if ((in_dev->arp_parms = neigh_parms_alloc(dev, &arp_tbl)) == NULL)
|
|
goto out_kfree;
|
|
goto out_kfree;
|
|
|
|
+ if (IPV4_DEVCONF(in_dev->cnf, FORWARDING))
|
|
|
|
+ dev_disable_lro(dev);
|
|
/* Reference in_dev->dev */
|
|
/* Reference in_dev->dev */
|
|
dev_hold(dev);
|
|
dev_hold(dev);
|
|
/* Account for reference dev->ip_ptr (below) */
|
|
/* Account for reference dev->ip_ptr (below) */
|
|
@@ -1241,6 +1243,8 @@ static void inet_forward_change(struct net *net)
|
|
read_lock(&dev_base_lock);
|
|
read_lock(&dev_base_lock);
|
|
for_each_netdev(net, dev) {
|
|
for_each_netdev(net, dev) {
|
|
struct in_device *in_dev;
|
|
struct in_device *in_dev;
|
|
|
|
+ if (on)
|
|
|
|
+ dev_disable_lro(dev);
|
|
rcu_read_lock();
|
|
rcu_read_lock();
|
|
in_dev = __in_dev_get_rcu(dev);
|
|
in_dev = __in_dev_get_rcu(dev);
|
|
if (in_dev)
|
|
if (in_dev)
|
|
@@ -1248,8 +1252,6 @@ static void inet_forward_change(struct net *net)
|
|
rcu_read_unlock();
|
|
rcu_read_unlock();
|
|
}
|
|
}
|
|
read_unlock(&dev_base_lock);
|
|
read_unlock(&dev_base_lock);
|
|
-
|
|
|
|
- rt_cache_flush(0);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
static int devinet_conf_proc(ctl_table *ctl, int write,
|
|
static int devinet_conf_proc(ctl_table *ctl, int write,
|
|
@@ -1335,10 +1337,19 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write,
|
|
if (write && *valp != val) {
|
|
if (write && *valp != val) {
|
|
struct net *net = ctl->extra2;
|
|
struct net *net = ctl->extra2;
|
|
|
|
|
|
- if (valp == &IPV4_DEVCONF_ALL(net, FORWARDING))
|
|
|
|
- inet_forward_change(net);
|
|
|
|
- else if (valp != &IPV4_DEVCONF_DFLT(net, FORWARDING))
|
|
|
|
|
|
+ if (valp != &IPV4_DEVCONF_DFLT(net, FORWARDING)) {
|
|
|
|
+ rtnl_lock();
|
|
|
|
+ if (valp == &IPV4_DEVCONF_ALL(net, FORWARDING)) {
|
|
|
|
+ inet_forward_change(net);
|
|
|
|
+ } else if (*valp) {
|
|
|
|
+ struct ipv4_devconf *cnf = ctl->extra1;
|
|
|
|
+ struct in_device *idev =
|
|
|
|
+ container_of(cnf, struct in_device, cnf);
|
|
|
|
+ dev_disable_lro(idev->dev);
|
|
|
|
+ }
|
|
|
|
+ rtnl_unlock();
|
|
rt_cache_flush(0);
|
|
rt_cache_flush(0);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
return ret;
|
|
return ret;
|