From 2e77b99a657c07557f1176b63b2ee5667fe9ffb2 Mon Sep 17 00:00:00 2001 From: rd235 Date: Wed, 26 Jan 2011 16:59:50 +0000 Subject: [PATCH] port to 2.6.37: mutex changed into semaphore and netdev_rx_handler management git-svn-id: https://vde.svn.sourceforge.net/svnroot/vde/trunk@464 d37a7db1-d92d-0410-89df-f68f52f87b57 --- ipn/README | 6 ++++++ ipn/af_ipn.c | 9 ++++++++- ipn/af_ipn.h | 3 +++ ipn/ipn_chrdev.c | 12 ++++++++++++ ipn/ipn_netdev.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- ipn/ipn_netdev.h | 9 ++++++++- 6 files changed, 84 insertions(+), 4 deletions(-) diff --git a/ipn/README b/ipn/README index f505c53..3eb97ab 100644 --- a/ipn/README +++ b/ipn/README @@ -169,6 +169,12 @@ I can write the patch (it needs just tens of minutes of cut&paste). We are studying some way to register/deregister grabbing services, I feel this would be the cleanest way. ++----- +|Note (2011 January): This issue seems to have been solved in 2.6.37 +| the new interface netdev_rx_handler_{register,unregister} can +| be effectively used for ipn. ++----- + WHERE? ------ There is an experimental version in the VDE svn tree. diff --git a/ipn/af_ipn.c b/ipn/af_ipn.c index e61d169..197578d 100644 --- a/ipn/af_ipn.c +++ b/ipn/af_ipn.c @@ -47,6 +47,9 @@ MODULE_DESCRIPTION("IPN Kernel Module"); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32) #define IPN_PRE2632 #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) +#define IPN_PRE2637 +#endif /*extension of RCV_SHUTDOWN defined in include/net/sock.h * when the bit is set recv fails */ @@ -59,7 +62,11 @@ MODULE_DESCRIPTION("IPN Kernel Module"); /* Global MUTEX: this is locked to add/delete/modify networks * this is *not* locked just to send/receive msgs */ +#ifdef IPN_PRE2637 static DECLARE_MUTEX(ipn_glob_mutex); +#else +static DEFINE_SEMAPHORE(ipn_glob_mutex); +#endif /* Network table and hash */ struct hlist_head ipn_network_table[IPN_HASH_SIZE + 1]; /* slab(s) for fast data structure allocation */ @@ -690,7 +697,7 @@ static int ipn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) ipnn->dentry=nd.dentry; ipnn->mnt=nd.mnt; #endif - init_MUTEX(&ipnn->ipnn_mutex); + sema_init(&ipnn->ipnn_mutex,1); ipnn->sunaddr_len=addr_len; ipnn->protocol=ipn_node->protocol; if (ipnn->protocol < 0) ipnn->protocol = 0; diff --git a/ipn/af_ipn.h b/ipn/af_ipn.h index f8eb349..241e456 100644 --- a/ipn/af_ipn.h +++ b/ipn/af_ipn.h @@ -1,12 +1,15 @@ #ifndef __LINUX_NET_AFIPN_H #define __LINUX_NET_AFIPN_H #include +#include #ifdef IPN_STEALING /* AF_NETBEUI seems to be unused */ #define AF_IPN AF_NETBEUI #define PF_IPN AF_IPN +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) #define ipn_handle_frame_hook br_handle_frame_hook +#endif #else #ifndef AF_IPN /* waiting for the official assigment of our AF */ diff --git a/ipn/ipn_chrdev.c b/ipn/ipn_chrdev.c index f86db38..d0a9de5 100644 --- a/ipn/ipn_chrdev.c +++ b/ipn/ipn_chrdev.c @@ -28,9 +28,13 @@ #include #include #include +#include #include "af_ipn.h" #include "ipn_chrdev.h" #include "ipn_msgbuf.h" +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) +#define IPN_PRE2637 +#endif #define IPN_CHRDEV_PERSISTENT 1 /* struct ipn_chrdev: @@ -113,7 +117,11 @@ static unsigned int ipn_chrdev_poll(struct file *filp, poll_table *wait) return ipn_node_poll(ipn_node,filp,wait); } +#ifdef IPN_PRE2637 static int ipn_chrdev_ioctl(struct inode *ino, struct file *filp, unsigned int cmd, unsigned long arg) +#else +static long ipn_chrdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +#endif { struct ipn_node *ipn_node=filp->private_data; return ipn_node_ioctl(ipn_node,cmd,arg); @@ -126,7 +134,11 @@ struct file_operations ipn_chrdev_fops = { .read = ipn_chrdev_read, .release = ipn_chrdev_release, .poll = ipn_chrdev_poll, +#ifdef IPN_PRE2637 .ioctl = ipn_chrdev_ioctl +#else + .unlocked_ioctl = ipn_chrdev_ioctl +#endif }; /* init a struct ipn_chrdev and add the cdev */ diff --git a/ipn/ipn_netdev.c b/ipn/ipn_netdev.c index 0107939..03e331b 100644 --- a/ipn/ipn_netdev.c +++ b/ipn/ipn_netdev.c @@ -36,9 +36,15 @@ #define DRV_NAME "ipn" #define DRV_VERSION "0.3.1" +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) +#define IPN_PRE2624 +#endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) #define IPN_PRE2629 #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) +#define IPN_PRE2637 +#endif static const struct ethtool_ops ipn_ethtool_ops; @@ -93,11 +99,18 @@ drop: return 0; } +#ifdef IPN_PRE2637 /* receive from a GRAB via interface hook */ struct sk_buff *ipn_handle_hook(struct ipn_node *ipn_node, struct sk_buff *skb) +#else +static struct sk_buff *ipn_handle_frame(struct sk_buff *skb) +#endif { char *data=(skb->data)-(skb->mac_len); int len=skb->len+skb->mac_len; +#ifndef IPN_PRE2637 + struct ipn_node *ipn_node=ipn_netdev2node(skb->dev); +#endif if (ipn_node && ((ipn_node->flags & IPN_NODEFLAG_DEVMASK) == IPN_NODEFLAG_GRAB) && @@ -161,6 +174,7 @@ struct net_device *ipn_netdev_alloc(struct net *net,int type, char *name, int *e random_ether_addr(dev->dev_addr); break; case IPN_NODEFLAG_GRAB: +#ifdef IPN_PRE2637 #ifdef IPN_STEALING /* only if bridge is not working */ if (ipn_handle_frame_hook != (void *) ipn_handle_hook) { @@ -168,7 +182,8 @@ struct net_device *ipn_netdev_alloc(struct net *net,int type, char *name, int *e return NULL; } #endif -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) +#endif +#ifdef IPN_PRE2624 dev=dev_get_by_name(name); #else dev=dev_get_by_name(net,name); @@ -176,8 +191,13 @@ struct net_device *ipn_netdev_alloc(struct net *net,int type, char *name, int *e if (dev) { if (dev->flags & IFF_LOOPBACK) *err= -EINVAL; +#ifdef IPN_PRE2637 else if (rcu_dereference(dev->ipn_port) != NULL) *err= -EBUSY; +#else + else if (rcu_dereference(dev->rx_handler) != NULL) + *err= -EBUSY; +#endif if (*err) dev=NULL; } @@ -195,12 +215,19 @@ int ipn_netdev_activate(struct ipn_node *ipn_node) struct ipntap *ipntap=netdev_priv(ipn_node->netdev); ipntap->ipn_node=ipn_node; rtnl_lock(); - if ((rv=register_netdevice(ipn_node->netdev)) == 0) + if ((rv=register_netdevice(ipn_node->netdev)) == 0) { +#ifdef IPN_PRE2637 rcu_assign_pointer(ipn_node->netdev->ipn_port, #ifdef IPN_STEALING (void *) #endif ipn_node); +#else + netdev_rx_handler_register(ipn_node->netdev, + ipn_handle_frame, + ipn_node); +#endif + } rtnl_unlock(); if (rv) {/* error! */ ipn_node->flags &= ~IPN_NODEFLAG_DEVMASK; @@ -210,11 +237,17 @@ int ipn_netdev_activate(struct ipn_node *ipn_node) break; case IPN_NODEFLAG_GRAB: rtnl_lock(); +#ifdef IPN_PRE2637 rcu_assign_pointer(ipn_node->netdev->ipn_port, #ifdef IPN_STEALING (void *) #endif ipn_node); +#else + netdev_rx_handler_register(ipn_node->netdev, + ipn_handle_frame, + ipn_node); +#endif dev_set_promiscuity(ipn_node->netdev,1); rtnl_unlock(); rv=0; @@ -229,7 +262,11 @@ void ipn_netdev_close(struct ipn_node *ipn_node) case IPN_NODEFLAG_TAP: ipn_node->flags &= ~IPN_NODEFLAG_DEVMASK; rtnl_lock(); +#ifdef IPN_PRE2637 rcu_assign_pointer(ipn_node->netdev->ipn_port, NULL); +#else + netdev_rx_handler_unregister(ipn_node->netdev); +#endif unregister_netdevice(ipn_node->netdev); rtnl_unlock(); free_netdev(ipn_node->netdev); @@ -237,7 +274,11 @@ void ipn_netdev_close(struct ipn_node *ipn_node) case IPN_NODEFLAG_GRAB: ipn_node->flags &= ~IPN_NODEFLAG_DEVMASK; rtnl_lock(); +#ifdef IPN_PRE2637 rcu_assign_pointer(ipn_node->netdev->ipn_port, NULL); +#else + netdev_rx_handler_unregister(ipn_node->netdev); +#endif dev_set_promiscuity(ipn_node->netdev,-1); rtnl_unlock(); break; @@ -313,6 +354,7 @@ static const struct ethtool_ops ipn_ethtool_ops = { int ipn_netdev_init(void) { +#ifdef IPN_PRE2637 #ifdef IPN_STEALING if (ipn_handle_frame_hook != NULL) printk (KERN_WARNING "IPN interface GRAB disabled (stealing mode) if bridge is loaded\n"); @@ -323,15 +365,18 @@ int ipn_netdev_init(void) (void *) #endif ipn_handle_hook; +#endif return 0; } void ipn_netdev_fini(void) { +#ifdef IPN_PRE2637 #ifdef IPN_STEALING /* only if bridge is not working */ if (ipn_handle_frame_hook == (void *) ipn_handle_hook) #endif ipn_handle_frame_hook=NULL; +#endif } diff --git a/ipn/ipn_netdev.h b/ipn/ipn_netdev.h index 8594708..e96850c 100644 --- a/ipn/ipn_netdev.h +++ b/ipn/ipn_netdev.h @@ -30,13 +30,16 @@ #include #include #include +#include #include /*#include */ #include "af_ipn.h" +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) #ifdef IPN_STEALING #define ipn_port br_port #endif +#endif struct net_device *ipn_netdev_alloc(struct net *net,int type, char *name, int *err); int ipn_netdev_activate(struct ipn_node *ipn_node); @@ -47,7 +50,11 @@ void ipn_netdev_fini(void); static inline struct ipn_node *ipn_netdev2node(struct net_device *dev) { - return (struct ipn_node *)rcu_dereference(dev->ipn_port); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) + return (struct ipn_node *) rcu_dereference(dev->ipn_port); +#else + return (struct ipn_node *) rcu_dereference(dev->rx_handler_data); +#endif } static inline void ipn_netdevsync(void) -- 2.11.4.GIT