diff options
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
| -rw-r--r-- | net/ipv6/tcp_ipv6.c | 10 | 
1 files changed, 7 insertions, 3 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 6963a6b6763..075f540ec19 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -38,6 +38,7 @@  #include <linux/jhash.h>  #include <linux/ipsec.h>  #include <linux/times.h> +#include <linux/slab.h>  #include <linux/ipv6.h>  #include <linux/icmpv6.h> @@ -1014,7 +1015,7 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,  	skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len);  	t1 = (struct tcphdr *) skb_push(buff, tot_len); -	skb_reset_transport_header(skb); +	skb_reset_transport_header(buff);  	/* Swap the send and the receive. */  	memset(t1, 0, sizeof(*t1)); @@ -1740,8 +1741,11 @@ process:  			if (!tcp_prequeue(sk, skb))  				ret = tcp_v6_do_rcv(sk, skb);  		} -	} else -		sk_add_backlog(sk, skb); +	} else if (unlikely(sk_add_backlog(sk, skb))) { +		bh_unlock_sock(sk); +		NET_INC_STATS_BH(net, LINUX_MIB_TCPBACKLOGDROP); +		goto discard_and_relse; +	}  	bh_unlock_sock(sk);  	sock_put(sk);  |