2013-10-29 14:10:26 -07:00
|
|
|
#include <linux/if_bridge.h>
|
2010-02-19 16:54:19 -05:00
|
|
|
#include <linux/netdevice.h>
|
2013-10-29 14:10:26 -07:00
|
|
|
#include <linux/version.h>
|
2015-12-03 11:40:53 -08:00
|
|
|
#include <net/rtnetlink.h>
|
2013-10-29 14:10:26 -07:00
|
|
|
|
2016-07-07 19:35:33 -07:00
|
|
|
#include "gso.h"
|
|
|
|
|
#include "vport.h"
|
|
|
|
|
#include "vport-internal_dev.h"
|
|
|
|
|
#include "vport-netdev.h"
|
|
|
|
|
|
2013-10-29 14:10:26 -07:00
|
|
|
#ifndef HAVE_DEV_DISABLE_LRO
|
2010-02-19 16:54:19 -05:00
|
|
|
|
2010-05-06 13:37:49 -07:00
|
|
|
#ifdef NETIF_F_LRO
|
2010-02-19 16:54:19 -05:00
|
|
|
#include <linux/ethtool.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);
|
|
|
|
|
}
|
2010-05-06 15:15:50 -07:00
|
|
|
#else
|
|
|
|
|
void dev_disable_lro(struct net_device *dev) { }
|
2010-02-19 16:54:19 -05:00
|
|
|
#endif /* NETIF_F_LRO */
|
|
|
|
|
|
2010-05-06 15:15:50 -07:00
|
|
|
#endif /* HAVE_DEV_DISABLE_LRO */
|
2013-10-29 14:10:26 -07:00
|
|
|
|
2015-12-03 11:40:53 -08:00
|
|
|
int rpl_rtnl_delete_link(struct net_device *dev)
|
|
|
|
|
{
|
|
|
|
|
const struct rtnl_link_ops *ops;
|
|
|
|
|
|
|
|
|
|
ops = dev->rtnl_link_ops;
|
|
|
|
|
if (!ops || !ops->dellink)
|
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
|
|
|
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34)
|
|
|
|
|
ops->dellink(dev);
|
|
|
|
|
#else
|
|
|
|
|
{
|
|
|
|
|
LIST_HEAD(list_kill);
|
|
|
|
|
|
|
|
|
|
ops->dellink(dev, &list_kill);
|
|
|
|
|
unregister_netdevice_many(&list_kill);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2016-07-07 19:35:33 -07:00
|
|
|
|
|
|
|
|
#ifndef HAVE_NDO_FILL_METADATA_DST
|
|
|
|
|
int ovs_dev_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
|
|
|
|
|
{
|
|
|
|
|
struct ip_tunnel_info *info;
|
|
|
|
|
struct vport *vport;
|
|
|
|
|
|
|
|
|
|
if (!SKB_SETUP_FILL_METADATA_DST(skb))
|
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
|
|
vport = ovs_netdev_get_vport(dev);
|
|
|
|
|
if (!vport)
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
|
|
if (!vport->ops->fill_metadata_dst)
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
|
|
info = skb_tunnel_info(skb);
|
|
|
|
|
if (!info)
|
|
|
|
|
return -ENOMEM;
|
|
|
|
|
if (unlikely(!(info->mode & IP_TUNNEL_INFO_TX)))
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
|
|
return vport->ops->fill_metadata_dst(dev, skb);
|
|
|
|
|
}
|
|
|
|
|
EXPORT_SYMBOL_GPL(ovs_dev_fill_metadata_dst);
|
|
|
|
|
#endif
|