diff options
Diffstat (limited to 'net/ipv4/udp.c')
-rw-r--r-- | net/ipv4/udp.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 25294d43e147..b057653ceca9 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -1388,6 +1388,11 @@ void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len) | |||
1388 | unlock_sock_fast(sk, slow); | 1388 | unlock_sock_fast(sk, slow); |
1389 | } | 1389 | } |
1390 | 1390 | ||
1391 | /* we cleared the head states previously only if the skb lacks any IP | ||
1392 | * options, see __udp_queue_rcv_skb(). | ||
1393 | */ | ||
1394 | if (unlikely(IPCB(skb)->opt.optlen > 0)) | ||
1395 | skb_release_head_state(skb); | ||
1391 | consume_stateless_skb(skb); | 1396 | consume_stateless_skb(skb); |
1392 | } | 1397 | } |
1393 | EXPORT_SYMBOL_GPL(skb_consume_udp); | 1398 | EXPORT_SYMBOL_GPL(skb_consume_udp); |
@@ -1779,8 +1784,12 @@ static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
1779 | sk_mark_napi_id_once(sk, skb); | 1784 | sk_mark_napi_id_once(sk, skb); |
1780 | } | 1785 | } |
1781 | 1786 | ||
1782 | /* clear all pending head states while they are hot in the cache */ | 1787 | /* At recvmsg() time we need skb->dst to process IP options-related |
1783 | skb_release_head_state(skb); | 1788 | * cmsg, elsewhere can we clear all pending head states while they are |
1789 | * hot in the cache | ||
1790 | */ | ||
1791 | if (likely(IPCB(skb)->opt.optlen == 0)) | ||
1792 | skb_release_head_state(skb); | ||
1784 | 1793 | ||
1785 | rc = __udp_enqueue_schedule_skb(sk, skb); | 1794 | rc = __udp_enqueue_schedule_skb(sk, skb); |
1786 | if (rc < 0) { | 1795 | if (rc < 0) { |