diff options
author | Eric Dumazet <edumazet@google.com> | 2023-02-10 18:47:06 +0000 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2023-02-13 19:55:32 -0800 |
commit | 1fb2d41501f38192d8a19da585cd441cf8845697 (patch) | |
tree | 81c97b4bcf20c5689ebfc82c53d382bcdf8f3b25 /include/linux/skbuff.h | |
parent | dc68eaf2c29f410fb078fd6da8e56201d3282e0b (diff) | |
download | lwn-1fb2d41501f38192d8a19da585cd441cf8845697.tar.gz lwn-1fb2d41501f38192d8a19da585cd441cf8845697.zip |
net: add pskb_may_pull_reason() helper
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>
Diffstat (limited to 'include/linux/skbuff.h')
-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 47ab28a37f2f..d5602b15c714 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2631,13 +2631,24 @@ 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) { 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) |