Commit bfe82422 authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds

[PATCH] add skb_pad/skb_padto functionality

This is the stuff in 2.4 which DaveM has been over so I hope is ok for 2.5.
It provides a simple API for driver writers with hardware that doesn't
do packet padding to say 'make sure n bytes beyond the data is all clear'
for DMA etc.
parent c257c8b6
......@@ -287,6 +287,7 @@ extern struct sk_buff *skb_realloc_headroom(struct sk_buff *skb,
extern struct sk_buff *skb_copy_expand(const struct sk_buff *skb,
int newheadroom, int newtailroom,
int priority);
extern struct sk_buff * skb_pad(struct sk_buff *skb, int pad);
#define dev_kfree_skb(a) kfree_skb(a)
extern void skb_over_panic(struct sk_buff *skb, int len,
void *here);
......@@ -1087,6 +1088,26 @@ static inline int skb_cow(struct sk_buff *skb, unsigned int headroom)
return 0;
}
/**
* skb_padto - pad an skbuff up to a minimal size
* @skb: buffer to pad
* @len: minimal length
*
* Pads up a buffer to ensure the trailing bytes exist and are
* blanked. If the buffer already contains sufficient data it
* is untouched. Returns the buffer, which may be a replacement
* for the original, or NULL for out of memory - in which case
* the original buffer is still freed.
*/
static inline struct sk_buff *skb_padto(struct sk_buff *skb, unsigned int len)
{
unsigned int size = skb->len + skb->data_len;
if (likely(size >= len))
return skb;
return skb_pad(skb, len-size);
}
/**
* skb_linearize - convert paged skb to linear one
* @skb: buffer to linarize
......
......@@ -761,6 +761,35 @@ struct sk_buff *skb_copy_expand(const struct sk_buff *skb,
return n;
}
/**
* skb_pad - zero pad the tail of an skb
* @skb: buffer to pad
* @pad: space to pad
*
* Ensure that a buffer is followed by a padding area that is zero
* filled. Used by network drivers which may DMA or transfer data
* beyond the buffer end onto the wire.
*
* May return NULL in out of memory cases.
*/
struct sk_buff *skb_pad(struct sk_buff *skb, int pad)
{
struct sk_buff *nskb;
/* If the skbuff is non linear tailroom is always zero.. */
if (skb_tailroom(skb) >= pad) {
memset(skb->data+skb->len, 0, pad);
return skb;
}
nskb = skb_copy_expand(skb, skb_headroom(skb), skb_tailroom(skb) + pad, GFP_ATOMIC);
kfree_skb(skb);
if (nskb)
memset(nskb->data+nskb->len, 0, pad);
return nskb;
}
/* Trims skb to length len. It can change skb pointers, if "realloc" is 1.
* If realloc==0 and trimming is impossible without change of data,
* it is BUG().
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment