1
2#ifndef _NET_FLOW_DISSECTOR_H
3#define _NET_FLOW_DISSECTOR_H
4
5#include <linux/types.h>
6#include <linux/in6.h>
7#include <linux/siphash.h>
8#include <linux/string.h>
9#include <uapi/linux/if_ether.h>
10
11struct bpf_prog;
12struct net;
13struct sk_buff;
14
15
16
17
18
19struct flow_dissector_key_control {
20 u16 thoff;
21 u16 addr_type;
22 u32 flags;
23};
24
25#define FLOW_DIS_IS_FRAGMENT BIT(0)
26#define FLOW_DIS_FIRST_FRAG BIT(1)
27#define FLOW_DIS_ENCAPSULATION BIT(2)
28
29enum flow_dissect_ret {
30 FLOW_DISSECT_RET_OUT_GOOD,
31 FLOW_DISSECT_RET_OUT_BAD,
32 FLOW_DISSECT_RET_PROTO_AGAIN,
33 FLOW_DISSECT_RET_IPPROTO_AGAIN,
34 FLOW_DISSECT_RET_CONTINUE,
35};
36
37
38
39
40
41
42struct flow_dissector_key_basic {
43 __be16 n_proto;
44 u8 ip_proto;
45 u8 padding;
46};
47
48struct flow_dissector_key_tags {
49 u32 flow_label;
50};
51
52struct flow_dissector_key_vlan {
53 union {
54 struct {
55 u16 vlan_id:12,
56 vlan_dei:1,
57 vlan_priority:3;
58 };
59 __be16 vlan_tci;
60 };
61 __be16 vlan_tpid;
62};
63
64struct flow_dissector_mpls_lse {
65 u32 mpls_ttl:8,
66 mpls_bos:1,
67 mpls_tc:3,
68 mpls_label:20;
69};
70
71#define FLOW_DIS_MPLS_MAX 7
72struct flow_dissector_key_mpls {
73 struct flow_dissector_mpls_lse ls[FLOW_DIS_MPLS_MAX];
74 u8 used_lses;
75};
76
77static inline void dissector_set_mpls_lse(struct flow_dissector_key_mpls *mpls,
78 int lse_index)
79{
80 mpls->used_lses |= 1 << lse_index;
81}
82
83#define FLOW_DIS_TUN_OPTS_MAX 255
84
85
86
87
88
89
90struct flow_dissector_key_enc_opts {
91 u8 data[FLOW_DIS_TUN_OPTS_MAX];
92
93
94 u8 len;
95 __be16 dst_opt_type;
96};
97
98struct flow_dissector_key_keyid {
99 __be32 keyid;
100};
101
102
103
104
105
106
107struct flow_dissector_key_ipv4_addrs {
108
109 __be32 src;
110 __be32 dst;
111};
112
113
114
115
116
117
118struct flow_dissector_key_ipv6_addrs {
119
120 struct in6_addr src;
121 struct in6_addr dst;
122};
123
124
125
126
127
128struct flow_dissector_key_tipc {
129 __be32 key;
130};
131
132
133
134
135
136
137struct flow_dissector_key_addrs {
138 union {
139 struct flow_dissector_key_ipv4_addrs v4addrs;
140 struct flow_dissector_key_ipv6_addrs v6addrs;
141 struct flow_dissector_key_tipc tipckey;
142 };
143};
144
145
146
147
148
149
150
151
152
153
154
155struct flow_dissector_key_arp {
156 __u32 sip;
157 __u32 tip;
158 __u8 op;
159 unsigned char sha[ETH_ALEN];
160 unsigned char tha[ETH_ALEN];
161};
162
163
164
165
166
167
168
169struct flow_dissector_key_ports {
170 union {
171 __be32 ports;
172 struct {
173 __be16 src;
174 __be16 dst;
175 };
176 };
177};
178
179
180
181
182
183
184
185struct flow_dissector_key_icmp {
186 struct {
187 u8 type;
188 u8 code;
189 };
190 u16 id;
191};
192
193
194
195
196
197
198struct flow_dissector_key_eth_addrs {
199
200 unsigned char dst[ETH_ALEN];
201 unsigned char src[ETH_ALEN];
202};
203
204
205
206
207
208struct flow_dissector_key_tcp {
209 __be16 flags;
210};
211
212
213
214
215
216
217struct flow_dissector_key_ip {
218 __u8 tos;
219 __u8 ttl;
220};
221
222
223
224
225
226
227struct flow_dissector_key_meta {
228 int ingress_ifindex;
229 u16 ingress_iftype;
230};
231
232
233
234
235
236
237
238
239struct flow_dissector_key_ct {
240 u16 ct_state;
241 u16 ct_zone;
242 u32 ct_mark;
243 u32 ct_labels[4];
244};
245
246
247
248
249
250struct flow_dissector_key_hash {
251 u32 hash;
252};
253
254enum flow_dissector_key_id {
255 FLOW_DISSECTOR_KEY_CONTROL,
256 FLOW_DISSECTOR_KEY_BASIC,
257 FLOW_DISSECTOR_KEY_IPV4_ADDRS,
258 FLOW_DISSECTOR_KEY_IPV6_ADDRS,
259 FLOW_DISSECTOR_KEY_PORTS,
260 FLOW_DISSECTOR_KEY_PORTS_RANGE,
261 FLOW_DISSECTOR_KEY_ICMP,
262 FLOW_DISSECTOR_KEY_ETH_ADDRS,
263 FLOW_DISSECTOR_KEY_TIPC,
264 FLOW_DISSECTOR_KEY_ARP,
265 FLOW_DISSECTOR_KEY_VLAN,
266 FLOW_DISSECTOR_KEY_FLOW_LABEL,
267 FLOW_DISSECTOR_KEY_GRE_KEYID,
268 FLOW_DISSECTOR_KEY_MPLS_ENTROPY,
269 FLOW_DISSECTOR_KEY_ENC_KEYID,
270 FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS,
271 FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS,
272 FLOW_DISSECTOR_KEY_ENC_CONTROL,
273 FLOW_DISSECTOR_KEY_ENC_PORTS,
274 FLOW_DISSECTOR_KEY_MPLS,
275 FLOW_DISSECTOR_KEY_TCP,
276 FLOW_DISSECTOR_KEY_IP,
277 FLOW_DISSECTOR_KEY_CVLAN,
278 FLOW_DISSECTOR_KEY_ENC_IP,
279 FLOW_DISSECTOR_KEY_ENC_OPTS,
280 FLOW_DISSECTOR_KEY_META,
281 FLOW_DISSECTOR_KEY_CT,
282 FLOW_DISSECTOR_KEY_HASH,
283
284 FLOW_DISSECTOR_KEY_MAX,
285};
286
287#define FLOW_DISSECTOR_F_PARSE_1ST_FRAG BIT(0)
288#define FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL BIT(1)
289#define FLOW_DISSECTOR_F_STOP_AT_ENCAP BIT(2)
290#define FLOW_DISSECTOR_F_STOP_BEFORE_ENCAP BIT(3)
291
292struct flow_dissector_key {
293 enum flow_dissector_key_id key_id;
294 size_t offset;
295
296};
297
298struct flow_dissector {
299 unsigned int used_keys;
300 unsigned short int offset[FLOW_DISSECTOR_KEY_MAX];
301};
302
303struct flow_keys_basic {
304 struct flow_dissector_key_control control;
305 struct flow_dissector_key_basic basic;
306};
307
308struct flow_keys {
309 struct flow_dissector_key_control control;
310#define FLOW_KEYS_HASH_START_FIELD basic
311 struct flow_dissector_key_basic basic __aligned(SIPHASH_ALIGNMENT);
312 struct flow_dissector_key_tags tags;
313 struct flow_dissector_key_vlan vlan;
314 struct flow_dissector_key_vlan cvlan;
315 struct flow_dissector_key_keyid keyid;
316 struct flow_dissector_key_ports ports;
317 struct flow_dissector_key_icmp icmp;
318
319 struct flow_dissector_key_addrs addrs;
320};
321
322#define FLOW_KEYS_HASH_OFFSET \
323 offsetof(struct flow_keys, FLOW_KEYS_HASH_START_FIELD)
324
325__be32 flow_get_u32_src(const struct flow_keys *flow);
326__be32 flow_get_u32_dst(const struct flow_keys *flow);
327
328extern struct flow_dissector flow_keys_dissector;
329extern struct flow_dissector flow_keys_basic_dissector;
330
331
332
333
334
335
336
337
338#define FLOW_KEYS_DIGEST_LEN 16
339struct flow_keys_digest {
340 u8 data[FLOW_KEYS_DIGEST_LEN];
341};
342
343void make_flow_keys_digest(struct flow_keys_digest *digest,
344 const struct flow_keys *flow);
345
346static inline bool flow_keys_have_l4(const struct flow_keys *keys)
347{
348 return (keys->ports.ports || keys->tags.flow_label);
349}
350
351u32 flow_hash_from_keys(struct flow_keys *keys);
352void skb_flow_get_icmp_tci(const struct sk_buff *skb,
353 struct flow_dissector_key_icmp *key_icmp,
354 const void *data, int thoff, int hlen);
355
356static inline bool dissector_uses_key(const struct flow_dissector *flow_dissector,
357 enum flow_dissector_key_id key_id)
358{
359 return flow_dissector->used_keys & (1 << key_id);
360}
361
362static inline void *skb_flow_dissector_target(struct flow_dissector *flow_dissector,
363 enum flow_dissector_key_id key_id,
364 void *target_container)
365{
366 return ((char *)target_container) + flow_dissector->offset[key_id];
367}
368
369struct bpf_flow_dissector {
370 struct bpf_flow_keys *flow_keys;
371 const struct sk_buff *skb;
372 const void *data;
373 const void *data_end;
374};
375
376static inline void
377flow_dissector_init_keys(struct flow_dissector_key_control *key_control,
378 struct flow_dissector_key_basic *key_basic)
379{
380 memset(key_control, 0, sizeof(*key_control));
381 memset(key_basic, 0, sizeof(*key_basic));
382}
383
384#ifdef CONFIG_BPF_SYSCALL
385int flow_dissector_bpf_prog_attach_check(struct net *net,
386 struct bpf_prog *prog);
387#endif
388
389#endif
390