[RAMEN9610-21564]net/flow_dissector: switch to siphash
[GitHub/MotorolaMobilityLLC/kernel-slsi.git] / net / core / flow_dissector.c
CommitLineData
fbff949e 1#include <linux/kernel.h>
0744dd00 2#include <linux/skbuff.h>
c452ed70 3#include <linux/export.h>
0744dd00
ED
4#include <linux/ip.h>
5#include <linux/ipv6.h>
6#include <linux/if_vlan.h>
43e66528 7#include <net/dsa.h>
0744dd00 8#include <net/ip.h>
ddbe5032 9#include <net/ipv6.h>
ab10dccb
GF
10#include <net/gre.h>
11#include <net/pptp.h>
f77668dc
DB
12#include <linux/igmp.h>
13#include <linux/icmp.h>
14#include <linux/sctp.h>
15#include <linux/dccp.h>
0744dd00
ED
16#include <linux/if_tunnel.h>
17#include <linux/if_pppox.h>
18#include <linux/ppp_defs.h>
06635a35 19#include <linux/stddef.h>
67a900cc 20#include <linux/if_ether.h>
b3baa0fb 21#include <linux/mpls.h>
ac4bb5de 22#include <linux/tcp.h>
1bd758eb 23#include <net/flow_dissector.h>
56193d1b 24#include <scsi/fc/fc_fcoe.h>
0744dd00 25
20a17bf6
DM
26static void dissector_set_key(struct flow_dissector *flow_dissector,
27 enum flow_dissector_key_id key_id)
fbff949e
JP
28{
29 flow_dissector->used_keys |= (1 << key_id);
30}
31
fbff949e
JP
32void skb_flow_dissector_init(struct flow_dissector *flow_dissector,
33 const struct flow_dissector_key *key,
34 unsigned int key_count)
35{
36 unsigned int i;
37
38 memset(flow_dissector, 0, sizeof(*flow_dissector));
39
40 for (i = 0; i < key_count; i++, key++) {
41 /* User should make sure that every key target offset is withing
42 * boundaries of unsigned short.
43 */
44 BUG_ON(key->offset > USHRT_MAX);
20a17bf6
DM
45 BUG_ON(dissector_uses_key(flow_dissector,
46 key->key_id));
fbff949e 47
20a17bf6 48 dissector_set_key(flow_dissector, key->key_id);
fbff949e
JP
49 flow_dissector->offset[key->key_id] = key->offset;
50 }
51
42aecaa9
TH
52 /* Ensure that the dissector always includes control and basic key.
53 * That way we are able to avoid handling lack of these in fast path.
fbff949e 54 */
20a17bf6
DM
55 BUG_ON(!dissector_uses_key(flow_dissector,
56 FLOW_DISSECTOR_KEY_CONTROL));
57 BUG_ON(!dissector_uses_key(flow_dissector,
58 FLOW_DISSECTOR_KEY_BASIC));
fbff949e
JP
59}
60EXPORT_SYMBOL(skb_flow_dissector_init);
61
972d3876
SH
62/**
63 * skb_flow_get_be16 - extract be16 entity
64 * @skb: sk_buff to extract from
65 * @poff: offset to extract at
66 * @data: raw buffer pointer to the packet
67 * @hlen: packet header length
68 *
69 * The function will try to retrieve a be32 entity at
70 * offset poff
71 */
d9584d8c
ED
72static __be16 skb_flow_get_be16(const struct sk_buff *skb, int poff,
73 void *data, int hlen)
972d3876
SH
74{
75 __be16 *u, _u;
76
77 u = __skb_header_pointer(skb, poff, sizeof(_u), data, hlen, &_u);
78 if (u)
79 return *u;
80
81 return 0;
82}
83
357afe9c 84/**
6451b3f5
WC
85 * __skb_flow_get_ports - extract the upper layer ports and return them
86 * @skb: sk_buff to extract the ports from
357afe9c
NA
87 * @thoff: transport header offset
88 * @ip_proto: protocol for which to get port offset
6451b3f5
WC
89 * @data: raw buffer pointer to the packet, if NULL use skb->data
90 * @hlen: packet header length, if @data is NULL use skb_headlen(skb)
357afe9c
NA
91 *
92 * The function will try to retrieve the ports at offset thoff + poff where poff
93 * is the protocol port offset returned from proto_ports_offset
94 */
690e36e7
DM
95__be32 __skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto,
96 void *data, int hlen)
357afe9c
NA
97{
98 int poff = proto_ports_offset(ip_proto);
99
690e36e7
DM
100 if (!data) {
101 data = skb->data;
102 hlen = skb_headlen(skb);
103 }
104
357afe9c
NA
105 if (poff >= 0) {
106 __be32 *ports, _ports;
107
690e36e7
DM
108 ports = __skb_header_pointer(skb, thoff + poff,
109 sizeof(_ports), data, hlen, &_ports);
357afe9c
NA
110 if (ports)
111 return *ports;
112 }
113
114 return 0;
115}
690e36e7 116EXPORT_SYMBOL(__skb_flow_get_ports);
357afe9c 117
4a5d6c8b
JP
118static enum flow_dissect_ret
119__skb_flow_dissect_mpls(const struct sk_buff *skb,
120 struct flow_dissector *flow_dissector,
121 void *target_container, void *data, int nhoff, int hlen)
122{
123 struct flow_dissector_key_keyid *key_keyid;
124 struct mpls_label *hdr, _hdr[2];
029c1ecb 125 u32 entry, label;
4a5d6c8b
JP
126
127 if (!dissector_uses_key(flow_dissector,
029c1ecb
BL
128 FLOW_DISSECTOR_KEY_MPLS_ENTROPY) &&
129 !dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_MPLS))
4a5d6c8b
JP
130 return FLOW_DISSECT_RET_OUT_GOOD;
131
132 hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data,
133 hlen, &_hdr);
134 if (!hdr)
135 return FLOW_DISSECT_RET_OUT_BAD;
136
029c1ecb
BL
137 entry = ntohl(hdr[0].entry);
138 label = (entry & MPLS_LS_LABEL_MASK) >> MPLS_LS_LABEL_SHIFT;
139
140 if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_MPLS)) {
141 struct flow_dissector_key_mpls *key_mpls;
142
143 key_mpls = skb_flow_dissector_target(flow_dissector,
144 FLOW_DISSECTOR_KEY_MPLS,
145 target_container);
146 key_mpls->mpls_label = label;
147 key_mpls->mpls_ttl = (entry & MPLS_LS_TTL_MASK)
148 >> MPLS_LS_TTL_SHIFT;
149 key_mpls->mpls_tc = (entry & MPLS_LS_TC_MASK)
150 >> MPLS_LS_TC_SHIFT;
151 key_mpls->mpls_bos = (entry & MPLS_LS_S_MASK)
152 >> MPLS_LS_S_SHIFT;
153 }
154
155 if (label == MPLS_LABEL_ENTROPY) {
4a5d6c8b
JP
156 key_keyid = skb_flow_dissector_target(flow_dissector,
157 FLOW_DISSECTOR_KEY_MPLS_ENTROPY,
158 target_container);
159 key_keyid->keyid = hdr[1].entry & htonl(MPLS_LS_LABEL_MASK);
160 }
161 return FLOW_DISSECT_RET_OUT_GOOD;
162}
163
9bf881ff
JP
164static enum flow_dissect_ret
165__skb_flow_dissect_arp(const struct sk_buff *skb,
166 struct flow_dissector *flow_dissector,
167 void *target_container, void *data, int nhoff, int hlen)
168{
169 struct flow_dissector_key_arp *key_arp;
170 struct {
171 unsigned char ar_sha[ETH_ALEN];
172 unsigned char ar_sip[4];
173 unsigned char ar_tha[ETH_ALEN];
174 unsigned char ar_tip[4];
175 } *arp_eth, _arp_eth;
176 const struct arphdr *arp;
6f14f443 177 struct arphdr _arp;
9bf881ff
JP
178
179 if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ARP))
180 return FLOW_DISSECT_RET_OUT_GOOD;
181
182 arp = __skb_header_pointer(skb, nhoff, sizeof(_arp), data,
183 hlen, &_arp);
184 if (!arp)
185 return FLOW_DISSECT_RET_OUT_BAD;
186
187 if (arp->ar_hrd != htons(ARPHRD_ETHER) ||
188 arp->ar_pro != htons(ETH_P_IP) ||
189 arp->ar_hln != ETH_ALEN ||
190 arp->ar_pln != 4 ||
191 (arp->ar_op != htons(ARPOP_REPLY) &&
192 arp->ar_op != htons(ARPOP_REQUEST)))
193 return FLOW_DISSECT_RET_OUT_BAD;
194
195 arp_eth = __skb_header_pointer(skb, nhoff + sizeof(_arp),
196 sizeof(_arp_eth), data,
197 hlen, &_arp_eth);
198 if (!arp_eth)
199 return FLOW_DISSECT_RET_OUT_BAD;
200
201 key_arp = skb_flow_dissector_target(flow_dissector,
202 FLOW_DISSECTOR_KEY_ARP,
203 target_container);
204
205 memcpy(&key_arp->sip, arp_eth->ar_sip, sizeof(key_arp->sip));
206 memcpy(&key_arp->tip, arp_eth->ar_tip, sizeof(key_arp->tip));
207
208 /* Only store the lower byte of the opcode;
209 * this covers ARPOP_REPLY and ARPOP_REQUEST.
210 */
211 key_arp->op = ntohs(arp->ar_op) & 0xff;
212
213 ether_addr_copy(key_arp->sha, arp_eth->ar_sha);
214 ether_addr_copy(key_arp->tha, arp_eth->ar_tha);
215
216 return FLOW_DISSECT_RET_OUT_GOOD;
217}
218
7c92de8e
JP
219static enum flow_dissect_ret
220__skb_flow_dissect_gre(const struct sk_buff *skb,
221 struct flow_dissector_key_control *key_control,
222 struct flow_dissector *flow_dissector,
223 void *target_container, void *data,
224 __be16 *p_proto, int *p_nhoff, int *p_hlen,
225 unsigned int flags)
226{
227 struct flow_dissector_key_keyid *key_keyid;
228 struct gre_base_hdr *hdr, _hdr;
229 int offset = 0;
230 u16 gre_ver;
231
232 hdr = __skb_header_pointer(skb, *p_nhoff, sizeof(_hdr),
233 data, *p_hlen, &_hdr);
234 if (!hdr)
235 return FLOW_DISSECT_RET_OUT_BAD;
236
237 /* Only look inside GRE without routing */
238 if (hdr->flags & GRE_ROUTING)
239 return FLOW_DISSECT_RET_OUT_GOOD;
240
241 /* Only look inside GRE for version 0 and 1 */
242 gre_ver = ntohs(hdr->flags & GRE_VERSION);
243 if (gre_ver > 1)
244 return FLOW_DISSECT_RET_OUT_GOOD;
245
246 *p_proto = hdr->protocol;
247 if (gre_ver) {
248 /* Version1 must be PPTP, and check the flags */
249 if (!(*p_proto == GRE_PROTO_PPP && (hdr->flags & GRE_KEY)))
250 return FLOW_DISSECT_RET_OUT_GOOD;
251 }
252
253 offset += sizeof(struct gre_base_hdr);
254
255 if (hdr->flags & GRE_CSUM)
256 offset += sizeof(((struct gre_full_hdr *) 0)->csum) +
257 sizeof(((struct gre_full_hdr *) 0)->reserved1);
258
259 if (hdr->flags & GRE_KEY) {
260 const __be32 *keyid;
261 __be32 _keyid;
262
263 keyid = __skb_header_pointer(skb, *p_nhoff + offset,
264 sizeof(_keyid),
265 data, *p_hlen, &_keyid);
266 if (!keyid)
267 return FLOW_DISSECT_RET_OUT_BAD;
268
269 if (dissector_uses_key(flow_dissector,
270 FLOW_DISSECTOR_KEY_GRE_KEYID)) {
271 key_keyid = skb_flow_dissector_target(flow_dissector,
272 FLOW_DISSECTOR_KEY_GRE_KEYID,
273 target_container);
274 if (gre_ver == 0)
275 key_keyid->keyid = *keyid;
276 else
277 key_keyid->keyid = *keyid & GRE_PPTP_KEY_MASK;
278 }
279 offset += sizeof(((struct gre_full_hdr *) 0)->key);
280 }
281
282 if (hdr->flags & GRE_SEQ)
283 offset += sizeof(((struct pptp_gre_header *) 0)->seq);
284
285 if (gre_ver == 0) {
286 if (*p_proto == htons(ETH_P_TEB)) {
287 const struct ethhdr *eth;
288 struct ethhdr _eth;
289
290 eth = __skb_header_pointer(skb, *p_nhoff + offset,
291 sizeof(_eth),
292 data, *p_hlen, &_eth);
293 if (!eth)
294 return FLOW_DISSECT_RET_OUT_BAD;
295 *p_proto = eth->h_proto;
296 offset += sizeof(*eth);
297
298 /* Cap headers that we access via pointers at the
299 * end of the Ethernet header as our maximum alignment
300 * at that point is only 2 bytes.
301 */
302 if (NET_IP_ALIGN)
303 *p_hlen = *p_nhoff + offset;
304 }
305 } else { /* version 1, must be PPTP */
306 u8 _ppp_hdr[PPP_HDRLEN];
307 u8 *ppp_hdr;
308
309 if (hdr->flags & GRE_ACK)
310 offset += sizeof(((struct pptp_gre_header *) 0)->ack);
311
312 ppp_hdr = __skb_header_pointer(skb, *p_nhoff + offset,
313 sizeof(_ppp_hdr),
314 data, *p_hlen, _ppp_hdr);
315 if (!ppp_hdr)
316 return FLOW_DISSECT_RET_OUT_BAD;
317
318 switch (PPP_PROTOCOL(ppp_hdr)) {
319 case PPP_IP:
320 *p_proto = htons(ETH_P_IP);
321 break;
322 case PPP_IPV6:
323 *p_proto = htons(ETH_P_IPV6);
324 break;
325 default:
326 /* Could probably catch some more like MPLS */
327 break;
328 }
329
330 offset += PPP_HDRLEN;
331 }
332
333 *p_nhoff += offset;
334 key_control->flags |= FLOW_DIS_ENCAPSULATION;
335 if (flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP)
336 return FLOW_DISSECT_RET_OUT_GOOD;
337
3a1214e8 338 return FLOW_DISSECT_RET_PROTO_AGAIN;
7c92de8e
JP
339}
340
ac4bb5de
JP
341static void
342__skb_flow_dissect_tcp(const struct sk_buff *skb,
343 struct flow_dissector *flow_dissector,
344 void *target_container, void *data, int thoff, int hlen)
345{
346 struct flow_dissector_key_tcp *key_tcp;
347 struct tcphdr *th, _th;
348
349 if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_TCP))
350 return;
351
352 th = __skb_header_pointer(skb, thoff, sizeof(_th), data, hlen, &_th);
353 if (!th)
354 return;
355
356 if (unlikely(__tcp_hdrlen(th) < sizeof(_th)))
357 return;
358
359 key_tcp = skb_flow_dissector_target(flow_dissector,
360 FLOW_DISSECTOR_KEY_TCP,
361 target_container);
362 key_tcp->flags = (*(__be16 *) &tcp_flag_word(th) & htons(0x0FFF));
363}
364
518d8a2e
OG
365static void
366__skb_flow_dissect_ipv4(const struct sk_buff *skb,
367 struct flow_dissector *flow_dissector,
368 void *target_container, void *data, const struct iphdr *iph)
369{
370 struct flow_dissector_key_ip *key_ip;
371
372 if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_IP))
373 return;
374
375 key_ip = skb_flow_dissector_target(flow_dissector,
376 FLOW_DISSECTOR_KEY_IP,
377 target_container);
378 key_ip->tos = iph->tos;
379 key_ip->ttl = iph->ttl;
380}
381
382static void
383__skb_flow_dissect_ipv6(const struct sk_buff *skb,
384 struct flow_dissector *flow_dissector,
385 void *target_container, void *data, const struct ipv6hdr *iph)
386{
387 struct flow_dissector_key_ip *key_ip;
388
389 if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_IP))
390 return;
391
392 key_ip = skb_flow_dissector_target(flow_dissector,
393 FLOW_DISSECTOR_KEY_IP,
394 target_container);
395 key_ip->tos = ipv6_get_dsfield(iph);
396 key_ip->ttl = iph->hop_limit;
397}
398
1eed4dfb
TH
399/* Maximum number of protocol headers that can be parsed in
400 * __skb_flow_dissect
401 */
402#define MAX_FLOW_DISSECT_HDRS 15
403
404static bool skb_flow_dissect_allowed(int *num_hdrs)
405{
406 ++*num_hdrs;
407
408 return (*num_hdrs <= MAX_FLOW_DISSECT_HDRS);
409}
410
453a940e
WC
411/**
412 * __skb_flow_dissect - extract the flow_keys struct and return it
413 * @skb: sk_buff to extract the flow from, can be NULL if the rest are specified
06635a35
JP
414 * @flow_dissector: list of keys to dissect
415 * @target_container: target structure to put dissected values into
453a940e
WC
416 * @data: raw buffer pointer to the packet, if NULL use skb->data
417 * @proto: protocol for which to get the flow, if @data is NULL use skb->protocol
418 * @nhoff: network header offset, if @data is NULL use skb_network_offset(skb)
419 * @hlen: packet header length, if @data is NULL use skb_headlen(skb)
420 *
06635a35
JP
421 * The function will try to retrieve individual keys into target specified
422 * by flow_dissector from either the skbuff or a raw buffer specified by the
423 * rest parameters.
424 *
425 * Caller must take care of zeroing target container memory.
453a940e 426 */
06635a35
JP
427bool __skb_flow_dissect(const struct sk_buff *skb,
428 struct flow_dissector *flow_dissector,
429 void *target_container,
cd79a238
TH
430 void *data, __be16 proto, int nhoff, int hlen,
431 unsigned int flags)
0744dd00 432{
42aecaa9 433 struct flow_dissector_key_control *key_control;
06635a35
JP
434 struct flow_dissector_key_basic *key_basic;
435 struct flow_dissector_key_addrs *key_addrs;
436 struct flow_dissector_key_ports *key_ports;
972d3876 437 struct flow_dissector_key_icmp *key_icmp;
d34af823 438 struct flow_dissector_key_tags *key_tags;
f6a66927 439 struct flow_dissector_key_vlan *key_vlan;
3a1214e8 440 enum flow_dissect_ret fdret;
d5709f7a 441 bool skip_vlan = false;
1eed4dfb 442 int num_hdrs = 0;
8e690ffd 443 u8 ip_proto = 0;
34fad54c 444 bool ret;
0744dd00 445
690e36e7
DM
446 if (!data) {
447 data = skb->data;
d5709f7a
HHZ
448 proto = skb_vlan_tag_present(skb) ?
449 skb->vlan_proto : skb->protocol;
453a940e 450 nhoff = skb_network_offset(skb);
690e36e7 451 hlen = skb_headlen(skb);
2d571645 452#if IS_ENABLED(CONFIG_NET_DSA)
7324157b 453 if (unlikely(skb->dev && netdev_uses_dsa(skb->dev))) {
43e66528
JC
454 const struct dsa_device_ops *ops;
455 int offset;
456
457 ops = skb->dev->dsa_ptr->tag_ops;
458 if (ops->flow_dissect &&
459 !ops->flow_dissect(skb, &proto, &offset)) {
460 hlen -= offset;
461 nhoff += offset;
462 }
463 }
2d571645 464#endif
690e36e7
DM
465 }
466
42aecaa9
TH
467 /* It is ensured by skb_flow_dissector_init() that control key will
468 * be always present.
469 */
470 key_control = skb_flow_dissector_target(flow_dissector,
471 FLOW_DISSECTOR_KEY_CONTROL,
472 target_container);
473
06635a35
JP
474 /* It is ensured by skb_flow_dissector_init() that basic key will
475 * be always present.
476 */
477 key_basic = skb_flow_dissector_target(flow_dissector,
478 FLOW_DISSECTOR_KEY_BASIC,
479 target_container);
0744dd00 480
20a17bf6
DM
481 if (dissector_uses_key(flow_dissector,
482 FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
67a900cc
JP
483 struct ethhdr *eth = eth_hdr(skb);
484 struct flow_dissector_key_eth_addrs *key_eth_addrs;
485
486 key_eth_addrs = skb_flow_dissector_target(flow_dissector,
487 FLOW_DISSECTOR_KEY_ETH_ADDRS,
488 target_container);
489 memcpy(key_eth_addrs, &eth->h_dest, sizeof(*key_eth_addrs));
490 }
491
c5ef188e 492proto_again:
3a1214e8
TH
493 fdret = FLOW_DISSECT_RET_CONTINUE;
494
0744dd00 495 switch (proto) {
2b8837ae 496 case htons(ETH_P_IP): {
0744dd00
ED
497 const struct iphdr *iph;
498 struct iphdr _iph;
3a1214e8 499
690e36e7 500 iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph);
3a1214e8
TH
501 if (!iph || iph->ihl < 5) {
502 fdret = FLOW_DISSECT_RET_OUT_BAD;
503 break;
504 }
505
3797d3e8 506 nhoff += iph->ihl * 4;
0744dd00 507
3797d3e8 508 ip_proto = iph->protocol;
3797d3e8 509
918c023f
AD
510 if (dissector_uses_key(flow_dissector,
511 FLOW_DISSECTOR_KEY_IPV4_ADDRS)) {
512 key_addrs = skb_flow_dissector_target(flow_dissector,
513 FLOW_DISSECTOR_KEY_IPV4_ADDRS,
514 target_container);
515
516 memcpy(&key_addrs->v4addrs, &iph->saddr,
517 sizeof(key_addrs->v4addrs));
518 key_control->addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
519 }
807e165d
TH
520
521 if (ip_is_fragment(iph)) {
4b36993d 522 key_control->flags |= FLOW_DIS_IS_FRAGMENT;
807e165d
TH
523
524 if (iph->frag_off & htons(IP_OFFSET)) {
3a1214e8
TH
525 fdret = FLOW_DISSECT_RET_OUT_GOOD;
526 break;
807e165d 527 } else {
4b36993d 528 key_control->flags |= FLOW_DIS_FIRST_FRAG;
3a1214e8
TH
529 if (!(flags &
530 FLOW_DISSECTOR_F_PARSE_1ST_FRAG)) {
531 fdret = FLOW_DISSECT_RET_OUT_GOOD;
532 break;
533 }
807e165d
TH
534 }
535 }
536
518d8a2e
OG
537 __skb_flow_dissect_ipv4(skb, flow_dissector,
538 target_container, data, iph);
539
3a1214e8
TH
540 if (flags & FLOW_DISSECTOR_F_STOP_AT_L3) {
541 fdret = FLOW_DISSECT_RET_OUT_GOOD;
542 break;
543 }
8306b688 544
0744dd00
ED
545 break;
546 }
2b8837ae 547 case htons(ETH_P_IPV6): {
0744dd00
ED
548 const struct ipv6hdr *iph;
549 struct ipv6hdr _iph;
19469a87 550
690e36e7 551 iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph);
3a1214e8
TH
552 if (!iph) {
553 fdret = FLOW_DISSECT_RET_OUT_BAD;
554 break;
555 }
0744dd00
ED
556
557 ip_proto = iph->nexthdr;
0744dd00 558 nhoff += sizeof(struct ipv6hdr);
19469a87 559
20a17bf6
DM
560 if (dissector_uses_key(flow_dissector,
561 FLOW_DISSECTOR_KEY_IPV6_ADDRS)) {
b3c3106c
AD
562 key_addrs = skb_flow_dissector_target(flow_dissector,
563 FLOW_DISSECTOR_KEY_IPV6_ADDRS,
564 target_container);
5af7fb6e 565
b3c3106c
AD
566 memcpy(&key_addrs->v6addrs, &iph->saddr,
567 sizeof(key_addrs->v6addrs));
c3f83241 568 key_control->addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
b924933c 569 }
87ee9e52 570
461547f3
AD
571 if ((dissector_uses_key(flow_dissector,
572 FLOW_DISSECTOR_KEY_FLOW_LABEL) ||
573 (flags & FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL)) &&
574 ip6_flowlabel(iph)) {
575 __be32 flow_label = ip6_flowlabel(iph);
576
20a17bf6
DM
577 if (dissector_uses_key(flow_dissector,
578 FLOW_DISSECTOR_KEY_FLOW_LABEL)) {
87ee9e52
TH
579 key_tags = skb_flow_dissector_target(flow_dissector,
580 FLOW_DISSECTOR_KEY_FLOW_LABEL,
581 target_container);
582 key_tags->flow_label = ntohl(flow_label);
12c227ec 583 }
3a1214e8
TH
584 if (flags & FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL) {
585 fdret = FLOW_DISSECT_RET_OUT_GOOD;
586 break;
587 }
19469a87
TH
588 }
589
518d8a2e
OG
590 __skb_flow_dissect_ipv6(skb, flow_dissector,
591 target_container, data, iph);
592
8306b688 593 if (flags & FLOW_DISSECTOR_F_STOP_AT_L3)
3a1214e8 594 fdret = FLOW_DISSECT_RET_OUT_GOOD;
8306b688 595
0744dd00
ED
596 break;
597 }
2b8837ae
JP
598 case htons(ETH_P_8021AD):
599 case htons(ETH_P_8021Q): {
0744dd00 600 const struct vlan_hdr *vlan;
bc72f3dd
AB
601 struct vlan_hdr _vlan;
602 bool vlan_tag_present = skb && skb_vlan_tag_present(skb);
0744dd00 603
bc72f3dd 604 if (vlan_tag_present)
d5709f7a
HHZ
605 proto = skb->protocol;
606
bc72f3dd 607 if (!vlan_tag_present || eth_type_vlan(skb->protocol)) {
d5709f7a
HHZ
608 vlan = __skb_header_pointer(skb, nhoff, sizeof(_vlan),
609 data, hlen, &_vlan);
3a1214e8
TH
610 if (!vlan) {
611 fdret = FLOW_DISSECT_RET_OUT_BAD;
612 break;
613 }
614
d5709f7a
HHZ
615 proto = vlan->h_vlan_encapsulated_proto;
616 nhoff += sizeof(*vlan);
3a1214e8
TH
617 if (skip_vlan) {
618 fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
619 break;
620 }
d5709f7a 621 }
0744dd00 622
d5709f7a 623 skip_vlan = true;
20a17bf6 624 if (dissector_uses_key(flow_dissector,
f6a66927
HHZ
625 FLOW_DISSECTOR_KEY_VLAN)) {
626 key_vlan = skb_flow_dissector_target(flow_dissector,
627 FLOW_DISSECTOR_KEY_VLAN,
d34af823
TH
628 target_container);
629
bc72f3dd 630 if (vlan_tag_present) {
f6a66927
HHZ
631 key_vlan->vlan_id = skb_vlan_tag_get_id(skb);
632 key_vlan->vlan_priority =
633 (skb_vlan_tag_get_prio(skb) >> VLAN_PRIO_SHIFT);
634 } else {
635 key_vlan->vlan_id = ntohs(vlan->h_vlan_TCI) &
d5709f7a 636 VLAN_VID_MASK;
f6a66927
HHZ
637 key_vlan->vlan_priority =
638 (ntohs(vlan->h_vlan_TCI) &
639 VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
640 }
d34af823
TH
641 }
642
3a1214e8
TH
643 fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
644 break;
0744dd00 645 }
2b8837ae 646 case htons(ETH_P_PPP_SES): {
0744dd00
ED
647 struct {
648 struct pppoe_hdr hdr;
649 __be16 proto;
650 } *hdr, _hdr;
690e36e7 651 hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
3a1214e8
TH
652 if (!hdr) {
653 fdret = FLOW_DISSECT_RET_OUT_BAD;
654 break;
655 }
656
0744dd00
ED
657 proto = hdr->proto;
658 nhoff += PPPOE_SES_HLEN;
659 switch (proto) {
2b8837ae 660 case htons(PPP_IP):
3a1214e8
TH
661 proto = htons(ETH_P_IP);
662 fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
663 break;
2b8837ae 664 case htons(PPP_IPV6):
3a1214e8
TH
665 proto = htons(ETH_P_IPV6);
666 fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
667 break;
0744dd00 668 default:
3a1214e8
TH
669 fdret = FLOW_DISSECT_RET_OUT_BAD;
670 break;
0744dd00 671 }
3a1214e8 672 break;
0744dd00 673 }
08bfc9cb
EH
674 case htons(ETH_P_TIPC): {
675 struct {
676 __be32 pre[3];
677 __be32 srcnode;
678 } *hdr, _hdr;
679 hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
3a1214e8
TH
680 if (!hdr) {
681 fdret = FLOW_DISSECT_RET_OUT_BAD;
682 break;
683 }
06635a35 684
20a17bf6
DM
685 if (dissector_uses_key(flow_dissector,
686 FLOW_DISSECTOR_KEY_TIPC_ADDRS)) {
06635a35 687 key_addrs = skb_flow_dissector_target(flow_dissector,
9f249089 688 FLOW_DISSECTOR_KEY_TIPC_ADDRS,
06635a35 689 target_container);
9f249089
TH
690 key_addrs->tipcaddrs.srcnode = hdr->srcnode;
691 key_control->addr_type = FLOW_DISSECTOR_KEY_TIPC_ADDRS;
06635a35 692 }
3a1214e8
TH
693 fdret = FLOW_DISSECT_RET_OUT_GOOD;
694 break;
08bfc9cb 695 }
b3baa0fb
TH
696
697 case htons(ETH_P_MPLS_UC):
4a5d6c8b 698 case htons(ETH_P_MPLS_MC):
3a1214e8 699 fdret = __skb_flow_dissect_mpls(skb, flow_dissector,
4a5d6c8b 700 target_container, data,
3a1214e8
TH
701 nhoff, hlen);
702 break;
56193d1b 703 case htons(ETH_P_FCOE):
3a1214e8
TH
704 if ((hlen - nhoff) < FCOE_HEADER_LEN) {
705 fdret = FLOW_DISSECT_RET_OUT_BAD;
706 break;
707 }
224516b3
AD
708
709 nhoff += FCOE_HEADER_LEN;
3a1214e8
TH
710 fdret = FLOW_DISSECT_RET_OUT_GOOD;
711 break;
55733350
SH
712
713 case htons(ETH_P_ARP):
9bf881ff 714 case htons(ETH_P_RARP):
3a1214e8 715 fdret = __skb_flow_dissect_arp(skb, flow_dissector,
9bf881ff 716 target_container, data,
3a1214e8
TH
717 nhoff, hlen);
718 break;
719
720 default:
721 fdret = FLOW_DISSECT_RET_OUT_BAD;
722 break;
723 }
724
725 /* Process result of proto processing */
726 switch (fdret) {
727 case FLOW_DISSECT_RET_OUT_GOOD:
728 goto out_good;
729 case FLOW_DISSECT_RET_PROTO_AGAIN:
1eed4dfb
TH
730 if (skb_flow_dissect_allowed(&num_hdrs))
731 goto proto_again;
732 goto out_good;
3a1214e8
TH
733 case FLOW_DISSECT_RET_CONTINUE:
734 case FLOW_DISSECT_RET_IPPROTO_AGAIN:
735 break;
736 case FLOW_DISSECT_RET_OUT_BAD:
0744dd00 737 default:
a6e544b0 738 goto out_bad;
0744dd00
ED
739 }
740
6a74fcf4 741ip_proto_again:
3a1214e8
TH
742 fdret = FLOW_DISSECT_RET_CONTINUE;
743
0744dd00 744 switch (ip_proto) {
7c92de8e 745 case IPPROTO_GRE:
3a1214e8 746 fdret = __skb_flow_dissect_gre(skb, key_control, flow_dissector,
7c92de8e 747 target_container, data,
3a1214e8
TH
748 &proto, &nhoff, &hlen, flags);
749 break;
750
6a74fcf4
TH
751 case NEXTHDR_HOP:
752 case NEXTHDR_ROUTING:
753 case NEXTHDR_DEST: {
754 u8 _opthdr[2], *opthdr;
755
756 if (proto != htons(ETH_P_IPV6))
757 break;
758
759 opthdr = __skb_header_pointer(skb, nhoff, sizeof(_opthdr),
760 data, hlen, &_opthdr);
3a1214e8
TH
761 if (!opthdr) {
762 fdret = FLOW_DISSECT_RET_OUT_BAD;
763 break;
764 }
6a74fcf4 765
1e98a0f0
ED
766 ip_proto = opthdr[0];
767 nhoff += (opthdr[1] + 1) << 3;
6a74fcf4 768
3a1214e8
TH
769 fdret = FLOW_DISSECT_RET_IPPROTO_AGAIN;
770 break;
6a74fcf4 771 }
b840f28b
TH
772 case NEXTHDR_FRAGMENT: {
773 struct frag_hdr _fh, *fh;
774
775 if (proto != htons(ETH_P_IPV6))
776 break;
777
778 fh = __skb_header_pointer(skb, nhoff, sizeof(_fh),
779 data, hlen, &_fh);
780
3a1214e8
TH
781 if (!fh) {
782 fdret = FLOW_DISSECT_RET_OUT_BAD;
783 break;
784 }
b840f28b 785
4b36993d 786 key_control->flags |= FLOW_DIS_IS_FRAGMENT;
b840f28b
TH
787
788 nhoff += sizeof(_fh);
43d2ccb3 789 ip_proto = fh->nexthdr;
b840f28b
TH
790
791 if (!(fh->frag_off & htons(IP6_OFFSET))) {
4b36993d 792 key_control->flags |= FLOW_DIS_FIRST_FRAG;
3a1214e8
TH
793 if (flags & FLOW_DISSECTOR_F_PARSE_1ST_FRAG) {
794 fdret = FLOW_DISSECT_RET_IPPROTO_AGAIN;
795 break;
796 }
b840f28b 797 }
3a1214e8
TH
798
799 fdret = FLOW_DISSECT_RET_OUT_GOOD;
800 break;
b840f28b 801 }
0744dd00 802 case IPPROTO_IPIP:
fca41895 803 proto = htons(ETH_P_IP);
823b9693 804
4b36993d 805 key_control->flags |= FLOW_DIS_ENCAPSULATION;
3a1214e8
TH
806 if (flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP) {
807 fdret = FLOW_DISSECT_RET_OUT_GOOD;
808 break;
809 }
810
811 fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
812 break;
823b9693 813
b438f940
TH
814 case IPPROTO_IPV6:
815 proto = htons(ETH_P_IPV6);
823b9693 816
4b36993d 817 key_control->flags |= FLOW_DIS_ENCAPSULATION;
3a1214e8
TH
818 if (flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP) {
819 fdret = FLOW_DISSECT_RET_OUT_GOOD;
820 break;
821 }
822
823 fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
824 break;
825
823b9693 826
b3baa0fb
TH
827 case IPPROTO_MPLS:
828 proto = htons(ETH_P_MPLS_UC);
3a1214e8
TH
829 fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
830 break;
831
ac4bb5de
JP
832 case IPPROTO_TCP:
833 __skb_flow_dissect_tcp(skb, flow_dissector, target_container,
834 data, nhoff, hlen);
835 break;
3a1214e8 836
0744dd00
ED
837 default:
838 break;
839 }
840
ceb85d87 841 if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_PORTS) &&
842 !(key_control->flags & FLOW_DIS_IS_FRAGMENT)) {
06635a35
JP
843 key_ports = skb_flow_dissector_target(flow_dissector,
844 FLOW_DISSECTOR_KEY_PORTS,
845 target_container);
846 key_ports->ports = __skb_flow_get_ports(skb, nhoff, ip_proto,
847 data, hlen);
848 }
5af7fb6e 849
972d3876
SH
850 if (dissector_uses_key(flow_dissector,
851 FLOW_DISSECTOR_KEY_ICMP)) {
852 key_icmp = skb_flow_dissector_target(flow_dissector,
853 FLOW_DISSECTOR_KEY_ICMP,
854 target_container);
855 key_icmp->icmp = skb_flow_get_be16(skb, nhoff, data, hlen);
856 }
857
3a1214e8
TH
858 /* Process result of IP proto processing */
859 switch (fdret) {
860 case FLOW_DISSECT_RET_PROTO_AGAIN:
1eed4dfb
TH
861 if (skb_flow_dissect_allowed(&num_hdrs))
862 goto proto_again;
863 break;
3a1214e8 864 case FLOW_DISSECT_RET_IPPROTO_AGAIN:
1eed4dfb
TH
865 if (skb_flow_dissect_allowed(&num_hdrs))
866 goto ip_proto_again;
867 break;
3a1214e8
TH
868 case FLOW_DISSECT_RET_OUT_GOOD:
869 case FLOW_DISSECT_RET_CONTINUE:
870 break;
871 case FLOW_DISSECT_RET_OUT_BAD:
872 default:
873 goto out_bad;
874 }
875
a6e544b0
TH
876out_good:
877 ret = true;
878
34fad54c 879out:
80f32728 880 key_control->thoff = min_t(u16, nhoff, skb ? skb->len : hlen);
a6e544b0
TH
881 key_basic->n_proto = proto;
882 key_basic->ip_proto = ip_proto;
a6e544b0
TH
883
884 return ret;
34fad54c
ED
885
886out_bad:
887 ret = false;
34fad54c 888 goto out;
0744dd00 889}
690e36e7 890EXPORT_SYMBOL(__skb_flow_dissect);
441d9d32 891
c94f5c5b 892static siphash_key_t hashrnd __read_mostly;
66415cf8
HFS
893static __always_inline void __flow_hash_secret_init(void)
894{
895 net_get_random_once(&hashrnd, sizeof(hashrnd));
896}
897
c94f5c5b 898static const void *flow_keys_hash_start(const struct flow_keys *flow)
42aecaa9 899{
c94f5c5b
ED
900 BUILD_BUG_ON(FLOW_KEYS_HASH_OFFSET % SIPHASH_ALIGNMENT);
901 return &flow->FLOW_KEYS_HASH_START_FIELD;
42aecaa9
TH
902}
903
20a17bf6 904static inline size_t flow_keys_hash_length(const struct flow_keys *flow)
42aecaa9 905{
c94f5c5b 906 size_t len = offsetof(typeof(*flow), addrs) - FLOW_KEYS_HASH_OFFSET;
c3f83241
TH
907
908 switch (flow->control.addr_type) {
909 case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
c94f5c5b 910 len += sizeof(flow->addrs.v4addrs);
c3f83241
TH
911 break;
912 case FLOW_DISSECTOR_KEY_IPV6_ADDRS:
c94f5c5b 913 len += sizeof(flow->addrs.v6addrs);
c3f83241 914 break;
9f249089 915 case FLOW_DISSECTOR_KEY_TIPC_ADDRS:
c94f5c5b 916 len += sizeof(flow->addrs.tipcaddrs);
9f249089 917 break;
c3f83241 918 }
c94f5c5b 919 return len;
c3f83241
TH
920}
921
922__be32 flow_get_u32_src(const struct flow_keys *flow)
923{
924 switch (flow->control.addr_type) {
925 case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
926 return flow->addrs.v4addrs.src;
927 case FLOW_DISSECTOR_KEY_IPV6_ADDRS:
928 return (__force __be32)ipv6_addr_hash(
929 &flow->addrs.v6addrs.src);
9f249089
TH
930 case FLOW_DISSECTOR_KEY_TIPC_ADDRS:
931 return flow->addrs.tipcaddrs.srcnode;
c3f83241
TH
932 default:
933 return 0;
934 }
935}
936EXPORT_SYMBOL(flow_get_u32_src);
937
938__be32 flow_get_u32_dst(const struct flow_keys *flow)
939{
940 switch (flow->control.addr_type) {
941 case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
942 return flow->addrs.v4addrs.dst;
943 case FLOW_DISSECTOR_KEY_IPV6_ADDRS:
944 return (__force __be32)ipv6_addr_hash(
945 &flow->addrs.v6addrs.dst);
946 default:
947 return 0;
948 }
949}
950EXPORT_SYMBOL(flow_get_u32_dst);
951
952static inline void __flow_hash_consistentify(struct flow_keys *keys)
953{
954 int addr_diff, i;
955
956 switch (keys->control.addr_type) {
957 case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
958 addr_diff = (__force u32)keys->addrs.v4addrs.dst -
959 (__force u32)keys->addrs.v4addrs.src;
960 if ((addr_diff < 0) ||
961 (addr_diff == 0 &&
962 ((__force u16)keys->ports.dst <
963 (__force u16)keys->ports.src))) {
964 swap(keys->addrs.v4addrs.src, keys->addrs.v4addrs.dst);
965 swap(keys->ports.src, keys->ports.dst);
966 }
967 break;
968 case FLOW_DISSECTOR_KEY_IPV6_ADDRS:
969 addr_diff = memcmp(&keys->addrs.v6addrs.dst,
970 &keys->addrs.v6addrs.src,
971 sizeof(keys->addrs.v6addrs.dst));
972 if ((addr_diff < 0) ||
973 (addr_diff == 0 &&
974 ((__force u16)keys->ports.dst <
975 (__force u16)keys->ports.src))) {
976 for (i = 0; i < 4; i++)
977 swap(keys->addrs.v6addrs.src.s6_addr32[i],
978 keys->addrs.v6addrs.dst.s6_addr32[i]);
979 swap(keys->ports.src, keys->ports.dst);
980 }
981 break;
982 }
66415cf8
HFS
983}
984
c94f5c5b
ED
985static inline u32 __flow_hash_from_keys(struct flow_keys *keys,
986 const siphash_key_t *keyval)
5ed20a68
TH
987{
988 u32 hash;
989
c3f83241 990 __flow_hash_consistentify(keys);
5ed20a68 991
c94f5c5b
ED
992 hash = siphash(flow_keys_hash_start(keys),
993 flow_keys_hash_length(keys), keyval);
5ed20a68
TH
994 if (!hash)
995 hash = 1;
996
997 return hash;
998}
999
1000u32 flow_hash_from_keys(struct flow_keys *keys)
1001{
50fb7992 1002 __flow_hash_secret_init();
c94f5c5b 1003 return __flow_hash_from_keys(keys, &hashrnd);
5ed20a68
TH
1004}
1005EXPORT_SYMBOL(flow_hash_from_keys);
1006
50fb7992 1007static inline u32 ___skb_get_hash(const struct sk_buff *skb,
c94f5c5b
ED
1008 struct flow_keys *keys,
1009 const siphash_key_t *keyval)
50fb7992 1010{
6db61d79
TH
1011 skb_flow_dissect_flow_keys(skb, keys,
1012 FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL);
50fb7992
TH
1013
1014 return __flow_hash_from_keys(keys, keyval);
1015}
1016
2f59e1eb
TH
1017struct _flow_keys_digest_data {
1018 __be16 n_proto;
1019 u8 ip_proto;
1020 u8 padding;
1021 __be32 ports;
1022 __be32 src;
1023 __be32 dst;
1024};
1025
1026void make_flow_keys_digest(struct flow_keys_digest *digest,
1027 const struct flow_keys *flow)
1028{
1029 struct _flow_keys_digest_data *data =
1030 (struct _flow_keys_digest_data *)digest;
1031
1032 BUILD_BUG_ON(sizeof(*data) > sizeof(*digest));
1033
1034 memset(digest, 0, sizeof(*digest));
1035
06635a35
JP
1036 data->n_proto = flow->basic.n_proto;
1037 data->ip_proto = flow->basic.ip_proto;
1038 data->ports = flow->ports.ports;
c3f83241
TH
1039 data->src = flow->addrs.v4addrs.src;
1040 data->dst = flow->addrs.v4addrs.dst;
2f59e1eb
TH
1041}
1042EXPORT_SYMBOL(make_flow_keys_digest);
1043
eb70db87
DM
1044static struct flow_dissector flow_keys_dissector_symmetric __read_mostly;
1045
b917783c 1046u32 __skb_get_hash_symmetric(const struct sk_buff *skb)
eb70db87
DM
1047{
1048 struct flow_keys keys;
1049
1050 __flow_hash_secret_init();
1051
1052 memset(&keys, 0, sizeof(keys));
1053 __skb_flow_dissect(skb, &flow_keys_dissector_symmetric, &keys,
1054 NULL, 0, 0, 0,
1055 FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL);
1056
c94f5c5b 1057 return __flow_hash_from_keys(&keys, &hashrnd);
eb70db87
DM
1058}
1059EXPORT_SYMBOL_GPL(__skb_get_hash_symmetric);
1060
d4fd3275
JP
1061/**
1062 * __skb_get_hash: calculate a flow hash
1063 * @skb: sk_buff to calculate flow hash from
1064 *
1065 * This function calculates a flow hash based on src/dst addresses
61b905da
TH
1066 * and src/dst port numbers. Sets hash in skb to non-zero hash value
1067 * on success, zero indicates no valid hash. Also, sets l4_hash in skb
441d9d32
CW
1068 * if hash is a canonical 4-tuple hash over transport ports.
1069 */
3958afa1 1070void __skb_get_hash(struct sk_buff *skb)
441d9d32
CW
1071{
1072 struct flow_keys keys;
635c223c 1073 u32 hash;
441d9d32 1074
50fb7992
TH
1075 __flow_hash_secret_init();
1076
c94f5c5b 1077 hash = ___skb_get_hash(skb, &keys, &hashrnd);
635c223c
GF
1078
1079 __skb_set_sw_hash(skb, hash, flow_keys_have_l4(&keys));
441d9d32 1080}
3958afa1 1081EXPORT_SYMBOL(__skb_get_hash);
441d9d32 1082
c94f5c5b
ED
1083__u32 skb_get_hash_perturb(const struct sk_buff *skb,
1084 const siphash_key_t *perturb)
50fb7992
TH
1085{
1086 struct flow_keys keys;
1087
1088 return ___skb_get_hash(skb, &keys, perturb);
1089}
1090EXPORT_SYMBOL(skb_get_hash_perturb);
1091
56193d1b
AD
1092u32 __skb_get_poff(const struct sk_buff *skb, void *data,
1093 const struct flow_keys *keys, int hlen)
f77668dc 1094{
42aecaa9 1095 u32 poff = keys->control.thoff;
f77668dc 1096
43d2ccb3
AD
1097 /* skip L4 headers for fragments after the first */
1098 if ((keys->control.flags & FLOW_DIS_IS_FRAGMENT) &&
1099 !(keys->control.flags & FLOW_DIS_FIRST_FRAG))
1100 return poff;
1101
06635a35 1102 switch (keys->basic.ip_proto) {
f77668dc 1103 case IPPROTO_TCP: {
5af7fb6e
AD
1104 /* access doff as u8 to avoid unaligned access */
1105 const u8 *doff;
1106 u8 _doff;
f77668dc 1107
5af7fb6e
AD
1108 doff = __skb_header_pointer(skb, poff + 12, sizeof(_doff),
1109 data, hlen, &_doff);
1110 if (!doff)
f77668dc
DB
1111 return poff;
1112
5af7fb6e 1113 poff += max_t(u32, sizeof(struct tcphdr), (*doff & 0xF0) >> 2);
f77668dc
DB
1114 break;
1115 }
1116 case IPPROTO_UDP:
1117 case IPPROTO_UDPLITE:
1118 poff += sizeof(struct udphdr);
1119 break;
1120 /* For the rest, we do not really care about header
1121 * extensions at this point for now.
1122 */
1123 case IPPROTO_ICMP:
1124 poff += sizeof(struct icmphdr);
1125 break;
1126 case IPPROTO_ICMPV6:
1127 poff += sizeof(struct icmp6hdr);
1128 break;
1129 case IPPROTO_IGMP:
1130 poff += sizeof(struct igmphdr);
1131 break;
1132 case IPPROTO_DCCP:
1133 poff += sizeof(struct dccp_hdr);
1134 break;
1135 case IPPROTO_SCTP:
1136 poff += sizeof(struct sctphdr);
1137 break;
1138 }
1139
1140 return poff;
1141}
1142
0db89b8b
JP
1143/**
1144 * skb_get_poff - get the offset to the payload
1145 * @skb: sk_buff to get the payload offset from
1146 *
1147 * The function will get the offset to the payload as far as it could
1148 * be dissected. The main user is currently BPF, so that we can dynamically
56193d1b
AD
1149 * truncate packets without needing to push actual payload to the user
1150 * space and can analyze headers only, instead.
1151 */
1152u32 skb_get_poff(const struct sk_buff *skb)
1153{
1154 struct flow_keys keys;
1155
cd79a238 1156 if (!skb_flow_dissect_flow_keys(skb, &keys, 0))
56193d1b
AD
1157 return 0;
1158
1159 return __skb_get_poff(skb, skb->data, &keys, skb_headlen(skb));
1160}
06635a35 1161
20a17bf6 1162__u32 __get_hash_from_flowi6(const struct flowi6 *fl6, struct flow_keys *keys)
a17ace95
DM
1163{
1164 memset(keys, 0, sizeof(*keys));
1165
1166 memcpy(&keys->addrs.v6addrs.src, &fl6->saddr,
1167 sizeof(keys->addrs.v6addrs.src));
1168 memcpy(&keys->addrs.v6addrs.dst, &fl6->daddr,
1169 sizeof(keys->addrs.v6addrs.dst));
1170 keys->control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
1171 keys->ports.src = fl6->fl6_sport;
1172 keys->ports.dst = fl6->fl6_dport;
1173 keys->keyid.keyid = fl6->fl6_gre_key;
3f8f52c5 1174 keys->tags.flow_label = (__force u32)flowi6_get_flowlabel(fl6);
a17ace95
DM
1175 keys->basic.ip_proto = fl6->flowi6_proto;
1176
1177 return flow_hash_from_keys(keys);
1178}
1179EXPORT_SYMBOL(__get_hash_from_flowi6);
1180
20a17bf6 1181__u32 __get_hash_from_flowi4(const struct flowi4 *fl4, struct flow_keys *keys)
a17ace95
DM
1182{
1183 memset(keys, 0, sizeof(*keys));
1184
1185 keys->addrs.v4addrs.src = fl4->saddr;
1186 keys->addrs.v4addrs.dst = fl4->daddr;
1187 keys->control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
1188 keys->ports.src = fl4->fl4_sport;
1189 keys->ports.dst = fl4->fl4_dport;
1190 keys->keyid.keyid = fl4->fl4_gre_key;
1191 keys->basic.ip_proto = fl4->flowi4_proto;
1192
1193 return flow_hash_from_keys(keys);
1194}
1195EXPORT_SYMBOL(__get_hash_from_flowi4);
1196
06635a35 1197static const struct flow_dissector_key flow_keys_dissector_keys[] = {
42aecaa9
TH
1198 {
1199 .key_id = FLOW_DISSECTOR_KEY_CONTROL,
1200 .offset = offsetof(struct flow_keys, control),
1201 },
06635a35
JP
1202 {
1203 .key_id = FLOW_DISSECTOR_KEY_BASIC,
1204 .offset = offsetof(struct flow_keys, basic),
1205 },
1206 {
1207 .key_id = FLOW_DISSECTOR_KEY_IPV4_ADDRS,
c3f83241
TH
1208 .offset = offsetof(struct flow_keys, addrs.v4addrs),
1209 },
1210 {
1211 .key_id = FLOW_DISSECTOR_KEY_IPV6_ADDRS,
1212 .offset = offsetof(struct flow_keys, addrs.v6addrs),
06635a35 1213 },
9f249089
TH
1214 {
1215 .key_id = FLOW_DISSECTOR_KEY_TIPC_ADDRS,
1216 .offset = offsetof(struct flow_keys, addrs.tipcaddrs),
1217 },
06635a35
JP
1218 {
1219 .key_id = FLOW_DISSECTOR_KEY_PORTS,
1220 .offset = offsetof(struct flow_keys, ports),
1221 },
d34af823 1222 {
f6a66927
HHZ
1223 .key_id = FLOW_DISSECTOR_KEY_VLAN,
1224 .offset = offsetof(struct flow_keys, vlan),
d34af823 1225 },
87ee9e52
TH
1226 {
1227 .key_id = FLOW_DISSECTOR_KEY_FLOW_LABEL,
1228 .offset = offsetof(struct flow_keys, tags),
1229 },
1fdd512c
TH
1230 {
1231 .key_id = FLOW_DISSECTOR_KEY_GRE_KEYID,
1232 .offset = offsetof(struct flow_keys, keyid),
1233 },
06635a35
JP
1234};
1235
eb70db87
DM
1236static const struct flow_dissector_key flow_keys_dissector_symmetric_keys[] = {
1237 {
1238 .key_id = FLOW_DISSECTOR_KEY_CONTROL,
1239 .offset = offsetof(struct flow_keys, control),
1240 },
1241 {
1242 .key_id = FLOW_DISSECTOR_KEY_BASIC,
1243 .offset = offsetof(struct flow_keys, basic),
1244 },
1245 {
1246 .key_id = FLOW_DISSECTOR_KEY_IPV4_ADDRS,
1247 .offset = offsetof(struct flow_keys, addrs.v4addrs),
1248 },
1249 {
1250 .key_id = FLOW_DISSECTOR_KEY_IPV6_ADDRS,
1251 .offset = offsetof(struct flow_keys, addrs.v6addrs),
1252 },
1253 {
1254 .key_id = FLOW_DISSECTOR_KEY_PORTS,
1255 .offset = offsetof(struct flow_keys, ports),
1256 },
1257};
1258
06635a35 1259static const struct flow_dissector_key flow_keys_buf_dissector_keys[] = {
42aecaa9
TH
1260 {
1261 .key_id = FLOW_DISSECTOR_KEY_CONTROL,
1262 .offset = offsetof(struct flow_keys, control),
1263 },
06635a35
JP
1264 {
1265 .key_id = FLOW_DISSECTOR_KEY_BASIC,
1266 .offset = offsetof(struct flow_keys, basic),
1267 },
1268};
1269
1270struct flow_dissector flow_keys_dissector __read_mostly;
1271EXPORT_SYMBOL(flow_keys_dissector);
1272
1273struct flow_dissector flow_keys_buf_dissector __read_mostly;
1274
1275static int __init init_default_flow_dissectors(void)
1276{
1277 skb_flow_dissector_init(&flow_keys_dissector,
1278 flow_keys_dissector_keys,
1279 ARRAY_SIZE(flow_keys_dissector_keys));
eb70db87
DM
1280 skb_flow_dissector_init(&flow_keys_dissector_symmetric,
1281 flow_keys_dissector_symmetric_keys,
1282 ARRAY_SIZE(flow_keys_dissector_symmetric_keys));
06635a35
JP
1283 skb_flow_dissector_init(&flow_keys_buf_dissector,
1284 flow_keys_buf_dissector_keys,
1285 ARRAY_SIZE(flow_keys_buf_dissector_keys));
1286 return 0;
1287}
1288
c9b8af13 1289core_initcall(init_default_flow_dissectors);