On Fri, 2017-06-16 at 14:29 +0200, Johannes Berg wrote:
> Changes from v1:
>  * add skb_put_u8() as suggested by Joe and Bjørn
> 
> Again build-tested by myself and kbuild bot.

Now that I think about it, I did something similar in 2015
https://www.spinics.net/lists/netdev/msg327404.html

At that time Eric Dumazet objected to the API expansion.

And here's an FYI that was a bit surprising to me:

Adding separate EXPORT_SYMBOL functions for skb_put_zero
and skb_put_data that do the memset/memcpy does not
shrink an x86-64 defconfig kernel image much at all.

$ size vmlinux.new vmlinux.old
   text    data     bss     dec     hex 
filename
10779941        4707128  892928 16379997         f9f05d 
vmlinux.new
10780631        4707128  892928 16380687         f9f30f 
vmlinux.old

This was the patch I tested:
---
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 852feacf4bbf..9de7c642ee4f 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1904,24 +1904,8 @@ static inline void *__skb_put(struct sk_buff *skb, 
unsigned int len)
        return tmp;
 }
 
-static inline void *skb_put_zero(struct sk_buff *skb, unsigned int len)
-{
-       void *tmp = skb_put(skb, len);
-
-       memset(tmp, 0, len);
-
-       return tmp;
-}
-
-static inline void *skb_put_data(struct sk_buff *skb, const void *data,
-                                unsigned int len)
-{
-       void *tmp = skb_put(skb, len);
-
-       memcpy(tmp, data, len);
-
-       return tmp;
-}
+void *skb_put_zero(struct sk_buff *skb, unsigned int len);
+void *skb_put_data(struct sk_buff *skb, const void *data, unsigned int len);
 
 static inline void skb_put_u8(struct sk_buff *skb, u8 val)
 {
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index f75897a33fa4..327f7cd2e0bb 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -1431,6 +1431,19 @@ void *pskb_put(struct sk_buff *skb, struct sk_buff 
*tail, int len)
 }
 EXPORT_SYMBOL_GPL(pskb_put);
 
+static __always_inline void *___skb_put(struct sk_buff *skb, unsigned int len)
+{
+       void *tmp = skb_tail_pointer(skb);
+
+       SKB_LINEAR_ASSERT(skb);
+       skb->tail += len;
+       skb->len  += len;
+       if (unlikely(skb->tail > skb->end))
+               skb_over_panic(skb, len, __builtin_return_address(0));
+
+       return tmp;
+}
+
 /**
  *     skb_put - add data to a buffer
  *     @skb: buffer to use
@@ -1442,17 +1455,42 @@ EXPORT_SYMBOL_GPL(pskb_put);
  */
 void *skb_put(struct sk_buff *skb, unsigned int len)
 {
-       void *tmp = skb_tail_pointer(skb);
-       SKB_LINEAR_ASSERT(skb);
-       skb->tail += len;
-       skb->len  += len;
-       if (unlikely(skb->tail > skb->end))
-               skb_over_panic(skb, len, __builtin_return_address(0));
-       return tmp;
+       return ___skb_put(skb, len);
 }
 EXPORT_SYMBOL(skb_put);
 
 /**
+ *     skb_put_zero - add zeroed data to a buffer
+ *     @skb: buffer to use
+ *     @len: amount of zeroed data to add
+ *
+ *     This function extends the used data area of the buffer. If this would
+ *     exceed the total buffer size the kernel will panic. A pointer to the
+ *     first byte of the extra data is returned.
+ */
+void *skb_put_zero(struct sk_buff *skb, unsigned int len)
+{
+       return memset(___skb_put(skb, len), 0, len);
+}
+EXPORT_SYMBOL(skb_put_zero);
+
+/**
+ *     skb_put_data - Copy data to a buffer
+ *     @skb: buffer to use
+ *     @data: pointer to data to copy
+ *     @len: amount of data to add
+ *
+ *     This function extends the used data area of the buffer. If this would
+ *     exceed the total buffer size the kernel will panic. A pointer to the
+ *     first byte of the extra data is returned.
+ */
+void *skb_put_data(struct sk_buff *skb, const void *data, unsigned int len)
+{
+       return memcpy(___skb_put(skb, len), data, len);
+}
+EXPORT_SYMBOL(skb_put_data);
+
+/**
  *     skb_push - add data to the start of a buffer
  *     @skb: buffer to use
  *     @len: amount of data to add

Reply via email to