162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* incoming call handling 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 562306a36Sopenharmony_ci * Written by David Howells (dhowells@redhat.com) 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/module.h> 1162306a36Sopenharmony_ci#include <linux/net.h> 1262306a36Sopenharmony_ci#include <linux/skbuff.h> 1362306a36Sopenharmony_ci#include <linux/errqueue.h> 1462306a36Sopenharmony_ci#include <linux/udp.h> 1562306a36Sopenharmony_ci#include <linux/in.h> 1662306a36Sopenharmony_ci#include <linux/in6.h> 1762306a36Sopenharmony_ci#include <linux/icmp.h> 1862306a36Sopenharmony_ci#include <linux/gfp.h> 1962306a36Sopenharmony_ci#include <linux/circ_buf.h> 2062306a36Sopenharmony_ci#include <net/sock.h> 2162306a36Sopenharmony_ci#include <net/af_rxrpc.h> 2262306a36Sopenharmony_ci#include <net/ip.h> 2362306a36Sopenharmony_ci#include "ar-internal.h" 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_cistatic void rxrpc_dummy_notify(struct sock *sk, struct rxrpc_call *call, 2662306a36Sopenharmony_ci unsigned long user_call_ID) 2762306a36Sopenharmony_ci{ 2862306a36Sopenharmony_ci} 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci/* 3162306a36Sopenharmony_ci * Preallocate a single service call, connection and peer and, if possible, 3262306a36Sopenharmony_ci * give them a user ID and attach the user's side of the ID to them. 3362306a36Sopenharmony_ci */ 3462306a36Sopenharmony_cistatic int rxrpc_service_prealloc_one(struct rxrpc_sock *rx, 3562306a36Sopenharmony_ci struct rxrpc_backlog *b, 3662306a36Sopenharmony_ci rxrpc_notify_rx_t notify_rx, 3762306a36Sopenharmony_ci rxrpc_user_attach_call_t user_attach_call, 3862306a36Sopenharmony_ci unsigned long user_call_ID, gfp_t gfp, 3962306a36Sopenharmony_ci unsigned int debug_id) 4062306a36Sopenharmony_ci{ 4162306a36Sopenharmony_ci struct rxrpc_call *call, *xcall; 4262306a36Sopenharmony_ci struct rxrpc_net *rxnet = rxrpc_net(sock_net(&rx->sk)); 4362306a36Sopenharmony_ci struct rb_node *parent, **pp; 4462306a36Sopenharmony_ci int max, tmp; 4562306a36Sopenharmony_ci unsigned int size = RXRPC_BACKLOG_MAX; 4662306a36Sopenharmony_ci unsigned int head, tail, call_head, call_tail; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci max = rx->sk.sk_max_ack_backlog; 4962306a36Sopenharmony_ci tmp = rx->sk.sk_ack_backlog; 5062306a36Sopenharmony_ci if (tmp >= max) { 5162306a36Sopenharmony_ci _leave(" = -ENOBUFS [full %u]", max); 5262306a36Sopenharmony_ci return -ENOBUFS; 5362306a36Sopenharmony_ci } 5462306a36Sopenharmony_ci max -= tmp; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci /* We don't need more conns and peers than we have calls, but on the 5762306a36Sopenharmony_ci * other hand, we shouldn't ever use more peers than conns or conns 5862306a36Sopenharmony_ci * than calls. 5962306a36Sopenharmony_ci */ 6062306a36Sopenharmony_ci call_head = b->call_backlog_head; 6162306a36Sopenharmony_ci call_tail = READ_ONCE(b->call_backlog_tail); 6262306a36Sopenharmony_ci tmp = CIRC_CNT(call_head, call_tail, size); 6362306a36Sopenharmony_ci if (tmp >= max) { 6462306a36Sopenharmony_ci _leave(" = -ENOBUFS [enough %u]", tmp); 6562306a36Sopenharmony_ci return -ENOBUFS; 6662306a36Sopenharmony_ci } 6762306a36Sopenharmony_ci max = tmp + 1; 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci head = b->peer_backlog_head; 7062306a36Sopenharmony_ci tail = READ_ONCE(b->peer_backlog_tail); 7162306a36Sopenharmony_ci if (CIRC_CNT(head, tail, size) < max) { 7262306a36Sopenharmony_ci struct rxrpc_peer *peer; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci peer = rxrpc_alloc_peer(rx->local, gfp, rxrpc_peer_new_prealloc); 7562306a36Sopenharmony_ci if (!peer) 7662306a36Sopenharmony_ci return -ENOMEM; 7762306a36Sopenharmony_ci b->peer_backlog[head] = peer; 7862306a36Sopenharmony_ci smp_store_release(&b->peer_backlog_head, 7962306a36Sopenharmony_ci (head + 1) & (size - 1)); 8062306a36Sopenharmony_ci } 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci head = b->conn_backlog_head; 8362306a36Sopenharmony_ci tail = READ_ONCE(b->conn_backlog_tail); 8462306a36Sopenharmony_ci if (CIRC_CNT(head, tail, size) < max) { 8562306a36Sopenharmony_ci struct rxrpc_connection *conn; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci conn = rxrpc_prealloc_service_connection(rxnet, gfp); 8862306a36Sopenharmony_ci if (!conn) 8962306a36Sopenharmony_ci return -ENOMEM; 9062306a36Sopenharmony_ci b->conn_backlog[head] = conn; 9162306a36Sopenharmony_ci smp_store_release(&b->conn_backlog_head, 9262306a36Sopenharmony_ci (head + 1) & (size - 1)); 9362306a36Sopenharmony_ci } 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci /* Now it gets complicated, because calls get registered with the 9662306a36Sopenharmony_ci * socket here, with a user ID preassigned by the user. 9762306a36Sopenharmony_ci */ 9862306a36Sopenharmony_ci call = rxrpc_alloc_call(rx, gfp, debug_id); 9962306a36Sopenharmony_ci if (!call) 10062306a36Sopenharmony_ci return -ENOMEM; 10162306a36Sopenharmony_ci call->flags |= (1 << RXRPC_CALL_IS_SERVICE); 10262306a36Sopenharmony_ci rxrpc_set_call_state(call, RXRPC_CALL_SERVER_PREALLOC); 10362306a36Sopenharmony_ci __set_bit(RXRPC_CALL_EV_INITIAL_PING, &call->events); 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci trace_rxrpc_call(call->debug_id, refcount_read(&call->ref), 10662306a36Sopenharmony_ci user_call_ID, rxrpc_call_new_prealloc_service); 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci write_lock(&rx->call_lock); 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci /* Check the user ID isn't already in use */ 11162306a36Sopenharmony_ci pp = &rx->calls.rb_node; 11262306a36Sopenharmony_ci parent = NULL; 11362306a36Sopenharmony_ci while (*pp) { 11462306a36Sopenharmony_ci parent = *pp; 11562306a36Sopenharmony_ci xcall = rb_entry(parent, struct rxrpc_call, sock_node); 11662306a36Sopenharmony_ci if (user_call_ID < xcall->user_call_ID) 11762306a36Sopenharmony_ci pp = &(*pp)->rb_left; 11862306a36Sopenharmony_ci else if (user_call_ID > xcall->user_call_ID) 11962306a36Sopenharmony_ci pp = &(*pp)->rb_right; 12062306a36Sopenharmony_ci else 12162306a36Sopenharmony_ci goto id_in_use; 12262306a36Sopenharmony_ci } 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci call->user_call_ID = user_call_ID; 12562306a36Sopenharmony_ci call->notify_rx = notify_rx; 12662306a36Sopenharmony_ci if (user_attach_call) { 12762306a36Sopenharmony_ci rxrpc_get_call(call, rxrpc_call_get_kernel_service); 12862306a36Sopenharmony_ci user_attach_call(call, user_call_ID); 12962306a36Sopenharmony_ci } 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci rxrpc_get_call(call, rxrpc_call_get_userid); 13262306a36Sopenharmony_ci rb_link_node(&call->sock_node, parent, pp); 13362306a36Sopenharmony_ci rb_insert_color(&call->sock_node, &rx->calls); 13462306a36Sopenharmony_ci set_bit(RXRPC_CALL_HAS_USERID, &call->flags); 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci list_add(&call->sock_link, &rx->sock_calls); 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci write_unlock(&rx->call_lock); 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci rxnet = call->rxnet; 14162306a36Sopenharmony_ci spin_lock(&rxnet->call_lock); 14262306a36Sopenharmony_ci list_add_tail_rcu(&call->link, &rxnet->calls); 14362306a36Sopenharmony_ci spin_unlock(&rxnet->call_lock); 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci b->call_backlog[call_head] = call; 14662306a36Sopenharmony_ci smp_store_release(&b->call_backlog_head, (call_head + 1) & (size - 1)); 14762306a36Sopenharmony_ci _leave(" = 0 [%d -> %lx]", call->debug_id, user_call_ID); 14862306a36Sopenharmony_ci return 0; 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ciid_in_use: 15162306a36Sopenharmony_ci write_unlock(&rx->call_lock); 15262306a36Sopenharmony_ci rxrpc_cleanup_call(call); 15362306a36Sopenharmony_ci _leave(" = -EBADSLT"); 15462306a36Sopenharmony_ci return -EBADSLT; 15562306a36Sopenharmony_ci} 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci/* 15862306a36Sopenharmony_ci * Allocate the preallocation buffers for incoming service calls. These must 15962306a36Sopenharmony_ci * be charged manually. 16062306a36Sopenharmony_ci */ 16162306a36Sopenharmony_ciint rxrpc_service_prealloc(struct rxrpc_sock *rx, gfp_t gfp) 16262306a36Sopenharmony_ci{ 16362306a36Sopenharmony_ci struct rxrpc_backlog *b = rx->backlog; 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci if (!b) { 16662306a36Sopenharmony_ci b = kzalloc(sizeof(struct rxrpc_backlog), gfp); 16762306a36Sopenharmony_ci if (!b) 16862306a36Sopenharmony_ci return -ENOMEM; 16962306a36Sopenharmony_ci rx->backlog = b; 17062306a36Sopenharmony_ci } 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci return 0; 17362306a36Sopenharmony_ci} 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci/* 17662306a36Sopenharmony_ci * Discard the preallocation on a service. 17762306a36Sopenharmony_ci */ 17862306a36Sopenharmony_civoid rxrpc_discard_prealloc(struct rxrpc_sock *rx) 17962306a36Sopenharmony_ci{ 18062306a36Sopenharmony_ci struct rxrpc_backlog *b = rx->backlog; 18162306a36Sopenharmony_ci struct rxrpc_net *rxnet = rxrpc_net(sock_net(&rx->sk)); 18262306a36Sopenharmony_ci unsigned int size = RXRPC_BACKLOG_MAX, head, tail; 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci if (!b) 18562306a36Sopenharmony_ci return; 18662306a36Sopenharmony_ci rx->backlog = NULL; 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci /* Make sure that there aren't any incoming calls in progress before we 18962306a36Sopenharmony_ci * clear the preallocation buffers. 19062306a36Sopenharmony_ci */ 19162306a36Sopenharmony_ci spin_lock(&rx->incoming_lock); 19262306a36Sopenharmony_ci spin_unlock(&rx->incoming_lock); 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci head = b->peer_backlog_head; 19562306a36Sopenharmony_ci tail = b->peer_backlog_tail; 19662306a36Sopenharmony_ci while (CIRC_CNT(head, tail, size) > 0) { 19762306a36Sopenharmony_ci struct rxrpc_peer *peer = b->peer_backlog[tail]; 19862306a36Sopenharmony_ci rxrpc_put_local(peer->local, rxrpc_local_put_prealloc_peer); 19962306a36Sopenharmony_ci kfree(peer); 20062306a36Sopenharmony_ci tail = (tail + 1) & (size - 1); 20162306a36Sopenharmony_ci } 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci head = b->conn_backlog_head; 20462306a36Sopenharmony_ci tail = b->conn_backlog_tail; 20562306a36Sopenharmony_ci while (CIRC_CNT(head, tail, size) > 0) { 20662306a36Sopenharmony_ci struct rxrpc_connection *conn = b->conn_backlog[tail]; 20762306a36Sopenharmony_ci write_lock(&rxnet->conn_lock); 20862306a36Sopenharmony_ci list_del(&conn->link); 20962306a36Sopenharmony_ci list_del(&conn->proc_link); 21062306a36Sopenharmony_ci write_unlock(&rxnet->conn_lock); 21162306a36Sopenharmony_ci kfree(conn); 21262306a36Sopenharmony_ci if (atomic_dec_and_test(&rxnet->nr_conns)) 21362306a36Sopenharmony_ci wake_up_var(&rxnet->nr_conns); 21462306a36Sopenharmony_ci tail = (tail + 1) & (size - 1); 21562306a36Sopenharmony_ci } 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci head = b->call_backlog_head; 21862306a36Sopenharmony_ci tail = b->call_backlog_tail; 21962306a36Sopenharmony_ci while (CIRC_CNT(head, tail, size) > 0) { 22062306a36Sopenharmony_ci struct rxrpc_call *call = b->call_backlog[tail]; 22162306a36Sopenharmony_ci rcu_assign_pointer(call->socket, rx); 22262306a36Sopenharmony_ci if (rx->discard_new_call) { 22362306a36Sopenharmony_ci _debug("discard %lx", call->user_call_ID); 22462306a36Sopenharmony_ci rx->discard_new_call(call, call->user_call_ID); 22562306a36Sopenharmony_ci if (call->notify_rx) 22662306a36Sopenharmony_ci call->notify_rx = rxrpc_dummy_notify; 22762306a36Sopenharmony_ci rxrpc_put_call(call, rxrpc_call_put_kernel); 22862306a36Sopenharmony_ci } 22962306a36Sopenharmony_ci rxrpc_call_completed(call); 23062306a36Sopenharmony_ci rxrpc_release_call(rx, call); 23162306a36Sopenharmony_ci rxrpc_put_call(call, rxrpc_call_put_discard_prealloc); 23262306a36Sopenharmony_ci tail = (tail + 1) & (size - 1); 23362306a36Sopenharmony_ci } 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci kfree(b); 23662306a36Sopenharmony_ci} 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci/* 23962306a36Sopenharmony_ci * Allocate a new incoming call from the prealloc pool, along with a connection 24062306a36Sopenharmony_ci * and a peer as necessary. 24162306a36Sopenharmony_ci */ 24262306a36Sopenharmony_cistatic struct rxrpc_call *rxrpc_alloc_incoming_call(struct rxrpc_sock *rx, 24362306a36Sopenharmony_ci struct rxrpc_local *local, 24462306a36Sopenharmony_ci struct rxrpc_peer *peer, 24562306a36Sopenharmony_ci struct rxrpc_connection *conn, 24662306a36Sopenharmony_ci const struct rxrpc_security *sec, 24762306a36Sopenharmony_ci struct sockaddr_rxrpc *peer_srx, 24862306a36Sopenharmony_ci struct sk_buff *skb) 24962306a36Sopenharmony_ci{ 25062306a36Sopenharmony_ci struct rxrpc_backlog *b = rx->backlog; 25162306a36Sopenharmony_ci struct rxrpc_call *call; 25262306a36Sopenharmony_ci unsigned short call_head, conn_head, peer_head; 25362306a36Sopenharmony_ci unsigned short call_tail, conn_tail, peer_tail; 25462306a36Sopenharmony_ci unsigned short call_count, conn_count; 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci /* #calls >= #conns >= #peers must hold true. */ 25762306a36Sopenharmony_ci call_head = smp_load_acquire(&b->call_backlog_head); 25862306a36Sopenharmony_ci call_tail = b->call_backlog_tail; 25962306a36Sopenharmony_ci call_count = CIRC_CNT(call_head, call_tail, RXRPC_BACKLOG_MAX); 26062306a36Sopenharmony_ci conn_head = smp_load_acquire(&b->conn_backlog_head); 26162306a36Sopenharmony_ci conn_tail = b->conn_backlog_tail; 26262306a36Sopenharmony_ci conn_count = CIRC_CNT(conn_head, conn_tail, RXRPC_BACKLOG_MAX); 26362306a36Sopenharmony_ci ASSERTCMP(conn_count, >=, call_count); 26462306a36Sopenharmony_ci peer_head = smp_load_acquire(&b->peer_backlog_head); 26562306a36Sopenharmony_ci peer_tail = b->peer_backlog_tail; 26662306a36Sopenharmony_ci ASSERTCMP(CIRC_CNT(peer_head, peer_tail, RXRPC_BACKLOG_MAX), >=, 26762306a36Sopenharmony_ci conn_count); 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci if (call_count == 0) 27062306a36Sopenharmony_ci return NULL; 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci if (!conn) { 27362306a36Sopenharmony_ci if (peer && !rxrpc_get_peer_maybe(peer, rxrpc_peer_get_service_conn)) 27462306a36Sopenharmony_ci peer = NULL; 27562306a36Sopenharmony_ci if (!peer) { 27662306a36Sopenharmony_ci peer = b->peer_backlog[peer_tail]; 27762306a36Sopenharmony_ci peer->srx = *peer_srx; 27862306a36Sopenharmony_ci b->peer_backlog[peer_tail] = NULL; 27962306a36Sopenharmony_ci smp_store_release(&b->peer_backlog_tail, 28062306a36Sopenharmony_ci (peer_tail + 1) & 28162306a36Sopenharmony_ci (RXRPC_BACKLOG_MAX - 1)); 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci rxrpc_new_incoming_peer(local, peer); 28462306a36Sopenharmony_ci } 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci /* Now allocate and set up the connection */ 28762306a36Sopenharmony_ci conn = b->conn_backlog[conn_tail]; 28862306a36Sopenharmony_ci b->conn_backlog[conn_tail] = NULL; 28962306a36Sopenharmony_ci smp_store_release(&b->conn_backlog_tail, 29062306a36Sopenharmony_ci (conn_tail + 1) & (RXRPC_BACKLOG_MAX - 1)); 29162306a36Sopenharmony_ci conn->local = rxrpc_get_local(local, rxrpc_local_get_prealloc_conn); 29262306a36Sopenharmony_ci conn->peer = peer; 29362306a36Sopenharmony_ci rxrpc_see_connection(conn, rxrpc_conn_see_new_service_conn); 29462306a36Sopenharmony_ci rxrpc_new_incoming_connection(rx, conn, sec, skb); 29562306a36Sopenharmony_ci } else { 29662306a36Sopenharmony_ci rxrpc_get_connection(conn, rxrpc_conn_get_service_conn); 29762306a36Sopenharmony_ci atomic_inc(&conn->active); 29862306a36Sopenharmony_ci } 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci /* And now we can allocate and set up a new call */ 30162306a36Sopenharmony_ci call = b->call_backlog[call_tail]; 30262306a36Sopenharmony_ci b->call_backlog[call_tail] = NULL; 30362306a36Sopenharmony_ci smp_store_release(&b->call_backlog_tail, 30462306a36Sopenharmony_ci (call_tail + 1) & (RXRPC_BACKLOG_MAX - 1)); 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci rxrpc_see_call(call, rxrpc_call_see_accept); 30762306a36Sopenharmony_ci call->local = rxrpc_get_local(conn->local, rxrpc_local_get_call); 30862306a36Sopenharmony_ci call->conn = conn; 30962306a36Sopenharmony_ci call->security = conn->security; 31062306a36Sopenharmony_ci call->security_ix = conn->security_ix; 31162306a36Sopenharmony_ci call->peer = rxrpc_get_peer(conn->peer, rxrpc_peer_get_accept); 31262306a36Sopenharmony_ci call->dest_srx = peer->srx; 31362306a36Sopenharmony_ci call->cong_ssthresh = call->peer->cong_ssthresh; 31462306a36Sopenharmony_ci call->tx_last_sent = ktime_get_real(); 31562306a36Sopenharmony_ci return call; 31662306a36Sopenharmony_ci} 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ci/* 31962306a36Sopenharmony_ci * Set up a new incoming call. Called from the I/O thread. 32062306a36Sopenharmony_ci * 32162306a36Sopenharmony_ci * If this is for a kernel service, when we allocate the call, it will have 32262306a36Sopenharmony_ci * three refs on it: (1) the kernel service, (2) the user_call_ID tree, (3) the 32362306a36Sopenharmony_ci * retainer ref obtained from the backlog buffer. Prealloc calls for userspace 32462306a36Sopenharmony_ci * services only have the ref from the backlog buffer. 32562306a36Sopenharmony_ci * 32662306a36Sopenharmony_ci * If we want to report an error, we mark the skb with the packet type and 32762306a36Sopenharmony_ci * abort code and return false. 32862306a36Sopenharmony_ci */ 32962306a36Sopenharmony_cibool rxrpc_new_incoming_call(struct rxrpc_local *local, 33062306a36Sopenharmony_ci struct rxrpc_peer *peer, 33162306a36Sopenharmony_ci struct rxrpc_connection *conn, 33262306a36Sopenharmony_ci struct sockaddr_rxrpc *peer_srx, 33362306a36Sopenharmony_ci struct sk_buff *skb) 33462306a36Sopenharmony_ci{ 33562306a36Sopenharmony_ci const struct rxrpc_security *sec = NULL; 33662306a36Sopenharmony_ci struct rxrpc_skb_priv *sp = rxrpc_skb(skb); 33762306a36Sopenharmony_ci struct rxrpc_call *call = NULL; 33862306a36Sopenharmony_ci struct rxrpc_sock *rx; 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ci _enter(""); 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_ci /* Don't set up a call for anything other than a DATA packet. */ 34362306a36Sopenharmony_ci if (sp->hdr.type != RXRPC_PACKET_TYPE_DATA) 34462306a36Sopenharmony_ci return rxrpc_protocol_error(skb, rxrpc_eproto_no_service_call); 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci read_lock(&local->services_lock); 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci /* Weed out packets to services we're not offering. Packets that would 34962306a36Sopenharmony_ci * begin a call are explicitly rejected and the rest are just 35062306a36Sopenharmony_ci * discarded. 35162306a36Sopenharmony_ci */ 35262306a36Sopenharmony_ci rx = local->service; 35362306a36Sopenharmony_ci if (!rx || (sp->hdr.serviceId != rx->srx.srx_service && 35462306a36Sopenharmony_ci sp->hdr.serviceId != rx->second_service) 35562306a36Sopenharmony_ci ) { 35662306a36Sopenharmony_ci if (sp->hdr.type == RXRPC_PACKET_TYPE_DATA && 35762306a36Sopenharmony_ci sp->hdr.seq == 1) 35862306a36Sopenharmony_ci goto unsupported_service; 35962306a36Sopenharmony_ci goto discard; 36062306a36Sopenharmony_ci } 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci if (!conn) { 36362306a36Sopenharmony_ci sec = rxrpc_get_incoming_security(rx, skb); 36462306a36Sopenharmony_ci if (!sec) 36562306a36Sopenharmony_ci goto unsupported_security; 36662306a36Sopenharmony_ci } 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_ci spin_lock(&rx->incoming_lock); 36962306a36Sopenharmony_ci if (rx->sk.sk_state == RXRPC_SERVER_LISTEN_DISABLED || 37062306a36Sopenharmony_ci rx->sk.sk_state == RXRPC_CLOSE) { 37162306a36Sopenharmony_ci rxrpc_direct_abort(skb, rxrpc_abort_shut_down, 37262306a36Sopenharmony_ci RX_INVALID_OPERATION, -ESHUTDOWN); 37362306a36Sopenharmony_ci goto no_call; 37462306a36Sopenharmony_ci } 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_ci call = rxrpc_alloc_incoming_call(rx, local, peer, conn, sec, peer_srx, 37762306a36Sopenharmony_ci skb); 37862306a36Sopenharmony_ci if (!call) { 37962306a36Sopenharmony_ci skb->mark = RXRPC_SKB_MARK_REJECT_BUSY; 38062306a36Sopenharmony_ci goto no_call; 38162306a36Sopenharmony_ci } 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_ci trace_rxrpc_receive(call, rxrpc_receive_incoming, 38462306a36Sopenharmony_ci sp->hdr.serial, sp->hdr.seq); 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ci /* Make the call live. */ 38762306a36Sopenharmony_ci rxrpc_incoming_call(rx, call, skb); 38862306a36Sopenharmony_ci conn = call->conn; 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci if (rx->notify_new_call) 39162306a36Sopenharmony_ci rx->notify_new_call(&rx->sk, call, call->user_call_ID); 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ci spin_lock(&conn->state_lock); 39462306a36Sopenharmony_ci if (conn->state == RXRPC_CONN_SERVICE_UNSECURED) { 39562306a36Sopenharmony_ci conn->state = RXRPC_CONN_SERVICE_CHALLENGING; 39662306a36Sopenharmony_ci set_bit(RXRPC_CONN_EV_CHALLENGE, &call->conn->events); 39762306a36Sopenharmony_ci rxrpc_queue_conn(call->conn, rxrpc_conn_queue_challenge); 39862306a36Sopenharmony_ci } 39962306a36Sopenharmony_ci spin_unlock(&conn->state_lock); 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_ci spin_unlock(&rx->incoming_lock); 40262306a36Sopenharmony_ci read_unlock(&local->services_lock); 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci if (hlist_unhashed(&call->error_link)) { 40562306a36Sopenharmony_ci spin_lock(&call->peer->lock); 40662306a36Sopenharmony_ci hlist_add_head(&call->error_link, &call->peer->error_targets); 40762306a36Sopenharmony_ci spin_unlock(&call->peer->lock); 40862306a36Sopenharmony_ci } 40962306a36Sopenharmony_ci 41062306a36Sopenharmony_ci _leave(" = %p{%d}", call, call->debug_id); 41162306a36Sopenharmony_ci rxrpc_input_call_event(call, skb); 41262306a36Sopenharmony_ci rxrpc_put_call(call, rxrpc_call_put_input); 41362306a36Sopenharmony_ci return true; 41462306a36Sopenharmony_ci 41562306a36Sopenharmony_ciunsupported_service: 41662306a36Sopenharmony_ci read_unlock(&local->services_lock); 41762306a36Sopenharmony_ci return rxrpc_direct_abort(skb, rxrpc_abort_service_not_offered, 41862306a36Sopenharmony_ci RX_INVALID_OPERATION, -EOPNOTSUPP); 41962306a36Sopenharmony_ciunsupported_security: 42062306a36Sopenharmony_ci read_unlock(&local->services_lock); 42162306a36Sopenharmony_ci return rxrpc_direct_abort(skb, rxrpc_abort_service_not_offered, 42262306a36Sopenharmony_ci RX_INVALID_OPERATION, -EKEYREJECTED); 42362306a36Sopenharmony_cino_call: 42462306a36Sopenharmony_ci spin_unlock(&rx->incoming_lock); 42562306a36Sopenharmony_ci read_unlock(&local->services_lock); 42662306a36Sopenharmony_ci _leave(" = f [%u]", skb->mark); 42762306a36Sopenharmony_ci return false; 42862306a36Sopenharmony_cidiscard: 42962306a36Sopenharmony_ci read_unlock(&local->services_lock); 43062306a36Sopenharmony_ci return true; 43162306a36Sopenharmony_ci} 43262306a36Sopenharmony_ci 43362306a36Sopenharmony_ci/* 43462306a36Sopenharmony_ci * Charge up socket with preallocated calls, attaching user call IDs. 43562306a36Sopenharmony_ci */ 43662306a36Sopenharmony_ciint rxrpc_user_charge_accept(struct rxrpc_sock *rx, unsigned long user_call_ID) 43762306a36Sopenharmony_ci{ 43862306a36Sopenharmony_ci struct rxrpc_backlog *b = rx->backlog; 43962306a36Sopenharmony_ci 44062306a36Sopenharmony_ci if (rx->sk.sk_state == RXRPC_CLOSE) 44162306a36Sopenharmony_ci return -ESHUTDOWN; 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_ci return rxrpc_service_prealloc_one(rx, b, NULL, NULL, user_call_ID, 44462306a36Sopenharmony_ci GFP_KERNEL, 44562306a36Sopenharmony_ci atomic_inc_return(&rxrpc_debug_id)); 44662306a36Sopenharmony_ci} 44762306a36Sopenharmony_ci 44862306a36Sopenharmony_ci/* 44962306a36Sopenharmony_ci * rxrpc_kernel_charge_accept - Charge up socket with preallocated calls 45062306a36Sopenharmony_ci * @sock: The socket on which to preallocate 45162306a36Sopenharmony_ci * @notify_rx: Event notification function for the call 45262306a36Sopenharmony_ci * @user_attach_call: Func to attach call to user_call_ID 45362306a36Sopenharmony_ci * @user_call_ID: The tag to attach to the preallocated call 45462306a36Sopenharmony_ci * @gfp: The allocation conditions. 45562306a36Sopenharmony_ci * @debug_id: The tracing debug ID. 45662306a36Sopenharmony_ci * 45762306a36Sopenharmony_ci * Charge up the socket with preallocated calls, each with a user ID. A 45862306a36Sopenharmony_ci * function should be provided to effect the attachment from the user's side. 45962306a36Sopenharmony_ci * The user is given a ref to hold on the call. 46062306a36Sopenharmony_ci * 46162306a36Sopenharmony_ci * Note that the call may be come connected before this function returns. 46262306a36Sopenharmony_ci */ 46362306a36Sopenharmony_ciint rxrpc_kernel_charge_accept(struct socket *sock, 46462306a36Sopenharmony_ci rxrpc_notify_rx_t notify_rx, 46562306a36Sopenharmony_ci rxrpc_user_attach_call_t user_attach_call, 46662306a36Sopenharmony_ci unsigned long user_call_ID, gfp_t gfp, 46762306a36Sopenharmony_ci unsigned int debug_id) 46862306a36Sopenharmony_ci{ 46962306a36Sopenharmony_ci struct rxrpc_sock *rx = rxrpc_sk(sock->sk); 47062306a36Sopenharmony_ci struct rxrpc_backlog *b = rx->backlog; 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_ci if (sock->sk->sk_state == RXRPC_CLOSE) 47362306a36Sopenharmony_ci return -ESHUTDOWN; 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_ci return rxrpc_service_prealloc_one(rx, b, notify_rx, 47662306a36Sopenharmony_ci user_attach_call, user_call_ID, 47762306a36Sopenharmony_ci gfp, debug_id); 47862306a36Sopenharmony_ci} 47962306a36Sopenharmony_ciEXPORT_SYMBOL(rxrpc_kernel_charge_accept); 480