rxrpc: Improve jumbo packet counting
authorDavid Howells <dhowells@redhat.com>
Mon, 19 Aug 2019 08:25:37 +0000 (09:25 +0100)
committerDavid Howells <dhowells@redhat.com>
Tue, 27 Aug 2019 08:48:37 +0000 (09:48 +0100)
Improve the information stored about jumbo packets so that we don't need to
reparse them so much later.

Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Jeffrey Altman <jaltman@auristor.com>
net/rxrpc/ar-internal.h
net/rxrpc/input.c
net/rxrpc/protocol.h

index 145335611af66b1e6fcd261cc532be0a72aaa6ae..87cff6c218b6cd498bb98074942a283f2844ef0c 100644 (file)
@@ -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 */
index dd47d465d1d3e7de3bcf72dc76611621bb2c0e6a..ffcec5117954da66661d7f3fe3bc237306418bec 100644 (file)
@@ -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;
 
index 99ce322d7caa0369ecd8905a0de53aac6b4a8909..49bb972539aa1c7534430f5d5362277ea203ddc2 100644 (file)
@@ -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