aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/addrconf.c
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2008-06-19 19:15:47 -0400
committerDavid S. Miller <davem@davemloft.net>2008-06-19 19:15:47 -0400
commit0187bdfb05674147774ca79a79942537f3ad54bd (patch)
tree43980261ce9e2b6ef76356dbbbc7efe3dbb60a02 /net/ipv6/addrconf.c
parent2e3216cd54b142ba605e87522e15f42e0c4e3996 (diff)
net: Disable LRO on devices that are forwarding
Large Receive Offload (LRO) is only appropriate for packets that are destined for the host, and should be disabled if received packets may be forwarded. It can also confuse the GSO on output. Add dev_disable_lro() function which uses the appropriate ethtool ops to disable LRO if enabled. Add calls to dev_disable_lro() in br_add_if() and functions that enable IPv4 and IPv6 forwarding. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r--net/ipv6/addrconf.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 9be6be3a7ff3..84127d854cfc 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -348,6 +348,8 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
348 kfree(ndev); 348 kfree(ndev);
349 return NULL; 349 return NULL;
350 } 350 }
351 if (ndev->cnf.forwarding)
352 dev_disable_lro(dev);
351 /* We refer to the device */ 353 /* We refer to the device */
352 dev_hold(dev); 354 dev_hold(dev);
353 355
@@ -442,6 +444,8 @@ static void dev_forward_change(struct inet6_dev *idev)
442 if (!idev) 444 if (!idev)
443 return; 445 return;
444 dev = idev->dev; 446 dev = idev->dev;
447 if (idev->cnf.forwarding)
448 dev_disable_lro(dev);
445 if (dev && (dev->flags & IFF_MULTICAST)) { 449 if (dev && (dev->flags & IFF_MULTICAST)) {
446 if (idev->cnf.forwarding) 450 if (idev->cnf.forwarding)
447 ipv6_dev_mc_inc(dev, &in6addr_linklocal_allrouters); 451 ipv6_dev_mc_inc(dev, &in6addr_linklocal_allrouters);
@@ -487,12 +491,14 @@ static void addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old)
487 if (p == &net->ipv6.devconf_dflt->forwarding) 491 if (p == &net->ipv6.devconf_dflt->forwarding)
488 return; 492 return;
489 493
494 rtnl_lock();
490 if (p == &net->ipv6.devconf_all->forwarding) { 495 if (p == &net->ipv6.devconf_all->forwarding) {
491 __s32 newf = net->ipv6.devconf_all->forwarding; 496 __s32 newf = net->ipv6.devconf_all->forwarding;
492 net->ipv6.devconf_dflt->forwarding = newf; 497 net->ipv6.devconf_dflt->forwarding = newf;
493 addrconf_forward_change(net, newf); 498 addrconf_forward_change(net, newf);
494 } else if ((!*p) ^ (!old)) 499 } else if ((!*p) ^ (!old))
495 dev_forward_change((struct inet6_dev *)table->extra1); 500 dev_forward_change((struct inet6_dev *)table->extra1);
501 rtnl_unlock();
496 502
497 if (*p) 503 if (*p)
498 rt6_purge_dflt_routers(net); 504 rt6_purge_dflt_routers(net);