diff options
Diffstat (limited to 'net/ipv4/devinet.c')
-rw-r--r-- | net/ipv4/devinet.c | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 79a7ef6209ff..2e667e2f90df 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -1,8 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * NET3 IP device support routines. | 2 | * NET3 IP device support routines. |
3 | * | 3 | * |
4 | * Version: $Id: devinet.c,v 1.44 2001/10/31 21:55:54 davem Exp $ | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | 4 | * This program is free software; you can redistribute it and/or |
7 | * modify it under the terms of the GNU General Public License | 5 | * modify it under the terms of the GNU General Public License |
8 | * as published by the Free Software Foundation; either version | 6 | * as published by the Free Software Foundation; either version |
@@ -170,6 +168,8 @@ static struct in_device *inetdev_init(struct net_device *dev) | |||
170 | in_dev->dev = dev; | 168 | in_dev->dev = dev; |
171 | 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) |
172 | goto out_kfree; | 170 | goto out_kfree; |
171 | if (IPV4_DEVCONF(in_dev->cnf, FORWARDING)) | ||
172 | dev_disable_lro(dev); | ||
173 | /* Reference in_dev->dev */ | 173 | /* Reference in_dev->dev */ |
174 | dev_hold(dev); | 174 | dev_hold(dev); |
175 | /* Account for reference dev->ip_ptr (below) */ | 175 | /* Account for reference dev->ip_ptr (below) */ |
@@ -1013,7 +1013,7 @@ static void inetdev_changename(struct net_device *dev, struct in_device *in_dev) | |||
1013 | memcpy(old, ifa->ifa_label, IFNAMSIZ); | 1013 | memcpy(old, ifa->ifa_label, IFNAMSIZ); |
1014 | memcpy(ifa->ifa_label, dev->name, IFNAMSIZ); | 1014 | memcpy(ifa->ifa_label, dev->name, IFNAMSIZ); |
1015 | if (named++ == 0) | 1015 | if (named++ == 0) |
1016 | continue; | 1016 | goto skip; |
1017 | dot = strchr(old, ':'); | 1017 | dot = strchr(old, ':'); |
1018 | if (dot == NULL) { | 1018 | if (dot == NULL) { |
1019 | sprintf(old, ":%d", named); | 1019 | sprintf(old, ":%d", named); |
@@ -1024,6 +1024,8 @@ static void inetdev_changename(struct net_device *dev, struct in_device *in_dev) | |||
1024 | } else { | 1024 | } else { |
1025 | strcpy(ifa->ifa_label + (IFNAMSIZ - strlen(dot) - 1), dot); | 1025 | strcpy(ifa->ifa_label + (IFNAMSIZ - strlen(dot) - 1), dot); |
1026 | } | 1026 | } |
1027 | skip: | ||
1028 | rtmsg_ifa(RTM_NEWADDR, ifa, NULL, 0); | ||
1027 | } | 1029 | } |
1028 | } | 1030 | } |
1029 | 1031 | ||
@@ -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 | ||
1255 | static int devinet_conf_proc(ctl_table *ctl, int write, | 1257 | static 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)) { |
1341 | rt_cache_flush(0); | 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(); | ||
1351 | rt_cache_flush(net, 0); | ||
1352 | } | ||
1342 | } | 1353 | } |
1343 | 1354 | ||
1344 | return ret; | 1355 | return ret; |
@@ -1351,9 +1362,10 @@ int ipv4_doint_and_flush(ctl_table *ctl, int write, | |||
1351 | int *valp = ctl->data; | 1362 | int *valp = ctl->data; |
1352 | int val = *valp; | 1363 | int val = *valp; |
1353 | int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); | 1364 | int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); |
1365 | struct net *net = ctl->extra2; | ||
1354 | 1366 | ||
1355 | if (write && *valp != val) | 1367 | if (write && *valp != val) |
1356 | rt_cache_flush(0); | 1368 | rt_cache_flush(net, 0); |
1357 | 1369 | ||
1358 | return ret; | 1370 | return ret; |
1359 | } | 1371 | } |
@@ -1364,9 +1376,10 @@ int ipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen, | |||
1364 | { | 1376 | { |
1365 | int ret = devinet_conf_sysctl(table, name, nlen, oldval, oldlenp, | 1377 | int ret = devinet_conf_sysctl(table, name, nlen, oldval, oldlenp, |
1366 | newval, newlen); | 1378 | newval, newlen); |
1379 | struct net *net = table->extra2; | ||
1367 | 1380 | ||
1368 | if (ret == 1) | 1381 | if (ret == 1) |
1369 | rt_cache_flush(0); | 1382 | rt_cache_flush(net, 0); |
1370 | 1383 | ||
1371 | return ret; | 1384 | return ret; |
1372 | } | 1385 | } |