blob: 1b95d5ccc9d62742048616f31d729752cf876bb3 [file] [log] [blame]
Jiri Pirkofbff9492015-05-12 14:56:15 +02001#include <linux/kernel.h>
Eric Dumazet0744dd02011-11-28 05:22:18 +00002#include <linux/skbuff.h>
Jesper Dangaard Brouerc452ed72012-01-24 16:03:33 -05003#include <linux/export.h>
Eric Dumazet0744dd02011-11-28 05:22:18 +00004#include <linux/ip.h>
5#include <linux/ipv6.h>
6#include <linux/if_vlan.h>
7#include <net/ip.h>
Eric Dumazetddbe5032012-07-18 08:11:12 +00008#include <net/ipv6.h>
Daniel Borkmannf77668d2013-03-19 06:39:30 +00009#include <linux/igmp.h>
10#include <linux/icmp.h>
11#include <linux/sctp.h>
12#include <linux/dccp.h>
Eric Dumazet0744dd02011-11-28 05:22:18 +000013#include <linux/if_tunnel.h>
14#include <linux/if_pppox.h>
15#include <linux/ppp_defs.h>
Jiri Pirko06635a32015-05-12 14:56:16 +020016#include <linux/stddef.h>
Jiri Pirko1bd758e2015-05-12 14:56:07 +020017#include <net/flow_dissector.h>
Alexander Duyck56193d12014-09-05 19:20:26 -040018#include <scsi/fc/fc_fcoe.h>
Eric Dumazet0744dd02011-11-28 05:22:18 +000019
Jiri Pirkofbff9492015-05-12 14:56:15 +020020static bool skb_flow_dissector_uses_key(struct flow_dissector *flow_dissector,
21 enum flow_dissector_key_id key_id)
22{
23 return flow_dissector->used_keys & (1 << key_id);
24}
25
26static void skb_flow_dissector_set_key(struct flow_dissector *flow_dissector,
27 enum flow_dissector_key_id key_id)
28{
29 flow_dissector->used_keys |= (1 << key_id);
30}
31
32static void *skb_flow_dissector_target(struct flow_dissector *flow_dissector,
33 enum flow_dissector_key_id key_id,
34 void *target_container)
35{
36 return ((char *) target_container) + flow_dissector->offset[key_id];
37}
38
39void skb_flow_dissector_init(struct flow_dissector *flow_dissector,
40 const struct flow_dissector_key *key,
41 unsigned int key_count)
42{
43 unsigned int i;
44
45 memset(flow_dissector, 0, sizeof(*flow_dissector));
46
47 for (i = 0; i < key_count; i++, key++) {
48 /* User should make sure that every key target offset is withing
49 * boundaries of unsigned short.
50 */
51 BUG_ON(key->offset > USHRT_MAX);
52 BUG_ON(skb_flow_dissector_uses_key(flow_dissector,
53 key->key_id));
54
55 skb_flow_dissector_set_key(flow_dissector, key->key_id);
56 flow_dissector->offset[key->key_id] = key->offset;
57 }
58
59 /* Ensure that the dissector always includes basic key. That way
60 * we are able to avoid handling lack of it in fast path.
61 */
62 BUG_ON(!skb_flow_dissector_uses_key(flow_dissector,
63 FLOW_DISSECTOR_KEY_BASIC));
64}
65EXPORT_SYMBOL(skb_flow_dissector_init);
66
Nikolay Aleksandrov357afe92013-10-02 13:39:24 +020067/**
WANG Cong6451b3f2014-08-25 17:03:46 -070068 * __skb_flow_get_ports - extract the upper layer ports and return them
69 * @skb: sk_buff to extract the ports from
Nikolay Aleksandrov357afe92013-10-02 13:39:24 +020070 * @thoff: transport header offset
71 * @ip_proto: protocol for which to get port offset
WANG Cong6451b3f2014-08-25 17:03:46 -070072 * @data: raw buffer pointer to the packet, if NULL use skb->data
73 * @hlen: packet header length, if @data is NULL use skb_headlen(skb)
Nikolay Aleksandrov357afe92013-10-02 13:39:24 +020074 *
75 * The function will try to retrieve the ports at offset thoff + poff where poff
76 * is the protocol port offset returned from proto_ports_offset
77 */
David S. Miller690e36e2014-08-23 12:13:41 -070078__be32 __skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto,
79 void *data, int hlen)
Nikolay Aleksandrov357afe92013-10-02 13:39:24 +020080{
81 int poff = proto_ports_offset(ip_proto);
82
David S. Miller690e36e2014-08-23 12:13:41 -070083 if (!data) {
84 data = skb->data;
85 hlen = skb_headlen(skb);
86 }
87
Nikolay Aleksandrov357afe92013-10-02 13:39:24 +020088 if (poff >= 0) {
89 __be32 *ports, _ports;
90
David S. Miller690e36e2014-08-23 12:13:41 -070091 ports = __skb_header_pointer(skb, thoff + poff,
92 sizeof(_ports), data, hlen, &_ports);
Nikolay Aleksandrov357afe92013-10-02 13:39:24 +020093 if (ports)
94 return *ports;
95 }
96
97 return 0;
98}
David S. Miller690e36e2014-08-23 12:13:41 -070099EXPORT_SYMBOL(__skb_flow_get_ports);
Nikolay Aleksandrov357afe92013-10-02 13:39:24 +0200100
WANG Cong453a9402014-08-25 17:03:47 -0700101/**
102 * __skb_flow_dissect - extract the flow_keys struct and return it
103 * @skb: sk_buff to extract the flow from, can be NULL if the rest are specified
Jiri Pirko06635a32015-05-12 14:56:16 +0200104 * @flow_dissector: list of keys to dissect
105 * @target_container: target structure to put dissected values into
WANG Cong453a9402014-08-25 17:03:47 -0700106 * @data: raw buffer pointer to the packet, if NULL use skb->data
107 * @proto: protocol for which to get the flow, if @data is NULL use skb->protocol
108 * @nhoff: network header offset, if @data is NULL use skb_network_offset(skb)
109 * @hlen: packet header length, if @data is NULL use skb_headlen(skb)
110 *
Jiri Pirko06635a32015-05-12 14:56:16 +0200111 * The function will try to retrieve individual keys into target specified
112 * by flow_dissector from either the skbuff or a raw buffer specified by the
113 * rest parameters.
114 *
115 * Caller must take care of zeroing target container memory.
WANG Cong453a9402014-08-25 17:03:47 -0700116 */
Jiri Pirko06635a32015-05-12 14:56:16 +0200117bool __skb_flow_dissect(const struct sk_buff *skb,
118 struct flow_dissector *flow_dissector,
119 void *target_container,
WANG Cong453a9402014-08-25 17:03:47 -0700120 void *data, __be16 proto, int nhoff, int hlen)
Eric Dumazet0744dd02011-11-28 05:22:18 +0000121{
Jiri Pirko06635a32015-05-12 14:56:16 +0200122 struct flow_dissector_key_basic *key_basic;
123 struct flow_dissector_key_addrs *key_addrs;
124 struct flow_dissector_key_ports *key_ports;
Eric Dumazet0744dd02011-11-28 05:22:18 +0000125 u8 ip_proto;
Eric Dumazet0744dd02011-11-28 05:22:18 +0000126
David S. Miller690e36e2014-08-23 12:13:41 -0700127 if (!data) {
128 data = skb->data;
WANG Cong453a9402014-08-25 17:03:47 -0700129 proto = skb->protocol;
130 nhoff = skb_network_offset(skb);
David S. Miller690e36e2014-08-23 12:13:41 -0700131 hlen = skb_headlen(skb);
132 }
133
Jiri Pirko06635a32015-05-12 14:56:16 +0200134 /* It is ensured by skb_flow_dissector_init() that basic key will
135 * be always present.
136 */
137 key_basic = skb_flow_dissector_target(flow_dissector,
138 FLOW_DISSECTOR_KEY_BASIC,
139 target_container);
Eric Dumazet0744dd02011-11-28 05:22:18 +0000140
141again:
142 switch (proto) {
Joe Perches2b8837a2014-03-12 10:04:17 -0700143 case htons(ETH_P_IP): {
Eric Dumazet0744dd02011-11-28 05:22:18 +0000144 const struct iphdr *iph;
145 struct iphdr _iph;
146ip:
David S. Miller690e36e2014-08-23 12:13:41 -0700147 iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph);
Jason Wang6f092342013-11-01 15:01:10 +0800148 if (!iph || iph->ihl < 5)
Eric Dumazet0744dd02011-11-28 05:22:18 +0000149 return false;
Eric Dumazet3797d3e2013-11-07 08:37:28 -0800150 nhoff += iph->ihl * 4;
Eric Dumazet0744dd02011-11-28 05:22:18 +0000151
Eric Dumazet3797d3e2013-11-07 08:37:28 -0800152 ip_proto = iph->protocol;
Eric Dumazet0744dd02011-11-28 05:22:18 +0000153 if (ip_is_fragment(iph))
154 ip_proto = 0;
Eric Dumazet3797d3e2013-11-07 08:37:28 -0800155
Jiri Pirko06635a32015-05-12 14:56:16 +0200156 if (!skb_flow_dissector_uses_key(flow_dissector,
157 FLOW_DISSECTOR_KEY_IPV4_ADDRS))
Alexander Duyck5af7fb62014-10-10 12:09:12 -0700158 break;
Jiri Pirko06635a32015-05-12 14:56:16 +0200159 key_addrs = skb_flow_dissector_target(flow_dissector,
160 FLOW_DISSECTOR_KEY_IPV4_ADDRS,
161 target_container);
162 memcpy(key_addrs, &iph->saddr, sizeof(*key_addrs));
Eric Dumazet0744dd02011-11-28 05:22:18 +0000163 break;
164 }
Joe Perches2b8837a2014-03-12 10:04:17 -0700165 case htons(ETH_P_IPV6): {
Eric Dumazet0744dd02011-11-28 05:22:18 +0000166 const struct ipv6hdr *iph;
167 struct ipv6hdr _iph;
Tom Herbert19469a82014-07-01 21:33:01 -0700168 __be32 flow_label;
169
Eric Dumazet0744dd02011-11-28 05:22:18 +0000170ipv6:
David S. Miller690e36e2014-08-23 12:13:41 -0700171 iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph);
Eric Dumazet0744dd02011-11-28 05:22:18 +0000172 if (!iph)
173 return false;
174
175 ip_proto = iph->nexthdr;
Eric Dumazet0744dd02011-11-28 05:22:18 +0000176 nhoff += sizeof(struct ipv6hdr);
Tom Herbert19469a82014-07-01 21:33:01 -0700177
Jiri Pirkob9249332015-05-12 14:56:18 +0200178 if (skb_flow_dissector_uses_key(flow_dissector,
179 FLOW_DISSECTOR_KEY_IPV6_HASH_ADDRS)) {
180 key_addrs = skb_flow_dissector_target(flow_dissector,
181 FLOW_DISSECTOR_KEY_IPV6_HASH_ADDRS,
182 target_container);
Alexander Duyck56193d12014-09-05 19:20:26 -0400183
Jiri Pirkob9249332015-05-12 14:56:18 +0200184 key_addrs->src = (__force __be32)ipv6_addr_hash(&iph->saddr);
185 key_addrs->dst = (__force __be32)ipv6_addr_hash(&iph->daddr);
186 goto flow_label;
187 }
188 if (skb_flow_dissector_uses_key(flow_dissector,
189 FLOW_DISSECTOR_KEY_IPV6_ADDRS)) {
190 struct flow_dissector_key_ipv6_addrs *key_ipv6_addrs;
Alexander Duyck5af7fb62014-10-10 12:09:12 -0700191
Jiri Pirkob9249332015-05-12 14:56:18 +0200192 key_ipv6_addrs = skb_flow_dissector_target(flow_dissector,
193 FLOW_DISSECTOR_KEY_IPV6_ADDRS,
194 target_container);
195
196 memcpy(key_ipv6_addrs, &iph->saddr, sizeof(*key_ipv6_addrs));
197 goto flow_label;
198 }
199 break;
200flow_label:
Tom Herbert19469a82014-07-01 21:33:01 -0700201 flow_label = ip6_flowlabel(iph);
202 if (flow_label) {
203 /* Awesome, IPv6 packet has a flow label so we can
204 * use that to represent the ports without any
205 * further dissection.
206 */
Jiri Pirko06635a32015-05-12 14:56:16 +0200207
208 key_basic->n_proto = proto;
209 key_basic->ip_proto = ip_proto;
210 key_basic->thoff = (u16)nhoff;
211
212 if (!skb_flow_dissector_uses_key(flow_dissector,
213 FLOW_DISSECTOR_KEY_PORTS))
214 break;
215 key_ports = skb_flow_dissector_target(flow_dissector,
216 FLOW_DISSECTOR_KEY_PORTS,
217 target_container);
218 key_ports->ports = flow_label;
Tom Herbert19469a82014-07-01 21:33:01 -0700219
220 return true;
221 }
222
Eric Dumazet0744dd02011-11-28 05:22:18 +0000223 break;
224 }
Joe Perches2b8837a2014-03-12 10:04:17 -0700225 case htons(ETH_P_8021AD):
226 case htons(ETH_P_8021Q): {
Eric Dumazet0744dd02011-11-28 05:22:18 +0000227 const struct vlan_hdr *vlan;
228 struct vlan_hdr _vlan;
229
David S. Miller690e36e2014-08-23 12:13:41 -0700230 vlan = __skb_header_pointer(skb, nhoff, sizeof(_vlan), data, hlen, &_vlan);
Eric Dumazet0744dd02011-11-28 05:22:18 +0000231 if (!vlan)
232 return false;
233
234 proto = vlan->h_vlan_encapsulated_proto;
235 nhoff += sizeof(*vlan);
236 goto again;
237 }
Joe Perches2b8837a2014-03-12 10:04:17 -0700238 case htons(ETH_P_PPP_SES): {
Eric Dumazet0744dd02011-11-28 05:22:18 +0000239 struct {
240 struct pppoe_hdr hdr;
241 __be16 proto;
242 } *hdr, _hdr;
David S. Miller690e36e2014-08-23 12:13:41 -0700243 hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
Eric Dumazet0744dd02011-11-28 05:22:18 +0000244 if (!hdr)
245 return false;
246 proto = hdr->proto;
247 nhoff += PPPOE_SES_HLEN;
248 switch (proto) {
Joe Perches2b8837a2014-03-12 10:04:17 -0700249 case htons(PPP_IP):
Eric Dumazet0744dd02011-11-28 05:22:18 +0000250 goto ip;
Joe Perches2b8837a2014-03-12 10:04:17 -0700251 case htons(PPP_IPV6):
Eric Dumazet0744dd02011-11-28 05:22:18 +0000252 goto ipv6;
253 default:
254 return false;
255 }
256 }
Erik Hugne08bfc9c2015-01-22 17:10:32 +0100257 case htons(ETH_P_TIPC): {
258 struct {
259 __be32 pre[3];
260 __be32 srcnode;
261 } *hdr, _hdr;
262 hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
263 if (!hdr)
264 return false;
Jiri Pirko06635a32015-05-12 14:56:16 +0200265 key_basic->n_proto = proto;
266 key_basic->thoff = (u16)nhoff;
267
268 if (skb_flow_dissector_uses_key(flow_dissector,
269 FLOW_DISSECTOR_KEY_IPV6_HASH_ADDRS)) {
270 return true;
271 key_addrs = skb_flow_dissector_target(flow_dissector,
272 FLOW_DISSECTOR_KEY_IPV6_HASH_ADDRS,
273 target_container);
274 key_addrs->src = hdr->srcnode;
275 key_addrs->dst = 0;
276 }
Erik Hugne08bfc9c2015-01-22 17:10:32 +0100277 return true;
278 }
Alexander Duyck56193d12014-09-05 19:20:26 -0400279 case htons(ETH_P_FCOE):
Jiri Pirko06635a32015-05-12 14:56:16 +0200280 key_basic->thoff = (u16)(nhoff + FCOE_HEADER_LEN);
Alexander Duyck56193d12014-09-05 19:20:26 -0400281 /* fall through */
Eric Dumazet0744dd02011-11-28 05:22:18 +0000282 default:
283 return false;
284 }
285
286 switch (ip_proto) {
287 case IPPROTO_GRE: {
288 struct gre_hdr {
289 __be16 flags;
290 __be16 proto;
291 } *hdr, _hdr;
292
David S. Miller690e36e2014-08-23 12:13:41 -0700293 hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
Eric Dumazet0744dd02011-11-28 05:22:18 +0000294 if (!hdr)
295 return false;
296 /*
297 * Only look inside GRE if version zero and no
298 * routing
299 */
300 if (!(hdr->flags & (GRE_VERSION|GRE_ROUTING))) {
301 proto = hdr->proto;
302 nhoff += 4;
303 if (hdr->flags & GRE_CSUM)
304 nhoff += 4;
305 if (hdr->flags & GRE_KEY)
306 nhoff += 4;
307 if (hdr->flags & GRE_SEQ)
308 nhoff += 4;
Michael Daltone1733de2013-03-11 06:52:28 +0000309 if (proto == htons(ETH_P_TEB)) {
310 const struct ethhdr *eth;
311 struct ethhdr _eth;
312
David S. Miller690e36e2014-08-23 12:13:41 -0700313 eth = __skb_header_pointer(skb, nhoff,
314 sizeof(_eth),
315 data, hlen, &_eth);
Michael Daltone1733de2013-03-11 06:52:28 +0000316 if (!eth)
317 return false;
318 proto = eth->h_proto;
319 nhoff += sizeof(*eth);
320 }
Eric Dumazet0744dd02011-11-28 05:22:18 +0000321 goto again;
322 }
323 break;
324 }
325 case IPPROTO_IPIP:
Tom Herbertfca41892013-07-29 11:07:36 -0700326 proto = htons(ETH_P_IP);
327 goto ip;
Tom Herbertb438f942013-07-29 11:07:42 -0700328 case IPPROTO_IPV6:
329 proto = htons(ETH_P_IPV6);
330 goto ipv6;
Eric Dumazet0744dd02011-11-28 05:22:18 +0000331 default:
332 break;
333 }
334
Jiri Pirko06635a32015-05-12 14:56:16 +0200335 /* It is ensured by skb_flow_dissector_init() that basic key will
336 * be always present.
337 */
338 key_basic = skb_flow_dissector_target(flow_dissector,
339 FLOW_DISSECTOR_KEY_BASIC,
340 target_container);
341 key_basic->n_proto = proto;
342 key_basic->ip_proto = ip_proto;
343 key_basic->thoff = (u16) nhoff;
Daniel Borkmann8ed78162013-03-19 06:39:29 +0000344
Jiri Pirko06635a32015-05-12 14:56:16 +0200345 if (skb_flow_dissector_uses_key(flow_dissector,
346 FLOW_DISSECTOR_KEY_PORTS)) {
347 key_ports = skb_flow_dissector_target(flow_dissector,
348 FLOW_DISSECTOR_KEY_PORTS,
349 target_container);
350 key_ports->ports = __skb_flow_get_ports(skb, nhoff, ip_proto,
351 data, hlen);
352 }
Alexander Duyck5af7fb62014-10-10 12:09:12 -0700353
Eric Dumazet0744dd02011-11-28 05:22:18 +0000354 return true;
355}
David S. Miller690e36e2014-08-23 12:13:41 -0700356EXPORT_SYMBOL(__skb_flow_dissect);
Cong Wang441d9d32013-01-21 00:39:24 +0000357
358static u32 hashrnd __read_mostly;
Hannes Frederic Sowa66415cf2013-10-23 20:06:00 +0200359static __always_inline void __flow_hash_secret_init(void)
360{
361 net_get_random_once(&hashrnd, sizeof(hashrnd));
362}
363
Tom Herbert50fb7992015-05-01 11:30:12 -0700364static __always_inline u32 __flow_hash_3words(u32 a, u32 b, u32 c, u32 keyval)
Hannes Frederic Sowa66415cf2013-10-23 20:06:00 +0200365{
Tom Herbert50fb7992015-05-01 11:30:12 -0700366 return jhash_3words(a, b, c, keyval);
Hannes Frederic Sowa66415cf2013-10-23 20:06:00 +0200367}
368
Tom Herbert50fb7992015-05-01 11:30:12 -0700369static inline u32 __flow_hash_from_keys(struct flow_keys *keys, u32 keyval)
Tom Herbert5ed20a62014-07-01 21:32:05 -0700370{
371 u32 hash;
372
373 /* get a consistent hash (same value on both flow directions) */
Jiri Pirko06635a32015-05-12 14:56:16 +0200374 if (((__force u32)keys->addrs.dst < (__force u32)keys->addrs.src) ||
375 (((__force u32)keys->addrs.dst == (__force u32)keys->addrs.src) &&
376 ((__force u16)keys->ports.port16[1] < (__force u16)keys->ports.port16[0]))) {
377 swap(keys->addrs.dst, keys->addrs.src);
378 swap(keys->ports.port16[0], keys->ports.port16[1]);
Tom Herbert5ed20a62014-07-01 21:32:05 -0700379 }
380
Jiri Pirko06635a32015-05-12 14:56:16 +0200381 hash = __flow_hash_3words((__force u32)keys->addrs.dst,
382 (__force u32)keys->addrs.src,
383 (__force u32)keys->ports.ports,
Tom Herbert50fb7992015-05-01 11:30:12 -0700384 keyval);
Tom Herbert5ed20a62014-07-01 21:32:05 -0700385 if (!hash)
386 hash = 1;
387
388 return hash;
389}
390
391u32 flow_hash_from_keys(struct flow_keys *keys)
392{
Tom Herbert50fb7992015-05-01 11:30:12 -0700393 __flow_hash_secret_init();
394 return __flow_hash_from_keys(keys, hashrnd);
Tom Herbert5ed20a62014-07-01 21:32:05 -0700395}
396EXPORT_SYMBOL(flow_hash_from_keys);
397
Tom Herbert50fb7992015-05-01 11:30:12 -0700398static inline u32 ___skb_get_hash(const struct sk_buff *skb,
399 struct flow_keys *keys, u32 keyval)
400{
Jiri Pirko06635a32015-05-12 14:56:16 +0200401 if (!skb_flow_dissect_flow_keys(skb, keys))
Tom Herbert50fb7992015-05-01 11:30:12 -0700402 return 0;
403
404 return __flow_hash_from_keys(keys, keyval);
405}
406
Tom Herbert2f59e1e2015-05-01 11:30:17 -0700407struct _flow_keys_digest_data {
408 __be16 n_proto;
409 u8 ip_proto;
410 u8 padding;
411 __be32 ports;
412 __be32 src;
413 __be32 dst;
414};
415
416void make_flow_keys_digest(struct flow_keys_digest *digest,
417 const struct flow_keys *flow)
418{
419 struct _flow_keys_digest_data *data =
420 (struct _flow_keys_digest_data *)digest;
421
422 BUILD_BUG_ON(sizeof(*data) > sizeof(*digest));
423
424 memset(digest, 0, sizeof(*digest));
425
Jiri Pirko06635a32015-05-12 14:56:16 +0200426 data->n_proto = flow->basic.n_proto;
427 data->ip_proto = flow->basic.ip_proto;
428 data->ports = flow->ports.ports;
429 data->src = flow->addrs.src;
430 data->dst = flow->addrs.dst;
Tom Herbert2f59e1e2015-05-01 11:30:17 -0700431}
432EXPORT_SYMBOL(make_flow_keys_digest);
433
Jiri Pirkod4fd3272015-05-12 14:56:10 +0200434/**
435 * __skb_get_hash: calculate a flow hash
436 * @skb: sk_buff to calculate flow hash from
437 *
438 * This function calculates a flow hash based on src/dst addresses
Tom Herbert61b905d2014-03-24 15:34:47 -0700439 * and src/dst port numbers. Sets hash in skb to non-zero hash value
440 * on success, zero indicates no valid hash. Also, sets l4_hash in skb
Cong Wang441d9d32013-01-21 00:39:24 +0000441 * if hash is a canonical 4-tuple hash over transport ports.
442 */
Tom Herbert3958afa1b2013-12-15 22:12:06 -0800443void __skb_get_hash(struct sk_buff *skb)
Cong Wang441d9d32013-01-21 00:39:24 +0000444{
445 struct flow_keys keys;
Tom Herbert50fb7992015-05-01 11:30:12 -0700446 u32 hash;
Cong Wang441d9d32013-01-21 00:39:24 +0000447
Tom Herbert50fb7992015-05-01 11:30:12 -0700448 __flow_hash_secret_init();
449
450 hash = ___skb_get_hash(skb, &keys, hashrnd);
451 if (!hash)
Cong Wang441d9d32013-01-21 00:39:24 +0000452 return;
Jiri Pirko06635a32015-05-12 14:56:16 +0200453 if (keys.ports.ports)
Tom Herbert61b905d2014-03-24 15:34:47 -0700454 skb->l4_hash = 1;
Tom Herberta3b18dd2014-07-01 21:33:17 -0700455 skb->sw_hash = 1;
Tom Herbert50fb7992015-05-01 11:30:12 -0700456 skb->hash = hash;
Cong Wang441d9d32013-01-21 00:39:24 +0000457}
Tom Herbert3958afa1b2013-12-15 22:12:06 -0800458EXPORT_SYMBOL(__skb_get_hash);
Cong Wang441d9d32013-01-21 00:39:24 +0000459
Tom Herbert50fb7992015-05-01 11:30:12 -0700460__u32 skb_get_hash_perturb(const struct sk_buff *skb, u32 perturb)
461{
462 struct flow_keys keys;
463
464 return ___skb_get_hash(skb, &keys, perturb);
465}
466EXPORT_SYMBOL(skb_get_hash_perturb);
467
Alexander Duyck56193d12014-09-05 19:20:26 -0400468u32 __skb_get_poff(const struct sk_buff *skb, void *data,
469 const struct flow_keys *keys, int hlen)
Daniel Borkmannf77668d2013-03-19 06:39:30 +0000470{
Jiri Pirko06635a32015-05-12 14:56:16 +0200471 u32 poff = keys->basic.thoff;
Daniel Borkmannf77668d2013-03-19 06:39:30 +0000472
Jiri Pirko06635a32015-05-12 14:56:16 +0200473 switch (keys->basic.ip_proto) {
Daniel Borkmannf77668d2013-03-19 06:39:30 +0000474 case IPPROTO_TCP: {
Alexander Duyck5af7fb62014-10-10 12:09:12 -0700475 /* access doff as u8 to avoid unaligned access */
476 const u8 *doff;
477 u8 _doff;
Daniel Borkmannf77668d2013-03-19 06:39:30 +0000478
Alexander Duyck5af7fb62014-10-10 12:09:12 -0700479 doff = __skb_header_pointer(skb, poff + 12, sizeof(_doff),
480 data, hlen, &_doff);
481 if (!doff)
Daniel Borkmannf77668d2013-03-19 06:39:30 +0000482 return poff;
483
Alexander Duyck5af7fb62014-10-10 12:09:12 -0700484 poff += max_t(u32, sizeof(struct tcphdr), (*doff & 0xF0) >> 2);
Daniel Borkmannf77668d2013-03-19 06:39:30 +0000485 break;
486 }
487 case IPPROTO_UDP:
488 case IPPROTO_UDPLITE:
489 poff += sizeof(struct udphdr);
490 break;
491 /* For the rest, we do not really care about header
492 * extensions at this point for now.
493 */
494 case IPPROTO_ICMP:
495 poff += sizeof(struct icmphdr);
496 break;
497 case IPPROTO_ICMPV6:
498 poff += sizeof(struct icmp6hdr);
499 break;
500 case IPPROTO_IGMP:
501 poff += sizeof(struct igmphdr);
502 break;
503 case IPPROTO_DCCP:
504 poff += sizeof(struct dccp_hdr);
505 break;
506 case IPPROTO_SCTP:
507 poff += sizeof(struct sctphdr);
508 break;
509 }
510
511 return poff;
512}
513
Jiri Pirko0db89b82015-05-12 14:56:14 +0200514/**
515 * skb_get_poff - get the offset to the payload
516 * @skb: sk_buff to get the payload offset from
517 *
518 * The function will get the offset to the payload as far as it could
519 * be dissected. The main user is currently BPF, so that we can dynamically
Alexander Duyck56193d12014-09-05 19:20:26 -0400520 * truncate packets without needing to push actual payload to the user
521 * space and can analyze headers only, instead.
522 */
523u32 skb_get_poff(const struct sk_buff *skb)
524{
525 struct flow_keys keys;
526
Jiri Pirko06635a32015-05-12 14:56:16 +0200527 if (!skb_flow_dissect_flow_keys(skb, &keys))
Alexander Duyck56193d12014-09-05 19:20:26 -0400528 return 0;
529
530 return __skb_get_poff(skb, skb->data, &keys, skb_headlen(skb));
531}
Jiri Pirko06635a32015-05-12 14:56:16 +0200532
533static const struct flow_dissector_key flow_keys_dissector_keys[] = {
534 {
535 .key_id = FLOW_DISSECTOR_KEY_BASIC,
536 .offset = offsetof(struct flow_keys, basic),
537 },
538 {
539 .key_id = FLOW_DISSECTOR_KEY_IPV4_ADDRS,
540 .offset = offsetof(struct flow_keys, addrs),
541 },
542 {
543 .key_id = FLOW_DISSECTOR_KEY_IPV6_HASH_ADDRS,
544 .offset = offsetof(struct flow_keys, addrs),
545 },
546 {
547 .key_id = FLOW_DISSECTOR_KEY_PORTS,
548 .offset = offsetof(struct flow_keys, ports),
549 },
550};
551
552static const struct flow_dissector_key flow_keys_buf_dissector_keys[] = {
553 {
554 .key_id = FLOW_DISSECTOR_KEY_BASIC,
555 .offset = offsetof(struct flow_keys, basic),
556 },
557};
558
559struct flow_dissector flow_keys_dissector __read_mostly;
560EXPORT_SYMBOL(flow_keys_dissector);
561
562struct flow_dissector flow_keys_buf_dissector __read_mostly;
563
564static int __init init_default_flow_dissectors(void)
565{
566 skb_flow_dissector_init(&flow_keys_dissector,
567 flow_keys_dissector_keys,
568 ARRAY_SIZE(flow_keys_dissector_keys));
569 skb_flow_dissector_init(&flow_keys_buf_dissector,
570 flow_keys_buf_dissector_keys,
571 ARRAY_SIZE(flow_keys_buf_dissector_keys));
572 return 0;
573}
574
575late_initcall_sync(init_default_flow_dissectors);