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