aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_ipv4.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_ipv4.c')
-rw-r--r--net/ipv4/tcp_ipv4.c68
1 files changed, 44 insertions, 24 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index fbea536cf5c0..552e87e3c269 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -89,7 +89,6 @@ int sysctl_tcp_tw_reuse __read_mostly;
89int sysctl_tcp_low_latency __read_mostly; 89int sysctl_tcp_low_latency __read_mostly;
90EXPORT_SYMBOL(sysctl_tcp_low_latency); 90EXPORT_SYMBOL(sysctl_tcp_low_latency);
91 91
92
93#ifdef CONFIG_TCP_MD5SIG 92#ifdef CONFIG_TCP_MD5SIG
94static int tcp_v4_md5_hash_hdr(char *md5_hash, const struct tcp_md5sig_key *key, 93static int tcp_v4_md5_hash_hdr(char *md5_hash, const struct tcp_md5sig_key *key,
95 __be32 daddr, __be32 saddr, const struct tcphdr *th); 94 __be32 daddr, __be32 saddr, const struct tcphdr *th);
@@ -430,15 +429,16 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
430 break; 429 break;
431 430
432 icsk->icsk_backoff--; 431 icsk->icsk_backoff--;
433 inet_csk(sk)->icsk_rto = (tp->srtt_us ? __tcp_set_rto(tp) : 432 icsk->icsk_rto = tp->srtt_us ? __tcp_set_rto(tp) :
434 TCP_TIMEOUT_INIT) << icsk->icsk_backoff; 433 TCP_TIMEOUT_INIT;
435 tcp_bound_rto(sk); 434 icsk->icsk_rto = inet_csk_rto_backoff(icsk, TCP_RTO_MAX);
436 435
437 skb = tcp_write_queue_head(sk); 436 skb = tcp_write_queue_head(sk);
438 BUG_ON(!skb); 437 BUG_ON(!skb);
439 438
440 remaining = icsk->icsk_rto - min(icsk->icsk_rto, 439 remaining = icsk->icsk_rto -
441 tcp_time_stamp - TCP_SKB_CB(skb)->when); 440 min(icsk->icsk_rto,
441 tcp_time_stamp - tcp_skb_timestamp(skb));
442 442
443 if (remaining) { 443 if (remaining) {
444 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, 444 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
@@ -680,8 +680,9 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
680 680
681 net = dev_net(skb_dst(skb)->dev); 681 net = dev_net(skb_dst(skb)->dev);
682 arg.tos = ip_hdr(skb)->tos; 682 arg.tos = ip_hdr(skb)->tos;
683 ip_send_unicast_reply(net, skb, ip_hdr(skb)->saddr, 683 ip_send_unicast_reply(net, skb, &TCP_SKB_CB(skb)->header.h4.opt,
684 ip_hdr(skb)->daddr, &arg, arg.iov[0].iov_len); 684 ip_hdr(skb)->saddr, ip_hdr(skb)->daddr,
685 &arg, arg.iov[0].iov_len);
685 686
686 TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); 687 TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS);
687 TCP_INC_STATS_BH(net, TCP_MIB_OUTRSTS); 688 TCP_INC_STATS_BH(net, TCP_MIB_OUTRSTS);
@@ -763,8 +764,9 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
763 if (oif) 764 if (oif)
764 arg.bound_dev_if = oif; 765 arg.bound_dev_if = oif;
765 arg.tos = tos; 766 arg.tos = tos;
766 ip_send_unicast_reply(net, skb, ip_hdr(skb)->saddr, 767 ip_send_unicast_reply(net, skb, &TCP_SKB_CB(skb)->header.h4.opt,
767 ip_hdr(skb)->daddr, &arg, arg.iov[0].iov_len); 768 ip_hdr(skb)->saddr, ip_hdr(skb)->daddr,
769 &arg, arg.iov[0].iov_len);
768 770
769 TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); 771 TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS);
770} 772}
@@ -883,18 +885,16 @@ EXPORT_SYMBOL(tcp_syn_flood_action);
883 */ 885 */
884static struct ip_options_rcu *tcp_v4_save_options(struct sk_buff *skb) 886static struct ip_options_rcu *tcp_v4_save_options(struct sk_buff *skb)
885{ 887{
886 const struct ip_options *opt = &(IPCB(skb)->opt); 888 const struct ip_options *opt = &TCP_SKB_CB(skb)->header.h4.opt;
887 struct ip_options_rcu *dopt = NULL; 889 struct ip_options_rcu *dopt = NULL;
888 890
889 if (opt && opt->optlen) { 891 if (opt && opt->optlen) {
890 int opt_size = sizeof(*dopt) + opt->optlen; 892 int opt_size = sizeof(*dopt) + opt->optlen;
891 893
892 dopt = kmalloc(opt_size, GFP_ATOMIC); 894 dopt = kmalloc(opt_size, GFP_ATOMIC);
893 if (dopt) { 895 if (dopt && __ip_options_echo(&dopt->opt, skb, opt)) {
894 if (ip_options_echo(&dopt->opt, skb)) { 896 kfree(dopt);
895 kfree(dopt); 897 dopt = NULL;
896 dopt = NULL;
897 }
898 } 898 }
899 } 899 }
900 return dopt; 900 return dopt;
@@ -1268,7 +1268,7 @@ struct request_sock_ops tcp_request_sock_ops __read_mostly = {
1268 .send_ack = tcp_v4_reqsk_send_ack, 1268 .send_ack = tcp_v4_reqsk_send_ack,
1269 .destructor = tcp_v4_reqsk_destructor, 1269 .destructor = tcp_v4_reqsk_destructor,
1270 .send_reset = tcp_v4_send_reset, 1270 .send_reset = tcp_v4_send_reset,
1271 .syn_ack_timeout = tcp_syn_ack_timeout, 1271 .syn_ack_timeout = tcp_syn_ack_timeout,
1272}; 1272};
1273 1273
1274static const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = { 1274static const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = {
@@ -1428,7 +1428,7 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
1428 1428
1429#ifdef CONFIG_SYN_COOKIES 1429#ifdef CONFIG_SYN_COOKIES
1430 if (!th->syn) 1430 if (!th->syn)
1431 sk = cookie_v4_check(sk, skb, &(IPCB(skb)->opt)); 1431 sk = cookie_v4_check(sk, skb, &TCP_SKB_CB(skb)->header.h4.opt);
1432#endif 1432#endif
1433 return sk; 1433 return sk;
1434} 1434}
@@ -1558,7 +1558,17 @@ bool tcp_prequeue(struct sock *sk, struct sk_buff *skb)
1558 skb_queue_len(&tp->ucopy.prequeue) == 0) 1558 skb_queue_len(&tp->ucopy.prequeue) == 0)
1559 return false; 1559 return false;
1560 1560
1561 skb_dst_force(skb); 1561 /* Before escaping RCU protected region, we need to take care of skb
1562 * dst. Prequeue is only enabled for established sockets.
1563 * For such sockets, we might need the skb dst only to set sk->sk_rx_dst
1564 * Instead of doing full sk_rx_dst validity here, let's perform
1565 * an optimistic check.
1566 */
1567 if (likely(sk->sk_rx_dst))
1568 skb_dst_drop(skb);
1569 else
1570 skb_dst_force(skb);
1571
1562 __skb_queue_tail(&tp->ucopy.prequeue, skb); 1572 __skb_queue_tail(&tp->ucopy.prequeue, skb);
1563 tp->ucopy.memory += skb->truesize; 1573 tp->ucopy.memory += skb->truesize;
1564 if (tp->ucopy.memory > sk->sk_rcvbuf) { 1574 if (tp->ucopy.memory > sk->sk_rcvbuf) {
@@ -1623,11 +1633,19 @@ int tcp_v4_rcv(struct sk_buff *skb)
1623 1633
1624 th = tcp_hdr(skb); 1634 th = tcp_hdr(skb);
1625 iph = ip_hdr(skb); 1635 iph = ip_hdr(skb);
1636 /* This is tricky : We move IPCB at its correct location into TCP_SKB_CB()
1637 * barrier() makes sure compiler wont play fool^Waliasing games.
1638 */
1639 memmove(&TCP_SKB_CB(skb)->header.h4, IPCB(skb),
1640 sizeof(struct inet_skb_parm));
1641 barrier();
1642
1626 TCP_SKB_CB(skb)->seq = ntohl(th->seq); 1643 TCP_SKB_CB(skb)->seq = ntohl(th->seq);
1627 TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin + 1644 TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq + th->syn + th->fin +
1628 skb->len - th->doff * 4); 1645 skb->len - th->doff * 4);
1629 TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq); 1646 TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);
1630 TCP_SKB_CB(skb)->when = 0; 1647 TCP_SKB_CB(skb)->tcp_flags = tcp_flag_byte(th);
1648 TCP_SKB_CB(skb)->tcp_tw_isn = 0;
1631 TCP_SKB_CB(skb)->ip_dsfield = ipv4_get_dsfield(iph); 1649 TCP_SKB_CB(skb)->ip_dsfield = ipv4_get_dsfield(iph);
1632 TCP_SKB_CB(skb)->sacked = 0; 1650 TCP_SKB_CB(skb)->sacked = 0;
1633 1651
@@ -1754,9 +1772,11 @@ void inet_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb)
1754{ 1772{
1755 struct dst_entry *dst = skb_dst(skb); 1773 struct dst_entry *dst = skb_dst(skb);
1756 1774
1757 dst_hold(dst); 1775 if (dst) {
1758 sk->sk_rx_dst = dst; 1776 dst_hold(dst);
1759 inet_sk(sk)->rx_dst_ifindex = skb->skb_iif; 1777 sk->sk_rx_dst = dst;
1778 inet_sk(sk)->rx_dst_ifindex = skb->skb_iif;
1779 }
1760} 1780}
1761EXPORT_SYMBOL(inet_sk_rx_dst_set); 1781EXPORT_SYMBOL(inet_sk_rx_dst_set);
1762 1782
@@ -2167,7 +2187,7 @@ int tcp_seq_open(struct inode *inode, struct file *file)
2167 2187
2168 s = ((struct seq_file *)file->private_data)->private; 2188 s = ((struct seq_file *)file->private_data)->private;
2169 s->family = afinfo->family; 2189 s->family = afinfo->family;
2170 s->last_pos = 0; 2190 s->last_pos = 0;
2171 return 0; 2191 return 0;
2172} 2192}
2173EXPORT_SYMBOL(tcp_seq_open); 2193EXPORT_SYMBOL(tcp_seq_open);