2
0
mirror of https://github.com/openvswitch/ovs synced 2025-10-29 15:28:56 +00:00
Files
openvswitch/datapath/linux/compat/dev-openvswitch.c
Flavio Leitner 572e54faff datapath: check for rx handler register
Red Hat Enterprise Linux 6 has backported the netdev RX
handler facility so use the netdev_rx_handler_register as
an indicator.

The handler prototype changed between 2.6.36 and 2.6.39
since there could be backports in any stage, don't look
at the kernel version, but at the prototype.

Signed-off-by: Flavio Leitner <fbl@redhat.com>
Signed-off-by: Jesse Gross <jesse@nicira.com>
2015-08-31 12:48:16 -07:00

96 lines
2.1 KiB
C

#include <linux/if_bridge.h>
#include <linux/netdevice.h>
#include <linux/version.h>
#ifndef HAVE_DEV_DISABLE_LRO
#ifdef NETIF_F_LRO
#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);
}
#else
void dev_disable_lro(struct net_device *dev) { }
#endif /* NETIF_F_LRO */
#endif /* HAVE_DEV_DISABLE_LRO */
#if !defined HAVE_NETDEV_RX_HANDLER_REGISTER || \
defined HAVE_RHEL_OVS_HOOK
static int nr_bridges;
#ifdef HAVE_RHEL_OVS_HOOK
int rpl_netdev_rx_handler_register(struct net_device *dev,
openvswitch_handle_frame_hook_t *hook,
void *rx_handler_data)
{
nr_bridges++;
rcu_assign_pointer(dev->ax25_ptr, rx_handler_data);
if (nr_bridges == 1)
rcu_assign_pointer(openvswitch_handle_frame_hook, hook);
return 0;
}
EXPORT_SYMBOL_GPL(rpl_netdev_rx_handler_register);
#else
int rpl_netdev_rx_handler_register(struct net_device *dev,
struct sk_buff *(*hook)(struct net_bridge_port *p,
struct sk_buff *skb),
void *rx_handler_data)
{
nr_bridges++;
if (dev->br_port)
return -EBUSY;
rcu_assign_pointer(dev->br_port, rx_handler_data);
if (nr_bridges == 1)
br_handle_frame_hook = hook;
return 0;
}
EXPORT_SYMBOL_GPL(rpl_netdev_rx_handler_register);
#endif
void rpl_netdev_rx_handler_unregister(struct net_device *dev)
{
nr_bridges--;
#ifdef HAVE_RHEL_OVS_HOOK
rcu_assign_pointer(dev->ax25_ptr, NULL);
if (nr_bridges)
return;
rcu_assign_pointer(openvswitch_handle_frame_hook, NULL);
#else
rcu_assign_pointer(dev->br_port, NULL);
if (nr_bridges)
return;
br_handle_frame_hook = NULL;
#endif
}
EXPORT_SYMBOL_GPL(rpl_netdev_rx_handler_unregister);
#endif