/*
 * 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 inline void sock_lock(struct tipc_sock* tsock)
{
        spin_lock_bh(tsock->p->lock);       
}

/* 
 * sock_unlock(): Unlock a port/socket pair
 */
static inline 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 inline 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 inline 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 ((sock->type != SOCK_STREAM) && 
	    (sock->type != SOCK_SEQPACKET) &&
	    (sock->type != SOCK_DGRAM) &&
	    (sock->type != SOCK_RDM))
		return -EPROTOTYPE;

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

	ref = tipc_createport_raw(0, &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;
	}

	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 = 0;
		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, 0);
		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 inline 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: (unused)
 * 
 * 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(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 (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: (unused)
 * 
 * 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;
        }

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

        do {
                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 errno otherwise
 */


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 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().
	 */

	my_msg = *m;
	curr_iov = my_msg.msg_iov;
	curr_iovlen = my_msg.msg_iovlen;
	my_msg.msg_iov = &my_iov;
	my_msg.msg_iovlen = 1;

	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 res;
			curr_left -= bytes_to_send;
			curr_start += bytes_to_send;
		}

		curr_iov++;
	}

	return total_len;
}

/**
 * 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 inline 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 inline 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 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_SOCKET, TIPC_ERRINFO, 8, anc_data)))
			return res;
		if (anc_data[1] &&
		    (res = put_cmsg(m, SOL_SOCKET, 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:
		anc_data[0] = msg_nametype(msg);
		anc_data[1] = msg_namelower(msg);
		anc_data[2] = msg_namelower(msg);
		break;
	case TIPC_MCAST_MSG:
		anc_data[0] = msg_nametype(msg);
		anc_data[1] = msg_namelower(msg);
		anc_data[2] = msg_nameupper(msg);
		break;
	case TIPC_CONN_MSG:
		anc_data[0] = tport->conn_type;
		anc_data[1] = tport->conn_instance;
		anc_data[2] = tport->conn_instance;
		break;
	default:
		anc_data[0] = 0;
	}
	if (anc_data[0] &&
	    (res = put_cmsg(m, SOL_SOCKET, 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 = (sz_copied == 0) ? -EWOULDBLOCK : 0;
		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 res ? res : sz_copied;
}

/**
 * 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 = {0,};
   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;

   /* MOVE THE REST OF THIS ERROR CHECKING TO send_msg()? */
   if (sock->state == SS_LISTENING)
	   return -EOPNOTSUPP;
   if (sock->state == SS_CONNECTING)
	   return -EALREADY;
   if (sock->state != SS_UNCONNECTED)
           return -EISCONN;

   if ((dst->family != AF_TIPC) ||
       ((dst->addrtype != TIPC_ADDR_NAME) && (dst->addrtype != TIPC_ADDR_ID)))
           return -EINVAL;

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

   m.msg_name = dest;
   if ((res = send_msg(0, 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 (dst->addrtype == TIPC_ADDR_NAME) {
			   tsock->p->conn_type = dst->addr.name.name.type;
			   tsock->p->conn_instance = dst->addr.name.name.instance;
		   }
		   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 = {0,};

                        send_packet(0, 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 (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 *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 *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);
}

