Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-only
2 : : #include <linux/kernel.h>
3 : : #include <linux/skbuff.h>
4 : : #include <linux/export.h>
5 : : #include <linux/ip.h>
6 : : #include <linux/ipv6.h>
7 : : #include <linux/if_vlan.h>
8 : : #include <net/dsa.h>
9 : : #include <net/dst_metadata.h>
10 : : #include <net/ip.h>
11 : : #include <net/ipv6.h>
12 : : #include <net/gre.h>
13 : : #include <net/pptp.h>
14 : : #include <net/tipc.h>
15 : : #include <linux/igmp.h>
16 : : #include <linux/icmp.h>
17 : : #include <linux/sctp.h>
18 : : #include <linux/dccp.h>
19 : : #include <linux/if_tunnel.h>
20 : : #include <linux/if_pppox.h>
21 : : #include <linux/ppp_defs.h>
22 : : #include <linux/stddef.h>
23 : : #include <linux/if_ether.h>
24 : : #include <linux/mpls.h>
25 : : #include <linux/tcp.h>
26 : : #include <net/flow_dissector.h>
27 : : #include <scsi/fc/fc_fcoe.h>
28 : : #include <uapi/linux/batadv_packet.h>
29 : : #include <linux/bpf.h>
30 : : #if IS_ENABLED(CONFIG_NF_CONNTRACK)
31 : : #include <net/netfilter/nf_conntrack_core.h>
32 : : #include <net/netfilter/nf_conntrack_labels.h>
33 : : #endif
34 : :
35 : : static DEFINE_MUTEX(flow_dissector_mutex);
36 : :
37 : 336 : static void dissector_set_key(struct flow_dissector *flow_dissector,
38 : : enum flow_dissector_key_id key_id)
39 : : {
40 : 336 : flow_dissector->used_keys |= (1 << key_id);
41 : : }
42 : :
43 : 63 : void skb_flow_dissector_init(struct flow_dissector *flow_dissector,
44 : : const struct flow_dissector_key *key,
45 : : unsigned int key_count)
46 : : {
47 : 63 : unsigned int i;
48 : :
49 : 63 : memset(flow_dissector, 0, sizeof(*flow_dissector));
50 : :
51 [ + + ]: 399 : for (i = 0; i < key_count; i++, key++) {
52 : : /* User should make sure that every key target offset is withing
53 : : * boundaries of unsigned short.
54 : : */
55 [ - + ]: 336 : BUG_ON(key->offset > USHRT_MAX);
56 [ - + ]: 336 : BUG_ON(dissector_uses_key(flow_dissector,
57 : : key->key_id));
58 : :
59 : 336 : dissector_set_key(flow_dissector, key->key_id);
60 : 336 : flow_dissector->offset[key->key_id] = key->offset;
61 : : }
62 : :
63 : : /* Ensure that the dissector always includes control and basic key.
64 : : * That way we are able to avoid handling lack of these in fast path.
65 : : */
66 [ - + ]: 63 : BUG_ON(!dissector_uses_key(flow_dissector,
67 : : FLOW_DISSECTOR_KEY_CONTROL));
68 [ - + ]: 63 : BUG_ON(!dissector_uses_key(flow_dissector,
69 : : FLOW_DISSECTOR_KEY_BASIC));
70 : 63 : }
71 : : EXPORT_SYMBOL(skb_flow_dissector_init);
72 : :
73 : 0 : int skb_flow_dissector_prog_query(const union bpf_attr *attr,
74 : : union bpf_attr __user *uattr)
75 : : {
76 : 0 : __u32 __user *prog_ids = u64_to_user_ptr(attr->query.prog_ids);
77 : 0 : u32 prog_id, prog_cnt = 0, flags = 0;
78 : 0 : struct bpf_prog *attached;
79 : 0 : struct net *net;
80 : :
81 [ # # ]: 0 : if (attr->query.query_flags)
82 : : return -EINVAL;
83 : :
84 : 0 : net = get_net_ns_by_fd(attr->query.target_fd);
85 [ # # ]: 0 : if (IS_ERR(net))
86 : 0 : return PTR_ERR(net);
87 : :
88 : 0 : rcu_read_lock();
89 [ # # ]: 0 : attached = rcu_dereference(net->flow_dissector_prog);
90 [ # # ]: 0 : if (attached) {
91 : 0 : prog_cnt = 1;
92 : 0 : prog_id = attached->aux->id;
93 : : }
94 : 0 : rcu_read_unlock();
95 : :
96 : 0 : put_net(net);
97 : :
98 [ # # ]: 0 : if (copy_to_user(&uattr->query.attach_flags, &flags, sizeof(flags)))
99 : : return -EFAULT;
100 [ # # ]: 0 : if (copy_to_user(&uattr->query.prog_cnt, &prog_cnt, sizeof(prog_cnt)))
101 : : return -EFAULT;
102 : :
103 [ # # # # : 0 : if (!attr->query.prog_cnt || !prog_ids || !prog_cnt)
# # ]
104 : : return 0;
105 : :
106 [ # # ]: 0 : if (copy_to_user(prog_ids, &prog_id, sizeof(u32)))
107 : 0 : return -EFAULT;
108 : :
109 : : return 0;
110 : : }
111 : :
112 : 0 : int skb_flow_dissector_bpf_prog_attach(const union bpf_attr *attr,
113 : : struct bpf_prog *prog)
114 : : {
115 : 0 : struct bpf_prog *attached;
116 : 0 : struct net *net;
117 : 0 : int ret = 0;
118 : :
119 : 0 : net = current->nsproxy->net_ns;
120 : 0 : mutex_lock(&flow_dissector_mutex);
121 : :
122 [ # # ]: 0 : if (net == &init_net) {
123 : : /* BPF flow dissector in the root namespace overrides
124 : : * any per-net-namespace one. When attaching to root,
125 : : * make sure we don't have any BPF program attached
126 : : * to the non-root namespaces.
127 : : */
128 : 0 : struct net *ns;
129 : :
130 [ # # ]: 0 : for_each_net(ns) {
131 [ # # ]: 0 : if (ns == &init_net)
132 : 0 : continue;
133 [ # # ]: 0 : if (rcu_access_pointer(ns->flow_dissector_prog)) {
134 : 0 : ret = -EEXIST;
135 : 0 : goto out;
136 : : }
137 : : }
138 : : } else {
139 : : /* Make sure root flow dissector is not attached
140 : : * when attaching to the non-root namespace.
141 : : */
142 [ # # ]: 0 : if (rcu_access_pointer(init_net.flow_dissector_prog)) {
143 : 0 : ret = -EEXIST;
144 : 0 : goto out;
145 : : }
146 : : }
147 : :
148 : 0 : attached = rcu_dereference_protected(net->flow_dissector_prog,
149 : : lockdep_is_held(&flow_dissector_mutex));
150 [ # # ]: 0 : if (attached == prog) {
151 : : /* The same program cannot be attached twice */
152 : 0 : ret = -EINVAL;
153 : 0 : goto out;
154 : : }
155 : 0 : rcu_assign_pointer(net->flow_dissector_prog, prog);
156 : 0 : if (attached)
157 : : bpf_prog_put(attached);
158 : 0 : out:
159 : 0 : mutex_unlock(&flow_dissector_mutex);
160 : 0 : return ret;
161 : : }
162 : :
163 : 0 : int skb_flow_dissector_bpf_prog_detach(const union bpf_attr *attr)
164 : : {
165 : 0 : struct bpf_prog *attached;
166 : 0 : struct net *net;
167 : :
168 : 0 : net = current->nsproxy->net_ns;
169 : 0 : mutex_lock(&flow_dissector_mutex);
170 : 0 : attached = rcu_dereference_protected(net->flow_dissector_prog,
171 : : lockdep_is_held(&flow_dissector_mutex));
172 [ # # ]: 0 : if (!attached) {
173 : 0 : mutex_unlock(&flow_dissector_mutex);
174 : 0 : return -ENOENT;
175 : : }
176 : 0 : RCU_INIT_POINTER(net->flow_dissector_prog, NULL);
177 : 0 : bpf_prog_put(attached);
178 : 0 : mutex_unlock(&flow_dissector_mutex);
179 : 0 : return 0;
180 : : }
181 : :
182 : : /**
183 : : * __skb_flow_get_ports - extract the upper layer ports and return them
184 : : * @skb: sk_buff to extract the ports from
185 : : * @thoff: transport header offset
186 : : * @ip_proto: protocol for which to get port offset
187 : : * @data: raw buffer pointer to the packet, if NULL use skb->data
188 : : * @hlen: packet header length, if @data is NULL use skb_headlen(skb)
189 : : *
190 : : * The function will try to retrieve the ports at offset thoff + poff where poff
191 : : * is the protocol port offset returned from proto_ports_offset
192 : : */
193 : 0 : __be32 __skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto,
194 : : void *data, int hlen)
195 : : {
196 [ # # # ]: 0 : int poff = proto_ports_offset(ip_proto);
197 : :
198 [ # # ]: 0 : if (!data) {
199 : 0 : data = skb->data;
200 : 0 : hlen = skb_headlen(skb);
201 : : }
202 : :
203 [ # # ]: 0 : if (poff >= 0) {
204 : 0 : __be32 *ports, _ports;
205 : :
206 [ # # ]: 0 : ports = __skb_header_pointer(skb, thoff + poff,
207 : : sizeof(_ports), data, hlen, &_ports);
208 [ # # ]: 0 : if (ports)
209 : 0 : return *ports;
210 : : }
211 : :
212 : : return 0;
213 : : }
214 : : EXPORT_SYMBOL(__skb_flow_get_ports);
215 : :
216 : 0 : static bool icmp_has_id(u8 type)
217 : : {
218 : 0 : switch (type) {
219 : : case ICMP_ECHO:
220 : : case ICMP_ECHOREPLY:
221 : : case ICMP_TIMESTAMP:
222 : : case ICMP_TIMESTAMPREPLY:
223 : : case ICMPV6_ECHO_REQUEST:
224 : : case ICMPV6_ECHO_REPLY:
225 : : return true;
226 : : }
227 : :
228 : 0 : return false;
229 : : }
230 : :
231 : : /**
232 : : * skb_flow_get_icmp_tci - extract ICMP(6) Type, Code and Identifier fields
233 : : * @skb: sk_buff to extract from
234 : : * @key_icmp: struct flow_dissector_key_icmp to fill
235 : : * @data: raw buffer pointer to the packet
236 : : * @thoff: offset to extract at
237 : : * @hlen: packet header length
238 : : */
239 : 0 : void skb_flow_get_icmp_tci(const struct sk_buff *skb,
240 : : struct flow_dissector_key_icmp *key_icmp,
241 : : void *data, int thoff, int hlen)
242 : : {
243 : 0 : struct icmphdr *ih, _ih;
244 : :
245 [ # # ]: 0 : ih = __skb_header_pointer(skb, thoff, sizeof(_ih), data, hlen, &_ih);
246 [ # # ]: 0 : if (!ih)
247 : 0 : return;
248 : :
249 : 0 : key_icmp->type = ih->type;
250 : 0 : key_icmp->code = ih->code;
251 : :
252 : : /* As we use 0 to signal that the Id field is not present,
253 : : * avoid confusion with packets without such field
254 : : */
255 [ # # ]: 0 : if (icmp_has_id(ih->type))
256 : 0 : key_icmp->id = ih->un.echo.id ? : 1;
257 : : else
258 : 0 : key_icmp->id = 0;
259 : : }
260 : : EXPORT_SYMBOL(skb_flow_get_icmp_tci);
261 : :
262 : : /* If FLOW_DISSECTOR_KEY_ICMP is set, dissect an ICMP packet
263 : : * using skb_flow_get_icmp_tci().
264 : : */
265 : 0 : static void __skb_flow_dissect_icmp(const struct sk_buff *skb,
266 : : struct flow_dissector *flow_dissector,
267 : : void *target_container,
268 : : void *data, int thoff, int hlen)
269 : : {
270 : 0 : struct flow_dissector_key_icmp *key_icmp;
271 : :
272 : 0 : if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ICMP))
273 : : return;
274 : :
275 : 0 : key_icmp = skb_flow_dissector_target(flow_dissector,
276 : : FLOW_DISSECTOR_KEY_ICMP,
277 : : target_container);
278 : :
279 : 0 : skb_flow_get_icmp_tci(skb, key_icmp, data, thoff, hlen);
280 : : }
281 : :
282 : 0 : void skb_flow_dissect_meta(const struct sk_buff *skb,
283 : : struct flow_dissector *flow_dissector,
284 : : void *target_container)
285 : : {
286 : 0 : struct flow_dissector_key_meta *meta;
287 : :
288 [ # # ]: 0 : if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_META))
289 : : return;
290 : :
291 : 0 : meta = skb_flow_dissector_target(flow_dissector,
292 : : FLOW_DISSECTOR_KEY_META,
293 : : target_container);
294 : 0 : meta->ingress_ifindex = skb->skb_iif;
295 : : }
296 : : EXPORT_SYMBOL(skb_flow_dissect_meta);
297 : :
298 : : static void
299 : 0 : skb_flow_dissect_set_enc_addr_type(enum flow_dissector_key_id type,
300 : : struct flow_dissector *flow_dissector,
301 : : void *target_container)
302 : : {
303 : 0 : struct flow_dissector_key_control *ctrl;
304 : :
305 : 0 : if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ENC_CONTROL))
306 : : return;
307 : :
308 : 0 : ctrl = skb_flow_dissector_target(flow_dissector,
309 : : FLOW_DISSECTOR_KEY_ENC_CONTROL,
310 : : target_container);
311 : 0 : ctrl->addr_type = type;
312 : : }
313 : :
314 : : void
315 : 0 : skb_flow_dissect_ct(const struct sk_buff *skb,
316 : : struct flow_dissector *flow_dissector,
317 : : void *target_container,
318 : : u16 *ctinfo_map,
319 : : size_t mapsize)
320 : : {
321 : : #if IS_ENABLED(CONFIG_NF_CONNTRACK)
322 : 0 : struct flow_dissector_key_ct *key;
323 : 0 : enum ip_conntrack_info ctinfo;
324 : 0 : struct nf_conn_labels *cl;
325 : 0 : struct nf_conn *ct;
326 : :
327 [ # # ]: 0 : if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_CT))
328 : : return;
329 : :
330 [ # # ]: 0 : ct = nf_ct_get(skb, &ctinfo);
331 [ # # ]: 0 : if (!ct)
332 : : return;
333 : :
334 [ # # ]: 0 : key = skb_flow_dissector_target(flow_dissector,
335 : : FLOW_DISSECTOR_KEY_CT,
336 : : target_container);
337 : :
338 [ # # ]: 0 : if (ctinfo < mapsize)
339 : 0 : key->ct_state = ctinfo_map[ctinfo];
340 : : #if IS_ENABLED(CONFIG_NF_CONNTRACK_ZONES)
341 : : key->ct_zone = ct->zone.id;
342 : : #endif
343 : : #if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK)
344 : : key->ct_mark = ct->mark;
345 : : #endif
346 : :
347 : : cl = nf_ct_labels_find(ct);
348 : : if (cl)
349 : : memcpy(key->ct_labels, cl->bits, sizeof(key->ct_labels));
350 : : #endif /* CONFIG_NF_CONNTRACK */
351 : : }
352 : : EXPORT_SYMBOL(skb_flow_dissect_ct);
353 : :
354 : : void
355 : 0 : skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
356 : : struct flow_dissector *flow_dissector,
357 : : void *target_container)
358 : : {
359 : 0 : struct ip_tunnel_info *info;
360 : 0 : struct ip_tunnel_key *key;
361 : :
362 : : /* A quick check to see if there might be something to do. */
363 [ # # ]: 0 : if (!dissector_uses_key(flow_dissector,
364 [ # # ]: 0 : FLOW_DISSECTOR_KEY_ENC_KEYID) &&
365 : : !dissector_uses_key(flow_dissector,
366 [ # # ]: 0 : FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS) &&
367 : : !dissector_uses_key(flow_dissector,
368 [ # # ]: 0 : FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS) &&
369 : : !dissector_uses_key(flow_dissector,
370 [ # # ]: 0 : FLOW_DISSECTOR_KEY_ENC_CONTROL) &&
371 : : !dissector_uses_key(flow_dissector,
372 [ # # ]: 0 : FLOW_DISSECTOR_KEY_ENC_PORTS) &&
373 : : !dissector_uses_key(flow_dissector,
374 [ # # ]: 0 : FLOW_DISSECTOR_KEY_ENC_IP) &&
375 : : !dissector_uses_key(flow_dissector,
376 : : FLOW_DISSECTOR_KEY_ENC_OPTS))
377 : : return;
378 : :
379 [ # # ]: 0 : info = skb_tunnel_info(skb);
380 [ # # ]: 0 : if (!info)
381 : : return;
382 : :
383 : 0 : key = &info->key;
384 : :
385 [ # # ]: 0 : switch (ip_tunnel_info_af(info)) {
386 : : case AF_INET:
387 [ # # ]: 0 : skb_flow_dissect_set_enc_addr_type(FLOW_DISSECTOR_KEY_IPV4_ADDRS,
388 : : flow_dissector,
389 : : target_container);
390 [ # # ]: 0 : if (dissector_uses_key(flow_dissector,
391 : : FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS)) {
392 : 0 : struct flow_dissector_key_ipv4_addrs *ipv4;
393 : :
394 : 0 : ipv4 = skb_flow_dissector_target(flow_dissector,
395 : : FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS,
396 : : target_container);
397 : 0 : ipv4->src = key->u.ipv4.src;
398 : 0 : ipv4->dst = key->u.ipv4.dst;
399 : : }
400 : : break;
401 : : case AF_INET6:
402 [ # # ]: 0 : skb_flow_dissect_set_enc_addr_type(FLOW_DISSECTOR_KEY_IPV6_ADDRS,
403 : : flow_dissector,
404 : : target_container);
405 [ # # ]: 0 : if (dissector_uses_key(flow_dissector,
406 : : FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS)) {
407 : 0 : struct flow_dissector_key_ipv6_addrs *ipv6;
408 : :
409 : 0 : ipv6 = skb_flow_dissector_target(flow_dissector,
410 : : FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS,
411 : : target_container);
412 : 0 : ipv6->src = key->u.ipv6.src;
413 : 0 : ipv6->dst = key->u.ipv6.dst;
414 : : }
415 : : break;
416 : : }
417 : :
418 [ # # ]: 0 : if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ENC_KEYID)) {
419 : 0 : struct flow_dissector_key_keyid *keyid;
420 : :
421 : 0 : keyid = skb_flow_dissector_target(flow_dissector,
422 : : FLOW_DISSECTOR_KEY_ENC_KEYID,
423 : : target_container);
424 : 0 : keyid->keyid = tunnel_id_to_key32(key->tun_id);
425 : : }
426 : :
427 [ # # ]: 0 : if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ENC_PORTS)) {
428 : 0 : struct flow_dissector_key_ports *tp;
429 : :
430 : 0 : tp = skb_flow_dissector_target(flow_dissector,
431 : : FLOW_DISSECTOR_KEY_ENC_PORTS,
432 : : target_container);
433 : 0 : tp->src = key->tp_src;
434 : 0 : tp->dst = key->tp_dst;
435 : : }
436 : :
437 [ # # ]: 0 : if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ENC_IP)) {
438 : 0 : struct flow_dissector_key_ip *ip;
439 : :
440 : 0 : ip = skb_flow_dissector_target(flow_dissector,
441 : : FLOW_DISSECTOR_KEY_ENC_IP,
442 : : target_container);
443 : 0 : ip->tos = key->tos;
444 : 0 : ip->ttl = key->ttl;
445 : : }
446 : :
447 [ # # ]: 0 : if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ENC_OPTS)) {
448 : 0 : struct flow_dissector_key_enc_opts *enc_opt;
449 : :
450 [ # # ]: 0 : enc_opt = skb_flow_dissector_target(flow_dissector,
451 : : FLOW_DISSECTOR_KEY_ENC_OPTS,
452 : : target_container);
453 : :
454 [ # # ]: 0 : if (info->options_len) {
455 : 0 : enc_opt->len = info->options_len;
456 : 0 : ip_tunnel_info_opts_get(enc_opt->data, info);
457 : 0 : enc_opt->dst_opt_type = info->key.tun_flags &
458 : : TUNNEL_OPTIONS_PRESENT;
459 : : }
460 : : }
461 : : }
462 : : EXPORT_SYMBOL(skb_flow_dissect_tunnel_info);
463 : :
464 : : static enum flow_dissect_ret
465 : 0 : __skb_flow_dissect_mpls(const struct sk_buff *skb,
466 : : struct flow_dissector *flow_dissector,
467 : : void *target_container, void *data, int nhoff, int hlen)
468 : : {
469 : 0 : struct flow_dissector_key_keyid *key_keyid;
470 : 0 : struct mpls_label *hdr, _hdr[2];
471 : 0 : u32 entry, label;
472 : :
473 [ # # ]: 0 : if (!dissector_uses_key(flow_dissector,
474 [ # # ]: 0 : FLOW_DISSECTOR_KEY_MPLS_ENTROPY) &&
475 : : !dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_MPLS))
476 : : return FLOW_DISSECT_RET_OUT_GOOD;
477 : :
478 [ # # ]: 0 : hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data,
479 : : hlen, &_hdr);
480 [ # # ]: 0 : if (!hdr)
481 : 0 : return FLOW_DISSECT_RET_OUT_BAD;
482 : :
483 : 0 : entry = ntohl(hdr[0].entry);
484 : 0 : label = (entry & MPLS_LS_LABEL_MASK) >> MPLS_LS_LABEL_SHIFT;
485 : :
486 [ # # ]: 0 : if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_MPLS)) {
487 : 0 : struct flow_dissector_key_mpls *key_mpls;
488 : :
489 : 0 : key_mpls = skb_flow_dissector_target(flow_dissector,
490 : : FLOW_DISSECTOR_KEY_MPLS,
491 : : target_container);
492 : 0 : key_mpls->mpls_label = label;
493 : 0 : key_mpls->mpls_ttl = (entry & MPLS_LS_TTL_MASK)
494 : : >> MPLS_LS_TTL_SHIFT;
495 : 0 : key_mpls->mpls_tc = (entry & MPLS_LS_TC_MASK)
496 : 0 : >> MPLS_LS_TC_SHIFT;
497 : 0 : key_mpls->mpls_bos = (entry & MPLS_LS_S_MASK)
498 : 0 : >> MPLS_LS_S_SHIFT;
499 : : }
500 : :
501 [ # # ]: 0 : if (label == MPLS_LABEL_ENTROPY) {
502 : 0 : key_keyid = skb_flow_dissector_target(flow_dissector,
503 : : FLOW_DISSECTOR_KEY_MPLS_ENTROPY,
504 : : target_container);
505 : 0 : key_keyid->keyid = hdr[1].entry & htonl(MPLS_LS_LABEL_MASK);
506 : : }
507 : : return FLOW_DISSECT_RET_OUT_GOOD;
508 : : }
509 : :
510 : : static enum flow_dissect_ret
511 : 0 : __skb_flow_dissect_arp(const struct sk_buff *skb,
512 : : struct flow_dissector *flow_dissector,
513 : : void *target_container, void *data, int nhoff, int hlen)
514 : : {
515 : 0 : struct flow_dissector_key_arp *key_arp;
516 : 0 : struct {
517 : : unsigned char ar_sha[ETH_ALEN];
518 : : unsigned char ar_sip[4];
519 : : unsigned char ar_tha[ETH_ALEN];
520 : : unsigned char ar_tip[4];
521 : : } *arp_eth, _arp_eth;
522 : 0 : const struct arphdr *arp;
523 : 0 : struct arphdr _arp;
524 : :
525 [ # # ]: 0 : if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ARP))
526 : : return FLOW_DISSECT_RET_OUT_GOOD;
527 : :
528 [ # # ]: 0 : arp = __skb_header_pointer(skb, nhoff, sizeof(_arp), data,
529 : : hlen, &_arp);
530 [ # # ]: 0 : if (!arp)
531 : 0 : return FLOW_DISSECT_RET_OUT_BAD;
532 : :
533 [ # # ]: 0 : if (arp->ar_hrd != htons(ARPHRD_ETHER) ||
534 [ # # ]: 0 : arp->ar_pro != htons(ETH_P_IP) ||
535 [ # # ]: 0 : arp->ar_hln != ETH_ALEN ||
536 : 0 : arp->ar_pln != 4 ||
537 [ # # ]: 0 : (arp->ar_op != htons(ARPOP_REPLY) &&
538 : : arp->ar_op != htons(ARPOP_REQUEST)))
539 : : return FLOW_DISSECT_RET_OUT_BAD;
540 : :
541 [ # # ]: 0 : arp_eth = __skb_header_pointer(skb, nhoff + sizeof(_arp),
542 : : sizeof(_arp_eth), data,
543 : : hlen, &_arp_eth);
544 [ # # ]: 0 : if (!arp_eth)
545 : 0 : return FLOW_DISSECT_RET_OUT_BAD;
546 : :
547 : 0 : key_arp = skb_flow_dissector_target(flow_dissector,
548 : : FLOW_DISSECTOR_KEY_ARP,
549 : : target_container);
550 : :
551 : 0 : memcpy(&key_arp->sip, arp_eth->ar_sip, sizeof(key_arp->sip));
552 : 0 : memcpy(&key_arp->tip, arp_eth->ar_tip, sizeof(key_arp->tip));
553 : :
554 : : /* Only store the lower byte of the opcode;
555 : : * this covers ARPOP_REPLY and ARPOP_REQUEST.
556 : : */
557 : 0 : key_arp->op = ntohs(arp->ar_op) & 0xff;
558 : :
559 : 0 : ether_addr_copy(key_arp->sha, arp_eth->ar_sha);
560 : 0 : ether_addr_copy(key_arp->tha, arp_eth->ar_tha);
561 : :
562 : 0 : return FLOW_DISSECT_RET_OUT_GOOD;
563 : : }
564 : :
565 : : static enum flow_dissect_ret
566 : : __skb_flow_dissect_gre(const struct sk_buff *skb,
567 : : struct flow_dissector_key_control *key_control,
568 : : struct flow_dissector *flow_dissector,
569 : : void *target_container, void *data,
570 : : __be16 *p_proto, int *p_nhoff, int *p_hlen,
571 : : unsigned int flags)
572 : : {
573 : : struct flow_dissector_key_keyid *key_keyid;
574 : : struct gre_base_hdr *hdr, _hdr;
575 : : int offset = 0;
576 : : u16 gre_ver;
577 : :
578 : : hdr = __skb_header_pointer(skb, *p_nhoff, sizeof(_hdr),
579 : : data, *p_hlen, &_hdr);
580 : : if (!hdr)
581 : : return FLOW_DISSECT_RET_OUT_BAD;
582 : :
583 : : /* Only look inside GRE without routing */
584 : : if (hdr->flags & GRE_ROUTING)
585 : : return FLOW_DISSECT_RET_OUT_GOOD;
586 : :
587 : : /* Only look inside GRE for version 0 and 1 */
588 : : gre_ver = ntohs(hdr->flags & GRE_VERSION);
589 : : if (gre_ver > 1)
590 : : return FLOW_DISSECT_RET_OUT_GOOD;
591 : :
592 : : *p_proto = hdr->protocol;
593 : : if (gre_ver) {
594 : : /* Version1 must be PPTP, and check the flags */
595 : : if (!(*p_proto == GRE_PROTO_PPP && (hdr->flags & GRE_KEY)))
596 : : return FLOW_DISSECT_RET_OUT_GOOD;
597 : : }
598 : :
599 : : offset += sizeof(struct gre_base_hdr);
600 : :
601 : : if (hdr->flags & GRE_CSUM)
602 : : offset += sizeof_field(struct gre_full_hdr, csum) +
603 : : sizeof_field(struct gre_full_hdr, reserved1);
604 : :
605 : : if (hdr->flags & GRE_KEY) {
606 : : const __be32 *keyid;
607 : : __be32 _keyid;
608 : :
609 : : keyid = __skb_header_pointer(skb, *p_nhoff + offset,
610 : : sizeof(_keyid),
611 : : data, *p_hlen, &_keyid);
612 : : if (!keyid)
613 : : return FLOW_DISSECT_RET_OUT_BAD;
614 : :
615 : : if (dissector_uses_key(flow_dissector,
616 : : FLOW_DISSECTOR_KEY_GRE_KEYID)) {
617 : : key_keyid = skb_flow_dissector_target(flow_dissector,
618 : : FLOW_DISSECTOR_KEY_GRE_KEYID,
619 : : target_container);
620 : : if (gre_ver == 0)
621 : : key_keyid->keyid = *keyid;
622 : : else
623 : : key_keyid->keyid = *keyid & GRE_PPTP_KEY_MASK;
624 : : }
625 : : offset += sizeof_field(struct gre_full_hdr, key);
626 : : }
627 : :
628 : : if (hdr->flags & GRE_SEQ)
629 : : offset += sizeof_field(struct pptp_gre_header, seq);
630 : :
631 : : if (gre_ver == 0) {
632 : : if (*p_proto == htons(ETH_P_TEB)) {
633 : : const struct ethhdr *eth;
634 : : struct ethhdr _eth;
635 : :
636 : : eth = __skb_header_pointer(skb, *p_nhoff + offset,
637 : : sizeof(_eth),
638 : : data, *p_hlen, &_eth);
639 : : if (!eth)
640 : : return FLOW_DISSECT_RET_OUT_BAD;
641 : : *p_proto = eth->h_proto;
642 : : offset += sizeof(*eth);
643 : :
644 : : /* Cap headers that we access via pointers at the
645 : : * end of the Ethernet header as our maximum alignment
646 : : * at that point is only 2 bytes.
647 : : */
648 : : if (NET_IP_ALIGN)
649 : : *p_hlen = *p_nhoff + offset;
650 : : }
651 : : } else { /* version 1, must be PPTP */
652 : : u8 _ppp_hdr[PPP_HDRLEN];
653 : : u8 *ppp_hdr;
654 : :
655 : : if (hdr->flags & GRE_ACK)
656 : : offset += sizeof_field(struct pptp_gre_header, ack);
657 : :
658 : : ppp_hdr = __skb_header_pointer(skb, *p_nhoff + offset,
659 : : sizeof(_ppp_hdr),
660 : : data, *p_hlen, _ppp_hdr);
661 : : if (!ppp_hdr)
662 : : return FLOW_DISSECT_RET_OUT_BAD;
663 : :
664 : : switch (PPP_PROTOCOL(ppp_hdr)) {
665 : : case PPP_IP:
666 : : *p_proto = htons(ETH_P_IP);
667 : : break;
668 : : case PPP_IPV6:
669 : : *p_proto = htons(ETH_P_IPV6);
670 : : break;
671 : : default:
672 : : /* Could probably catch some more like MPLS */
673 : : break;
674 : : }
675 : :
676 : : offset += PPP_HDRLEN;
677 : : }
678 : :
679 : : *p_nhoff += offset;
680 : : key_control->flags |= FLOW_DIS_ENCAPSULATION;
681 : : if (flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP)
682 : : return FLOW_DISSECT_RET_OUT_GOOD;
683 : :
684 : : return FLOW_DISSECT_RET_PROTO_AGAIN;
685 : : }
686 : :
687 : : /**
688 : : * __skb_flow_dissect_batadv() - dissect batman-adv header
689 : : * @skb: sk_buff to with the batman-adv header
690 : : * @key_control: flow dissectors control key
691 : : * @data: raw buffer pointer to the packet, if NULL use skb->data
692 : : * @p_proto: pointer used to update the protocol to process next
693 : : * @p_nhoff: pointer used to update inner network header offset
694 : : * @hlen: packet header length
695 : : * @flags: any combination of FLOW_DISSECTOR_F_*
696 : : *
697 : : * ETH_P_BATMAN packets are tried to be dissected. Only
698 : : * &struct batadv_unicast packets are actually processed because they contain an
699 : : * inner ethernet header and are usually followed by actual network header. This
700 : : * allows the flow dissector to continue processing the packet.
701 : : *
702 : : * Return: FLOW_DISSECT_RET_PROTO_AGAIN when &struct batadv_unicast was found,
703 : : * FLOW_DISSECT_RET_OUT_GOOD when dissector should stop after encapsulation,
704 : : * otherwise FLOW_DISSECT_RET_OUT_BAD
705 : : */
706 : : static enum flow_dissect_ret
707 : : __skb_flow_dissect_batadv(const struct sk_buff *skb,
708 : : struct flow_dissector_key_control *key_control,
709 : : void *data, __be16 *p_proto, int *p_nhoff, int hlen,
710 : : unsigned int flags)
711 : : {
712 : : struct {
713 : : struct batadv_unicast_packet batadv_unicast;
714 : : struct ethhdr eth;
715 : : } *hdr, _hdr;
716 : :
717 : : hdr = __skb_header_pointer(skb, *p_nhoff, sizeof(_hdr), data, hlen,
718 : : &_hdr);
719 : : if (!hdr)
720 : : return FLOW_DISSECT_RET_OUT_BAD;
721 : :
722 : : if (hdr->batadv_unicast.version != BATADV_COMPAT_VERSION)
723 : : return FLOW_DISSECT_RET_OUT_BAD;
724 : :
725 : : if (hdr->batadv_unicast.packet_type != BATADV_UNICAST)
726 : : return FLOW_DISSECT_RET_OUT_BAD;
727 : :
728 : : *p_proto = hdr->eth.h_proto;
729 : : *p_nhoff += sizeof(*hdr);
730 : :
731 : : key_control->flags |= FLOW_DIS_ENCAPSULATION;
732 : : if (flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP)
733 : : return FLOW_DISSECT_RET_OUT_GOOD;
734 : :
735 : : return FLOW_DISSECT_RET_PROTO_AGAIN;
736 : : }
737 : :
738 : : static void
739 : 0 : __skb_flow_dissect_tcp(const struct sk_buff *skb,
740 : : struct flow_dissector *flow_dissector,
741 : : void *target_container, void *data, int thoff, int hlen)
742 : : {
743 : 0 : struct flow_dissector_key_tcp *key_tcp;
744 : 0 : struct tcphdr *th, _th;
745 : :
746 [ # # ]: 0 : if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_TCP))
747 : 0 : return;
748 : :
749 [ # # ]: 0 : th = __skb_header_pointer(skb, thoff, sizeof(_th), data, hlen, &_th);
750 [ # # ]: 0 : if (!th)
751 : 0 : return;
752 : :
753 [ # # ]: 0 : if (unlikely(__tcp_hdrlen(th) < sizeof(_th)))
754 : : return;
755 : :
756 : 0 : key_tcp = skb_flow_dissector_target(flow_dissector,
757 : : FLOW_DISSECTOR_KEY_TCP,
758 : : target_container);
759 : 0 : key_tcp->flags = (*(__be16 *) &tcp_flag_word(th) & htons(0x0FFF));
760 : : }
761 : :
762 : : static void
763 : 0 : __skb_flow_dissect_ports(const struct sk_buff *skb,
764 : : struct flow_dissector *flow_dissector,
765 : : void *target_container, void *data, int nhoff,
766 : : u8 ip_proto, int hlen)
767 : : {
768 : 0 : enum flow_dissector_key_id dissector_ports = FLOW_DISSECTOR_KEY_MAX;
769 : 0 : struct flow_dissector_key_ports *key_ports;
770 : :
771 [ # # ]: 0 : if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_PORTS))
772 : : dissector_ports = FLOW_DISSECTOR_KEY_PORTS;
773 [ # # ]: 0 : else if (dissector_uses_key(flow_dissector,
774 : : FLOW_DISSECTOR_KEY_PORTS_RANGE))
775 : : dissector_ports = FLOW_DISSECTOR_KEY_PORTS_RANGE;
776 : :
777 : : if (dissector_ports == FLOW_DISSECTOR_KEY_MAX)
778 : : return;
779 : :
780 : 0 : key_ports = skb_flow_dissector_target(flow_dissector,
781 : : dissector_ports,
782 : : target_container);
783 : 0 : key_ports->ports = __skb_flow_get_ports(skb, nhoff, ip_proto,
784 : : data, hlen);
785 : : }
786 : :
787 : : static void
788 : 0 : __skb_flow_dissect_ipv4(const struct sk_buff *skb,
789 : : struct flow_dissector *flow_dissector,
790 : : void *target_container, void *data, const struct iphdr *iph)
791 : : {
792 : 0 : struct flow_dissector_key_ip *key_ip;
793 : :
794 : 0 : if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_IP))
795 : : return;
796 : :
797 : 0 : key_ip = skb_flow_dissector_target(flow_dissector,
798 : : FLOW_DISSECTOR_KEY_IP,
799 : : target_container);
800 : 0 : key_ip->tos = iph->tos;
801 : 0 : key_ip->ttl = iph->ttl;
802 : : }
803 : :
804 : : static void
805 : 0 : __skb_flow_dissect_ipv6(const struct sk_buff *skb,
806 : : struct flow_dissector *flow_dissector,
807 : : void *target_container, void *data, const struct ipv6hdr *iph)
808 : : {
809 : 0 : struct flow_dissector_key_ip *key_ip;
810 : :
811 : 0 : if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_IP))
812 : : return;
813 : :
814 : 0 : key_ip = skb_flow_dissector_target(flow_dissector,
815 : : FLOW_DISSECTOR_KEY_IP,
816 : : target_container);
817 : 0 : key_ip->tos = ipv6_get_dsfield(iph);
818 : 0 : key_ip->ttl = iph->hop_limit;
819 : : }
820 : :
821 : : /* Maximum number of protocol headers that can be parsed in
822 : : * __skb_flow_dissect
823 : : */
824 : : #define MAX_FLOW_DISSECT_HDRS 15
825 : :
826 : 0 : static bool skb_flow_dissect_allowed(int *num_hdrs)
827 : : {
828 : 0 : ++*num_hdrs;
829 : :
830 : 0 : return (*num_hdrs <= MAX_FLOW_DISSECT_HDRS);
831 : : }
832 : :
833 : 0 : static void __skb_flow_bpf_to_target(const struct bpf_flow_keys *flow_keys,
834 : : struct flow_dissector *flow_dissector,
835 : : void *target_container)
836 : : {
837 : 0 : struct flow_dissector_key_ports *key_ports = NULL;
838 : 0 : struct flow_dissector_key_control *key_control;
839 : 0 : struct flow_dissector_key_basic *key_basic;
840 : 0 : struct flow_dissector_key_addrs *key_addrs;
841 : 0 : struct flow_dissector_key_tags *key_tags;
842 : :
843 [ # # ]: 0 : key_control = skb_flow_dissector_target(flow_dissector,
844 : : FLOW_DISSECTOR_KEY_CONTROL,
845 : : target_container);
846 : 0 : key_control->thoff = flow_keys->thoff;
847 [ # # ]: 0 : if (flow_keys->is_frag)
848 : 0 : key_control->flags |= FLOW_DIS_IS_FRAGMENT;
849 [ # # ]: 0 : if (flow_keys->is_first_frag)
850 : 0 : key_control->flags |= FLOW_DIS_FIRST_FRAG;
851 [ # # ]: 0 : if (flow_keys->is_encap)
852 : 0 : key_control->flags |= FLOW_DIS_ENCAPSULATION;
853 : :
854 [ # # ]: 0 : key_basic = skb_flow_dissector_target(flow_dissector,
855 : : FLOW_DISSECTOR_KEY_BASIC,
856 : : target_container);
857 : 0 : key_basic->n_proto = flow_keys->n_proto;
858 : 0 : key_basic->ip_proto = flow_keys->ip_proto;
859 : :
860 [ # # # # ]: 0 : if (flow_keys->addr_proto == ETH_P_IP &&
861 [ # # ]: 0 : dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_IPV4_ADDRS)) {
862 : 0 : key_addrs = skb_flow_dissector_target(flow_dissector,
863 : : FLOW_DISSECTOR_KEY_IPV4_ADDRS,
864 : : target_container);
865 : 0 : key_addrs->v4addrs.src = flow_keys->ipv4_src;
866 : 0 : key_addrs->v4addrs.dst = flow_keys->ipv4_dst;
867 : 0 : key_control->addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
868 [ # # # # ]: 0 : } else if (flow_keys->addr_proto == ETH_P_IPV6 &&
869 [ # # ]: 0 : dissector_uses_key(flow_dissector,
870 : : FLOW_DISSECTOR_KEY_IPV6_ADDRS)) {
871 : 0 : key_addrs = skb_flow_dissector_target(flow_dissector,
872 : : FLOW_DISSECTOR_KEY_IPV6_ADDRS,
873 : : target_container);
874 : 0 : memcpy(&key_addrs->v6addrs, &flow_keys->ipv6_src,
875 : : sizeof(key_addrs->v6addrs));
876 : 0 : key_control->addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
877 : : }
878 : :
879 [ # # ]: 0 : if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_PORTS))
880 : 0 : key_ports = skb_flow_dissector_target(flow_dissector,
881 : : FLOW_DISSECTOR_KEY_PORTS,
882 : : target_container);
883 [ # # ]: 0 : else if (dissector_uses_key(flow_dissector,
884 : : FLOW_DISSECTOR_KEY_PORTS_RANGE))
885 : 0 : key_ports = skb_flow_dissector_target(flow_dissector,
886 : : FLOW_DISSECTOR_KEY_PORTS_RANGE,
887 : : target_container);
888 : :
889 [ # # ]: 0 : if (key_ports) {
890 : 0 : key_ports->src = flow_keys->sport;
891 : 0 : key_ports->dst = flow_keys->dport;
892 : : }
893 : :
894 [ # # ]: 0 : if (dissector_uses_key(flow_dissector,
895 : : FLOW_DISSECTOR_KEY_FLOW_LABEL)) {
896 : 0 : key_tags = skb_flow_dissector_target(flow_dissector,
897 : : FLOW_DISSECTOR_KEY_FLOW_LABEL,
898 : : target_container);
899 : 0 : key_tags->flow_label = ntohl(flow_keys->flow_label);
900 : : }
901 : 0 : }
902 : :
903 : 0 : bool bpf_flow_dissect(struct bpf_prog *prog, struct bpf_flow_dissector *ctx,
904 : : __be16 proto, int nhoff, int hlen, unsigned int flags)
905 : : {
906 : 0 : struct bpf_flow_keys *flow_keys = ctx->flow_keys;
907 : 0 : u32 result;
908 : :
909 : : /* Pass parameters to the BPF program */
910 : 0 : memset(flow_keys, 0, sizeof(*flow_keys));
911 : 0 : flow_keys->n_proto = proto;
912 : 0 : flow_keys->nhoff = nhoff;
913 : 0 : flow_keys->thoff = flow_keys->nhoff;
914 : :
915 : 0 : BUILD_BUG_ON((int)BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG !=
916 : : (int)FLOW_DISSECTOR_F_PARSE_1ST_FRAG);
917 : 0 : BUILD_BUG_ON((int)BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL !=
918 : : (int)FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL);
919 : 0 : BUILD_BUG_ON((int)BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP !=
920 : : (int)FLOW_DISSECTOR_F_STOP_AT_ENCAP);
921 : 0 : flow_keys->flags = flags;
922 : :
923 : 0 : preempt_disable();
924 [ # # # # ]: 0 : result = BPF_PROG_RUN(prog, ctx);
925 : 0 : preempt_enable();
926 : :
927 : 0 : flow_keys->nhoff = clamp_t(u16, flow_keys->nhoff, nhoff, hlen);
928 : 0 : flow_keys->thoff = clamp_t(u16, flow_keys->thoff,
929 : : flow_keys->nhoff, hlen);
930 : :
931 : 0 : return result == BPF_OK;
932 : : }
933 : :
934 : : /**
935 : : * __skb_flow_dissect - extract the flow_keys struct and return it
936 : : * @net: associated network namespace, derived from @skb if NULL
937 : : * @skb: sk_buff to extract the flow from, can be NULL if the rest are specified
938 : : * @flow_dissector: list of keys to dissect
939 : : * @target_container: target structure to put dissected values into
940 : : * @data: raw buffer pointer to the packet, if NULL use skb->data
941 : : * @proto: protocol for which to get the flow, if @data is NULL use skb->protocol
942 : : * @nhoff: network header offset, if @data is NULL use skb_network_offset(skb)
943 : : * @hlen: packet header length, if @data is NULL use skb_headlen(skb)
944 : : * @flags: flags that control the dissection process, e.g.
945 : : * FLOW_DISSECTOR_F_STOP_AT_ENCAP.
946 : : *
947 : : * The function will try to retrieve individual keys into target specified
948 : : * by flow_dissector from either the skbuff or a raw buffer specified by the
949 : : * rest parameters.
950 : : *
951 : : * Caller must take care of zeroing target container memory.
952 : : */
953 : 0 : bool __skb_flow_dissect(const struct net *net,
954 : : const struct sk_buff *skb,
955 : : struct flow_dissector *flow_dissector,
956 : : void *target_container,
957 : : void *data, __be16 proto, int nhoff, int hlen,
958 : : unsigned int flags)
959 : : {
960 : 0 : struct flow_dissector_key_control *key_control;
961 : 0 : struct flow_dissector_key_basic *key_basic;
962 : 0 : struct flow_dissector_key_addrs *key_addrs;
963 : 0 : struct flow_dissector_key_tags *key_tags;
964 : 0 : struct flow_dissector_key_vlan *key_vlan;
965 : 0 : struct bpf_prog *attached = NULL;
966 : 0 : enum flow_dissect_ret fdret;
967 : 0 : enum flow_dissector_key_id dissector_vlan = FLOW_DISSECTOR_KEY_MAX;
968 : 0 : int num_hdrs = 0;
969 : 0 : u8 ip_proto = 0;
970 : 0 : bool ret;
971 : :
972 [ # # ]: 0 : if (!data) {
973 : 0 : data = skb->data;
974 [ # # ]: 0 : proto = skb_vlan_tag_present(skb) ?
975 : : skb->vlan_proto : skb->protocol;
976 : 0 : nhoff = skb_network_offset(skb);
977 : 0 : hlen = skb_headlen(skb);
978 : : #if IS_ENABLED(CONFIG_NET_DSA)
979 : : if (unlikely(skb->dev && netdev_uses_dsa(skb->dev) &&
980 : : proto == htons(ETH_P_XDSA))) {
981 : : const struct dsa_device_ops *ops;
982 : : int offset = 0;
983 : :
984 : : ops = skb->dev->dsa_ptr->tag_ops;
985 : : if (ops->flow_dissect &&
986 : : !ops->flow_dissect(skb, &proto, &offset)) {
987 : : hlen -= offset;
988 : : nhoff += offset;
989 : : }
990 : : }
991 : : #endif
992 : : }
993 : :
994 : : /* It is ensured by skb_flow_dissector_init() that control key will
995 : : * be always present.
996 : : */
997 [ # # ]: 0 : key_control = skb_flow_dissector_target(flow_dissector,
998 : : FLOW_DISSECTOR_KEY_CONTROL,
999 : : target_container);
1000 : :
1001 : : /* It is ensured by skb_flow_dissector_init() that basic key will
1002 : : * be always present.
1003 : : */
1004 : 0 : key_basic = skb_flow_dissector_target(flow_dissector,
1005 : : FLOW_DISSECTOR_KEY_BASIC,
1006 : : target_container);
1007 : :
1008 [ # # ]: 0 : if (skb) {
1009 [ # # ]: 0 : if (!net) {
1010 [ # # ]: 0 : if (skb->dev)
1011 : 0 : net = dev_net(skb->dev);
1012 [ # # ]: 0 : else if (skb->sk)
1013 : 0 : net = sock_net(skb->sk);
1014 : : }
1015 : : }
1016 : :
1017 [ # # ]: 0 : WARN_ON_ONCE(!net);
1018 [ # # ]: 0 : if (net) {
1019 : 0 : rcu_read_lock();
1020 [ # # ]: 0 : attached = rcu_dereference(init_net.flow_dissector_prog);
1021 : :
1022 [ # # ]: 0 : if (!attached)
1023 : 0 : attached = rcu_dereference(net->flow_dissector_prog);
1024 : :
1025 [ # # ]: 0 : if (attached) {
1026 : 0 : struct bpf_flow_keys flow_keys;
1027 : 0 : struct bpf_flow_dissector ctx = {
1028 : : .flow_keys = &flow_keys,
1029 : : .data = data,
1030 : 0 : .data_end = data + hlen,
1031 : : };
1032 : 0 : __be16 n_proto = proto;
1033 : :
1034 [ # # ]: 0 : if (skb) {
1035 : 0 : ctx.skb = skb;
1036 : : /* we can't use 'proto' in the skb case
1037 : : * because it might be set to skb->vlan_proto
1038 : : * which has been pulled from the data
1039 : : */
1040 : 0 : n_proto = skb->protocol;
1041 : : }
1042 : :
1043 : 0 : ret = bpf_flow_dissect(attached, &ctx, n_proto, nhoff,
1044 : : hlen, flags);
1045 : 0 : __skb_flow_bpf_to_target(&flow_keys, flow_dissector,
1046 : : target_container);
1047 : 0 : rcu_read_unlock();
1048 : 0 : return ret;
1049 : : }
1050 : 0 : rcu_read_unlock();
1051 : : }
1052 : :
1053 [ # # ]: 0 : if (dissector_uses_key(flow_dissector,
1054 : : FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
1055 : 0 : struct ethhdr *eth = eth_hdr(skb);
1056 : 0 : struct flow_dissector_key_eth_addrs *key_eth_addrs;
1057 : :
1058 : 0 : key_eth_addrs = skb_flow_dissector_target(flow_dissector,
1059 : : FLOW_DISSECTOR_KEY_ETH_ADDRS,
1060 : : target_container);
1061 : 0 : memcpy(key_eth_addrs, ð->h_dest, sizeof(*key_eth_addrs));
1062 : : }
1063 : :
1064 : 0 : proto_again:
1065 : 0 : fdret = FLOW_DISSECT_RET_CONTINUE;
1066 : :
1067 [ # # # # : 0 : switch (proto) {
# # # # #
# ]
1068 : 0 : case htons(ETH_P_IP): {
1069 : 0 : const struct iphdr *iph;
1070 : 0 : struct iphdr _iph;
1071 : :
1072 [ # # ]: 0 : iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph);
1073 [ # # # # ]: 0 : if (!iph || iph->ihl < 5) {
1074 : : fdret = FLOW_DISSECT_RET_OUT_BAD;
1075 : : break;
1076 : : }
1077 : :
1078 : 0 : nhoff += iph->ihl * 4;
1079 : :
1080 : 0 : ip_proto = iph->protocol;
1081 : :
1082 [ # # ]: 0 : if (dissector_uses_key(flow_dissector,
1083 : : FLOW_DISSECTOR_KEY_IPV4_ADDRS)) {
1084 : 0 : key_addrs = skb_flow_dissector_target(flow_dissector,
1085 : : FLOW_DISSECTOR_KEY_IPV4_ADDRS,
1086 : : target_container);
1087 : :
1088 : 0 : memcpy(&key_addrs->v4addrs, &iph->saddr,
1089 : : sizeof(key_addrs->v4addrs));
1090 : 0 : key_control->addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
1091 : : }
1092 : :
1093 [ # # ]: 0 : if (ip_is_fragment(iph)) {
1094 : 0 : key_control->flags |= FLOW_DIS_IS_FRAGMENT;
1095 : :
1096 [ # # ]: 0 : if (iph->frag_off & htons(IP_OFFSET)) {
1097 : : fdret = FLOW_DISSECT_RET_OUT_GOOD;
1098 : : break;
1099 : : } else {
1100 : 0 : key_control->flags |= FLOW_DIS_FIRST_FRAG;
1101 [ # # ]: 0 : if (!(flags &
1102 : : FLOW_DISSECTOR_F_PARSE_1ST_FRAG)) {
1103 : : fdret = FLOW_DISSECT_RET_OUT_GOOD;
1104 : : break;
1105 : : }
1106 : : }
1107 : : }
1108 : :
1109 [ # # ]: 0 : __skb_flow_dissect_ipv4(skb, flow_dissector,
1110 : : target_container, data, iph);
1111 : :
1112 : : break;
1113 : : }
1114 : 0 : case htons(ETH_P_IPV6): {
1115 : 0 : const struct ipv6hdr *iph;
1116 : 0 : struct ipv6hdr _iph;
1117 : :
1118 [ # # ]: 0 : iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph);
1119 [ # # ]: 0 : if (!iph) {
1120 : : fdret = FLOW_DISSECT_RET_OUT_BAD;
1121 : : break;
1122 : : }
1123 : :
1124 : 0 : ip_proto = iph->nexthdr;
1125 : 0 : nhoff += sizeof(struct ipv6hdr);
1126 : :
1127 [ # # ]: 0 : if (dissector_uses_key(flow_dissector,
1128 : : FLOW_DISSECTOR_KEY_IPV6_ADDRS)) {
1129 : 0 : key_addrs = skb_flow_dissector_target(flow_dissector,
1130 : : FLOW_DISSECTOR_KEY_IPV6_ADDRS,
1131 : : target_container);
1132 : :
1133 : 0 : memcpy(&key_addrs->v6addrs, &iph->saddr,
1134 : : sizeof(key_addrs->v6addrs));
1135 : 0 : key_control->addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
1136 : : }
1137 : :
1138 [ # # ]: 0 : if ((dissector_uses_key(flow_dissector,
1139 [ # # ]: 0 : FLOW_DISSECTOR_KEY_FLOW_LABEL) ||
1140 [ # # ]: 0 : (flags & FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL)) &&
1141 : : ip6_flowlabel(iph)) {
1142 [ # # ]: 0 : __be32 flow_label = ip6_flowlabel(iph);
1143 : :
1144 [ # # ]: 0 : if (dissector_uses_key(flow_dissector,
1145 : : FLOW_DISSECTOR_KEY_FLOW_LABEL)) {
1146 : 0 : key_tags = skb_flow_dissector_target(flow_dissector,
1147 : : FLOW_DISSECTOR_KEY_FLOW_LABEL,
1148 : : target_container);
1149 : 0 : key_tags->flow_label = ntohl(flow_label);
1150 : : }
1151 [ # # ]: 0 : if (flags & FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL) {
1152 : : fdret = FLOW_DISSECT_RET_OUT_GOOD;
1153 : : break;
1154 : : }
1155 : : }
1156 : :
1157 [ # # ]: 0 : __skb_flow_dissect_ipv6(skb, flow_dissector,
1158 : : target_container, data, iph);
1159 : :
1160 : : break;
1161 : : }
1162 : 0 : case htons(ETH_P_8021AD):
1163 : : case htons(ETH_P_8021Q): {
1164 : 0 : const struct vlan_hdr *vlan = NULL;
1165 : 0 : struct vlan_hdr _vlan;
1166 : 0 : __be16 saved_vlan_tpid = proto;
1167 : :
1168 [ # # ]: 0 : if (dissector_vlan == FLOW_DISSECTOR_KEY_MAX &&
1169 [ # # ]: 0 : skb && skb_vlan_tag_present(skb)) {
1170 : 0 : proto = skb->protocol;
1171 : : } else {
1172 [ # # ]: 0 : vlan = __skb_header_pointer(skb, nhoff, sizeof(_vlan),
1173 : : data, hlen, &_vlan);
1174 [ # # ]: 0 : if (!vlan) {
1175 : : fdret = FLOW_DISSECT_RET_OUT_BAD;
1176 : : break;
1177 : : }
1178 : :
1179 : 0 : proto = vlan->h_vlan_encapsulated_proto;
1180 : 0 : nhoff += sizeof(*vlan);
1181 : : }
1182 : :
1183 [ # # ]: 0 : if (dissector_vlan == FLOW_DISSECTOR_KEY_MAX) {
1184 : : dissector_vlan = FLOW_DISSECTOR_KEY_VLAN;
1185 [ # # ]: 0 : } else if (dissector_vlan == FLOW_DISSECTOR_KEY_VLAN) {
1186 : : dissector_vlan = FLOW_DISSECTOR_KEY_CVLAN;
1187 : : } else {
1188 : : fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
1189 : : break;
1190 : : }
1191 : :
1192 [ # # ]: 0 : if (dissector_uses_key(flow_dissector, dissector_vlan)) {
1193 [ # # ]: 0 : key_vlan = skb_flow_dissector_target(flow_dissector,
1194 : : dissector_vlan,
1195 : : target_container);
1196 : :
1197 [ # # ]: 0 : if (!vlan) {
1198 : 0 : key_vlan->vlan_id = skb_vlan_tag_get_id(skb);
1199 : 0 : key_vlan->vlan_priority = skb_vlan_tag_get_prio(skb);
1200 : : } else {
1201 : 0 : key_vlan->vlan_id = ntohs(vlan->h_vlan_TCI) &
1202 : : VLAN_VID_MASK;
1203 : 0 : key_vlan->vlan_priority =
1204 : 0 : (ntohs(vlan->h_vlan_TCI) &
1205 : 0 : VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
1206 : : }
1207 : 0 : key_vlan->vlan_tpid = saved_vlan_tpid;
1208 : : }
1209 : :
1210 : : fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
1211 : : break;
1212 : : }
1213 : 0 : case htons(ETH_P_PPP_SES): {
1214 : 0 : struct {
1215 : : struct pppoe_hdr hdr;
1216 : : __be16 proto;
1217 : : } *hdr, _hdr;
1218 [ # # ]: 0 : hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
1219 [ # # ]: 0 : if (!hdr) {
1220 : : fdret = FLOW_DISSECT_RET_OUT_BAD;
1221 : : break;
1222 : : }
1223 : :
1224 : 0 : proto = hdr->proto;
1225 : 0 : nhoff += PPPOE_SES_HLEN;
1226 [ # # # ]: 0 : switch (proto) {
1227 : 0 : case htons(PPP_IP):
1228 : 0 : proto = htons(ETH_P_IP);
1229 : 0 : fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
1230 : 0 : break;
1231 : 0 : case htons(PPP_IPV6):
1232 : 0 : proto = htons(ETH_P_IPV6);
1233 : 0 : fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
1234 : 0 : break;
1235 : : default:
1236 : : fdret = FLOW_DISSECT_RET_OUT_BAD;
1237 : : break;
1238 : : }
1239 : : break;
1240 : : }
1241 : 0 : case htons(ETH_P_TIPC): {
1242 : 0 : struct tipc_basic_hdr *hdr, _hdr;
1243 : :
1244 [ # # ]: 0 : hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr),
1245 : : data, hlen, &_hdr);
1246 [ # # ]: 0 : if (!hdr) {
1247 : : fdret = FLOW_DISSECT_RET_OUT_BAD;
1248 : : break;
1249 : : }
1250 : :
1251 [ # # ]: 0 : if (dissector_uses_key(flow_dissector,
1252 : : FLOW_DISSECTOR_KEY_TIPC)) {
1253 [ # # ]: 0 : key_addrs = skb_flow_dissector_target(flow_dissector,
1254 : : FLOW_DISSECTOR_KEY_TIPC,
1255 : : target_container);
1256 [ # # ]: 0 : key_addrs->tipckey.key = tipc_hdr_rps_key(hdr);
1257 : 0 : key_control->addr_type = FLOW_DISSECTOR_KEY_TIPC;
1258 : : }
1259 : : fdret = FLOW_DISSECT_RET_OUT_GOOD;
1260 : : break;
1261 : : }
1262 : :
1263 : 0 : case htons(ETH_P_MPLS_UC):
1264 : : case htons(ETH_P_MPLS_MC):
1265 : 0 : fdret = __skb_flow_dissect_mpls(skb, flow_dissector,
1266 : : target_container, data,
1267 : : nhoff, hlen);
1268 : 0 : break;
1269 : 0 : case htons(ETH_P_FCOE):
1270 [ # # ]: 0 : if ((hlen - nhoff) < FCOE_HEADER_LEN) {
1271 : : fdret = FLOW_DISSECT_RET_OUT_BAD;
1272 : : break;
1273 : : }
1274 : :
1275 : 0 : nhoff += FCOE_HEADER_LEN;
1276 : 0 : fdret = FLOW_DISSECT_RET_OUT_GOOD;
1277 : 0 : break;
1278 : :
1279 : 0 : case htons(ETH_P_ARP):
1280 : : case htons(ETH_P_RARP):
1281 : 0 : fdret = __skb_flow_dissect_arp(skb, flow_dissector,
1282 : : target_container, data,
1283 : : nhoff, hlen);
1284 : 0 : break;
1285 : :
1286 : 0 : case htons(ETH_P_BATMAN):
1287 : 0 : fdret = __skb_flow_dissect_batadv(skb, key_control, data,
1288 : : &proto, &nhoff, hlen, flags);
1289 : 0 : break;
1290 : :
1291 : : default:
1292 : : fdret = FLOW_DISSECT_RET_OUT_BAD;
1293 : : break;
1294 : : }
1295 : :
1296 : : /* Process result of proto processing */
1297 [ # # # # ]: 0 : switch (fdret) {
1298 : 0 : case FLOW_DISSECT_RET_OUT_GOOD:
1299 : 0 : goto out_good;
1300 : : case FLOW_DISSECT_RET_PROTO_AGAIN:
1301 [ # # ]: 0 : if (skb_flow_dissect_allowed(&num_hdrs))
1302 : 0 : goto proto_again;
1303 : 0 : goto out_good;
1304 : : case FLOW_DISSECT_RET_CONTINUE:
1305 : : case FLOW_DISSECT_RET_IPPROTO_AGAIN:
1306 : : break;
1307 : 0 : case FLOW_DISSECT_RET_OUT_BAD:
1308 : : default:
1309 : 0 : goto out_bad;
1310 : : }
1311 : :
1312 : 0 : ip_proto_again:
1313 : 0 : fdret = FLOW_DISSECT_RET_CONTINUE;
1314 : :
1315 [ # # # # : 0 : switch (ip_proto) {
# # # #
# ]
1316 : 0 : case IPPROTO_GRE:
1317 : 0 : fdret = __skb_flow_dissect_gre(skb, key_control, flow_dissector,
1318 : : target_container, data,
1319 : : &proto, &nhoff, &hlen, flags);
1320 : 0 : break;
1321 : :
1322 : 0 : case NEXTHDR_HOP:
1323 : : case NEXTHDR_ROUTING:
1324 : : case NEXTHDR_DEST: {
1325 : 0 : u8 _opthdr[2], *opthdr;
1326 : :
1327 [ # # ]: 0 : if (proto != htons(ETH_P_IPV6))
1328 : : break;
1329 : :
1330 [ # # ]: 0 : opthdr = __skb_header_pointer(skb, nhoff, sizeof(_opthdr),
1331 : : data, hlen, &_opthdr);
1332 [ # # ]: 0 : if (!opthdr) {
1333 : : fdret = FLOW_DISSECT_RET_OUT_BAD;
1334 : : break;
1335 : : }
1336 : :
1337 : 0 : ip_proto = opthdr[0];
1338 : 0 : nhoff += (opthdr[1] + 1) << 3;
1339 : :
1340 : 0 : fdret = FLOW_DISSECT_RET_IPPROTO_AGAIN;
1341 : 0 : break;
1342 : : }
1343 : 0 : case NEXTHDR_FRAGMENT: {
1344 : 0 : struct frag_hdr _fh, *fh;
1345 : :
1346 [ # # ]: 0 : if (proto != htons(ETH_P_IPV6))
1347 : : break;
1348 : :
1349 [ # # ]: 0 : fh = __skb_header_pointer(skb, nhoff, sizeof(_fh),
1350 : : data, hlen, &_fh);
1351 : :
1352 [ # # ]: 0 : if (!fh) {
1353 : : fdret = FLOW_DISSECT_RET_OUT_BAD;
1354 : : break;
1355 : : }
1356 : :
1357 : 0 : key_control->flags |= FLOW_DIS_IS_FRAGMENT;
1358 : :
1359 : 0 : nhoff += sizeof(_fh);
1360 : 0 : ip_proto = fh->nexthdr;
1361 : :
1362 [ # # ]: 0 : if (!(fh->frag_off & htons(IP6_OFFSET))) {
1363 : 0 : key_control->flags |= FLOW_DIS_FIRST_FRAG;
1364 [ # # ]: 0 : if (flags & FLOW_DISSECTOR_F_PARSE_1ST_FRAG) {
1365 : : fdret = FLOW_DISSECT_RET_IPPROTO_AGAIN;
1366 : : break;
1367 : : }
1368 : : }
1369 : :
1370 : : fdret = FLOW_DISSECT_RET_OUT_GOOD;
1371 : : break;
1372 : : }
1373 : 0 : case IPPROTO_IPIP:
1374 : 0 : proto = htons(ETH_P_IP);
1375 : :
1376 : 0 : key_control->flags |= FLOW_DIS_ENCAPSULATION;
1377 [ # # ]: 0 : if (flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP) {
1378 : : fdret = FLOW_DISSECT_RET_OUT_GOOD;
1379 : : break;
1380 : : }
1381 : :
1382 : 0 : fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
1383 : 0 : break;
1384 : :
1385 : 0 : case IPPROTO_IPV6:
1386 : 0 : proto = htons(ETH_P_IPV6);
1387 : :
1388 : 0 : key_control->flags |= FLOW_DIS_ENCAPSULATION;
1389 [ # # ]: 0 : if (flags & FLOW_DISSECTOR_F_STOP_AT_ENCAP) {
1390 : : fdret = FLOW_DISSECT_RET_OUT_GOOD;
1391 : : break;
1392 : : }
1393 : :
1394 : 0 : fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
1395 : 0 : break;
1396 : :
1397 : :
1398 : 0 : case IPPROTO_MPLS:
1399 : 0 : proto = htons(ETH_P_MPLS_UC);
1400 : 0 : fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
1401 : 0 : break;
1402 : :
1403 : 0 : case IPPROTO_TCP:
1404 : 0 : __skb_flow_dissect_tcp(skb, flow_dissector, target_container,
1405 : : data, nhoff, hlen);
1406 : 0 : break;
1407 : :
1408 : 0 : case IPPROTO_ICMP:
1409 : : case IPPROTO_ICMPV6:
1410 [ # # ]: 0 : __skb_flow_dissect_icmp(skb, flow_dissector, target_container,
1411 : : data, nhoff, hlen);
1412 : : break;
1413 : :
1414 : : default:
1415 : : break;
1416 : : }
1417 : :
1418 [ # # ]: 0 : if (!(key_control->flags & FLOW_DIS_IS_FRAGMENT))
1419 : 0 : __skb_flow_dissect_ports(skb, flow_dissector, target_container,
1420 : : data, nhoff, ip_proto, hlen);
1421 : :
1422 : : /* Process result of IP proto processing */
1423 [ # # # # ]: 0 : switch (fdret) {
1424 : : case FLOW_DISSECT_RET_PROTO_AGAIN:
1425 [ # # ]: 0 : if (skb_flow_dissect_allowed(&num_hdrs))
1426 : 0 : goto proto_again;
1427 : : break;
1428 : : case FLOW_DISSECT_RET_IPPROTO_AGAIN:
1429 [ # # ]: 0 : if (skb_flow_dissect_allowed(&num_hdrs))
1430 : 0 : goto ip_proto_again;
1431 : : break;
1432 : : case FLOW_DISSECT_RET_OUT_GOOD:
1433 : : case FLOW_DISSECT_RET_CONTINUE:
1434 : : break;
1435 : 0 : case FLOW_DISSECT_RET_OUT_BAD:
1436 : : default:
1437 : 0 : goto out_bad;
1438 : : }
1439 : :
1440 : : out_good:
1441 : : ret = true;
1442 : :
1443 : 0 : out:
1444 [ # # ]: 0 : key_control->thoff = min_t(u16, nhoff, skb ? skb->len : hlen);
1445 : 0 : key_basic->n_proto = proto;
1446 : 0 : key_basic->ip_proto = ip_proto;
1447 : :
1448 : 0 : return ret;
1449 : :
1450 : 0 : out_bad:
1451 : 0 : ret = false;
1452 : 0 : goto out;
1453 : : }
1454 : : EXPORT_SYMBOL(__skb_flow_dissect);
1455 : :
1456 : : static siphash_key_t hashrnd __read_mostly;
1457 : 0 : static __always_inline void __flow_hash_secret_init(void)
1458 : : {
1459 [ # # # # : 0 : net_get_random_once(&hashrnd, sizeof(hashrnd));
# # # # #
# # # ]
1460 : : }
1461 : :
1462 : 0 : static const void *flow_keys_hash_start(const struct flow_keys *flow)
1463 : : {
1464 : 0 : BUILD_BUG_ON(FLOW_KEYS_HASH_OFFSET % SIPHASH_ALIGNMENT);
1465 : 0 : return &flow->FLOW_KEYS_HASH_START_FIELD;
1466 : : }
1467 : :
1468 : 0 : static inline size_t flow_keys_hash_length(const struct flow_keys *flow)
1469 : : {
1470 : 0 : size_t diff = FLOW_KEYS_HASH_OFFSET + sizeof(flow->addrs);
1471 : :
1472 : 0 : BUILD_BUG_ON((sizeof(*flow) - FLOW_KEYS_HASH_OFFSET) % sizeof(u32));
1473 : :
1474 : 0 : switch (flow->control.addr_type) {
1475 : : case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
1476 : : diff -= sizeof(flow->addrs.v4addrs);
1477 : : break;
1478 : : case FLOW_DISSECTOR_KEY_IPV6_ADDRS:
1479 : : diff -= sizeof(flow->addrs.v6addrs);
1480 : : break;
1481 : : case FLOW_DISSECTOR_KEY_TIPC:
1482 : : diff -= sizeof(flow->addrs.tipckey);
1483 : : break;
1484 : : }
1485 : 0 : return sizeof(*flow) - diff;
1486 : : }
1487 : :
1488 : 0 : __be32 flow_get_u32_src(const struct flow_keys *flow)
1489 : : {
1490 [ # # # # ]: 0 : switch (flow->control.addr_type) {
1491 : 0 : case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
1492 : 0 : return flow->addrs.v4addrs.src;
1493 : 0 : case FLOW_DISSECTOR_KEY_IPV6_ADDRS:
1494 : 0 : return (__force __be32)ipv6_addr_hash(
1495 : : &flow->addrs.v6addrs.src);
1496 : 0 : case FLOW_DISSECTOR_KEY_TIPC:
1497 : 0 : return flow->addrs.tipckey.key;
1498 : : default:
1499 : : return 0;
1500 : : }
1501 : : }
1502 : : EXPORT_SYMBOL(flow_get_u32_src);
1503 : :
1504 : 0 : __be32 flow_get_u32_dst(const struct flow_keys *flow)
1505 : : {
1506 [ # # # ]: 0 : switch (flow->control.addr_type) {
1507 : 0 : case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
1508 : 0 : return flow->addrs.v4addrs.dst;
1509 : 0 : case FLOW_DISSECTOR_KEY_IPV6_ADDRS:
1510 : 0 : return (__force __be32)ipv6_addr_hash(
1511 : : &flow->addrs.v6addrs.dst);
1512 : : default:
1513 : : return 0;
1514 : : }
1515 : : }
1516 : : EXPORT_SYMBOL(flow_get_u32_dst);
1517 : :
1518 : : /* Sort the source and destination IP (and the ports if the IP are the same),
1519 : : * to have consistent hash within the two directions
1520 : : */
1521 : 0 : static inline void __flow_hash_consistentify(struct flow_keys *keys)
1522 : : {
1523 : 0 : int addr_diff, i;
1524 : :
1525 [ # # # ]: 0 : switch (keys->control.addr_type) {
1526 : 0 : case FLOW_DISSECTOR_KEY_IPV4_ADDRS:
1527 : 0 : addr_diff = (__force u32)keys->addrs.v4addrs.dst -
1528 : 0 : (__force u32)keys->addrs.v4addrs.src;
1529 [ # # # # ]: 0 : if ((addr_diff < 0) ||
1530 : 0 : (addr_diff == 0 &&
1531 : 0 : ((__force u16)keys->ports.dst <
1532 [ # # ]: 0 : (__force u16)keys->ports.src))) {
1533 : 0 : swap(keys->addrs.v4addrs.src, keys->addrs.v4addrs.dst);
1534 : 0 : swap(keys->ports.src, keys->ports.dst);
1535 : : }
1536 : : break;
1537 : 0 : case FLOW_DISSECTOR_KEY_IPV6_ADDRS:
1538 : 0 : addr_diff = memcmp(&keys->addrs.v6addrs.dst,
1539 : 0 : &keys->addrs.v6addrs.src,
1540 : : sizeof(keys->addrs.v6addrs.dst));
1541 [ # # # # ]: 0 : if ((addr_diff < 0) ||
1542 : 0 : (addr_diff == 0 &&
1543 : 0 : ((__force u16)keys->ports.dst <
1544 [ # # ]: 0 : (__force u16)keys->ports.src))) {
1545 [ # # ]: 0 : for (i = 0; i < 4; i++)
1546 : 0 : swap(keys->addrs.v6addrs.src.s6_addr32[i],
1547 : : keys->addrs.v6addrs.dst.s6_addr32[i]);
1548 : 0 : swap(keys->ports.src, keys->ports.dst);
1549 : : }
1550 : : break;
1551 : : }
1552 : 0 : }
1553 : :
1554 : 0 : static inline u32 __flow_hash_from_keys(struct flow_keys *keys,
1555 : : const siphash_key_t *keyval)
1556 : : {
1557 : 0 : u32 hash;
1558 : :
1559 : 0 : __flow_hash_consistentify(keys);
1560 : :
1561 [ # # ]: 0 : hash = siphash(flow_keys_hash_start(keys),
1562 : : flow_keys_hash_length(keys), keyval);
1563 : 0 : if (!hash)
1564 : : hash = 1;
1565 : :
1566 : 0 : return hash;
1567 : : }
1568 : :
1569 : 0 : u32 flow_hash_from_keys(struct flow_keys *keys)
1570 : : {
1571 [ # # ]: 0 : __flow_hash_secret_init();
1572 : 0 : return __flow_hash_from_keys(keys, &hashrnd);
1573 : : }
1574 : : EXPORT_SYMBOL(flow_hash_from_keys);
1575 : :
1576 : 0 : static inline u32 ___skb_get_hash(const struct sk_buff *skb,
1577 : : struct flow_keys *keys,
1578 : : const siphash_key_t *keyval)
1579 : : {
1580 : 0 : skb_flow_dissect_flow_keys(skb, keys,
1581 : : FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL);
1582 : :
1583 : 0 : return __flow_hash_from_keys(keys, keyval);
1584 : : }
1585 : :
1586 : : struct _flow_keys_digest_data {
1587 : : __be16 n_proto;
1588 : : u8 ip_proto;
1589 : : u8 padding;
1590 : : __be32 ports;
1591 : : __be32 src;
1592 : : __be32 dst;
1593 : : };
1594 : :
1595 : 0 : void make_flow_keys_digest(struct flow_keys_digest *digest,
1596 : : const struct flow_keys *flow)
1597 : : {
1598 : 0 : struct _flow_keys_digest_data *data =
1599 : : (struct _flow_keys_digest_data *)digest;
1600 : :
1601 : 0 : BUILD_BUG_ON(sizeof(*data) > sizeof(*digest));
1602 : :
1603 : 0 : memset(digest, 0, sizeof(*digest));
1604 : :
1605 : 0 : data->n_proto = flow->basic.n_proto;
1606 : 0 : data->ip_proto = flow->basic.ip_proto;
1607 : 0 : data->ports = flow->ports.ports;
1608 : 0 : data->src = flow->addrs.v4addrs.src;
1609 : 0 : data->dst = flow->addrs.v4addrs.dst;
1610 : 0 : }
1611 : : EXPORT_SYMBOL(make_flow_keys_digest);
1612 : :
1613 : : static struct flow_dissector flow_keys_dissector_symmetric __read_mostly;
1614 : :
1615 : 0 : u32 __skb_get_hash_symmetric(const struct sk_buff *skb)
1616 : : {
1617 : 0 : struct flow_keys keys;
1618 : :
1619 [ # # ]: 0 : __flow_hash_secret_init();
1620 : :
1621 : 0 : memset(&keys, 0, sizeof(keys));
1622 : 0 : __skb_flow_dissect(NULL, skb, &flow_keys_dissector_symmetric,
1623 : : &keys, NULL, 0, 0, 0,
1624 : : FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL);
1625 : :
1626 : 0 : return __flow_hash_from_keys(&keys, &hashrnd);
1627 : : }
1628 : : EXPORT_SYMBOL_GPL(__skb_get_hash_symmetric);
1629 : :
1630 : : /**
1631 : : * __skb_get_hash: calculate a flow hash
1632 : : * @skb: sk_buff to calculate flow hash from
1633 : : *
1634 : : * This function calculates a flow hash based on src/dst addresses
1635 : : * and src/dst port numbers. Sets hash in skb to non-zero hash value
1636 : : * on success, zero indicates no valid hash. Also, sets l4_hash in skb
1637 : : * if hash is a canonical 4-tuple hash over transport ports.
1638 : : */
1639 : 0 : void __skb_get_hash(struct sk_buff *skb)
1640 : : {
1641 : 0 : struct flow_keys keys;
1642 : 0 : u32 hash;
1643 : :
1644 [ # # ]: 0 : __flow_hash_secret_init();
1645 : :
1646 : 0 : hash = ___skb_get_hash(skb, &keys, &hashrnd);
1647 : :
1648 [ # # ]: 0 : __skb_set_sw_hash(skb, hash, flow_keys_have_l4(&keys));
1649 : 0 : }
1650 : : EXPORT_SYMBOL(__skb_get_hash);
1651 : :
1652 : 0 : __u32 skb_get_hash_perturb(const struct sk_buff *skb,
1653 : : const siphash_key_t *perturb)
1654 : : {
1655 : 0 : struct flow_keys keys;
1656 : :
1657 : 0 : return ___skb_get_hash(skb, &keys, perturb);
1658 : : }
1659 : : EXPORT_SYMBOL(skb_get_hash_perturb);
1660 : :
1661 : 0 : u32 __skb_get_poff(const struct sk_buff *skb, void *data,
1662 : : const struct flow_keys_basic *keys, int hlen)
1663 : : {
1664 : 0 : u32 poff = keys->control.thoff;
1665 : :
1666 : : /* skip L4 headers for fragments after the first */
1667 [ # # ]: 0 : if ((keys->control.flags & FLOW_DIS_IS_FRAGMENT) &&
1668 : : !(keys->control.flags & FLOW_DIS_FIRST_FRAG))
1669 : : return poff;
1670 : :
1671 [ # # # # : 0 : switch (keys->basic.ip_proto) {
# # # # ]
1672 : 0 : case IPPROTO_TCP: {
1673 : : /* access doff as u8 to avoid unaligned access */
1674 : 0 : const u8 *doff;
1675 : 0 : u8 _doff;
1676 : :
1677 [ # # ]: 0 : doff = __skb_header_pointer(skb, poff + 12, sizeof(_doff),
1678 : : data, hlen, &_doff);
1679 [ # # ]: 0 : if (!doff)
1680 : 0 : return poff;
1681 : :
1682 : 0 : poff += max_t(u32, sizeof(struct tcphdr), (*doff & 0xF0) >> 2);
1683 : 0 : break;
1684 : : }
1685 : 0 : case IPPROTO_UDP:
1686 : : case IPPROTO_UDPLITE:
1687 : 0 : poff += sizeof(struct udphdr);
1688 : 0 : break;
1689 : : /* For the rest, we do not really care about header
1690 : : * extensions at this point for now.
1691 : : */
1692 : 0 : case IPPROTO_ICMP:
1693 : 0 : poff += sizeof(struct icmphdr);
1694 : 0 : break;
1695 : 0 : case IPPROTO_ICMPV6:
1696 : 0 : poff += sizeof(struct icmp6hdr);
1697 : 0 : break;
1698 : 0 : case IPPROTO_IGMP:
1699 : 0 : poff += sizeof(struct igmphdr);
1700 : 0 : break;
1701 : 0 : case IPPROTO_DCCP:
1702 : 0 : poff += sizeof(struct dccp_hdr);
1703 : 0 : break;
1704 : 0 : case IPPROTO_SCTP:
1705 : 0 : poff += sizeof(struct sctphdr);
1706 : 0 : break;
1707 : : }
1708 : :
1709 : : return poff;
1710 : : }
1711 : :
1712 : : /**
1713 : : * skb_get_poff - get the offset to the payload
1714 : : * @skb: sk_buff to get the payload offset from
1715 : : *
1716 : : * The function will get the offset to the payload as far as it could
1717 : : * be dissected. The main user is currently BPF, so that we can dynamically
1718 : : * truncate packets without needing to push actual payload to the user
1719 : : * space and can analyze headers only, instead.
1720 : : */
1721 : 0 : u32 skb_get_poff(const struct sk_buff *skb)
1722 : : {
1723 : 0 : struct flow_keys_basic keys;
1724 : :
1725 [ # # ]: 0 : if (!skb_flow_dissect_flow_keys_basic(NULL, skb, &keys,
1726 : : NULL, 0, 0, 0, 0))
1727 : : return 0;
1728 : :
1729 : 0 : return __skb_get_poff(skb, skb->data, &keys, skb_headlen(skb));
1730 : : }
1731 : :
1732 : 0 : __u32 __get_hash_from_flowi6(const struct flowi6 *fl6, struct flow_keys *keys)
1733 : : {
1734 : 0 : memset(keys, 0, sizeof(*keys));
1735 : :
1736 : 0 : memcpy(&keys->addrs.v6addrs.src, &fl6->saddr,
1737 : : sizeof(keys->addrs.v6addrs.src));
1738 : 0 : memcpy(&keys->addrs.v6addrs.dst, &fl6->daddr,
1739 : : sizeof(keys->addrs.v6addrs.dst));
1740 : 0 : keys->control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
1741 : 0 : keys->ports.src = fl6->fl6_sport;
1742 : 0 : keys->ports.dst = fl6->fl6_dport;
1743 : 0 : keys->keyid.keyid = fl6->fl6_gre_key;
1744 : 0 : keys->tags.flow_label = (__force u32)flowi6_get_flowlabel(fl6);
1745 : 0 : keys->basic.ip_proto = fl6->flowi6_proto;
1746 : :
1747 : 0 : return flow_hash_from_keys(keys);
1748 : : }
1749 : : EXPORT_SYMBOL(__get_hash_from_flowi6);
1750 : :
1751 : : static const struct flow_dissector_key flow_keys_dissector_keys[] = {
1752 : : {
1753 : : .key_id = FLOW_DISSECTOR_KEY_CONTROL,
1754 : : .offset = offsetof(struct flow_keys, control),
1755 : : },
1756 : : {
1757 : : .key_id = FLOW_DISSECTOR_KEY_BASIC,
1758 : : .offset = offsetof(struct flow_keys, basic),
1759 : : },
1760 : : {
1761 : : .key_id = FLOW_DISSECTOR_KEY_IPV4_ADDRS,
1762 : : .offset = offsetof(struct flow_keys, addrs.v4addrs),
1763 : : },
1764 : : {
1765 : : .key_id = FLOW_DISSECTOR_KEY_IPV6_ADDRS,
1766 : : .offset = offsetof(struct flow_keys, addrs.v6addrs),
1767 : : },
1768 : : {
1769 : : .key_id = FLOW_DISSECTOR_KEY_TIPC,
1770 : : .offset = offsetof(struct flow_keys, addrs.tipckey),
1771 : : },
1772 : : {
1773 : : .key_id = FLOW_DISSECTOR_KEY_PORTS,
1774 : : .offset = offsetof(struct flow_keys, ports),
1775 : : },
1776 : : {
1777 : : .key_id = FLOW_DISSECTOR_KEY_VLAN,
1778 : : .offset = offsetof(struct flow_keys, vlan),
1779 : : },
1780 : : {
1781 : : .key_id = FLOW_DISSECTOR_KEY_FLOW_LABEL,
1782 : : .offset = offsetof(struct flow_keys, tags),
1783 : : },
1784 : : {
1785 : : .key_id = FLOW_DISSECTOR_KEY_GRE_KEYID,
1786 : : .offset = offsetof(struct flow_keys, keyid),
1787 : : },
1788 : : };
1789 : :
1790 : : static const struct flow_dissector_key flow_keys_dissector_symmetric_keys[] = {
1791 : : {
1792 : : .key_id = FLOW_DISSECTOR_KEY_CONTROL,
1793 : : .offset = offsetof(struct flow_keys, control),
1794 : : },
1795 : : {
1796 : : .key_id = FLOW_DISSECTOR_KEY_BASIC,
1797 : : .offset = offsetof(struct flow_keys, basic),
1798 : : },
1799 : : {
1800 : : .key_id = FLOW_DISSECTOR_KEY_IPV4_ADDRS,
1801 : : .offset = offsetof(struct flow_keys, addrs.v4addrs),
1802 : : },
1803 : : {
1804 : : .key_id = FLOW_DISSECTOR_KEY_IPV6_ADDRS,
1805 : : .offset = offsetof(struct flow_keys, addrs.v6addrs),
1806 : : },
1807 : : {
1808 : : .key_id = FLOW_DISSECTOR_KEY_PORTS,
1809 : : .offset = offsetof(struct flow_keys, ports),
1810 : : },
1811 : : };
1812 : :
1813 : : static const struct flow_dissector_key flow_keys_basic_dissector_keys[] = {
1814 : : {
1815 : : .key_id = FLOW_DISSECTOR_KEY_CONTROL,
1816 : : .offset = offsetof(struct flow_keys, control),
1817 : : },
1818 : : {
1819 : : .key_id = FLOW_DISSECTOR_KEY_BASIC,
1820 : : .offset = offsetof(struct flow_keys, basic),
1821 : : },
1822 : : };
1823 : :
1824 : : struct flow_dissector flow_keys_dissector __read_mostly;
1825 : : EXPORT_SYMBOL(flow_keys_dissector);
1826 : :
1827 : : struct flow_dissector flow_keys_basic_dissector __read_mostly;
1828 : : EXPORT_SYMBOL(flow_keys_basic_dissector);
1829 : :
1830 : 21 : static int __init init_default_flow_dissectors(void)
1831 : : {
1832 : 21 : skb_flow_dissector_init(&flow_keys_dissector,
1833 : : flow_keys_dissector_keys,
1834 : : ARRAY_SIZE(flow_keys_dissector_keys));
1835 : 21 : skb_flow_dissector_init(&flow_keys_dissector_symmetric,
1836 : : flow_keys_dissector_symmetric_keys,
1837 : : ARRAY_SIZE(flow_keys_dissector_symmetric_keys));
1838 : 21 : skb_flow_dissector_init(&flow_keys_basic_dissector,
1839 : : flow_keys_basic_dissector_keys,
1840 : : ARRAY_SIZE(flow_keys_basic_dissector_keys));
1841 : 21 : return 0;
1842 : : }
1843 : :
1844 : : core_initcall(init_default_flow_dissectors);
|