diff options
author | Christian Hopps <chopps@labn.net> | 2024-08-15 19:21:14 +0200 |
---|---|---|
committer | Steffen Klassert <steffen.klassert@secunet.com> | 2024-08-20 08:11:48 +0200 |
commit | 6ad8bc92a47702f0b5d0b96b680199910b89f688 (patch) | |
tree | a2713b111e104b02d0bcaea18b71d9255514be5a /net/core/skbuff.c | |
parent | xfrm: Remove documentation WARN_ON to limit return values for offloaded SA (diff) | |
download | linux-6ad8bc92a47702f0b5d0b96b680199910b89f688.tar.xz linux-6ad8bc92a47702f0b5d0b96b680199910b89f688.zip |
net: add copy from skb_seq_state to buffer function
Add an skb helper function to copy a range of bytes from within
an existing skb_seq_state.
Signed-off-by: Christian Hopps <chopps@labn.net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net/core/skbuff.c')
-rw-r--r-- | net/core/skbuff.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 83f8cd8aa2d1..fe4b2dc5c19b 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -4409,6 +4409,41 @@ void skb_abort_seq_read(struct skb_seq_state *st) } EXPORT_SYMBOL(skb_abort_seq_read); +/** + * skb_copy_seq_read() - copy from a skb_seq_state to a buffer + * @st: source skb_seq_state + * @offset: offset in source + * @to: destination buffer + * @len: number of bytes to copy + * + * Copy @len bytes from @offset bytes into the source @st to the destination + * buffer @to. `offset` should increase (or be unchanged) with each subsequent + * call to this function. If offset needs to decrease from the previous use `st` + * should be reset first. + * + * Return: 0 on success or -EINVAL if the copy ended early + */ +int skb_copy_seq_read(struct skb_seq_state *st, int offset, void *to, int len) +{ + const u8 *data; + u32 sqlen; + + for (;;) { + sqlen = skb_seq_read(offset, &data, st); + if (sqlen == 0) + return -EINVAL; + if (sqlen >= len) { + memcpy(to, data, len); + return 0; + } + memcpy(to, data, sqlen); + to += sqlen; + offset += sqlen; + len -= sqlen; + } +} +EXPORT_SYMBOL(skb_copy_seq_read); + #define TS_SKB_CB(state) ((struct skb_seq_state *) &((state)->cb)) static unsigned int skb_ts_get_next_block(unsigned int offset, const u8 **text, |