* [PATCH net-next] net: selectively purge error queue in IP_RECVERR / IPV6_RECVERR
@ 2023-08-18 17:41 Eric Dumazet
2023-08-18 18:04 ` Willem de Bruijn
0 siblings, 1 reply; 2+ messages in thread
From: Eric Dumazet @ 2023-08-18 17:41 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: netdev, eric.dumazet, Eric Dumazet, Willem de Bruijn,
Soheil Hassas Yeganeh
Setting IP_RECVERR and IPV6_RECVERR options to zero currently
purges the socket error queue, which was probably not expected
for zerocopy and tx_timestamp users.
I discovered this issue while preparing commit 6b5f43ea0815
("inet: move inet->recverr to inet->inet_flags"), I presume this
change does not need to be backported to stable kernels.
Add skb_errqueue_purge() helper to purge error messages only.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Willem de Bruijn <willemb@google.com>
Cc: Soheil Hassas Yeganeh <soheil@google.com>
---
include/linux/skbuff.h | 1 +
net/core/skbuff.c | 21 +++++++++++++++++++++
net/ipv4/ip_sockglue.c | 2 +-
net/ipv6/ipv6_sockglue.c | 2 +-
4 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index aa57e2eca33be01d6d1d55297a8ffcdb5b6a1f55..9a8200c7a0c3124d78e95f9524b854043a6fd368 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -3165,6 +3165,7 @@ static inline void __skb_queue_purge(struct sk_buff_head *list)
void skb_queue_purge(struct sk_buff_head *list);
unsigned int skb_rbtree_purge(struct rb_root *root);
+void skb_errqueue_purge(struct sk_buff_head *list);
void *__netdev_alloc_frag_align(unsigned int fragsz, unsigned int align_mask);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 33fdf04d4334dd71481bc1ecf7c131aff8f18826..e2ece6b822f442079c1ea20cdd5f6d0dc27ba8a5 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -3742,6 +3742,27 @@ unsigned int skb_rbtree_purge(struct rb_root *root)
return sum;
}
+void skb_errqueue_purge(struct sk_buff_head *list)
+{
+ struct sk_buff *skb, *next;
+ struct sk_buff_head kill;
+ unsigned long flags;
+
+ __skb_queue_head_init(&kill);
+
+ spin_lock_irqsave(&list->lock, flags);
+ skb_queue_walk_safe(list, skb, next) {
+ if (SKB_EXT_ERR(skb)->ee.ee_origin == SO_EE_ORIGIN_ZEROCOPY ||
+ SKB_EXT_ERR(skb)->ee.ee_origin == SO_EE_ORIGIN_TIMESTAMPING)
+ continue;
+ __skb_unlink(skb, list);
+ __skb_queue_tail(&kill, skb);
+ }
+ spin_unlock_irqrestore(&list->lock, flags);
+ __skb_queue_purge(&kill);
+}
+EXPORT_SYMBOL(skb_errqueue_purge);
+
/**
* skb_queue_head - queue a buffer at the list head
* @list: list to use
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 61b2e7bc7031501ff5a3ebeffc3f90be180fa09e..54ad0f0d5c2dd2273f290de5693060a2cb185534 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -976,7 +976,7 @@ int do_ip_setsockopt(struct sock *sk, int level, int optname,
case IP_RECVERR:
inet_assign_bit(RECVERR, sk, val);
if (!val)
- skb_queue_purge(&sk->sk_error_queue);
+ skb_errqueue_purge(&sk->sk_error_queue);
return 0;
case IP_RECVERR_RFC4884:
if (val < 0 || val > 1)
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index d19577a94bcc6120e85dafb2768521e6567c0511..0e2a0847b387f0f6f50211b89f92ac1e00a0b07a 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -923,7 +923,7 @@ int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
goto e_inval;
np->recverr = valbool;
if (!val)
- skb_queue_purge(&sk->sk_error_queue);
+ skb_errqueue_purge(&sk->sk_error_queue);
retv = 0;
break;
case IPV6_FLOWINFO_SEND:
--
2.42.0.rc1.204.g551eb34607-goog
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH net-next] net: selectively purge error queue in IP_RECVERR / IPV6_RECVERR
2023-08-18 17:41 [PATCH net-next] net: selectively purge error queue in IP_RECVERR / IPV6_RECVERR Eric Dumazet
@ 2023-08-18 18:04 ` Willem de Bruijn
0 siblings, 0 replies; 2+ messages in thread
From: Willem de Bruijn @ 2023-08-18 18:04 UTC (permalink / raw)
To: Eric Dumazet, David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: netdev, eric.dumazet, Eric Dumazet, Willem de Bruijn,
Soheil Hassas Yeganeh
Eric Dumazet wrote:
> Setting IP_RECVERR and IPV6_RECVERR options to zero currently
> purges the socket error queue, which was probably not expected
> for zerocopy and tx_timestamp users.
>
> I discovered this issue while preparing commit 6b5f43ea0815
> ("inet: move inet->recverr to inet->inet_flags"), I presume this
> change does not need to be backported to stable kernels.
>
> Add skb_errqueue_purge() helper to purge error messages only.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Willem de Bruijn <willemb@google.com>
> Cc: Soheil Hassas Yeganeh <soheil@google.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2023-08-18 18:04 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-18 17:41 [PATCH net-next] net: selectively purge error queue in IP_RECVERR / IPV6_RECVERR Eric Dumazet
2023-08-18 18:04 ` Willem de Bruijn
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.