aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/core/skbuff.c20
-rw-r--r--net/core/sock.c14
-rw-r--r--net/ipv4/ip_sockglue.c15
-rw-r--r--net/ipv6/datagram.c15
-rw-r--r--net/rxrpc/ar-error.c14
5 files changed, 27 insertions, 51 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 163b673f9e62..53ce536e3d6e 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -3491,6 +3491,26 @@ int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
3491} 3491}
3492EXPORT_SYMBOL(sock_queue_err_skb); 3492EXPORT_SYMBOL(sock_queue_err_skb);
3493 3493
3494struct sk_buff *sock_dequeue_err_skb(struct sock *sk)
3495{
3496 struct sk_buff_head *q = &sk->sk_error_queue;
3497 struct sk_buff *skb, *skb_next;
3498 int err = 0;
3499
3500 spin_lock_bh(&q->lock);
3501 skb = __skb_dequeue(q);
3502 if (skb && (skb_next = skb_peek(q)))
3503 err = SKB_EXT_ERR(skb_next)->ee.ee_errno;
3504 spin_unlock_bh(&q->lock);
3505
3506 sk->sk_err = err;
3507 if (err)
3508 sk->sk_error_report(sk);
3509
3510 return skb;
3511}
3512EXPORT_SYMBOL(sock_dequeue_err_skb);
3513
3494void __skb_tstamp_tx(struct sk_buff *orig_skb, 3514void __skb_tstamp_tx(struct sk_buff *orig_skb,
3495 struct skb_shared_hwtstamps *hwtstamps, 3515 struct skb_shared_hwtstamps *hwtstamps,
3496 struct sock *sk, int tstype) 3516 struct sock *sk, int tstype)
diff --git a/net/core/sock.c b/net/core/sock.c
index f7f2352200ad..f1a638ee93d9 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -2488,11 +2488,11 @@ int sock_recv_errqueue(struct sock *sk, struct msghdr *msg, int len,
2488 int level, int type) 2488 int level, int type)
2489{ 2489{
2490 struct sock_exterr_skb *serr; 2490 struct sock_exterr_skb *serr;
2491 struct sk_buff *skb, *skb2; 2491 struct sk_buff *skb;
2492 int copied, err; 2492 int copied, err;
2493 2493
2494 err = -EAGAIN; 2494 err = -EAGAIN;
2495 skb = skb_dequeue(&sk->sk_error_queue); 2495 skb = sock_dequeue_err_skb(sk);
2496 if (skb == NULL) 2496 if (skb == NULL)
2497 goto out; 2497 goto out;
2498 2498
@@ -2513,16 +2513,6 @@ int sock_recv_errqueue(struct sock *sk, struct msghdr *msg, int len,
2513 msg->msg_flags |= MSG_ERRQUEUE; 2513 msg->msg_flags |= MSG_ERRQUEUE;
2514 err = copied; 2514 err = copied;
2515 2515
2516 /* Reset and regenerate socket error */
2517 spin_lock_bh(&sk->sk_error_queue.lock);
2518 sk->sk_err = 0;
2519 if ((skb2 = skb_peek(&sk->sk_error_queue)) != NULL) {
2520 sk->sk_err = SKB_EXT_ERR(skb2)->ee.ee_errno;
2521 spin_unlock_bh(&sk->sk_error_queue.lock);
2522 sk->sk_error_report(sk);
2523 } else
2524 spin_unlock_bh(&sk->sk_error_queue.lock);
2525
2526out_free_skb: 2516out_free_skb:
2527 kfree_skb(skb); 2517 kfree_skb(skb);
2528out: 2518out:
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 5cb830c78990..455e75bcb167 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -405,7 +405,7 @@ void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 port, u32 inf
405int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) 405int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
406{ 406{
407 struct sock_exterr_skb *serr; 407 struct sock_exterr_skb *serr;
408 struct sk_buff *skb, *skb2; 408 struct sk_buff *skb;
409 DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name); 409 DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name);
410 struct { 410 struct {
411 struct sock_extended_err ee; 411 struct sock_extended_err ee;
@@ -415,7 +415,7 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
415 int copied; 415 int copied;
416 416
417 err = -EAGAIN; 417 err = -EAGAIN;
418 skb = skb_dequeue(&sk->sk_error_queue); 418 skb = sock_dequeue_err_skb(sk);
419 if (skb == NULL) 419 if (skb == NULL)
420 goto out; 420 goto out;
421 421
@@ -462,17 +462,6 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
462 msg->msg_flags |= MSG_ERRQUEUE; 462 msg->msg_flags |= MSG_ERRQUEUE;
463 err = copied; 463 err = copied;
464 464
465 /* Reset and regenerate socket error */
466 spin_lock_bh(&sk->sk_error_queue.lock);
467 sk->sk_err = 0;
468 skb2 = skb_peek(&sk->sk_error_queue);
469 if (skb2 != NULL) {
470 sk->sk_err = SKB_EXT_ERR(skb2)->ee.ee_errno;
471 spin_unlock_bh(&sk->sk_error_queue.lock);
472 sk->sk_error_report(sk);
473 } else
474 spin_unlock_bh(&sk->sk_error_queue.lock);
475
476out_free_skb: 465out_free_skb:
477 kfree_skb(skb); 466 kfree_skb(skb);
478out: 467out:
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 1844e874a350..2cdc38338be3 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -332,7 +332,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
332{ 332{
333 struct ipv6_pinfo *np = inet6_sk(sk); 333 struct ipv6_pinfo *np = inet6_sk(sk);
334 struct sock_exterr_skb *serr; 334 struct sock_exterr_skb *serr;
335 struct sk_buff *skb, *skb2; 335 struct sk_buff *skb;
336 DECLARE_SOCKADDR(struct sockaddr_in6 *, sin, msg->msg_name); 336 DECLARE_SOCKADDR(struct sockaddr_in6 *, sin, msg->msg_name);
337 struct { 337 struct {
338 struct sock_extended_err ee; 338 struct sock_extended_err ee;
@@ -342,7 +342,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
342 int copied; 342 int copied;
343 343
344 err = -EAGAIN; 344 err = -EAGAIN;
345 skb = skb_dequeue(&sk->sk_error_queue); 345 skb = sock_dequeue_err_skb(sk);
346 if (skb == NULL) 346 if (skb == NULL)
347 goto out; 347 goto out;
348 348
@@ -415,17 +415,6 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
415 msg->msg_flags |= MSG_ERRQUEUE; 415 msg->msg_flags |= MSG_ERRQUEUE;
416 err = copied; 416 err = copied;
417 417
418 /* Reset and regenerate socket error */
419 spin_lock_bh(&sk->sk_error_queue.lock);
420 sk->sk_err = 0;
421 if ((skb2 = skb_peek(&sk->sk_error_queue)) != NULL) {
422 sk->sk_err = SKB_EXT_ERR(skb2)->ee.ee_errno;
423 spin_unlock_bh(&sk->sk_error_queue.lock);
424 sk->sk_error_report(sk);
425 } else {
426 spin_unlock_bh(&sk->sk_error_queue.lock);
427 }
428
429out_free_skb: 418out_free_skb:
430 kfree_skb(skb); 419 kfree_skb(skb);
431out: 420out:
diff --git a/net/rxrpc/ar-error.c b/net/rxrpc/ar-error.c
index db57458c824c..74c0fcd36838 100644
--- a/net/rxrpc/ar-error.c
+++ b/net/rxrpc/ar-error.c
@@ -37,7 +37,7 @@ void rxrpc_UDP_error_report(struct sock *sk)
37 37
38 _enter("%p{%d}", sk, local->debug_id); 38 _enter("%p{%d}", sk, local->debug_id);
39 39
40 skb = skb_dequeue(&sk->sk_error_queue); 40 skb = sock_dequeue_err_skb(sk);
41 if (!skb) { 41 if (!skb) {
42 _leave("UDP socket errqueue empty"); 42 _leave("UDP socket errqueue empty");
43 return; 43 return;
@@ -111,18 +111,6 @@ void rxrpc_UDP_error_report(struct sock *sk)
111 skb_queue_tail(&trans->error_queue, skb); 111 skb_queue_tail(&trans->error_queue, skb);
112 rxrpc_queue_work(&trans->error_handler); 112 rxrpc_queue_work(&trans->error_handler);
113 113
114 /* reset and regenerate socket error */
115 spin_lock_bh(&sk->sk_error_queue.lock);
116 sk->sk_err = 0;
117 skb = skb_peek(&sk->sk_error_queue);
118 if (skb) {
119 sk->sk_err = SKB_EXT_ERR(skb)->ee.ee_errno;
120 spin_unlock_bh(&sk->sk_error_queue.lock);
121 sk->sk_error_report(sk);
122 } else {
123 spin_unlock_bh(&sk->sk_error_queue.lock);
124 }
125
126 _leave(""); 114 _leave("");
127} 115}
128 116