#define SKB_DATAREF_SHIFT 16
#define SKB_DATAREF_MASK ((1 << SKB_DATAREF_SHIFT) - 1)
+struct skb_timeval {
+ u32 off_sec;
+ u32 off_usec;
+};
+
+
+enum {
+ SKB_FCLONE_UNAVAILABLE,
+ SKB_FCLONE_ORIG,
+ SKB_FCLONE_CLONE,
+};
+
/**
* struct sk_buff - socket buffer
* @next: Next buffer in list
* @prev: Previous buffer in list
* @list: List we are on
* @sk: Socket we are owned by
- * @stamp: Time we arrived
+ * @tstamp: Time we arrived
* @dev: Device we arrived on/are leaving by
* @input_dev: Device we arrived on
- * @real_dev: The real device we are using
* @h: Transport layer header
* @nh: Network layer header
* @mac: Link layer header
struct sk_buff *prev;
struct sock *sk;
- struct timeval stamp;
+ struct skb_timeval tstamp;
struct net_device *dev;
struct net_device *input_dev;
- struct net_device *real_dev;
union {
struct tcphdr *th;
ip_summed:2,
nohdr:1,
nfctinfo:3;
- __u8 pkt_type;
+ __u8 pkt_type:3,
+ fclone:2;
__be16 protocol;
void (*destructor)(struct sk_buff *skb);
#include <asm/system.h>
extern void __kfree_skb(struct sk_buff *skb);
-extern struct sk_buff *alloc_skb(unsigned int size,
- unsigned int __nocast priority);
+extern struct sk_buff *__alloc_skb(unsigned int size,
+ gfp_t priority, int fclone);
+static inline struct sk_buff *alloc_skb(unsigned int size,
+ gfp_t priority)
+{
+ return __alloc_skb(size, priority, 0);
+}
+
+static inline struct sk_buff *alloc_skb_fclone(unsigned int size,
+ gfp_t priority)
+{
+ return __alloc_skb(size, priority, 1);
+}
+
extern struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp,
unsigned int size,
- unsigned int __nocast priority);
+ gfp_t priority);
extern void kfree_skbmem(struct sk_buff *skb);
extern struct sk_buff *skb_clone(struct sk_buff *skb,
- unsigned int __nocast priority);
+ gfp_t priority);
extern struct sk_buff *skb_copy(const struct sk_buff *skb,
- unsigned int __nocast priority);
+ gfp_t priority);
extern struct sk_buff *pskb_copy(struct sk_buff *skb,
- unsigned int __nocast gfp_mask);
+ gfp_t gfp_mask);
extern int pskb_expand_head(struct sk_buff *skb,
int nhead, int ntail,
- unsigned int __nocast gfp_mask);
+ gfp_t gfp_mask);
extern struct sk_buff *skb_realloc_headroom(struct sk_buff *skb,
unsigned int headroom);
extern struct sk_buff *skb_copy_expand(const struct sk_buff *skb,
int newheadroom, int newtailroom,
- unsigned int __nocast priority);
+ gfp_t 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,
* NULL is returned on a memory allocation failure.
*/
static inline struct sk_buff *skb_share_check(struct sk_buff *skb,
- unsigned int __nocast pri)
+ gfp_t pri)
{
might_sleep_if(pri & __GFP_WAIT);
if (skb_shared(skb)) {
* %NULL is returned on a memory allocation failure.
*/
static inline struct sk_buff *skb_unshare(struct sk_buff *skb,
- unsigned int __nocast pri)
+ gfp_t pri)
{
might_sleep_if(pri & __GFP_WAIT);
if (skb_cloned(skb)) {
* %NULL is returned in there is no free memory.
*/
static inline struct sk_buff *__dev_alloc_skb(unsigned int length,
- unsigned int __nocast gfp_mask)
+ gfp_t gfp_mask)
{
struct sk_buff *skb = alloc_skb(length + 16, gfp_mask);
if (likely(skb))
* If there is no free memory -ENOMEM is returned, otherwise zero
* is returned and the old skb data released.
*/
-extern int __skb_linearize(struct sk_buff *skb, unsigned int __nocast gfp);
-static inline int skb_linearize(struct sk_buff *skb, unsigned int __nocast gfp)
+extern int __skb_linearize(struct sk_buff *skb, gfp_t gfp);
+static inline int skb_linearize(struct sk_buff *skb, gfp_t gfp)
{
return __skb_linearize(skb, gfp);
}
static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len)
{
- if (len >= skb->len)
+ if (likely(len >= skb->len))
return 0;
if (skb->ip_summed == CHECKSUM_HW)
skb->ip_summed = CHECKSUM_NONE;
extern void skb_split(struct sk_buff *skb,
struct sk_buff *skb1, const u32 len);
+extern void skb_release_data(struct sk_buff *skb);
+
static inline void *skb_header_pointer(const struct sk_buff *skb, int offset,
int len, void *buffer)
{
extern void skb_init(void);
extern void skb_add_mtu(int mtu);
+/**
+ * skb_get_timestamp - get timestamp from a skb
+ * @skb: skb to get stamp from
+ * @stamp: pointer to struct timeval to store stamp in
+ *
+ * Timestamps are stored in the skb as offsets to a base timestamp.
+ * This function converts the offset back to a struct timeval and stores
+ * it in stamp.
+ */
+static inline void skb_get_timestamp(const struct sk_buff *skb, struct timeval *stamp)
+{
+ stamp->tv_sec = skb->tstamp.off_sec;
+ stamp->tv_usec = skb->tstamp.off_usec;
+}
+
+/**
+ * skb_set_timestamp - set timestamp of a skb
+ * @skb: skb to set stamp of
+ * @stamp: pointer to struct timeval to get stamp from
+ *
+ * Timestamps are stored in the skb as offsets to a base timestamp.
+ * This function converts a struct timeval to an offset and stores
+ * it in the skb.
+ */
+static inline void skb_set_timestamp(struct sk_buff *skb, const struct timeval *stamp)
+{
+ skb->tstamp.off_sec = stamp->tv_sec;
+ skb->tstamp.off_usec = stamp->tv_usec;
+}
+
+extern void __net_timestamp(struct sk_buff *skb);
+
#ifdef CONFIG_NETFILTER
static inline void nf_conntrack_put(struct nf_conntrack *nfct)
{