aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/devinet.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/devinet.c')
-rw-r--r--net/ipv4/devinet.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index f8c0b0aea93a..9de2514946ca 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -168,6 +168,8 @@ static struct in_device *inetdev_init(struct net_device *dev)
168 in_dev->dev = dev; 168 in_dev->dev = dev;
169 if ((in_dev->arp_parms = neigh_parms_alloc(dev, &arp_tbl)) == NULL) 169 if ((in_dev->arp_parms = neigh_parms_alloc(dev, &arp_tbl)) == NULL)
170 goto out_kfree; 170 goto out_kfree;
171 if (IPV4_DEVCONF(in_dev->cnf, FORWARDING))
172 dev_disable_lro(dev);
171 /* Reference in_dev->dev */ 173 /* Reference in_dev->dev */
172 dev_hold(dev); 174 dev_hold(dev);
173 /* Account for reference dev->ip_ptr (below) */ 175 /* Account for reference dev->ip_ptr (below) */
@@ -1241,6 +1243,8 @@ static void inet_forward_change(struct net *net)
1241 read_lock(&dev_base_lock); 1243 read_lock(&dev_base_lock);
1242 for_each_netdev(net, dev) { 1244 for_each_netdev(net, dev) {
1243 struct in_device *in_dev; 1245 struct in_device *in_dev;
1246 if (on)
1247 dev_disable_lro(dev);
1244 rcu_read_lock(); 1248 rcu_read_lock();
1245 in_dev = __in_dev_get_rcu(dev); 1249 in_dev = __in_dev_get_rcu(dev);
1246 if (in_dev) 1250 if (in_dev)
@@ -1248,8 +1252,6 @@ static void inet_forward_change(struct net *net)
1248 rcu_read_unlock(); 1252 rcu_read_unlock();
1249 } 1253 }
1250 read_unlock(&dev_base_lock); 1254 read_unlock(&dev_base_lock);
1251
1252 rt_cache_flush(0);
1253} 1255}
1254 1256
1255static int devinet_conf_proc(ctl_table *ctl, int write, 1257static int devinet_conf_proc(ctl_table *ctl, int write,
@@ -1335,10 +1337,19 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write,
1335 if (write && *valp != val) { 1337 if (write && *valp != val) {
1336 struct net *net = ctl->extra2; 1338 struct net *net = ctl->extra2;
1337 1339
1338 if (valp == &IPV4_DEVCONF_ALL(net, FORWARDING)) 1340 if (valp != &IPV4_DEVCONF_DFLT(net, FORWARDING)) {
1339 inet_forward_change(net); 1341 rtnl_lock();
1340 else if (valp != &IPV4_DEVCONF_DFLT(net, FORWARDING)) 1342 if (valp == &IPV4_DEVCONF_ALL(net, FORWARDING)) {
1343 inet_forward_change(net);
1344 } else if (*valp) {
1345 struct ipv4_devconf *cnf = ctl->extra1;
1346 struct in_device *idev =
1347 container_of(cnf, struct in_device, cnf);
1348 dev_disable_lro(idev->dev);
1349 }
1350 rtnl_unlock();
1341 rt_cache_flush(0); 1351 rt_cache_flush(0);
1352 }
1342 } 1353 }
1343 1354
1344 return ret; 1355 return ret;