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.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 277d71239d75..3979939804b7 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1774,6 +1774,7 @@ static void tcp_v4_fill_cb(struct sk_buff *skb, const struct iphdr *iph,
1774int tcp_v4_rcv(struct sk_buff *skb) 1774int tcp_v4_rcv(struct sk_buff *skb)
1775{ 1775{
1776 struct net *net = dev_net(skb->dev); 1776 struct net *net = dev_net(skb->dev);
1777 struct sk_buff *skb_to_free;
1777 int sdif = inet_sdif(skb); 1778 int sdif = inet_sdif(skb);
1778 const struct iphdr *iph; 1779 const struct iphdr *iph;
1779 const struct tcphdr *th; 1780 const struct tcphdr *th;
@@ -1905,11 +1906,17 @@ process:
1905 tcp_segs_in(tcp_sk(sk), skb); 1906 tcp_segs_in(tcp_sk(sk), skb);
1906 ret = 0; 1907 ret = 0;
1907 if (!sock_owned_by_user(sk)) { 1908 if (!sock_owned_by_user(sk)) {
1909 skb_to_free = sk->sk_rx_skb_cache;
1910 sk->sk_rx_skb_cache = NULL;
1908 ret = tcp_v4_do_rcv(sk, skb); 1911 ret = tcp_v4_do_rcv(sk, skb);
1909 } else if (tcp_add_backlog(sk, skb)) { 1912 } else {
1910 goto discard_and_relse; 1913 if (tcp_add_backlog(sk, skb))
1914 goto discard_and_relse;
1915 skb_to_free = NULL;
1911 } 1916 }
1912 bh_unlock_sock(sk); 1917 bh_unlock_sock(sk);
1918 if (skb_to_free)
1919 __kfree_skb(skb_to_free);
1913 1920
1914put_and_return: 1921put_and_return:
1915 if (refcounted) 1922 if (refcounted)