net: add pskb_may_pull_reason() helper
authorEric Dumazet <edumazet@google.com>
Fri, 10 Feb 2023 18:47:06 +0000 (18:47 +0000)
committerJakub Kicinski <kuba@kernel.org>
Tue, 14 Feb 2023 03:55:32 +0000 (19:55 -0800)
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>
include/linux/skbuff.h

index 47ab28a..d5602b1 100644 (file)
@@ -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)