From: Pravin B Shelar Date: Tue, 29 Oct 2013 21:10:26 +0000 (-0700) Subject: datapath: Simplify vport-netdev-hook compatibility code. X-Git-Tag: sliver-openvswitch-2.0.90-1~6^2~55 X-Git-Url: http://git.onelab.eu/?p=sliver-openvswitch.git;a=commitdiff_plain;h=95986f397de7e5eb8d202c115d1dab5b67777747 datapath: Simplify vport-netdev-hook compatibility code. Move compat code to netdev_rx_handler_register() definition. It also adds type safety for netdev-hook. Signed-off-by: Pravin B Shelar Acked-by: Jesse Gross --- diff --git a/datapath/linux/compat/dev-openvswitch.c b/datapath/linux/compat/dev-openvswitch.c index 5b7444bb3..1035fe83d 100644 --- a/datapath/linux/compat/dev-openvswitch.c +++ b/datapath/linux/compat/dev-openvswitch.c @@ -1,6 +1,8 @@ -#ifndef HAVE_DEV_DISABLE_LRO - +#include #include +#include + +#ifndef HAVE_DEV_DISABLE_LRO #ifdef NETIF_F_LRO #include @@ -30,3 +32,60 @@ void dev_disable_lro(struct net_device *dev) { } #endif /* NETIF_F_LRO */ #endif /* HAVE_DEV_DISABLE_LRO */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) || \ + defined HAVE_RHEL_OVS_HOOK + +static int nr_bridges; + +#ifdef HAVE_RHEL_OVS_HOOK +int 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; +} +#else + +int 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; +} +#endif + +void 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 +} +#endif diff --git a/datapath/linux/compat/include/linux/netdevice.h b/datapath/linux/compat/include/linux/netdevice.h index c5c366bd7..b303f39db 100644 --- a/datapath/linux/compat/include/linux/netdevice.h +++ b/datapath/linux/compat/include/linux/netdevice.h @@ -2,6 +2,7 @@ #define __LINUX_NETDEVICE_WRAPPER_H 1 #include_next +#include struct net; @@ -11,11 +12,6 @@ struct net; #define to_net_dev(class) container_of(class, struct net_device, NETDEV_DEV_MEMBER) #endif -#ifdef HAVE_RHEL_OVS_HOOK -extern struct sk_buff *(*openvswitch_handle_frame_hook)(struct sk_buff *skb); -extern int nr_bridges; -#endif - #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33) extern void unregister_netdevice_queue(struct net_device *dev, struct list_head *head); @@ -28,32 +24,23 @@ extern void dev_disable_lro(struct net_device *dev); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) || \ defined HAVE_RHEL_OVS_HOOK -static inline int netdev_rx_handler_register(struct net_device *dev, - void *rx_handler, - void *rx_handler_data) -{ -#ifdef HAVE_RHEL_OVS_HOOK - rcu_assign_pointer(dev->ax25_ptr, rx_handler_data); - nr_bridges++; - rcu_assign_pointer(openvswitch_handle_frame_hook, rx_handler); -#else - if (dev->br_port) - return -EBUSY; - rcu_assign_pointer(dev->br_port, rx_handler_data); -#endif - return 0; -} -static inline void netdev_rx_handler_unregister(struct net_device *dev) -{ + #ifdef HAVE_RHEL_OVS_HOOK - rcu_assign_pointer(dev->ax25_ptr, NULL); +typedef struct sk_buff *(openvswitch_handle_frame_hook_t)(struct sk_buff *skb); +extern openvswitch_handle_frame_hook_t *openvswitch_handle_frame_hook; - if (--nr_bridges <= 0) - rcu_assign_pointer(openvswitch_handle_frame_hook, NULL); +int netdev_rx_handler_register(struct net_device *dev, + openvswitch_handle_frame_hook_t *hook, + void *rx_handler_data); #else - rcu_assign_pointer(dev->br_port, NULL); + +int netdev_rx_handler_register(struct net_device *dev, + struct sk_buff *(*netdev_hook)(struct net_bridge_port *p, + struct sk_buff *skb), + void *rx_handler_data); #endif -} + +void netdev_rx_handler_unregister(struct net_device *dev); #endif #ifndef HAVE_DEV_GET_BY_INDEX_RCU diff --git a/datapath/linux/compat/netdevice.c b/datapath/linux/compat/netdevice.c index 248066df7..3d28a9ba0 100644 --- a/datapath/linux/compat/netdevice.c +++ b/datapath/linux/compat/netdevice.c @@ -1,10 +1,6 @@ #include #include -#ifdef HAVE_RHEL_OVS_HOOK -int nr_bridges = 0; -#endif - #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38) #ifndef HAVE_CAN_CHECKSUM_PROTOCOL static bool can_checksum_protocol(unsigned long features, __be16 protocol) diff --git a/datapath/vport-netdev.c b/datapath/vport-netdev.c index 778038634..c15923b20 100644 --- a/datapath/vport-netdev.c +++ b/datapath/vport-netdev.c @@ -84,36 +84,6 @@ static struct sk_buff *netdev_frame_hook(struct net_bridge_port *p, #error #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) || \ - defined HAVE_RHEL_OVS_HOOK -static int netdev_init(void) { return 0; } -static void netdev_exit(void) { } -#else -static int port_count; - -static void netdev_init(void) -{ - port_count++; - if (port_count > 1) - return; - - /* Hook into callback used by the bridge to intercept packets. - * Parasites we are. */ - br_handle_frame_hook = netdev_frame_hook; - - return; -} - -static void netdev_exit(void) -{ - port_count--; - if (port_count > 0) - return; - - br_handle_frame_hook = NULL; -} -#endif - static struct net_device *get_dpdev(struct datapath *dp) { struct vport *local; @@ -166,7 +136,6 @@ static struct vport *netdev_create(const struct vport_parms *parms) netdev_vport->dev->priv_flags |= IFF_OVS_DATAPATH; rtnl_unlock(); - netdev_init(); return vport; error_master_upper_dev_unlink: @@ -206,8 +175,6 @@ static void netdev_destroy(struct vport *vport) { struct netdev_vport *netdev_vport = netdev_vport_priv(vport); - netdev_exit(); - rtnl_lock(); if (ovs_netdev_get_vport(netdev_vport->dev)) ovs_netdev_detach_dev(vport);