diff options
author | Patrick McHardy <kaber@trash.net> | 2010-04-20 16:02:01 +0200 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-04-20 16:02:01 +0200 |
commit | 62910554656cdcd6b6f84a5154c4155aae4ca231 (patch) | |
tree | dcf14004f6fd2ef7154362ff948bfeba0f3ea92d /net/ipv4/tcp_ipv4.c | |
parent | 22265a5c3c103cf8c50be62e6c90d045eb649e6d (diff) | |
parent | ab9304717f7624c41927f442e6b6d418b2d8b3e4 (diff) |
Merge branch 'master' of /repos/git/net-next-2.6
Conflicts:
Documentation/feature-removal-schedule.txt
net/ipv6/netfilter/ip6t_REJECT.c
net/netfilter/xt_limit.c
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/ipv4/tcp_ipv4.c')
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 39 |
1 files changed, 22 insertions, 17 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 70df40980a8..ad08392a738 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -60,6 +60,7 @@ #include <linux/jhash.h> #include <linux/init.h> #include <linux/times.h> +#include <linux/slab.h> #include <net/net_namespace.h> #include <net/icmp.h> @@ -370,6 +371,11 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) if (sk->sk_state == TCP_CLOSE) goto out; + if (unlikely(iph->ttl < inet_sk(sk)->min_ttl)) { + NET_INC_STATS_BH(net, LINUX_MIB_TCPMINTTLDROP); + goto out; + } + icsk = inet_csk(sk); tp = tcp_sk(sk); seq = ntohl(th->seq); @@ -513,26 +519,31 @@ out: sock_put(sk); } -/* This routine computes an IPv4 TCP checksum. */ -void tcp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb) +static void __tcp_v4_send_check(struct sk_buff *skb, + __be32 saddr, __be32 daddr) { - struct inet_sock *inet = inet_sk(sk); struct tcphdr *th = tcp_hdr(skb); if (skb->ip_summed == CHECKSUM_PARTIAL) { - th->check = ~tcp_v4_check(len, inet->inet_saddr, - inet->inet_daddr, 0); + th->check = ~tcp_v4_check(skb->len, saddr, daddr, 0); skb->csum_start = skb_transport_header(skb) - skb->head; skb->csum_offset = offsetof(struct tcphdr, check); } else { - th->check = tcp_v4_check(len, inet->inet_saddr, - inet->inet_daddr, + th->check = tcp_v4_check(skb->len, saddr, daddr, csum_partial(th, th->doff << 2, skb->csum)); } } +/* This routine computes an IPv4 TCP checksum. */ +void tcp_v4_send_check(struct sock *sk, struct sk_buff *skb) +{ + struct inet_sock *inet = inet_sk(sk); + + __tcp_v4_send_check(skb, inet->inet_saddr, inet->inet_daddr); +} + int tcp_v4_gso_send_check(struct sk_buff *skb) { const struct iphdr *iph; @@ -545,10 +556,8 @@ int tcp_v4_gso_send_check(struct sk_buff *skb) th = tcp_hdr(skb); th->check = 0; - th->check = ~tcp_v4_check(skb->len, iph->saddr, iph->daddr, 0); - skb->csum_start = skb_transport_header(skb) - skb->head; - skb->csum_offset = offsetof(struct tcphdr, check); skb->ip_summed = CHECKSUM_PARTIAL; + __tcp_v4_send_check(skb, iph->saddr, iph->daddr); return 0; } @@ -757,13 +766,7 @@ static int tcp_v4_send_synack(struct sock *sk, struct dst_entry *dst, skb = tcp_make_synack(sk, dst, req, rvp); if (skb) { - struct tcphdr *th = tcp_hdr(skb); - - th->check = tcp_v4_check(skb->len, - ireq->loc_addr, - ireq->rmt_addr, - csum_partial(th, skb->len, - skb->csum)); + __tcp_v4_send_check(skb, ireq->loc_addr, ireq->rmt_addr); err = ip_build_and_send_pkt(skb, sk, ireq->loc_addr, ireq->rmt_addr, @@ -1669,6 +1672,8 @@ process: skb->dev = NULL; + inet_rps_save_rxhash(sk, skb->rxhash); + bh_lock_sock_nested(sk); ret = 0; if (!sock_owned_by_user(sk)) { |