git: c39947cdd369 - stable/13 - LinuxKPI: skbuff: start implementing skb_copy()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 18 Apr 2022 09:33:51 UTC
The branch stable/13 has been updated by bz:
URL: https://cgit.FreeBSD.org/src/commit/?id=c39947cdd36988852a6144586a735f6be95f4861
commit c39947cdd36988852a6144586a735f6be95f4861
Author: Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2022-04-15 12:30:51 +0000
Commit: Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2022-04-18 09:32:58 +0000
LinuxKPI: skbuff: start implementing skb_copy()
Implement skb_copy() with omissions of fragments and possibly other fields
for now. Should we hit frags at any point a log message will let us know.
For the few cases we need this currently this is enough.
Sponsored by: The FreeBSD Foundation
(cherry picked from commit 349b042b90057c1e9dbb64dfdb894fe03ea20a1d)
---
sys/compat/linuxkpi/common/include/linux/skbuff.h | 10 ++++--
sys/compat/linuxkpi/common/src/linux_skbuff.c | 38 +++++++++++++++++++++++
2 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/sys/compat/linuxkpi/common/include/linux/skbuff.h b/sys/compat/linuxkpi/common/include/linux/skbuff.h
index 2b1b66844640..3caf7059dd15 100644
--- a/sys/compat/linuxkpi/common/include/linux/skbuff.h
+++ b/sys/compat/linuxkpi/common/include/linux/skbuff.h
@@ -172,6 +172,8 @@ struct sk_buff *linuxkpi_alloc_skb(size_t, gfp_t);
struct sk_buff *linuxkpi_dev_alloc_skb(size_t, gfp_t);
void linuxkpi_kfree_skb(struct sk_buff *);
+struct sk_buff *linuxkpi_skb_copy(struct sk_buff *, gfp_t);
+
/* -------------------------------------------------------------------------- */
static inline struct sk_buff *
@@ -667,9 +669,11 @@ skb_queue_prev(struct sk_buff_head *q, struct sk_buff *skb)
static inline struct sk_buff *
skb_copy(struct sk_buff *skb, gfp_t gfp)
{
- SKB_TRACE(skb);
- SKB_TODO();
- return (NULL);
+ struct sk_buff *new;
+
+ new = linuxkpi_skb_copy(skb, gfp);
+ SKB_TRACE2(skb, new);
+ return (new);
}
static inline void
diff --git a/sys/compat/linuxkpi/common/src/linux_skbuff.c b/sys/compat/linuxkpi/common/src/linux_skbuff.c
index dfa9dfb2ceb4..df1f6439c694 100644
--- a/sys/compat/linuxkpi/common/src/linux_skbuff.c
+++ b/sys/compat/linuxkpi/common/src/linux_skbuff.c
@@ -111,6 +111,44 @@ linuxkpi_dev_alloc_skb(size_t size, gfp_t gfp)
return (skb);
}
+struct sk_buff *
+linuxkpi_skb_copy(struct sk_buff *skb, gfp_t gfp)
+{
+ struct sk_buff *new;
+ struct skb_shared_info *shinfo;
+ size_t len;
+ unsigned int headroom;
+
+ /* Full buffer size + any fragments. */
+ len = skb->end - skb->head + skb->data_len;
+
+ new = linuxkpi_alloc_skb(len, gfp);
+ if (new == NULL)
+ return (NULL);
+
+ headroom = skb_headroom(skb);
+ /* Fixup head and end. */
+ skb_reserve(new, headroom); /* data and tail move headroom forward. */
+ skb_put(new, skb->len); /* tail and len get adjusted */
+
+ /* Copy data. */
+ memcpy(new->head, skb->data - headroom, headroom + skb->len);
+
+ /* Deal with fragments. */
+ shinfo = skb->shinfo;
+ if (shinfo->nr_frags > 0) {
+ printf("%s:%d: NOT YET SUPPORTED; missing %d frags\n",
+ __func__, __LINE__, shinfo->nr_frags);
+ SKB_TODO();
+ }
+
+ /* Deal with header fields. */
+ memcpy(new->cb, skb->cb, sizeof(skb->cb));
+ SKB_IMPROVE("more header fields to copy?");
+
+ return (new);
+}
+
void
linuxkpi_kfree_skb(struct sk_buff *skb)
{