diff options
Diffstat (limited to 'net/ipv4/tcp_ipv4.c')
| -rw-r--r-- | net/ipv4/tcp_ipv4.c | 74 |
1 files changed, 22 insertions, 52 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index d978bb2f748b..856f68466d49 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
| @@ -1210,12 +1210,6 @@ static const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = { | |||
| 1210 | }; | 1210 | }; |
| 1211 | #endif | 1211 | #endif |
| 1212 | 1212 | ||
| 1213 | static struct timewait_sock_ops tcp_timewait_sock_ops = { | ||
| 1214 | .twsk_obj_size = sizeof(struct tcp_timewait_sock), | ||
| 1215 | .twsk_unique = tcp_twsk_unique, | ||
| 1216 | .twsk_destructor= tcp_twsk_destructor, | ||
| 1217 | }; | ||
| 1218 | |||
| 1219 | int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) | 1213 | int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) |
| 1220 | { | 1214 | { |
| 1221 | struct tcp_extend_values tmp_ext; | 1215 | struct tcp_extend_values tmp_ext; |
| @@ -1347,7 +1341,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) | |||
| 1347 | tcp_death_row.sysctl_tw_recycle && | 1341 | tcp_death_row.sysctl_tw_recycle && |
| 1348 | (dst = inet_csk_route_req(sk, req)) != NULL && | 1342 | (dst = inet_csk_route_req(sk, req)) != NULL && |
| 1349 | (peer = rt_get_peer((struct rtable *)dst)) != NULL && | 1343 | (peer = rt_get_peer((struct rtable *)dst)) != NULL && |
| 1350 | peer->v4daddr == saddr) { | 1344 | peer->daddr.a4 == saddr) { |
| 1351 | inet_peer_refcheck(peer); | 1345 | inet_peer_refcheck(peer); |
| 1352 | if ((u32)get_seconds() - peer->tcp_ts_stamp < TCP_PAWS_MSL && | 1346 | if ((u32)get_seconds() - peer->tcp_ts_stamp < TCP_PAWS_MSL && |
| 1353 | (s32)(peer->tcp_ts - req->ts_recent) > | 1347 | (s32)(peer->tcp_ts - req->ts_recent) > |
| @@ -1442,7 +1436,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
| 1442 | 1436 | ||
| 1443 | tcp_mtup_init(newsk); | 1437 | tcp_mtup_init(newsk); |
| 1444 | tcp_sync_mss(newsk, dst_mtu(dst)); | 1438 | tcp_sync_mss(newsk, dst_mtu(dst)); |
| 1445 | newtp->advmss = dst_metric(dst, RTAX_ADVMSS); | 1439 | newtp->advmss = dst_metric_advmss(dst); |
| 1446 | if (tcp_sk(sk)->rx_opt.user_mss && | 1440 | if (tcp_sk(sk)->rx_opt.user_mss && |
| 1447 | tcp_sk(sk)->rx_opt.user_mss < newtp->advmss) | 1441 | tcp_sk(sk)->rx_opt.user_mss < newtp->advmss) |
| 1448 | newtp->advmss = tcp_sk(sk)->rx_opt.user_mss; | 1442 | newtp->advmss = tcp_sk(sk)->rx_opt.user_mss; |
| @@ -1763,64 +1757,40 @@ do_time_wait: | |||
| 1763 | goto discard_it; | 1757 | goto discard_it; |
| 1764 | } | 1758 | } |
| 1765 | 1759 | ||
| 1766 | /* VJ's idea. Save last timestamp seen from this destination | 1760 | struct inet_peer *tcp_v4_get_peer(struct sock *sk, bool *release_it) |
| 1767 | * and hold it at least for normal timewait interval to use for duplicate | ||
| 1768 | * segment detection in subsequent connections, before they enter synchronized | ||
| 1769 | * state. | ||
| 1770 | */ | ||
| 1771 | |||
| 1772 | int tcp_v4_remember_stamp(struct sock *sk) | ||
| 1773 | { | 1761 | { |
| 1762 | struct rtable *rt = (struct rtable *) __sk_dst_get(sk); | ||
| 1774 | struct inet_sock *inet = inet_sk(sk); | 1763 | struct inet_sock *inet = inet_sk(sk); |
| 1775 | struct tcp_sock *tp = tcp_sk(sk); | 1764 | struct inet_peer *peer; |
| 1776 | struct rtable *rt = (struct rtable *)__sk_dst_get(sk); | ||
| 1777 | struct inet_peer *peer = NULL; | ||
| 1778 | int release_it = 0; | ||
| 1779 | 1765 | ||
| 1780 | if (!rt || rt->rt_dst != inet->inet_daddr) { | 1766 | if (!rt || rt->rt_dst != inet->inet_daddr) { |
| 1781 | peer = inet_getpeer(inet->inet_daddr, 1); | 1767 | peer = inet_getpeer_v4(inet->inet_daddr, 1); |
| 1782 | release_it = 1; | 1768 | *release_it = true; |
| 1783 | } else { | 1769 | } else { |
| 1784 | if (!rt->peer) | 1770 | if (!rt->peer) |
| 1785 | rt_bind_peer(rt, 1); | 1771 | rt_bind_peer(rt, 1); |
| 1786 | peer = rt->peer; | 1772 | peer = rt->peer; |
| 1773 | *release_it = false; | ||
| 1787 | } | 1774 | } |
| 1788 | 1775 | ||
| 1789 | if (peer) { | 1776 | return peer; |
| 1790 | if ((s32)(peer->tcp_ts - tp->rx_opt.ts_recent) <= 0 || | ||
| 1791 | ((u32)get_seconds() - peer->tcp_ts_stamp > TCP_PAWS_MSL && | ||
| 1792 | peer->tcp_ts_stamp <= (u32)tp->rx_opt.ts_recent_stamp)) { | ||
| 1793 | peer->tcp_ts_stamp = (u32)tp->rx_opt.ts_recent_stamp; | ||
| 1794 | peer->tcp_ts = tp->rx_opt.ts_recent; | ||
| 1795 | } | ||
| 1796 | if (release_it) | ||
| 1797 | inet_putpeer(peer); | ||
| 1798 | return 1; | ||
| 1799 | } | ||
| 1800 | |||
| 1801 | return 0; | ||
| 1802 | } | 1777 | } |
| 1803 | EXPORT_SYMBOL(tcp_v4_remember_stamp); | 1778 | EXPORT_SYMBOL(tcp_v4_get_peer); |
| 1804 | 1779 | ||
| 1805 | int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw) | 1780 | void *tcp_v4_tw_get_peer(struct sock *sk) |
| 1806 | { | 1781 | { |
| 1807 | struct inet_peer *peer = inet_getpeer(tw->tw_daddr, 1); | 1782 | struct inet_timewait_sock *tw = inet_twsk(sk); |
| 1808 | |||
| 1809 | if (peer) { | ||
| 1810 | const struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw); | ||
| 1811 | |||
| 1812 | if ((s32)(peer->tcp_ts - tcptw->tw_ts_recent) <= 0 || | ||
| 1813 | ((u32)get_seconds() - peer->tcp_ts_stamp > TCP_PAWS_MSL && | ||
| 1814 | peer->tcp_ts_stamp <= (u32)tcptw->tw_ts_recent_stamp)) { | ||
| 1815 | peer->tcp_ts_stamp = (u32)tcptw->tw_ts_recent_stamp; | ||
| 1816 | peer->tcp_ts = tcptw->tw_ts_recent; | ||
| 1817 | } | ||
| 1818 | inet_putpeer(peer); | ||
| 1819 | return 1; | ||
| 1820 | } | ||
| 1821 | 1783 | ||
| 1822 | return 0; | 1784 | return inet_getpeer_v4(tw->tw_daddr, 1); |
| 1823 | } | 1785 | } |
| 1786 | EXPORT_SYMBOL(tcp_v4_tw_get_peer); | ||
| 1787 | |||
| 1788 | static struct timewait_sock_ops tcp_timewait_sock_ops = { | ||
| 1789 | .twsk_obj_size = sizeof(struct tcp_timewait_sock), | ||
| 1790 | .twsk_unique = tcp_twsk_unique, | ||
| 1791 | .twsk_destructor= tcp_twsk_destructor, | ||
| 1792 | .twsk_getpeer = tcp_v4_tw_get_peer, | ||
| 1793 | }; | ||
| 1824 | 1794 | ||
| 1825 | const struct inet_connection_sock_af_ops ipv4_specific = { | 1795 | const struct inet_connection_sock_af_ops ipv4_specific = { |
| 1826 | .queue_xmit = ip_queue_xmit, | 1796 | .queue_xmit = ip_queue_xmit, |
| @@ -1828,7 +1798,7 @@ const struct inet_connection_sock_af_ops ipv4_specific = { | |||
| 1828 | .rebuild_header = inet_sk_rebuild_header, | 1798 | .rebuild_header = inet_sk_rebuild_header, |
| 1829 | .conn_request = tcp_v4_conn_request, | 1799 | .conn_request = tcp_v4_conn_request, |
| 1830 | .syn_recv_sock = tcp_v4_syn_recv_sock, | 1800 | .syn_recv_sock = tcp_v4_syn_recv_sock, |
| 1831 | .remember_stamp = tcp_v4_remember_stamp, | 1801 | .get_peer = tcp_v4_get_peer, |
| 1832 | .net_header_len = sizeof(struct iphdr), | 1802 | .net_header_len = sizeof(struct iphdr), |
| 1833 | .setsockopt = ip_setsockopt, | 1803 | .setsockopt = ip_setsockopt, |
| 1834 | .getsockopt = ip_getsockopt, | 1804 | .getsockopt = ip_getsockopt, |
