117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells/* incoming call handling
217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells *
317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells * Written by David Howells (dhowells@redhat.com)
517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells *
617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells * This program is free software; you can redistribute it and/or
717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells * modify it under the terms of the GNU General Public License
817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells * as published by the Free Software Foundation; either version
917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells * 2 of the License, or (at your option) any later version.
1017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells */
1117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
1217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells#include <linux/module.h>
1317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells#include <linux/net.h>
1417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells#include <linux/skbuff.h>
1517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells#include <linux/errqueue.h>
1617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells#include <linux/udp.h>
1717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells#include <linux/in.h>
1817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells#include <linux/in6.h>
1917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells#include <linux/icmp.h>
205a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/gfp.h>
2117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells#include <net/sock.h>
2217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells#include <net/af_rxrpc.h>
2317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells#include <net/ip.h>
2417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells#include "ar-internal.h"
2517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
2617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells/*
2717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells * generate a connection-level abort
2817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells */
2917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howellsstatic int rxrpc_busy(struct rxrpc_local *local, struct sockaddr_rxrpc *srx,
3017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		      struct rxrpc_header *hdr)
3117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells{
3217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	struct msghdr msg;
3317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	struct kvec iov[1];
3417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	size_t len;
3517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	int ret;
3617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
3717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	_enter("%d,,", local->debug_id);
3817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
3917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	msg.msg_name	= &srx->transport.sin;
4017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	msg.msg_namelen	= sizeof(srx->transport.sin);
4117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	msg.msg_control	= NULL;
4217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	msg.msg_controllen = 0;
4317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	msg.msg_flags	= 0;
4417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
4517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	hdr->seq	= 0;
4617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	hdr->type	= RXRPC_PACKET_TYPE_BUSY;
4717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	hdr->flags	= 0;
4817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	hdr->userStatus	= 0;
4917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	hdr->_rsvd	= 0;
5017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
5117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	iov[0].iov_base	= hdr;
5217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	iov[0].iov_len	= sizeof(*hdr);
5317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
5417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	len = iov[0].iov_len;
5517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
5617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	hdr->serial = htonl(1);
5717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	_proto("Tx BUSY %%%u", ntohl(hdr->serial));
5817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
5917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	ret = kernel_sendmsg(local->socket, &msg, iov, 1, len);
6017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	if (ret < 0) {
6117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		_leave(" = -EAGAIN [sendmsg failed: %d]", ret);
6217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		return -EAGAIN;
6317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	}
6417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
6517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	_leave(" = 0");
6617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	return 0;
6717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells}
6817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
6917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells/*
7017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells * accept an incoming call that needs peer, transport and/or connection setting
7117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells * up
7217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells */
7317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howellsstatic int rxrpc_accept_incoming_call(struct rxrpc_local *local,
7417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells				      struct rxrpc_sock *rx,
7517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells				      struct sk_buff *skb,
7617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells				      struct sockaddr_rxrpc *srx)
7717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells{
7817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	struct rxrpc_connection *conn;
7917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	struct rxrpc_transport *trans;
8017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	struct rxrpc_skb_priv *sp, *nsp;
8117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	struct rxrpc_peer *peer;
8217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	struct rxrpc_call *call;
8317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	struct sk_buff *notification;
8417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	int ret;
8517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
8617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	_enter("");
8717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
8817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	sp = rxrpc_skb(skb);
8917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
9017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	/* get a notification message to send to the server app */
9117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	notification = alloc_skb(0, GFP_NOFS);
92c3824d21eb653fe7017476724257ccaa8bf3d9e1Tetsuo Handa	if (!notification) {
93c3824d21eb653fe7017476724257ccaa8bf3d9e1Tetsuo Handa		_debug("no memory");
94c3824d21eb653fe7017476724257ccaa8bf3d9e1Tetsuo Handa		ret = -ENOMEM;
95c3824d21eb653fe7017476724257ccaa8bf3d9e1Tetsuo Handa		goto error_nofree;
96c3824d21eb653fe7017476724257ccaa8bf3d9e1Tetsuo Handa	}
9717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	rxrpc_new_skb(notification);
9817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	notification->mark = RXRPC_SKB_MARK_NEW_CALL;
9917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
10017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	peer = rxrpc_get_peer(srx, GFP_NOIO);
10117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	if (IS_ERR(peer)) {
10217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		_debug("no peer");
10317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		ret = -EBUSY;
10417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		goto error;
10517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	}
10617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
10717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	trans = rxrpc_get_transport(local, peer, GFP_NOIO);
10817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	rxrpc_put_peer(peer);
10934093d055e09d1bb549efc11c8d448373437bbe4Julien Brunel	if (IS_ERR(trans)) {
11017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		_debug("no trans");
11117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		ret = -EBUSY;
11217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		goto error;
11317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	}
11417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
11517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	conn = rxrpc_incoming_connection(trans, &sp->hdr, GFP_NOIO);
11617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	rxrpc_put_transport(trans);
11717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	if (IS_ERR(conn)) {
11817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		_debug("no conn");
11917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		ret = PTR_ERR(conn);
12017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		goto error;
12117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	}
12217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
12317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	call = rxrpc_incoming_call(rx, conn, &sp->hdr, GFP_NOIO);
12417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	rxrpc_put_connection(conn);
12517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	if (IS_ERR(call)) {
12617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		_debug("no call");
12717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		ret = PTR_ERR(call);
12817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		goto error;
12917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	}
13017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
13117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	/* attach the call to the socket */
13217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	read_lock_bh(&local->services_lock);
13317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	if (rx->sk.sk_state == RXRPC_CLOSE)
13417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		goto invalid_service;
13517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
13617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	write_lock(&rx->call_lock);
13717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	if (!test_and_set_bit(RXRPC_CALL_INIT_ACCEPT, &call->flags)) {
13817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		rxrpc_get_call(call);
13917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
14017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		spin_lock(&call->conn->state_lock);
14117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		if (sp->hdr.securityIndex > 0 &&
14217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		    call->conn->state == RXRPC_CONN_SERVER_UNSECURED) {
14317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells			_debug("await conn sec");
14417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells			list_add_tail(&call->accept_link, &rx->secureq);
14517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells			call->conn->state = RXRPC_CONN_SERVER_CHALLENGING;
14617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells			atomic_inc(&call->conn->usage);
14717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells			set_bit(RXRPC_CONN_CHALLENGE, &call->conn->events);
148651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells			rxrpc_queue_conn(call->conn);
14917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		} else {
15017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells			_debug("conn ready");
15117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells			call->state = RXRPC_CALL_SERVER_ACCEPTING;
15217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells			list_add_tail(&call->accept_link, &rx->acceptq);
15317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells			rxrpc_get_call(call);
15417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells			nsp = rxrpc_skb(notification);
15517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells			nsp->call = call;
15617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
15717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells			ASSERTCMP(atomic_read(&call->usage), >=, 3);
15817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
15917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells			_debug("notify");
16017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells			spin_lock(&call->lock);
16117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells			ret = rxrpc_queue_rcv_skb(call, notification, true,
16217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells						  false);
16317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells			spin_unlock(&call->lock);
16417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells			notification = NULL;
165163e3cb7daa8c3a6dde6a13a3d09a198930c6822Julia Lawall			BUG_ON(ret < 0);
16617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		}
16717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		spin_unlock(&call->conn->state_lock);
16817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
16917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		_debug("queued");
17017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	}
17117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	write_unlock(&rx->call_lock);
17217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
17317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	_debug("process");
17417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	rxrpc_fast_process_packet(call, skb);
17517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
17617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	_debug("done");
17717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	read_unlock_bh(&local->services_lock);
17817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	rxrpc_free_skb(notification);
17917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	rxrpc_put_call(call);
18017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	_leave(" = 0");
18117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	return 0;
18217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
18317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howellsinvalid_service:
18417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	_debug("invalid");
18517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	read_unlock_bh(&local->services_lock);
18617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
18717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	read_lock_bh(&call->state_lock);
18817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	if (!test_bit(RXRPC_CALL_RELEASE, &call->flags) &&
18917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	    !test_and_set_bit(RXRPC_CALL_RELEASE, &call->events)) {
19017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		rxrpc_get_call(call);
191651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells		rxrpc_queue_call(call);
19217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	}
19317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	read_unlock_bh(&call->state_lock);
19417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	rxrpc_put_call(call);
19517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	ret = -ECONNREFUSED;
19617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howellserror:
19717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	rxrpc_free_skb(notification);
198c3824d21eb653fe7017476724257ccaa8bf3d9e1Tetsuo Handaerror_nofree:
19917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	_leave(" = %d", ret);
20017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	return ret;
20117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells}
20217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
20317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells/*
20417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells * accept incoming calls that need peer, transport and/or connection setting up
20517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells * - the packets we get are all incoming client DATA packets that have seq == 1
20617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells */
20717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howellsvoid rxrpc_accept_incoming_calls(struct work_struct *work)
20817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells{
20917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	struct rxrpc_local *local =
21017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		container_of(work, struct rxrpc_local, acceptor);
21117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	struct rxrpc_skb_priv *sp;
21217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	struct sockaddr_rxrpc srx;
21317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	struct rxrpc_sock *rx;
21417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	struct sk_buff *skb;
21517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	__be16 service_id;
21617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	int ret;
21717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
21817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	_enter("%d", local->debug_id);
21917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
22017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	read_lock_bh(&rxrpc_local_lock);
22117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	if (atomic_read(&local->usage) > 0)
22217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		rxrpc_get_local(local);
22317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	else
22417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		local = NULL;
22517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	read_unlock_bh(&rxrpc_local_lock);
22617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	if (!local) {
22717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		_leave(" [local dead]");
22817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		return;
22917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	}
23017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
23117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howellsprocess_next_packet:
23217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	skb = skb_dequeue(&local->accept_queue);
23317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	if (!skb) {
23417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		rxrpc_put_local(local);
23517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		_leave("\n");
23617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		return;
23717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	}
23817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
23917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	_net("incoming call skb %p", skb);
24017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
24117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	sp = rxrpc_skb(skb);
24217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
24317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	/* determine the remote address */
24417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	memset(&srx, 0, sizeof(srx));
24517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	srx.srx_family = AF_RXRPC;
24617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	srx.transport.family = local->srx.transport.family;
24717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	srx.transport_type = local->srx.transport_type;
24817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	switch (srx.transport.family) {
24917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	case AF_INET:
25017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		srx.transport_len = sizeof(struct sockaddr_in);
25117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		srx.transport.sin.sin_port = udp_hdr(skb)->source;
25217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		srx.transport.sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
25317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		break;
25417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	default:
25517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		goto busy;
25617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	}
25717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
25817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	/* get the socket providing the service */
25917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	service_id = sp->hdr.serviceId;
26017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	read_lock_bh(&local->services_lock);
26117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	list_for_each_entry(rx, &local->services, listen_link) {
26217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		if (rx->service_id == service_id &&
26317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		    rx->sk.sk_state != RXRPC_CLOSE)
26417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells			goto found_service;
26517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	}
26617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	read_unlock_bh(&local->services_lock);
26717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	goto invalid_service;
26817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
26917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howellsfound_service:
27017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	_debug("found service %hd", ntohs(rx->service_id));
27117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	if (sk_acceptq_is_full(&rx->sk))
27217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		goto backlog_full;
27317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	sk_acceptq_added(&rx->sk);
27417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	sock_hold(&rx->sk);
27517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	read_unlock_bh(&local->services_lock);
27617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
27717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	ret = rxrpc_accept_incoming_call(local, rx, skb, &srx);
27817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	if (ret < 0)
27917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		sk_acceptq_removed(&rx->sk);
28017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	sock_put(&rx->sk);
28117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	switch (ret) {
28217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	case -ECONNRESET: /* old calls are ignored */
28317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	case -ECONNABORTED: /* aborted calls are reaborted or ignored */
28417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	case 0:
28517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		goto process_next_packet;
28617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	case -ECONNREFUSED:
28717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		goto invalid_service;
28817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	case -EBUSY:
28917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		goto busy;
29017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	case -EKEYREJECTED:
29117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		goto security_mismatch;
29217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	default:
29317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		BUG();
29417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	}
29517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
29617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howellsbacklog_full:
29717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	read_unlock_bh(&local->services_lock);
29817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howellsbusy:
29917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	rxrpc_busy(local, &srx, &sp->hdr);
30017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	rxrpc_free_skb(skb);
30117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	goto process_next_packet;
30217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
30317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howellsinvalid_service:
30417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	skb->priority = RX_INVALID_OPERATION;
30517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	rxrpc_reject_packet(local, skb);
30617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	goto process_next_packet;
30717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
30817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	/* can't change connection security type mid-flow */
30917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howellssecurity_mismatch:
31017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	skb->priority = RX_PROTOCOL_ERROR;
31117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	rxrpc_reject_packet(local, skb);
31217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	goto process_next_packet;
31317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells}
31417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
31517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells/*
31617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells * handle acceptance of a call by userspace
31717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells * - assign the user call ID to the call at the front of the queue
31817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells */
319651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howellsstruct rxrpc_call *rxrpc_accept_call(struct rxrpc_sock *rx,
320651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells				     unsigned long user_call_ID)
32117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells{
32217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	struct rxrpc_call *call;
32317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	struct rb_node *parent, **pp;
32417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	int ret;
32517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
32617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	_enter(",%lx", user_call_ID);
32717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
32817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	ASSERT(!irqs_disabled());
32917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
33017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	write_lock(&rx->call_lock);
33117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
33217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	ret = -ENODATA;
33317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	if (list_empty(&rx->acceptq))
33417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		goto out;
33517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
33617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	/* check the user ID isn't already in use */
33717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	ret = -EBADSLT;
33817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	pp = &rx->calls.rb_node;
33917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	parent = NULL;
34017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	while (*pp) {
34117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		parent = *pp;
34217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		call = rb_entry(parent, struct rxrpc_call, sock_node);
34317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
34417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		if (user_call_ID < call->user_call_ID)
34517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells			pp = &(*pp)->rb_left;
34617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		else if (user_call_ID > call->user_call_ID)
34717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells			pp = &(*pp)->rb_right;
34817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		else
34917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells			goto out;
35017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	}
35117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
35217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	/* dequeue the first call and check it's still valid */
35317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	call = list_entry(rx->acceptq.next, struct rxrpc_call, accept_link);
35417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	list_del_init(&call->accept_link);
35517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	sk_acceptq_removed(&rx->sk);
35617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
35717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	write_lock_bh(&call->state_lock);
35817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	switch (call->state) {
35917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	case RXRPC_CALL_SERVER_ACCEPTING:
36017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		call->state = RXRPC_CALL_SERVER_RECV_REQUEST;
36117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		break;
36217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	case RXRPC_CALL_REMOTELY_ABORTED:
36317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	case RXRPC_CALL_LOCALLY_ABORTED:
36417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		ret = -ECONNABORTED;
36517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		goto out_release;
36617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	case RXRPC_CALL_NETWORK_ERROR:
36717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		ret = call->conn->error;
36817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		goto out_release;
36917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	case RXRPC_CALL_DEAD:
37017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		ret = -ETIME;
37117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		goto out_discard;
37217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	default:
37317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		BUG();
37417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	}
37517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
37617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	/* formalise the acceptance */
37717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	call->user_call_ID = user_call_ID;
37817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	rb_link_node(&call->sock_node, parent, pp);
37917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	rb_insert_color(&call->sock_node, &rx->calls);
38017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	if (test_and_set_bit(RXRPC_CALL_HAS_USERID, &call->flags))
38117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		BUG();
38217926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	if (test_and_set_bit(RXRPC_CALL_ACCEPTED, &call->events))
38317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells		BUG();
384651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	rxrpc_queue_call(call);
38517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
386651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	rxrpc_get_call(call);
38717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	write_unlock_bh(&call->state_lock);
38817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	write_unlock(&rx->call_lock);
389651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	_leave(" = %p{%d}", call, call->debug_id);
390651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	return call;
391651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells
392651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	/* if the call is already dying or dead, then we leave the socket's ref
393651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	 * on it to be released by rxrpc_dead_call_expired() as induced by
394651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	 * rxrpc_release_call() */
395651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howellsout_release:
396651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	_debug("release %p", call);
397651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	if (!test_bit(RXRPC_CALL_RELEASED, &call->flags) &&
398651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	    !test_and_set_bit(RXRPC_CALL_RELEASE, &call->events))
399651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells		rxrpc_queue_call(call);
400651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howellsout_discard:
401651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	write_unlock_bh(&call->state_lock);
402651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	_debug("discard %p", call);
403651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howellsout:
404651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	write_unlock(&rx->call_lock);
405651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	_leave(" = %d", ret);
406651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	return ERR_PTR(ret);
407651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells}
408651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells
409651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells/*
410651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells * handle rejectance of a call by userspace
411651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells * - reject the call at the front of the queue
412651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells */
413651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howellsint rxrpc_reject_call(struct rxrpc_sock *rx)
414651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells{
415651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	struct rxrpc_call *call;
416651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	int ret;
417651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells
418651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	_enter("");
419651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells
420651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	ASSERT(!irqs_disabled());
421651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells
422651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	write_lock(&rx->call_lock);
423651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells
424651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	ret = -ENODATA;
425651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	if (list_empty(&rx->acceptq))
426651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells		goto out;
427651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells
428651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	/* dequeue the first call and check it's still valid */
429651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	call = list_entry(rx->acceptq.next, struct rxrpc_call, accept_link);
430651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	list_del_init(&call->accept_link);
431651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	sk_acceptq_removed(&rx->sk);
432651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells
433651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	write_lock_bh(&call->state_lock);
434651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	switch (call->state) {
435651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	case RXRPC_CALL_SERVER_ACCEPTING:
436651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells		call->state = RXRPC_CALL_SERVER_BUSY;
437651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells		if (test_and_set_bit(RXRPC_CALL_REJECT_BUSY, &call->events))
438651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells			rxrpc_queue_call(call);
439651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells		ret = 0;
440651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells		goto out_release;
441651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	case RXRPC_CALL_REMOTELY_ABORTED:
442651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	case RXRPC_CALL_LOCALLY_ABORTED:
443651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells		ret = -ECONNABORTED;
444651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells		goto out_release;
445651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	case RXRPC_CALL_NETWORK_ERROR:
446651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells		ret = call->conn->error;
447651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells		goto out_release;
448651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	case RXRPC_CALL_DEAD:
449651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells		ret = -ETIME;
450651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells		goto out_discard;
451651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	default:
452651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells		BUG();
453651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	}
45417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells
45517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	/* if the call is already dying or dead, then we leave the socket's ref
45617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	 * on it to be released by rxrpc_dead_call_expired() as induced by
45717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	 * rxrpc_release_call() */
45817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howellsout_release:
45917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	_debug("release %p", call);
46017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	if (!test_bit(RXRPC_CALL_RELEASED, &call->flags) &&
46117926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	    !test_and_set_bit(RXRPC_CALL_RELEASE, &call->events))
462651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells		rxrpc_queue_call(call);
46317926a79320afa9b95df6b977b40cca6d8713ceaDavid Howellsout_discard:
46417926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	write_unlock_bh(&call->state_lock);
46517926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	_debug("discard %p", call);
46617926a79320afa9b95df6b977b40cca6d8713ceaDavid Howellsout:
46717926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	write_unlock(&rx->call_lock);
46817926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	_leave(" = %d", ret);
46917926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells	return ret;
47017926a79320afa9b95df6b977b40cca6d8713ceaDavid Howells}
471651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells
472651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells/**
473651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells * rxrpc_kernel_accept_call - Allow a kernel service to accept an incoming call
474651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells * @sock: The socket on which the impending call is waiting
475651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells * @user_call_ID: The tag to attach to the call
476651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells *
477651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells * Allow a kernel service to accept an incoming call, assuming the incoming
478651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells * call is still valid.
479651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells */
480651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howellsstruct rxrpc_call *rxrpc_kernel_accept_call(struct socket *sock,
481651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells					    unsigned long user_call_ID)
482651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells{
483651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	struct rxrpc_call *call;
484651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells
485651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	_enter(",%lx", user_call_ID);
486651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	call = rxrpc_accept_call(rxrpc_sk(sock->sk), user_call_ID);
487651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	_leave(" = %p", call);
488651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	return call;
489651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells}
490651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells
491651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid HowellsEXPORT_SYMBOL(rxrpc_kernel_accept_call);
492651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells
493651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells/**
494651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells * rxrpc_kernel_reject_call - Allow a kernel service to reject an incoming call
495651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells * @sock: The socket on which the impending call is waiting
496651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells *
497651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells * Allow a kernel service to reject an incoming call with a BUSY message,
498651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells * assuming the incoming call is still valid.
499651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells */
500651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howellsint rxrpc_kernel_reject_call(struct socket *sock)
501651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells{
502651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	int ret;
503651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells
504651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	_enter("");
505651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	ret = rxrpc_reject_call(rxrpc_sk(sock->sk));
506651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	_leave(" = %d", ret);
507651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells	return ret;
508651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells}
509651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid Howells
510651350d10f93bed7003c9a66e24cf25e0f8eed3dDavid HowellsEXPORT_SYMBOL(rxrpc_kernel_reject_call);
511