|
@@ -244,6 +244,55 @@ nodata:
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(__alloc_skb);
|
|
EXPORT_SYMBOL(__alloc_skb);
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * build_skb - build a network buffer
|
|
|
|
+ * @data: data buffer provided by caller
|
|
|
|
+ *
|
|
|
|
+ * Allocate a new &sk_buff. Caller provides space holding head and
|
|
|
|
+ * skb_shared_info. @data must have been allocated by kmalloc()
|
|
|
|
+ * The return is the new skb buffer.
|
|
|
|
+ * On a failure the return is %NULL, and @data is not freed.
|
|
|
|
+ * Notes :
|
|
|
|
+ * Before IO, driver allocates only data buffer where NIC put incoming frame
|
|
|
|
+ * Driver should add room at head (NET_SKB_PAD) and
|
|
|
|
+ * MUST add room at tail (SKB_DATA_ALIGN(skb_shared_info))
|
|
|
|
+ * After IO, driver calls build_skb(), to allocate sk_buff and populate it
|
|
|
|
+ * before giving packet to stack.
|
|
|
|
+ * RX rings only contains data buffers, not full skbs.
|
|
|
|
+ */
|
|
|
|
+struct sk_buff *build_skb(void *data)
|
|
|
|
+{
|
|
|
|
+ struct skb_shared_info *shinfo;
|
|
|
|
+ struct sk_buff *skb;
|
|
|
|
+ unsigned int size;
|
|
|
|
+
|
|
|
|
+ skb = kmem_cache_alloc(skbuff_head_cache, GFP_ATOMIC);
|
|
|
|
+ if (!skb)
|
|
|
|
+ return NULL;
|
|
|
|
+
|
|
|
|
+ size = ksize(data) - SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
|
|
|
|
+
|
|
|
|
+ memset(skb, 0, offsetof(struct sk_buff, tail));
|
|
|
|
+ skb->truesize = SKB_TRUESIZE(size);
|
|
|
|
+ atomic_set(&skb->users, 1);
|
|
|
|
+ skb->head = data;
|
|
|
|
+ skb->data = data;
|
|
|
|
+ skb_reset_tail_pointer(skb);
|
|
|
|
+ skb->end = skb->tail + size;
|
|
|
|
+#ifdef NET_SKBUFF_DATA_USES_OFFSET
|
|
|
|
+ skb->mac_header = ~0U;
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ /* make sure we initialize shinfo sequentially */
|
|
|
|
+ shinfo = skb_shinfo(skb);
|
|
|
|
+ memset(shinfo, 0, offsetof(struct skb_shared_info, dataref));
|
|
|
|
+ atomic_set(&shinfo->dataref, 1);
|
|
|
|
+ kmemcheck_annotate_variable(shinfo->destructor_arg);
|
|
|
|
+
|
|
|
|
+ return skb;
|
|
|
|
+}
|
|
|
|
+EXPORT_SYMBOL(build_skb);
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* __netdev_alloc_skb - allocate an skbuff for rx on a specific device
|
|
* __netdev_alloc_skb - allocate an skbuff for rx on a specific device
|
|
* @dev: network device to receive on
|
|
* @dev: network device to receive on
|