Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 103069
b: refs/heads/master
c: 0187bdf
h: refs/heads/master
i:
  103067: d60ce6a
v: v3
  • Loading branch information
Ben Hutchings authored and David S. Miller committed Jun 19, 2008
1 parent 59291ab commit 4909fb7
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 6 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2e3216cd54b142ba605e87522e15f42e0c4e3996
refs/heads/master: 0187bdfb05674147774ca79a79942537f3ad54bd
1 change: 1 addition & 0 deletions trunk/include/linux/netdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -886,6 +886,7 @@ extern struct net_device *__dev_get_by_name(struct net *net, const char *name);
extern int dev_alloc_name(struct net_device *dev, const char *name);
extern int dev_open(struct net_device *dev);
extern int dev_close(struct net_device *dev);
extern void dev_disable_lro(struct net_device *dev);
extern int dev_queue_xmit(struct sk_buff *skb);
extern int register_netdevice(struct net_device *dev);
extern void unregister_netdevice(struct net_device *dev);
Expand Down
1 change: 1 addition & 0 deletions trunk/net/bridge/br_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
goto err2;

rcu_assign_pointer(dev->br_port, p);
dev_disable_lro(dev);
dev_set_promiscuity(dev, 1);

list_add_rcu(&p->list, &br->port_list);
Expand Down
24 changes: 24 additions & 0 deletions trunk/net/core/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
#include <linux/if_ether.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/notifier.h>
#include <linux/skbuff.h>
#include <net/net_namespace.h>
Expand Down Expand Up @@ -1123,6 +1124,29 @@ int dev_close(struct net_device *dev)
}


/**
* dev_disable_lro - disable Large Receive Offload on a device
* @dev: device
*
* Disable Large Receive Offload (LRO) on a net device. Must be
* called under RTNL. This is needed if received packets may be
* forwarded to another interface.
*/
void dev_disable_lro(struct net_device *dev)
{
if (dev->ethtool_ops && dev->ethtool_ops->get_flags &&
dev->ethtool_ops->set_flags) {
u32 flags = dev->ethtool_ops->get_flags(dev);
if (flags & ETH_FLAG_LRO) {
flags &= ~ETH_FLAG_LRO;
dev->ethtool_ops->set_flags(dev, flags);
}
}
WARN_ON(dev->features & NETIF_F_LRO);
}
EXPORT_SYMBOL(dev_disable_lro);


static int dev_boot_phase = 1;

/*
Expand Down
21 changes: 16 additions & 5 deletions trunk/net/ipv4/devinet.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ static struct in_device *inetdev_init(struct net_device *dev)
in_dev->dev = dev;
if ((in_dev->arp_parms = neigh_parms_alloc(dev, &arp_tbl)) == NULL)
goto out_kfree;
if (IPV4_DEVCONF(in_dev->cnf, FORWARDING))
dev_disable_lro(dev);
/* Reference in_dev->dev */
dev_hold(dev);
/* Account for reference dev->ip_ptr (below) */
Expand Down Expand Up @@ -1241,15 +1243,15 @@ static void inet_forward_change(struct net *net)
read_lock(&dev_base_lock);
for_each_netdev(net, dev) {
struct in_device *in_dev;
if (on)
dev_disable_lro(dev);
rcu_read_lock();
in_dev = __in_dev_get_rcu(dev);
if (in_dev)
IN_DEV_CONF_SET(in_dev, FORWARDING, on);
rcu_read_unlock();
}
read_unlock(&dev_base_lock);

rt_cache_flush(0);
}

static int devinet_conf_proc(ctl_table *ctl, int write,
Expand Down Expand Up @@ -1335,10 +1337,19 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write,
if (write && *valp != val) {
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);
}
}

return ret;
Expand Down
6 changes: 6 additions & 0 deletions trunk/net/ipv6/addrconf.c
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,8 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
kfree(ndev);
return NULL;
}
if (ndev->cnf.forwarding)
dev_disable_lro(dev);
/* We refer to the device */
dev_hold(dev);

Expand Down Expand Up @@ -442,6 +444,8 @@ static void dev_forward_change(struct inet6_dev *idev)
if (!idev)
return;
dev = idev->dev;
if (idev->cnf.forwarding)
dev_disable_lro(dev);
if (dev && (dev->flags & IFF_MULTICAST)) {
if (idev->cnf.forwarding)
ipv6_dev_mc_inc(dev, &in6addr_linklocal_allrouters);
Expand Down Expand Up @@ -487,12 +491,14 @@ static void addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old)
if (p == &net->ipv6.devconf_dflt->forwarding)
return;

rtnl_lock();
if (p == &net->ipv6.devconf_all->forwarding) {
__s32 newf = net->ipv6.devconf_all->forwarding;
net->ipv6.devconf_dflt->forwarding = newf;
addrconf_forward_change(net, newf);
} else if ((!*p) ^ (!old))
dev_forward_change((struct inet6_dev *)table->extra1);
rtnl_unlock();

if (*p)
rt6_purge_dflt_routers(net);
Expand Down

0 comments on commit 4909fb7

Please sign in to comment.