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);
 
                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);
 
 #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>
 }
 
 
+/**
+ *     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;
 
 /*
 
        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) */
        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)
                rcu_read_unlock();
        }
        read_unlock(&dev_base_lock);
-
-       rt_cache_flush(0);
 }
 
 static int devinet_conf_proc(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;
 
                kfree(ndev);
                return NULL;
        }
+       if (ndev->cnf.forwarding)
+               dev_disable_lro(dev);
        /* We refer to the device */
        dev_hold(dev);
 
        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);
        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);