Revision: 526
          http://vde.svn.sourceforge.net/vde/?rev=526&view=rev
Author:   rd235
Date:     2011-12-21 17:28:47 +0000 (Wed, 21 Dec 2011)
Log Message:
-----------
IPN: kernel module update for Linux >= 3.1.0

Modified Paths:
--------------
    trunk/ipn/af_ipn.c

Modified: trunk/ipn/af_ipn.c
===================================================================
--- trunk/ipn/af_ipn.c  2011-12-15 23:08:42 UTC (rev 525)
+++ trunk/ipn/af_ipn.c  2011-12-21 17:28:47 UTC (rev 526)
@@ -56,6 +56,9 @@
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39)
 #define IPN_PRE2639
 #endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,1,0)
+#define IPN_PRE310
+#endif
 
 /*extension of RCV_SHUTDOWN defined in include/net/sock.h
  * when the bit is set recv fails */
@@ -569,10 +572,180 @@
 }
 
 /* IPN BIND */
+#ifndef IPN_PRE310
 static int ipn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 {
        struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
        struct ipn_node *ipn_node=((struct ipn_sock *)sock->sk)->node;
+       struct path path;
+       struct ipn_network *ipnn;
+       struct dentry * dentry = NULL;
+       int err;
+       struct pre_bind_parms parms=STD_BIND_PARMS;
+
+       //printk("IPN bind\n");
+
+       if (down_interruptible(&ipn_glob_mutex))
+               return -ERESTARTSYS;
+       if (sock->state != SS_UNCONNECTED || 
+                       ipn_node->ipn != NULL) {
+               err= -EISCONN;
+               goto out;
+       }
+
+       if (ipn_node->protocol >= 0 && 
+                       (ipn_node->protocol >= IPN_MAX_PROTO ||
+                        ipn_protocol_table[ipn_node->protocol] == NULL)) {
+               err= -EPROTONOSUPPORT;
+               goto out;
+       }
+
+       addr_len = ipn_mkname(sunaddr, addr_len);
+       if (addr_len < 0) {
+               err=addr_len;
+               goto out;
+       }
+
+       /* check if there is already an ipn-network socket with that name */
+       err = kern_path(sunaddr->sun_path, LOOKUP_FOLLOW, &path);
+       if (err) { /* it does not exist, NEW IPN socket! */
+               unsigned int mode;
+               /* Do I have the permission to create a file? */
+               dentry = kern_path_create(AT_FDCWD, sunaddr->sun_path, &path, 
0);
+               err = PTR_ERR(dentry);
+               if (IS_ERR(dentry))
+                       goto out_mknod_unlock;
+               /*
+                * All right, let's create it.
+                */
+               if (ipn_node->pbp) 
+                       mode = ipn_node->pbp->mode;
+               else
+                       mode = SOCK_INODE(sock)->i_mode;
+               mode = S_IFSOCK | (mode & ~current_umask());
+               err = mnt_want_write(path.mnt);
+               if (err)
+                       goto out_mknod_dput;
+               if (!err) {
+#ifdef APPARMOR
+                       err = vfs_mknod(path.dentry->d_inode, dentry, path.mnt, 
mode, 0);
+#else
+                       err = vfs_mknod(path.dentry->d_inode, dentry, mode, 0);
+#endif
+               }
+               mnt_drop_write(path.mnt);
+               if (err)
+                       goto out_mknod_dput;
+               mutex_unlock(&path.dentry->d_inode->i_mutex);
+               dput(path.dentry);
+               path.dentry = dentry;
+               /* create a new ipn_network item */
+               if (ipn_node->pbp) 
+                       parms=*ipn_node->pbp;
+               ipnn=kmem_cache_zalloc(ipn_network_cache,GFP_KERNEL); 
+               if (!ipnn) {
+                       err=-ENOMEM;
+                       goto out_mknod_dput_ipnn;
+               }
+               ipnn->connport=kzalloc(parms.maxports * sizeof(struct ipn_node 
*),GFP_KERNEL);
+               if (!ipnn->connport) {
+                       err=-ENOMEM;
+                       goto out_mknod_dput_ipnn2;
+               }
+
+               /* module refcnt is incremented for each network, thus
+                * rmmod is forbidden if there are persistent nodes */
+               if (!try_module_get(THIS_MODULE)) {
+                       err = -EINVAL;
+                       goto out_mknod_dput_ipnn2;
+               }
+               memcpy(&ipnn->sunaddr,sunaddr,addr_len);
+               ipnn->mtu=parms.mtu;
+               ipnn->flags=parms.flags;
+               if (ipnn->flags & IPN_FLAG_FLEXMTU)
+                       ipnn->msgpool_cache= NULL;
+               else {
+                       ipnn->msgpool_cache=ipn_msgbuf_get(ipnn->mtu);
+                       if (!ipnn->msgpool_cache) {
+                               err=-ENOMEM;
+                               goto out_mknod_dput_putmodule;
+                       }
+               }
+               INIT_LIST_HEAD(&ipnn->unconnectqueue);
+               INIT_LIST_HEAD(&ipnn->connectqueue);
+               ipnn->refcnt=0;
+               ipnn->dentry=path.dentry;
+               ipnn->mnt=path.mnt;
+               sema_init(&ipnn->ipnn_mutex,1);
+               ipnn->sunaddr_len=addr_len;
+               ipnn->protocol=ipn_node->protocol;
+               if (ipnn->protocol < 0) ipnn->protocol = 0;
+               ipn_protocol_table[ipnn->protocol]->refcnt++;
+               ipnn->numreaders=0;
+               ipnn->numwriters=0;
+               ipnn->maxports=parms.maxports;
+               atomic_set(&ipnn->msgpool_nelem,0);
+               ipnn->msgpool_size=parms.msgpoolsize;
+               ipnn->proto_private=NULL;
+               init_waitqueue_head(&ipnn->send_wait);
+               ipnn->chrdev=NULL;
+               err=ipn_protocol_table[ipnn->protocol]->ipn_p_newnet(ipnn);
+               if (err)
+                       goto out_mknod_dput_putmodule;
+               
ipn_insert_network(&ipn_network_table[path.dentry->d_inode->i_ino & 
(IPN_HASH_SIZE-1)],ipnn);
+       } else {
+               /* join an existing network */
+               if (parms.flags & IPN_FLAG_EXCL) {
+                       err=-EEXIST;
+                       goto put_fail;
+               }
+               err = inode_permission(path.dentry->d_inode, MAY_EXEC);
+               if (err)
+                       goto put_fail;
+               err = -ECONNREFUSED;
+               if (!S_ISSOCK(path.dentry->d_inode->i_mode))
+                       goto put_fail;
+               ipnn=ipn_find_network_byinode(path.dentry->d_inode);
+               if (!ipnn || (ipnn->flags & IPN_FLAG_TERMINATED) ||
+                               (ipnn->flags & IPN_FLAG_EXCL))
+                       goto put_fail;
+       }
+       if (ipn_node->pbp) {
+               kfree(ipn_node->pbp);
+               ipn_node->pbp=NULL;
+       } 
+       ipn_node_bind(ipn_node,ipnn);
+       up(&ipn_glob_mutex);
+       return 0;
+
+put_fail:
+       path_put(&path);
+out:
+       up(&ipn_glob_mutex);
+       return err;
+
+out_mknod_dput_putmodule:
+       module_put(THIS_MODULE);
+out_mknod_dput_ipnn2:
+       kfree(ipnn->connport);
+out_mknod_dput_ipnn:
+       kmem_cache_free(ipn_network_cache,ipnn);
+out_mknod_dput:
+       dput(dentry);
+       mutex_unlock(&path.dentry->d_inode->i_mutex);
+       path_put(&path);
+out_mknod_unlock:
+       if (err==-EEXIST)
+               err=-EADDRINUSE;
+       up(&ipn_glob_mutex);
+       return err;
+}
+#else
+/* pre 3.1.0 */
+static int ipn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
+{
+       struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
+       struct ipn_node *ipn_node=((struct ipn_sock *)sock->sk)->node;
        struct nameidata nd;
        struct ipn_network *ipnn;
        struct dentry * dentry = NULL;
@@ -747,6 +920,7 @@
        up(&ipn_glob_mutex);
        return err;
 }
+#endif
 
 /* IPN CONNECT */
 static int ipn_connect(struct socket *sock, struct sockaddr *addr,

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Write once. Port to many.
Get the SDK and tools to simplify cross-platform app development. Create 
new or port existing apps to sell to consumers worldwide. Explore the 
Intel AppUpSM program developer opportunity. appdeveloper.intel.com/join
http://p.sf.net/sfu/intel-appdev
_______________________________________________
vde-users mailing list
vde-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/vde-users

Reply via email to