sock: deduplicate errqueue dequeue
[cascardo/linux.git] / net / core / skbuff.c
index 163b673..53ce536 100644 (file)
@@ -3491,6 +3491,26 @@ int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
 }
 EXPORT_SYMBOL(sock_queue_err_skb);
 
+struct sk_buff *sock_dequeue_err_skb(struct sock *sk)
+{
+       struct sk_buff_head *q = &sk->sk_error_queue;
+       struct sk_buff *skb, *skb_next;
+       int err = 0;
+
+       spin_lock_bh(&q->lock);
+       skb = __skb_dequeue(q);
+       if (skb && (skb_next = skb_peek(q)))
+               err = SKB_EXT_ERR(skb_next)->ee.ee_errno;
+       spin_unlock_bh(&q->lock);
+
+       sk->sk_err = err;
+       if (err)
+               sk->sk_error_report(sk);
+
+       return skb;
+}
+EXPORT_SYMBOL(sock_dequeue_err_skb);
+
 void __skb_tstamp_tx(struct sk_buff *orig_skb,
                     struct skb_shared_hwtstamps *hwtstamps,
                     struct sock *sk, int tstype)