blob: 6a49acaa665137e55caf3138708135ee9c599799 [file] [log] [blame]
Jiri Pirkofbff9492015-05-12 14:56:15 +02001#include <linux/kernel.h>
Eric Dumazet0744dd02011-11-28 05:22:18 +00002#include <linux/skbuff.h>
Jesper Dangaard Brouerc452ed72012-01-24 16:03:33 -05003#include <linux/export.h>
Eric Dumazet0744dd02011-11-28 05:22:18 +00004#include <linux/ip.h>
5#include <linux/ipv6.h>
6#include <linux/if_vlan.h>
7#include <net/ip.h>
Eric Dumazetddbe5032012-07-18 08:11:12 +00008#include <net/ipv6.h>
Daniel Borkmannf77668d2013-03-19 06:39:30 +00009#include <linux/igmp.h>
10#include <linux/icmp.h>
11#include <linux/sctp.h>
12#include <linux/dccp.h>
Eric Dumazet0744dd02011-11-28 05:22:18 +000013#include <linux/if_tunnel.h>
14#include <linux/if_pppox.h>
15#include <linux/ppp_defs.h>
Jiri Pirko06635a32015-05-12 14:56:16 +020016#include <linux/stddef.h>
Jiri Pirko1bd758e2015-05-12 14:56:07 +020017#include <net/flow_dissector.h>
Alexander Duyck56193d12014-09-05 19:20:26 -040018#include <scsi/fc/fc_fcoe.h>
Eric Dumazet0744dd02011-11-28 05:22:18 +000019
Jiri Pirkofbff9492015-05-12 14:56:15 +020020static bool skb_flow_dissector_uses_key(struct flow_dissector *flow_dissector,
21 enum flow_dissector_key_id key_id)
22{
23 return flow_dissector->used_keys & (1 << key_id);
24}
25
26static void skb_flow_dissector_set_key(struct flow_dissector *flow_dissector,
27 enum flow_dissector_key_id key_id)
28{
29 flow_dissector->used_keys |= (1 << key_id);
30}
31
32static void *skb_flow_dissector_target(struct flow_dissector *flow_dissector,
33 enum flow_dissector_key_id key_id,
34 void *target_container)
35{
36 return ((char *) target_container) + flow_dissector->offset[key_id];
37}
38
39void skb_flow_dissector_init(struct flow_dissector *flow_dissector,
40 const struct flow_dissector_key *key,
41 unsigned int key_count)
42{
43 unsigned int i;
44
45 memset(flow_dissector, 0, sizeof(*flow_dissector));
46
47 for (i = 0; i < key_count; i++, key++) {
48 /* User should make sure that every key target offset is withing
49 * boundaries of unsigned short.
50 */
51 BUG_ON(key->offset > USHRT_MAX);
52 BUG_ON(skb_flow_dissector_uses_key(flow_dissector,
53 key->key_id));
54
55 skb_flow_dissector_set_key(flow_dissector, key->key_id);
56 flow_dissector->offset[key->key_id] = key->offset;
57 }
58
59 /* Ensure that the dissector always includes basic key. That way
60 * we are able to avoid handling lack of it in fast path.
61 */
62 BUG_ON(!skb_flow_dissector_uses_key(flow_dissector,
63 FLOW_DISSECTOR_KEY_BASIC));
64}
65EXPORT_SYMBOL(skb_flow_dissector_init);
66
Nikolay Aleksandrov357afe92013-10-02 13:39:24 +020067/**
WANG Cong6451b3f2014-08-25 17:03:46 -070068 * __skb_flow_get_ports - extract the upper layer ports and return them
69 * @skb: sk_buff to extract the ports from
Nikolay Aleksandrov357afe92013-10-02 13:39:24 +020070 * @thoff: transport header offset
71 * @ip_proto: protocol for which to get port offset
WANG Cong6451b3f2014-08-25 17:03:46 -070072 * @data: raw buffer pointer to the packet, if NULL use skb->data
73 * @hlen: packet header length, if @data is NULL use skb_headlen(skb)
Nikolay Aleksandrov357afe92013-10-02 13:39:24 +020074 *
75 * The function will try to retrieve the ports at offset thoff + poff where poff
76 * is the protocol port offset returned from proto_ports_offset
77 */
David S. Miller690e36e2014-08-23 12:13:41 -070078__be32 __skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto,
79 void *data, int hlen)
Nikolay Aleksandrov357afe92013-10-02 13:39:24 +020080{
81 int poff = proto_ports_offset(ip_proto);
82
David S. Miller690e36e2014-08-23 12:13:41 -070083 if (!data) {
84 data = skb->data;
85 hlen = skb_headlen(skb);
86 }
87
Nikolay Aleksandrov357afe92013-10-02 13:39:24 +020088 if (poff >= 0) {
89 __be32 *ports, _ports;
90
David S. Miller690e36e2014-08-23 12:13:41 -070091 ports = __skb_header_pointer(skb, thoff + poff,
92 sizeof(_ports), data, hlen, &_ports);
Nikolay Aleksandrov357afe92013-10-02 13:39:24 +020093 if (ports)
94 return *ports;
95 }
96
97 return 0;
98}
David S. Miller690e36e2014-08-23 12:13:41 -070099EXPORT_SYMBOL(__skb_flow_get_ports);
Nikolay Aleksandrov357afe92013-10-02 13:39:24 +0200100
WANG Cong453a9402014-08-25 17:03:47 -0700101/**
102 * __skb_flow_dissect - extract the flow_keys struct and return it
103 * @skb: sk_buff to extract the flow from, can be NULL if the rest are specified
Jiri Pirko06635a32015-05-12 14:56:16 +0200104 * @flow_dissector: list of keys to dissect
105 * @target_container: target structure to put dissected values into
WANG Cong453a9402014-08-25 17:03:47 -0700106 * @data: raw buffer pointer to the packet, if NULL use skb->data
107 * @proto: protocol for which to get the flow, if @data is NULL use skb->protocol
108 * @nhoff: network header offset, if @data is NULL use skb_network_offset(skb)
109 * @hlen: packet header length, if @data is NULL use skb_headlen(skb)
110 *
Jiri Pirko06635a32015-05-12 14:56:16 +0200111 * The function will try to retrieve individual keys into target specified
112 * by flow_dissector from either the skbuff or a raw buffer specified by the
113 * rest parameters.
114 *
115 * Caller must take care of zeroing target container memory.
WANG Cong453a9402014-08-25 17:03:47 -0700116 */
Jiri Pirko06635a32015-05-12 14:56:16 +0200117bool __skb_flow_dissect(const struct sk_buff *skb,
118 struct flow_dissector *flow_dissector,
119 void *target_container,
WANG Cong453a9402014-08-25 17:03:47 -0700120 void *data, __be16 proto, int nhoff, int hlen)
Eric Dumazet0744dd02011-11-28 05:22:18 +0000121{
Jiri Pirko06635a32015-05-12 14:56:16 +0200122 struct flow_dissector_key_basic *key_basic;
123 struct flow_dissector_key_addrs *key_addrs;
124 struct flow_dissector_key_ports *key_ports;
Eric Dumazet0744dd02011-11-28 05:22:18 +0000125 u8 ip_proto;
Eric Dumazet0744dd02011-11-28 05:22:18 +0000126
David S. Miller690e36e2014-08-23 12:13:41 -0700127 if (!data) {
128 data = skb->data;
WANG Cong453a9402014-08-25 17:03:47 -0700129 proto = skb->protocol;
130 nhoff = skb_network_offset(skb);
David S. Miller690e36e2014-08-23 12:13:41 -0700131 hlen = skb_headlen(skb);
132 }
133
Jiri Pirko06635a32015-05-12 14:56:16 +0200134 /* It is ensured by skb_flow_dissector_init() that basic key will
135 * be always present.
136 */
137 key_basic = skb_flow_dissector_target(flow_dissector,
138 FLOW_DISSECTOR_KEY_BASIC,
139 target_container);
Eric Dumazet0744dd02011-11-28 05:22:18 +0000140
141again:
142 switch (proto) {
Joe Perches2b8837a2014-03-12 10:04:17 -0700143 case htons(ETH_P_IP): {
Eric Dumazet0744dd02011-11-28 05:22:18 +0000144 const struct iphdr *iph;
145 struct iphdr _iph;
146ip:
David S. Miller690e36e2014-08-23 12:13:41 -0700147 iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph);
Jason Wang6f092342013-11-01 15:01:10 +0800148 if (!iph || iph->ihl < 5)
Eric Dumazet0744dd02011-11-28 05:22:18 +0000149 return false;
Eric Dumazet3797d3e2013-11-07 08:37:28 -0800150 nhoff += iph->ihl * 4;
Eric Dumazet0744dd02011-11-28 05:22:18 +0000151
Eric Dumazet3797d3e2013-11-07 08:37:28 -0800152 ip_proto = iph->protocol;
Eric Dumazet0744dd02011-11-28 05:22:18 +0000153 if (ip_is_fragment(iph))
154 ip_proto = 0;
Eric Dumazet3797d3e2013-11-07 08:37:28 -0800155
Jiri Pirko06635a32015-05-12 14:56:16 +0200156 if (!skb_flow_dissector_uses_key(flow_dissector,
157 FLOW_DISSECTOR_KEY_IPV4_ADDRS))
Alexander Duyck5af7fb62014-10-10 12:09:12 -0700158 break;
Jiri Pirko06635a32015-05-12 14:56:16 +0200159 key_addrs = skb_flow_dissector_target(flow_dissector,
160 FLOW_DISSECTOR_KEY_IPV4_ADDRS,
161 target_container);
162 memcpy(key_addrs, &iph->saddr, sizeof(*key_addrs));
Eric Dumazet0744dd02011-11-28 05:22:18 +0000163 break;
164 }
Joe Perches2b8837a2014-03-12 10:04:17 -0700165 case htons(ETH_P_IPV6): {
Eric Dumazet0744dd02011-11-28 05:22:18 +0000166 const struct ipv6hdr *iph;
167 struct ipv6hdr _iph;
Tom Herbert19469a82014-07-01 21:33:01 -0700168 __be32 flow_label;
169
Eric Dumazet0744dd02011-11-28 05:22:18 +0000170ipv6:
David S. Miller690e36e2014-08-23 12:13:41 -0700171 iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph);
Eric Dumazet0744dd02011-11-28 05:22:18 +0000172 if (!iph)
173 return false;
174
175 ip_proto = iph->nexthdr;
Eric Dumazet0744dd02011-11-28 05:22:18 +0000176 nhoff += sizeof(struct ipv6hdr);
Tom Herbert19469a82014-07-01 21:33:01 -0700177
Jiri Pirko06635a32015-05-12 14:56:16 +0200178 if (!skb_flow_dissector_uses_key(flow_dissector,
179 FLOW_DISSECTOR_KEY_IPV6_HASH_ADDRS))
Alexander Duyck56193d12014-09-05 19:20:26 -0400180 break;
Jiri Pirko06635a32015-05-12 14:56:16 +0200181 key_addrs = skb_flow_dissector_target(flow_dissector,
182 FLOW_DISSECTOR_KEY_IPV6_HASH_ADDRS,
183 target_container);
Alexander Duyck56193d12014-09-05 19:20:26 -0400184
Jiri Pirko06635a32015-05-12 14:56:16 +0200185 key_addrs->src = (__force __be32)ipv6_addr_hash(&iph->saddr);
186 key_addrs->dst = (__force __be32)ipv6_addr_hash(&iph->daddr);
Alexander Duyck5af7fb62014-10-10 12:09:12 -0700187
Tom Herbert19469a82014-07-01 21:33:01 -0700188 flow_label = ip6_flowlabel(iph);
189 if (flow_label) {
190 /* Awesome, IPv6 packet has a flow label so we can
191 * use that to represent the ports without any
192 * further dissection.
193 */
Jiri Pirko06635a32015-05-12 14:56:16 +0200194
195 key_basic->n_proto = proto;
196 key_basic->ip_proto = ip_proto;
197 key_basic->thoff = (u16)nhoff;
198
199 if (!skb_flow_dissector_uses_key(flow_dissector,
200 FLOW_DISSECTOR_KEY_PORTS))
201 break;
202 key_ports = skb_flow_dissector_target(flow_dissector,
203 FLOW_DISSECTOR_KEY_PORTS,
204 target_container);
205 key_ports->ports = flow_label;
Tom Herbert19469a82014-07-01 21:33:01 -0700206
207 return true;
208 }
209
Eric Dumazet0744dd02011-11-28 05:22:18 +0000210 break;
211 }
Joe Perches2b8837a2014-03-12 10:04:17 -0700212 case htons(ETH_P_8021AD):
213 case htons(ETH_P_8021Q): {
Eric Dumazet0744dd02011-11-28 05:22:18 +0000214 const struct vlan_hdr *vlan;
215 struct vlan_hdr _vlan;
216
David S. Miller690e36e2014-08-23 12:13:41 -0700217 vlan = __skb_header_pointer(skb, nhoff, sizeof(_vlan), data, hlen, &_vlan);
Eric Dumazet0744dd02011-11-28 05:22:18 +0000218 if (!vlan)
219 return false;
220
221 proto = vlan->h_vlan_encapsulated_proto;
222 nhoff += sizeof(*vlan);
223 goto again;
224 }
Joe Perches2b8837a2014-03-12 10:04:17 -0700225 case htons(ETH_P_PPP_SES): {
Eric Dumazet0744dd02011-11-28 05:22:18 +0000226 struct {
227 struct pppoe_hdr hdr;
228 __be16 proto;
229 } *hdr, _hdr;
David S. Miller690e36e2014-08-23 12:13:41 -0700230 hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
Eric Dumazet0744dd02011-11-28 05:22:18 +0000231 if (!hdr)
232 return false;
233 proto = hdr->proto;
234 nhoff += PPPOE_SES_HLEN;
235 switch (proto) {
Joe Perches2b8837a2014-03-12 10:04:17 -0700236 case htons(PPP_IP):
Eric Dumazet0744dd02011-11-28 05:22:18 +0000237 goto ip;
Joe Perches2b8837a2014-03-12 10:04:17 -0700238 case htons(PPP_IPV6):
Eric Dumazet0744dd02011-11-28 05:22:18 +0000239 goto ipv6;
240 default:
241 return false;
242 }
243 }
Erik Hugne08bfc9c2015-01-22 17:10:32 +0100244 case htons(ETH_P_TIPC): {
245 struct {
246 __be32 pre[3];
247 __be32 srcnode;
248 } *hdr, _hdr;
249 hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
250 if (!hdr)
251 return false;
Jiri Pirko06635a32015-05-12 14:56:16 +0200252 key_basic->n_proto = proto;
253 key_basic->thoff = (u16)nhoff;
254
255 if (skb_flow_dissector_uses_key(flow_dissector,
256 FLOW_DISSECTOR_KEY_IPV6_HASH_ADDRS)) {
257 return true;
258 key_addrs = skb_flow_dissector_target(flow_dissector,
259 FLOW_DISSECTOR_KEY_IPV6_HASH_ADDRS,
260 target_container);
261 key_addrs->src = hdr->srcnode;
262 key_addrs->dst = 0;
263 }
Erik Hugne08bfc9c2015-01-22 17:10:32 +0100264 return true;
265 }
Alexander Duyck56193d12014-09-05 19:20:26 -0400266 case htons(ETH_P_FCOE):
Jiri Pirko06635a32015-05-12 14:56:16 +0200267 key_basic->thoff = (u16)(nhoff + FCOE_HEADER_LEN);
Alexander Duyck56193d12014-09-05 19:20:26 -0400268 /* fall through */
Eric Dumazet0744dd02011-11-28 05:22:18 +0000269 default:
270 return false;
271 }
272
273 switch (ip_proto) {
274 case IPPROTO_GRE: {
275 struct gre_hdr {
276 __be16 flags;
277 __be16 proto;
278 } *hdr, _hdr;
279
David S. Miller690e36e2014-08-23 12:13:41 -0700280 hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
Eric Dumazet0744dd02011-11-28 05:22:18 +0000281 if (!hdr)
282 return false;
283 /*
284 * Only look inside GRE if version zero and no
285 * routing
286 */
287 if (!(hdr->flags & (GRE_VERSION|GRE_ROUTING))) {
288 proto = hdr->proto;
289 nhoff += 4;
290 if (hdr->flags & GRE_CSUM)
291 nhoff += 4;
292 if (hdr->flags & GRE_KEY)
293 nhoff += 4;
294 if (hdr->flags & GRE_SEQ)
295 nhoff += 4;
Michael Daltone1733de2013-03-11 06:52:28 +0000296 if (proto == htons(ETH_P_TEB)) {
297 const struct ethhdr *eth;
298 struct ethhdr _eth;
299
David S. Miller690e36e2014-08-23 12:13:41 -0700300 eth = __skb_header_pointer(skb, nhoff,
301 sizeof(_eth),
302 data, hlen, &_eth);
Michael Daltone1733de2013-03-11 06:52:28 +0000303 if (!eth)
304 return false;
305 proto = eth->h_proto;
306 nhoff += sizeof(*eth);
307 }
Eric Dumazet0744dd02011-11-28 05:22:18 +0000308 goto again;
309 }
310 break;
311 }
312 case IPPROTO_IPIP:
Tom Herbertfca41892013-07-29 11:07:36 -0700313 proto = htons(ETH_P_IP);
314 goto ip;
Tom Herbertb438f942013-07-29 11:07:42 -0700315 case IPPROTO_IPV6:
316 proto = htons(ETH_P_IPV6);
317 goto ipv6;
Eric Dumazet0744dd02011-11-28 05:22:18 +0000318 default:
319 break;
320 }
321
Jiri Pirko06635a32015-05-12 14:56:16 +0200322 /* It is ensured by skb_flow_dissector_init() that basic key will
323 * be always present.
324 */
325 key_basic = skb_flow_dissector_target(flow_dissector,
326 FLOW_DISSECTOR_KEY_BASIC,
327 target_container);
328 key_basic->n_proto = proto;
329 key_basic->ip_proto = ip_proto;
330 key_basic->thoff = (u16) nhoff;
Daniel Borkmann8ed78162013-03-19 06:39:29 +0000331
Jiri Pirko06635a32015-05-12 14:56:16 +0200332 if (skb_flow_dissector_uses_key(flow_dissector,
333 FLOW_DISSECTOR_KEY_PORTS)) {
334 key_ports = skb_flow_dissector_target(flow_dissector,
335 FLOW_DISSECTOR_KEY_PORTS,
336 target_container);
337 key_ports->ports = __skb_flow_get_ports(skb, nhoff, ip_proto,
338 data, hlen);
339 }
Alexander Duyck5af7fb62014-10-10 12:09:12 -0700340
Eric Dumazet0744dd02011-11-28 05:22:18 +0000341 return true;
342}
David S. Miller690e36e2014-08-23 12:13:41 -0700343EXPORT_SYMBOL(__skb_flow_dissect);
Cong Wang441d9d32013-01-21 00:39:24 +0000344
345static u32 hashrnd __read_mostly;
Hannes Frederic Sowa66415cf2013-10-23 20:06:00 +0200346static __always_inline void __flow_hash_secret_init(void)
347{
348 net_get_random_once(&hashrnd, sizeof(hashrnd));
349}
350
Tom Herbert50fb7992015-05-01 11:30:12 -0700351static __always_inline u32 __flow_hash_3words(u32 a, u32 b, u32 c, u32 keyval)
Hannes Frederic Sowa66415cf2013-10-23 20:06:00 +0200352{
Tom Herbert50fb7992015-05-01 11:30:12 -0700353 return jhash_3words(a, b, c, keyval);
Hannes Frederic Sowa66415cf2013-10-23 20:06:00 +0200354}
355
Tom Herbert50fb7992015-05-01 11:30:12 -0700356static inline u32 __flow_hash_from_keys(struct flow_keys *keys, u32 keyval)
Tom Herbert5ed20a62014-07-01 21:32:05 -0700357{
358 u32 hash;
359
360 /* get a consistent hash (same value on both flow directions) */
Jiri Pirko06635a32015-05-12 14:56:16 +0200361 if (((__force u32)keys->addrs.dst < (__force u32)keys->addrs.src) ||
362 (((__force u32)keys->addrs.dst == (__force u32)keys->addrs.src) &&
363 ((__force u16)keys->ports.port16[1] < (__force u16)keys->ports.port16[0]))) {
364 swap(keys->addrs.dst, keys->addrs.src);
365 swap(keys->ports.port16[0], keys->ports.port16[1]);
Tom Herbert5ed20a62014-07-01 21:32:05 -0700366 }
367
Jiri Pirko06635a32015-05-12 14:56:16 +0200368 hash = __flow_hash_3words((__force u32)keys->addrs.dst,
369 (__force u32)keys->addrs.src,
370 (__force u32)keys->ports.ports,
Tom Herbert50fb7992015-05-01 11:30:12 -0700371 keyval);
Tom Herbert5ed20a62014-07-01 21:32:05 -0700372 if (!hash)
373 hash = 1;
374
375 return hash;
376}
377
378u32 flow_hash_from_keys(struct flow_keys *keys)
379{
Tom Herbert50fb7992015-05-01 11:30:12 -0700380 __flow_hash_secret_init();
381 return __flow_hash_from_keys(keys, hashrnd);
Tom Herbert5ed20a62014-07-01 21:32:05 -0700382}
383EXPORT_SYMBOL(flow_hash_from_keys);
384
Tom Herbert50fb7992015-05-01 11:30:12 -0700385static inline u32 ___skb_get_hash(const struct sk_buff *skb,
386 struct flow_keys *keys, u32 keyval)
387{
Jiri Pirko06635a32015-05-12 14:56:16 +0200388 if (!skb_flow_dissect_flow_keys(skb, keys))
Tom Herbert50fb7992015-05-01 11:30:12 -0700389 return 0;
390
391 return __flow_hash_from_keys(keys, keyval);
392}
393
Tom Herbert2f59e1e2015-05-01 11:30:17 -0700394struct _flow_keys_digest_data {
395 __be16 n_proto;
396 u8 ip_proto;
397 u8 padding;
398 __be32 ports;
399 __be32 src;
400 __be32 dst;
401};
402
403void make_flow_keys_digest(struct flow_keys_digest *digest,
404 const struct flow_keys *flow)
405{
406 struct _flow_keys_digest_data *data =
407 (struct _flow_keys_digest_data *)digest;
408
409 BUILD_BUG_ON(sizeof(*data) > sizeof(*digest));
410
411 memset(digest, 0, sizeof(*digest));
412
Jiri Pirko06635a32015-05-12 14:56:16 +0200413 data->n_proto = flow->basic.n_proto;
414 data->ip_proto = flow->basic.ip_proto;
415 data->ports = flow->ports.ports;
416 data->src = flow->addrs.src;
417 data->dst = flow->addrs.dst;
Tom Herbert2f59e1e2015-05-01 11:30:17 -0700418}
419EXPORT_SYMBOL(make_flow_keys_digest);
420
Jiri Pirkod4fd3272015-05-12 14:56:10 +0200421/**
422 * __skb_get_hash: calculate a flow hash
423 * @skb: sk_buff to calculate flow hash from
424 *
425 * This function calculates a flow hash based on src/dst addresses
Tom Herbert61b905d2014-03-24 15:34:47 -0700426 * and src/dst port numbers. Sets hash in skb to non-zero hash value
427 * on success, zero indicates no valid hash. Also, sets l4_hash in skb
Cong Wang441d9d32013-01-21 00:39:24 +0000428 * if hash is a canonical 4-tuple hash over transport ports.
429 */
Tom Herbert3958afa1b2013-12-15 22:12:06 -0800430void __skb_get_hash(struct sk_buff *skb)
Cong Wang441d9d32013-01-21 00:39:24 +0000431{
432 struct flow_keys keys;
Tom Herbert50fb7992015-05-01 11:30:12 -0700433 u32 hash;
Cong Wang441d9d32013-01-21 00:39:24 +0000434
Tom Herbert50fb7992015-05-01 11:30:12 -0700435 __flow_hash_secret_init();
436
437 hash = ___skb_get_hash(skb, &keys, hashrnd);
438 if (!hash)
Cong Wang441d9d32013-01-21 00:39:24 +0000439 return;
Jiri Pirko06635a32015-05-12 14:56:16 +0200440 if (keys.ports.ports)
Tom Herbert61b905d2014-03-24 15:34:47 -0700441 skb->l4_hash = 1;
Tom Herberta3b18dd2014-07-01 21:33:17 -0700442 skb->sw_hash = 1;
Tom Herbert50fb7992015-05-01 11:30:12 -0700443 skb->hash = hash;
Cong Wang441d9d32013-01-21 00:39:24 +0000444}
Tom Herbert3958afa1b2013-12-15 22:12:06 -0800445EXPORT_SYMBOL(__skb_get_hash);
Cong Wang441d9d32013-01-21 00:39:24 +0000446
Tom Herbert50fb7992015-05-01 11:30:12 -0700447__u32 skb_get_hash_perturb(const struct sk_buff *skb, u32 perturb)
448{
449 struct flow_keys keys;
450
451 return ___skb_get_hash(skb, &keys, perturb);
452}
453EXPORT_SYMBOL(skb_get_hash_perturb);
454
Alexander Duyck56193d12014-09-05 19:20:26 -0400455u32 __skb_get_poff(const struct sk_buff *skb, void *data,
456 const struct flow_keys *keys, int hlen)
Daniel Borkmannf77668d2013-03-19 06:39:30 +0000457{
Jiri Pirko06635a32015-05-12 14:56:16 +0200458 u32 poff = keys->basic.thoff;
Daniel Borkmannf77668d2013-03-19 06:39:30 +0000459
Jiri Pirko06635a32015-05-12 14:56:16 +0200460 switch (keys->basic.ip_proto) {
Daniel Borkmannf77668d2013-03-19 06:39:30 +0000461 case IPPROTO_TCP: {
Alexander Duyck5af7fb62014-10-10 12:09:12 -0700462 /* access doff as u8 to avoid unaligned access */
463 const u8 *doff;
464 u8 _doff;
Daniel Borkmannf77668d2013-03-19 06:39:30 +0000465
Alexander Duyck5af7fb62014-10-10 12:09:12 -0700466 doff = __skb_header_pointer(skb, poff + 12, sizeof(_doff),
467 data, hlen, &_doff);
468 if (!doff)
Daniel Borkmannf77668d2013-03-19 06:39:30 +0000469 return poff;
470
Alexander Duyck5af7fb62014-10-10 12:09:12 -0700471 poff += max_t(u32, sizeof(struct tcphdr), (*doff & 0xF0) >> 2);
Daniel Borkmannf77668d2013-03-19 06:39:30 +0000472 break;
473 }
474 case IPPROTO_UDP:
475 case IPPROTO_UDPLITE:
476 poff += sizeof(struct udphdr);
477 break;
478 /* For the rest, we do not really care about header
479 * extensions at this point for now.
480 */
481 case IPPROTO_ICMP:
482 poff += sizeof(struct icmphdr);
483 break;
484 case IPPROTO_ICMPV6:
485 poff += sizeof(struct icmp6hdr);
486 break;
487 case IPPROTO_IGMP:
488 poff += sizeof(struct igmphdr);
489 break;
490 case IPPROTO_DCCP:
491 poff += sizeof(struct dccp_hdr);
492 break;
493 case IPPROTO_SCTP:
494 poff += sizeof(struct sctphdr);
495 break;
496 }
497
498 return poff;
499}
500
Jiri Pirko0db89b82015-05-12 14:56:14 +0200501/**
502 * skb_get_poff - get the offset to the payload
503 * @skb: sk_buff to get the payload offset from
504 *
505 * The function will get the offset to the payload as far as it could
506 * be dissected. The main user is currently BPF, so that we can dynamically
Alexander Duyck56193d12014-09-05 19:20:26 -0400507 * truncate packets without needing to push actual payload to the user
508 * space and can analyze headers only, instead.
509 */
510u32 skb_get_poff(const struct sk_buff *skb)
511{
512 struct flow_keys keys;
513
Jiri Pirko06635a32015-05-12 14:56:16 +0200514 if (!skb_flow_dissect_flow_keys(skb, &keys))
Alexander Duyck56193d12014-09-05 19:20:26 -0400515 return 0;
516
517 return __skb_get_poff(skb, skb->data, &keys, skb_headlen(skb));
518}
Jiri Pirko06635a32015-05-12 14:56:16 +0200519
520static const struct flow_dissector_key flow_keys_dissector_keys[] = {
521 {
522 .key_id = FLOW_DISSECTOR_KEY_BASIC,
523 .offset = offsetof(struct flow_keys, basic),
524 },
525 {
526 .key_id = FLOW_DISSECTOR_KEY_IPV4_ADDRS,
527 .offset = offsetof(struct flow_keys, addrs),
528 },
529 {
530 .key_id = FLOW_DISSECTOR_KEY_IPV6_HASH_ADDRS,
531 .offset = offsetof(struct flow_keys, addrs),
532 },
533 {
534 .key_id = FLOW_DISSECTOR_KEY_PORTS,
535 .offset = offsetof(struct flow_keys, ports),
536 },
537};
538
539static const struct flow_dissector_key flow_keys_buf_dissector_keys[] = {
540 {
541 .key_id = FLOW_DISSECTOR_KEY_BASIC,
542 .offset = offsetof(struct flow_keys, basic),
543 },
544};
545
546struct flow_dissector flow_keys_dissector __read_mostly;
547EXPORT_SYMBOL(flow_keys_dissector);
548
549struct flow_dissector flow_keys_buf_dissector __read_mostly;
550
551static int __init init_default_flow_dissectors(void)
552{
553 skb_flow_dissector_init(&flow_keys_dissector,
554 flow_keys_dissector_keys,
555 ARRAY_SIZE(flow_keys_dissector_keys));
556 skb_flow_dissector_init(&flow_keys_buf_dissector,
557 flow_keys_buf_dissector_keys,
558 ARRAY_SIZE(flow_keys_buf_dissector_keys));
559 return 0;
560}
561
562late_initcall_sync(init_default_flow_dissectors);