]> git.karo-electronics.de Git - karo-tx-linux.git/blob - net/core/flow_dissector.c
flow_dissector: Jump to exit code in __skb_flow_dissect
[karo-tx-linux.git] / net / core / flow_dissector.c
1 #include <linux/kernel.h>
2 #include <linux/skbuff.h>
3 #include <linux/export.h>
4 #include <linux/ip.h>
5 #include <linux/ipv6.h>
6 #include <linux/if_vlan.h>
7 #include <net/ip.h>
8 #include <net/ipv6.h>
9 #include <linux/igmp.h>
10 #include <linux/icmp.h>
11 #include <linux/sctp.h>
12 #include <linux/dccp.h>
13 #include <linux/if_tunnel.h>
14 #include <linux/if_pppox.h>
15 #include <linux/ppp_defs.h>
16 #include <linux/stddef.h>
17 #include <linux/if_ether.h>
18 #include <linux/mpls.h>
19 #include <net/flow_dissector.h>
20 #include <scsi/fc/fc_fcoe.h>
21
22 static bool skb_flow_dissector_uses_key(struct flow_dissector *flow_dissector,
23                                         enum flow_dissector_key_id key_id)
24 {
25         return flow_dissector->used_keys & (1 << key_id);
26 }
27
28 static void skb_flow_dissector_set_key(struct flow_dissector *flow_dissector,
29                                        enum flow_dissector_key_id key_id)
30 {
31         flow_dissector->used_keys |= (1 << key_id);
32 }
33
34 static void *skb_flow_dissector_target(struct flow_dissector *flow_dissector,
35                                        enum flow_dissector_key_id key_id,
36                                        void *target_container)
37 {
38         return ((char *) target_container) + flow_dissector->offset[key_id];
39 }
40
41 void skb_flow_dissector_init(struct flow_dissector *flow_dissector,
42                              const struct flow_dissector_key *key,
43                              unsigned int key_count)
44 {
45         unsigned int i;
46
47         memset(flow_dissector, 0, sizeof(*flow_dissector));
48
49         for (i = 0; i < key_count; i++, key++) {
50                 /* User should make sure that every key target offset is withing
51                  * boundaries of unsigned short.
52                  */
53                 BUG_ON(key->offset > USHRT_MAX);
54                 BUG_ON(skb_flow_dissector_uses_key(flow_dissector,
55                                                    key->key_id));
56
57                 skb_flow_dissector_set_key(flow_dissector, key->key_id);
58                 flow_dissector->offset[key->key_id] = key->offset;
59         }
60
61         /* Ensure that the dissector always includes control and basic key.
62          * That way we are able to avoid handling lack of these in fast path.
63          */
64         BUG_ON(!skb_flow_dissector_uses_key(flow_dissector,
65                                             FLOW_DISSECTOR_KEY_CONTROL));
66         BUG_ON(!skb_flow_dissector_uses_key(flow_dissector,
67                                             FLOW_DISSECTOR_KEY_BASIC));
68 }
69 EXPORT_SYMBOL(skb_flow_dissector_init);
70
71 /**
72  * __skb_flow_get_ports - extract the upper layer ports and return them
73  * @skb: sk_buff to extract the ports from
74  * @thoff: transport header offset
75  * @ip_proto: protocol for which to get port offset
76  * @data: raw buffer pointer to the packet, if NULL use skb->data
77  * @hlen: packet header length, if @data is NULL use skb_headlen(skb)
78  *
79  * The function will try to retrieve the ports at offset thoff + poff where poff
80  * is the protocol port offset returned from proto_ports_offset
81  */
82 __be32 __skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto,
83                             void *data, int hlen)
84 {
85         int poff = proto_ports_offset(ip_proto);
86
87         if (!data) {
88                 data = skb->data;
89                 hlen = skb_headlen(skb);
90         }
91
92         if (poff >= 0) {
93                 __be32 *ports, _ports;
94
95                 ports = __skb_header_pointer(skb, thoff + poff,
96                                              sizeof(_ports), data, hlen, &_ports);
97                 if (ports)
98                         return *ports;
99         }
100
101         return 0;
102 }
103 EXPORT_SYMBOL(__skb_flow_get_ports);
104
105 /**
106  * __skb_flow_dissect - extract the flow_keys struct and return it
107  * @skb: sk_buff to extract the flow from, can be NULL if the rest are specified
108  * @flow_dissector: list of keys to dissect
109  * @target_container: target structure to put dissected values into
110  * @data: raw buffer pointer to the packet, if NULL use skb->data
111  * @proto: protocol for which to get the flow, if @data is NULL use skb->protocol
112  * @nhoff: network header offset, if @data is NULL use skb_network_offset(skb)
113  * @hlen: packet header length, if @data is NULL use skb_headlen(skb)
114  *
115  * The function will try to retrieve individual keys into target specified
116  * by flow_dissector from either the skbuff or a raw buffer specified by the
117  * rest parameters.
118  *
119  * Caller must take care of zeroing target container memory.
120  */
121 bool __skb_flow_dissect(const struct sk_buff *skb,
122                         struct flow_dissector *flow_dissector,
123                         void *target_container,
124                         void *data, __be16 proto, int nhoff, int hlen)
125 {
126         struct flow_dissector_key_control *key_control;
127         struct flow_dissector_key_basic *key_basic;
128         struct flow_dissector_key_addrs *key_addrs;
129         struct flow_dissector_key_ports *key_ports;
130         struct flow_dissector_key_tags *key_tags;
131         struct flow_dissector_key_keyid *key_keyid;
132         u8 ip_proto = 0;
133         bool ret = false;
134
135         if (!data) {
136                 data = skb->data;
137                 proto = skb->protocol;
138                 nhoff = skb_network_offset(skb);
139                 hlen = skb_headlen(skb);
140         }
141
142         /* It is ensured by skb_flow_dissector_init() that control key will
143          * be always present.
144          */
145         key_control = skb_flow_dissector_target(flow_dissector,
146                                                 FLOW_DISSECTOR_KEY_CONTROL,
147                                                 target_container);
148
149         /* It is ensured by skb_flow_dissector_init() that basic key will
150          * be always present.
151          */
152         key_basic = skb_flow_dissector_target(flow_dissector,
153                                               FLOW_DISSECTOR_KEY_BASIC,
154                                               target_container);
155
156         if (skb_flow_dissector_uses_key(flow_dissector,
157                                         FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
158                 struct ethhdr *eth = eth_hdr(skb);
159                 struct flow_dissector_key_eth_addrs *key_eth_addrs;
160
161                 key_eth_addrs = skb_flow_dissector_target(flow_dissector,
162                                                           FLOW_DISSECTOR_KEY_ETH_ADDRS,
163                                                           target_container);
164                 memcpy(key_eth_addrs, &eth->h_dest, sizeof(*key_eth_addrs));
165         }
166
167 again:
168         switch (proto) {
169         case htons(ETH_P_IP): {
170                 const struct iphdr *iph;
171                 struct iphdr _iph;
172 ip:
173                 iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph);
174                 if (!iph || iph->ihl < 5)
175                         goto out_bad;
176                 nhoff += iph->ihl * 4;
177
178                 ip_proto = iph->protocol;
179                 if (ip_is_fragment(iph))
180                         ip_proto = 0;
181
182                 if (!skb_flow_dissector_uses_key(flow_dissector,
183                                                  FLOW_DISSECTOR_KEY_IPV4_ADDRS))
184                         break;
185
186                 key_addrs = skb_flow_dissector_target(flow_dissector,
187                               FLOW_DISSECTOR_KEY_IPV4_ADDRS, target_container);
188                 memcpy(&key_addrs->v4addrs, &iph->saddr,
189                        sizeof(key_addrs->v4addrs));
190                 key_control->addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
191                 break;
192         }
193         case htons(ETH_P_IPV6): {
194                 const struct ipv6hdr *iph;
195                 struct ipv6hdr _iph;
196                 __be32 flow_label;
197
198 ipv6:
199                 iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph);
200                 if (!iph)
201                         goto out_bad;
202
203                 ip_proto = iph->nexthdr;
204                 nhoff += sizeof(struct ipv6hdr);
205
206                 if (skb_flow_dissector_uses_key(flow_dissector,
207                                                 FLOW_DISSECTOR_KEY_IPV6_ADDRS)) {
208                         struct flow_dissector_key_ipv6_addrs *key_ipv6_addrs;
209
210                         key_ipv6_addrs = skb_flow_dissector_target(flow_dissector,
211                                                                    FLOW_DISSECTOR_KEY_IPV6_ADDRS,
212                                                                    target_container);
213
214                         memcpy(key_ipv6_addrs, &iph->saddr, sizeof(*key_ipv6_addrs));
215                         key_control->addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
216                 }
217
218                 flow_label = ip6_flowlabel(iph);
219                 if (flow_label) {
220                         if (skb_flow_dissector_uses_key(flow_dissector,
221                                 FLOW_DISSECTOR_KEY_FLOW_LABEL)) {
222                                 key_tags = skb_flow_dissector_target(flow_dissector,
223                                                                      FLOW_DISSECTOR_KEY_FLOW_LABEL,
224                                                                      target_container);
225                                 key_tags->flow_label = ntohl(flow_label);
226                         }
227                 }
228
229                 break;
230         }
231         case htons(ETH_P_8021AD):
232         case htons(ETH_P_8021Q): {
233                 const struct vlan_hdr *vlan;
234                 struct vlan_hdr _vlan;
235
236                 vlan = __skb_header_pointer(skb, nhoff, sizeof(_vlan), data, hlen, &_vlan);
237                 if (!vlan)
238                         goto out_bad;
239
240                 if (skb_flow_dissector_uses_key(flow_dissector,
241                                                 FLOW_DISSECTOR_KEY_VLANID)) {
242                         key_tags = skb_flow_dissector_target(flow_dissector,
243                                                              FLOW_DISSECTOR_KEY_VLANID,
244                                                              target_container);
245
246                         key_tags->vlan_id = skb_vlan_tag_get_id(skb);
247                 }
248
249                 proto = vlan->h_vlan_encapsulated_proto;
250                 nhoff += sizeof(*vlan);
251                 goto again;
252         }
253         case htons(ETH_P_PPP_SES): {
254                 struct {
255                         struct pppoe_hdr hdr;
256                         __be16 proto;
257                 } *hdr, _hdr;
258                 hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
259                 if (!hdr)
260                         goto out_bad;
261                 proto = hdr->proto;
262                 nhoff += PPPOE_SES_HLEN;
263                 switch (proto) {
264                 case htons(PPP_IP):
265                         goto ip;
266                 case htons(PPP_IPV6):
267                         goto ipv6;
268                 default:
269                         goto out_bad;
270                 }
271         }
272         case htons(ETH_P_TIPC): {
273                 struct {
274                         __be32 pre[3];
275                         __be32 srcnode;
276                 } *hdr, _hdr;
277                 hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
278                 if (!hdr)
279                         goto out_bad;
280
281                 if (skb_flow_dissector_uses_key(flow_dissector,
282                                                 FLOW_DISSECTOR_KEY_TIPC_ADDRS)) {
283                         key_addrs = skb_flow_dissector_target(flow_dissector,
284                                                               FLOW_DISSECTOR_KEY_TIPC_ADDRS,
285                                                               target_container);
286                         key_addrs->tipcaddrs.srcnode = hdr->srcnode;
287                         key_control->addr_type = FLOW_DISSECTOR_KEY_TIPC_ADDRS;
288                 }
289                 goto out_good;
290         }
291
292         case htons(ETH_P_MPLS_UC):
293         case htons(ETH_P_MPLS_MC): {
294                 struct mpls_label *hdr, _hdr[2];
295 mpls:
296                 hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data,
297                                            hlen, &_hdr);
298                 if (!hdr)
299                         goto out_bad;
300
301                 if ((ntohl(hdr[0].entry) & MPLS_LS_LABEL_MASK) >>
302                      MPLS_LS_LABEL_SHIFT == MPLS_LABEL_ENTROPY) {
303                         if (skb_flow_dissector_uses_key(flow_dissector,
304                                                         FLOW_DISSECTOR_KEY_MPLS_ENTROPY)) {
305                                 key_keyid = skb_flow_dissector_target(flow_dissector,
306                                                                       FLOW_DISSECTOR_KEY_MPLS_ENTROPY,
307                                                                       target_container);
308                                 key_keyid->keyid = hdr[1].entry &
309                                         htonl(MPLS_LS_LABEL_MASK);
310                         }
311
312                         goto out_good;
313                 }
314
315                 goto out_good;
316         }
317
318         case htons(ETH_P_FCOE):
319                 key_control->thoff = (u16)(nhoff + FCOE_HEADER_LEN);
320                 /* fall through */
321         default:
322                 goto out_bad;
323         }
324
325 ip_proto_again:
326         switch (ip_proto) {
327         case IPPROTO_GRE: {
328                 struct gre_hdr {
329                         __be16 flags;
330                         __be16 proto;
331                 } *hdr, _hdr;
332
333                 hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
334                 if (!hdr)
335                         goto out_bad;
336                 /*
337                  * Only look inside GRE if version zero and no
338                  * routing
339                  */
340                 if (hdr->flags & (GRE_VERSION | GRE_ROUTING))
341                         break;
342
343                 proto = hdr->proto;
344                 nhoff += 4;
345                 if (hdr->flags & GRE_CSUM)
346                         nhoff += 4;
347                 if (hdr->flags & GRE_KEY) {
348                         const __be32 *keyid;
349                         __be32 _keyid;
350
351                         keyid = __skb_header_pointer(skb, nhoff, sizeof(_keyid),
352                                                      data, hlen, &_keyid);
353
354                         if (!keyid)
355                                 goto out_bad;
356
357                         if (skb_flow_dissector_uses_key(flow_dissector,
358                                                         FLOW_DISSECTOR_KEY_GRE_KEYID)) {
359                                 key_keyid = skb_flow_dissector_target(flow_dissector,
360                                                                       FLOW_DISSECTOR_KEY_GRE_KEYID,
361                                                                       target_container);
362                                 key_keyid->keyid = *keyid;
363                         }
364                         nhoff += 4;
365                 }
366                 if (hdr->flags & GRE_SEQ)
367                         nhoff += 4;
368                 if (proto == htons(ETH_P_TEB)) {
369                         const struct ethhdr *eth;
370                         struct ethhdr _eth;
371
372                         eth = __skb_header_pointer(skb, nhoff,
373                                                    sizeof(_eth),
374                                                    data, hlen, &_eth);
375                         if (!eth)
376                                 goto out_bad;
377                         proto = eth->h_proto;
378                         nhoff += sizeof(*eth);
379                 }
380                 goto again;
381         }
382         case NEXTHDR_HOP:
383         case NEXTHDR_ROUTING:
384         case NEXTHDR_DEST: {
385                 u8 _opthdr[2], *opthdr;
386
387                 if (proto != htons(ETH_P_IPV6))
388                         break;
389
390                 opthdr = __skb_header_pointer(skb, nhoff, sizeof(_opthdr),
391                                               data, hlen, &_opthdr);
392                 if (!opthdr)
393                         goto out_bad;
394
395                 ip_proto = opthdr[0];
396                 nhoff += (opthdr[1] + 1) << 3;
397
398                 goto ip_proto_again;
399         }
400         case IPPROTO_IPIP:
401                 proto = htons(ETH_P_IP);
402                 goto ip;
403         case IPPROTO_IPV6:
404                 proto = htons(ETH_P_IPV6);
405                 goto ipv6;
406         case IPPROTO_MPLS:
407                 proto = htons(ETH_P_MPLS_UC);
408                 goto mpls;
409         default:
410                 break;
411         }
412
413         if (skb_flow_dissector_uses_key(flow_dissector,
414                                         FLOW_DISSECTOR_KEY_PORTS)) {
415                 key_ports = skb_flow_dissector_target(flow_dissector,
416                                                       FLOW_DISSECTOR_KEY_PORTS,
417                                                       target_container);
418                 key_ports->ports = __skb_flow_get_ports(skb, nhoff, ip_proto,
419                                                         data, hlen);
420         }
421
422 out_good:
423         ret = true;
424
425 out_bad:
426         key_basic->n_proto = proto;
427         key_basic->ip_proto = ip_proto;
428         key_control->thoff = (u16)nhoff;
429
430         return ret;
431 }
432 EXPORT_SYMBOL(__skb_flow_dissect);
433
434 static u32 hashrnd __read_mostly;
435 static __always_inline void __flow_hash_secret_init(void)
436 {
437         net_get_random_once(&hashrnd, sizeof(hashrnd));
438 }
439
440 static __always_inline u32 __flow_hash_words(u32 *words, u32 length, u32 keyval)
441 {
442         return jhash2(words, length, keyval);
443 }
444
445 static inline void *flow_keys_hash_start(struct flow_keys *flow)
446 {
447         BUILD_BUG_ON(FLOW_KEYS_HASH_OFFSET % sizeof(u32));
448         return (void *)flow + FLOW_KEYS_HASH_OFFSET;
449 }
450
451 static inline size_t flow_keys_hash_length(struct flow_keys *flow)
452 {
453         size_t diff = FLOW_KEYS_HASH_OFFSET + sizeof(flow->addrs);
454         BUILD_BUG_ON((sizeof(*flow) - FLOW_KEYS_HASH_OFFSET) % sizeof(u32));
455         BUILD_BUG_ON(offsetof(typeof(*flow), addrs) !=
456                      sizeof(*flow) - sizeof(flow->addrs));
457
458         switch (flow->control.addr_type) {
459         case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
460                 diff -= sizeof(flow->addrs.v4addrs);
461                 break;
462         case FLOW_DISSECTOR_KEY_IPV6_ADDRS:
463                 diff -= sizeof(flow->addrs.v6addrs);
464                 break;
465         case FLOW_DISSECTOR_KEY_TIPC_ADDRS:
466                 diff -= sizeof(flow->addrs.tipcaddrs);
467                 break;
468         }
469         return (sizeof(*flow) - diff) / sizeof(u32);
470 }
471
472 __be32 flow_get_u32_src(const struct flow_keys *flow)
473 {
474         switch (flow->control.addr_type) {
475         case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
476                 return flow->addrs.v4addrs.src;
477         case FLOW_DISSECTOR_KEY_IPV6_ADDRS:
478                 return (__force __be32)ipv6_addr_hash(
479                         &flow->addrs.v6addrs.src);
480         case FLOW_DISSECTOR_KEY_TIPC_ADDRS:
481                 return flow->addrs.tipcaddrs.srcnode;
482         default:
483                 return 0;
484         }
485 }
486 EXPORT_SYMBOL(flow_get_u32_src);
487
488 __be32 flow_get_u32_dst(const struct flow_keys *flow)
489 {
490         switch (flow->control.addr_type) {
491         case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
492                 return flow->addrs.v4addrs.dst;
493         case FLOW_DISSECTOR_KEY_IPV6_ADDRS:
494                 return (__force __be32)ipv6_addr_hash(
495                         &flow->addrs.v6addrs.dst);
496         default:
497                 return 0;
498         }
499 }
500 EXPORT_SYMBOL(flow_get_u32_dst);
501
502 static inline void __flow_hash_consistentify(struct flow_keys *keys)
503 {
504         int addr_diff, i;
505
506         switch (keys->control.addr_type) {
507         case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
508                 addr_diff = (__force u32)keys->addrs.v4addrs.dst -
509                             (__force u32)keys->addrs.v4addrs.src;
510                 if ((addr_diff < 0) ||
511                     (addr_diff == 0 &&
512                      ((__force u16)keys->ports.dst <
513                       (__force u16)keys->ports.src))) {
514                         swap(keys->addrs.v4addrs.src, keys->addrs.v4addrs.dst);
515                         swap(keys->ports.src, keys->ports.dst);
516                 }
517                 break;
518         case FLOW_DISSECTOR_KEY_IPV6_ADDRS:
519                 addr_diff = memcmp(&keys->addrs.v6addrs.dst,
520                                    &keys->addrs.v6addrs.src,
521                                    sizeof(keys->addrs.v6addrs.dst));
522                 if ((addr_diff < 0) ||
523                     (addr_diff == 0 &&
524                      ((__force u16)keys->ports.dst <
525                       (__force u16)keys->ports.src))) {
526                         for (i = 0; i < 4; i++)
527                                 swap(keys->addrs.v6addrs.src.s6_addr32[i],
528                                      keys->addrs.v6addrs.dst.s6_addr32[i]);
529                         swap(keys->ports.src, keys->ports.dst);
530                 }
531                 break;
532         }
533 }
534
535 static inline u32 __flow_hash_from_keys(struct flow_keys *keys, u32 keyval)
536 {
537         u32 hash;
538
539         __flow_hash_consistentify(keys);
540
541         hash = __flow_hash_words((u32 *)flow_keys_hash_start(keys),
542                                  flow_keys_hash_length(keys), keyval);
543         if (!hash)
544                 hash = 1;
545
546         return hash;
547 }
548
549 u32 flow_hash_from_keys(struct flow_keys *keys)
550 {
551         __flow_hash_secret_init();
552         return __flow_hash_from_keys(keys, hashrnd);
553 }
554 EXPORT_SYMBOL(flow_hash_from_keys);
555
556 static inline u32 ___skb_get_hash(const struct sk_buff *skb,
557                                   struct flow_keys *keys, u32 keyval)
558 {
559         if (!skb_flow_dissect_flow_keys(skb, keys))
560                 return 0;
561
562         return __flow_hash_from_keys(keys, keyval);
563 }
564
565 struct _flow_keys_digest_data {
566         __be16  n_proto;
567         u8      ip_proto;
568         u8      padding;
569         __be32  ports;
570         __be32  src;
571         __be32  dst;
572 };
573
574 void make_flow_keys_digest(struct flow_keys_digest *digest,
575                            const struct flow_keys *flow)
576 {
577         struct _flow_keys_digest_data *data =
578             (struct _flow_keys_digest_data *)digest;
579
580         BUILD_BUG_ON(sizeof(*data) > sizeof(*digest));
581
582         memset(digest, 0, sizeof(*digest));
583
584         data->n_proto = flow->basic.n_proto;
585         data->ip_proto = flow->basic.ip_proto;
586         data->ports = flow->ports.ports;
587         data->src = flow->addrs.v4addrs.src;
588         data->dst = flow->addrs.v4addrs.dst;
589 }
590 EXPORT_SYMBOL(make_flow_keys_digest);
591
592 /**
593  * __skb_get_hash: calculate a flow hash
594  * @skb: sk_buff to calculate flow hash from
595  *
596  * This function calculates a flow hash based on src/dst addresses
597  * and src/dst port numbers.  Sets hash in skb to non-zero hash value
598  * on success, zero indicates no valid hash.  Also, sets l4_hash in skb
599  * if hash is a canonical 4-tuple hash over transport ports.
600  */
601 void __skb_get_hash(struct sk_buff *skb)
602 {
603         struct flow_keys keys;
604         u32 hash;
605
606         __flow_hash_secret_init();
607
608         hash = ___skb_get_hash(skb, &keys, hashrnd);
609         if (!hash)
610                 return;
611
612         __skb_set_sw_hash(skb, hash,
613                           flow_keys_have_l4(&keys));
614 }
615 EXPORT_SYMBOL(__skb_get_hash);
616
617 __u32 skb_get_hash_perturb(const struct sk_buff *skb, u32 perturb)
618 {
619         struct flow_keys keys;
620
621         return ___skb_get_hash(skb, &keys, perturb);
622 }
623 EXPORT_SYMBOL(skb_get_hash_perturb);
624
625 __u32 __skb_get_hash_flowi6(struct sk_buff *skb, struct flowi6 *fl6)
626 {
627         struct flow_keys keys;
628
629         memset(&keys, 0, sizeof(keys));
630
631         memcpy(&keys.addrs.v6addrs.src, &fl6->saddr,
632                sizeof(keys.addrs.v6addrs.src));
633         memcpy(&keys.addrs.v6addrs.dst, &fl6->daddr,
634                sizeof(keys.addrs.v6addrs.dst));
635         keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
636         keys.ports.src = fl6->fl6_sport;
637         keys.ports.dst = fl6->fl6_dport;
638         keys.keyid.keyid = fl6->fl6_gre_key;
639         keys.tags.flow_label = (__force u32)fl6->flowlabel;
640         keys.basic.ip_proto = fl6->flowi6_proto;
641
642         __skb_set_sw_hash(skb, flow_hash_from_keys(&keys),
643                           flow_keys_have_l4(&keys));
644
645         return skb->hash;
646 }
647 EXPORT_SYMBOL(__skb_get_hash_flowi6);
648
649 __u32 __skb_get_hash_flowi4(struct sk_buff *skb, struct flowi4 *fl4)
650 {
651         struct flow_keys keys;
652
653         memset(&keys, 0, sizeof(keys));
654
655         keys.addrs.v4addrs.src = fl4->saddr;
656         keys.addrs.v4addrs.dst = fl4->daddr;
657         keys.control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
658         keys.ports.src = fl4->fl4_sport;
659         keys.ports.dst = fl4->fl4_dport;
660         keys.keyid.keyid = fl4->fl4_gre_key;
661         keys.basic.ip_proto = fl4->flowi4_proto;
662
663         __skb_set_sw_hash(skb, flow_hash_from_keys(&keys),
664                           flow_keys_have_l4(&keys));
665
666         return skb->hash;
667 }
668 EXPORT_SYMBOL(__skb_get_hash_flowi4);
669
670 u32 __skb_get_poff(const struct sk_buff *skb, void *data,
671                    const struct flow_keys *keys, int hlen)
672 {
673         u32 poff = keys->control.thoff;
674
675         switch (keys->basic.ip_proto) {
676         case IPPROTO_TCP: {
677                 /* access doff as u8 to avoid unaligned access */
678                 const u8 *doff;
679                 u8 _doff;
680
681                 doff = __skb_header_pointer(skb, poff + 12, sizeof(_doff),
682                                             data, hlen, &_doff);
683                 if (!doff)
684                         return poff;
685
686                 poff += max_t(u32, sizeof(struct tcphdr), (*doff & 0xF0) >> 2);
687                 break;
688         }
689         case IPPROTO_UDP:
690         case IPPROTO_UDPLITE:
691                 poff += sizeof(struct udphdr);
692                 break;
693         /* For the rest, we do not really care about header
694          * extensions at this point for now.
695          */
696         case IPPROTO_ICMP:
697                 poff += sizeof(struct icmphdr);
698                 break;
699         case IPPROTO_ICMPV6:
700                 poff += sizeof(struct icmp6hdr);
701                 break;
702         case IPPROTO_IGMP:
703                 poff += sizeof(struct igmphdr);
704                 break;
705         case IPPROTO_DCCP:
706                 poff += sizeof(struct dccp_hdr);
707                 break;
708         case IPPROTO_SCTP:
709                 poff += sizeof(struct sctphdr);
710                 break;
711         }
712
713         return poff;
714 }
715
716 /**
717  * skb_get_poff - get the offset to the payload
718  * @skb: sk_buff to get the payload offset from
719  *
720  * The function will get the offset to the payload as far as it could
721  * be dissected.  The main user is currently BPF, so that we can dynamically
722  * truncate packets without needing to push actual payload to the user
723  * space and can analyze headers only, instead.
724  */
725 u32 skb_get_poff(const struct sk_buff *skb)
726 {
727         struct flow_keys keys;
728
729         if (!skb_flow_dissect_flow_keys(skb, &keys))
730                 return 0;
731
732         return __skb_get_poff(skb, skb->data, &keys, skb_headlen(skb));
733 }
734
735 static const struct flow_dissector_key flow_keys_dissector_keys[] = {
736         {
737                 .key_id = FLOW_DISSECTOR_KEY_CONTROL,
738                 .offset = offsetof(struct flow_keys, control),
739         },
740         {
741                 .key_id = FLOW_DISSECTOR_KEY_BASIC,
742                 .offset = offsetof(struct flow_keys, basic),
743         },
744         {
745                 .key_id = FLOW_DISSECTOR_KEY_IPV4_ADDRS,
746                 .offset = offsetof(struct flow_keys, addrs.v4addrs),
747         },
748         {
749                 .key_id = FLOW_DISSECTOR_KEY_IPV6_ADDRS,
750                 .offset = offsetof(struct flow_keys, addrs.v6addrs),
751         },
752         {
753                 .key_id = FLOW_DISSECTOR_KEY_TIPC_ADDRS,
754                 .offset = offsetof(struct flow_keys, addrs.tipcaddrs),
755         },
756         {
757                 .key_id = FLOW_DISSECTOR_KEY_PORTS,
758                 .offset = offsetof(struct flow_keys, ports),
759         },
760         {
761                 .key_id = FLOW_DISSECTOR_KEY_VLANID,
762                 .offset = offsetof(struct flow_keys, tags),
763         },
764         {
765                 .key_id = FLOW_DISSECTOR_KEY_FLOW_LABEL,
766                 .offset = offsetof(struct flow_keys, tags),
767         },
768         {
769                 .key_id = FLOW_DISSECTOR_KEY_GRE_KEYID,
770                 .offset = offsetof(struct flow_keys, keyid),
771         },
772 };
773
774 static const struct flow_dissector_key flow_keys_buf_dissector_keys[] = {
775         {
776                 .key_id = FLOW_DISSECTOR_KEY_CONTROL,
777                 .offset = offsetof(struct flow_keys, control),
778         },
779         {
780                 .key_id = FLOW_DISSECTOR_KEY_BASIC,
781                 .offset = offsetof(struct flow_keys, basic),
782         },
783 };
784
785 struct flow_dissector flow_keys_dissector __read_mostly;
786 EXPORT_SYMBOL(flow_keys_dissector);
787
788 struct flow_dissector flow_keys_buf_dissector __read_mostly;
789
790 static int __init init_default_flow_dissectors(void)
791 {
792         skb_flow_dissector_init(&flow_keys_dissector,
793                                 flow_keys_dissector_keys,
794                                 ARRAY_SIZE(flow_keys_dissector_keys));
795         skb_flow_dissector_init(&flow_keys_buf_dissector,
796                                 flow_keys_buf_dissector_keys,
797                                 ARRAY_SIZE(flow_keys_buf_dissector_keys));
798         return 0;
799 }
800
801 late_initcall_sync(init_default_flow_dissectors);