Commit c3c9e3df authored by David Howells's avatar David Howells

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
...@@ -185,11 +185,15 @@ struct rxrpc_host_header { ...@@ -185,11 +185,15 @@ struct rxrpc_host_header {
* - max 48 bytes (struct sk_buff::cb) * - max 48 bytes (struct sk_buff::cb)
*/ */
struct rxrpc_skb_priv { struct rxrpc_skb_priv {
union { u8 nr_subpackets; /* Number of subpackets */
u8 nr_jumbo; /* Number of jumbo subpackets */ u8 rx_flags; /* Received packet flags */
}; #define RXRPC_SKB_INCL_LAST 0x01 /* - Includes last packet */
union { union {
int remain; /* amount of space remaining for next write */ 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 */ struct rxrpc_host_header hdr; /* RxRPC packet header from this packet */
......
...@@ -347,7 +347,7 @@ static bool rxrpc_receiving_reply(struct rxrpc_call *call) ...@@ -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. * subpackets it contains.
* *
* A jumbo packet is a collection of consecutive packets glued together with * 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) ...@@ -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 * the last are RXRPC_JUMBO_DATALEN in size. The last subpacket may be of any
* size. * 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); struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
unsigned int offset = sizeof(struct rxrpc_wire_header); unsigned int offset = sizeof(struct rxrpc_wire_header);
unsigned int len = skb->len; unsigned int len = skb->len;
int nr_jumbo = 1;
u8 flags = sp->hdr.flags; u8 flags = sp->hdr.flags;
do { for (;;) {
nr_jumbo++; 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) if (len - offset < RXRPC_JUMBO_SUBPKTLEN)
goto protocol_error; goto protocol_error;
if (flags & RXRPC_LAST_PACKET) if (flags & RXRPC_LAST_PACKET)
...@@ -376,9 +381,10 @@ static bool rxrpc_validate_jumbo(struct sk_buff *skb) ...@@ -376,9 +381,10 @@ static bool rxrpc_validate_jumbo(struct sk_buff *skb)
if (skb_copy_bits(skb, offset, &flags, 1) < 0) if (skb_copy_bits(skb, offset, &flags, 1) < 0)
goto protocol_error; goto protocol_error;
offset += sizeof(struct rxrpc_jumbo_header); 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; return true;
protocol_error: protocol_error:
...@@ -1237,8 +1243,7 @@ int rxrpc_input_packet(struct sock *udp_sk, struct sk_buff *skb) ...@@ -1237,8 +1243,7 @@ int rxrpc_input_packet(struct sock *udp_sk, struct sk_buff *skb)
if (sp->hdr.callNumber == 0 || if (sp->hdr.callNumber == 0 ||
sp->hdr.seq == 0) sp->hdr.seq == 0)
goto bad_message; goto bad_message;
if (sp->hdr.flags & RXRPC_JUMBO_PACKET && if (!rxrpc_validate_data(skb))
!rxrpc_validate_jumbo(skb))
goto bad_message; goto bad_message;
break; break;
......
...@@ -89,6 +89,15 @@ struct rxrpc_jumbo_header { ...@@ -89,6 +89,15 @@ struct rxrpc_jumbo_header {
#define RXRPC_JUMBO_DATALEN 1412 /* non-terminal jumbo packet data length */ #define RXRPC_JUMBO_DATALEN 1412 /* non-terminal jumbo packet data length */
#define RXRPC_JUMBO_SUBPKTLEN (RXRPC_JUMBO_DATALEN + sizeof(struct rxrpc_jumbo_header)) #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 * on-the-wire Rx ACK packet data payload
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment