diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2014-09-05 19:20:26 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-09-05 20:47:02 -0400 |
commit | 56193d1bce2b2759cb4bdcc00cd05544894a0c90 (patch) | |
tree | 621b2ce35961049dd263c2f83aee3d9ec39ac686 /net/ethernet | |
parent | 2c048e646212f9880e6f201771a30daa963d7f8b (diff) |
net: Add function for parsing the header length out of linear ethernet frames
This patch updates some of the flow_dissector api so that it can be used to
parse the length of ethernet buffers stored in fragments. Most of the
changes needed were to __skb_get_poff as it needed to be updated to support
sending a linear buffer instead of a skb.
I have split __skb_get_poff into two functions, the first is skb_get_poff
and it retains the functionality of the original __skb_get_poff. The other
function is __skb_get_poff which now works much like __skb_flow_dissect in
relation to skb_flow_dissect in that it provides the same functionality but
works with just a data buffer and hlen instead of needing an skb.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ethernet')
-rw-r--r-- | net/ethernet/eth.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index 5cebca134585..33a140e15834 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c | |||
@@ -146,6 +146,33 @@ int eth_rebuild_header(struct sk_buff *skb) | |||
146 | EXPORT_SYMBOL(eth_rebuild_header); | 146 | EXPORT_SYMBOL(eth_rebuild_header); |
147 | 147 | ||
148 | /** | 148 | /** |
149 | * eth_get_headlen - determine the the length of header for an ethernet frame | ||
150 | * @data: pointer to start of frame | ||
151 | * @len: total length of frame | ||
152 | * | ||
153 | * Make a best effort attempt to pull the length for all of the headers for | ||
154 | * a given frame in a linear buffer. | ||
155 | */ | ||
156 | u32 eth_get_headlen(void *data, unsigned int len) | ||
157 | { | ||
158 | const struct ethhdr *eth = (const struct ethhdr *)data; | ||
159 | struct flow_keys keys; | ||
160 | |||
161 | /* this should never happen, but better safe than sorry */ | ||
162 | if (len < sizeof(*eth)) | ||
163 | return len; | ||
164 | |||
165 | /* parse any remaining L2/L3 headers, check for L4 */ | ||
166 | if (!__skb_flow_dissect(NULL, &keys, data, | ||
167 | eth->h_proto, sizeof(*eth), len)) | ||
168 | return max_t(u32, keys.thoff, sizeof(*eth)); | ||
169 | |||
170 | /* parse for any L4 headers */ | ||
171 | return min_t(u32, __skb_get_poff(NULL, data, &keys, len), len); | ||
172 | } | ||
173 | EXPORT_SYMBOL(eth_get_headlen); | ||
174 | |||
175 | /** | ||
149 | * eth_type_trans - determine the packet's protocol ID. | 176 | * eth_type_trans - determine the packet's protocol ID. |
150 | * @skb: received socket data | 177 | * @skb: received socket data |
151 | * @dev: receiving network device | 178 | * @dev: receiving network device |