Skip to content

Commit 6ad8bc9

Browse files
choppsv1klassert
authored andcommitted
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 <[email protected]> Signed-off-by: Steffen Klassert <[email protected]>
1 parent 9b49f55 commit 6ad8bc9

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

include/linux/skbuff.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1433,6 +1433,7 @@ void skb_prepare_seq_read(struct sk_buff *skb, unsigned int from,
14331433
unsigned int skb_seq_read(unsigned int consumed, const u8 **data,
14341434
struct skb_seq_state *st);
14351435
void skb_abort_seq_read(struct skb_seq_state *st);
1436+
int skb_copy_seq_read(struct skb_seq_state *st, int offset, void *to, int len);
14361437

14371438
unsigned int skb_find_text(struct sk_buff *skb, unsigned int from,
14381439
unsigned int to, struct ts_config *config);

net/core/skbuff.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4409,6 +4409,41 @@ void skb_abort_seq_read(struct skb_seq_state *st)
44094409
}
44104410
EXPORT_SYMBOL(skb_abort_seq_read);
44114411

4412+
/**
4413+
* skb_copy_seq_read() - copy from a skb_seq_state to a buffer
4414+
* @st: source skb_seq_state
4415+
* @offset: offset in source
4416+
* @to: destination buffer
4417+
* @len: number of bytes to copy
4418+
*
4419+
* Copy @len bytes from @offset bytes into the source @st to the destination
4420+
* buffer @to. `offset` should increase (or be unchanged) with each subsequent
4421+
* call to this function. If offset needs to decrease from the previous use `st`
4422+
* should be reset first.
4423+
*
4424+
* Return: 0 on success or -EINVAL if the copy ended early
4425+
*/
4426+
int skb_copy_seq_read(struct skb_seq_state *st, int offset, void *to, int len)
4427+
{
4428+
const u8 *data;
4429+
u32 sqlen;
4430+
4431+
for (;;) {
4432+
sqlen = skb_seq_read(offset, &data, st);
4433+
if (sqlen == 0)
4434+
return -EINVAL;
4435+
if (sqlen >= len) {
4436+
memcpy(to, data, len);
4437+
return 0;
4438+
}
4439+
memcpy(to, data, sqlen);
4440+
to += sqlen;
4441+
offset += sqlen;
4442+
len -= sqlen;
4443+
}
4444+
}
4445+
EXPORT_SYMBOL(skb_copy_seq_read);
4446+
44124447
#define TS_SKB_CB(state) ((struct skb_seq_state *) &((state)->cb))
44134448

44144449
static unsigned int skb_ts_get_next_block(unsigned int offset, const u8 **text,

0 commit comments

Comments
 (0)