aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv4/tcp_input.c32
1 files changed, 17 insertions, 15 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index ca46eb9151f8..3c8e297e2c39 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1289,7 +1289,8 @@ static int tcp_match_skb_to_sack(struct sock *sk, struct sk_buff *skb,
1289} 1289}
1290 1290
1291static int tcp_sacktag_one(struct sk_buff *skb, struct sock *sk, 1291static int tcp_sacktag_one(struct sk_buff *skb, struct sock *sk,
1292 int *reord, int dup_sack, int fack_count) 1292 int *reord, int dup_sack, int fack_count,
1293 u8 *sackedto, int pcount)
1293{ 1294{
1294 struct tcp_sock *tp = tcp_sk(sk); 1295 struct tcp_sock *tp = tcp_sk(sk);
1295 u8 sacked = TCP_SKB_CB(skb)->sacked; 1296 u8 sacked = TCP_SKB_CB(skb)->sacked;
@@ -1314,10 +1315,9 @@ static int tcp_sacktag_one(struct sk_buff *skb, struct sock *sk,
1314 * that retransmission is still in flight. 1315 * that retransmission is still in flight.
1315 */ 1316 */
1316 if (sacked & TCPCB_LOST) { 1317 if (sacked & TCPCB_LOST) {
1317 TCP_SKB_CB(skb)->sacked &= 1318 *sackedto &= ~(TCPCB_LOST|TCPCB_SACKED_RETRANS);
1318 ~(TCPCB_LOST|TCPCB_SACKED_RETRANS); 1319 tp->lost_out -= pcount;
1319 tp->lost_out -= tcp_skb_pcount(skb); 1320 tp->retrans_out -= pcount;
1320 tp->retrans_out -= tcp_skb_pcount(skb);
1321 } 1321 }
1322 } else { 1322 } else {
1323 if (!(sacked & TCPCB_RETRANS)) { 1323 if (!(sacked & TCPCB_RETRANS)) {
@@ -1334,22 +1334,22 @@ static int tcp_sacktag_one(struct sk_buff *skb, struct sock *sk,
1334 } 1334 }
1335 1335
1336 if (sacked & TCPCB_LOST) { 1336 if (sacked & TCPCB_LOST) {
1337 TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST; 1337 *sackedto &= ~TCPCB_LOST;
1338 tp->lost_out -= tcp_skb_pcount(skb); 1338 tp->lost_out -= pcount;
1339 } 1339 }
1340 } 1340 }
1341 1341
1342 TCP_SKB_CB(skb)->sacked |= TCPCB_SACKED_ACKED; 1342 *sackedto |= TCPCB_SACKED_ACKED;
1343 flag |= FLAG_DATA_SACKED; 1343 flag |= FLAG_DATA_SACKED;
1344 tp->sacked_out += tcp_skb_pcount(skb); 1344 tp->sacked_out += pcount;
1345 1345
1346 fack_count += tcp_skb_pcount(skb); 1346 fack_count += pcount;
1347 1347
1348 /* Lost marker hint past SACKed? Tweak RFC3517 cnt */ 1348 /* Lost marker hint past SACKed? Tweak RFC3517 cnt */
1349 if (!tcp_is_fack(tp) && (tp->lost_skb_hint != NULL) && 1349 if (!tcp_is_fack(tp) && (tp->lost_skb_hint != NULL) &&
1350 before(TCP_SKB_CB(skb)->seq, 1350 before(TCP_SKB_CB(skb)->seq,
1351 TCP_SKB_CB(tp->lost_skb_hint)->seq)) 1351 TCP_SKB_CB(tp->lost_skb_hint)->seq))
1352 tp->lost_cnt_hint += tcp_skb_pcount(skb); 1352 tp->lost_cnt_hint += pcount;
1353 1353
1354 if (fack_count > tp->fackets_out) 1354 if (fack_count > tp->fackets_out)
1355 tp->fackets_out = fack_count; 1355 tp->fackets_out = fack_count;
@@ -1362,9 +1362,9 @@ static int tcp_sacktag_one(struct sk_buff *skb, struct sock *sk,
1362 * frames and clear it. undo_retrans is decreased above, L|R frames 1362 * frames and clear it. undo_retrans is decreased above, L|R frames
1363 * are accounted above as well. 1363 * are accounted above as well.
1364 */ 1364 */
1365 if (dup_sack && (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS)) { 1365 if (dup_sack && (*sackedto & TCPCB_SACKED_RETRANS)) {
1366 TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS; 1366 *sackedto &= ~TCPCB_SACKED_RETRANS;
1367 tp->retrans_out -= tcp_skb_pcount(skb); 1367 tp->retrans_out -= pcount;
1368 } 1368 }
1369 1369
1370 return flag; 1370 return flag;
@@ -1404,7 +1404,9 @@ static struct sk_buff *tcp_sacktag_walk(struct sk_buff *skb, struct sock *sk,
1404 1404
1405 if (in_sack) 1405 if (in_sack)
1406 *flag |= tcp_sacktag_one(skb, sk, reord, dup_sack, 1406 *flag |= tcp_sacktag_one(skb, sk, reord, dup_sack,
1407 *fack_count); 1407 *fack_count,
1408 &(TCP_SKB_CB(skb)->sacked),
1409 tcp_skb_pcount(skb));
1408 1410
1409 *fack_count += tcp_skb_pcount(skb); 1411 *fack_count += tcp_skb_pcount(skb);
1410 } 1412 }