git: 349b042b9005 - main - LinuxKPI: skbuff: start implementing skb_copy()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 15 Apr 2022 15:56:50 UTC
The branch main has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=349b042b90057c1e9dbb64dfdb894fe03ea20a1d commit 349b042b90057c1e9dbb64dfdb894fe03ea20a1d 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-15 15:54:03 +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 MFC after: 3 days --- 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) {