aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/tcp.h1
-rw-r--r--include/net/tcp.h1
-rw-r--r--net/ipv4/tcp_input.c15
-rw-r--r--net/ipv4/tcp_minisocks.c3
-rw-r--r--net/ipv4/tcp_output.c12
5 files changed, 9 insertions, 23 deletions
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 0cd99e6baca5..4b86ad71e054 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -218,7 +218,6 @@ struct tcp_options_received {
218 snd_wscale : 4, /* Window scaling received from sender */ 218 snd_wscale : 4, /* Window scaling received from sender */
219 rcv_wscale : 4; /* Window scaling to send to receiver */ 219 rcv_wscale : 4; /* Window scaling to send to receiver */
220/* SACKs data */ 220/* SACKs data */
221 u8 eff_sacks; /* Size of SACK array to send with next packet */
222 u8 num_sacks; /* Number of SACK blocks */ 221 u8 num_sacks; /* Number of SACK blocks */
223 u16 user_mss; /* mss requested by user in ioctl */ 222 u16 user_mss; /* mss requested by user in ioctl */
224 u16 mss_clamp; /* Maximal mss, negotiated at connection setup */ 223 u16 mss_clamp; /* Maximal mss, negotiated at connection setup */
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 0366a559afec..055e4946d4c8 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -926,7 +926,6 @@ extern void tcp_done(struct sock *sk);
926static inline void tcp_sack_reset(struct tcp_options_received *rx_opt) 926static inline void tcp_sack_reset(struct tcp_options_received *rx_opt)
927{ 927{
928 rx_opt->dsack = 0; 928 rx_opt->dsack = 0;
929 rx_opt->eff_sacks = 0;
930 rx_opt->num_sacks = 0; 929 rx_opt->num_sacks = 0;
931} 930}
932 931
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 03f5ede87224..e4442a293eb0 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4099,7 +4099,6 @@ static void tcp_dsack_set(struct sock *sk, u32 seq, u32 end_seq)
4099 tp->rx_opt.dsack = 1; 4099 tp->rx_opt.dsack = 1;
4100 tp->duplicate_sack[0].start_seq = seq; 4100 tp->duplicate_sack[0].start_seq = seq;
4101 tp->duplicate_sack[0].end_seq = end_seq; 4101 tp->duplicate_sack[0].end_seq = end_seq;
4102 tp->rx_opt.eff_sacks = tp->rx_opt.num_sacks + 1;
4103 } 4102 }
4104} 4103}
4105 4104
@@ -4154,8 +4153,6 @@ static void tcp_sack_maybe_coalesce(struct tcp_sock *tp)
4154 * Decrease num_sacks. 4153 * Decrease num_sacks.
4155 */ 4154 */
4156 tp->rx_opt.num_sacks--; 4155 tp->rx_opt.num_sacks--;
4157 tp->rx_opt.eff_sacks = tp->rx_opt.num_sacks +
4158 tp->rx_opt.dsack;
4159 for (i = this_sack; i < tp->rx_opt.num_sacks; i++) 4156 for (i = this_sack; i < tp->rx_opt.num_sacks; i++)
4160 sp[i] = sp[i + 1]; 4157 sp[i] = sp[i + 1];
4161 continue; 4158 continue;
@@ -4218,7 +4215,6 @@ new_sack:
4218 sp->start_seq = seq; 4215 sp->start_seq = seq;
4219 sp->end_seq = end_seq; 4216 sp->end_seq = end_seq;
4220 tp->rx_opt.num_sacks++; 4217 tp->rx_opt.num_sacks++;
4221 tp->rx_opt.eff_sacks = tp->rx_opt.num_sacks + tp->rx_opt.dsack;
4222} 4218}
4223 4219
4224/* RCV.NXT advances, some SACKs should be eaten. */ 4220/* RCV.NXT advances, some SACKs should be eaten. */
@@ -4232,7 +4228,6 @@ static void tcp_sack_remove(struct tcp_sock *tp)
4232 /* Empty ofo queue, hence, all the SACKs are eaten. Clear. */ 4228 /* Empty ofo queue, hence, all the SACKs are eaten. Clear. */
4233 if (skb_queue_empty(&tp->out_of_order_queue)) { 4229 if (skb_queue_empty(&tp->out_of_order_queue)) {
4234 tp->rx_opt.num_sacks = 0; 4230 tp->rx_opt.num_sacks = 0;
4235 tp->rx_opt.eff_sacks = tp->rx_opt.dsack;
4236 return; 4231 return;
4237 } 4232 }
4238 4233
@@ -4253,11 +4248,8 @@ static void tcp_sack_remove(struct tcp_sock *tp)
4253 this_sack++; 4248 this_sack++;
4254 sp++; 4249 sp++;
4255 } 4250 }
4256 if (num_sacks != tp->rx_opt.num_sacks) { 4251 if (num_sacks != tp->rx_opt.num_sacks)
4257 tp->rx_opt.num_sacks = num_sacks; 4252 tp->rx_opt.num_sacks = num_sacks;
4258 tp->rx_opt.eff_sacks = tp->rx_opt.num_sacks +
4259 tp->rx_opt.dsack;
4260 }
4261} 4253}
4262 4254
4263/* This one checks to see if we can put data from the 4255/* This one checks to see if we can put data from the
@@ -4333,10 +4325,8 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
4333 4325
4334 TCP_ECN_accept_cwr(tp, skb); 4326 TCP_ECN_accept_cwr(tp, skb);
4335 4327
4336 if (tp->rx_opt.dsack) { 4328 if (tp->rx_opt.dsack)
4337 tp->rx_opt.dsack = 0; 4329 tp->rx_opt.dsack = 0;
4338 tp->rx_opt.eff_sacks = tp->rx_opt.num_sacks;
4339 }
4340 4330
4341 /* Queue data for delivery to the user. 4331 /* Queue data for delivery to the user.
4342 * Packets in sequence go to the receive queue. 4332 * Packets in sequence go to the receive queue.
@@ -4456,7 +4446,6 @@ drop:
4456 if (tcp_is_sack(tp)) { 4446 if (tcp_is_sack(tp)) {
4457 tp->rx_opt.num_sacks = 1; 4447 tp->rx_opt.num_sacks = 1;
4458 tp->rx_opt.dsack = 0; 4448 tp->rx_opt.dsack = 0;
4459 tp->rx_opt.eff_sacks = 1;
4460 tp->selective_acks[0].start_seq = TCP_SKB_CB(skb)->seq; 4449 tp->selective_acks[0].start_seq = TCP_SKB_CB(skb)->seq;
4461 tp->selective_acks[0].end_seq = 4450 tp->selective_acks[0].end_seq =
4462 TCP_SKB_CB(skb)->end_seq; 4451 TCP_SKB_CB(skb)->end_seq;
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index f67effbb102b..bb3d8b35f19a 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -434,9 +434,8 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
434 newtp->rx_opt.saw_tstamp = 0; 434 newtp->rx_opt.saw_tstamp = 0;
435 435
436 newtp->rx_opt.dsack = 0; 436 newtp->rx_opt.dsack = 0;
437 newtp->rx_opt.eff_sacks = 0;
438
439 newtp->rx_opt.num_sacks = 0; 437 newtp->rx_opt.num_sacks = 0;
438
440 newtp->urg_data = 0; 439 newtp->urg_data = 0;
441 440
442 if (sock_flag(newsk, SOCK_KEEPOPEN)) 441 if (sock_flag(newsk, SOCK_KEEPOPEN))
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 61445b57610c..1555bb73b638 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -441,10 +441,8 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp,
441 *ptr++ = htonl(sp[this_sack].end_seq); 441 *ptr++ = htonl(sp[this_sack].end_seq);
442 } 442 }
443 443
444 if (tp->rx_opt.dsack) { 444 if (tp->rx_opt.dsack)
445 tp->rx_opt.dsack = 0; 445 tp->rx_opt.dsack = 0;
446 tp->rx_opt.eff_sacks = tp->rx_opt.num_sacks;
447 }
448 } 446 }
449} 447}
450 448
@@ -550,6 +548,7 @@ static unsigned tcp_established_options(struct sock *sk, struct sk_buff *skb,
550 struct tcp_skb_cb *tcb = skb ? TCP_SKB_CB(skb) : NULL; 548 struct tcp_skb_cb *tcb = skb ? TCP_SKB_CB(skb) : NULL;
551 struct tcp_sock *tp = tcp_sk(sk); 549 struct tcp_sock *tp = tcp_sk(sk);
552 unsigned size = 0; 550 unsigned size = 0;
551 unsigned int eff_sacks;
553 552
554#ifdef CONFIG_TCP_MD5SIG 553#ifdef CONFIG_TCP_MD5SIG
555 *md5 = tp->af_specific->md5_lookup(sk, sk); 554 *md5 = tp->af_specific->md5_lookup(sk, sk);
@@ -568,10 +567,11 @@ static unsigned tcp_established_options(struct sock *sk, struct sk_buff *skb,
568 size += TCPOLEN_TSTAMP_ALIGNED; 567 size += TCPOLEN_TSTAMP_ALIGNED;
569 } 568 }
570 569
571 if (unlikely(tp->rx_opt.eff_sacks)) { 570 eff_sacks = tp->rx_opt.num_sacks + tp->rx_opt.dsack;
571 if (unlikely(eff_sacks)) {
572 const unsigned remaining = MAX_TCP_OPTION_SPACE - size; 572 const unsigned remaining = MAX_TCP_OPTION_SPACE - size;
573 opts->num_sack_blocks = 573 opts->num_sack_blocks =
574 min_t(unsigned, tp->rx_opt.eff_sacks, 574 min_t(unsigned, eff_sacks,
575 (remaining - TCPOLEN_SACK_BASE_ALIGNED) / 575 (remaining - TCPOLEN_SACK_BASE_ALIGNED) /
576 TCPOLEN_SACK_PERBLOCK); 576 TCPOLEN_SACK_PERBLOCK);
577 size += TCPOLEN_SACK_BASE_ALIGNED + 577 size += TCPOLEN_SACK_BASE_ALIGNED +
@@ -1418,7 +1418,7 @@ static int tcp_mtu_probe(struct sock *sk)
1418 icsk->icsk_mtup.probe_size || 1418 icsk->icsk_mtup.probe_size ||
1419 inet_csk(sk)->icsk_ca_state != TCP_CA_Open || 1419 inet_csk(sk)->icsk_ca_state != TCP_CA_Open ||
1420 tp->snd_cwnd < 11 || 1420 tp->snd_cwnd < 11 ||
1421 tp->rx_opt.eff_sacks) 1421 tp->rx_opt.num_sacks || tp->rx_opt.dsack)
1422 return -1; 1422 return -1;
1423 1423
1424 /* Very simple search strategy: just double the MSS. */ 1424 /* Very simple search strategy: just double the MSS. */