18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci/* AF_RXRPC internal definitions
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
58c2ecf20Sopenharmony_ci * Written by David Howells (dhowells@redhat.com)
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <linux/atomic.h>
98c2ecf20Sopenharmony_ci#include <linux/seqlock.h>
108c2ecf20Sopenharmony_ci#include <linux/win_minmax.h>
118c2ecf20Sopenharmony_ci#include <net/net_namespace.h>
128c2ecf20Sopenharmony_ci#include <net/netns/generic.h>
138c2ecf20Sopenharmony_ci#include <net/sock.h>
148c2ecf20Sopenharmony_ci#include <net/af_rxrpc.h>
158c2ecf20Sopenharmony_ci#include "protocol.h"
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci#define FCRYPT_BSIZE 8
188c2ecf20Sopenharmony_cistruct rxrpc_crypt {
198c2ecf20Sopenharmony_ci	union {
208c2ecf20Sopenharmony_ci		u8	x[FCRYPT_BSIZE];
218c2ecf20Sopenharmony_ci		__be32	n[2];
228c2ecf20Sopenharmony_ci	};
238c2ecf20Sopenharmony_ci} __attribute__((aligned(8)));
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci#define rxrpc_queue_work(WS)	queue_work(rxrpc_workqueue, (WS))
268c2ecf20Sopenharmony_ci#define rxrpc_queue_delayed_work(WS,D)	\
278c2ecf20Sopenharmony_ci	queue_delayed_work(rxrpc_workqueue, (WS), (D))
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_cistruct rxrpc_connection;
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci/*
328c2ecf20Sopenharmony_ci * Mark applied to socket buffers in skb->mark.  skb->priority is used
338c2ecf20Sopenharmony_ci * to pass supplementary information.
348c2ecf20Sopenharmony_ci */
358c2ecf20Sopenharmony_cienum rxrpc_skb_mark {
368c2ecf20Sopenharmony_ci	RXRPC_SKB_MARK_REJECT_BUSY,	/* Reject with BUSY */
378c2ecf20Sopenharmony_ci	RXRPC_SKB_MARK_REJECT_ABORT,	/* Reject with ABORT (code in skb->priority) */
388c2ecf20Sopenharmony_ci};
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci/*
418c2ecf20Sopenharmony_ci * sk_state for RxRPC sockets
428c2ecf20Sopenharmony_ci */
438c2ecf20Sopenharmony_cienum {
448c2ecf20Sopenharmony_ci	RXRPC_UNBOUND = 0,
458c2ecf20Sopenharmony_ci	RXRPC_CLIENT_UNBOUND,		/* Unbound socket used as client */
468c2ecf20Sopenharmony_ci	RXRPC_CLIENT_BOUND,		/* client local address bound */
478c2ecf20Sopenharmony_ci	RXRPC_SERVER_BOUND,		/* server local address bound */
488c2ecf20Sopenharmony_ci	RXRPC_SERVER_BOUND2,		/* second server local address bound */
498c2ecf20Sopenharmony_ci	RXRPC_SERVER_LISTENING,		/* server listening for connections */
508c2ecf20Sopenharmony_ci	RXRPC_SERVER_LISTEN_DISABLED,	/* server listening disabled */
518c2ecf20Sopenharmony_ci	RXRPC_CLOSE,			/* socket is being closed */
528c2ecf20Sopenharmony_ci};
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci/*
558c2ecf20Sopenharmony_ci * Per-network namespace data.
568c2ecf20Sopenharmony_ci */
578c2ecf20Sopenharmony_cistruct rxrpc_net {
588c2ecf20Sopenharmony_ci	struct proc_dir_entry	*proc_net;	/* Subdir in /proc/net */
598c2ecf20Sopenharmony_ci	u32			epoch;		/* Local epoch for detecting local-end reset */
608c2ecf20Sopenharmony_ci	struct list_head	calls;		/* List of calls active in this namespace */
618c2ecf20Sopenharmony_ci	rwlock_t		call_lock;	/* Lock for ->calls */
628c2ecf20Sopenharmony_ci	atomic_t		nr_calls;	/* Count of allocated calls */
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci	atomic_t		nr_conns;
658c2ecf20Sopenharmony_ci	struct list_head	conn_proc_list;	/* List of conns in this namespace for proc */
668c2ecf20Sopenharmony_ci	struct list_head	service_conns;	/* Service conns in this namespace */
678c2ecf20Sopenharmony_ci	rwlock_t		conn_lock;	/* Lock for ->conn_proc_list, ->service_conns */
688c2ecf20Sopenharmony_ci	struct work_struct	service_conn_reaper;
698c2ecf20Sopenharmony_ci	struct timer_list	service_conn_reap_timer;
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci	bool			live;
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci	bool			kill_all_client_conns;
748c2ecf20Sopenharmony_ci	atomic_t		nr_client_conns;
758c2ecf20Sopenharmony_ci	spinlock_t		client_conn_cache_lock; /* Lock for ->*_client_conns */
768c2ecf20Sopenharmony_ci	spinlock_t		client_conn_discard_lock; /* Prevent multiple discarders */
778c2ecf20Sopenharmony_ci	struct list_head	idle_client_conns;
788c2ecf20Sopenharmony_ci	struct work_struct	client_conn_reaper;
798c2ecf20Sopenharmony_ci	struct timer_list	client_conn_reap_timer;
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci	struct hlist_head	local_endpoints;
828c2ecf20Sopenharmony_ci	struct mutex		local_mutex;	/* Lock for ->local_endpoints */
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci	DECLARE_HASHTABLE	(peer_hash, 10);
858c2ecf20Sopenharmony_ci	spinlock_t		peer_hash_lock;	/* Lock for ->peer_hash */
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci#define RXRPC_KEEPALIVE_TIME 20 /* NAT keepalive time in seconds */
888c2ecf20Sopenharmony_ci	u8			peer_keepalive_cursor;
898c2ecf20Sopenharmony_ci	time64_t		peer_keepalive_base;
908c2ecf20Sopenharmony_ci	struct list_head	peer_keepalive[32];
918c2ecf20Sopenharmony_ci	struct list_head	peer_keepalive_new;
928c2ecf20Sopenharmony_ci	struct timer_list	peer_keepalive_timer;
938c2ecf20Sopenharmony_ci	struct work_struct	peer_keepalive_work;
948c2ecf20Sopenharmony_ci};
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci/*
978c2ecf20Sopenharmony_ci * Service backlog preallocation.
988c2ecf20Sopenharmony_ci *
998c2ecf20Sopenharmony_ci * This contains circular buffers of preallocated peers, connections and calls
1008c2ecf20Sopenharmony_ci * for incoming service calls and their head and tail pointers.  This allows
1018c2ecf20Sopenharmony_ci * calls to be set up in the data_ready handler, thereby avoiding the need to
1028c2ecf20Sopenharmony_ci * shuffle packets around so much.
1038c2ecf20Sopenharmony_ci */
1048c2ecf20Sopenharmony_cistruct rxrpc_backlog {
1058c2ecf20Sopenharmony_ci	unsigned short		peer_backlog_head;
1068c2ecf20Sopenharmony_ci	unsigned short		peer_backlog_tail;
1078c2ecf20Sopenharmony_ci	unsigned short		conn_backlog_head;
1088c2ecf20Sopenharmony_ci	unsigned short		conn_backlog_tail;
1098c2ecf20Sopenharmony_ci	unsigned short		call_backlog_head;
1108c2ecf20Sopenharmony_ci	unsigned short		call_backlog_tail;
1118c2ecf20Sopenharmony_ci#define RXRPC_BACKLOG_MAX	32
1128c2ecf20Sopenharmony_ci	struct rxrpc_peer	*peer_backlog[RXRPC_BACKLOG_MAX];
1138c2ecf20Sopenharmony_ci	struct rxrpc_connection	*conn_backlog[RXRPC_BACKLOG_MAX];
1148c2ecf20Sopenharmony_ci	struct rxrpc_call	*call_backlog[RXRPC_BACKLOG_MAX];
1158c2ecf20Sopenharmony_ci};
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci/*
1188c2ecf20Sopenharmony_ci * RxRPC socket definition
1198c2ecf20Sopenharmony_ci */
1208c2ecf20Sopenharmony_cistruct rxrpc_sock {
1218c2ecf20Sopenharmony_ci	/* WARNING: sk has to be the first member */
1228c2ecf20Sopenharmony_ci	struct sock		sk;
1238c2ecf20Sopenharmony_ci	rxrpc_notify_new_call_t	notify_new_call; /* Func to notify of new call */
1248c2ecf20Sopenharmony_ci	rxrpc_discard_new_call_t discard_new_call; /* Func to discard a new call */
1258c2ecf20Sopenharmony_ci	struct rxrpc_local	*local;		/* local endpoint */
1268c2ecf20Sopenharmony_ci	struct rxrpc_backlog	*backlog;	/* Preallocation for services */
1278c2ecf20Sopenharmony_ci	spinlock_t		incoming_lock;	/* Incoming call vs service shutdown lock */
1288c2ecf20Sopenharmony_ci	struct list_head	sock_calls;	/* List of calls owned by this socket */
1298c2ecf20Sopenharmony_ci	struct list_head	to_be_accepted;	/* calls awaiting acceptance */
1308c2ecf20Sopenharmony_ci	struct list_head	recvmsg_q;	/* Calls awaiting recvmsg's attention  */
1318c2ecf20Sopenharmony_ci	rwlock_t		recvmsg_lock;	/* Lock for recvmsg_q */
1328c2ecf20Sopenharmony_ci	struct key		*key;		/* security for this socket */
1338c2ecf20Sopenharmony_ci	struct key		*securities;	/* list of server security descriptors */
1348c2ecf20Sopenharmony_ci	struct rb_root		calls;		/* User ID -> call mapping */
1358c2ecf20Sopenharmony_ci	unsigned long		flags;
1368c2ecf20Sopenharmony_ci#define RXRPC_SOCK_CONNECTED		0	/* connect_srx is set */
1378c2ecf20Sopenharmony_ci	rwlock_t		call_lock;	/* lock for calls */
1388c2ecf20Sopenharmony_ci	u32			min_sec_level;	/* minimum security level */
1398c2ecf20Sopenharmony_ci#define RXRPC_SECURITY_MAX	RXRPC_SECURITY_ENCRYPT
1408c2ecf20Sopenharmony_ci	bool			exclusive;	/* Exclusive connection for a client socket */
1418c2ecf20Sopenharmony_ci	u16			second_service;	/* Additional service bound to the endpoint */
1428c2ecf20Sopenharmony_ci	struct {
1438c2ecf20Sopenharmony_ci		/* Service upgrade information */
1448c2ecf20Sopenharmony_ci		u16		from;		/* Service ID to upgrade (if not 0) */
1458c2ecf20Sopenharmony_ci		u16		to;		/* service ID to upgrade to */
1468c2ecf20Sopenharmony_ci	} service_upgrade;
1478c2ecf20Sopenharmony_ci	sa_family_t		family;		/* Protocol family created with */
1488c2ecf20Sopenharmony_ci	struct sockaddr_rxrpc	srx;		/* Primary Service/local addresses */
1498c2ecf20Sopenharmony_ci	struct sockaddr_rxrpc	connect_srx;	/* Default client address from connect() */
1508c2ecf20Sopenharmony_ci};
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ci#define rxrpc_sk(__sk) container_of((__sk), struct rxrpc_sock, sk)
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci/*
1558c2ecf20Sopenharmony_ci * CPU-byteorder normalised Rx packet header.
1568c2ecf20Sopenharmony_ci */
1578c2ecf20Sopenharmony_cistruct rxrpc_host_header {
1588c2ecf20Sopenharmony_ci	u32		epoch;		/* client boot timestamp */
1598c2ecf20Sopenharmony_ci	u32		cid;		/* connection and channel ID */
1608c2ecf20Sopenharmony_ci	u32		callNumber;	/* call ID (0 for connection-level packets) */
1618c2ecf20Sopenharmony_ci	u32		seq;		/* sequence number of pkt in call stream */
1628c2ecf20Sopenharmony_ci	u32		serial;		/* serial number of pkt sent to network */
1638c2ecf20Sopenharmony_ci	u8		type;		/* packet type */
1648c2ecf20Sopenharmony_ci	u8		flags;		/* packet flags */
1658c2ecf20Sopenharmony_ci	u8		userStatus;	/* app-layer defined status */
1668c2ecf20Sopenharmony_ci	u8		securityIndex;	/* security protocol ID */
1678c2ecf20Sopenharmony_ci	union {
1688c2ecf20Sopenharmony_ci		u16	_rsvd;		/* reserved */
1698c2ecf20Sopenharmony_ci		u16	cksum;		/* kerberos security checksum */
1708c2ecf20Sopenharmony_ci	};
1718c2ecf20Sopenharmony_ci	u16		serviceId;	/* service ID */
1728c2ecf20Sopenharmony_ci} __packed;
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ci/*
1758c2ecf20Sopenharmony_ci * RxRPC socket buffer private variables
1768c2ecf20Sopenharmony_ci * - max 48 bytes (struct sk_buff::cb)
1778c2ecf20Sopenharmony_ci */
1788c2ecf20Sopenharmony_cistruct rxrpc_skb_priv {
1798c2ecf20Sopenharmony_ci	atomic_t	nr_ring_pins;		/* Number of rxtx ring pins */
1808c2ecf20Sopenharmony_ci	u8		nr_subpackets;		/* Number of subpackets */
1818c2ecf20Sopenharmony_ci	u8		rx_flags;		/* Received packet flags */
1828c2ecf20Sopenharmony_ci#define RXRPC_SKB_INCL_LAST	0x01		/* - Includes last packet */
1838c2ecf20Sopenharmony_ci#define RXRPC_SKB_TX_BUFFER	0x02		/* - Is transmit buffer */
1848c2ecf20Sopenharmony_ci	union {
1858c2ecf20Sopenharmony_ci		int		remain;		/* amount of space remaining for next write */
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci		/* List of requested ACKs on subpackets */
1888c2ecf20Sopenharmony_ci		unsigned long	rx_req_ack[(RXRPC_MAX_NR_JUMBO + BITS_PER_LONG - 1) /
1898c2ecf20Sopenharmony_ci					   BITS_PER_LONG];
1908c2ecf20Sopenharmony_ci	};
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_ci	struct rxrpc_host_header hdr;		/* RxRPC packet header from this packet */
1938c2ecf20Sopenharmony_ci};
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ci#define rxrpc_skb(__skb) ((struct rxrpc_skb_priv *) &(__skb)->cb)
1968c2ecf20Sopenharmony_ci
1978c2ecf20Sopenharmony_ci/*
1988c2ecf20Sopenharmony_ci * RxRPC security module interface
1998c2ecf20Sopenharmony_ci */
2008c2ecf20Sopenharmony_cistruct rxrpc_security {
2018c2ecf20Sopenharmony_ci	const char		*name;		/* name of this service */
2028c2ecf20Sopenharmony_ci	u8			security_index;	/* security type provided */
2038c2ecf20Sopenharmony_ci	u32			no_key_abort;	/* Abort code indicating no key */
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_ci	/* Initialise a security service */
2068c2ecf20Sopenharmony_ci	int (*init)(void);
2078c2ecf20Sopenharmony_ci
2088c2ecf20Sopenharmony_ci	/* Clean up a security service */
2098c2ecf20Sopenharmony_ci	void (*exit)(void);
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_ci	/* initialise a connection's security */
2128c2ecf20Sopenharmony_ci	int (*init_connection_security)(struct rxrpc_connection *);
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ci	/* prime a connection's packet security */
2158c2ecf20Sopenharmony_ci	int (*prime_packet_security)(struct rxrpc_connection *);
2168c2ecf20Sopenharmony_ci
2178c2ecf20Sopenharmony_ci	/* impose security on a packet */
2188c2ecf20Sopenharmony_ci	int (*secure_packet)(struct rxrpc_call *,
2198c2ecf20Sopenharmony_ci			     struct sk_buff *,
2208c2ecf20Sopenharmony_ci			     size_t,
2218c2ecf20Sopenharmony_ci			     void *);
2228c2ecf20Sopenharmony_ci
2238c2ecf20Sopenharmony_ci	/* verify the security on a received packet */
2248c2ecf20Sopenharmony_ci	int (*verify_packet)(struct rxrpc_call *, struct sk_buff *,
2258c2ecf20Sopenharmony_ci			     unsigned int, unsigned int, rxrpc_seq_t, u16);
2268c2ecf20Sopenharmony_ci
2278c2ecf20Sopenharmony_ci	/* Free crypto request on a call */
2288c2ecf20Sopenharmony_ci	void (*free_call_crypto)(struct rxrpc_call *);
2298c2ecf20Sopenharmony_ci
2308c2ecf20Sopenharmony_ci	/* Locate the data in a received packet that has been verified. */
2318c2ecf20Sopenharmony_ci	void (*locate_data)(struct rxrpc_call *, struct sk_buff *,
2328c2ecf20Sopenharmony_ci			    unsigned int *, unsigned int *);
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_ci	/* issue a challenge */
2358c2ecf20Sopenharmony_ci	int (*issue_challenge)(struct rxrpc_connection *);
2368c2ecf20Sopenharmony_ci
2378c2ecf20Sopenharmony_ci	/* respond to a challenge */
2388c2ecf20Sopenharmony_ci	int (*respond_to_challenge)(struct rxrpc_connection *,
2398c2ecf20Sopenharmony_ci				    struct sk_buff *,
2408c2ecf20Sopenharmony_ci				    u32 *);
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_ci	/* verify a response */
2438c2ecf20Sopenharmony_ci	int (*verify_response)(struct rxrpc_connection *,
2448c2ecf20Sopenharmony_ci			       struct sk_buff *,
2458c2ecf20Sopenharmony_ci			       u32 *);
2468c2ecf20Sopenharmony_ci
2478c2ecf20Sopenharmony_ci	/* clear connection security */
2488c2ecf20Sopenharmony_ci	void (*clear)(struct rxrpc_connection *);
2498c2ecf20Sopenharmony_ci};
2508c2ecf20Sopenharmony_ci
2518c2ecf20Sopenharmony_ci/*
2528c2ecf20Sopenharmony_ci * RxRPC local transport endpoint description
2538c2ecf20Sopenharmony_ci * - owned by a single AF_RXRPC socket
2548c2ecf20Sopenharmony_ci * - pointed to by transport socket struct sk_user_data
2558c2ecf20Sopenharmony_ci */
2568c2ecf20Sopenharmony_cistruct rxrpc_local {
2578c2ecf20Sopenharmony_ci	struct rcu_head		rcu;
2588c2ecf20Sopenharmony_ci	atomic_t		active_users;	/* Number of users of the local endpoint */
2598c2ecf20Sopenharmony_ci	refcount_t		ref;		/* Number of references to the structure */
2608c2ecf20Sopenharmony_ci	struct rxrpc_net	*rxnet;		/* The network ns in which this resides */
2618c2ecf20Sopenharmony_ci	struct hlist_node	link;
2628c2ecf20Sopenharmony_ci	struct socket		*socket;	/* my UDP socket */
2638c2ecf20Sopenharmony_ci	struct work_struct	processor;
2648c2ecf20Sopenharmony_ci	struct rxrpc_sock __rcu	*service;	/* Service(s) listening on this endpoint */
2658c2ecf20Sopenharmony_ci	struct rw_semaphore	defrag_sem;	/* control re-enablement of IP DF bit */
2668c2ecf20Sopenharmony_ci	struct sk_buff_head	reject_queue;	/* packets awaiting rejection */
2678c2ecf20Sopenharmony_ci	struct sk_buff_head	event_queue;	/* endpoint event packets awaiting processing */
2688c2ecf20Sopenharmony_ci	struct rb_root		client_bundles;	/* Client connection bundles by socket params */
2698c2ecf20Sopenharmony_ci	spinlock_t		client_bundles_lock; /* Lock for client_bundles */
2708c2ecf20Sopenharmony_ci	spinlock_t		lock;		/* access lock */
2718c2ecf20Sopenharmony_ci	rwlock_t		services_lock;	/* lock for services list */
2728c2ecf20Sopenharmony_ci	int			debug_id;	/* debug ID for printks */
2738c2ecf20Sopenharmony_ci	bool			dead;
2748c2ecf20Sopenharmony_ci	bool			service_closed;	/* Service socket closed */
2758c2ecf20Sopenharmony_ci	struct sockaddr_rxrpc	srx;		/* local address */
2768c2ecf20Sopenharmony_ci};
2778c2ecf20Sopenharmony_ci
2788c2ecf20Sopenharmony_ci/*
2798c2ecf20Sopenharmony_ci * RxRPC remote transport endpoint definition
2808c2ecf20Sopenharmony_ci * - matched by local endpoint, remote port, address and protocol type
2818c2ecf20Sopenharmony_ci */
2828c2ecf20Sopenharmony_cistruct rxrpc_peer {
2838c2ecf20Sopenharmony_ci	struct rcu_head		rcu;		/* This must be first */
2848c2ecf20Sopenharmony_ci	refcount_t		ref;
2858c2ecf20Sopenharmony_ci	unsigned long		hash_key;
2868c2ecf20Sopenharmony_ci	struct hlist_node	hash_link;
2878c2ecf20Sopenharmony_ci	struct rxrpc_local	*local;
2888c2ecf20Sopenharmony_ci	struct hlist_head	error_targets;	/* targets for net error distribution */
2898c2ecf20Sopenharmony_ci	struct rb_root		service_conns;	/* Service connections */
2908c2ecf20Sopenharmony_ci	struct list_head	keepalive_link;	/* Link in net->peer_keepalive[] */
2918c2ecf20Sopenharmony_ci	time64_t		last_tx_at;	/* Last time packet sent here */
2928c2ecf20Sopenharmony_ci	seqlock_t		service_conn_lock;
2938c2ecf20Sopenharmony_ci	spinlock_t		lock;		/* access lock */
2948c2ecf20Sopenharmony_ci	unsigned int		if_mtu;		/* interface MTU for this peer */
2958c2ecf20Sopenharmony_ci	unsigned int		mtu;		/* network MTU for this peer */
2968c2ecf20Sopenharmony_ci	unsigned int		maxdata;	/* data size (MTU - hdrsize) */
2978c2ecf20Sopenharmony_ci	unsigned short		hdrsize;	/* header size (IP + UDP + RxRPC) */
2988c2ecf20Sopenharmony_ci	int			debug_id;	/* debug ID for printks */
2998c2ecf20Sopenharmony_ci	struct sockaddr_rxrpc	srx;		/* remote address */
3008c2ecf20Sopenharmony_ci
3018c2ecf20Sopenharmony_ci	/* calculated RTT cache */
3028c2ecf20Sopenharmony_ci#define RXRPC_RTT_CACHE_SIZE 32
3038c2ecf20Sopenharmony_ci	spinlock_t		rtt_input_lock;	/* RTT lock for input routine */
3048c2ecf20Sopenharmony_ci	ktime_t			rtt_last_req;	/* Time of last RTT request */
3058c2ecf20Sopenharmony_ci	unsigned int		rtt_count;	/* Number of samples we've got */
3068c2ecf20Sopenharmony_ci
3078c2ecf20Sopenharmony_ci	u32			srtt_us;	/* smoothed round trip time << 3 in usecs */
3088c2ecf20Sopenharmony_ci	u32			mdev_us;	/* medium deviation			*/
3098c2ecf20Sopenharmony_ci	u32			mdev_max_us;	/* maximal mdev for the last rtt period	*/
3108c2ecf20Sopenharmony_ci	u32			rttvar_us;	/* smoothed mdev_max			*/
3118c2ecf20Sopenharmony_ci	u32			rto_j;		/* Retransmission timeout in jiffies */
3128c2ecf20Sopenharmony_ci	u8			backoff;	/* Backoff timeout */
3138c2ecf20Sopenharmony_ci
3148c2ecf20Sopenharmony_ci	u8			cong_cwnd;	/* Congestion window size */
3158c2ecf20Sopenharmony_ci};
3168c2ecf20Sopenharmony_ci
3178c2ecf20Sopenharmony_ci/*
3188c2ecf20Sopenharmony_ci * Keys for matching a connection.
3198c2ecf20Sopenharmony_ci */
3208c2ecf20Sopenharmony_cistruct rxrpc_conn_proto {
3218c2ecf20Sopenharmony_ci	union {
3228c2ecf20Sopenharmony_ci		struct {
3238c2ecf20Sopenharmony_ci			u32	epoch;		/* epoch of this connection */
3248c2ecf20Sopenharmony_ci			u32	cid;		/* connection ID */
3258c2ecf20Sopenharmony_ci		};
3268c2ecf20Sopenharmony_ci		u64		index_key;
3278c2ecf20Sopenharmony_ci	};
3288c2ecf20Sopenharmony_ci};
3298c2ecf20Sopenharmony_ci
3308c2ecf20Sopenharmony_cistruct rxrpc_conn_parameters {
3318c2ecf20Sopenharmony_ci	struct rxrpc_local	*local;		/* Representation of local endpoint */
3328c2ecf20Sopenharmony_ci	struct rxrpc_peer	*peer;		/* Remote endpoint */
3338c2ecf20Sopenharmony_ci	struct key		*key;		/* Security details */
3348c2ecf20Sopenharmony_ci	bool			exclusive;	/* T if conn is exclusive */
3358c2ecf20Sopenharmony_ci	bool			upgrade;	/* T if service ID can be upgraded */
3368c2ecf20Sopenharmony_ci	u16			service_id;	/* Service ID for this connection */
3378c2ecf20Sopenharmony_ci	u32			security_level;	/* Security level selected */
3388c2ecf20Sopenharmony_ci};
3398c2ecf20Sopenharmony_ci
3408c2ecf20Sopenharmony_ci/*
3418c2ecf20Sopenharmony_ci * Bits in the connection flags.
3428c2ecf20Sopenharmony_ci */
3438c2ecf20Sopenharmony_cienum rxrpc_conn_flag {
3448c2ecf20Sopenharmony_ci	RXRPC_CONN_HAS_IDR,		/* Has a client conn ID assigned */
3458c2ecf20Sopenharmony_ci	RXRPC_CONN_IN_SERVICE_CONNS,	/* Conn is in peer->service_conns */
3468c2ecf20Sopenharmony_ci	RXRPC_CONN_DONT_REUSE,		/* Don't reuse this connection */
3478c2ecf20Sopenharmony_ci	RXRPC_CONN_PROBING_FOR_UPGRADE,	/* Probing for service upgrade */
3488c2ecf20Sopenharmony_ci	RXRPC_CONN_FINAL_ACK_0,		/* Need final ACK for channel 0 */
3498c2ecf20Sopenharmony_ci	RXRPC_CONN_FINAL_ACK_1,		/* Need final ACK for channel 1 */
3508c2ecf20Sopenharmony_ci	RXRPC_CONN_FINAL_ACK_2,		/* Need final ACK for channel 2 */
3518c2ecf20Sopenharmony_ci	RXRPC_CONN_FINAL_ACK_3,		/* Need final ACK for channel 3 */
3528c2ecf20Sopenharmony_ci};
3538c2ecf20Sopenharmony_ci
3548c2ecf20Sopenharmony_ci#define RXRPC_CONN_FINAL_ACK_MASK ((1UL << RXRPC_CONN_FINAL_ACK_0) |	\
3558c2ecf20Sopenharmony_ci				   (1UL << RXRPC_CONN_FINAL_ACK_1) |	\
3568c2ecf20Sopenharmony_ci				   (1UL << RXRPC_CONN_FINAL_ACK_2) |	\
3578c2ecf20Sopenharmony_ci				   (1UL << RXRPC_CONN_FINAL_ACK_3))
3588c2ecf20Sopenharmony_ci
3598c2ecf20Sopenharmony_ci/*
3608c2ecf20Sopenharmony_ci * Events that can be raised upon a connection.
3618c2ecf20Sopenharmony_ci */
3628c2ecf20Sopenharmony_cienum rxrpc_conn_event {
3638c2ecf20Sopenharmony_ci	RXRPC_CONN_EV_CHALLENGE,	/* Send challenge packet */
3648c2ecf20Sopenharmony_ci};
3658c2ecf20Sopenharmony_ci
3668c2ecf20Sopenharmony_ci/*
3678c2ecf20Sopenharmony_ci * The connection protocol state.
3688c2ecf20Sopenharmony_ci */
3698c2ecf20Sopenharmony_cienum rxrpc_conn_proto_state {
3708c2ecf20Sopenharmony_ci	RXRPC_CONN_UNUSED,		/* Connection not yet attempted */
3718c2ecf20Sopenharmony_ci	RXRPC_CONN_CLIENT,		/* Client connection */
3728c2ecf20Sopenharmony_ci	RXRPC_CONN_SERVICE_PREALLOC,	/* Service connection preallocation */
3738c2ecf20Sopenharmony_ci	RXRPC_CONN_SERVICE_UNSECURED,	/* Service unsecured connection */
3748c2ecf20Sopenharmony_ci	RXRPC_CONN_SERVICE_CHALLENGING,	/* Service challenging for security */
3758c2ecf20Sopenharmony_ci	RXRPC_CONN_SERVICE,		/* Service secured connection */
3768c2ecf20Sopenharmony_ci	RXRPC_CONN_REMOTELY_ABORTED,	/* Conn aborted by peer */
3778c2ecf20Sopenharmony_ci	RXRPC_CONN_LOCALLY_ABORTED,	/* Conn aborted locally */
3788c2ecf20Sopenharmony_ci	RXRPC_CONN__NR_STATES
3798c2ecf20Sopenharmony_ci};
3808c2ecf20Sopenharmony_ci
3818c2ecf20Sopenharmony_ci/*
3828c2ecf20Sopenharmony_ci * RxRPC client connection bundle.
3838c2ecf20Sopenharmony_ci */
3848c2ecf20Sopenharmony_cistruct rxrpc_bundle {
3858c2ecf20Sopenharmony_ci	struct rxrpc_conn_parameters params;
3868c2ecf20Sopenharmony_ci	refcount_t		ref;
3878c2ecf20Sopenharmony_ci	atomic_t		active;		/* Number of active users */
3888c2ecf20Sopenharmony_ci	unsigned int		debug_id;
3898c2ecf20Sopenharmony_ci	bool			try_upgrade;	/* True if the bundle is attempting upgrade */
3908c2ecf20Sopenharmony_ci	bool			alloc_conn;	/* True if someone's getting a conn */
3918c2ecf20Sopenharmony_ci	short			alloc_error;	/* Error from last conn allocation */
3928c2ecf20Sopenharmony_ci	spinlock_t		channel_lock;
3938c2ecf20Sopenharmony_ci	struct rb_node		local_node;	/* Node in local->client_conns */
3948c2ecf20Sopenharmony_ci	struct list_head	waiting_calls;	/* Calls waiting for channels */
3958c2ecf20Sopenharmony_ci	unsigned long		avail_chans;	/* Mask of available channels */
3968c2ecf20Sopenharmony_ci	struct rxrpc_connection	*conns[4];	/* The connections in the bundle (max 4) */
3978c2ecf20Sopenharmony_ci};
3988c2ecf20Sopenharmony_ci
3998c2ecf20Sopenharmony_ci/*
4008c2ecf20Sopenharmony_ci * RxRPC connection definition
4018c2ecf20Sopenharmony_ci * - matched by { local, peer, epoch, conn_id, direction }
4028c2ecf20Sopenharmony_ci * - each connection can only handle four simultaneous calls
4038c2ecf20Sopenharmony_ci */
4048c2ecf20Sopenharmony_cistruct rxrpc_connection {
4058c2ecf20Sopenharmony_ci	struct rxrpc_conn_proto	proto;
4068c2ecf20Sopenharmony_ci	struct rxrpc_conn_parameters params;
4078c2ecf20Sopenharmony_ci
4088c2ecf20Sopenharmony_ci	refcount_t		ref;
4098c2ecf20Sopenharmony_ci	struct rcu_head		rcu;
4108c2ecf20Sopenharmony_ci	struct list_head	cache_link;
4118c2ecf20Sopenharmony_ci
4128c2ecf20Sopenharmony_ci	unsigned char		act_chans;	/* Mask of active channels */
4138c2ecf20Sopenharmony_ci	struct rxrpc_channel {
4148c2ecf20Sopenharmony_ci		unsigned long		final_ack_at;	/* Time at which to issue final ACK */
4158c2ecf20Sopenharmony_ci		struct rxrpc_call __rcu	*call;		/* Active call */
4168c2ecf20Sopenharmony_ci		unsigned int		call_debug_id;	/* call->debug_id */
4178c2ecf20Sopenharmony_ci		u32			call_id;	/* ID of current call */
4188c2ecf20Sopenharmony_ci		u32			call_counter;	/* Call ID counter */
4198c2ecf20Sopenharmony_ci		u32			last_call;	/* ID of last call */
4208c2ecf20Sopenharmony_ci		u8			last_type;	/* Type of last packet */
4218c2ecf20Sopenharmony_ci		union {
4228c2ecf20Sopenharmony_ci			u32		last_seq;
4238c2ecf20Sopenharmony_ci			u32		last_abort;
4248c2ecf20Sopenharmony_ci		};
4258c2ecf20Sopenharmony_ci	} channels[RXRPC_MAXCALLS];
4268c2ecf20Sopenharmony_ci
4278c2ecf20Sopenharmony_ci	struct timer_list	timer;		/* Conn event timer */
4288c2ecf20Sopenharmony_ci	struct work_struct	processor;	/* connection event processor */
4298c2ecf20Sopenharmony_ci	struct rxrpc_bundle	*bundle;	/* Client connection bundle */
4308c2ecf20Sopenharmony_ci	struct rb_node		service_node;	/* Node in peer->service_conns */
4318c2ecf20Sopenharmony_ci	struct list_head	proc_link;	/* link in procfs list */
4328c2ecf20Sopenharmony_ci	struct list_head	link;		/* link in master connection list */
4338c2ecf20Sopenharmony_ci	struct sk_buff_head	rx_queue;	/* received conn-level packets */
4348c2ecf20Sopenharmony_ci	const struct rxrpc_security *security;	/* applied security module */
4358c2ecf20Sopenharmony_ci	struct key		*server_key;	/* security for this service */
4368c2ecf20Sopenharmony_ci	struct crypto_sync_skcipher *cipher;	/* encryption handle */
4378c2ecf20Sopenharmony_ci	struct rxrpc_crypt	csum_iv;	/* packet checksum base */
4388c2ecf20Sopenharmony_ci	unsigned long		flags;
4398c2ecf20Sopenharmony_ci	unsigned long		events;
4408c2ecf20Sopenharmony_ci	unsigned long		idle_timestamp;	/* Time at which last became idle */
4418c2ecf20Sopenharmony_ci	spinlock_t		state_lock;	/* state-change lock */
4428c2ecf20Sopenharmony_ci	enum rxrpc_conn_proto_state state;	/* current state of connection */
4438c2ecf20Sopenharmony_ci	u32			abort_code;	/* Abort code of connection abort */
4448c2ecf20Sopenharmony_ci	int			debug_id;	/* debug ID for printks */
4458c2ecf20Sopenharmony_ci	atomic_t		serial;		/* packet serial number counter */
4468c2ecf20Sopenharmony_ci	unsigned int		hi_serial;	/* highest serial number received */
4478c2ecf20Sopenharmony_ci	u32			security_nonce;	/* response re-use preventer */
4488c2ecf20Sopenharmony_ci	u32			service_id;	/* Service ID, possibly upgraded */
4498c2ecf20Sopenharmony_ci	u8			size_align;	/* data size alignment (for security) */
4508c2ecf20Sopenharmony_ci	u8			security_size;	/* security header size */
4518c2ecf20Sopenharmony_ci	u8			security_ix;	/* security type */
4528c2ecf20Sopenharmony_ci	u8			out_clientflag;	/* RXRPC_CLIENT_INITIATED if we are client */
4538c2ecf20Sopenharmony_ci	u8			bundle_shift;	/* Index into bundle->avail_chans */
4548c2ecf20Sopenharmony_ci	short			error;		/* Local error code */
4558c2ecf20Sopenharmony_ci};
4568c2ecf20Sopenharmony_ci
4578c2ecf20Sopenharmony_cistatic inline bool rxrpc_to_server(const struct rxrpc_skb_priv *sp)
4588c2ecf20Sopenharmony_ci{
4598c2ecf20Sopenharmony_ci	return sp->hdr.flags & RXRPC_CLIENT_INITIATED;
4608c2ecf20Sopenharmony_ci}
4618c2ecf20Sopenharmony_ci
4628c2ecf20Sopenharmony_cistatic inline bool rxrpc_to_client(const struct rxrpc_skb_priv *sp)
4638c2ecf20Sopenharmony_ci{
4648c2ecf20Sopenharmony_ci	return !rxrpc_to_server(sp);
4658c2ecf20Sopenharmony_ci}
4668c2ecf20Sopenharmony_ci
4678c2ecf20Sopenharmony_ci/*
4688c2ecf20Sopenharmony_ci * Flags in call->flags.
4698c2ecf20Sopenharmony_ci */
4708c2ecf20Sopenharmony_cienum rxrpc_call_flag {
4718c2ecf20Sopenharmony_ci	RXRPC_CALL_RELEASED,		/* call has been released - no more message to userspace */
4728c2ecf20Sopenharmony_ci	RXRPC_CALL_HAS_USERID,		/* has a user ID attached */
4738c2ecf20Sopenharmony_ci	RXRPC_CALL_IS_SERVICE,		/* Call is service call */
4748c2ecf20Sopenharmony_ci	RXRPC_CALL_EXPOSED,		/* The call was exposed to the world */
4758c2ecf20Sopenharmony_ci	RXRPC_CALL_RX_LAST,		/* Received the last packet (at rxtx_top) */
4768c2ecf20Sopenharmony_ci	RXRPC_CALL_TX_LAST,		/* Last packet in Tx buffer (at rxtx_top) */
4778c2ecf20Sopenharmony_ci	RXRPC_CALL_SEND_PING,		/* A ping will need to be sent */
4788c2ecf20Sopenharmony_ci	RXRPC_CALL_RETRANS_TIMEOUT,	/* Retransmission due to timeout occurred */
4798c2ecf20Sopenharmony_ci	RXRPC_CALL_BEGAN_RX_TIMER,	/* We began the expect_rx_by timer */
4808c2ecf20Sopenharmony_ci	RXRPC_CALL_RX_HEARD,		/* The peer responded at least once to this call */
4818c2ecf20Sopenharmony_ci	RXRPC_CALL_RX_UNDERRUN,		/* Got data underrun */
4828c2ecf20Sopenharmony_ci	RXRPC_CALL_DISCONNECTED,	/* The call has been disconnected */
4838c2ecf20Sopenharmony_ci	RXRPC_CALL_KERNEL,		/* The call was made by the kernel */
4848c2ecf20Sopenharmony_ci	RXRPC_CALL_UPGRADE,		/* Service upgrade was requested for the call */
4858c2ecf20Sopenharmony_ci};
4868c2ecf20Sopenharmony_ci
4878c2ecf20Sopenharmony_ci/*
4888c2ecf20Sopenharmony_ci * Events that can be raised on a call.
4898c2ecf20Sopenharmony_ci */
4908c2ecf20Sopenharmony_cienum rxrpc_call_event {
4918c2ecf20Sopenharmony_ci	RXRPC_CALL_EV_ACK,		/* need to generate ACK */
4928c2ecf20Sopenharmony_ci	RXRPC_CALL_EV_ABORT,		/* need to generate abort */
4938c2ecf20Sopenharmony_ci	RXRPC_CALL_EV_RESEND,		/* Tx resend required */
4948c2ecf20Sopenharmony_ci	RXRPC_CALL_EV_PING,		/* Ping send required */
4958c2ecf20Sopenharmony_ci	RXRPC_CALL_EV_EXPIRED,		/* Expiry occurred */
4968c2ecf20Sopenharmony_ci	RXRPC_CALL_EV_ACK_LOST,		/* ACK may be lost, send ping */
4978c2ecf20Sopenharmony_ci};
4988c2ecf20Sopenharmony_ci
4998c2ecf20Sopenharmony_ci/*
5008c2ecf20Sopenharmony_ci * The states that a call can be in.
5018c2ecf20Sopenharmony_ci */
5028c2ecf20Sopenharmony_cienum rxrpc_call_state {
5038c2ecf20Sopenharmony_ci	RXRPC_CALL_UNINITIALISED,
5048c2ecf20Sopenharmony_ci	RXRPC_CALL_CLIENT_AWAIT_CONN,	/* - client waiting for connection to become available */
5058c2ecf20Sopenharmony_ci	RXRPC_CALL_CLIENT_SEND_REQUEST,	/* - client sending request phase */
5068c2ecf20Sopenharmony_ci	RXRPC_CALL_CLIENT_AWAIT_REPLY,	/* - client awaiting reply */
5078c2ecf20Sopenharmony_ci	RXRPC_CALL_CLIENT_RECV_REPLY,	/* - client receiving reply phase */
5088c2ecf20Sopenharmony_ci	RXRPC_CALL_SERVER_PREALLOC,	/* - service preallocation */
5098c2ecf20Sopenharmony_ci	RXRPC_CALL_SERVER_SECURING,	/* - server securing request connection */
5108c2ecf20Sopenharmony_ci	RXRPC_CALL_SERVER_RECV_REQUEST,	/* - server receiving request */
5118c2ecf20Sopenharmony_ci	RXRPC_CALL_SERVER_ACK_REQUEST,	/* - server pending ACK of request */
5128c2ecf20Sopenharmony_ci	RXRPC_CALL_SERVER_SEND_REPLY,	/* - server sending reply */
5138c2ecf20Sopenharmony_ci	RXRPC_CALL_SERVER_AWAIT_ACK,	/* - server awaiting final ACK */
5148c2ecf20Sopenharmony_ci	RXRPC_CALL_COMPLETE,		/* - call complete */
5158c2ecf20Sopenharmony_ci	NR__RXRPC_CALL_STATES
5168c2ecf20Sopenharmony_ci};
5178c2ecf20Sopenharmony_ci
5188c2ecf20Sopenharmony_ci/*
5198c2ecf20Sopenharmony_ci * Call completion condition (state == RXRPC_CALL_COMPLETE).
5208c2ecf20Sopenharmony_ci */
5218c2ecf20Sopenharmony_cienum rxrpc_call_completion {
5228c2ecf20Sopenharmony_ci	RXRPC_CALL_SUCCEEDED,		/* - Normal termination */
5238c2ecf20Sopenharmony_ci	RXRPC_CALL_REMOTELY_ABORTED,	/* - call aborted by peer */
5248c2ecf20Sopenharmony_ci	RXRPC_CALL_LOCALLY_ABORTED,	/* - call aborted locally on error or close */
5258c2ecf20Sopenharmony_ci	RXRPC_CALL_LOCAL_ERROR,		/* - call failed due to local error */
5268c2ecf20Sopenharmony_ci	RXRPC_CALL_NETWORK_ERROR,	/* - call terminated by network error */
5278c2ecf20Sopenharmony_ci	NR__RXRPC_CALL_COMPLETIONS
5288c2ecf20Sopenharmony_ci};
5298c2ecf20Sopenharmony_ci
5308c2ecf20Sopenharmony_ci/*
5318c2ecf20Sopenharmony_ci * Call Tx congestion management modes.
5328c2ecf20Sopenharmony_ci */
5338c2ecf20Sopenharmony_cienum rxrpc_congest_mode {
5348c2ecf20Sopenharmony_ci	RXRPC_CALL_SLOW_START,
5358c2ecf20Sopenharmony_ci	RXRPC_CALL_CONGEST_AVOIDANCE,
5368c2ecf20Sopenharmony_ci	RXRPC_CALL_PACKET_LOSS,
5378c2ecf20Sopenharmony_ci	RXRPC_CALL_FAST_RETRANSMIT,
5388c2ecf20Sopenharmony_ci	NR__RXRPC_CONGEST_MODES
5398c2ecf20Sopenharmony_ci};
5408c2ecf20Sopenharmony_ci
5418c2ecf20Sopenharmony_ci/*
5428c2ecf20Sopenharmony_ci * RxRPC call definition
5438c2ecf20Sopenharmony_ci * - matched by { connection, call_id }
5448c2ecf20Sopenharmony_ci */
5458c2ecf20Sopenharmony_cistruct rxrpc_call {
5468c2ecf20Sopenharmony_ci	struct rcu_head		rcu;
5478c2ecf20Sopenharmony_ci	struct rxrpc_connection	*conn;		/* connection carrying call */
5488c2ecf20Sopenharmony_ci	struct rxrpc_peer	*peer;		/* Peer record for remote address */
5498c2ecf20Sopenharmony_ci	struct rxrpc_sock __rcu	*socket;	/* socket responsible */
5508c2ecf20Sopenharmony_ci	struct rxrpc_net	*rxnet;		/* Network namespace to which call belongs */
5518c2ecf20Sopenharmony_ci	const struct rxrpc_security *security;	/* applied security module */
5528c2ecf20Sopenharmony_ci	struct mutex		user_mutex;	/* User access mutex */
5538c2ecf20Sopenharmony_ci	unsigned long		ack_at;		/* When deferred ACK needs to happen */
5548c2ecf20Sopenharmony_ci	unsigned long		ack_lost_at;	/* When ACK is figured as lost */
5558c2ecf20Sopenharmony_ci	unsigned long		resend_at;	/* When next resend needs to happen */
5568c2ecf20Sopenharmony_ci	unsigned long		ping_at;	/* When next to send a ping */
5578c2ecf20Sopenharmony_ci	unsigned long		keepalive_at;	/* When next to send a keepalive ping */
5588c2ecf20Sopenharmony_ci	unsigned long		expect_rx_by;	/* When we expect to get a packet by */
5598c2ecf20Sopenharmony_ci	unsigned long		expect_req_by;	/* When we expect to get a request DATA packet by */
5608c2ecf20Sopenharmony_ci	unsigned long		expect_term_by;	/* When we expect call termination by */
5618c2ecf20Sopenharmony_ci	u32			next_rx_timo;	/* Timeout for next Rx packet (jif) */
5628c2ecf20Sopenharmony_ci	u32			next_req_timo;	/* Timeout for next Rx request packet (jif) */
5638c2ecf20Sopenharmony_ci	struct skcipher_request	*cipher_req;	/* Packet cipher request buffer */
5648c2ecf20Sopenharmony_ci	struct timer_list	timer;		/* Combined event timer */
5658c2ecf20Sopenharmony_ci	struct work_struct	processor;	/* Event processor */
5668c2ecf20Sopenharmony_ci	rxrpc_notify_rx_t	notify_rx;	/* kernel service Rx notification function */
5678c2ecf20Sopenharmony_ci	struct list_head	link;		/* link in master call list */
5688c2ecf20Sopenharmony_ci	struct list_head	chan_wait_link;	/* Link in conn->bundle->waiting_calls */
5698c2ecf20Sopenharmony_ci	struct hlist_node	error_link;	/* link in error distribution list */
5708c2ecf20Sopenharmony_ci	struct list_head	accept_link;	/* Link in rx->acceptq */
5718c2ecf20Sopenharmony_ci	struct list_head	recvmsg_link;	/* Link in rx->recvmsg_q */
5728c2ecf20Sopenharmony_ci	struct list_head	sock_link;	/* Link in rx->sock_calls */
5738c2ecf20Sopenharmony_ci	struct rb_node		sock_node;	/* Node in rx->calls */
5748c2ecf20Sopenharmony_ci	struct sk_buff		*tx_pending;	/* Tx socket buffer being filled */
5758c2ecf20Sopenharmony_ci	wait_queue_head_t	waitq;		/* Wait queue for channel or Tx */
5768c2ecf20Sopenharmony_ci	s64			tx_total_len;	/* Total length left to be transmitted (or -1) */
5778c2ecf20Sopenharmony_ci	__be32			crypto_buf[2];	/* Temporary packet crypto buffer */
5788c2ecf20Sopenharmony_ci	unsigned long		user_call_ID;	/* user-defined call ID */
5798c2ecf20Sopenharmony_ci	unsigned long		flags;
5808c2ecf20Sopenharmony_ci	unsigned long		events;
5818c2ecf20Sopenharmony_ci	spinlock_t		lock;
5828c2ecf20Sopenharmony_ci	spinlock_t		notify_lock;	/* Kernel notification lock */
5838c2ecf20Sopenharmony_ci	rwlock_t		state_lock;	/* lock for state transition */
5848c2ecf20Sopenharmony_ci	u32			abort_code;	/* Local/remote abort code */
5858c2ecf20Sopenharmony_ci	int			error;		/* Local error incurred */
5868c2ecf20Sopenharmony_ci	enum rxrpc_call_state	state;		/* current state of call */
5878c2ecf20Sopenharmony_ci	enum rxrpc_call_completion completion;	/* Call completion condition */
5888c2ecf20Sopenharmony_ci	refcount_t		ref;
5898c2ecf20Sopenharmony_ci	u16			service_id;	/* service ID */
5908c2ecf20Sopenharmony_ci	u8			security_ix;	/* Security type */
5918c2ecf20Sopenharmony_ci	enum rxrpc_interruptibility interruptibility; /* At what point call may be interrupted */
5928c2ecf20Sopenharmony_ci	u32			call_id;	/* call ID on connection  */
5938c2ecf20Sopenharmony_ci	u32			cid;		/* connection ID plus channel index */
5948c2ecf20Sopenharmony_ci	int			debug_id;	/* debug ID for printks */
5958c2ecf20Sopenharmony_ci	unsigned short		rx_pkt_offset;	/* Current recvmsg packet offset */
5968c2ecf20Sopenharmony_ci	unsigned short		rx_pkt_len;	/* Current recvmsg packet len */
5978c2ecf20Sopenharmony_ci	bool			rx_pkt_last;	/* Current recvmsg packet is last */
5988c2ecf20Sopenharmony_ci
5998c2ecf20Sopenharmony_ci	/* Rx/Tx circular buffer, depending on phase.
6008c2ecf20Sopenharmony_ci	 *
6018c2ecf20Sopenharmony_ci	 * In the Rx phase, packets are annotated with 0 or the number of the
6028c2ecf20Sopenharmony_ci	 * segment of a jumbo packet each buffer refers to.  There can be up to
6038c2ecf20Sopenharmony_ci	 * 47 segments in a maximum-size UDP packet.
6048c2ecf20Sopenharmony_ci	 *
6058c2ecf20Sopenharmony_ci	 * In the Tx phase, packets are annotated with which buffers have been
6068c2ecf20Sopenharmony_ci	 * acked.
6078c2ecf20Sopenharmony_ci	 */
6088c2ecf20Sopenharmony_ci#define RXRPC_RXTX_BUFF_SIZE	64
6098c2ecf20Sopenharmony_ci#define RXRPC_RXTX_BUFF_MASK	(RXRPC_RXTX_BUFF_SIZE - 1)
6108c2ecf20Sopenharmony_ci#define RXRPC_INIT_RX_WINDOW_SIZE 63
6118c2ecf20Sopenharmony_ci	struct sk_buff		**rxtx_buffer;
6128c2ecf20Sopenharmony_ci	u8			*rxtx_annotations;
6138c2ecf20Sopenharmony_ci#define RXRPC_TX_ANNO_ACK	0
6148c2ecf20Sopenharmony_ci#define RXRPC_TX_ANNO_UNACK	1
6158c2ecf20Sopenharmony_ci#define RXRPC_TX_ANNO_NAK	2
6168c2ecf20Sopenharmony_ci#define RXRPC_TX_ANNO_RETRANS	3
6178c2ecf20Sopenharmony_ci#define RXRPC_TX_ANNO_MASK	0x03
6188c2ecf20Sopenharmony_ci#define RXRPC_TX_ANNO_LAST	0x04
6198c2ecf20Sopenharmony_ci#define RXRPC_TX_ANNO_RESENT	0x08
6208c2ecf20Sopenharmony_ci
6218c2ecf20Sopenharmony_ci#define RXRPC_RX_ANNO_SUBPACKET	0x3f		/* Subpacket number in jumbogram */
6228c2ecf20Sopenharmony_ci#define RXRPC_RX_ANNO_VERIFIED	0x80		/* Set if verified and decrypted */
6238c2ecf20Sopenharmony_ci	rxrpc_seq_t		tx_hard_ack;	/* Dead slot in buffer; the first transmitted but
6248c2ecf20Sopenharmony_ci						 * not hard-ACK'd packet follows this.
6258c2ecf20Sopenharmony_ci						 */
6268c2ecf20Sopenharmony_ci	rxrpc_seq_t		tx_top;		/* Highest Tx slot allocated. */
6278c2ecf20Sopenharmony_ci	u16			tx_backoff;	/* Delay to insert due to Tx failure */
6288c2ecf20Sopenharmony_ci
6298c2ecf20Sopenharmony_ci	/* TCP-style slow-start congestion control [RFC5681].  Since the SMSS
6308c2ecf20Sopenharmony_ci	 * is fixed, we keep these numbers in terms of segments (ie. DATA
6318c2ecf20Sopenharmony_ci	 * packets) rather than bytes.
6328c2ecf20Sopenharmony_ci	 */
6338c2ecf20Sopenharmony_ci#define RXRPC_TX_SMSS		RXRPC_JUMBO_DATALEN
6348c2ecf20Sopenharmony_ci	u8			cong_cwnd;	/* Congestion window size */
6358c2ecf20Sopenharmony_ci	u8			cong_extra;	/* Extra to send for congestion management */
6368c2ecf20Sopenharmony_ci	u8			cong_ssthresh;	/* Slow-start threshold */
6378c2ecf20Sopenharmony_ci	enum rxrpc_congest_mode	cong_mode:8;	/* Congestion management mode */
6388c2ecf20Sopenharmony_ci	u8			cong_dup_acks;	/* Count of ACKs showing missing packets */
6398c2ecf20Sopenharmony_ci	u8			cong_cumul_acks; /* Cumulative ACK count */
6408c2ecf20Sopenharmony_ci	ktime_t			cong_tstamp;	/* Last time cwnd was changed */
6418c2ecf20Sopenharmony_ci
6428c2ecf20Sopenharmony_ci	rxrpc_seq_t		rx_hard_ack;	/* Dead slot in buffer; the first received but not
6438c2ecf20Sopenharmony_ci						 * consumed packet follows this.
6448c2ecf20Sopenharmony_ci						 */
6458c2ecf20Sopenharmony_ci	rxrpc_seq_t		rx_top;		/* Highest Rx slot allocated. */
6468c2ecf20Sopenharmony_ci	rxrpc_seq_t		rx_expect_next;	/* Expected next packet sequence number */
6478c2ecf20Sopenharmony_ci	rxrpc_serial_t		rx_serial;	/* Highest serial received for this call */
6488c2ecf20Sopenharmony_ci	u8			rx_winsize;	/* Size of Rx window */
6498c2ecf20Sopenharmony_ci	u8			tx_winsize;	/* Maximum size of Tx window */
6508c2ecf20Sopenharmony_ci	bool			tx_phase;	/* T if transmission phase, F if receive phase */
6518c2ecf20Sopenharmony_ci	u8			nr_jumbo_bad;	/* Number of jumbo dups/exceeds-windows */
6528c2ecf20Sopenharmony_ci
6538c2ecf20Sopenharmony_ci	spinlock_t		input_lock;	/* Lock for packet input to this call */
6548c2ecf20Sopenharmony_ci
6558c2ecf20Sopenharmony_ci	/* Receive-phase ACK management (ACKs we send). */
6568c2ecf20Sopenharmony_ci	u8			ackr_reason;	/* reason to ACK */
6578c2ecf20Sopenharmony_ci	rxrpc_serial_t		ackr_serial;	/* serial of packet being ACK'd */
6588c2ecf20Sopenharmony_ci	rxrpc_seq_t		ackr_highest_seq; /* Higest sequence number received */
6598c2ecf20Sopenharmony_ci	atomic_t		ackr_nr_unacked; /* Number of unacked packets */
6608c2ecf20Sopenharmony_ci	atomic_t		ackr_nr_consumed; /* Number of packets needing hard ACK */
6618c2ecf20Sopenharmony_ci
6628c2ecf20Sopenharmony_ci	/* RTT management */
6638c2ecf20Sopenharmony_ci	rxrpc_serial_t		rtt_serial[4];	/* Serial number of DATA or PING sent */
6648c2ecf20Sopenharmony_ci	ktime_t			rtt_sent_at[4];	/* Time packet sent */
6658c2ecf20Sopenharmony_ci	unsigned long		rtt_avail;	/* Mask of available slots in bits 0-3,
6668c2ecf20Sopenharmony_ci						 * Mask of pending samples in 8-11 */
6678c2ecf20Sopenharmony_ci#define RXRPC_CALL_RTT_AVAIL_MASK	0xf
6688c2ecf20Sopenharmony_ci#define RXRPC_CALL_RTT_PEND_SHIFT	8
6698c2ecf20Sopenharmony_ci
6708c2ecf20Sopenharmony_ci	/* Transmission-phase ACK management (ACKs we've received). */
6718c2ecf20Sopenharmony_ci	ktime_t			acks_latest_ts;	/* Timestamp of latest ACK received */
6728c2ecf20Sopenharmony_ci	rxrpc_seq_t		acks_first_seq;	/* first sequence number received */
6738c2ecf20Sopenharmony_ci	rxrpc_seq_t		acks_prev_seq;	/* Highest previousPacket received */
6748c2ecf20Sopenharmony_ci	rxrpc_seq_t		acks_lowest_nak; /* Lowest NACK in the buffer (or ==tx_hard_ack) */
6758c2ecf20Sopenharmony_ci	rxrpc_seq_t		acks_lost_top;	/* tx_top at the time lost-ack ping sent */
6768c2ecf20Sopenharmony_ci	rxrpc_serial_t		acks_lost_ping;	/* Serial number of probe ACK */
6778c2ecf20Sopenharmony_ci};
6788c2ecf20Sopenharmony_ci
6798c2ecf20Sopenharmony_ci/*
6808c2ecf20Sopenharmony_ci * Summary of a new ACK and the changes it made to the Tx buffer packet states.
6818c2ecf20Sopenharmony_ci */
6828c2ecf20Sopenharmony_cistruct rxrpc_ack_summary {
6838c2ecf20Sopenharmony_ci	u8			ack_reason;
6848c2ecf20Sopenharmony_ci	u8			nr_acks;		/* Number of ACKs in packet */
6858c2ecf20Sopenharmony_ci	u8			nr_nacks;		/* Number of NACKs in packet */
6868c2ecf20Sopenharmony_ci	u8			nr_new_acks;		/* Number of new ACKs in packet */
6878c2ecf20Sopenharmony_ci	u8			nr_new_nacks;		/* Number of new NACKs in packet */
6888c2ecf20Sopenharmony_ci	u8			nr_rot_new_acks;	/* Number of rotated new ACKs */
6898c2ecf20Sopenharmony_ci	bool			new_low_nack;		/* T if new low NACK found */
6908c2ecf20Sopenharmony_ci	bool			retrans_timeo;		/* T if reTx due to timeout happened */
6918c2ecf20Sopenharmony_ci	u8			flight_size;		/* Number of unreceived transmissions */
6928c2ecf20Sopenharmony_ci	/* Place to stash values for tracing */
6938c2ecf20Sopenharmony_ci	enum rxrpc_congest_mode	mode:8;
6948c2ecf20Sopenharmony_ci	u8			cwnd;
6958c2ecf20Sopenharmony_ci	u8			ssthresh;
6968c2ecf20Sopenharmony_ci	u8			dup_acks;
6978c2ecf20Sopenharmony_ci	u8			cumulative_acks;
6988c2ecf20Sopenharmony_ci};
6998c2ecf20Sopenharmony_ci
7008c2ecf20Sopenharmony_ci/*
7018c2ecf20Sopenharmony_ci * sendmsg() cmsg-specified parameters.
7028c2ecf20Sopenharmony_ci */
7038c2ecf20Sopenharmony_cienum rxrpc_command {
7048c2ecf20Sopenharmony_ci	RXRPC_CMD_SEND_DATA,		/* send data message */
7058c2ecf20Sopenharmony_ci	RXRPC_CMD_SEND_ABORT,		/* request abort generation */
7068c2ecf20Sopenharmony_ci	RXRPC_CMD_REJECT_BUSY,		/* [server] reject a call as busy */
7078c2ecf20Sopenharmony_ci	RXRPC_CMD_CHARGE_ACCEPT,	/* [server] charge accept preallocation */
7088c2ecf20Sopenharmony_ci};
7098c2ecf20Sopenharmony_ci
7108c2ecf20Sopenharmony_cistruct rxrpc_call_params {
7118c2ecf20Sopenharmony_ci	s64			tx_total_len;	/* Total Tx data length (if send data) */
7128c2ecf20Sopenharmony_ci	unsigned long		user_call_ID;	/* User's call ID */
7138c2ecf20Sopenharmony_ci	struct {
7148c2ecf20Sopenharmony_ci		u32		hard;		/* Maximum lifetime (sec) */
7158c2ecf20Sopenharmony_ci		u32		idle;		/* Max time since last data packet (msec) */
7168c2ecf20Sopenharmony_ci		u32		normal;		/* Max time since last call packet (msec) */
7178c2ecf20Sopenharmony_ci	} timeouts;
7188c2ecf20Sopenharmony_ci	u8			nr_timeouts;	/* Number of timeouts specified */
7198c2ecf20Sopenharmony_ci	bool			kernel;		/* T if kernel is making the call */
7208c2ecf20Sopenharmony_ci	enum rxrpc_interruptibility interruptibility; /* How is interruptible is the call? */
7218c2ecf20Sopenharmony_ci};
7228c2ecf20Sopenharmony_ci
7238c2ecf20Sopenharmony_cistruct rxrpc_send_params {
7248c2ecf20Sopenharmony_ci	struct rxrpc_call_params call;
7258c2ecf20Sopenharmony_ci	u32			abort_code;	/* Abort code to Tx (if abort) */
7268c2ecf20Sopenharmony_ci	enum rxrpc_command	command : 8;	/* The command to implement */
7278c2ecf20Sopenharmony_ci	bool			exclusive;	/* Shared or exclusive call */
7288c2ecf20Sopenharmony_ci	bool			upgrade;	/* If the connection is upgradeable */
7298c2ecf20Sopenharmony_ci};
7308c2ecf20Sopenharmony_ci
7318c2ecf20Sopenharmony_ci#include <trace/events/rxrpc.h>
7328c2ecf20Sopenharmony_ci
7338c2ecf20Sopenharmony_ci/*
7348c2ecf20Sopenharmony_ci * af_rxrpc.c
7358c2ecf20Sopenharmony_ci */
7368c2ecf20Sopenharmony_ciextern atomic_t rxrpc_n_tx_skbs, rxrpc_n_rx_skbs;
7378c2ecf20Sopenharmony_ciextern struct workqueue_struct *rxrpc_workqueue;
7388c2ecf20Sopenharmony_ci
7398c2ecf20Sopenharmony_ci/*
7408c2ecf20Sopenharmony_ci * call_accept.c
7418c2ecf20Sopenharmony_ci */
7428c2ecf20Sopenharmony_ciint rxrpc_service_prealloc(struct rxrpc_sock *, gfp_t);
7438c2ecf20Sopenharmony_civoid rxrpc_discard_prealloc(struct rxrpc_sock *);
7448c2ecf20Sopenharmony_cistruct rxrpc_call *rxrpc_new_incoming_call(struct rxrpc_local *,
7458c2ecf20Sopenharmony_ci					   struct rxrpc_sock *,
7468c2ecf20Sopenharmony_ci					   struct sk_buff *);
7478c2ecf20Sopenharmony_civoid rxrpc_accept_incoming_calls(struct rxrpc_local *);
7488c2ecf20Sopenharmony_ciint rxrpc_user_charge_accept(struct rxrpc_sock *, unsigned long);
7498c2ecf20Sopenharmony_ci
7508c2ecf20Sopenharmony_ci/*
7518c2ecf20Sopenharmony_ci * call_event.c
7528c2ecf20Sopenharmony_ci */
7538c2ecf20Sopenharmony_civoid rxrpc_propose_ACK(struct rxrpc_call *, u8, u32, bool, bool,
7548c2ecf20Sopenharmony_ci		       enum rxrpc_propose_ack_trace);
7558c2ecf20Sopenharmony_civoid rxrpc_process_call(struct work_struct *);
7568c2ecf20Sopenharmony_ci
7578c2ecf20Sopenharmony_civoid rxrpc_reduce_call_timer(struct rxrpc_call *call,
7588c2ecf20Sopenharmony_ci			     unsigned long expire_at,
7598c2ecf20Sopenharmony_ci			     unsigned long now,
7608c2ecf20Sopenharmony_ci			     enum rxrpc_timer_trace why);
7618c2ecf20Sopenharmony_ci
7628c2ecf20Sopenharmony_civoid rxrpc_delete_call_timer(struct rxrpc_call *call);
7638c2ecf20Sopenharmony_ci
7648c2ecf20Sopenharmony_ci/*
7658c2ecf20Sopenharmony_ci * call_object.c
7668c2ecf20Sopenharmony_ci */
7678c2ecf20Sopenharmony_ciextern const char *const rxrpc_call_states[];
7688c2ecf20Sopenharmony_ciextern const char *const rxrpc_call_completions[];
7698c2ecf20Sopenharmony_ciextern unsigned int rxrpc_max_call_lifetime;
7708c2ecf20Sopenharmony_ciextern struct kmem_cache *rxrpc_call_jar;
7718c2ecf20Sopenharmony_ci
7728c2ecf20Sopenharmony_cistruct rxrpc_call *rxrpc_find_call_by_user_ID(struct rxrpc_sock *, unsigned long);
7738c2ecf20Sopenharmony_cistruct rxrpc_call *rxrpc_alloc_call(struct rxrpc_sock *, gfp_t, unsigned int);
7748c2ecf20Sopenharmony_cistruct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *,
7758c2ecf20Sopenharmony_ci					 struct rxrpc_conn_parameters *,
7768c2ecf20Sopenharmony_ci					 struct sockaddr_rxrpc *,
7778c2ecf20Sopenharmony_ci					 struct rxrpc_call_params *, gfp_t,
7788c2ecf20Sopenharmony_ci					 unsigned int);
7798c2ecf20Sopenharmony_civoid rxrpc_incoming_call(struct rxrpc_sock *, struct rxrpc_call *,
7808c2ecf20Sopenharmony_ci			 struct sk_buff *);
7818c2ecf20Sopenharmony_civoid rxrpc_release_call(struct rxrpc_sock *, struct rxrpc_call *);
7828c2ecf20Sopenharmony_civoid rxrpc_release_calls_on_socket(struct rxrpc_sock *);
7838c2ecf20Sopenharmony_cibool __rxrpc_queue_call(struct rxrpc_call *);
7848c2ecf20Sopenharmony_cibool rxrpc_queue_call(struct rxrpc_call *);
7858c2ecf20Sopenharmony_civoid rxrpc_see_call(struct rxrpc_call *);
7868c2ecf20Sopenharmony_cibool rxrpc_try_get_call(struct rxrpc_call *call, enum rxrpc_call_trace op);
7878c2ecf20Sopenharmony_civoid rxrpc_get_call(struct rxrpc_call *, enum rxrpc_call_trace);
7888c2ecf20Sopenharmony_civoid rxrpc_put_call(struct rxrpc_call *, enum rxrpc_call_trace);
7898c2ecf20Sopenharmony_civoid rxrpc_cleanup_call(struct rxrpc_call *);
7908c2ecf20Sopenharmony_civoid rxrpc_destroy_all_calls(struct rxrpc_net *);
7918c2ecf20Sopenharmony_ci
7928c2ecf20Sopenharmony_cistatic inline bool rxrpc_is_service_call(const struct rxrpc_call *call)
7938c2ecf20Sopenharmony_ci{
7948c2ecf20Sopenharmony_ci	return test_bit(RXRPC_CALL_IS_SERVICE, &call->flags);
7958c2ecf20Sopenharmony_ci}
7968c2ecf20Sopenharmony_ci
7978c2ecf20Sopenharmony_cistatic inline bool rxrpc_is_client_call(const struct rxrpc_call *call)
7988c2ecf20Sopenharmony_ci{
7998c2ecf20Sopenharmony_ci	return !rxrpc_is_service_call(call);
8008c2ecf20Sopenharmony_ci}
8018c2ecf20Sopenharmony_ci
8028c2ecf20Sopenharmony_ci/*
8038c2ecf20Sopenharmony_ci * conn_client.c
8048c2ecf20Sopenharmony_ci */
8058c2ecf20Sopenharmony_ciextern unsigned int rxrpc_reap_client_connections;
8068c2ecf20Sopenharmony_ciextern unsigned long rxrpc_conn_idle_client_expiry;
8078c2ecf20Sopenharmony_ciextern unsigned long rxrpc_conn_idle_client_fast_expiry;
8088c2ecf20Sopenharmony_ciextern struct idr rxrpc_client_conn_ids;
8098c2ecf20Sopenharmony_ci
8108c2ecf20Sopenharmony_civoid rxrpc_destroy_client_conn_ids(void);
8118c2ecf20Sopenharmony_cistruct rxrpc_bundle *rxrpc_get_bundle(struct rxrpc_bundle *);
8128c2ecf20Sopenharmony_civoid rxrpc_put_bundle(struct rxrpc_bundle *);
8138c2ecf20Sopenharmony_ciint rxrpc_connect_call(struct rxrpc_sock *, struct rxrpc_call *,
8148c2ecf20Sopenharmony_ci		       struct rxrpc_conn_parameters *, struct sockaddr_rxrpc *,
8158c2ecf20Sopenharmony_ci		       gfp_t);
8168c2ecf20Sopenharmony_civoid rxrpc_expose_client_call(struct rxrpc_call *);
8178c2ecf20Sopenharmony_civoid rxrpc_disconnect_client_call(struct rxrpc_bundle *, struct rxrpc_call *);
8188c2ecf20Sopenharmony_civoid rxrpc_put_client_conn(struct rxrpc_connection *);
8198c2ecf20Sopenharmony_civoid rxrpc_discard_expired_client_conns(struct work_struct *);
8208c2ecf20Sopenharmony_civoid rxrpc_destroy_all_client_connections(struct rxrpc_net *);
8218c2ecf20Sopenharmony_civoid rxrpc_clean_up_local_conns(struct rxrpc_local *);
8228c2ecf20Sopenharmony_ci
8238c2ecf20Sopenharmony_ci/*
8248c2ecf20Sopenharmony_ci * conn_event.c
8258c2ecf20Sopenharmony_ci */
8268c2ecf20Sopenharmony_civoid rxrpc_process_connection(struct work_struct *);
8278c2ecf20Sopenharmony_civoid rxrpc_process_delayed_final_acks(struct rxrpc_connection *, bool);
8288c2ecf20Sopenharmony_ci
8298c2ecf20Sopenharmony_ci/*
8308c2ecf20Sopenharmony_ci * conn_object.c
8318c2ecf20Sopenharmony_ci */
8328c2ecf20Sopenharmony_ciextern unsigned int rxrpc_connection_expiry;
8338c2ecf20Sopenharmony_ciextern unsigned int rxrpc_closed_conn_expiry;
8348c2ecf20Sopenharmony_ci
8358c2ecf20Sopenharmony_cistruct rxrpc_connection *rxrpc_alloc_connection(gfp_t);
8368c2ecf20Sopenharmony_cistruct rxrpc_connection *rxrpc_find_connection_rcu(struct rxrpc_local *,
8378c2ecf20Sopenharmony_ci						   struct sk_buff *,
8388c2ecf20Sopenharmony_ci						   struct rxrpc_peer **);
8398c2ecf20Sopenharmony_civoid __rxrpc_disconnect_call(struct rxrpc_connection *, struct rxrpc_call *);
8408c2ecf20Sopenharmony_civoid rxrpc_disconnect_call(struct rxrpc_call *);
8418c2ecf20Sopenharmony_civoid rxrpc_kill_connection(struct rxrpc_connection *);
8428c2ecf20Sopenharmony_cibool rxrpc_queue_conn(struct rxrpc_connection *);
8438c2ecf20Sopenharmony_civoid rxrpc_see_connection(struct rxrpc_connection *);
8448c2ecf20Sopenharmony_cistruct rxrpc_connection *rxrpc_get_connection(struct rxrpc_connection *);
8458c2ecf20Sopenharmony_cistruct rxrpc_connection *rxrpc_get_connection_maybe(struct rxrpc_connection *);
8468c2ecf20Sopenharmony_civoid rxrpc_put_service_conn(struct rxrpc_connection *);
8478c2ecf20Sopenharmony_civoid rxrpc_service_connection_reaper(struct work_struct *);
8488c2ecf20Sopenharmony_civoid rxrpc_destroy_all_connections(struct rxrpc_net *);
8498c2ecf20Sopenharmony_ci
8508c2ecf20Sopenharmony_cistatic inline bool rxrpc_conn_is_client(const struct rxrpc_connection *conn)
8518c2ecf20Sopenharmony_ci{
8528c2ecf20Sopenharmony_ci	return conn->out_clientflag;
8538c2ecf20Sopenharmony_ci}
8548c2ecf20Sopenharmony_ci
8558c2ecf20Sopenharmony_cistatic inline bool rxrpc_conn_is_service(const struct rxrpc_connection *conn)
8568c2ecf20Sopenharmony_ci{
8578c2ecf20Sopenharmony_ci	return !rxrpc_conn_is_client(conn);
8588c2ecf20Sopenharmony_ci}
8598c2ecf20Sopenharmony_ci
8608c2ecf20Sopenharmony_cistatic inline void rxrpc_put_connection(struct rxrpc_connection *conn)
8618c2ecf20Sopenharmony_ci{
8628c2ecf20Sopenharmony_ci	if (!conn)
8638c2ecf20Sopenharmony_ci		return;
8648c2ecf20Sopenharmony_ci
8658c2ecf20Sopenharmony_ci	if (rxrpc_conn_is_client(conn))
8668c2ecf20Sopenharmony_ci		rxrpc_put_client_conn(conn);
8678c2ecf20Sopenharmony_ci	else
8688c2ecf20Sopenharmony_ci		rxrpc_put_service_conn(conn);
8698c2ecf20Sopenharmony_ci}
8708c2ecf20Sopenharmony_ci
8718c2ecf20Sopenharmony_cistatic inline void rxrpc_reduce_conn_timer(struct rxrpc_connection *conn,
8728c2ecf20Sopenharmony_ci					   unsigned long expire_at)
8738c2ecf20Sopenharmony_ci{
8748c2ecf20Sopenharmony_ci	timer_reduce(&conn->timer, expire_at);
8758c2ecf20Sopenharmony_ci}
8768c2ecf20Sopenharmony_ci
8778c2ecf20Sopenharmony_ci/*
8788c2ecf20Sopenharmony_ci * conn_service.c
8798c2ecf20Sopenharmony_ci */
8808c2ecf20Sopenharmony_cistruct rxrpc_connection *rxrpc_find_service_conn_rcu(struct rxrpc_peer *,
8818c2ecf20Sopenharmony_ci						     struct sk_buff *);
8828c2ecf20Sopenharmony_cistruct rxrpc_connection *rxrpc_prealloc_service_connection(struct rxrpc_net *, gfp_t);
8838c2ecf20Sopenharmony_civoid rxrpc_new_incoming_connection(struct rxrpc_sock *, struct rxrpc_connection *,
8848c2ecf20Sopenharmony_ci				   const struct rxrpc_security *, struct key *,
8858c2ecf20Sopenharmony_ci				   struct sk_buff *);
8868c2ecf20Sopenharmony_civoid rxrpc_unpublish_service_conn(struct rxrpc_connection *);
8878c2ecf20Sopenharmony_ci
8888c2ecf20Sopenharmony_ci/*
8898c2ecf20Sopenharmony_ci * input.c
8908c2ecf20Sopenharmony_ci */
8918c2ecf20Sopenharmony_ciint rxrpc_input_packet(struct sock *, struct sk_buff *);
8928c2ecf20Sopenharmony_ci
8938c2ecf20Sopenharmony_ci/*
8948c2ecf20Sopenharmony_ci * insecure.c
8958c2ecf20Sopenharmony_ci */
8968c2ecf20Sopenharmony_ciextern const struct rxrpc_security rxrpc_no_security;
8978c2ecf20Sopenharmony_ci
8988c2ecf20Sopenharmony_ci/*
8998c2ecf20Sopenharmony_ci * key.c
9008c2ecf20Sopenharmony_ci */
9018c2ecf20Sopenharmony_ciextern struct key_type key_type_rxrpc;
9028c2ecf20Sopenharmony_ciextern struct key_type key_type_rxrpc_s;
9038c2ecf20Sopenharmony_ci
9048c2ecf20Sopenharmony_ciint rxrpc_request_key(struct rxrpc_sock *, sockptr_t , int);
9058c2ecf20Sopenharmony_ciint rxrpc_server_keyring(struct rxrpc_sock *, sockptr_t, int);
9068c2ecf20Sopenharmony_ciint rxrpc_get_server_data_key(struct rxrpc_connection *, const void *, time64_t,
9078c2ecf20Sopenharmony_ci			      u32);
9088c2ecf20Sopenharmony_ci
9098c2ecf20Sopenharmony_ci/*
9108c2ecf20Sopenharmony_ci * local_event.c
9118c2ecf20Sopenharmony_ci */
9128c2ecf20Sopenharmony_ciextern void rxrpc_process_local_events(struct rxrpc_local *);
9138c2ecf20Sopenharmony_ci
9148c2ecf20Sopenharmony_ci/*
9158c2ecf20Sopenharmony_ci * local_object.c
9168c2ecf20Sopenharmony_ci */
9178c2ecf20Sopenharmony_cistruct rxrpc_local *rxrpc_lookup_local(struct net *, const struct sockaddr_rxrpc *);
9188c2ecf20Sopenharmony_cistruct rxrpc_local *rxrpc_get_local(struct rxrpc_local *);
9198c2ecf20Sopenharmony_cistruct rxrpc_local *rxrpc_get_local_maybe(struct rxrpc_local *);
9208c2ecf20Sopenharmony_civoid rxrpc_put_local(struct rxrpc_local *);
9218c2ecf20Sopenharmony_cistruct rxrpc_local *rxrpc_use_local(struct rxrpc_local *);
9228c2ecf20Sopenharmony_civoid rxrpc_unuse_local(struct rxrpc_local *);
9238c2ecf20Sopenharmony_civoid rxrpc_queue_local(struct rxrpc_local *);
9248c2ecf20Sopenharmony_civoid rxrpc_destroy_all_locals(struct rxrpc_net *);
9258c2ecf20Sopenharmony_ci
9268c2ecf20Sopenharmony_cistatic inline bool __rxrpc_unuse_local(struct rxrpc_local *local)
9278c2ecf20Sopenharmony_ci{
9288c2ecf20Sopenharmony_ci	return atomic_dec_return(&local->active_users) == 0;
9298c2ecf20Sopenharmony_ci}
9308c2ecf20Sopenharmony_ci
9318c2ecf20Sopenharmony_cistatic inline bool __rxrpc_use_local(struct rxrpc_local *local)
9328c2ecf20Sopenharmony_ci{
9338c2ecf20Sopenharmony_ci	return atomic_fetch_add_unless(&local->active_users, 1, 0) != 0;
9348c2ecf20Sopenharmony_ci}
9358c2ecf20Sopenharmony_ci
9368c2ecf20Sopenharmony_ci/*
9378c2ecf20Sopenharmony_ci * misc.c
9388c2ecf20Sopenharmony_ci */
9398c2ecf20Sopenharmony_ciextern unsigned int rxrpc_max_backlog __read_mostly;
9408c2ecf20Sopenharmony_ciextern unsigned long rxrpc_requested_ack_delay;
9418c2ecf20Sopenharmony_ciextern unsigned long rxrpc_soft_ack_delay;
9428c2ecf20Sopenharmony_ciextern unsigned long rxrpc_idle_ack_delay;
9438c2ecf20Sopenharmony_ciextern unsigned int rxrpc_rx_window_size;
9448c2ecf20Sopenharmony_ciextern unsigned int rxrpc_rx_mtu;
9458c2ecf20Sopenharmony_ciextern unsigned int rxrpc_rx_jumbo_max;
9468c2ecf20Sopenharmony_ci
9478c2ecf20Sopenharmony_ciextern const s8 rxrpc_ack_priority[];
9488c2ecf20Sopenharmony_ci
9498c2ecf20Sopenharmony_ci/*
9508c2ecf20Sopenharmony_ci * net_ns.c
9518c2ecf20Sopenharmony_ci */
9528c2ecf20Sopenharmony_ciextern unsigned int rxrpc_net_id;
9538c2ecf20Sopenharmony_ciextern struct pernet_operations rxrpc_net_ops;
9548c2ecf20Sopenharmony_ci
9558c2ecf20Sopenharmony_cistatic inline struct rxrpc_net *rxrpc_net(struct net *net)
9568c2ecf20Sopenharmony_ci{
9578c2ecf20Sopenharmony_ci	return net_generic(net, rxrpc_net_id);
9588c2ecf20Sopenharmony_ci}
9598c2ecf20Sopenharmony_ci
9608c2ecf20Sopenharmony_ci/*
9618c2ecf20Sopenharmony_ci * output.c
9628c2ecf20Sopenharmony_ci */
9638c2ecf20Sopenharmony_ciint rxrpc_send_ack_packet(struct rxrpc_call *, bool, rxrpc_serial_t *);
9648c2ecf20Sopenharmony_ciint rxrpc_send_abort_packet(struct rxrpc_call *);
9658c2ecf20Sopenharmony_ciint rxrpc_send_data_packet(struct rxrpc_call *, struct sk_buff *, bool);
9668c2ecf20Sopenharmony_civoid rxrpc_reject_packets(struct rxrpc_local *);
9678c2ecf20Sopenharmony_civoid rxrpc_send_keepalive(struct rxrpc_peer *);
9688c2ecf20Sopenharmony_ci
9698c2ecf20Sopenharmony_ci/*
9708c2ecf20Sopenharmony_ci * peer_event.c
9718c2ecf20Sopenharmony_ci */
9728c2ecf20Sopenharmony_civoid rxrpc_error_report(struct sock *);
9738c2ecf20Sopenharmony_civoid rxrpc_peer_keepalive_worker(struct work_struct *);
9748c2ecf20Sopenharmony_ci
9758c2ecf20Sopenharmony_ci/*
9768c2ecf20Sopenharmony_ci * peer_object.c
9778c2ecf20Sopenharmony_ci */
9788c2ecf20Sopenharmony_cistruct rxrpc_peer *rxrpc_lookup_peer_rcu(struct rxrpc_local *,
9798c2ecf20Sopenharmony_ci					 const struct sockaddr_rxrpc *);
9808c2ecf20Sopenharmony_cistruct rxrpc_peer *rxrpc_lookup_peer(struct rxrpc_sock *, struct rxrpc_local *,
9818c2ecf20Sopenharmony_ci				     struct sockaddr_rxrpc *, gfp_t);
9828c2ecf20Sopenharmony_cistruct rxrpc_peer *rxrpc_alloc_peer(struct rxrpc_local *, gfp_t);
9838c2ecf20Sopenharmony_civoid rxrpc_new_incoming_peer(struct rxrpc_sock *, struct rxrpc_local *,
9848c2ecf20Sopenharmony_ci			     struct rxrpc_peer *);
9858c2ecf20Sopenharmony_civoid rxrpc_destroy_all_peers(struct rxrpc_net *);
9868c2ecf20Sopenharmony_cistruct rxrpc_peer *rxrpc_get_peer(struct rxrpc_peer *);
9878c2ecf20Sopenharmony_cistruct rxrpc_peer *rxrpc_get_peer_maybe(struct rxrpc_peer *);
9888c2ecf20Sopenharmony_civoid rxrpc_put_peer(struct rxrpc_peer *);
9898c2ecf20Sopenharmony_civoid rxrpc_put_peer_locked(struct rxrpc_peer *);
9908c2ecf20Sopenharmony_ci
9918c2ecf20Sopenharmony_ci/*
9928c2ecf20Sopenharmony_ci * proc.c
9938c2ecf20Sopenharmony_ci */
9948c2ecf20Sopenharmony_ciextern const struct seq_operations rxrpc_call_seq_ops;
9958c2ecf20Sopenharmony_ciextern const struct seq_operations rxrpc_connection_seq_ops;
9968c2ecf20Sopenharmony_ciextern const struct seq_operations rxrpc_peer_seq_ops;
9978c2ecf20Sopenharmony_ciextern const struct seq_operations rxrpc_local_seq_ops;
9988c2ecf20Sopenharmony_ci
9998c2ecf20Sopenharmony_ci/*
10008c2ecf20Sopenharmony_ci * recvmsg.c
10018c2ecf20Sopenharmony_ci */
10028c2ecf20Sopenharmony_civoid rxrpc_notify_socket(struct rxrpc_call *);
10038c2ecf20Sopenharmony_cibool __rxrpc_set_call_completion(struct rxrpc_call *, enum rxrpc_call_completion, u32, int);
10048c2ecf20Sopenharmony_cibool rxrpc_set_call_completion(struct rxrpc_call *, enum rxrpc_call_completion, u32, int);
10058c2ecf20Sopenharmony_cibool __rxrpc_call_completed(struct rxrpc_call *);
10068c2ecf20Sopenharmony_cibool rxrpc_call_completed(struct rxrpc_call *);
10078c2ecf20Sopenharmony_cibool __rxrpc_abort_call(const char *, struct rxrpc_call *, rxrpc_seq_t, u32, int);
10088c2ecf20Sopenharmony_cibool rxrpc_abort_call(const char *, struct rxrpc_call *, rxrpc_seq_t, u32, int);
10098c2ecf20Sopenharmony_ciint rxrpc_recvmsg(struct socket *, struct msghdr *, size_t, int);
10108c2ecf20Sopenharmony_ci
10118c2ecf20Sopenharmony_ci/*
10128c2ecf20Sopenharmony_ci * Abort a call due to a protocol error.
10138c2ecf20Sopenharmony_ci */
10148c2ecf20Sopenharmony_cistatic inline bool __rxrpc_abort_eproto(struct rxrpc_call *call,
10158c2ecf20Sopenharmony_ci					struct sk_buff *skb,
10168c2ecf20Sopenharmony_ci					const char *eproto_why,
10178c2ecf20Sopenharmony_ci					const char *why,
10188c2ecf20Sopenharmony_ci					u32 abort_code)
10198c2ecf20Sopenharmony_ci{
10208c2ecf20Sopenharmony_ci	struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
10218c2ecf20Sopenharmony_ci
10228c2ecf20Sopenharmony_ci	trace_rxrpc_rx_eproto(call, sp->hdr.serial, eproto_why);
10238c2ecf20Sopenharmony_ci	return rxrpc_abort_call(why, call, sp->hdr.seq, abort_code, -EPROTO);
10248c2ecf20Sopenharmony_ci}
10258c2ecf20Sopenharmony_ci
10268c2ecf20Sopenharmony_ci#define rxrpc_abort_eproto(call, skb, eproto_why, abort_why, abort_code) \
10278c2ecf20Sopenharmony_ci	__rxrpc_abort_eproto((call), (skb), tracepoint_string(eproto_why), \
10288c2ecf20Sopenharmony_ci			     (abort_why), (abort_code))
10298c2ecf20Sopenharmony_ci
10308c2ecf20Sopenharmony_ci/*
10318c2ecf20Sopenharmony_ci * rtt.c
10328c2ecf20Sopenharmony_ci */
10338c2ecf20Sopenharmony_civoid rxrpc_peer_add_rtt(struct rxrpc_call *, enum rxrpc_rtt_rx_trace, int,
10348c2ecf20Sopenharmony_ci			rxrpc_serial_t, rxrpc_serial_t, ktime_t, ktime_t);
10358c2ecf20Sopenharmony_ciunsigned long rxrpc_get_rto_backoff(struct rxrpc_peer *, bool);
10368c2ecf20Sopenharmony_civoid rxrpc_peer_init_rtt(struct rxrpc_peer *);
10378c2ecf20Sopenharmony_ci
10388c2ecf20Sopenharmony_ci/*
10398c2ecf20Sopenharmony_ci * rxkad.c
10408c2ecf20Sopenharmony_ci */
10418c2ecf20Sopenharmony_ci#ifdef CONFIG_RXKAD
10428c2ecf20Sopenharmony_ciextern const struct rxrpc_security rxkad;
10438c2ecf20Sopenharmony_ci#endif
10448c2ecf20Sopenharmony_ci
10458c2ecf20Sopenharmony_ci/*
10468c2ecf20Sopenharmony_ci * security.c
10478c2ecf20Sopenharmony_ci */
10488c2ecf20Sopenharmony_ciint __init rxrpc_init_security(void);
10498c2ecf20Sopenharmony_civoid rxrpc_exit_security(void);
10508c2ecf20Sopenharmony_ciint rxrpc_init_client_conn_security(struct rxrpc_connection *);
10518c2ecf20Sopenharmony_cibool rxrpc_look_up_server_security(struct rxrpc_local *, struct rxrpc_sock *,
10528c2ecf20Sopenharmony_ci				   const struct rxrpc_security **, struct key **,
10538c2ecf20Sopenharmony_ci				   struct sk_buff *);
10548c2ecf20Sopenharmony_ci
10558c2ecf20Sopenharmony_ci/*
10568c2ecf20Sopenharmony_ci * sendmsg.c
10578c2ecf20Sopenharmony_ci */
10588c2ecf20Sopenharmony_ciint rxrpc_do_sendmsg(struct rxrpc_sock *, struct msghdr *, size_t);
10598c2ecf20Sopenharmony_ci
10608c2ecf20Sopenharmony_ci/*
10618c2ecf20Sopenharmony_ci * skbuff.c
10628c2ecf20Sopenharmony_ci */
10638c2ecf20Sopenharmony_civoid rxrpc_kernel_data_consumed(struct rxrpc_call *, struct sk_buff *);
10648c2ecf20Sopenharmony_civoid rxrpc_packet_destructor(struct sk_buff *);
10658c2ecf20Sopenharmony_civoid rxrpc_new_skb(struct sk_buff *, enum rxrpc_skb_trace);
10668c2ecf20Sopenharmony_civoid rxrpc_see_skb(struct sk_buff *, enum rxrpc_skb_trace);
10678c2ecf20Sopenharmony_civoid rxrpc_eaten_skb(struct sk_buff *, enum rxrpc_skb_trace);
10688c2ecf20Sopenharmony_civoid rxrpc_get_skb(struct sk_buff *, enum rxrpc_skb_trace);
10698c2ecf20Sopenharmony_civoid rxrpc_free_skb(struct sk_buff *, enum rxrpc_skb_trace);
10708c2ecf20Sopenharmony_civoid rxrpc_purge_queue(struct sk_buff_head *);
10718c2ecf20Sopenharmony_ci
10728c2ecf20Sopenharmony_ci/*
10738c2ecf20Sopenharmony_ci * sysctl.c
10748c2ecf20Sopenharmony_ci */
10758c2ecf20Sopenharmony_ci#ifdef CONFIG_SYSCTL
10768c2ecf20Sopenharmony_ciextern int __init rxrpc_sysctl_init(void);
10778c2ecf20Sopenharmony_ciextern void rxrpc_sysctl_exit(void);
10788c2ecf20Sopenharmony_ci#else
10798c2ecf20Sopenharmony_cistatic inline int __init rxrpc_sysctl_init(void) { return 0; }
10808c2ecf20Sopenharmony_cistatic inline void rxrpc_sysctl_exit(void) {}
10818c2ecf20Sopenharmony_ci#endif
10828c2ecf20Sopenharmony_ci
10838c2ecf20Sopenharmony_ci/*
10848c2ecf20Sopenharmony_ci * utils.c
10858c2ecf20Sopenharmony_ci */
10868c2ecf20Sopenharmony_ciint rxrpc_extract_addr_from_skb(struct sockaddr_rxrpc *, struct sk_buff *);
10878c2ecf20Sopenharmony_ci
10888c2ecf20Sopenharmony_cistatic inline bool before(u32 seq1, u32 seq2)
10898c2ecf20Sopenharmony_ci{
10908c2ecf20Sopenharmony_ci        return (s32)(seq1 - seq2) < 0;
10918c2ecf20Sopenharmony_ci}
10928c2ecf20Sopenharmony_cistatic inline bool before_eq(u32 seq1, u32 seq2)
10938c2ecf20Sopenharmony_ci{
10948c2ecf20Sopenharmony_ci        return (s32)(seq1 - seq2) <= 0;
10958c2ecf20Sopenharmony_ci}
10968c2ecf20Sopenharmony_cistatic inline bool after(u32 seq1, u32 seq2)
10978c2ecf20Sopenharmony_ci{
10988c2ecf20Sopenharmony_ci        return (s32)(seq1 - seq2) > 0;
10998c2ecf20Sopenharmony_ci}
11008c2ecf20Sopenharmony_cistatic inline bool after_eq(u32 seq1, u32 seq2)
11018c2ecf20Sopenharmony_ci{
11028c2ecf20Sopenharmony_ci        return (s32)(seq1 - seq2) >= 0;
11038c2ecf20Sopenharmony_ci}
11048c2ecf20Sopenharmony_ci
11058c2ecf20Sopenharmony_ci/*
11068c2ecf20Sopenharmony_ci * debug tracing
11078c2ecf20Sopenharmony_ci */
11088c2ecf20Sopenharmony_ciextern unsigned int rxrpc_debug;
11098c2ecf20Sopenharmony_ci
11108c2ecf20Sopenharmony_ci#define dbgprintk(FMT,...) \
11118c2ecf20Sopenharmony_ci	printk("[%-6.6s] "FMT"\n", current->comm ,##__VA_ARGS__)
11128c2ecf20Sopenharmony_ci
11138c2ecf20Sopenharmony_ci#define kenter(FMT,...)	dbgprintk("==> %s("FMT")",__func__ ,##__VA_ARGS__)
11148c2ecf20Sopenharmony_ci#define kleave(FMT,...)	dbgprintk("<== %s()"FMT"",__func__ ,##__VA_ARGS__)
11158c2ecf20Sopenharmony_ci#define kdebug(FMT,...)	dbgprintk("    "FMT ,##__VA_ARGS__)
11168c2ecf20Sopenharmony_ci#define kproto(FMT,...)	dbgprintk("### "FMT ,##__VA_ARGS__)
11178c2ecf20Sopenharmony_ci#define knet(FMT,...)	dbgprintk("@@@ "FMT ,##__VA_ARGS__)
11188c2ecf20Sopenharmony_ci
11198c2ecf20Sopenharmony_ci
11208c2ecf20Sopenharmony_ci#if defined(__KDEBUG)
11218c2ecf20Sopenharmony_ci#define _enter(FMT,...)	kenter(FMT,##__VA_ARGS__)
11228c2ecf20Sopenharmony_ci#define _leave(FMT,...)	kleave(FMT,##__VA_ARGS__)
11238c2ecf20Sopenharmony_ci#define _debug(FMT,...)	kdebug(FMT,##__VA_ARGS__)
11248c2ecf20Sopenharmony_ci#define _proto(FMT,...)	kproto(FMT,##__VA_ARGS__)
11258c2ecf20Sopenharmony_ci#define _net(FMT,...)	knet(FMT,##__VA_ARGS__)
11268c2ecf20Sopenharmony_ci
11278c2ecf20Sopenharmony_ci#elif defined(CONFIG_AF_RXRPC_DEBUG)
11288c2ecf20Sopenharmony_ci#define RXRPC_DEBUG_KENTER	0x01
11298c2ecf20Sopenharmony_ci#define RXRPC_DEBUG_KLEAVE	0x02
11308c2ecf20Sopenharmony_ci#define RXRPC_DEBUG_KDEBUG	0x04
11318c2ecf20Sopenharmony_ci#define RXRPC_DEBUG_KPROTO	0x08
11328c2ecf20Sopenharmony_ci#define RXRPC_DEBUG_KNET	0x10
11338c2ecf20Sopenharmony_ci
11348c2ecf20Sopenharmony_ci#define _enter(FMT,...)					\
11358c2ecf20Sopenharmony_cido {							\
11368c2ecf20Sopenharmony_ci	if (unlikely(rxrpc_debug & RXRPC_DEBUG_KENTER))	\
11378c2ecf20Sopenharmony_ci		kenter(FMT,##__VA_ARGS__);		\
11388c2ecf20Sopenharmony_ci} while (0)
11398c2ecf20Sopenharmony_ci
11408c2ecf20Sopenharmony_ci#define _leave(FMT,...)					\
11418c2ecf20Sopenharmony_cido {							\
11428c2ecf20Sopenharmony_ci	if (unlikely(rxrpc_debug & RXRPC_DEBUG_KLEAVE))	\
11438c2ecf20Sopenharmony_ci		kleave(FMT,##__VA_ARGS__);		\
11448c2ecf20Sopenharmony_ci} while (0)
11458c2ecf20Sopenharmony_ci
11468c2ecf20Sopenharmony_ci#define _debug(FMT,...)					\
11478c2ecf20Sopenharmony_cido {							\
11488c2ecf20Sopenharmony_ci	if (unlikely(rxrpc_debug & RXRPC_DEBUG_KDEBUG))	\
11498c2ecf20Sopenharmony_ci		kdebug(FMT,##__VA_ARGS__);		\
11508c2ecf20Sopenharmony_ci} while (0)
11518c2ecf20Sopenharmony_ci
11528c2ecf20Sopenharmony_ci#define _proto(FMT,...)					\
11538c2ecf20Sopenharmony_cido {							\
11548c2ecf20Sopenharmony_ci	if (unlikely(rxrpc_debug & RXRPC_DEBUG_KPROTO))	\
11558c2ecf20Sopenharmony_ci		kproto(FMT,##__VA_ARGS__);		\
11568c2ecf20Sopenharmony_ci} while (0)
11578c2ecf20Sopenharmony_ci
11588c2ecf20Sopenharmony_ci#define _net(FMT,...)					\
11598c2ecf20Sopenharmony_cido {							\
11608c2ecf20Sopenharmony_ci	if (unlikely(rxrpc_debug & RXRPC_DEBUG_KNET))	\
11618c2ecf20Sopenharmony_ci		knet(FMT,##__VA_ARGS__);		\
11628c2ecf20Sopenharmony_ci} while (0)
11638c2ecf20Sopenharmony_ci
11648c2ecf20Sopenharmony_ci#else
11658c2ecf20Sopenharmony_ci#define _enter(FMT,...)	no_printk("==> %s("FMT")",__func__ ,##__VA_ARGS__)
11668c2ecf20Sopenharmony_ci#define _leave(FMT,...)	no_printk("<== %s()"FMT"",__func__ ,##__VA_ARGS__)
11678c2ecf20Sopenharmony_ci#define _debug(FMT,...)	no_printk("    "FMT ,##__VA_ARGS__)
11688c2ecf20Sopenharmony_ci#define _proto(FMT,...)	no_printk("### "FMT ,##__VA_ARGS__)
11698c2ecf20Sopenharmony_ci#define _net(FMT,...)	no_printk("@@@ "FMT ,##__VA_ARGS__)
11708c2ecf20Sopenharmony_ci#endif
11718c2ecf20Sopenharmony_ci
11728c2ecf20Sopenharmony_ci/*
11738c2ecf20Sopenharmony_ci * debug assertion checking
11748c2ecf20Sopenharmony_ci */
11758c2ecf20Sopenharmony_ci#if 1 // defined(__KDEBUGALL)
11768c2ecf20Sopenharmony_ci
11778c2ecf20Sopenharmony_ci#define ASSERT(X)						\
11788c2ecf20Sopenharmony_cido {								\
11798c2ecf20Sopenharmony_ci	if (unlikely(!(X))) {					\
11808c2ecf20Sopenharmony_ci		pr_err("Assertion failed\n");			\
11818c2ecf20Sopenharmony_ci		BUG();						\
11828c2ecf20Sopenharmony_ci	}							\
11838c2ecf20Sopenharmony_ci} while (0)
11848c2ecf20Sopenharmony_ci
11858c2ecf20Sopenharmony_ci#define ASSERTCMP(X, OP, Y)						\
11868c2ecf20Sopenharmony_cido {									\
11878c2ecf20Sopenharmony_ci	__typeof__(X) _x = (X);						\
11888c2ecf20Sopenharmony_ci	__typeof__(Y) _y = (__typeof__(X))(Y);				\
11898c2ecf20Sopenharmony_ci	if (unlikely(!(_x OP _y))) {					\
11908c2ecf20Sopenharmony_ci		pr_err("Assertion failed - %lu(0x%lx) %s %lu(0x%lx) is false\n", \
11918c2ecf20Sopenharmony_ci		       (unsigned long)_x, (unsigned long)_x, #OP,	\
11928c2ecf20Sopenharmony_ci		       (unsigned long)_y, (unsigned long)_y);		\
11938c2ecf20Sopenharmony_ci		BUG();							\
11948c2ecf20Sopenharmony_ci	}								\
11958c2ecf20Sopenharmony_ci} while (0)
11968c2ecf20Sopenharmony_ci
11978c2ecf20Sopenharmony_ci#define ASSERTIF(C, X)						\
11988c2ecf20Sopenharmony_cido {								\
11998c2ecf20Sopenharmony_ci	if (unlikely((C) && !(X))) {				\
12008c2ecf20Sopenharmony_ci		pr_err("Assertion failed\n");			\
12018c2ecf20Sopenharmony_ci		BUG();						\
12028c2ecf20Sopenharmony_ci	}							\
12038c2ecf20Sopenharmony_ci} while (0)
12048c2ecf20Sopenharmony_ci
12058c2ecf20Sopenharmony_ci#define ASSERTIFCMP(C, X, OP, Y)					\
12068c2ecf20Sopenharmony_cido {									\
12078c2ecf20Sopenharmony_ci	__typeof__(X) _x = (X);						\
12088c2ecf20Sopenharmony_ci	__typeof__(Y) _y = (__typeof__(X))(Y);				\
12098c2ecf20Sopenharmony_ci	if (unlikely((C) && !(_x OP _y))) {				\
12108c2ecf20Sopenharmony_ci		pr_err("Assertion failed - %lu(0x%lx) %s %lu(0x%lx) is false\n", \
12118c2ecf20Sopenharmony_ci		       (unsigned long)_x, (unsigned long)_x, #OP,	\
12128c2ecf20Sopenharmony_ci		       (unsigned long)_y, (unsigned long)_y);		\
12138c2ecf20Sopenharmony_ci		BUG();							\
12148c2ecf20Sopenharmony_ci	}								\
12158c2ecf20Sopenharmony_ci} while (0)
12168c2ecf20Sopenharmony_ci
12178c2ecf20Sopenharmony_ci#else
12188c2ecf20Sopenharmony_ci
12198c2ecf20Sopenharmony_ci#define ASSERT(X)				\
12208c2ecf20Sopenharmony_cido {						\
12218c2ecf20Sopenharmony_ci} while (0)
12228c2ecf20Sopenharmony_ci
12238c2ecf20Sopenharmony_ci#define ASSERTCMP(X, OP, Y)			\
12248c2ecf20Sopenharmony_cido {						\
12258c2ecf20Sopenharmony_ci} while (0)
12268c2ecf20Sopenharmony_ci
12278c2ecf20Sopenharmony_ci#define ASSERTIF(C, X)				\
12288c2ecf20Sopenharmony_cido {						\
12298c2ecf20Sopenharmony_ci} while (0)
12308c2ecf20Sopenharmony_ci
12318c2ecf20Sopenharmony_ci#define ASSERTIFCMP(C, X, OP, Y)		\
12328c2ecf20Sopenharmony_cido {						\
12338c2ecf20Sopenharmony_ci} while (0)
12348c2ecf20Sopenharmony_ci
12358c2ecf20Sopenharmony_ci#endif /* __KDEBUGALL */
1236