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