aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/tcp_ipv4.c10
-rw-r--r--net/ipv4/tcp_minisocks.c27
2 files changed, 20 insertions, 17 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 77f049d00dbb..fda2ca17135e 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1835,20 +1835,10 @@ struct inet_peer *tcp_v4_get_peer(struct sock *sk)
1835} 1835}
1836EXPORT_SYMBOL(tcp_v4_get_peer); 1836EXPORT_SYMBOL(tcp_v4_get_peer);
1837 1837
1838void *tcp_v4_tw_get_peer(struct sock *sk)
1839{
1840 const struct inet_timewait_sock *tw = inet_twsk(sk);
1841 struct net *net = sock_net(sk);
1842
1843 return inet_getpeer_v4(net, tw->tw_daddr, 1);
1844}
1845EXPORT_SYMBOL(tcp_v4_tw_get_peer);
1846
1847static struct timewait_sock_ops tcp_timewait_sock_ops = { 1838static struct timewait_sock_ops tcp_timewait_sock_ops = {
1848 .twsk_obj_size = sizeof(struct tcp_timewait_sock), 1839 .twsk_obj_size = sizeof(struct tcp_timewait_sock),
1849 .twsk_unique = tcp_twsk_unique, 1840 .twsk_unique = tcp_twsk_unique,
1850 .twsk_destructor= tcp_twsk_destructor, 1841 .twsk_destructor= tcp_twsk_destructor,
1851 .twsk_getpeer = tcp_v4_tw_get_peer,
1852}; 1842};
1853 1843
1854const struct inet_connection_sock_af_ops ipv4_specific = { 1844const struct inet_connection_sock_af_ops ipv4_specific = {
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index fef9dbf3af00..cb015317c9f7 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -77,20 +77,19 @@ static bool tcp_remember_stamp(struct sock *sk)
77 77
78static bool tcp_tw_remember_stamp(struct inet_timewait_sock *tw) 78static bool tcp_tw_remember_stamp(struct inet_timewait_sock *tw)
79{ 79{
80 const struct tcp_timewait_sock *tcptw;
80 struct sock *sk = (struct sock *) tw; 81 struct sock *sk = (struct sock *) tw;
81 struct inet_peer *peer; 82 struct inet_peer *peer;
82 83
83 peer = twsk_getpeer(sk); 84 tcptw = tcp_twsk(sk);
85 peer = tcptw->tw_peer;
84 if (peer) { 86 if (peer) {
85 const struct tcp_timewait_sock *tcptw = tcp_twsk(sk);
86
87 if ((s32)(peer->tcp_ts - tcptw->tw_ts_recent) <= 0 || 87 if ((s32)(peer->tcp_ts - tcptw->tw_ts_recent) <= 0 ||
88 ((u32)get_seconds() - peer->tcp_ts_stamp > TCP_PAWS_MSL && 88 ((u32)get_seconds() - peer->tcp_ts_stamp > TCP_PAWS_MSL &&
89 peer->tcp_ts_stamp <= (u32)tcptw->tw_ts_recent_stamp)) { 89 peer->tcp_ts_stamp <= (u32)tcptw->tw_ts_recent_stamp)) {
90 peer->tcp_ts_stamp = (u32)tcptw->tw_ts_recent_stamp; 90 peer->tcp_ts_stamp = (u32)tcptw->tw_ts_recent_stamp;
91 peer->tcp_ts = tcptw->tw_ts_recent; 91 peer->tcp_ts = tcptw->tw_ts_recent;
92 } 92 }
93 inet_putpeer(peer);
94 return true; 93 return true;
95 } 94 }
96 return false; 95 return false;
@@ -314,9 +313,12 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
314 const struct inet_connection_sock *icsk = inet_csk(sk); 313 const struct inet_connection_sock *icsk = inet_csk(sk);
315 const struct tcp_sock *tp = tcp_sk(sk); 314 const struct tcp_sock *tp = tcp_sk(sk);
316 bool recycle_ok = false; 315 bool recycle_ok = false;
316 bool recycle_on = false;
317 317
318 if (tcp_death_row.sysctl_tw_recycle && tp->rx_opt.ts_recent_stamp) 318 if (tcp_death_row.sysctl_tw_recycle && tp->rx_opt.ts_recent_stamp) {
319 recycle_ok = tcp_remember_stamp(sk); 319 recycle_ok = tcp_remember_stamp(sk);
320 recycle_on = true;
321 }
320 322
321 if (tcp_death_row.tw_count < tcp_death_row.sysctl_max_tw_buckets) 323 if (tcp_death_row.tw_count < tcp_death_row.sysctl_max_tw_buckets)
322 tw = inet_twsk_alloc(sk, state); 324 tw = inet_twsk_alloc(sk, state);
@@ -324,8 +326,10 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
324 if (tw != NULL) { 326 if (tw != NULL) {
325 struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw); 327 struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw);
326 const int rto = (icsk->icsk_rto << 2) - (icsk->icsk_rto >> 1); 328 const int rto = (icsk->icsk_rto << 2) - (icsk->icsk_rto >> 1);
329 struct inet_sock *inet = inet_sk(sk);
330 struct inet_peer *peer = NULL;
327 331
328 tw->tw_transparent = inet_sk(sk)->transparent; 332 tw->tw_transparent = inet->transparent;
329 tw->tw_rcv_wscale = tp->rx_opt.rcv_wscale; 333 tw->tw_rcv_wscale = tp->rx_opt.rcv_wscale;
330 tcptw->tw_rcv_nxt = tp->rcv_nxt; 334 tcptw->tw_rcv_nxt = tp->rcv_nxt;
331 tcptw->tw_snd_nxt = tp->snd_nxt; 335 tcptw->tw_snd_nxt = tp->snd_nxt;
@@ -347,6 +351,12 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
347 } 351 }
348#endif 352#endif
349 353
354 if (recycle_on)
355 peer = icsk->icsk_af_ops->get_peer(sk);
356 tcptw->tw_peer = peer;
357 if (peer)
358 atomic_inc(&peer->refcnt);
359
350#ifdef CONFIG_TCP_MD5SIG 360#ifdef CONFIG_TCP_MD5SIG
351 /* 361 /*
352 * The timewait bucket does not have the key DB from the 362 * The timewait bucket does not have the key DB from the
@@ -398,8 +408,11 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
398 408
399void tcp_twsk_destructor(struct sock *sk) 409void tcp_twsk_destructor(struct sock *sk)
400{ 410{
401#ifdef CONFIG_TCP_MD5SIG
402 struct tcp_timewait_sock *twsk = tcp_twsk(sk); 411 struct tcp_timewait_sock *twsk = tcp_twsk(sk);
412
413 if (twsk->tw_peer)
414 inet_putpeer(twsk->tw_peer);
415#ifdef CONFIG_TCP_MD5SIG
403 if (twsk->tw_md5_key) { 416 if (twsk->tw_md5_key) {
404 tcp_free_md5sig_pool(); 417 tcp_free_md5sig_pool();
405 kfree_rcu(twsk->tw_md5_key, rcu); 418 kfree_rcu(twsk->tw_md5_key, rcu);