aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_input.c
diff options
context:
space:
mode:
authorJohn Heffner <jheffner@psc.edu>2006-03-20 20:53:41 -0500
committerDavid S. Miller <davem@davemloft.net>2006-03-20 20:53:41 -0500
commit5d424d5a674f782d0659a3b66d951f412901faee (patch)
tree579871172044e02e626a90388d19ec55cf2d1fc4 /net/ipv4/tcp_input.c
parent1d60290f27e7dc4bce2c43922d0bfa9abd246fc9 (diff)
[TCP]: MTU probing
Implementation of packetization layer path mtu discovery for TCP, based on the internet-draft currently found at <http://www.ietf.org/internet-drafts/draft-ietf-pmtud-method-05.txt>. Signed-off-by: John Heffner <jheffner@psc.edu> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r--net/ipv4/tcp_input.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index e9a54ae7d690..0ac388e3d01d 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1891,6 +1891,34 @@ static void tcp_try_to_open(struct sock *sk, struct tcp_sock *tp, int flag)
1891 } 1891 }
1892} 1892}
1893 1893
1894static void tcp_mtup_probe_failed(struct sock *sk)
1895{
1896 struct inet_connection_sock *icsk = inet_csk(sk);
1897
1898 icsk->icsk_mtup.search_high = icsk->icsk_mtup.probe_size - 1;
1899 icsk->icsk_mtup.probe_size = 0;
1900}
1901
1902static void tcp_mtup_probe_success(struct sock *sk, struct sk_buff *skb)
1903{
1904 struct tcp_sock *tp = tcp_sk(sk);
1905 struct inet_connection_sock *icsk = inet_csk(sk);
1906
1907 /* FIXME: breaks with very large cwnd */
1908 tp->prior_ssthresh = tcp_current_ssthresh(sk);
1909 tp->snd_cwnd = tp->snd_cwnd *
1910 tcp_mss_to_mtu(sk, tp->mss_cache) /
1911 icsk->icsk_mtup.probe_size;
1912 tp->snd_cwnd_cnt = 0;
1913 tp->snd_cwnd_stamp = tcp_time_stamp;
1914 tp->rcv_ssthresh = tcp_current_ssthresh(sk);
1915
1916 icsk->icsk_mtup.search_low = icsk->icsk_mtup.probe_size;
1917 icsk->icsk_mtup.probe_size = 0;
1918 tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
1919}
1920
1921
1894/* Process an event, which can update packets-in-flight not trivially. 1922/* Process an event, which can update packets-in-flight not trivially.
1895 * Main goal of this function is to calculate new estimate for left_out, 1923 * Main goal of this function is to calculate new estimate for left_out,
1896 * taking into account both packets sitting in receiver's buffer and 1924 * taking into account both packets sitting in receiver's buffer and
@@ -2023,6 +2051,17 @@ tcp_fastretrans_alert(struct sock *sk, u32 prior_snd_una,
2023 return; 2051 return;
2024 } 2052 }
2025 2053
2054 /* MTU probe failure: don't reduce cwnd */
2055 if (icsk->icsk_ca_state < TCP_CA_CWR &&
2056 icsk->icsk_mtup.probe_size &&
2057 tp->snd_una == icsk->icsk_mtup.probe_seq_start) {
2058 tcp_mtup_probe_failed(sk);
2059 /* Restores the reduction we did in tcp_mtup_probe() */
2060 tp->snd_cwnd++;
2061 tcp_simple_retransmit(sk);
2062 return;
2063 }
2064
2026 /* Otherwise enter Recovery state */ 2065 /* Otherwise enter Recovery state */
2027 2066
2028 if (IsReno(tp)) 2067 if (IsReno(tp))
@@ -2243,6 +2282,13 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p)
2243 tp->retrans_stamp = 0; 2282 tp->retrans_stamp = 0;
2244 } 2283 }
2245 2284
2285 /* MTU probing checks */
2286 if (icsk->icsk_mtup.probe_size) {
2287 if (!after(icsk->icsk_mtup.probe_seq_end, TCP_SKB_CB(skb)->end_seq)) {
2288 tcp_mtup_probe_success(sk, skb);
2289 }
2290 }
2291
2246 if (sacked) { 2292 if (sacked) {
2247 if (sacked & TCPCB_RETRANS) { 2293 if (sacked & TCPCB_RETRANS) {
2248 if(sacked & TCPCB_SACKED_RETRANS) 2294 if(sacked & TCPCB_SACKED_RETRANS)
@@ -4101,6 +4147,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
4101 if (tp->rx_opt.sack_ok && sysctl_tcp_fack) 4147 if (tp->rx_opt.sack_ok && sysctl_tcp_fack)
4102 tp->rx_opt.sack_ok |= 2; 4148 tp->rx_opt.sack_ok |= 2;
4103 4149
4150 tcp_mtup_init(sk);
4104 tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); 4151 tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
4105 tcp_initialize_rcv_mss(sk); 4152 tcp_initialize_rcv_mss(sk);
4106 4153
@@ -4211,6 +4258,7 @@ discard:
4211 if (tp->ecn_flags&TCP_ECN_OK) 4258 if (tp->ecn_flags&TCP_ECN_OK)
4212 sock_set_flag(sk, SOCK_NO_LARGESEND); 4259 sock_set_flag(sk, SOCK_NO_LARGESEND);
4213 4260
4261 tcp_mtup_init(sk);
4214 tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); 4262 tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
4215 tcp_initialize_rcv_mss(sk); 4263 tcp_initialize_rcv_mss(sk);
4216 4264
@@ -4399,6 +4447,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
4399 */ 4447 */
4400 tp->lsndtime = tcp_time_stamp; 4448 tp->lsndtime = tcp_time_stamp;
4401 4449
4450 tcp_mtup_init(sk);
4402 tcp_initialize_rcv_mss(sk); 4451 tcp_initialize_rcv_mss(sk);
4403 tcp_init_buffer_space(sk); 4452 tcp_init_buffer_space(sk);
4404 tcp_fast_path_on(tp); 4453 tcp_fast_path_on(tp);