do not integrate with kread
[linux-2.6.git] / include / linux / skbuff.h
index c7e0f55..099dc5e 100644 (file)
@@ -14,7 +14,6 @@
 #ifndef _LINUX_SKBUFF_H
 #define _LINUX_SKBUFF_H
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/compiler.h>
 #include <linux/time.h>
@@ -29,6 +28,7 @@
 #include <linux/net.h>
 #include <linux/textsearch.h>
 #include <net/checksum.h>
+#include <linux/dmaengine.h>
 
 #define HAVE_ALLOC_SKB         /* For the drivers to know */
 #define HAVE_ALIGNABLE_SKB     /* Ditto 8)                */
@@ -134,9 +134,10 @@ struct skb_frag_struct {
 struct skb_shared_info {
        atomic_t        dataref;
        unsigned short  nr_frags;
-       unsigned short  tso_size;
-       unsigned short  tso_segs;
-       unsigned short  ufo_size;
+       unsigned short  gso_size;
+       /* Warning: this field is not always filled in (UFO)! */
+       unsigned short  gso_segs;
+       unsigned short  gso_type;
        unsigned int    ip6_frag_id;
        struct sk_buff  *frag_list;
        skb_frag_t      frags[MAX_SKB_FRAGS];
@@ -168,6 +169,19 @@ enum {
        SKB_FCLONE_CLONE,
 };
 
+enum {
+       SKB_GSO_TCPV4 = 1 << 0,
+       SKB_GSO_UDP = 1 << 1,
+
+       /* This indicates the skb is from an untrusted source. */
+       SKB_GSO_DODGY = 1 << 2,
+
+       /* This indicates the tcp segment has CWR set. */
+       SKB_GSO_TCP_ECN = 1 << 3,
+
+       SKB_GSO_TCPV6 = 1 << 4,
+};
+
 /** 
  *     struct sk_buff - socket buffer
  *     @next: Next buffer in list
@@ -189,6 +203,8 @@ enum {
  *     @local_df: allow local fragmentation
  *     @cloned: Head may be cloned (check refcnt to be sure)
  *     @nohdr: Payload reference only, must not modify header
+ *     @proto_data_valid: Protocol data validated since arriving at localhost
+ *     @proto_csum_blank: Protocol csum must be added before leaving localhost
  *     @pkt_type: Packet class
  *     @fclone: skbuff clone status
  *     @ip_summed: Driver fed us an IP checksum
@@ -209,6 +225,9 @@ enum {
  *     @nf_bridge: Saved data about a bridged frame - see br_netfilter.c
  *     @tc_index: Traffic control index
  *     @tc_verd: traffic control verdict
+ *     @dma_cookie: a cookie to one of several possible DMA operations
+ *             done by skb DMA functions
+ *     @secmark: security marking
  */
 
 struct sk_buff {
@@ -265,7 +284,13 @@ struct sk_buff {
                                nfctinfo:3;
        __u8                    pkt_type:3,
                                fclone:2,
+#ifndef CONFIG_XEN
                                ipvs_property:1;
+#else
+                               ipvs_property:1,
+                               proto_data_valid:1,
+                               proto_csum_blank:1;
+#endif
        __be16                  protocol;
 
        void                    (*destructor)(struct sk_buff *skb);
@@ -288,6 +313,12 @@ struct sk_buff {
 #if defined(CONFIG_VNET) || defined(CONFIG_VNET_MODULE)
        xid_t                   xid;                    /* VServer context ID */
 #endif
+#ifdef CONFIG_NET_DMA
+       dma_cookie_t            dma_cookie;
+#endif
+#ifdef CONFIG_NETWORK_SECMARK
+       __u32                   secmark;
+#endif
 
        /* These elements must be at the end, see alloc_skb() for details.  */
        unsigned int            truesize;
@@ -324,7 +355,8 @@ static inline struct sk_buff *alloc_skb_fclone(unsigned int size,
 
 extern struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp,
                                            unsigned int size,
-                                           gfp_t priority);
+                                           gfp_t priority,
+                                           int fclone);
 extern void           kfree_skbmem(struct sk_buff *skb);
 extern struct sk_buff *skb_clone(struct sk_buff *skb,
                                 gfp_t priority);
@@ -340,7 +372,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,
                                       gfp_t priority);
-extern struct sk_buff *                skb_pad(struct sk_buff *skb, int pad);
+extern int            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);
@@ -583,6 +615,14 @@ static inline __u32 skb_queue_len(const struct sk_buff_head *list_)
        return list_->qlen;
 }
 
+/*
+ * This function creates a split out lock class for each invocation;
+ * this is needed for now since a whole lot of users of the skb-queue
+ * infrastructure in drivers have different locking usage (in hardirq)
+ * than the networking core (in softirq only). In the long run either the
+ * network layer or drivers should need annotation to consolidate the
+ * main types of usage into 3 classes.
+ */
 static inline void skb_queue_head_init(struct sk_buff_head *list)
 {
        spin_lock_init(&list->lock);
@@ -969,15 +1009,16 @@ static inline void skb_reserve(struct sk_buff *skb, int len)
 #define NET_SKB_PAD    16
 #endif
 
-extern int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc);
+extern int ___pskb_trim(struct sk_buff *skb, unsigned int len);
 
 static inline void __skb_trim(struct sk_buff *skb, unsigned int len)
 {
-       if (!skb->data_len) {
-               skb->len  = len;
-               skb->tail = skb->data + len;
-       } else
-               ___pskb_trim(skb, len, 0);
+       if (unlikely(skb->data_len)) {
+               WARN_ON(1);
+               return;
+       }
+       skb->len  = len;
+       skb->tail = skb->data + len;
 }
 
 /**
@@ -987,6 +1028,7 @@ static inline void __skb_trim(struct sk_buff *skb, unsigned int len)
  *
  *     Cut the length of a buffer down by removing data from the tail. If
  *     the buffer is already under the length specified it is not modified.
+ *     The skb must be linear.
  */
 static inline void skb_trim(struct sk_buff *skb, unsigned int len)
 {
@@ -997,12 +1039,10 @@ static inline void skb_trim(struct sk_buff *skb, unsigned int len)
 
 static inline int __pskb_trim(struct sk_buff *skb, unsigned int len)
 {
-       if (!skb->data_len) {
-               skb->len  = len;
-               skb->tail = skb->data+len;
-               return 0;
-       }
-       return ___pskb_trim(skb, len, 1);
+       if (skb->data_len)
+               return ___pskb_trim(skb, len);
+       __skb_trim(skb, len);
+       return 0;
 }
 
 static inline int pskb_trim(struct sk_buff *skb, unsigned int len)
@@ -1010,6 +1050,21 @@ static inline int pskb_trim(struct sk_buff *skb, unsigned int len)
        return (len < skb->len) ? __pskb_trim(skb, len) : 0;
 }
 
+/**
+ *     pskb_trim_unique - remove end from a paged unique (not cloned) buffer
+ *     @skb: buffer to alter
+ *     @len: new length
+ *
+ *     This is identical to pskb_trim except that the caller knows that
+ *     the skb is not cloned so we should never get an error due to out-
+ *     of-memory.
+ */
+static inline void pskb_trim_unique(struct sk_buff *skb, unsigned int len)
+{
+       int err = pskb_trim(skb, len);
+       BUG_ON(err);
+}
+
 /**
  *     skb_orphan - orphan a buffer
  *     @skb: buffer to orphan
@@ -1044,7 +1099,7 @@ static inline void __skb_queue_purge(struct sk_buff_head *list)
 
 #ifndef CONFIG_HAVE_ARCH_DEV_ALLOC_SKB
 /**
- *     __dev_alloc_skb - allocate an skbuff for sending
+ *     __dev_alloc_skb - allocate an skbuff for receiving
  *     @length: length to allocate
  *     @gfp_mask: get_free_pages mask, passed to alloc_skb
  *
@@ -1053,7 +1108,7 @@ static inline void __skb_queue_purge(struct sk_buff_head *list)
  *     the headroom they think they need without accounting for the
  *     built in space. The built in space is used for optimisations.
  *
- *     %NULL is returned in there is no free memory.
+ *     %NULL is returned if there is no free memory.
  */
 static inline struct sk_buff *__dev_alloc_skb(unsigned int length,
                                              gfp_t gfp_mask)
@@ -1064,11 +1119,11 @@ static inline struct sk_buff *__dev_alloc_skb(unsigned int length,
        return skb;
 }
 #else
-extern struct sk_buff *__dev_alloc_skb(unsigned int length, int gfp_mask);
+extern struct sk_buff *__dev_alloc_skb(unsigned int length, gfp_t gfp_mask);
 #endif
 
 /**
- *     dev_alloc_skb - allocate an skbuff for sending
+ *     dev_alloc_skb - allocate an skbuff for receiving
  *     @length: length to allocate
  *
  *     Allocate a new &sk_buff and assign it a usage count of one. The
@@ -1076,7 +1131,7 @@ extern struct sk_buff *__dev_alloc_skb(unsigned int length, int gfp_mask);
  *     the headroom they think they need without accounting for the
  *     built in space. The built in space is used for optimisations.
  *
- *     %NULL is returned in there is no free memory. Although this function
+ *     %NULL is returned if there is no free memory. Although this function
  *     allocates memory it can be called from an interrupt.
  */
 static inline struct sk_buff *dev_alloc_skb(unsigned int length)
@@ -1084,6 +1139,28 @@ static inline struct sk_buff *dev_alloc_skb(unsigned int length)
        return __dev_alloc_skb(length, GFP_ATOMIC);
 }
 
+extern struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
+               unsigned int length, gfp_t gfp_mask);
+
+/**
+ *     netdev_alloc_skb - allocate an skbuff for rx on a specific device
+ *     @dev: network device to receive on
+ *     @length: length to allocate
+ *
+ *     Allocate a new &sk_buff and assign it a usage count of one. The
+ *     buffer has unspecified headroom built in. Users should allocate
+ *     the headroom they think they need without accounting for the
+ *     built in space. The built in space is used for optimisations.
+ *
+ *     %NULL is returned if there is no free memory. Although this function
+ *     allocates memory it can be called from an interrupt.
+ */
+static inline struct sk_buff *netdev_alloc_skb(struct net_device *dev,
+               unsigned int length)
+{
+       return __netdev_alloc_skb(dev, length, GFP_ATOMIC);
+}
+
 /**
  *     skb_cow - copy header of skb when it is required
  *     @skb: buffer to cow
@@ -1117,16 +1194,15 @@ static inline int skb_cow(struct sk_buff *skb, unsigned int headroom)
  *
  *     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.
+ *     is untouched. Otherwise it is extended. Returns zero on
+ *     success. The skb is freed on error.
  */
  
-static inline struct sk_buff *skb_padto(struct sk_buff *skb, unsigned int len)
+static inline int skb_padto(struct sk_buff *skb, unsigned int len)
 {
        unsigned int size = skb->len;
        if (likely(size >= len))
-               return skb;
+               return 0;
        return skb_pad(skb, len-size);
 }
 
@@ -1163,18 +1239,34 @@ static inline int skb_can_coalesce(struct sk_buff *skb, int i,
        return 0;
 }
 
+static inline int __skb_linearize(struct sk_buff *skb)
+{
+       return __pskb_pull_tail(skb, skb->data_len) ? 0 : -ENOMEM;
+}
+
 /**
  *     skb_linearize - convert paged skb to linear one
  *     @skb: buffer to linarize
- *     @gfp: allocation mode
  *
  *     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, gfp_t gfp);
-static inline int skb_linearize(struct sk_buff *skb, gfp_t gfp)
+static inline int skb_linearize(struct sk_buff *skb)
 {
-       return __skb_linearize(skb, gfp);
+       return skb_is_nonlinear(skb) ? __skb_linearize(skb) : 0;
+}
+
+/**
+ *     skb_linearize_cow - make sure skb is linear and writable
+ *     @skb: buffer to process
+ *
+ *     If there is no free memory -ENOMEM is returned, otherwise zero
+ *     is returned and the old skb data released.
+ */
+static inline int skb_linearize_cow(struct sk_buff *skb)
+{
+       return skb_is_nonlinear(skb) || skb_cloned(skb) ?
+              __skb_linearize(skb) : 0;
 }
 
 /**
@@ -1270,7 +1362,7 @@ extern void              skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to);
 extern void           skb_split(struct sk_buff *skb,
                                 struct sk_buff *skb1, const u32 len);
 
-extern void           skb_release_data(struct sk_buff *skb);
+extern struct sk_buff *skb_segment(struct sk_buff *skb, int features);
 
 static inline void *skb_header_pointer(const struct sk_buff *skb, int offset,
                                       int len, void *buffer)
@@ -1400,5 +1492,28 @@ static inline void nf_reset(struct sk_buff *skb)
 static inline void nf_reset(struct sk_buff *skb) {}
 #endif /* CONFIG_NETFILTER */
 
+#ifdef CONFIG_NETWORK_SECMARK
+static inline void skb_copy_secmark(struct sk_buff *to, const struct sk_buff *from)
+{
+       to->secmark = from->secmark;
+}
+
+static inline void skb_init_secmark(struct sk_buff *skb)
+{
+       skb->secmark = 0;
+}
+#else
+static inline void skb_copy_secmark(struct sk_buff *to, const struct sk_buff *from)
+{ }
+
+static inline void skb_init_secmark(struct sk_buff *skb)
+{ }
+#endif
+
+static inline int skb_is_gso(const struct sk_buff *skb)
+{
+       return skb_shinfo(skb)->gso_size;
+}
+
 #endif /* __KERNEL__ */
 #endif /* _LINUX_SKBUFF_H */