diff options
| author | Eric Dumazet <edumazet@google.com> | 2023-02-10 18:47:06 +0000 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2024-06-12 11:03:32 +0200 |
| commit | ce83060743247555c2bacb674997e3ce6234ce4a (patch) | |
| tree | a66e032ea555ace5c120d091aeb9bd5cd90b9223 /include | |
| parent | 43504dae4d20c41ddced1d1c64d3a9669d94bab7 (diff) | |
| download | linux-ce83060743247555c2bacb674997e3ce6234ce4a.tar.gz linux-ce83060743247555c2bacb674997e3ce6234ce4a.tar.bz2 linux-ce83060743247555c2bacb674997e3ce6234ce4a.zip | |
net: add pskb_may_pull_reason() helper
[ Upstream commit 1fb2d41501f38192d8a19da585cd441cf8845697 ]
pskb_may_pull() can fail for two different reasons.
Provide pskb_may_pull_reason() helper to distinguish
between these reasons.
It returns:
SKB_NOT_DROPPED_YET : Success
SKB_DROP_REASON_PKT_TOO_SMALL : packet too small
SKB_DROP_REASON_NOMEM : skb->head could not be resized
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 8bd67ebb50c0 ("net: bridge: xmit: make sure we have at least eth header len bytes")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/skbuff.h | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index cecd3b6bebb8..2b5466204888 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2636,15 +2636,26 @@ void *skb_pull_data(struct sk_buff *skb, size_t len); void *__pskb_pull_tail(struct sk_buff *skb, int delta); -static inline bool pskb_may_pull(struct sk_buff *skb, unsigned int len) +static inline enum skb_drop_reason +pskb_may_pull_reason(struct sk_buff *skb, unsigned int len) { DEBUG_NET_WARN_ON_ONCE(len > INT_MAX); if (likely(len <= skb_headlen(skb))) - return true; + return SKB_NOT_DROPPED_YET; + if (unlikely(len > skb->len)) - return false; - return __pskb_pull_tail(skb, len - skb_headlen(skb)) != NULL; + return SKB_DROP_REASON_PKT_TOO_SMALL; + + if (unlikely(!__pskb_pull_tail(skb, len - skb_headlen(skb)))) + return SKB_DROP_REASON_NOMEM; + + return SKB_NOT_DROPPED_YET; +} + +static inline bool pskb_may_pull(struct sk_buff *skb, unsigned int len) +{ + return pskb_may_pull_reason(skb, len) == SKB_NOT_DROPPED_YET; } static inline void *pskb_pull(struct sk_buff *skb, unsigned int len) |
