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

Commit c3c9e3df authored by David Howells's avatar David Howells
Browse files

rxrpc: Improve jumbo packet counting



Improve the information stored about jumbo packets so that we don't need to
reparse them so much later.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Reviewed-by: default avatarJeffrey Altman <jaltman@auristor.com>
parent cfef46d6
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -185,11 +185,15 @@ struct rxrpc_host_header {
 * - max 48 bytes (struct sk_buff::cb)
 */
struct rxrpc_skb_priv {
	union {
		u8		nr_jumbo;	/* Number of jumbo subpackets */
	};
	u8		nr_subpackets;		/* Number of subpackets */
	u8		rx_flags;		/* Received packet flags */
#define RXRPC_SKB_INCL_LAST	0x01		/* - Includes last packet */
	union {
		int		remain;		/* amount of space remaining for next write */

		/* List of requested ACKs on subpackets */
		unsigned long	rx_req_ack[(RXRPC_MAX_NR_JUMBO + BITS_PER_LONG - 1) /
					   BITS_PER_LONG];
	};

	struct rxrpc_host_header hdr;		/* RxRPC packet header from this packet */
+14 −9
Original line number Diff line number Diff line
@@ -347,7 +347,7 @@ static bool rxrpc_receiving_reply(struct rxrpc_call *call)
}

/*
 * Scan a jumbo packet to validate its structure and to work out how many
 * Scan a data packet to validate its structure and to work out how many
 * subpackets it contains.
 *
 * A jumbo packet is a collection of consecutive packets glued together with
@@ -358,16 +358,21 @@ static bool rxrpc_receiving_reply(struct rxrpc_call *call)
 * the last are RXRPC_JUMBO_DATALEN in size.  The last subpacket may be of any
 * size.
 */
static bool rxrpc_validate_jumbo(struct sk_buff *skb)
static bool rxrpc_validate_data(struct sk_buff *skb)
{
	struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
	unsigned int offset = sizeof(struct rxrpc_wire_header);
	unsigned int len = skb->len;
	int nr_jumbo = 1;
	u8 flags = sp->hdr.flags;

	do {
		nr_jumbo++;
	for (;;) {
		if (flags & RXRPC_REQUEST_ACK)
			__set_bit(sp->nr_subpackets, sp->rx_req_ack);
		sp->nr_subpackets++;

		if (!(flags & RXRPC_JUMBO_PACKET))
			break;

		if (len - offset < RXRPC_JUMBO_SUBPKTLEN)
			goto protocol_error;
		if (flags & RXRPC_LAST_PACKET)
@@ -376,9 +381,10 @@ static bool rxrpc_validate_jumbo(struct sk_buff *skb)
		if (skb_copy_bits(skb, offset, &flags, 1) < 0)
			goto protocol_error;
		offset += sizeof(struct rxrpc_jumbo_header);
	} while (flags & RXRPC_JUMBO_PACKET);
	}

	sp->nr_jumbo = nr_jumbo;
	if (flags & RXRPC_LAST_PACKET)
		sp->rx_flags |= RXRPC_SKB_INCL_LAST;
	return true;

protocol_error:
@@ -1237,8 +1243,7 @@ int rxrpc_input_packet(struct sock *udp_sk, struct sk_buff *skb)
		if (sp->hdr.callNumber == 0 ||
		    sp->hdr.seq == 0)
			goto bad_message;
		if (sp->hdr.flags & RXRPC_JUMBO_PACKET &&
		    !rxrpc_validate_jumbo(skb))
		if (!rxrpc_validate_data(skb))
			goto bad_message;
		break;

+9 −0
Original line number Diff line number Diff line
@@ -89,6 +89,15 @@ struct rxrpc_jumbo_header {
#define RXRPC_JUMBO_DATALEN	1412	/* non-terminal jumbo packet data length */
#define RXRPC_JUMBO_SUBPKTLEN	(RXRPC_JUMBO_DATALEN + sizeof(struct rxrpc_jumbo_header))

/*
 * The maximum number of subpackets that can possibly fit in a UDP packet is:
 *
 *	((max_IP - IP_hdr - UDP_hdr) / RXRPC_JUMBO_SUBPKTLEN) + 1
 *	= ((65535 - 28 - 28) / 1416) + 1
 *	= 46 non-terminal packets and 1 terminal packet.
 */
#define RXRPC_MAX_NR_JUMBO	47

/*****************************************************************************/
/*
 * on-the-wire Rx ACK packet data payload