Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0d12f8a4 authored by David Howells's avatar David Howells
Browse files

rxrpc: Keep the skb private record of the Rx header in host byte order



Currently, a copy of the Rx packet header is copied into the the sk_buff
private data so that we can advance the pointer into the buffer,
potentially discarding the original.  At the moment, this copy is held in
network byte order, but this means we're doing a lot of unnecessary
translations.

The reasons it was done this way are that we need the values in network
byte order occasionally and we can use the copy, slightly modified, as part
of an iov array when sending an ack or an abort packet.

However, it seems more reasonable on review that it would be better kept in
host byte order and that we make up a new header when we want to send
another packet.

To this end, rename the original header struct to rxrpc_wire_header (with
BE fields) and institute a variant called rxrpc_host_header that has host
order fields.  Change the struct in the sk_buff private data into an
rxrpc_host_header and translate the values when filling it in.

This further allows us to keep values kept in various structures in host
byte order rather than network byte order and allows removal of some fields
that are byteswapped duplicates.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent 4c198ad1
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@ typedef __be32 rxrpc_serial_net_t; /* on-the-wire Rx message serial number */
 * on-the-wire Rx packet header
 * - all multibyte fields should be in network byte order
 */
struct rxrpc_header {
struct rxrpc_wire_header {
	__be32		epoch;		/* client boot timestamp */

	__be32		cid;		/* connection and channel ID */
@@ -68,8 +68,6 @@ struct rxrpc_header {

} __packed;

#define __rxrpc_header_off(X) offsetof(struct rxrpc_header,X)

extern const char *rxrpc_pkts[];

/*****************************************************************************/
+7 −13
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ static struct proto rxrpc_proto;
static const struct proto_ops rxrpc_rpc_ops;

/* local epoch for detecting local-end reset */
__be32 rxrpc_epoch;
u32 rxrpc_epoch;

/* current debugging ID */
atomic_t rxrpc_debug_id;
@@ -125,7 +125,6 @@ static int rxrpc_bind(struct socket *sock, struct sockaddr *saddr, int len)
	struct sock *sk = sock->sk;
	struct rxrpc_local *local;
	struct rxrpc_sock *rx = rxrpc_sk(sk), *prx;
	__be16 service_id;
	int ret;

	_enter("%p,%p,%d", rx, saddr, len);
@@ -152,14 +151,12 @@ static int rxrpc_bind(struct socket *sock, struct sockaddr *saddr, int len)

	rx->local = local;
	if (srx->srx_service) {
		service_id = htons(srx->srx_service);
		write_lock_bh(&local->services_lock);
		list_for_each_entry(prx, &local->services, listen_link) {
			if (prx->service_id == service_id)
			if (prx->srx.srx_service == srx->srx_service)
				goto service_in_use;
		}

		rx->service_id = service_id;
		list_add_tail(&rx->listen_link, &local->services);
		write_unlock_bh(&local->services_lock);

@@ -276,7 +273,6 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
	struct rxrpc_transport *trans;
	struct rxrpc_call *call;
	struct rxrpc_sock *rx = rxrpc_sk(sock->sk);
	__be16 service_id;

	_enter(",,%x,%lx", key_serial(key), user_call_ID);

@@ -299,16 +295,15 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
		atomic_inc(&trans->usage);
	}

	service_id = rx->service_id;
	if (srx)
		service_id = htons(srx->srx_service);
	if (!srx)
		srx = &rx->srx;

	if (!key)
		key = rx->key;
	if (key && !key->payload.data[0])
		key = NULL; /* a no-security key */

	bundle = rxrpc_get_bundle(rx, trans, key, service_id, gfp);
	bundle = rxrpc_get_bundle(rx, trans, key, srx->srx_service, gfp);
	if (IS_ERR(bundle)) {
		call = ERR_CAST(bundle);
		goto out;
@@ -425,7 +420,6 @@ static int rxrpc_connect(struct socket *sock, struct sockaddr *addr,
	}

	rx->trans = trans;
	rx->service_id = htons(srx->srx_service);
	rx->sk.sk_state = RXRPC_CLIENT_CONNECTED;

	release_sock(&rx->sk);
@@ -778,7 +772,7 @@ static struct proto rxrpc_proto = {
	.name		= "RXRPC",
	.owner		= THIS_MODULE,
	.obj_size	= sizeof(struct rxrpc_sock),
	.max_header	= sizeof(struct rxrpc_header),
	.max_header	= sizeof(struct rxrpc_wire_header),
};

static const struct net_proto_family rxrpc_family_ops = {
@@ -796,7 +790,7 @@ static int __init af_rxrpc_init(void)

	BUILD_BUG_ON(sizeof(struct rxrpc_skb_priv) > FIELD_SIZEOF(struct sk_buff, cb));

	rxrpc_epoch = htonl(get_seconds());
	rxrpc_epoch = get_seconds();

	ret = -ENOMEM;
	rxrpc_call_jar = kmem_cache_create(
+24 −16
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@
 * generate a connection-level abort
 */
static int rxrpc_busy(struct rxrpc_local *local, struct sockaddr_rxrpc *srx,
		      struct rxrpc_header *hdr)
		      struct rxrpc_wire_header *whdr)
{
	struct msghdr msg;
	struct kvec iov[1];
@@ -36,25 +36,21 @@ static int rxrpc_busy(struct rxrpc_local *local, struct sockaddr_rxrpc *srx,

	_enter("%d,,", local->debug_id);

	whdr->type	= RXRPC_PACKET_TYPE_BUSY;
	whdr->serial	= htonl(1);

	msg.msg_name	= &srx->transport.sin;
	msg.msg_namelen	= sizeof(srx->transport.sin);
	msg.msg_control	= NULL;
	msg.msg_controllen = 0;
	msg.msg_flags	= 0;

	hdr->seq	= 0;
	hdr->type	= RXRPC_PACKET_TYPE_BUSY;
	hdr->flags	= 0;
	hdr->userStatus	= 0;
	hdr->_rsvd	= 0;

	iov[0].iov_base	= hdr;
	iov[0].iov_len	= sizeof(*hdr);
	iov[0].iov_base	= whdr;
	iov[0].iov_len	= sizeof(*whdr);

	len = iov[0].iov_len;

	hdr->serial = htonl(1);
	_proto("Tx BUSY %%%u", ntohl(hdr->serial));
	_proto("Tx BUSY %%1");

	ret = kernel_sendmsg(local->socket, &msg, iov, 1, len);
	if (ret < 0) {
@@ -211,8 +207,8 @@ void rxrpc_accept_incoming_calls(struct work_struct *work)
	struct rxrpc_skb_priv *sp;
	struct sockaddr_rxrpc srx;
	struct rxrpc_sock *rx;
	struct rxrpc_wire_header whdr;
	struct sk_buff *skb;
	__be16 service_id;
	int ret;

	_enter("%d", local->debug_id);
@@ -240,6 +236,19 @@ void rxrpc_accept_incoming_calls(struct work_struct *work)

	sp = rxrpc_skb(skb);

	/* Set up a response packet header in case we need it */
	whdr.epoch	= htonl(sp->hdr.epoch);
	whdr.cid	= htonl(sp->hdr.cid);
	whdr.callNumber	= htonl(sp->hdr.callNumber);
	whdr.seq	= htonl(sp->hdr.seq);
	whdr.serial	= 0;
	whdr.flags	= 0;
	whdr.type	= 0;
	whdr.userStatus	= 0;
	whdr.securityIndex = sp->hdr.securityIndex;
	whdr._rsvd	= 0;
	whdr.serviceId	= htons(sp->hdr.serviceId);

	/* determine the remote address */
	memset(&srx, 0, sizeof(srx));
	srx.srx_family = AF_RXRPC;
@@ -256,10 +265,9 @@ void rxrpc_accept_incoming_calls(struct work_struct *work)
	}

	/* get the socket providing the service */
	service_id = sp->hdr.serviceId;
	read_lock_bh(&local->services_lock);
	list_for_each_entry(rx, &local->services, listen_link) {
		if (rx->service_id == service_id &&
		if (rx->srx.srx_service == sp->hdr.serviceId &&
		    rx->sk.sk_state != RXRPC_CLOSE)
			goto found_service;
	}
@@ -267,7 +275,7 @@ void rxrpc_accept_incoming_calls(struct work_struct *work)
	goto invalid_service;

found_service:
	_debug("found service %hd", ntohs(rx->service_id));
	_debug("found service %hd", rx->srx.srx_service);
	if (sk_acceptq_is_full(&rx->sk))
		goto backlog_full;
	sk_acceptq_added(&rx->sk);
@@ -296,7 +304,7 @@ void rxrpc_accept_incoming_calls(struct work_struct *work)
backlog_full:
	read_unlock_bh(&local->services_lock);
busy:
	rxrpc_busy(local, &srx, &sp->hdr);
	rxrpc_busy(local, &srx, &whdr);
	rxrpc_free_skb(skb);
	goto process_next_packet;

+51 −57
Original line number Diff line number Diff line
@@ -91,7 +91,7 @@ static const s8 rxrpc_ack_priority[] = {
 * propose an ACK be sent
 */
void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason,
			 __be32 serial, bool immediate)
			 u32 serial, bool immediate)
{
	unsigned long expiry;
	s8 prior = rxrpc_ack_priority[ack_reason];
@@ -99,8 +99,7 @@ void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason,
	ASSERTCMP(prior, >, 0);

	_enter("{%d},%s,%%%x,%u",
	       call->debug_id, rxrpc_acks(ack_reason), ntohl(serial),
	       immediate);
	       call->debug_id, rxrpc_acks(ack_reason), serial, immediate);

	if (prior < rxrpc_ack_priority[call->ackr_reason]) {
		if (immediate)
@@ -139,7 +138,7 @@ void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason,
		expiry = rxrpc_requested_ack_delay;
		if (!expiry)
			goto cancel_timer;
		if (!immediate || serial == cpu_to_be32(1)) {
		if (!immediate || serial == 1) {
			_debug("run defer timer");
			goto run_timer;
		}
@@ -157,7 +156,7 @@ void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason,
	return;

cancel_timer:
	_debug("cancel timer %%%u", ntohl(serial));
	_debug("cancel timer %%%u", serial);
	try_to_del_timer_sync(&call->ack_timer);
	read_lock_bh(&call->state_lock);
	if (call->state <= RXRPC_CALL_COMPLETE &&
@@ -170,7 +169,7 @@ void __rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason,
 * propose an ACK be sent, locking the call structure
 */
void rxrpc_propose_ACK(struct rxrpc_call *call, u8 ack_reason,
		       __be32 serial, bool immediate)
		       u32 serial, bool immediate)
{
	s8 prior = rxrpc_ack_priority[ack_reason];

@@ -214,8 +213,8 @@ static void rxrpc_set_resend(struct rxrpc_call *call, u8 resend,
 */
static void rxrpc_resend(struct rxrpc_call *call)
{
	struct rxrpc_wire_header *whdr;
	struct rxrpc_skb_priv *sp;
	struct rxrpc_header *hdr;
	struct sk_buff *txb;
	unsigned long *p_txb, resend_at;
	bool stop;
@@ -247,14 +246,13 @@ static void rxrpc_resend(struct rxrpc_call *call)
			sp->need_resend = false;

			/* each Tx packet has a new serial number */
			sp->hdr.serial =
				htonl(atomic_inc_return(&call->conn->serial));
			sp->hdr.serial = atomic_inc_return(&call->conn->serial);

			hdr = (struct rxrpc_header *) txb->head;
			hdr->serial = sp->hdr.serial;
			whdr = (struct rxrpc_wire_header *)txb->head;
			whdr->serial = htonl(sp->hdr.serial);

			_proto("Tx DATA %%%u { #%d }",
			       ntohl(sp->hdr.serial), ntohl(sp->hdr.seq));
			       sp->hdr.serial, sp->hdr.seq);
			if (rxrpc_send_packet(call->conn->trans, txb) < 0) {
				stop = true;
				sp->resend_at = jiffies + 3;
@@ -428,7 +426,7 @@ static void rxrpc_rotate_tx_window(struct rxrpc_call *call, u32 hard)
	int tail = call->acks_tail, old_tail;
	int win = CIRC_CNT(call->acks_head, tail, call->acks_winsz);

	_enter("{%u,%u},%u", call->acks_hard, win, hard);
	kenter("{%u,%u},%u", call->acks_hard, win, hard);

	ASSERTCMP(hard - call->acks_hard, <=, win);

@@ -478,11 +476,11 @@ static int rxrpc_drain_rx_oos_queue(struct rxrpc_call *call)
		sp = rxrpc_skb(skb);

		_debug("drain OOS packet %d [%d]",
		       ntohl(sp->hdr.seq), call->rx_first_oos);
		       sp->hdr.seq, call->rx_first_oos);

		if (ntohl(sp->hdr.seq) != call->rx_first_oos) {
		if (sp->hdr.seq != call->rx_first_oos) {
			skb_queue_head(&call->rx_oos_queue, skb);
			call->rx_first_oos = ntohl(rxrpc_skb(skb)->hdr.seq);
			call->rx_first_oos = rxrpc_skb(skb)->hdr.seq;
			_debug("requeue %p {%u}", skb, call->rx_first_oos);
		} else {
			skb->mark = RXRPC_SKB_MARK_DATA;
@@ -496,8 +494,7 @@ static int rxrpc_drain_rx_oos_queue(struct rxrpc_call *call)
			/* find out what the next packet is */
			skb = skb_peek(&call->rx_oos_queue);
			if (skb)
				call->rx_first_oos =
					ntohl(rxrpc_skb(skb)->hdr.seq);
				call->rx_first_oos = rxrpc_skb(skb)->hdr.seq;
			else
				call->rx_first_oos = 0;
			_debug("peek %p {%u}", skb, call->rx_first_oos);
@@ -522,7 +519,7 @@ static void rxrpc_insert_oos_packet(struct rxrpc_call *call,
	u32 seq;

	sp = rxrpc_skb(skb);
	seq = ntohl(sp->hdr.seq);
	seq = sp->hdr.seq;
	_enter(",,{%u}", seq);

	skb->destructor = rxrpc_packet_destructor;
@@ -535,9 +532,8 @@ static void rxrpc_insert_oos_packet(struct rxrpc_call *call,

	skb_queue_walk(&call->rx_oos_queue, p) {
		psp = rxrpc_skb(p);
		if (ntohl(psp->hdr.seq) > seq) {
			_debug("insert oos #%u before #%u",
			       seq, ntohl(psp->hdr.seq));
		if (psp->hdr.seq > seq) {
			_debug("insert oos #%u before #%u", seq, psp->hdr.seq);
			skb_insert(p, skb, &call->rx_oos_queue);
			goto inserted;
		}
@@ -586,7 +582,7 @@ static void rxrpc_zap_tx_window(struct rxrpc_call *call)

		skb = (struct sk_buff *) _skb;
		sp = rxrpc_skb(skb);
		_debug("+++ clear Tx %u", ntohl(sp->hdr.seq));
		_debug("+++ clear Tx %u", sp->hdr.seq);
		rxrpc_free_skb(skb);
	}

@@ -657,8 +653,7 @@ static int rxrpc_process_rx_queue(struct rxrpc_call *call,
		/* data packets that wind up here have been received out of
		 * order, need security processing or are jumbo packets */
	case RXRPC_PACKET_TYPE_DATA:
		_proto("OOSQ DATA %%%u { #%u }",
		       ntohl(sp->hdr.serial), ntohl(sp->hdr.seq));
		_proto("OOSQ DATA %%%u { #%u }", sp->hdr.serial, sp->hdr.seq);

		/* secured packets must be verified and possibly decrypted */
		if (rxrpc_verify_packet(call, skb, _abort_code) < 0)
@@ -676,7 +671,7 @@ static int rxrpc_process_rx_queue(struct rxrpc_call *call,
		if (!skb_pull(skb, sizeof(ack)))
			BUG();

		latest = ntohl(sp->hdr.serial);
		latest = sp->hdr.serial;
		hard = ntohl(ack.firstPacket);
		tx = atomic_read(&call->sequence);

@@ -881,9 +876,9 @@ void rxrpc_process_call(struct work_struct *work)
{
	struct rxrpc_call *call =
		container_of(work, struct rxrpc_call, processor);
	struct rxrpc_wire_header whdr;
	struct rxrpc_ackpacket ack;
	struct rxrpc_ackinfo ackinfo;
	struct rxrpc_header hdr;
	struct msghdr msg;
	struct kvec iov[5];
	enum rxrpc_call_event genbit;
@@ -891,7 +886,7 @@ void rxrpc_process_call(struct work_struct *work)
	__be32 data, pad;
	size_t len;
	int loop, nbit, ioc, ret, mtu;
	u32 abort_code = RX_PROTOCOL_ERROR;
	u32 serial, abort_code = RX_PROTOCOL_ERROR;
	u8 *acks = NULL;

	//printk("\n--------------------\n");
@@ -912,20 +907,20 @@ void rxrpc_process_call(struct work_struct *work)
	msg.msg_controllen = 0;
	msg.msg_flags	= 0;

	hdr.epoch	= call->conn->epoch;
	hdr.cid		= call->cid;
	hdr.callNumber	= call->call_id;
	hdr.seq		= 0;
	hdr.type	= RXRPC_PACKET_TYPE_ACK;
	hdr.flags	= call->conn->out_clientflag;
	hdr.userStatus	= 0;
	hdr.securityIndex = call->conn->security_ix;
	hdr._rsvd	= 0;
	hdr.serviceId	= call->conn->service_id;
	whdr.epoch	= htonl(call->conn->epoch);
	whdr.cid	= htonl(call->cid);
	whdr.callNumber	= htonl(call->call_id);
	whdr.seq	= 0;
	whdr.type	= RXRPC_PACKET_TYPE_ACK;
	whdr.flags	= call->conn->out_clientflag;
	whdr.userStatus	= 0;
	whdr.securityIndex = call->conn->security_ix;
	whdr._rsvd	= 0;
	whdr.serviceId	= htons(call->service_id);

	memset(iov, 0, sizeof(iov));
	iov[0].iov_base	= &hdr;
	iov[0].iov_len	= sizeof(hdr);
	iov[0].iov_base	= &whdr;
	iov[0].iov_len	= sizeof(whdr);

	/* deal with events of a final nature */
	if (test_bit(RXRPC_CALL_EV_RELEASE, &call->events)) {
@@ -966,7 +961,7 @@ void rxrpc_process_call(struct work_struct *work)
	}

	if (test_bit(RXRPC_CALL_EV_REJECT_BUSY, &call->events)) {
		hdr.type = RXRPC_PACKET_TYPE_BUSY;
		whdr.type = RXRPC_PACKET_TYPE_BUSY;
		genbit = RXRPC_CALL_EV_REJECT_BUSY;
		goto send_message;
	}
@@ -977,7 +972,7 @@ void rxrpc_process_call(struct work_struct *work)
		if (rxrpc_post_message(call, RXRPC_SKB_MARK_LOCAL_ERROR,
				       ECONNABORTED, true) < 0)
			goto no_mem;
		hdr.type = RXRPC_PACKET_TYPE_ABORT;
		whdr.type = RXRPC_PACKET_TYPE_ABORT;
		data = htonl(call->abort_code);
		iov[1].iov_base = &data;
		iov[1].iov_len = sizeof(data);
@@ -996,8 +991,8 @@ void rxrpc_process_call(struct work_struct *work)
		call->ackr_reason = 0;

		spin_lock_bh(&call->lock);
		ack.serial = call->ackr_serial;
		ack.previousPacket = call->ackr_prev_seq;
		ack.serial	= htonl(call->ackr_serial);
		ack.previousPacket = htonl(call->ackr_prev_seq);
		ack.firstPacket	= htonl(call->rx_data_eaten + 1);
		spin_unlock_bh(&call->lock);

@@ -1100,13 +1095,11 @@ void rxrpc_process_call(struct work_struct *work)
		//hdr.flags	= RXRPC_SLOW_START_OK;
		ack.bufferSpace	= htons(8);
		ack.maxSkew	= 0;
		ack.serial	= 0;
		ack.reason	= 0;

		spin_lock_bh(&call->lock);
		ack.reason	= call->ackr_reason;
		ack.serial = call->ackr_serial;
		ack.previousPacket = call->ackr_prev_seq;
		ack.serial	= htonl(call->ackr_serial);
		ack.previousPacket = htonl(call->ackr_prev_seq);
		ack.firstPacket = htonl(call->rx_data_eaten + 1);

		ack.nAcks = 0;
@@ -1225,9 +1218,10 @@ void rxrpc_process_call(struct work_struct *work)
	ackinfo.rxMTU	= htonl(rxrpc_rx_mtu);
	ackinfo.jumbo_max = htonl(rxrpc_rx_jumbo_max);

	hdr.serial = htonl(atomic_inc_return(&call->conn->serial));
	serial = atomic_inc_return(&call->conn->serial);
	whdr.serial = htonl(serial);
	_proto("Tx ACK %%%u { m=%hu f=#%u p=#%u s=%%%u r=%s n=%u }",
	       ntohl(hdr.serial),
	       serial,
	       ntohs(ack.maxSkew),
	       ntohl(ack.firstPacket),
	       ntohl(ack.previousPacket),
@@ -1243,8 +1237,9 @@ void rxrpc_process_call(struct work_struct *work)
send_message:
	_debug("send message");

	hdr.serial = htonl(atomic_inc_return(&call->conn->serial));
	_proto("Tx %s %%%u", rxrpc_pkts[hdr.type], ntohl(hdr.serial));
	serial = atomic_inc_return(&call->conn->serial);
	whdr.serial = htonl(serial);
	_proto("Tx %s %%%u", rxrpc_pkts[whdr.type], serial);
send_message_2:

	len = iov[0].iov_len;
@@ -1327,8 +1322,7 @@ void rxrpc_process_call(struct work_struct *work)
	if (call->state >= RXRPC_CALL_COMPLETE &&
	    !list_empty(&call->accept_link)) {
		_debug("X unlinking once-pending call %p { e=%lx f=%lx c=%x }",
		       call, call->events, call->flags,
		       ntohl(call->conn->cid));
		       call, call->events, call->flags, call->conn->cid);

		read_lock_bh(&call->state_lock);
		if (!test_bit(RXRPC_CALL_RELEASED, &call->flags) &&
@@ -1346,7 +1340,7 @@ void rxrpc_process_call(struct work_struct *work)
	 * this means there's a race between clearing the flag and setting the
	 * work pending bit and the work item being processed again */
	if (call->events && !work_pending(&call->processor)) {
		_debug("jumpstart %x", ntohl(call->conn->cid));
		_debug("jumpstart %x", call->conn->cid);
		rxrpc_queue_call(call);
	}

+32 −36
Original line number Diff line number Diff line
@@ -64,11 +64,11 @@ static DEFINE_HASHTABLE(rxrpc_call_hash, 10);
 * Hash function for rxrpc_call_hash
 */
static unsigned long rxrpc_call_hashfunc(
	u8		clientflag,
	__be32		cid,
	__be32		call_id,
	__be32		epoch,
	__be16		service_id,
	u8		in_clientflag,
	u32		cid,
	u32		call_id,
	u32		epoch,
	u16		service_id,
	sa_family_t	proto,
	void		*localptr,
	unsigned int	addr_size,
@@ -77,7 +77,6 @@ static unsigned long rxrpc_call_hashfunc(
	const u16 *p;
	unsigned int i;
	unsigned long key;
	u32 hcid = ntohl(cid);

	_enter("");

@@ -85,12 +84,12 @@ static unsigned long rxrpc_call_hashfunc(
	/* We just want to add up the __be32 values, so forcing the
	 * cast should be okay.
	 */
	key += (__force u32)epoch;
	key += (__force u16)service_id;
	key += (__force u32)call_id;
	key += (hcid & RXRPC_CIDMASK) >> RXRPC_CIDSHIFT;
	key += hcid & RXRPC_CHANNELMASK;
	key += clientflag;
	key += epoch;
	key += service_id;
	key += call_id;
	key += (cid & RXRPC_CIDMASK) >> RXRPC_CIDSHIFT;
	key += cid & RXRPC_CHANNELMASK;
	key += in_clientflag;
	key += proto;
	/* Step through the peer address in 16-bit portions for speed */
	for (i = 0, p = (const u16 *)peer_addr; i < addr_size >> 1; i++, p++)
@@ -148,19 +147,16 @@ static void rxrpc_call_hash_del(struct rxrpc_call *call)
 * isn't there.
 */
struct rxrpc_call *rxrpc_find_call_hash(
	u8		clientflag,
	__be32		cid,
	__be32		call_id,
	__be32		epoch,
	__be16		service_id,
	struct rxrpc_host_header *hdr,
	void		*localptr,
	sa_family_t	proto,
	const u8	*peer_addr)
	const void	*peer_addr)
{
	unsigned long key;
	unsigned int addr_size = 0;
	struct rxrpc_call *call = NULL;
	struct rxrpc_call *ret = NULL;
	u8 in_clientflag = hdr->flags & RXRPC_CLIENT_INITIATED;

	_enter("");
	switch (proto) {
@@ -174,20 +170,21 @@ struct rxrpc_call *rxrpc_find_call_hash(
		break;
	}

	key = rxrpc_call_hashfunc(clientflag, cid, call_id, epoch,
				  service_id, proto, localptr, addr_size,
	key = rxrpc_call_hashfunc(in_clientflag, hdr->cid, hdr->callNumber,
				  hdr->epoch, hdr->serviceId,
				  proto, localptr, addr_size,
				  peer_addr);
	hash_for_each_possible_rcu(rxrpc_call_hash, call, hash_node, key) {
		if (call->hash_key == key &&
		    call->call_id == call_id &&
		    call->cid == cid &&
		    call->in_clientflag == clientflag &&
		    call->service_id == service_id &&
		    call->call_id == hdr->callNumber &&
		    call->cid == hdr->cid &&
		    call->in_clientflag == in_clientflag &&
		    call->service_id == hdr->serviceId &&
		    call->proto == proto &&
		    call->local == localptr &&
		    memcmp(call->peer_ip.ipv6_addr, peer_addr,
			   addr_size) == 0 &&
		    call->epoch == epoch) {
		    call->epoch == hdr->epoch) {
			ret = call;
			break;
		}
@@ -414,12 +411,12 @@ struct rxrpc_call *rxrpc_get_client_call(struct rxrpc_sock *rx,
 */
struct rxrpc_call *rxrpc_incoming_call(struct rxrpc_sock *rx,
				       struct rxrpc_connection *conn,
				       struct rxrpc_header *hdr,
				       struct rxrpc_host_header *hdr,
				       gfp_t gfp)
{
	struct rxrpc_call *call, *candidate;
	struct rb_node **p, *parent;
	__be32 call_id;
	u32 call_id;

	_enter(",%d,,%x", conn->debug_id, gfp);

@@ -433,7 +430,7 @@ struct rxrpc_call *rxrpc_incoming_call(struct rxrpc_sock *rx,
	candidate->conn = conn;
	candidate->cid = hdr->cid;
	candidate->call_id = hdr->callNumber;
	candidate->channel = ntohl(hdr->cid) & RXRPC_CHANNELMASK;
	candidate->channel = hdr->cid & RXRPC_CHANNELMASK;
	candidate->rx_data_post = 0;
	candidate->state = RXRPC_CALL_SERVER_ACCEPTING;
	if (conn->security_ix > 0)
@@ -492,9 +489,9 @@ struct rxrpc_call *rxrpc_incoming_call(struct rxrpc_sock *rx,
		/* The tree is sorted in order of the __be32 value without
		 * turning it into host order.
		 */
		if ((__force u32)call_id < (__force u32)call->call_id)
		if (call_id < call->call_id)
			p = &(*p)->rb_left;
		else if ((__force u32)call_id > (__force u32)call->call_id)
		else if (call_id > call->call_id)
			p = &(*p)->rb_right;
		else
			goto old_call;
@@ -714,8 +711,7 @@ void rxrpc_release_call(struct rxrpc_call *call)

			_debug("- zap %s %%%u #%u",
			       rxrpc_pkts[sp->hdr.type],
			       ntohl(sp->hdr.serial),
			       ntohl(sp->hdr.seq));
			       sp->hdr.serial, sp->hdr.seq);
			rxrpc_free_skb(skb);
			spin_lock_bh(&call->lock);
		}
@@ -874,7 +870,7 @@ static void rxrpc_cleanup_call(struct rxrpc_call *call)

			_skb = call->acks_window[call->acks_tail] & ~1;
			sp = rxrpc_skb((struct sk_buff *)_skb);
			_debug("+++ clear Tx %u", ntohl(sp->hdr.seq));
			_debug("+++ clear Tx %u", sp->hdr.seq);
			rxrpc_free_skb((struct sk_buff *)_skb);
			call->acks_tail =
				(call->acks_tail + 1) & (call->acks_winsz - 1);
Loading