LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
From: David Howells <dhowells@redhat.com>
To: Jeffrey E Altman <jaltman@auristor.com>,
	Marc Dionne <marc.dionne@auristor.com>
Cc: dhowells@redhat.com, Benjamin Kaduk <kaduk@mit.edu>,
	linux-afs@lists.infradead.org, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: [RFC][PATCH] rxrpc: Support reception of extended-SACK ACK packet
Date: Fri, 06 Aug 2021 11:08:54 +0100	[thread overview]
Message-ID: <1290708.1628244534@warthog.procyon.org.uk> (raw)

    
The RxRPC ACK packet supports selective ACK of up to 255 DATA packets.  It
contains a variable length array with one octet allocated for each DATA
packet to be ACK'd.  Each octet is either 0 or 1 depending on whether it is
a negative or positive ACK.  7 bits in each octet are effectively unused
and, further, there are three reserved octets following the ACK array that
are all set to 0.

To extend the ACK window up to 2048 ACKs, it is proposed[1]:

 (1) that the ACKs for DATA packets first+0...first+254 in the Rx window
     are in bit 0 of the octets in the array, ie. acks[0...254], pretty
     much as now; and

 (2) that if the ACK count is >=256, the first reserved byte after the ACK
     table is annexed to the ACK table as acks[255] and contains the ACK
     for packet first+255 in bit 0; and

 (3) that if the ACK count is >256, horizontal striping be employed such
     that the ACK for packet first+256 in the window is then in bit 1 of
     acks[0], first+257 is in bit 1 of acks[1], up to first+511 being in
     bit 1 of the borrowed reserved byte (ie. acks[255]).

     first+512 is then in bit 2 of acks[0], going all the way up to
     first+2048 being in bit 7 of acks[255].

If extended SACK is employed in an ACK packet, it should have EXTENDED-SACK
(0x08) set in the RxRPC packet header.

Alter rxrpc_input_ack() to sanity check the ACK count.

Alter rxrpc_input_ack() to limit the number of bytes it extracts from the
packet for the ack array to 256.

Alter rxrpc_input_soft_acks() to handle an extended SACK table.

Signed-off-by: David Howells <dhowells@redhat.com>
Link: https://gerrit.openafs.org/#/c/14693/3 [1]
---
 net/rxrpc/input.c    |   21 ++++++++++++++-------
 net/rxrpc/protocol.h |    7 +++++--
 2 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c
index dc201363f2c4..0a7f7462b617 100644
--- a/net/rxrpc/input.c
+++ b/net/rxrpc/input.c
@@ -767,15 +767,17 @@ static void rxrpc_input_soft_acks(struct rxrpc_call *call, u8 *acks,
 				  rxrpc_seq_t seq, int nr_acks,
 				  struct rxrpc_ack_summary *summary)
 {
-	int ix;
-	u8 annotation, anno_type;
+	int ix, i;
+	u8 annotation, anno_type, ack;
 
-	for (; nr_acks > 0; nr_acks--, seq++) {
+	for (i = 0; i < nr_acks; i++, seq++) {
 		ix = seq & RXRPC_RXTX_BUFF_MASK;
 		annotation = call->rxtx_annotations[ix];
 		anno_type = annotation & RXRPC_TX_ANNO_MASK;
 		annotation &= ~RXRPC_TX_ANNO_MASK;
-		switch (*acks++) {
+		ack = acks[i % RXRPC_EXTENDED_SACK_SIZE];
+		ack >>= i / RXRPC_EXTENDED_SACK_SIZE;
+		switch (ack) {
 		case RXRPC_ACK_TYPE_ACK:
 			summary->nr_acks++;
 			if (anno_type == RXRPC_TX_ANNO_ACK)
@@ -846,7 +848,7 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb)
 	union {
 		struct rxrpc_ackpacket ack;
 		struct rxrpc_ackinfo info;
-		u8 acks[RXRPC_MAXACKS];
+		u8 acks[RXRPC_EXTENDED_SACK_SIZE];
 	} buf;
 	rxrpc_serial_t ack_serial, acked_serial;
 	rxrpc_seq_t first_soft_ack, hard_ack, prev_pkt;
@@ -874,6 +876,10 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb)
 			   first_soft_ack, prev_pkt,
 			   summary.ack_reason, nr_acks);
 
+	if ((nr_acks > RXRPC_MAXACKS && !(sp->hdr.flags & RXRPC_EXTENDED_SACK)) ||
+	    (nr_acks > RXRPC_MAXACKS_EXTENDED))
+		return rxrpc_proto_abort("AKC", call, 0);
+	
 	switch (buf.ack.reason) {
 	case RXRPC_ACK_PING_RESPONSE:
 		rxrpc_input_ping_response(call, skb->tstamp, acked_serial,
@@ -912,7 +918,7 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb)
 	}
 
 	buf.info.rxMTU = 0;
-	ioffset = offset + nr_acks + 3;
+	ioffset = offset + min(nr_acks, RXRPC_MAXACKS) + 3;
 	if (skb->len >= ioffset + sizeof(buf.info) &&
 	    skb_copy_bits(skb, ioffset, &buf.info, sizeof(buf.info)) < 0)
 		return rxrpc_proto_abort("XAI", call, 0);
@@ -969,7 +975,8 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb)
 	}
 
 	if (nr_acks > 0) {
-		if (skb_copy_bits(skb, offset, buf.acks, nr_acks) < 0) {
+		if (skb_copy_bits(skb, offset, buf.acks,
+				  min_t(unsigned int, nr_acks, sizeof(buf.acks))) < 0) {
 			rxrpc_proto_abort("XSA", call, 0);
 			goto out;
 		}
diff --git a/net/rxrpc/protocol.h b/net/rxrpc/protocol.h
index 49bb972539aa..287986012cd9 100644
--- a/net/rxrpc/protocol.h
+++ b/net/rxrpc/protocol.h
@@ -51,7 +51,8 @@ struct rxrpc_wire_header {
 #define RXRPC_CLIENT_INITIATED	0x01		/* signifies a packet generated by a client */
 #define RXRPC_REQUEST_ACK	0x02		/* request an unconditional ACK of this packet */
 #define RXRPC_LAST_PACKET	0x04		/* the last packet from this side for this call */
-#define RXRPC_MORE_PACKETS	0x08		/* more packets to come */
+#define RXRPC_MORE_PACKETS	0x08		/* [DATA] More packets to come */
+#define RXRPC_EXTENDED_SACK	0x08		/* [ACK] Extended SACK table */
 #define RXRPC_JUMBO_PACKET	0x20		/* [DATA] this is a jumbo packet */
 #define RXRPC_SLOW_START_OK	0x20		/* [ACK] slow start supported */
 
@@ -124,7 +125,9 @@ struct rxrpc_ackpacket {
 #define RXRPC_ACK__INVALID		10	/* Representation of invalid ACK reason */
 
 	uint8_t		nAcks;		/* number of ACKs */
-#define RXRPC_MAXACKS	255
+#define RXRPC_MAXACKS	255		/* Normal maximum number of ACKs */
+#define RXRPC_EXTENDED_SACK_SIZE 256	/* Size of the extended SACK table */
+#define RXRPC_MAXACKS_EXTENDED	2048	/* Maximum number of ACKs in extended SACK table */
 
 	uint8_t		acks[0];	/* list of ACK/NAKs */
 #define RXRPC_ACK_TYPE_NACK		0


             reply	other threads:[~2021-08-06 10:09 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-06 10:08 David Howells [this message]
2021-08-06 13:45 ` [RFC][PATCH] rxrpc: Support reception of extended-SACK ACK packet Jeffrey E Altman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1290708.1628244534@warthog.procyon.org.uk \
    --to=dhowells@redhat.com \
    --cc=jaltman@auristor.com \
    --cc=kaduk@mit.edu \
    --cc=linux-afs@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=marc.dionne@auristor.com \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).