aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/skbuff.h
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-08-23 15:13:41 -0400
committerDavid S. Miller <davem@davemloft.net>2014-08-23 15:13:41 -0400
commit690e36e726d00d2528bc569809048adf61550d80 (patch)
treee28c0ca1fce29a077415235ec3b90db4527de6c9 /include/linux/skbuff.h
parent1ad676a6bc4b284b68e4d24c0eac366438a32af6 (diff)
net: Allow raw buffers to be passed into the flow dissector.
Drivers, and perhaps other entities we have not yet considered, sometimes want to know how deep the protocol headers go before deciding how large of an SKB to allocate and how much of the packet to place into the linear SKB area. For example, consider a driver which has a device which DMAs into pools of pages and then tells the driver where the data went in the DMA descriptor(s). The driver can then build an SKB and reference most of the data via SKB fragments (which are page/offset/length triplets). However at least some of the front of the packet should be placed into the linear SKB area, which comes before the fragments, so that packet processing can get at the headers efficiently. The first thing each protocol layer is going to do is a "pskb_may_pull()" so we might as well aggregate as much of this as possible while we're building the SKB in the driver. Part of supporting this is that we don't have an SKB yet, so we want to be able to let the flow dissector operate on a raw buffer in order to compute the offset of the end of the headers. So now we have a __skb_flow_dissect() which takes an explicit data pointer and length. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/skbuff.h')
-rw-r--r--include/linux/skbuff.h18
1 files changed, 12 insertions, 6 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index abde271c18ae..18ddf9684a27 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -2567,20 +2567,26 @@ __wsum __skb_checksum(const struct sk_buff *skb, int offset, int len,
2567__wsum skb_checksum(const struct sk_buff *skb, int offset, int len, 2567__wsum skb_checksum(const struct sk_buff *skb, int offset, int len,
2568 __wsum csum); 2568 __wsum csum);
2569 2569
2570static inline void *skb_header_pointer(const struct sk_buff *skb, int offset, 2570static inline void *__skb_header_pointer(const struct sk_buff *skb, int offset,
2571 int len, void *buffer) 2571 int len, void *data, int hlen, void *buffer)
2572{ 2572{
2573 int hlen = skb_headlen(skb);
2574
2575 if (hlen - offset >= len) 2573 if (hlen - offset >= len)
2576 return skb->data + offset; 2574 return data + offset;
2577 2575
2578 if (skb_copy_bits(skb, offset, buffer, len) < 0) 2576 if (!skb ||
2577 skb_copy_bits(skb, offset, buffer, len) < 0)
2579 return NULL; 2578 return NULL;
2580 2579
2581 return buffer; 2580 return buffer;
2582} 2581}
2583 2582
2583static inline void *skb_header_pointer(const struct sk_buff *skb, int offset,
2584 int len, void *buffer)
2585{
2586 return __skb_header_pointer(skb, offset, len, skb->data,
2587 skb_headlen(skb), buffer);
2588}
2589
2584/** 2590/**
2585 * skb_needs_linearize - check if we need to linearize a given skb 2591 * skb_needs_linearize - check if we need to linearize a given skb
2586 * depending on the given device features. 2592 * depending on the given device features.