/*
 * net/tipc/socket.c: TIPC socket API
 * 
 * Copyright (c) 2001-2006, Ericsson AB
 * Copyright (c) 2004-2005, Wind River Systems
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the names of the copyright holders nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/net.h>
#include <linux/socket.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/poll.h>
#include <linux/fcntl.h>
#include <asm/semaphore.h>
#include <asm/string.h>
#include <asm/atomic.h>
#include <net/sock.h>

#include <linux/tipc.h>
#include <linux/tipc_config.h>
#include <net/tipc/tipc_msg.h>
#include <net/tipc/tipc_port.h>

#include "core.h"

#define SS_LISTENING	-1	/* socket is listening */
#define SS_READY	-2	/* socket is connectionless */

#define OVERLOAD_LIMIT_BASE    5000

struct tipc_sock {
	struct sock sk;
	struct tipc_port *p;
	struct semaphore sem;
};

#define tipc_sk(sk) ((struct tipc_sock*)sk)

static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf);
static void wakeupdispatch(struct tipc_port *tport);

static struct proto_ops packet_ops;
static struct proto_ops stream_ops;
static struct proto_ops msg_ops;

static struct proto tipc_proto;

static int sockets_enabled = 0;

static atomic_t tipc_queue_size = ATOMIC_INIT(0);


/* 
 * sock_lock(): Lock a port/socket pair. lock_sock() can 
 * not be used here, since the same lock must protect ports 
 * with non-socket interfaces.
 * See net.c for description of locking policy.
 */
static void sock_lock(struct tipc_sock* tsock)
{
        spin_lock_bh(tsock->p->lock);       
}

/* 
 * sock_unlock(): Unlock a port/socket pair
 */
static void sock_unlock(struct tipc_sock* tsock)
{
        spin_unlock_bh(tsock->p->lock);
}

/**
 * pollmask - determine the current set of poll() events for a socket
 * @sock: socket structure
 * 
 * TIPC sets the returned events as follows:
 * a) POLLRDNORM and POLLIN are set if the socket's receive queue is non-empty
 *    or if a connection-oriented socket is does not have an active connection
 *    (i.e. a read operation will not block).
 * b) POLLOUT is set except when a socket's connection has been terminated
 *    (i.e. a write operation will not block).
 * c) POLLHUP is set when a socket's connection has been terminated.
 *
 * IMPORTANT: The fact that a read or write operation will not block does NOT
 * imply that the operation will succeed!
 * 
 * Returns pollmask value
 */

static u32 pollmask(struct socket *sock)
{
	u32 mask;

	if ((skb_queue_len(&sock->sk->sk_receive_queue) != 0) ||
	    (sock->state == SS_UNCONNECTED) ||
	    (sock->state == SS_DISCONNECTING))
		mask = (POLLRDNORM | POLLIN);
	else
		mask = 0;

	if (sock->state == SS_DISCONNECTING) 
		mask |= POLLHUP;
	else
		mask |= POLLOUT;

	return mask;
}


/**
 * advance_queue - discard first buffer in queue
 * @tsock: TIPC socket
 */

static void advance_queue(struct tipc_sock *tsock)
{
        sock_lock(tsock);
	buf_discard(skb_dequeue(&tsock->sk.sk_receive_queue));
        sock_unlock(tsock);
	atomic_dec(&tipc_queue_size);
}

/**
 * tipc_create - create a TIPC socket
 * @sock: pre-allocated socket structure
 * @protocol: protocol indicator (must be 0)
 * 
 * This routine creates and attaches a 'struct sock' to the 'struct socket',
 * then create and attaches a TIPC port to the 'struct sock' part.
 *
 * Returns 0 on success, errno otherwise
 */
static int tipc_create(struct socket *sock, int protocol)
{
	struct tipc_sock *tsock;
	struct tipc_port *port;
	struct sock *sk;
        u32 ref;

	if (unlikely(protocol != 0))
		return -EPROTONOSUPPORT;

	ref = tipc_createport_raw(NULL, &dispatch, &wakeupdispatch, TIPC_LOW_IMPORTANCE);
	if (unlikely(!ref))
		return -ENOMEM;

	sock->state = SS_UNCONNECTED;

	switch (sock->type) {
	case SOCK_STREAM:
		sock->ops = &stream_ops;
		break;
	case SOCK_SEQPACKET:
		sock->ops = &packet_ops;
		break;
	case SOCK_DGRAM:
		tipc_set_portunreliable(ref, 1);
		/* fall through */
	case SOCK_RDM:
		tipc_set_portunreturnable(ref, 1);
		sock->ops = &msg_ops;
		sock->state = SS_READY;
		break;
	default:
		tipc_deleteport(ref);
		return -EPROTOTYPE;
	}

	sk = sk_alloc(AF_TIPC, GFP_KERNEL, &tipc_proto, 1);
	if (!sk) {
		tipc_deleteport(ref);
		return -ENOMEM;
	}

	sock_init_data(sock, sk);
	init_waitqueue_head(sk->sk_sleep);
	sk->sk_rcvtimeo = 8 * HZ;   /* default connect timeout = 8s */

	tsock = tipc_sk(sk);
	port = tipc_get_port(ref);

	tsock->p = port;
	port->usr_handle = tsock;

	init_MUTEX(&tsock->sem);

	dbg("sock_create: %x\n",tsock);

	atomic_inc(&tipc_user_count);

	return 0;
}

/**
 * release - destroy a TIPC socket
 * @sock: socket to destroy
 *
 * This routine cleans up any messages that are still queued on the socket.
 * For DGRAM and RDM socket types, all queued messages are rejected.
 * For SEQPACKET and STREAM socket types, the first message is rejected
 * and any others are discarded.  (If the first message on a STREAM socket
 * is partially-read, it is discarded and the next one is rejected instead.)
 * 
 * NOTE: Rejected messages are not necessarily returned to the sender!  They
 * are returned or discarded according to the "destination droppable" setting
 * specified for the message by the sender.
 *
 * Returns 0 on success, errno otherwise
 */

static int release(struct socket *sock)
{
	struct tipc_sock *tsock = tipc_sk(sock->sk);
	struct sock *sk = sock->sk;
	int res = TIPC_OK;
	struct sk_buff *buf;

        dbg("sock_delete: %x\n",tsock);
	if (!tsock)
		return 0;
	down_interruptible(&tsock->sem);
	if (!sock->sk) {
		up(&tsock->sem);
		return 0;
	}
	
	/* Reject unreceived messages, unless no longer connected */

	while (sock->state != SS_DISCONNECTING) {
		sock_lock(tsock);
		buf = skb_dequeue(&sk->sk_receive_queue);
		if (!buf)
			tsock->p->usr_handle = NULL;
		sock_unlock(tsock);
		if (!buf)
			break;
		if (TIPC_SKB_CB(buf)->handle != msg_data(buf_msg(buf)))
			buf_discard(buf);
		else
			tipc_reject_msg(buf, TIPC_ERR_NO_PORT);
		atomic_dec(&tipc_queue_size);
	}

	/* Delete TIPC port */

	res = tipc_deleteport(tsock->p->ref);
	sock->sk = NULL;

	/* Discard any remaining messages */

	while ((buf = skb_dequeue(&sk->sk_receive_queue))) {
		buf_discard(buf);
		atomic_dec(&tipc_queue_size);
	}

	up(&tsock->sem);

	sock_put(sk);

        atomic_dec(&tipc_user_count);
	return res;
}

/**
 * bind - associate or disassocate TIPC name(s) with a socket
 * @sock: socket structure
 * @uaddr: socket address describing name(s) and desired operation
 * @uaddr_len: size of socket address data structure
 * 
 * Name and name sequence binding is indicated using a positive scope value;
 * a negative scope value unbinds the specified name.  Specifying no name
 * (i.e. a socket address length of 0) unbinds all names from the socket.
 * 
 * Returns 0 on success, errno otherwise
 */

static int bind(struct socket *sock, struct sockaddr *uaddr, int uaddr_len)
{
	struct tipc_sock *tsock = tipc_sk(sock->sk);
	struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr;
	int res;

	if (down_interruptible(&tsock->sem))
		return -ERESTARTSYS;
	
	if (unlikely(!uaddr_len)) {
		res = tipc_withdraw(tsock->p->ref, 0, NULL);
		goto exit;
	}

	if (uaddr_len < sizeof(struct sockaddr_tipc)) {
		res = -EINVAL;
		goto exit;
	}

	if (addr->family != AF_TIPC) {
		res = -EAFNOSUPPORT;
		goto exit;
	}
	if (addr->addrtype == TIPC_ADDR_NAME)
		addr->addr.nameseq.upper = addr->addr.nameseq.lower;
	else if (addr->addrtype != TIPC_ADDR_NAMESEQ) {
		res = -EAFNOSUPPORT;
		goto exit;
	}
        
       	if (addr->scope > 0)
		res = tipc_publish(tsock->p->ref, addr->scope,
				   &addr->addr.nameseq);
	else
		res = tipc_withdraw(tsock->p->ref, -addr->scope,
				    &addr->addr.nameseq);
exit:
	up(&tsock->sem);
	return res;
}

/** 
 * get_name - get port ID of socket or peer socket
 * @sock: socket structure
 * @uaddr: area for returned socket address
 * @uaddr_len: area for returned length of socket address
 * @peer: 0 to obtain socket name, 1 to obtain peer socket name
 * 
 * Returns 0 on success, errno otherwise
 */

static int get_name(struct socket *sock, struct sockaddr *uaddr, 
		    int *uaddr_len, int peer)
{
	struct tipc_sock *tsock = tipc_sk(sock->sk);
	struct sockaddr_tipc *addr = (struct sockaddr_tipc *)uaddr;
	u32 res;

	if (down_interruptible(&tsock->sem))
		return -ERESTARTSYS;

	*uaddr_len = sizeof(*addr);
	addr->addrtype = TIPC_ADDR_ID;
	addr->family = AF_TIPC;
	addr->scope = 0;
	if (peer)
		res = tipc_peer(tsock->p->ref, &addr->addr.id);
	else
		res = tipc_ownidentity(tsock->p->ref, &addr->addr.id);
	addr->addr.name.domain = 0;

	up(&tsock->sem);
	return res;
}

/**
 * poll - read and possibly block on pollmask
 * @file: file structure associated with the socket
 * @sock: socket for which to calculate the poll bits
 * @wait: ???
 *
 * Returns the pollmask
 */

static unsigned int poll(struct file *file, struct socket *sock, 
			 poll_table *wait)
{
	poll_wait(file, sock->sk->sk_sleep, wait);
	/* NEED LOCK HERE? */
	return pollmask(sock);
}

/** 
 * dest_name_check - verify user is permitted to send to specified port name
 * @dest: destination address
 * @m: descriptor for message to be sent
 * 
 * Prevents restricted configuration commands from being issued by
 * unauthorized users.
 * 
 * Returns 0 if permission is granted, otherwise errno
 */

static int dest_name_check(struct sockaddr_tipc *dest, struct msghdr *m)
{
	struct tipc_cfg_msg_hdr hdr;

        if (likely(dest->addr.name.name.type >= TIPC_RESERVED_TYPES))
                return 0;
        if (likely(dest->addr.name.name.type == TIPC_TOP_SRV))
                return 0;

        if (likely(dest->addr.name.name.type != TIPC_CFG_SRV))
                return -EACCES;

        if (copy_from_user(&hdr, m->msg_iov[0].iov_base, sizeof(hdr)))
		return -EFAULT;
	if ((ntohs(hdr.tcm_type) & 0xC000) && (!capable(CAP_NET_ADMIN)))
		return -EACCES;
        
	return 0;
}

/**
 * send_msg - send message in connectionless manner
 * @iocb: (unused)
 * @sock: socket structure
 * @m: message to send
 * @total_len: length of message
 * 
 * Message must have an destination specified explicitly.
 * Used for SOCK_RDM and SOCK_DGRAM messages, 
 * and for 'SYN' messages on SOCK_SEQPACKET and SOCK_STREAM connections.
 * (Note: 'SYN+' is prohibited on SOCK_STREAM.)
 * 
 * Returns the number of bytes sent on success, or errno otherwise
 */

static int send_msg(struct kiocb *iocb, struct socket *sock,
		    struct msghdr *m, size_t total_len)
{
	struct tipc_sock *tsock = tipc_sk(sock->sk);
        struct sockaddr_tipc *dest = (struct sockaddr_tipc *)m->msg_name;
	struct sk_buff *buf;
	int needs_conn;
	int res = -EINVAL;

	if (unlikely(!dest))
		return -EDESTADDRREQ;
	if (unlikely((m->msg_namelen < sizeof(*dest)) ||
		     (dest->family != AF_TIPC)))
		return -EINVAL;

	needs_conn = (sock->state != SS_READY);
	if (unlikely(needs_conn)) {
		if (sock->state == SS_LISTENING)
			return -EPIPE;
		if (sock->state != SS_UNCONNECTED)
			return -EISCONN;
		if ((tsock->p->published) ||
		    ((sock->type == SOCK_STREAM) && (total_len != 0)))
			return -EOPNOTSUPP;
		if (dest->addrtype == TIPC_ADDR_NAME) {
			tsock->p->conn_type = dest->addr.name.name.type;
			tsock->p->conn_instance = dest->addr.name.name.instance;
		}
	}

	if (down_interruptible(&tsock->sem))
		return -ERESTARTSYS;

	if (needs_conn) {

		/* Abort any pending connection attempts (very unlikely) */

		while ((buf = skb_dequeue(&sock->sk->sk_receive_queue))) {
			tipc_reject_msg(buf, TIPC_ERR_NO_PORT);
			atomic_dec(&tipc_queue_size);
		}

		sock->state = SS_CONNECTING;
	}

        do {
                if (dest->addrtype == TIPC_ADDR_NAME) {
                        if ((res = dest_name_check(dest, m)))
                                goto exit;
                        res = tipc_send2name(tsock->p->ref,
                                             &dest->addr.name.name,
                                             dest->addr.name.domain, 
                                             m->msg_iovlen,
                                             m->msg_iov);
                }
                else if (dest->addrtype == TIPC_ADDR_ID) {
                        res = tipc_send2port(tsock->p->ref,
                                             &dest->addr.id,
                                             m->msg_iovlen,
                                             m->msg_iov);
                }
                else if (dest->addrtype == TIPC_ADDR_MCAST) {
			if (needs_conn) {
				res = -EOPNOTSUPP;
				goto exit;
			}
                        if ((res = dest_name_check(dest, m)))
                                goto exit;
                        res = tipc_multicast(tsock->p->ref,
                                             &dest->addr.nameseq,
                                             0,
                                             m->msg_iovlen,
                                             m->msg_iov);
                }
                if (likely(res != -ELINKCONG)) {
exit:                                
                        up(&tsock->sem);
                        return res;
                }
		if (m->msg_flags & MSG_DONTWAIT) {
			res = -EWOULDBLOCK;
			goto exit;
		}
                if (wait_event_interruptible(*sock->sk->sk_sleep,
                                             !tsock->p->congested)) {
                    res = -ERESTARTSYS;
                    goto exit;
                }
        } while (1);
}

/** 
 * send_packet - send a connection-oriented message
 * @iocb: (unused)
 * @sock: socket structure
 * @m: message to send
 * @total_len: length of message
 * 
 * Used for SOCK_SEQPACKET messages and SOCK_STREAM data.
 * 
 * Returns the number of bytes sent on success, or errno otherwise
 */

static int send_packet(struct kiocb *iocb, struct socket *sock,
		       struct msghdr *m, size_t total_len)
{
	struct tipc_sock *tsock = tipc_sk(sock->sk);
        struct sockaddr_tipc *dest = (struct sockaddr_tipc *)m->msg_name;
	int res;

	/* Handle implied connection establishment */

	if (unlikely(dest))
		return send_msg(iocb, sock, m, total_len);

	if (down_interruptible(&tsock->sem)) {
		return -ERESTARTSYS;
        }

        do {
		if (unlikely(sock->state != SS_CONNECTED)) {
			if (sock->state == SS_DISCONNECTING)
				res = -EPIPE;   
			else
				res = -ENOTCONN;
			goto exit;
		}

                res = tipc_send(tsock->p->ref, m->msg_iovlen, m->msg_iov);
                if (likely(res != -ELINKCONG)) {
exit:
                        up(&tsock->sem);
                        return res;
                }
		if (m->msg_flags & MSG_DONTWAIT) {
			res = -EWOULDBLOCK;
			goto exit;
		}
                if (wait_event_interruptible(*sock->sk->sk_sleep,
                                             !tsock->p->congested)) {
                    res = -ERESTARTSYS;
                    goto exit;
                }
        } while (1);
}

/** 
 * send_stream - send stream-oriented data
 * @iocb: (unused)
 * @sock: socket structure
 * @m: data to send
 * @total_len: total length of data to be sent
 * 
 * Used for SOCK_STREAM data.
 * 
 * Returns the number of bytes sent on success (or partial success), 
 * or errno if no data sent
 */


static int send_stream(struct kiocb *iocb, struct socket *sock,
		       struct msghdr *m, size_t total_len)
{
	struct msghdr my_msg;
	struct iovec my_iov;
	struct iovec *curr_iov;
	int curr_iovlen;
	char __user *curr_start;
	int curr_left;
	int bytes_to_send;
	int bytes_sent;
	int res;
	
	if (likely(total_len <= TIPC_MAX_USER_MSG_SIZE))
		return send_packet(iocb, sock, m, total_len);

	/* Can only send large data streams if already connected */

        if (unlikely(sock->state != SS_CONNECTED)) {
                if (sock->state == SS_DISCONNECTING)
                        return -EPIPE;   
                else
                        return -ENOTCONN;
        }

	/* 
	 * Send each iovec entry using one or more messages
	 *
	 * Note: This algorithm is good for the most likely case 
	 * (i.e. one large iovec entry), but could be improved to pass sets
	 * of small iovec entries into send_packet().
	 */

	curr_iov = m->msg_iov;
	curr_iovlen = m->msg_iovlen;
	my_msg.msg_iov = &my_iov;
	my_msg.msg_iovlen = 1;
	bytes_sent = 0;

	while (curr_iovlen--) {
		curr_start = curr_iov->iov_base;
		curr_left = curr_iov->iov_len;

		while (curr_left) {
			bytes_to_send = (curr_left < TIPC_MAX_USER_MSG_SIZE)
				? curr_left : TIPC_MAX_USER_MSG_SIZE;
			my_iov.iov_base = curr_start;
			my_iov.iov_len = bytes_to_send;
                        if ((res = send_packet(iocb, sock, &my_msg, 0)) < 0) {
				return bytes_sent ? bytes_sent : res;
			}
			curr_left -= bytes_to_send;
			curr_start += bytes_to_send;
			bytes_sent += bytes_to_send;
		}

		curr_iov++;
	}

	return bytes_sent;
}

/**
 * auto_connect - complete connection setup to a remote port
 * @sock: socket structure
 * @tsock: TIPC-specific socket structure
 * @msg: peer's response message
 * 
 * Returns 0 on success, errno otherwise
 */

static int auto_connect(struct socket *sock, struct tipc_sock *tsock, 
			struct tipc_msg *msg)
{
	struct tipc_portid peer;

	if (msg_errcode(msg)) {
		sock->state = SS_DISCONNECTING;
		return -ECONNREFUSED;
	}

	peer.ref = msg_origport(msg);
	peer.node = msg_orignode(msg);
	tipc_connect2port(tsock->p->ref, &peer);
	tipc_set_portimportance(tsock->p->ref, msg_importance(msg));
	sock->state = SS_CONNECTED;
	return 0;
}

/**
 * set_orig_addr - capture sender's address for received message
 * @m: descriptor for message info
 * @msg: received message header
 * 
 * Note: Address is not captured if not requested by receiver.
 */

static void set_orig_addr(struct msghdr *m, struct tipc_msg *msg)
{
        struct sockaddr_tipc *addr = (struct sockaddr_tipc *)m->msg_name;

        if (addr) {
		addr->family = AF_TIPC;
		addr->addrtype = TIPC_ADDR_ID;
		addr->addr.id.ref = msg_origport(msg);
		addr->addr.id.node = msg_orignode(msg);
		addr->addr.name.domain = 0;   	/* could leave uninitialized */
		addr->scope = 0;   		/* could leave uninitialized */
		m->msg_namelen = sizeof(struct sockaddr_tipc);
	}
}

/**
 * anc_data_recv - optionally capture ancillary data for received message 
 * @m: descriptor for message info
 * @msg: received message header
 * @tport: TIPC port associated with message
 * 
 * Note: Ancillary data is not captured if not requested by receiver.
 * 
 * Returns 0 if successful, otherwise errno
 */

static int anc_data_recv(struct msghdr *m, struct tipc_msg *msg,
				struct tipc_port *tport)
{
	u32 anc_data[3];
	u32 err;
	u32 dest_type;
	int has_name;
	int res;

	if (likely(m->msg_controllen == 0))
		return 0;

	/* Optionally capture errored message object(s) */

	err = msg ? msg_errcode(msg) : 0;
	if (unlikely(err)) {
		anc_data[0] = err;
		anc_data[1] = msg_data_sz(msg);
		if ((res = put_cmsg(m, SOL_TIPC, TIPC_ERRINFO, 8, anc_data)))
			return res;
		if (anc_data[1] &&
		    (res = put_cmsg(m, SOL_TIPC, TIPC_RETDATA, anc_data[1], 
				    msg_data(msg))))
			return res;
	}

	/* Optionally capture message destination object */

	dest_type = msg ? msg_type(msg) : TIPC_DIRECT_MSG;
	switch (dest_type) {
	case TIPC_NAMED_MSG:
		has_name = 1;
		anc_data[0] = msg_nametype(msg);
		anc_data[1] = msg_namelower(msg);
		anc_data[2] = msg_namelower(msg);
		break;
	case TIPC_MCAST_MSG:
		has_name = 1;
		anc_data[0] = msg_nametype(msg);
		anc_data[1] = msg_namelower(msg);
		anc_data[2] = msg_nameupper(msg);
		break;
	case TIPC_CONN_MSG:
		has_name = (tport->conn_type != 0);
		anc_data[0] = tport->conn_type;
		anc_data[1] = tport->conn_instance;
		anc_data[2] = tport->conn_instance;
		break;
	default:
		has_name = 0;
	}
	if (has_name &&
	    (res = put_cmsg(m, SOL_TIPC, TIPC_DESTNAME, 12, anc_data)))
		return res;

	return 0;
}

/** 
 * recv_msg - receive packet-oriented message
 * @iocb: (unused)
 * @m: descriptor for message info
 * @buf_len: total size of user buffer area
 * @flags: receive flags
 * 
 * Used for SOCK_DGRAM, SOCK_RDM, and SOCK_SEQPACKET messages.
 * If the complete message doesn't fit in user area, truncate it.
 *
 * Returns size of returned message data, errno otherwise
 */

static int recv_msg(struct kiocb *iocb, struct socket *sock,
		    struct msghdr *m, size_t buf_len, int flags)
{
	struct tipc_sock *tsock = tipc_sk(sock->sk);
	struct sk_buff *buf;
	struct tipc_msg *msg;
	unsigned int q_len;
	unsigned int sz;
	u32 err;
	int res;

	/* Currently doesn't support receiving into multiple iovec entries */

	if (m->msg_iovlen != 1)
		return -EOPNOTSUPP;

	/* Catch invalid receive attempts */

	if (unlikely(!buf_len))
		return -EINVAL;

	if (sock->type == SOCK_SEQPACKET) {
		if (unlikely(sock->state == SS_UNCONNECTED))
			return -ENOTCONN;
		if (unlikely((sock->state == SS_DISCONNECTING) && 
			     (skb_queue_len(&sock->sk->sk_receive_queue) == 0)))
		       	return -ENOTCONN;
	}

	/* Look for a message in receive queue; wait if necessary */

	if (unlikely(down_interruptible(&tsock->sem)))
		return -ERESTARTSYS;

restart:
	if (unlikely((skb_queue_len(&sock->sk->sk_receive_queue) == 0) &&
		     (flags & MSG_DONTWAIT))) {
		res = -EWOULDBLOCK;
		goto exit;
	}

	if ((res = wait_event_interruptible(
		*sock->sk->sk_sleep, 
		((q_len = skb_queue_len(&sock->sk->sk_receive_queue)) ||
		 (sock->state == SS_DISCONNECTING))) )) {
		goto exit;
	}

	/* Catch attempt to receive on an already terminated connection */
	/* [THIS CHECK MAY OVERLAP WITH AN EARLIER CHECK] */

	if (!q_len) {
		res = -ENOTCONN;
		goto exit;
	}

	/* Get access to first message in receive queue */

	buf = skb_peek(&sock->sk->sk_receive_queue);
	msg = buf_msg(buf);
	sz = msg_data_sz(msg);
	err = msg_errcode(msg);

	/* Complete connection setup for an implied connect */

	if (unlikely(sock->state == SS_CONNECTING)) {
		if ((res = auto_connect(sock, tsock, msg)))
			goto exit;
	}

	/* Discard an empty non-errored message & try again */

	if ((!sz) && (!err)) {
		advance_queue(tsock);
		goto restart;
	}

	/* Capture sender's address (optional) */

	set_orig_addr(m, msg);

	/* Capture ancillary data (optional) */

	if ((res = anc_data_recv(m, msg, tsock->p)))
		goto exit;

	/* Capture message data (if valid) & compute return value (always) */
	
	if (!err) {
		if (unlikely(buf_len < sz)) {
			sz = buf_len;
			m->msg_flags |= MSG_TRUNC;
		}
		if (unlikely(copy_to_user(m->msg_iov->iov_base, msg_data(msg),
					  sz))) {
			res = -EFAULT;
			goto exit;
		}
		res = sz;
	} else {
		if ((sock->state == SS_READY) ||
		    ((err == TIPC_CONN_SHUTDOWN) || m->msg_control))
			res = 0;
		else
			res = -ECONNRESET;
	}

	/* Consume received message (optional) */

	if (likely(!(flags & MSG_PEEK))) {
                if (unlikely(++tsock->p->conn_unacked >= TIPC_FLOW_CONTROL_WIN))
                        tipc_acknowledge(tsock->p->ref, tsock->p->conn_unacked);
		advance_queue(tsock);
        }
exit:
	up(&tsock->sem);
	return res;
}

/** 
 * recv_stream - receive stream-oriented data
 * @iocb: (unused)
 * @m: descriptor for message info
 * @buf_len: total size of user buffer area
 * @flags: receive flags
 * 
 * Used for SOCK_STREAM messages only.  If not enough data is available 
 * will optionally wait for more; never truncates data.
 *
 * Returns size of returned message data, errno otherwise
 */

static int recv_stream(struct kiocb *iocb, struct socket *sock,
		       struct msghdr *m, size_t buf_len, int flags)
{
	struct tipc_sock *tsock = tipc_sk(sock->sk);
	struct sk_buff *buf;
	struct tipc_msg *msg;
	unsigned int q_len;
	unsigned int sz;
	int sz_to_copy;
	int sz_copied = 0;
	int needed;
	char *crs = m->msg_iov->iov_base;
	unsigned char *buf_crs;
	u32 err;
	int res;

	/* Currently doesn't support receiving into multiple iovec entries */

	if (m->msg_iovlen != 1)
		return -EOPNOTSUPP;

	/* Catch invalid receive attempts */

	if (unlikely(!buf_len))
		return -EINVAL;

	if (unlikely(sock->state == SS_DISCONNECTING)) {
		if (skb_queue_len(&sock->sk->sk_receive_queue) == 0)
			return -ENOTCONN;
	} else if (unlikely(sock->state != SS_CONNECTED))
		return -ENOTCONN;

	/* Look for a message in receive queue; wait if necessary */

	if (unlikely(down_interruptible(&tsock->sem)))
		return -ERESTARTSYS;

restart:
	if (unlikely((skb_queue_len(&sock->sk->sk_receive_queue) == 0) &&
		     (flags & MSG_DONTWAIT))) {
		res = -EWOULDBLOCK;
		goto exit;
	}

	if ((res = wait_event_interruptible(
		*sock->sk->sk_sleep, 
		((q_len = skb_queue_len(&sock->sk->sk_receive_queue)) ||
		 (sock->state == SS_DISCONNECTING))) )) {
		goto exit;
	}

	/* Catch attempt to receive on an already terminated connection */
	/* [THIS CHECK MAY OVERLAP WITH AN EARLIER CHECK] */

	if (!q_len) {
		res = -ENOTCONN;
		goto exit;
	}

	/* Get access to first message in receive queue */

	buf = skb_peek(&sock->sk->sk_receive_queue);
	msg = buf_msg(buf);
	sz = msg_data_sz(msg);
	err = msg_errcode(msg);

	/* Discard an empty non-errored message & try again */

	if ((!sz) && (!err)) {
		advance_queue(tsock);
		goto restart;
	}

	/* Optionally capture sender's address & ancillary data of first msg */

	if (sz_copied == 0) {
		set_orig_addr(m, msg);
		if ((res = anc_data_recv(m, msg, tsock->p)))
			goto exit;
	}

	/* Capture message data (if valid) & compute return value (always) */
	
	if (!err) {
		buf_crs = (unsigned char *)(TIPC_SKB_CB(buf)->handle);
		sz = buf->tail - buf_crs;

		needed = (buf_len - sz_copied);
		sz_to_copy = (sz <= needed) ? sz : needed;
		if (unlikely(copy_to_user(crs, buf_crs, sz_to_copy))) {
			res = -EFAULT;
			goto exit;
		}
		sz_copied += sz_to_copy;

		if (sz_to_copy < sz) {
			if (!(flags & MSG_PEEK))
				TIPC_SKB_CB(buf)->handle = buf_crs + sz_to_copy;
			goto exit;
		}

		crs += sz_to_copy;
	} else {
		if (sz_copied != 0)
			goto exit; /* can't add error msg to valid data */

		if ((err == TIPC_CONN_SHUTDOWN) || m->msg_control)
			res = 0;
		else
			res = -ECONNRESET;
	}

	/* Consume received message (optional) */

	if (likely(!(flags & MSG_PEEK))) {
                if (unlikely(++tsock->p->conn_unacked >= TIPC_FLOW_CONTROL_WIN))
                        tipc_acknowledge(tsock->p->ref, tsock->p->conn_unacked);
		advance_queue(tsock);
        }

	/* Loop around if more data is required */

	if ((sz_copied < buf_len)    /* didn't get all requested data */ 
	    && (flags & MSG_WAITALL) /* ... and need to wait for more */
	    && (!(flags & MSG_PEEK)) /* ... and aren't just peeking at data */
	    && (!err)                /* ... and haven't reached a FIN */
	    )
		goto restart;

exit:
	up(&tsock->sem);
	return sz_copied ? sz_copied : res;
}

/**
 * queue_overloaded - test if queue overload condition exists
 * @queue_size: current size of queue
 * @base: nominal maximum size of queue
 * @msg: message to be added to queue
 * 
 * Returns 1 if queue is currently overloaded, 0 otherwise
 */

static int queue_overloaded(u32 queue_size, u32 base, struct tipc_msg *msg)
{
	u32 threshold;
	u32 imp = msg_importance(msg);

	if (imp == TIPC_LOW_IMPORTANCE)
		threshold = base;
	else if (imp == TIPC_MEDIUM_IMPORTANCE)
		threshold = base * 2;
	else if (imp == TIPC_HIGH_IMPORTANCE)
		threshold = base * 100;
	else
		return 0;

	if (msg_connected(msg))
		threshold *= 4;

	return (queue_size > threshold);
}

/** 
 * async_disconnect - wrapper function used to disconnect port
 * @portref: TIPC port reference (passed as pointer-sized value)
 */

static void async_disconnect(unsigned long portref)
{
	tipc_disconnect((u32)portref);
}

/** 
 * dispatch - handle arriving message
 * @tport: TIPC port that received message
 * @buf: message
 * 
 * Called with port locked.  Must not take socket lock to avoid deadlock risk.
 * 
 * Returns TIPC error status code (TIPC_OK if message is not to be rejected)
 */

static u32 dispatch(struct tipc_port *tport, struct sk_buff *buf)
{
	struct tipc_msg *msg = buf_msg(buf);
	struct tipc_sock *tsock = (struct tipc_sock *)tport->usr_handle;
	struct socket *sock;
	u32 recv_q_len;

	/* Reject message if socket is closing */

	if (!tsock)
		return TIPC_ERR_NO_PORT;

	/* Reject message if it is wrong sort of message for socket */

	/*
	 * WOULD IT BE BETTER TO JUST DISCARD THESE MESSAGES INSTEAD?
	 * "NO PORT" ISN'T REALLY THE RIGHT ERROR CODE, AND THERE MAY
	 * BE SECURITY IMPLICATIONS INHERENT IN REJECTING INVALID TRAFFIC
	 */
	sock = tsock->sk.sk_socket;
	if (sock->state == SS_READY) {
		if (msg_connected(msg)) {
			msg_dbg(msg, "dispatch filter 1\n");
			return TIPC_ERR_NO_PORT;
		}
	} else {
		if (msg_mcast(msg)) {
			msg_dbg(msg, "dispatch filter 2\n");
			return TIPC_ERR_NO_PORT;
		}
		if (sock->state == SS_CONNECTED) {
			if (!msg_connected(msg)) {
				msg_dbg(msg, "dispatch filter 3\n");
				return TIPC_ERR_NO_PORT;
			}
		}
		else if (sock->state == SS_CONNECTING) {
			if (!msg_connected(msg) && (msg_errcode(msg) == 0)) {
				msg_dbg(msg, "dispatch filter 4\n");
				return TIPC_ERR_NO_PORT;
			}
		} 
		else if (sock->state == SS_LISTENING) {
			if (msg_connected(msg) || msg_errcode(msg)) {
				msg_dbg(msg, "dispatch filter 5\n");
				return TIPC_ERR_NO_PORT;
			}
		} 
		else if (sock->state == SS_DISCONNECTING) {
			msg_dbg(msg, "dispatch filter 6\n");
			return TIPC_ERR_NO_PORT;
		}
		else /* (sock->state == SS_UNCONNECTED) */ {
			if (msg_connected(msg) || msg_errcode(msg)) {
				msg_dbg(msg, "dispatch filter 7\n");
				return TIPC_ERR_NO_PORT;
			}
		}
	}

	/* Reject message if there isn't room to queue it */

	if (unlikely((u32)atomic_read(&tipc_queue_size) > 
		     OVERLOAD_LIMIT_BASE)) {
		if (queue_overloaded(atomic_read(&tipc_queue_size), 
				     OVERLOAD_LIMIT_BASE, msg))
			return TIPC_ERR_OVERLOAD;
        }
	recv_q_len = skb_queue_len(&tsock->sk.sk_receive_queue);
	if (unlikely(recv_q_len > (OVERLOAD_LIMIT_BASE / 2))) {
		if (queue_overloaded(recv_q_len, 
				     OVERLOAD_LIMIT_BASE / 2, msg)) 
			return TIPC_ERR_OVERLOAD;
        }

	/* Initiate connection termination for an incoming 'FIN' */

	if (unlikely(msg_errcode(msg) && (sock->state == SS_CONNECTED))) {
		sock->state = SS_DISCONNECTING;
		/* Note: Use signal since port lock is already taken! */
		tipc_k_signal((Handler)async_disconnect, tport->ref);
	}

	/* Enqueue message (finally!) */

	msg_dbg(msg,"<DISP<: ");
	TIPC_SKB_CB(buf)->handle = msg_data(msg);
	atomic_inc(&tipc_queue_size);
	skb_queue_tail(&sock->sk->sk_receive_queue, buf);

        wake_up_interruptible(sock->sk->sk_sleep);
	return TIPC_OK;
}

/** 
 * wakeupdispatch - wake up port after congestion
 * @tport: port to wakeup
 * 
 * Called with port lock on.
 */

static void wakeupdispatch(struct tipc_port *tport)
{
	struct tipc_sock *tsock = (struct tipc_sock *)tport->usr_handle;

        wake_up_interruptible(tsock->sk.sk_sleep);
}

/**
 * connect - establish a connection to another TIPC port
 * @sock: socket structure
 * @dest: socket address for destination port
 * @destlen: size of socket address data structure
 * @flags: (unused)
 *
 * Returns 0 on success, errno otherwise
 */

static int connect(struct socket *sock, struct sockaddr *dest, int destlen, 
		   int flags)
{
   struct tipc_sock *tsock = tipc_sk(sock->sk);
   struct sockaddr_tipc *dst = (struct sockaddr_tipc *)dest;
   struct msghdr m = {NULL,};
   struct sk_buff *buf;
   struct tipc_msg *msg;
   int res;

   /* For now, TIPC does not allow use of connect() with DGRAM or RDM types */

   if (sock->state == SS_READY)
	   return -EOPNOTSUPP;

   /* Issue Posix-compliant error code if socket is in the wrong state */

   if (sock->state == SS_LISTENING)
	   return -EOPNOTSUPP;
   if (sock->state == SS_CONNECTING)
	   return -EALREADY;
   if (sock->state != SS_UNCONNECTED)
           return -EISCONN;

   /*
    * Reject connection attempt using multicast address
    *
    * Note: send_msg() validates the rest of the address fields,
    *       so there's no need to do it here
    */

   if (dst->addrtype == TIPC_ADDR_MCAST)
           return -EINVAL;

   /* Send a 'SYN-' to destination */

   m.msg_name = dest;
   m.msg_namelen = destlen;
   if ((res = send_msg(NULL, sock, &m, 0)) < 0) {
	   sock->state = SS_DISCONNECTING;
	   return res;
   }

   if (down_interruptible(&tsock->sem)) 
           return -ERESTARTSYS;
	
   /* Wait for destination's 'ACK' response */

   res = wait_event_interruptible_timeout(*sock->sk->sk_sleep,
                                          skb_queue_len(&sock->sk->sk_receive_queue),
					  sock->sk->sk_rcvtimeo);
   buf = skb_peek(&sock->sk->sk_receive_queue);
   if (res > 0) {
	   msg = buf_msg(buf);
           res = auto_connect(sock, tsock, msg);
           if (!res) {
		   if (!msg_data_sz(msg))
			   advance_queue(tsock);
	   }
   } else {
	   if (res == 0) {
		   res = -ETIMEDOUT;
	   } else
	           { /* leave "res" unchanged */ }
	   sock->state = SS_DISCONNECTING;
   }

   up(&tsock->sem);
   return res;
}

/** 
 * listen - allow socket to listen for incoming connections
 * @sock: socket structure
 * @len: (unused)
 * 
 * Returns 0 on success, errno otherwise
 */

static int listen(struct socket *sock, int len)
{
	/* REQUIRES SOCKET LOCKING OF SOME SORT? */

	if (sock->state == SS_READY)
		return -EOPNOTSUPP;
	if (sock->state != SS_UNCONNECTED)
		return -EINVAL;
	sock->state = SS_LISTENING;
        return 0;
}

/** 
 * accept - wait for connection request
 * @sock: listening socket
 * @newsock: new socket that is to be connected
 * @flags: file-related flags associated with socket
 * 
 * Returns 0 on success, errno otherwise
 */

static int accept(struct socket *sock, struct socket *newsock, int flags)
{
	struct tipc_sock *tsock = tipc_sk(sock->sk);
	struct sk_buff *buf;
	int res = -EFAULT;

	if (sock->state == SS_READY)
		return -EOPNOTSUPP;
	if (sock->state != SS_LISTENING)
		return -EINVAL;
	
	if (unlikely((skb_queue_len(&sock->sk->sk_receive_queue) == 0) && 
		     (flags & O_NONBLOCK)))
		return -EWOULDBLOCK;

	if (down_interruptible(&tsock->sem))
		return -ERESTARTSYS;

	if (wait_event_interruptible(*sock->sk->sk_sleep, 
				     skb_queue_len(&sock->sk->sk_receive_queue))) {
		res = -ERESTARTSYS;
		goto exit;
	}
	buf = skb_peek(&sock->sk->sk_receive_queue);

	res = tipc_create(newsock, 0);
	if (!res) {
		struct tipc_sock *new_tsock = tipc_sk(newsock->sk);
		struct tipc_portid id;
		struct tipc_msg *msg = buf_msg(buf);
		u32 new_ref = new_tsock->p->ref;

		id.ref = msg_origport(msg);
		id.node = msg_orignode(msg);
		tipc_connect2port(new_ref, &id);
		newsock->state = SS_CONNECTED;

		tipc_set_portimportance(new_ref, msg_importance(msg));
		if (msg_named(msg)) {
			new_tsock->p->conn_type = msg_nametype(msg);
			new_tsock->p->conn_instance = msg_nameinst(msg);
		}

               /* 
		 * Respond to 'SYN-' by discarding it & returning 'ACK'-.
		 * Respond to 'SYN+' by queuing it on new socket.
		 */

		msg_dbg(msg,"<ACC<: ");
                if (!msg_data_sz(msg)) {
                        struct msghdr m = {NULL,};

                        send_packet(NULL, newsock, &m, 0);
                        advance_queue(tsock);
                } else {
			sock_lock(tsock);
			skb_dequeue(&sock->sk->sk_receive_queue);
			sock_unlock(tsock);
			skb_queue_head(&newsock->sk->sk_receive_queue, buf);
		}
	}
exit:
	up(&tsock->sem);
	return res;
}

/**
 * shutdown - shutdown socket connection
 * @sock: socket structure
 * @how: direction to close (unused; always treated as read + write)
 *
 * Terminates connection (if necessary), then purges socket's receive queue.
 * 
 * Returns 0 on success, errno otherwise
 */

static int shutdown(struct socket *sock, int how)
{
	struct tipc_sock* tsock = tipc_sk(sock->sk);
	struct sk_buff *buf;
	int res;

	/* Could return -EINVAL for an invalid "how", but why bother? */

	if (down_interruptible(&tsock->sem))
		return -ERESTARTSYS;

	sock_lock(tsock);

	switch (sock->state) {
	case SS_CONNECTED:

		/* Send 'FIN+' or 'FIN-' message to peer */

		sock_unlock(tsock);
restart:
		if ((buf = skb_dequeue(&sock->sk->sk_receive_queue))) {
			atomic_dec(&tipc_queue_size);
			if (TIPC_SKB_CB(buf)->handle != msg_data(buf_msg(buf))) {
				buf_discard(buf);
				goto restart;
			}
			tipc_reject_msg(buf, TIPC_CONN_SHUTDOWN);
		}
		else {
			tipc_shutdown(tsock->p->ref);
		}
		sock_lock(tsock);

		/* fall through */

	case SS_DISCONNECTING:

		/* Discard any unreceived messages */

		while ((buf = skb_dequeue(&sock->sk->sk_receive_queue))) {
			atomic_dec(&tipc_queue_size);
			buf_discard(buf);
		}
		tsock->p->conn_unacked = 0;

		/* fall through */

	case SS_CONNECTING:
		sock->state = SS_DISCONNECTING;
		res = 0;
		break;

	default:
		res = -ENOTCONN;
	}

	sock_unlock(tsock);

	up(&tsock->sem);
	return res;
}

/**
 * setsockopt - set socket option
 * @sock: socket structure
 * @lvl: option level
 * @opt: option identifier
 * @ov: pointer to new option value
 * @ol: length of option value
 * 
 * For stream sockets only, accepts and ignores all IPPROTO_TCP options 
 * (to ease compatibility).
 * 
 * Returns 0 on success, errno otherwise
 */

static int setsockopt(struct socket *sock, 
		      int lvl, int opt, char __user *ov, int ol)
{
	struct tipc_sock *tsock = tipc_sk(sock->sk);
	u32 value;
	int res;

        if ((lvl == IPPROTO_TCP) && (sock->type == SOCK_STREAM))
                return 0;
	if (lvl != SOL_TIPC)
		return -ENOPROTOOPT;
	if (ol < sizeof(value))
		return -EINVAL;
        if ((res = get_user(value, (u32 *)ov)))
		return res;

	if (down_interruptible(&tsock->sem)) 
		return -ERESTARTSYS;
	
	switch (opt) {
	case TIPC_IMPORTANCE:
		res = tipc_set_portimportance(tsock->p->ref, value);
		break;
	case TIPC_SRC_DROPPABLE:
		if (sock->type != SOCK_STREAM)
			res = tipc_set_portunreliable(tsock->p->ref, value);
		else 
			res = -ENOPROTOOPT;
		break;
	case TIPC_DEST_DROPPABLE:
		res = tipc_set_portunreturnable(tsock->p->ref, value);
		break;
	case TIPC_CONN_TIMEOUT:
		sock->sk->sk_rcvtimeo = (value * HZ / 1000);
		break;
	default:
		res = -EINVAL;
	}

	up(&tsock->sem);
	return res;
}

/**
 * getsockopt - get socket option
 * @sock: socket structure
 * @lvl: option level
 * @opt: option identifier
 * @ov: receptacle for option value
 * @ol: receptacle for length of option value
 * 
 * For stream sockets only, returns 0 length result for all IPPROTO_TCP options 
 * (to ease compatibility).
 * 
 * Returns 0 on success, errno otherwise
 */

static int getsockopt(struct socket *sock, 
		      int lvl, int opt, char __user *ov, int *ol)
{
	struct tipc_sock *tsock = tipc_sk(sock->sk);
        int len;
	u32 value;
        int res;

        if ((lvl == IPPROTO_TCP) && (sock->type == SOCK_STREAM))
                return put_user(0, ol);
	if (lvl != SOL_TIPC)
		return -ENOPROTOOPT;
        if ((res = get_user(len, ol)))
                return res;

	if (down_interruptible(&tsock->sem)) 
		return -ERESTARTSYS;

	switch (opt) {
	case TIPC_IMPORTANCE:
		res = tipc_portimportance(tsock->p->ref, &value);
		break;
	case TIPC_SRC_DROPPABLE:
		res = tipc_portunreliable(tsock->p->ref, &value);
		break;
	case TIPC_DEST_DROPPABLE:
		res = tipc_portunreturnable(tsock->p->ref, &value);
		break;
	case TIPC_CONN_TIMEOUT:
		value = (sock->sk->sk_rcvtimeo * 1000) / HZ;
		break;
	default:
		res = -EINVAL;
	}

	if (res) {
		/* "get" failed */
	}
	else if (len < sizeof(value)) {
		res = -EINVAL;
	}
	else if ((res = copy_to_user(ov, &value, sizeof(value)))) {
		/* couldn't return value */
	}
	else {
		res = put_user(sizeof(value), ol);
	}

        up(&tsock->sem);
	return res;
}

/**
 * Placeholders for non-implemented functionality
 * 
 * Returns error code (POSIX-compliant where defined)
 */

static int ioctl(struct socket *s, u32 cmd, unsigned long arg)
{
        return -EINVAL;
}

static int no_mmap(struct file *file, struct socket *sock,
                   struct vm_area_struct *vma)
{
        return -EINVAL;
}
static ssize_t no_sendpage(struct socket *sock, struct page *page,
                           int offset, size_t size, int flags)
{
        return -EINVAL;
}

static int no_skpair(struct socket *s1, struct socket *s2)
{
	return -EOPNOTSUPP;
}

/**
 * Protocol switches for the various types of TIPC sockets
 */

static struct proto_ops msg_ops = {
	.owner 		= THIS_MODULE,
	.family		= AF_TIPC,
	.release	= release,
	.bind		= bind,
	.connect	= connect,
	.socketpair	= no_skpair,
	.accept		= accept,
	.getname	= get_name,
	.poll		= poll,
	.ioctl		= ioctl,
	.listen		= listen,
	.shutdown	= shutdown,
	.setsockopt	= setsockopt,
	.getsockopt	= getsockopt,
	.sendmsg	= send_msg,
	.recvmsg	= recv_msg,
        .mmap		= no_mmap,
        .sendpage	= no_sendpage
};

static struct proto_ops packet_ops = {
	.owner 		= THIS_MODULE,
	.family		= AF_TIPC,
	.release	= release,
	.bind		= bind,
	.connect	= connect,
	.socketpair	= no_skpair,
	.accept		= accept,
	.getname	= get_name,
	.poll		= poll,
	.ioctl		= ioctl,
	.listen		= listen,
	.shutdown	= shutdown,
	.setsockopt	= setsockopt,
	.getsockopt	= getsockopt,
	.sendmsg	= send_packet,
	.recvmsg	= recv_msg,
        .mmap		= no_mmap,
        .sendpage	= no_sendpage
};

static struct proto_ops stream_ops = {
	.owner 		= THIS_MODULE,
	.family		= AF_TIPC,
	.release	= release,
	.bind		= bind,
	.connect	= connect,
	.socketpair	= no_skpair,
	.accept		= accept,
	.getname	= get_name,
	.poll		= poll,
	.ioctl		= ioctl,
	.listen		= listen,
	.shutdown	= shutdown,
	.setsockopt	= setsockopt,
	.getsockopt	= getsockopt,
	.sendmsg	= send_stream,
	.recvmsg	= recv_stream,
        .mmap		= no_mmap,
        .sendpage	= no_sendpage
};

static struct net_proto_family tipc_family_ops = {
	.owner 		= THIS_MODULE,
	.family		= AF_TIPC,
	.create		= tipc_create
};

static struct proto tipc_proto = {
	.name		= "TIPC",
	.owner		= THIS_MODULE,
	.obj_size	= sizeof(struct tipc_sock)
};

/**
 * tipc_socket_init - initialize TIPC socket interface
 * 
 * Returns 0 on success, errno otherwise
 */
int tipc_socket_init(void)
{
	int res;

        res = proto_register(&tipc_proto, 1);
	if (res) {
		err("Failed to register TIPC protocol type\n");
		goto out;
	}

	res = sock_register(&tipc_family_ops);
	if (res) {
		err("Failed to register TIPC socket type\n");
		proto_unregister(&tipc_proto);
		goto out;
	}

	sockets_enabled = 1;
 out:
	return res;
}

/**
 * tipc_socket_stop - stop TIPC socket interface
 */
void tipc_socket_stop(void)
{
	if (!sockets_enabled)
		return;

	sockets_enabled = 0;
	sock_unregister(tipc_family_ops.family);
	proto_unregister(&tipc_proto);
}

