Skip to content

Commit 4b68137

Browse files
committed
rxrpc: Extract useful fields from a received ACK to skb priv data
Extract useful fields from a received ACK packet into the skb private data early on in the process of parsing incoming packets. This makes the ACK fields available even before we've matched the ACK up to a call and will allow us to deal with path MTU discovery probe responses even after the relevant call has been completed. Signed-off-by: David Howells <[email protected]> cc: Marc Dionne <[email protected]> cc: "David S. Miller" <[email protected]> cc: Eric Dumazet <[email protected]> cc: Jakub Kicinski <[email protected]> cc: Paolo Abeni <[email protected]> cc: [email protected] cc: [email protected]
1 parent 37473e4 commit 4b68137

File tree

4 files changed

+45
-38
lines changed

4 files changed

+45
-38
lines changed

net/rxrpc/ar-internal.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,8 @@ struct rxrpc_host_header {
198198
* - max 48 bytes (struct sk_buff::cb)
199199
*/
200200
struct rxrpc_skb_priv {
201-
struct rxrpc_connection *conn; /* Connection referred to (poke packet) */
202201
union {
202+
struct rxrpc_connection *conn; /* Connection referred to (poke packet) */
203203
struct {
204204
u16 offset; /* Offset of data */
205205
u16 len; /* Length of data */
@@ -208,9 +208,12 @@ struct rxrpc_skb_priv {
208208
};
209209
struct {
210210
rxrpc_seq_t first_ack; /* First packet in acks table */
211+
rxrpc_seq_t prev_ack; /* Highest seq seen */
212+
rxrpc_serial_t acked_serial; /* Packet in response to (or 0) */
213+
u8 reason; /* Reason for ack */
211214
u8 nr_acks; /* Number of acks+nacks */
212215
u8 nr_nacks; /* Number of nacks */
213-
};
216+
} ack;
214217
};
215218
struct rxrpc_host_header hdr; /* RxRPC packet header from this packet */
216219
};

net/rxrpc/call_event.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,12 @@ void rxrpc_resend(struct rxrpc_call *call, struct sk_buff *ack_skb)
9393
sp = rxrpc_skb(ack_skb);
9494
ack = (void *)ack_skb->data + sizeof(struct rxrpc_wire_header);
9595

96-
for (i = 0; i < sp->nr_acks; i++) {
96+
for (i = 0; i < sp->ack.nr_acks; i++) {
9797
rxrpc_seq_t seq;
9898

9999
if (ack->acks[i] & 1)
100100
continue;
101-
seq = sp->first_ack + i;
101+
seq = sp->ack.first_ack + i;
102102
if (after(txb->seq, transmitted))
103103
break;
104104
if (after(txb->seq, seq))

net/rxrpc/input.c

Lines changed: 27 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -710,20 +710,19 @@ static rxrpc_seq_t rxrpc_input_check_prev_ack(struct rxrpc_call *call,
710710
rxrpc_seq_t seq)
711711
{
712712
struct sk_buff *skb = call->cong_last_nack;
713-
struct rxrpc_ackpacket ack;
714713
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
715714
unsigned int i, new_acks = 0, retained_nacks = 0;
716-
rxrpc_seq_t old_seq = sp->first_ack;
717-
u8 *acks = skb->data + sizeof(struct rxrpc_wire_header) + sizeof(ack);
715+
rxrpc_seq_t old_seq = sp->ack.first_ack;
716+
u8 *acks = skb->data + sizeof(struct rxrpc_wire_header) + sizeof(struct rxrpc_ackpacket);
718717

719-
if (after_eq(seq, old_seq + sp->nr_acks)) {
720-
summary->nr_new_acks += sp->nr_nacks;
721-
summary->nr_new_acks += seq - (old_seq + sp->nr_acks);
718+
if (after_eq(seq, old_seq + sp->ack.nr_acks)) {
719+
summary->nr_new_acks += sp->ack.nr_nacks;
720+
summary->nr_new_acks += seq - (old_seq + sp->ack.nr_acks);
722721
summary->nr_retained_nacks = 0;
723722
} else if (seq == old_seq) {
724-
summary->nr_retained_nacks = sp->nr_nacks;
723+
summary->nr_retained_nacks = sp->ack.nr_nacks;
725724
} else {
726-
for (i = 0; i < sp->nr_acks; i++) {
725+
for (i = 0; i < sp->ack.nr_acks; i++) {
727726
if (acks[i] == RXRPC_ACK_TYPE_NACK) {
728727
if (before(old_seq + i, seq))
729728
new_acks++;
@@ -736,7 +735,7 @@ static rxrpc_seq_t rxrpc_input_check_prev_ack(struct rxrpc_call *call,
736735
summary->nr_retained_nacks = retained_nacks;
737736
}
738737

739-
return old_seq + sp->nr_acks;
738+
return old_seq + sp->ack.nr_acks;
740739
}
741740

742741
/*
@@ -756,10 +755,10 @@ static void rxrpc_input_soft_acks(struct rxrpc_call *call,
756755
{
757756
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
758757
unsigned int i, old_nacks = 0;
759-
rxrpc_seq_t lowest_nak = seq + sp->nr_acks;
758+
rxrpc_seq_t lowest_nak = seq + sp->ack.nr_acks;
760759
u8 *acks = skb->data + sizeof(struct rxrpc_wire_header) + sizeof(struct rxrpc_ackpacket);
761760

762-
for (i = 0; i < sp->nr_acks; i++) {
761+
for (i = 0; i < sp->ack.nr_acks; i++) {
763762
if (acks[i] == RXRPC_ACK_TYPE_ACK) {
764763
summary->nr_acks++;
765764
if (after_eq(seq, since))
@@ -771,7 +770,7 @@ static void rxrpc_input_soft_acks(struct rxrpc_call *call,
771770
old_nacks++;
772771
} else {
773772
summary->nr_new_nacks++;
774-
sp->nr_nacks++;
773+
sp->ack.nr_nacks++;
775774
}
776775

777776
if (before(seq, lowest_nak))
@@ -832,7 +831,6 @@ static bool rxrpc_is_ack_valid(struct rxrpc_call *call,
832831
static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb)
833832
{
834833
struct rxrpc_ack_summary summary = { 0 };
835-
struct rxrpc_ackpacket ack;
836834
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
837835
struct rxrpc_acktrailer trailer;
838836
rxrpc_serial_t ack_serial, acked_serial;
@@ -841,29 +839,24 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb)
841839

842840
_enter("");
843841

844-
offset = sizeof(struct rxrpc_wire_header);
845-
if (skb_copy_bits(skb, offset, &ack, sizeof(ack)) < 0)
846-
return rxrpc_proto_abort(call, 0, rxrpc_badmsg_short_ack);
847-
offset += sizeof(ack);
848-
849-
ack_serial = sp->hdr.serial;
850-
acked_serial = ntohl(ack.serial);
851-
first_soft_ack = ntohl(ack.firstPacket);
852-
prev_pkt = ntohl(ack.previousPacket);
853-
hard_ack = first_soft_ack - 1;
854-
nr_acks = ack.nAcks;
855-
sp->first_ack = first_soft_ack;
856-
sp->nr_acks = nr_acks;
857-
summary.ack_reason = (ack.reason < RXRPC_ACK__INVALID ?
858-
ack.reason : RXRPC_ACK__INVALID);
842+
offset = sizeof(struct rxrpc_wire_header) + sizeof(struct rxrpc_ackpacket);
843+
844+
ack_serial = sp->hdr.serial;
845+
acked_serial = sp->ack.acked_serial;
846+
first_soft_ack = sp->ack.first_ack;
847+
prev_pkt = sp->ack.prev_ack;
848+
nr_acks = sp->ack.nr_acks;
849+
hard_ack = first_soft_ack - 1;
850+
summary.ack_reason = (sp->ack.reason < RXRPC_ACK__INVALID ?
851+
sp->ack.reason : RXRPC_ACK__INVALID);
859852

860853
trace_rxrpc_rx_ack(call, ack_serial, acked_serial,
861854
first_soft_ack, prev_pkt,
862855
summary.ack_reason, nr_acks);
863-
rxrpc_inc_stat(call->rxnet, stat_rx_acks[ack.reason]);
856+
rxrpc_inc_stat(call->rxnet, stat_rx_acks[summary.ack_reason]);
864857

865858
if (acked_serial != 0) {
866-
switch (ack.reason) {
859+
switch (summary.ack_reason) {
867860
case RXRPC_ACK_PING_RESPONSE:
868861
rxrpc_complete_rtt_probe(call, skb->tstamp, acked_serial, ack_serial,
869862
rxrpc_rtt_rx_ping_response);
@@ -883,7 +876,7 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb)
883876
* indicates that the client address changed due to NAT. The server
884877
* lost the call because it switched to a different peer.
885878
*/
886-
if (unlikely(ack.reason == RXRPC_ACK_EXCEEDS_WINDOW) &&
879+
if (unlikely(summary.ack_reason == RXRPC_ACK_EXCEEDS_WINDOW) &&
887880
first_soft_ack == 1 &&
888881
prev_pkt == 0 &&
889882
rxrpc_is_client_call(call)) {
@@ -896,7 +889,7 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb)
896889
* indicate a change of address. However, we can retransmit the call
897890
* if we still have it buffered to the beginning.
898891
*/
899-
if (unlikely(ack.reason == RXRPC_ACK_OUT_OF_SEQUENCE) &&
892+
if (unlikely(summary.ack_reason == RXRPC_ACK_OUT_OF_SEQUENCE) &&
900893
first_soft_ack == 1 &&
901894
prev_pkt == 0 &&
902895
call->acks_hard_ack == 0 &&
@@ -937,7 +930,7 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb)
937930
call->acks_first_seq = first_soft_ack;
938931
call->acks_prev_seq = prev_pkt;
939932

940-
switch (ack.reason) {
933+
switch (summary.ack_reason) {
941934
case RXRPC_ACK_PING:
942935
break;
943936
default:
@@ -994,7 +987,7 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb)
994987
rxrpc_congestion_management(call, skb, &summary, acked_serial);
995988

996989
send_response:
997-
if (ack.reason == RXRPC_ACK_PING)
990+
if (summary.ack_reason == RXRPC_ACK_PING)
998991
rxrpc_send_ACK(call, RXRPC_ACK_PING_RESPONSE, ack_serial,
999992
rxrpc_propose_ack_respond_to_ping);
1000993
else if (sp->hdr.flags & RXRPC_REQUEST_ACK)

net/rxrpc/io_thread.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ static bool rxrpc_extract_header(struct rxrpc_skb_priv *sp,
124124
struct sk_buff *skb)
125125
{
126126
struct rxrpc_wire_header whdr;
127+
struct rxrpc_ackpacket ack;
127128

128129
/* dig out the RxRPC connection details */
129130
if (skb_copy_bits(skb, 0, &whdr, sizeof(whdr)) < 0)
@@ -141,6 +142,16 @@ static bool rxrpc_extract_header(struct rxrpc_skb_priv *sp,
141142
sp->hdr.securityIndex = whdr.securityIndex;
142143
sp->hdr._rsvd = ntohs(whdr._rsvd);
143144
sp->hdr.serviceId = ntohs(whdr.serviceId);
145+
146+
if (sp->hdr.type == RXRPC_PACKET_TYPE_ACK) {
147+
if (skb_copy_bits(skb, sizeof(whdr), &ack, sizeof(ack)) < 0)
148+
return rxrpc_bad_message(skb, rxrpc_badmsg_short_ack);
149+
sp->ack.first_ack = ntohl(ack.firstPacket);
150+
sp->ack.prev_ack = ntohl(ack.previousPacket);
151+
sp->ack.acked_serial = ntohl(ack.serial);
152+
sp->ack.reason = ack.reason;
153+
sp->ack.nr_acks = ack.nAcks;
154+
}
144155
return true;
145156
}
146157

0 commit comments

Comments
 (0)