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 <uapi/linux/if_ether.h>
8
9
10
11
12
13struct flow_dissector_key_control {
14 u16 thoff;
15 u16 addr_type;
16 u32 flags;
17};
18
19#define FLOW_DIS_IS_FRAGMENT BIT(0)
20#define FLOW_DIS_FIRST_FRAG BIT(1)
21#define FLOW_DIS_ENCAPSULATION BIT(2)
22
23enum flow_dissect_ret {
24 FLOW_DISSECT_RET_OUT_GOOD,
25 FLOW_DISSECT_RET_OUT_BAD,
26 FLOW_DISSECT_RET_PROTO_AGAIN,
27 FLOW_DISSECT_RET_IPPROTO_AGAIN,
28 FLOW_DISSECT_RET_CONTINUE,
29};
30
31
32
33
34
35
36
37struct flow_dissector_key_basic {
38 __be16 n_proto;
39 u8 ip_proto;
40 u8 padding;
41};
42
43struct flow_dissector_key_tags {
44 u32 flow_label;
45};
46
47struct flow_dissector_key_vlan {
48 u16 vlan_id:12,
49 vlan_dei:1,
50 vlan_priority:3;
51 __be16 vlan_tpid;
52};
53
54struct flow_dissector_key_mpls {
55 u32 mpls_ttl:8,
56 mpls_bos:1,
57 mpls_tc:3,
58 mpls_label:20;
59};
60
61#define FLOW_DIS_TUN_OPTS_MAX 255
62
63
64
65
66
67
68struct flow_dissector_key_enc_opts {
69 u8 data[FLOW_DIS_TUN_OPTS_MAX];
70
71
72 u8 len;
73 __be16 dst_opt_type;
74};
75
76struct flow_dissector_key_keyid {
77 __be32 keyid;
78};
79
80
81
82
83
84
85struct flow_dissector_key_ipv4_addrs {
86
87 __be32 src;
88 __be32 dst;
89};
90
91
92
93
94
95
96struct flow_dissector_key_ipv6_addrs {
97
98 struct in6_addr src;
99 struct in6_addr dst;
100};
101
102
103
104
105
106struct flow_dissector_key_tipc {
107 __be32 key;
108};
109
110
111
112
113
114
115struct flow_dissector_key_addrs {
116 union {
117 struct flow_dissector_key_ipv4_addrs v4addrs;
118 struct flow_dissector_key_ipv6_addrs v6addrs;
119 struct flow_dissector_key_tipc tipckey;
120 };
121};
122
123
124
125
126
127
128
129
130
131
132
133struct flow_dissector_key_arp {
134 __u32 sip;
135 __u32 tip;
136 __u8 op;
137 unsigned char sha[ETH_ALEN];
138 unsigned char tha[ETH_ALEN];
139};
140
141
142
143
144
145
146
147struct flow_dissector_key_ports {
148 union {
149 __be32 ports;
150 struct {
151 __be16 src;
152 __be16 dst;
153 };
154 };
155};
156
157
158
159
160
161
162
163
164struct flow_dissector_key_icmp {
165 union {
166 __be16 icmp;
167 struct {
168 u8 type;
169 u8 code;
170 };
171 };
172};
173
174
175
176
177
178
179struct flow_dissector_key_eth_addrs {
180
181 unsigned char dst[ETH_ALEN];
182 unsigned char src[ETH_ALEN];
183};
184
185
186
187
188
189struct flow_dissector_key_tcp {
190 __be16 flags;
191};
192
193
194
195
196
197
198struct flow_dissector_key_ip {
199 __u8 tos;
200 __u8 ttl;
201};
202
203enum flow_dissector_key_id {
204 FLOW_DISSECTOR_KEY_CONTROL,
205 FLOW_DISSECTOR_KEY_BASIC,
206 FLOW_DISSECTOR_KEY_IPV4_ADDRS,
207 FLOW_DISSECTOR_KEY_IPV6_ADDRS,
208 FLOW_DISSECTOR_KEY_PORTS,
209 FLOW_DISSECTOR_KEY_ICMP,
210 FLOW_DISSECTOR_KEY_ETH_ADDRS,
211 FLOW_DISSECTOR_KEY_TIPC,
212 FLOW_DISSECTOR_KEY_ARP,
213 FLOW_DISSECTOR_KEY_VLAN,
214 FLOW_DISSECTOR_KEY_FLOW_LABEL,
215 FLOW_DISSECTOR_KEY_GRE_KEYID,
216 FLOW_DISSECTOR_KEY_MPLS_ENTROPY,
217 FLOW_DISSECTOR_KEY_ENC_KEYID,
218 FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS,
219 FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS,
220 FLOW_DISSECTOR_KEY_ENC_CONTROL,
221 FLOW_DISSECTOR_KEY_ENC_PORTS,
222 FLOW_DISSECTOR_KEY_MPLS,
223 FLOW_DISSECTOR_KEY_TCP,
224 FLOW_DISSECTOR_KEY_IP,
225 FLOW_DISSECTOR_KEY_CVLAN,
226 FLOW_DISSECTOR_KEY_ENC_IP,
227 FLOW_DISSECTOR_KEY_ENC_OPTS,
228
229 FLOW_DISSECTOR_KEY_MAX,
230};
231
232#define FLOW_DISSECTOR_F_PARSE_1ST_FRAG BIT(0)
233#define FLOW_DISSECTOR_F_STOP_AT_L3 BIT(1)
234#define FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL BIT(2)
235#define FLOW_DISSECTOR_F_STOP_AT_ENCAP BIT(3)
236
237struct flow_dissector_key {
238 enum flow_dissector_key_id key_id;
239 size_t offset;
240
241};
242
243struct flow_dissector {
244 unsigned int used_keys;
245 unsigned short int offset[FLOW_DISSECTOR_KEY_MAX];
246};
247
248struct flow_keys_basic {
249 struct flow_dissector_key_control control;
250 struct flow_dissector_key_basic basic;
251};
252
253struct flow_keys {
254 struct flow_dissector_key_control control;
255#define FLOW_KEYS_HASH_START_FIELD basic
256 struct flow_dissector_key_basic basic;
257 struct flow_dissector_key_tags tags;
258 struct flow_dissector_key_vlan vlan;
259 struct flow_dissector_key_vlan cvlan;
260 struct flow_dissector_key_keyid keyid;
261 struct flow_dissector_key_ports ports;
262 struct flow_dissector_key_addrs addrs;
263};
264
265#define FLOW_KEYS_HASH_OFFSET \
266 offsetof(struct flow_keys, FLOW_KEYS_HASH_START_FIELD)
267
268__be32 flow_get_u32_src(const struct flow_keys *flow);
269__be32 flow_get_u32_dst(const struct flow_keys *flow);
270
271extern struct flow_dissector flow_keys_dissector;
272extern struct flow_dissector flow_keys_basic_dissector;
273
274
275
276
277
278
279
280
281#define FLOW_KEYS_DIGEST_LEN 16
282struct flow_keys_digest {
283 u8 data[FLOW_KEYS_DIGEST_LEN];
284};
285
286void make_flow_keys_digest(struct flow_keys_digest *digest,
287 const struct flow_keys *flow);
288
289static inline bool flow_keys_have_l4(const struct flow_keys *keys)
290{
291 return (keys->ports.ports || keys->tags.flow_label);
292}
293
294u32 flow_hash_from_keys(struct flow_keys *keys);
295
296static inline bool dissector_uses_key(const struct flow_dissector *flow_dissector,
297 enum flow_dissector_key_id key_id)
298{
299 return flow_dissector->used_keys & (1 << key_id);
300}
301
302static inline void *skb_flow_dissector_target(struct flow_dissector *flow_dissector,
303 enum flow_dissector_key_id key_id,
304 void *target_container)
305{
306 return ((char *)target_container) + flow_dissector->offset[key_id];
307}
308
309struct bpf_flow_dissector {
310 struct bpf_flow_keys *flow_keys;
311 const struct sk_buff *skb;
312 void *data;
313 void *data_end;
314};
315
316#endif
317