]> Git Repo - linux.git/blame - net/core/flow_dissector.c
flow_dissector: Cleanup control flow
[linux.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
453a940e
WC
399/**
400 * __skb_flow_dissect - extract the flow_keys struct and return it
401 * @skb: sk_buff to extract the flow from, can be NULL if the rest are specified
06635a35
JP
402 * @flow_dissector: list of keys to dissect
403 * @target_container: target structure to put dissected values into
453a940e
WC
404 * @data: raw buffer pointer to the packet, if NULL use skb->data
405 * @proto: protocol for which to get the flow, if @data is NULL use skb->protocol
406 * @nhoff: network header offset, if @data is NULL use skb_network_offset(skb)
407 * @hlen: packet header length, if @data is NULL use skb_headlen(skb)
408 *
06635a35
JP
409 * The function will try to retrieve individual keys into target specified
410 * by flow_dissector from either the skbuff or a raw buffer specified by the
411 * rest parameters.
412 *
413 * Caller must take care of zeroing target container memory.
453a940e 414 */
06635a35
JP
415bool __skb_flow_dissect(const struct sk_buff *skb,
416 struct flow_dissector *flow_dissector,
417 void *target_container,
cd79a238
TH
418 void *data, __be16 proto, int nhoff, int hlen,
419 unsigned int flags)
0744dd00 420{
42aecaa9 421 struct flow_dissector_key_control *key_control;
06635a35
JP
422 struct flow_dissector_key_basic *key_basic;
423 struct flow_dissector_key_addrs *key_addrs;
424 struct flow_dissector_key_ports *key_ports;
972d3876 425 struct flow_dissector_key_icmp *key_icmp;
d34af823 426 struct flow_dissector_key_tags *key_tags;
f6a66927 427 struct flow_dissector_key_vlan *key_vlan;
3a1214e8 428 enum flow_dissect_ret fdret;
d5709f7a 429 bool skip_vlan = false;
8e690ffd 430 u8 ip_proto = 0;
34fad54c 431 bool ret;
0744dd00 432
690e36e7
DM
433 if (!data) {
434 data = skb->data;
d5709f7a
HHZ
435 proto = skb_vlan_tag_present(skb) ?
436 skb->vlan_proto : skb->protocol;
453a940e 437 nhoff = skb_network_offset(skb);
690e36e7 438 hlen = skb_headlen(skb);
2d571645 439#if IS_ENABLED(CONFIG_NET_DSA)
7324157b 440 if (unlikely(skb->dev && netdev_uses_dsa(skb->dev))) {
43e66528
JC
441 const struct dsa_device_ops *ops;
442 int offset;
443
444 ops = skb->dev->dsa_ptr->tag_ops;
445 if (ops->flow_dissect &&
446 !ops->flow_dissect(skb, &proto, &offset)) {
447 hlen -= offset;
448 nhoff += offset;
449 }
450 }
2d571645 451#endif
690e36e7
DM
452 }
453
42aecaa9
TH
454 /* It is ensured by skb_flow_dissector_init() that control key will
455 * be always present.
456 */
457 key_control = skb_flow_dissector_target(flow_dissector,
458 FLOW_DISSECTOR_KEY_CONTROL,
459 target_container);
460
06635a35
JP
461 /* It is ensured by skb_flow_dissector_init() that basic key will
462 * be always present.
463 */
464 key_basic = skb_flow_dissector_target(flow_dissector,
465 FLOW_DISSECTOR_KEY_BASIC,
466 target_container);
0744dd00 467
20a17bf6
DM
468 if (dissector_uses_key(flow_dissector,
469 FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
67a900cc
JP
470 struct ethhdr *eth = eth_hdr(skb);
471 struct flow_dissector_key_eth_addrs *key_eth_addrs;
472
473 key_eth_addrs = skb_flow_dissector_target(flow_dissector,
474 FLOW_DISSECTOR_KEY_ETH_ADDRS,
475 target_container);
476 memcpy(key_eth_addrs, &eth->h_dest, sizeof(*key_eth_addrs));
477 }
478
c5ef188e 479proto_again:
3a1214e8
TH
480 fdret = FLOW_DISSECT_RET_CONTINUE;
481
0744dd00 482 switch (proto) {
2b8837ae 483 case htons(ETH_P_IP): {
0744dd00
ED
484 const struct iphdr *iph;
485 struct iphdr _iph;
3a1214e8 486
690e36e7 487 iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph);
3a1214e8
TH
488 if (!iph || iph->ihl < 5) {
489 fdret = FLOW_DISSECT_RET_OUT_BAD;
490 break;
491 }
492
3797d3e8 493 nhoff += iph->ihl * 4;
0744dd00 494
3797d3e8 495 ip_proto = iph->protocol;
3797d3e8 496
918c023f
AD
497 if (dissector_uses_key(flow_dissector,
498 FLOW_DISSECTOR_KEY_IPV4_ADDRS)) {
499 key_addrs = skb_flow_dissector_target(flow_dissector,
500 FLOW_DISSECTOR_KEY_IPV4_ADDRS,
501 target_container);
502
503 memcpy(&key_addrs->v4addrs, &iph->saddr,
504 sizeof(key_addrs->v4addrs));
505 key_control->addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
506 }
807e165d
TH
507
508 if (ip_is_fragment(iph)) {
4b36993d 509 key_control->flags |= FLOW_DIS_IS_FRAGMENT;
807e165d
TH
510
511 if (iph->frag_off & htons(IP_OFFSET)) {
3a1214e8
TH
512 fdret = FLOW_DISSECT_RET_OUT_GOOD;
513 break;
807e165d 514 } else {
4b36993d 515 key_control->flags |= FLOW_DIS_FIRST_FRAG;
3a1214e8
TH
516 if (!(flags &
517 FLOW_DISSECTOR_F_PARSE_1ST_FRAG)) {
518 fdret = FLOW_DISSECT_RET_OUT_GOOD;
519 break;
520 }
807e165d
TH
521 }
522 }
523
518d8a2e
OG
524 __skb_flow_dissect_ipv4(skb, flow_dissector,
525 target_container, data, iph);
526
3a1214e8
TH
527 if (flags & FLOW_DISSECTOR_F_STOP_AT_L3) {
528 fdret = FLOW_DISSECT_RET_OUT_GOOD;
529 break;
530 }
8306b688 531
0744dd00
ED
532 break;
533 }
2b8837ae 534 case htons(ETH_P_IPV6): {
0744dd00
ED
535 const struct ipv6hdr *iph;
536 struct ipv6hdr _iph;
19469a87 537
690e36e7 538 iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph);
3a1214e8
TH
539 if (!iph) {
540 fdret = FLOW_DISSECT_RET_OUT_BAD;
541 break;
542 }
0744dd00
ED
543
544 ip_proto = iph->nexthdr;
0744dd00 545 nhoff += sizeof(struct ipv6hdr);
19469a87 546
20a17bf6
DM
547 if (dissector_uses_key(flow_dissector,
548 FLOW_DISSECTOR_KEY_IPV6_ADDRS)) {
b3c3106c
AD
549 key_addrs = skb_flow_dissector_target(flow_dissector,
550 FLOW_DISSECTOR_KEY_IPV6_ADDRS,
551 target_container);
5af7fb6e 552
b3c3106c
AD
553 memcpy(&key_addrs->v6addrs, &iph->saddr,
554 sizeof(key_addrs->v6addrs));
c3f83241 555 key_control->addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
b924933c 556 }
87ee9e52 557
461547f3
AD
558 if ((dissector_uses_key(flow_dissector,
559 FLOW_DISSECTOR_KEY_FLOW_LABEL) ||
560 (flags & FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL)) &&
561 ip6_flowlabel(iph)) {
562 __be32 flow_label = ip6_flowlabel(iph);
563
20a17bf6
DM
564 if (dissector_uses_key(flow_dissector,
565 FLOW_DISSECTOR_KEY_FLOW_LABEL)) {
87ee9e52
TH
566 key_tags = skb_flow_dissector_target(flow_dissector,
567 FLOW_DISSECTOR_KEY_FLOW_LABEL,
568 target_container);
569 key_tags->flow_label = ntohl(flow_label);
12c227ec 570 }
3a1214e8
TH
571 if (flags & FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL) {
572 fdret = FLOW_DISSECT_RET_OUT_GOOD;
573 break;
574 }
19469a87
TH
575 }
576
518d8a2e
OG
577 __skb_flow_dissect_ipv6(skb, flow_dissector,
578 target_container, data, iph);
579
8306b688 580 if (flags & FLOW_DISSECTOR_F_STOP_AT_L3)
3a1214e8 581 fdret = FLOW_DISSECT_RET_OUT_GOOD;
8306b688 582
0744dd00
ED
583 break;
584 }
2b8837ae
JP
585 case htons(ETH_P_8021AD):
586 case htons(ETH_P_8021Q): {
0744dd00 587 const struct vlan_hdr *vlan;
bc72f3dd
AB
588 struct vlan_hdr _vlan;
589 bool vlan_tag_present = skb && skb_vlan_tag_present(skb);
0744dd00 590
bc72f3dd 591 if (vlan_tag_present)
d5709f7a
HHZ
592 proto = skb->protocol;
593
bc72f3dd 594 if (!vlan_tag_present || eth_type_vlan(skb->protocol)) {
d5709f7a
HHZ
595 vlan = __skb_header_pointer(skb, nhoff, sizeof(_vlan),
596 data, hlen, &_vlan);
3a1214e8
TH
597 if (!vlan) {
598 fdret = FLOW_DISSECT_RET_OUT_BAD;
599 break;
600 }
601
d5709f7a
HHZ
602 proto = vlan->h_vlan_encapsulated_proto;
603 nhoff += sizeof(*vlan);
3a1214e8
TH
604 if (skip_vlan) {
605 fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
606 break;
607 }
d5709f7a 608 }
0744dd00 609
d5709f7a 610 skip_vlan = true;
20a17bf6 611 if (dissector_uses_key(flow_dissector,
f6a66927
HHZ
612 FLOW_DISSECTOR_KEY_VLAN)) {
613 key_vlan = skb_flow_dissector_target(flow_dissector,
614 FLOW_DISSECTOR_KEY_VLAN,
d34af823
TH
615 target_container);
616
bc72f3dd 617 if (vlan_tag_present) {
f6a66927
HHZ
618 key_vlan->vlan_id = skb_vlan_tag_get_id(skb);
619 key_vlan->vlan_priority =
620 (skb_vlan_tag_get_prio(skb) >> VLAN_PRIO_SHIFT);
621 } else {
622 key_vlan->vlan_id = ntohs(vlan->h_vlan_TCI) &
d5709f7a 623 VLAN_VID_MASK;
f6a66927
HHZ
624 key_vlan->vlan_priority =
625 (ntohs(vlan->h_vlan_TCI) &
626 VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
627 }
d34af823
TH
628 }
629
3a1214e8
TH
630 fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
631 break;
0744dd00 632 }
2b8837ae 633 case htons(ETH_P_PPP_SES): {
0744dd00
ED
634 struct {
635 struct pppoe_hdr hdr;
636 __be16 proto;
637 } *hdr, _hdr;
690e36e7 638 hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
3a1214e8
TH
639 if (!hdr) {
640 fdret = FLOW_DISSECT_RET_OUT_BAD;
641 break;
642 }
643
0744dd00
ED
644 proto = hdr->proto;
645 nhoff += PPPOE_SES_HLEN;
646 switch (proto) {
2b8837ae 647 case htons(PPP_IP):
3a1214e8
TH
648 proto = htons(ETH_P_IP);
649 fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
650 break;
2b8837ae 651 case htons(PPP_IPV6):
3a1214e8
TH
652 proto = htons(ETH_P_IPV6);
653 fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
654 break;
0744dd00 655 default:
3a1214e8
TH
656 fdret = FLOW_DISSECT_RET_OUT_BAD;
657 break;
0744dd00 658 }
3a1214e8 659 break;
0744dd00 660 }
08bfc9cb
EH
661 case htons(ETH_P_TIPC): {
662 struct {
663 __be32 pre[3];
664 __be32 srcnode;
665 } *hdr, _hdr;
666 hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
3a1214e8
TH
667 if (!hdr) {
668 fdret = FLOW_DISSECT_RET_OUT_BAD;
669 break;
670 }
06635a35 671
20a17bf6
DM
672 if (dissector_uses_key(flow_dissector,
673 FLOW_DISSECTOR_KEY_TIPC_ADDRS)) {
06635a35 674 key_addrs = skb_flow_dissector_target(flow_dissector,
9f249089 675 FLOW_DISSECTOR_KEY_TIPC_ADDRS,
06635a35 676 target_container);
9f249089
TH
677 key_addrs->tipcaddrs.srcnode = hdr->srcnode;
678 key_control->addr_type = FLOW_DISSECTOR_KEY_TIPC_ADDRS;
06635a35 679 }
3a1214e8
TH
680 fdret = FLOW_DISSECT_RET_OUT_GOOD;
681 break;
08bfc9cb 682 }
b3baa0fb
TH
683
684 case htons(ETH_P_MPLS_UC):
4a5d6c8b 685 case htons(ETH_P_MPLS_MC):
3a1214e8 686 fdret = __skb_flow_dissect_mpls(skb, flow_dissector,
4a5d6c8b 687 target_container, data,
3a1214e8
TH
688 nhoff, hlen);
689 break;
56193d1b 690 case htons(ETH_P_FCOE):
3a1214e8
TH
691 if ((hlen - nhoff) < FCOE_HEADER_LEN) {
692 fdret = FLOW_DISSECT_RET_OUT_BAD;
693 break;
694 }
224516b3
AD
695
696 nhoff += FCOE_HEADER_LEN;
3a1214e8
TH
697 fdret = FLOW_DISSECT_RET_OUT_GOOD;
698 break;
55733350
SH
699
700 case htons(ETH_P_ARP):
9bf881ff 701 case htons(ETH_P_RARP):
3a1214e8 702 fdret = __skb_flow_dissect_arp(skb, flow_dissector,
9bf881ff 703 target_container, data,
3a1214e8
TH
704 nhoff, hlen);
705 break;
706
707 default:
708 fdret = FLOW_DISSECT_RET_OUT_BAD;
709 break;
710 }
711
712 /* Process result of proto processing */
713 switch (fdret) {
714 case FLOW_DISSECT_RET_OUT_GOOD:
715 goto out_good;
716 case FLOW_DISSECT_RET_PROTO_AGAIN:
717 goto proto_again;
718 case FLOW_DISSECT_RET_CONTINUE:
719 case FLOW_DISSECT_RET_IPPROTO_AGAIN:
720 break;
721 case FLOW_DISSECT_RET_OUT_BAD:
0744dd00 722 default:
a6e544b0 723 goto out_bad;
0744dd00
ED
724 }
725
6a74fcf4 726ip_proto_again:
3a1214e8
TH
727 fdret = FLOW_DISSECT_RET_CONTINUE;
728
0744dd00 729 switch (ip_proto) {
7c92de8e 730 case IPPROTO_GRE:
3a1214e8 731 fdret = __skb_flow_dissect_gre(skb, key_control, flow_dissector,
7c92de8e 732 target_container, data,
3a1214e8
TH
733 &proto, &nhoff, &hlen, flags);
734 break;
735
6a74fcf4
TH
736 case NEXTHDR_HOP:
737 case NEXTHDR_ROUTING:
738 case NEXTHDR_DEST: {
739 u8 _opthdr[2], *opthdr;
740
741 if (proto != htons(ETH_P_IPV6))
742 break;
743
744 opthdr = __skb_header_pointer(skb, nhoff, sizeof(_opthdr),
745 data, hlen, &_opthdr);
3a1214e8
TH
746 if (!opthdr) {
747 fdret = FLOW_DISSECT_RET_OUT_BAD;
748 break;
749 }
6a74fcf4 750
1e98a0f0
ED
751 ip_proto = opthdr[0];
752 nhoff += (opthdr[1] + 1) << 3;
6a74fcf4 753
3a1214e8
TH
754 fdret = FLOW_DISSECT_RET_IPPROTO_AGAIN;
755 break;
6a74fcf4 756 }
b840f28b
TH
757 case NEXTHDR_FRAGMENT: {
758 struct frag_hdr _fh, *fh;
759
760 if (proto != htons(ETH_P_IPV6))
761 break;
762
763 fh = __skb_header_pointer(skb, nhoff, sizeof(_fh),
764 data, hlen, &_fh);
765
3a1214e8
TH
766 if (!fh) {
767 fdret = FLOW_DISSECT_RET_OUT_BAD;
768 break;
769 }
b840f28b 770
4b36993d 771 key_control->flags |= FLOW_DIS_IS_FRAGMENT;
b840f28b
TH
772
773 nhoff += sizeof(_fh);
43d2ccb3 774 ip_proto = fh->nexthdr;
b840f28b
TH
775
776 if (!(fh->frag_off & htons(IP6_OFFSET))) {
4b36993d 777 key_control->flags |= FLOW_DIS_FIRST_FRAG;
3a1214e8
TH
778 if (flags & FLOW_DISSECTOR_F_PARSE_1ST_FRAG) {
779 fdret = FLOW_DISSECT_RET_IPPROTO_AGAIN;
780 break;
781 }
b840f28b 782 }
3a1214e8
TH
783
784 fdret = FLOW_DISSECT_RET_OUT_GOOD;
785 break;
b840f28b 786 }
0744dd00 787 case IPPROTO_IPIP:
fca41895 788 proto = htons(ETH_P_IP);
823b9693 789
4b36993d 790 key_control->flags |= FLOW_DIS_ENCAPSULATION;
3a1214e8
TH
791 if (flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP) {
792 fdret = FLOW_DISSECT_RET_OUT_GOOD;
793 break;
794 }
795
796 fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
797 break;
823b9693 798
b438f940
TH
799 case IPPROTO_IPV6:
800 proto = htons(ETH_P_IPV6);
823b9693 801
4b36993d 802 key_control->flags |= FLOW_DIS_ENCAPSULATION;
3a1214e8
TH
803 if (flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP) {
804 fdret = FLOW_DISSECT_RET_OUT_GOOD;
805 break;
806 }
807
808 fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
809 break;
810
823b9693 811
b3baa0fb
TH
812 case IPPROTO_MPLS:
813 proto = htons(ETH_P_MPLS_UC);
3a1214e8
TH
814 fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
815 break;
816
ac4bb5de
JP
817 case IPPROTO_TCP:
818 __skb_flow_dissect_tcp(skb, flow_dissector, target_container,
819 data, nhoff, hlen);
820 break;
3a1214e8 821
0744dd00
ED
822 default:
823 break;
824 }
825
20a17bf6
DM
826 if (dissector_uses_key(flow_dissector,
827 FLOW_DISSECTOR_KEY_PORTS)) {
06635a35
JP
828 key_ports = skb_flow_dissector_target(flow_dissector,
829 FLOW_DISSECTOR_KEY_PORTS,
830 target_container);
831 key_ports->ports = __skb_flow_get_ports(skb, nhoff, ip_proto,
832 data, hlen);
833 }
5af7fb6e 834
972d3876
SH
835 if (dissector_uses_key(flow_dissector,
836 FLOW_DISSECTOR_KEY_ICMP)) {
837 key_icmp = skb_flow_dissector_target(flow_dissector,
838 FLOW_DISSECTOR_KEY_ICMP,
839 target_container);
840 key_icmp->icmp = skb_flow_get_be16(skb, nhoff, data, hlen);
841 }
842
3a1214e8
TH
843 /* Process result of IP proto processing */
844 switch (fdret) {
845 case FLOW_DISSECT_RET_PROTO_AGAIN:
846 goto proto_again;
847 case FLOW_DISSECT_RET_IPPROTO_AGAIN:
848 goto ip_proto_again;
849 case FLOW_DISSECT_RET_OUT_GOOD:
850 case FLOW_DISSECT_RET_CONTINUE:
851 break;
852 case FLOW_DISSECT_RET_OUT_BAD:
853 default:
854 goto out_bad;
855 }
856
a6e544b0
TH
857out_good:
858 ret = true;
859
34fad54c
ED
860 key_control->thoff = (u16)nhoff;
861out:
a6e544b0
TH
862 key_basic->n_proto = proto;
863 key_basic->ip_proto = ip_proto;
a6e544b0
TH
864
865 return ret;
34fad54c
ED
866
867out_bad:
868 ret = false;
869 key_control->thoff = min_t(u16, nhoff, skb ? skb->len : hlen);
870 goto out;
0744dd00 871}
690e36e7 872EXPORT_SYMBOL(__skb_flow_dissect);
441d9d32
CW
873
874static u32 hashrnd __read_mostly;
66415cf8
HFS
875static __always_inline void __flow_hash_secret_init(void)
876{
877 net_get_random_once(&hashrnd, sizeof(hashrnd));
878}
879
20a17bf6
DM
880static __always_inline u32 __flow_hash_words(const u32 *words, u32 length,
881 u32 keyval)
42aecaa9
TH
882{
883 return jhash2(words, length, keyval);
884}
885
20a17bf6 886static inline const u32 *flow_keys_hash_start(const struct flow_keys *flow)
66415cf8 887{
20a17bf6
DM
888 const void *p = flow;
889
42aecaa9 890 BUILD_BUG_ON(FLOW_KEYS_HASH_OFFSET % sizeof(u32));
20a17bf6 891 return (const u32 *)(p + FLOW_KEYS_HASH_OFFSET);
42aecaa9
TH
892}
893
20a17bf6 894static inline size_t flow_keys_hash_length(const struct flow_keys *flow)
42aecaa9 895{
c3f83241 896 size_t diff = FLOW_KEYS_HASH_OFFSET + sizeof(flow->addrs);
42aecaa9 897 BUILD_BUG_ON((sizeof(*flow) - FLOW_KEYS_HASH_OFFSET) % sizeof(u32));
c3f83241
TH
898 BUILD_BUG_ON(offsetof(typeof(*flow), addrs) !=
899 sizeof(*flow) - sizeof(flow->addrs));
900
901 switch (flow->control.addr_type) {
902 case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
903 diff -= sizeof(flow->addrs.v4addrs);
904 break;
905 case FLOW_DISSECTOR_KEY_IPV6_ADDRS:
906 diff -= sizeof(flow->addrs.v6addrs);
907 break;
9f249089
TH
908 case FLOW_DISSECTOR_KEY_TIPC_ADDRS:
909 diff -= sizeof(flow->addrs.tipcaddrs);
910 break;
c3f83241
TH
911 }
912 return (sizeof(*flow) - diff) / sizeof(u32);
913}
914
915__be32 flow_get_u32_src(const struct flow_keys *flow)
916{
917 switch (flow->control.addr_type) {
918 case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
919 return flow->addrs.v4addrs.src;
920 case FLOW_DISSECTOR_KEY_IPV6_ADDRS:
921 return (__force __be32)ipv6_addr_hash(
922 &flow->addrs.v6addrs.src);
9f249089
TH
923 case FLOW_DISSECTOR_KEY_TIPC_ADDRS:
924 return flow->addrs.tipcaddrs.srcnode;
c3f83241
TH
925 default:
926 return 0;
927 }
928}
929EXPORT_SYMBOL(flow_get_u32_src);
930
931__be32 flow_get_u32_dst(const struct flow_keys *flow)
932{
933 switch (flow->control.addr_type) {
934 case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
935 return flow->addrs.v4addrs.dst;
936 case FLOW_DISSECTOR_KEY_IPV6_ADDRS:
937 return (__force __be32)ipv6_addr_hash(
938 &flow->addrs.v6addrs.dst);
939 default:
940 return 0;
941 }
942}
943EXPORT_SYMBOL(flow_get_u32_dst);
944
945static inline void __flow_hash_consistentify(struct flow_keys *keys)
946{
947 int addr_diff, i;
948
949 switch (keys->control.addr_type) {
950 case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
951 addr_diff = (__force u32)keys->addrs.v4addrs.dst -
952 (__force u32)keys->addrs.v4addrs.src;
953 if ((addr_diff < 0) ||
954 (addr_diff == 0 &&
955 ((__force u16)keys->ports.dst <
956 (__force u16)keys->ports.src))) {
957 swap(keys->addrs.v4addrs.src, keys->addrs.v4addrs.dst);
958 swap(keys->ports.src, keys->ports.dst);
959 }
960 break;
961 case FLOW_DISSECTOR_KEY_IPV6_ADDRS:
962 addr_diff = memcmp(&keys->addrs.v6addrs.dst,
963 &keys->addrs.v6addrs.src,
964 sizeof(keys->addrs.v6addrs.dst));
965 if ((addr_diff < 0) ||
966 (addr_diff == 0 &&
967 ((__force u16)keys->ports.dst <
968 (__force u16)keys->ports.src))) {
969 for (i = 0; i < 4; i++)
970 swap(keys->addrs.v6addrs.src.s6_addr32[i],
971 keys->addrs.v6addrs.dst.s6_addr32[i]);
972 swap(keys->ports.src, keys->ports.dst);
973 }
974 break;
975 }
66415cf8
HFS
976}
977
50fb7992 978static inline u32 __flow_hash_from_keys(struct flow_keys *keys, u32 keyval)
5ed20a68
TH
979{
980 u32 hash;
981
c3f83241 982 __flow_hash_consistentify(keys);
5ed20a68 983
20a17bf6 984 hash = __flow_hash_words(flow_keys_hash_start(keys),
42aecaa9 985 flow_keys_hash_length(keys), keyval);
5ed20a68
TH
986 if (!hash)
987 hash = 1;
988
989 return hash;
990}
991
992u32 flow_hash_from_keys(struct flow_keys *keys)
993{
50fb7992
TH
994 __flow_hash_secret_init();
995 return __flow_hash_from_keys(keys, hashrnd);
5ed20a68
TH
996}
997EXPORT_SYMBOL(flow_hash_from_keys);
998
50fb7992
TH
999static inline u32 ___skb_get_hash(const struct sk_buff *skb,
1000 struct flow_keys *keys, u32 keyval)
1001{
6db61d79
TH
1002 skb_flow_dissect_flow_keys(skb, keys,
1003 FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL);
50fb7992
TH
1004
1005 return __flow_hash_from_keys(keys, keyval);
1006}
1007
2f59e1eb
TH
1008struct _flow_keys_digest_data {
1009 __be16 n_proto;
1010 u8 ip_proto;
1011 u8 padding;
1012 __be32 ports;
1013 __be32 src;
1014 __be32 dst;
1015};
1016
1017void make_flow_keys_digest(struct flow_keys_digest *digest,
1018 const struct flow_keys *flow)
1019{
1020 struct _flow_keys_digest_data *data =
1021 (struct _flow_keys_digest_data *)digest;
1022
1023 BUILD_BUG_ON(sizeof(*data) > sizeof(*digest));
1024
1025 memset(digest, 0, sizeof(*digest));
1026
06635a35
JP
1027 data->n_proto = flow->basic.n_proto;
1028 data->ip_proto = flow->basic.ip_proto;
1029 data->ports = flow->ports.ports;
c3f83241
TH
1030 data->src = flow->addrs.v4addrs.src;
1031 data->dst = flow->addrs.v4addrs.dst;
2f59e1eb
TH
1032}
1033EXPORT_SYMBOL(make_flow_keys_digest);
1034
eb70db87
DM
1035static struct flow_dissector flow_keys_dissector_symmetric __read_mostly;
1036
b917783c 1037u32 __skb_get_hash_symmetric(const struct sk_buff *skb)
eb70db87
DM
1038{
1039 struct flow_keys keys;
1040
1041 __flow_hash_secret_init();
1042
1043 memset(&keys, 0, sizeof(keys));
1044 __skb_flow_dissect(skb, &flow_keys_dissector_symmetric, &keys,
1045 NULL, 0, 0, 0,
1046 FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL);
1047
1048 return __flow_hash_from_keys(&keys, hashrnd);
1049}
1050EXPORT_SYMBOL_GPL(__skb_get_hash_symmetric);
1051
d4fd3275
JP
1052/**
1053 * __skb_get_hash: calculate a flow hash
1054 * @skb: sk_buff to calculate flow hash from
1055 *
1056 * This function calculates a flow hash based on src/dst addresses
61b905da
TH
1057 * and src/dst port numbers. Sets hash in skb to non-zero hash value
1058 * on success, zero indicates no valid hash. Also, sets l4_hash in skb
441d9d32
CW
1059 * if hash is a canonical 4-tuple hash over transport ports.
1060 */
3958afa1 1061void __skb_get_hash(struct sk_buff *skb)
441d9d32
CW
1062{
1063 struct flow_keys keys;
635c223c 1064 u32 hash;
441d9d32 1065
50fb7992
TH
1066 __flow_hash_secret_init();
1067
635c223c
GF
1068 hash = ___skb_get_hash(skb, &keys, hashrnd);
1069
1070 __skb_set_sw_hash(skb, hash, flow_keys_have_l4(&keys));
441d9d32 1071}
3958afa1 1072EXPORT_SYMBOL(__skb_get_hash);
441d9d32 1073
50fb7992
TH
1074__u32 skb_get_hash_perturb(const struct sk_buff *skb, u32 perturb)
1075{
1076 struct flow_keys keys;
1077
1078 return ___skb_get_hash(skb, &keys, perturb);
1079}
1080EXPORT_SYMBOL(skb_get_hash_perturb);
1081
56193d1b
AD
1082u32 __skb_get_poff(const struct sk_buff *skb, void *data,
1083 const struct flow_keys *keys, int hlen)
f77668dc 1084{
42aecaa9 1085 u32 poff = keys->control.thoff;
f77668dc 1086
43d2ccb3
AD
1087 /* skip L4 headers for fragments after the first */
1088 if ((keys->control.flags & FLOW_DIS_IS_FRAGMENT) &&
1089 !(keys->control.flags & FLOW_DIS_FIRST_FRAG))
1090 return poff;
1091
06635a35 1092 switch (keys->basic.ip_proto) {
f77668dc 1093 case IPPROTO_TCP: {
5af7fb6e
AD
1094 /* access doff as u8 to avoid unaligned access */
1095 const u8 *doff;
1096 u8 _doff;
f77668dc 1097
5af7fb6e
AD
1098 doff = __skb_header_pointer(skb, poff + 12, sizeof(_doff),
1099 data, hlen, &_doff);
1100 if (!doff)
f77668dc
DB
1101 return poff;
1102
5af7fb6e 1103 poff += max_t(u32, sizeof(struct tcphdr), (*doff & 0xF0) >> 2);
f77668dc
DB
1104 break;
1105 }
1106 case IPPROTO_UDP:
1107 case IPPROTO_UDPLITE:
1108 poff += sizeof(struct udphdr);
1109 break;
1110 /* For the rest, we do not really care about header
1111 * extensions at this point for now.
1112 */
1113 case IPPROTO_ICMP:
1114 poff += sizeof(struct icmphdr);
1115 break;
1116 case IPPROTO_ICMPV6:
1117 poff += sizeof(struct icmp6hdr);
1118 break;
1119 case IPPROTO_IGMP:
1120 poff += sizeof(struct igmphdr);
1121 break;
1122 case IPPROTO_DCCP:
1123 poff += sizeof(struct dccp_hdr);
1124 break;
1125 case IPPROTO_SCTP:
1126 poff += sizeof(struct sctphdr);
1127 break;
1128 }
1129
1130 return poff;
1131}
1132
0db89b8b
JP
1133/**
1134 * skb_get_poff - get the offset to the payload
1135 * @skb: sk_buff to get the payload offset from
1136 *
1137 * The function will get the offset to the payload as far as it could
1138 * be dissected. The main user is currently BPF, so that we can dynamically
56193d1b
AD
1139 * truncate packets without needing to push actual payload to the user
1140 * space and can analyze headers only, instead.
1141 */
1142u32 skb_get_poff(const struct sk_buff *skb)
1143{
1144 struct flow_keys keys;
1145
cd79a238 1146 if (!skb_flow_dissect_flow_keys(skb, &keys, 0))
56193d1b
AD
1147 return 0;
1148
1149 return __skb_get_poff(skb, skb->data, &keys, skb_headlen(skb));
1150}
06635a35 1151
20a17bf6 1152__u32 __get_hash_from_flowi6(const struct flowi6 *fl6, struct flow_keys *keys)
a17ace95
DM
1153{
1154 memset(keys, 0, sizeof(*keys));
1155
1156 memcpy(&keys->addrs.v6addrs.src, &fl6->saddr,
1157 sizeof(keys->addrs.v6addrs.src));
1158 memcpy(&keys->addrs.v6addrs.dst, &fl6->daddr,
1159 sizeof(keys->addrs.v6addrs.dst));
1160 keys->control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
1161 keys->ports.src = fl6->fl6_sport;
1162 keys->ports.dst = fl6->fl6_dport;
1163 keys->keyid.keyid = fl6->fl6_gre_key;
1164 keys->tags.flow_label = (__force u32)fl6->flowlabel;
1165 keys->basic.ip_proto = fl6->flowi6_proto;
1166
1167 return flow_hash_from_keys(keys);
1168}
1169EXPORT_SYMBOL(__get_hash_from_flowi6);
1170
20a17bf6 1171__u32 __get_hash_from_flowi4(const struct flowi4 *fl4, struct flow_keys *keys)
a17ace95
DM
1172{
1173 memset(keys, 0, sizeof(*keys));
1174
1175 keys->addrs.v4addrs.src = fl4->saddr;
1176 keys->addrs.v4addrs.dst = fl4->daddr;
1177 keys->control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
1178 keys->ports.src = fl4->fl4_sport;
1179 keys->ports.dst = fl4->fl4_dport;
1180 keys->keyid.keyid = fl4->fl4_gre_key;
1181 keys->basic.ip_proto = fl4->flowi4_proto;
1182
1183 return flow_hash_from_keys(keys);
1184}
1185EXPORT_SYMBOL(__get_hash_from_flowi4);
1186
06635a35 1187static const struct flow_dissector_key flow_keys_dissector_keys[] = {
42aecaa9
TH
1188 {
1189 .key_id = FLOW_DISSECTOR_KEY_CONTROL,
1190 .offset = offsetof(struct flow_keys, control),
1191 },
06635a35
JP
1192 {
1193 .key_id = FLOW_DISSECTOR_KEY_BASIC,
1194 .offset = offsetof(struct flow_keys, basic),
1195 },
1196 {
1197 .key_id = FLOW_DISSECTOR_KEY_IPV4_ADDRS,
c3f83241
TH
1198 .offset = offsetof(struct flow_keys, addrs.v4addrs),
1199 },
1200 {
1201 .key_id = FLOW_DISSECTOR_KEY_IPV6_ADDRS,
1202 .offset = offsetof(struct flow_keys, addrs.v6addrs),
06635a35 1203 },
9f249089
TH
1204 {
1205 .key_id = FLOW_DISSECTOR_KEY_TIPC_ADDRS,
1206 .offset = offsetof(struct flow_keys, addrs.tipcaddrs),
1207 },
06635a35
JP
1208 {
1209 .key_id = FLOW_DISSECTOR_KEY_PORTS,
1210 .offset = offsetof(struct flow_keys, ports),
1211 },
d34af823 1212 {
f6a66927
HHZ
1213 .key_id = FLOW_DISSECTOR_KEY_VLAN,
1214 .offset = offsetof(struct flow_keys, vlan),
d34af823 1215 },
87ee9e52
TH
1216 {
1217 .key_id = FLOW_DISSECTOR_KEY_FLOW_LABEL,
1218 .offset = offsetof(struct flow_keys, tags),
1219 },
1fdd512c
TH
1220 {
1221 .key_id = FLOW_DISSECTOR_KEY_GRE_KEYID,
1222 .offset = offsetof(struct flow_keys, keyid),
1223 },
06635a35
JP
1224};
1225
eb70db87
DM
1226static const struct flow_dissector_key flow_keys_dissector_symmetric_keys[] = {
1227 {
1228 .key_id = FLOW_DISSECTOR_KEY_CONTROL,
1229 .offset = offsetof(struct flow_keys, control),
1230 },
1231 {
1232 .key_id = FLOW_DISSECTOR_KEY_BASIC,
1233 .offset = offsetof(struct flow_keys, basic),
1234 },
1235 {
1236 .key_id = FLOW_DISSECTOR_KEY_IPV4_ADDRS,
1237 .offset = offsetof(struct flow_keys, addrs.v4addrs),
1238 },
1239 {
1240 .key_id = FLOW_DISSECTOR_KEY_IPV6_ADDRS,
1241 .offset = offsetof(struct flow_keys, addrs.v6addrs),
1242 },
1243 {
1244 .key_id = FLOW_DISSECTOR_KEY_PORTS,
1245 .offset = offsetof(struct flow_keys, ports),
1246 },
1247};
1248
06635a35 1249static const struct flow_dissector_key flow_keys_buf_dissector_keys[] = {
42aecaa9
TH
1250 {
1251 .key_id = FLOW_DISSECTOR_KEY_CONTROL,
1252 .offset = offsetof(struct flow_keys, control),
1253 },
06635a35
JP
1254 {
1255 .key_id = FLOW_DISSECTOR_KEY_BASIC,
1256 .offset = offsetof(struct flow_keys, basic),
1257 },
1258};
1259
1260struct flow_dissector flow_keys_dissector __read_mostly;
1261EXPORT_SYMBOL(flow_keys_dissector);
1262
1263struct flow_dissector flow_keys_buf_dissector __read_mostly;
1264
1265static int __init init_default_flow_dissectors(void)
1266{
1267 skb_flow_dissector_init(&flow_keys_dissector,
1268 flow_keys_dissector_keys,
1269 ARRAY_SIZE(flow_keys_dissector_keys));
eb70db87
DM
1270 skb_flow_dissector_init(&flow_keys_dissector_symmetric,
1271 flow_keys_dissector_symmetric_keys,
1272 ARRAY_SIZE(flow_keys_dissector_symmetric_keys));
06635a35
JP
1273 skb_flow_dissector_init(&flow_keys_buf_dissector,
1274 flow_keys_buf_dissector_keys,
1275 ARRAY_SIZE(flow_keys_buf_dissector_keys));
1276 return 0;
1277}
1278
c9b8af13 1279core_initcall(init_default_flow_dissectors);
This page took 0.578959 seconds and 4 git commands to generate.