diff options
Diffstat (limited to 'net/ipv4/tcp_output.c')
-rw-r--r-- | net/ipv4/tcp_output.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 493553c71d32..990a58493235 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -345,6 +345,11 @@ static void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags) | |||
345 | TCP_SKB_CB(skb)->end_seq = seq; | 345 | TCP_SKB_CB(skb)->end_seq = seq; |
346 | } | 346 | } |
347 | 347 | ||
348 | static inline int tcp_urg_mode(const struct tcp_sock *tp) | ||
349 | { | ||
350 | return tp->snd_una != tp->snd_up; | ||
351 | } | ||
352 | |||
348 | #define OPTION_SACK_ADVERTISE (1 << 0) | 353 | #define OPTION_SACK_ADVERTISE (1 << 0) |
349 | #define OPTION_TS (1 << 1) | 354 | #define OPTION_TS (1 << 1) |
350 | #define OPTION_MD5 (1 << 2) | 355 | #define OPTION_MD5 (1 << 2) |
@@ -646,7 +651,8 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
646 | th->check = 0; | 651 | th->check = 0; |
647 | th->urg_ptr = 0; | 652 | th->urg_ptr = 0; |
648 | 653 | ||
649 | if (unlikely(tp->urg_mode && | 654 | /* The urg_mode check is necessary during a below snd_una win probe */ |
655 | if (unlikely(tcp_urg_mode(tp) && | ||
650 | between(tp->snd_up, tcb->seq + 1, tcb->seq + 0xFFFF))) { | 656 | between(tp->snd_up, tcb->seq + 1, tcb->seq + 0xFFFF))) { |
651 | th->urg_ptr = htons(tp->snd_up - tcb->seq); | 657 | th->urg_ptr = htons(tp->snd_up - tcb->seq); |
652 | th->urg = 1; | 658 | th->urg = 1; |
@@ -1012,7 +1018,7 @@ unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu) | |||
1012 | /* Compute the current effective MSS, taking SACKs and IP options, | 1018 | /* Compute the current effective MSS, taking SACKs and IP options, |
1013 | * and even PMTU discovery events into account. | 1019 | * and even PMTU discovery events into account. |
1014 | * | 1020 | * |
1015 | * LARGESEND note: !urg_mode is overkill, only frames up to snd_up | 1021 | * LARGESEND note: !tcp_urg_mode is overkill, only frames up to snd_up |
1016 | * cannot be large. However, taking into account rare use of URG, this | 1022 | * cannot be large. However, taking into account rare use of URG, this |
1017 | * is not a big flaw. | 1023 | * is not a big flaw. |
1018 | */ | 1024 | */ |
@@ -1029,7 +1035,7 @@ unsigned int tcp_current_mss(struct sock *sk, int large_allowed) | |||
1029 | 1035 | ||
1030 | mss_now = tp->mss_cache; | 1036 | mss_now = tp->mss_cache; |
1031 | 1037 | ||
1032 | if (large_allowed && sk_can_gso(sk) && !tp->urg_mode) | 1038 | if (large_allowed && sk_can_gso(sk) && !tcp_urg_mode(tp)) |
1033 | doing_tso = 1; | 1039 | doing_tso = 1; |
1034 | 1040 | ||
1035 | if (dst) { | 1041 | if (dst) { |
@@ -1193,7 +1199,7 @@ static inline int tcp_nagle_test(struct tcp_sock *tp, struct sk_buff *skb, | |||
1193 | /* Don't use the nagle rule for urgent data (or for the final FIN). | 1199 | /* Don't use the nagle rule for urgent data (or for the final FIN). |
1194 | * Nagle can be ignored during F-RTO too (see RFC4138). | 1200 | * Nagle can be ignored during F-RTO too (see RFC4138). |
1195 | */ | 1201 | */ |
1196 | if (tp->urg_mode || (tp->frto_counter == 2) || | 1202 | if (tcp_urg_mode(tp) || (tp->frto_counter == 2) || |
1197 | (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)) | 1203 | (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)) |
1198 | return 1; | 1204 | return 1; |
1199 | 1205 | ||
@@ -2358,6 +2364,7 @@ static void tcp_connect_init(struct sock *sk) | |||
2358 | tcp_init_wl(tp, tp->write_seq, 0); | 2364 | tcp_init_wl(tp, tp->write_seq, 0); |
2359 | tp->snd_una = tp->write_seq; | 2365 | tp->snd_una = tp->write_seq; |
2360 | tp->snd_sml = tp->write_seq; | 2366 | tp->snd_sml = tp->write_seq; |
2367 | tp->snd_up = tp->write_seq; | ||
2361 | tp->rcv_nxt = 0; | 2368 | tp->rcv_nxt = 0; |
2362 | tp->rcv_wup = 0; | 2369 | tp->rcv_wup = 0; |
2363 | tp->copied_seq = 0; | 2370 | tp->copied_seq = 0; |
@@ -2567,8 +2574,7 @@ int tcp_write_wakeup(struct sock *sk) | |||
2567 | tcp_event_new_data_sent(sk, skb); | 2574 | tcp_event_new_data_sent(sk, skb); |
2568 | return err; | 2575 | return err; |
2569 | } else { | 2576 | } else { |
2570 | if (tp->urg_mode && | 2577 | if (between(tp->snd_up, tp->snd_una + 1, tp->snd_una + 0xFFFF)) |
2571 | between(tp->snd_up, tp->snd_una + 1, tp->snd_una + 0xFFFF)) | ||
2572 | tcp_xmit_probe_skb(sk, 1); | 2578 | tcp_xmit_probe_skb(sk, 1); |
2573 | return tcp_xmit_probe_skb(sk, 0); | 2579 | return tcp_xmit_probe_skb(sk, 0); |
2574 | } | 2580 | } |