Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0 */
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 : :
11 : : /**
12 : : * struct flow_dissector_key_control:
13 : : * @thoff: Transport header offset
14 : : */
15 : : struct flow_dissector_key_control {
16 : : u16 thoff;
17 : : u16 addr_type;
18 : : u32 flags;
19 : : };
20 : :
21 : : #define FLOW_DIS_IS_FRAGMENT BIT(0)
22 : : #define FLOW_DIS_FIRST_FRAG BIT(1)
23 : : #define FLOW_DIS_ENCAPSULATION BIT(2)
24 : :
25 : : enum flow_dissect_ret {
26 : : FLOW_DISSECT_RET_OUT_GOOD,
27 : : FLOW_DISSECT_RET_OUT_BAD,
28 : : FLOW_DISSECT_RET_PROTO_AGAIN,
29 : : FLOW_DISSECT_RET_IPPROTO_AGAIN,
30 : : FLOW_DISSECT_RET_CONTINUE,
31 : : };
32 : :
33 : : /**
34 : : * struct flow_dissector_key_basic:
35 : : * @thoff: Transport header offset
36 : : * @n_proto: Network header protocol (eg. IPv4/IPv6)
37 : : * @ip_proto: Transport header protocol (eg. TCP/UDP)
38 : : */
39 : : struct flow_dissector_key_basic {
40 : : __be16 n_proto;
41 : : u8 ip_proto;
42 : : u8 padding;
43 : : };
44 : :
45 : : struct flow_dissector_key_tags {
46 : : u32 flow_label;
47 : : };
48 : :
49 : : struct flow_dissector_key_vlan {
50 : : u16 vlan_id:12,
51 : : vlan_dei:1,
52 : : vlan_priority:3;
53 : : __be16 vlan_tpid;
54 : : };
55 : :
56 : : struct flow_dissector_key_mpls {
57 : : u32 mpls_ttl:8,
58 : : mpls_bos:1,
59 : : mpls_tc:3,
60 : : mpls_label:20;
61 : : };
62 : :
63 : : #define FLOW_DIS_TUN_OPTS_MAX 255
64 : : /**
65 : : * struct flow_dissector_key_enc_opts:
66 : : * @data: tunnel option data
67 : : * @len: length of tunnel option data
68 : : * @dst_opt_type: tunnel option type
69 : : */
70 : : struct flow_dissector_key_enc_opts {
71 : : u8 data[FLOW_DIS_TUN_OPTS_MAX]; /* Using IP_TUNNEL_OPTS_MAX is desired
72 : : * here but seems difficult to #include
73 : : */
74 : : u8 len;
75 : : __be16 dst_opt_type;
76 : : };
77 : :
78 : : struct flow_dissector_key_keyid {
79 : : __be32 keyid;
80 : : };
81 : :
82 : : /**
83 : : * struct flow_dissector_key_ipv4_addrs:
84 : : * @src: source ip address
85 : : * @dst: destination ip address
86 : : */
87 : : struct flow_dissector_key_ipv4_addrs {
88 : : /* (src,dst) must be grouped, in the same way than in IP header */
89 : : __be32 src;
90 : : __be32 dst;
91 : : };
92 : :
93 : : /**
94 : : * struct flow_dissector_key_ipv6_addrs:
95 : : * @src: source ip address
96 : : * @dst: destination ip address
97 : : */
98 : : struct flow_dissector_key_ipv6_addrs {
99 : : /* (src,dst) must be grouped, in the same way than in IP header */
100 : : struct in6_addr src;
101 : : struct in6_addr dst;
102 : : };
103 : :
104 : : /**
105 : : * struct flow_dissector_key_tipc:
106 : : * @key: source node address combined with selector
107 : : */
108 : : struct flow_dissector_key_tipc {
109 : : __be32 key;
110 : : };
111 : :
112 : : /**
113 : : * struct flow_dissector_key_addrs:
114 : : * @v4addrs: IPv4 addresses
115 : : * @v6addrs: IPv6 addresses
116 : : */
117 : : struct flow_dissector_key_addrs {
118 : : union {
119 : : struct flow_dissector_key_ipv4_addrs v4addrs;
120 : : struct flow_dissector_key_ipv6_addrs v6addrs;
121 : : struct flow_dissector_key_tipc tipckey;
122 : : };
123 : : };
124 : :
125 : : /**
126 : : * flow_dissector_key_arp:
127 : : * @ports: Operation, source and target addresses for an ARP header
128 : : * for Ethernet hardware addresses and IPv4 protocol addresses
129 : : * sip: Sender IP address
130 : : * tip: Target IP address
131 : : * op: Operation
132 : : * sha: Sender hardware address
133 : : * tpa: Target hardware address
134 : : */
135 : : struct flow_dissector_key_arp {
136 : : __u32 sip;
137 : : __u32 tip;
138 : : __u8 op;
139 : : unsigned char sha[ETH_ALEN];
140 : : unsigned char tha[ETH_ALEN];
141 : : };
142 : :
143 : : /**
144 : : * flow_dissector_key_tp_ports:
145 : : * @ports: port numbers of Transport header
146 : : * src: source port number
147 : : * dst: destination port number
148 : : */
149 : : struct flow_dissector_key_ports {
150 : : union {
151 : : __be32 ports;
152 : : struct {
153 : : __be16 src;
154 : : __be16 dst;
155 : : };
156 : : };
157 : : };
158 : :
159 : : /**
160 : : * flow_dissector_key_icmp:
161 : : * @ports: type and code of ICMP header
162 : : * icmp: ICMP type (high) and code (low)
163 : : * type: ICMP type
164 : : * code: ICMP code
165 : : */
166 : : struct flow_dissector_key_icmp {
167 : : union {
168 : : __be16 icmp;
169 : : struct {
170 : : u8 type;
171 : : u8 code;
172 : : };
173 : : };
174 : : };
175 : :
176 : : /**
177 : : * struct flow_dissector_key_eth_addrs:
178 : : * @src: source Ethernet address
179 : : * @dst: destination Ethernet address
180 : : */
181 : : struct flow_dissector_key_eth_addrs {
182 : : /* (dst,src) must be grouped, in the same way than in ETH header */
183 : : unsigned char dst[ETH_ALEN];
184 : : unsigned char src[ETH_ALEN];
185 : : };
186 : :
187 : : /**
188 : : * struct flow_dissector_key_tcp:
189 : : * @flags: flags
190 : : */
191 : : struct flow_dissector_key_tcp {
192 : : __be16 flags;
193 : : };
194 : :
195 : : /**
196 : : * struct flow_dissector_key_ip:
197 : : * @tos: tos
198 : : * @ttl: ttl
199 : : */
200 : : struct flow_dissector_key_ip {
201 : : __u8 tos;
202 : : __u8 ttl;
203 : : };
204 : :
205 : : /**
206 : : * struct flow_dissector_key_meta:
207 : : * @ingress_ifindex: ingress ifindex
208 : : */
209 : : struct flow_dissector_key_meta {
210 : : int ingress_ifindex;
211 : : };
212 : :
213 : : /**
214 : : * struct flow_dissector_key_ct:
215 : : * @ct_state: conntrack state after converting with map
216 : : * @ct_mark: conttrack mark
217 : : * @ct_zone: conntrack zone
218 : : * @ct_labels: conntrack labels
219 : : */
220 : : struct flow_dissector_key_ct {
221 : : u16 ct_state;
222 : : u16 ct_zone;
223 : : u32 ct_mark;
224 : : u32 ct_labels[4];
225 : : };
226 : :
227 : : enum flow_dissector_key_id {
228 : : FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
229 : : FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
230 : : FLOW_DISSECTOR_KEY_IPV4_ADDRS, /* struct flow_dissector_key_ipv4_addrs */
231 : : FLOW_DISSECTOR_KEY_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */
232 : : FLOW_DISSECTOR_KEY_PORTS, /* struct flow_dissector_key_ports */
233 : : FLOW_DISSECTOR_KEY_PORTS_RANGE, /* struct flow_dissector_key_ports */
234 : : FLOW_DISSECTOR_KEY_ICMP, /* struct flow_dissector_key_icmp */
235 : : FLOW_DISSECTOR_KEY_ETH_ADDRS, /* struct flow_dissector_key_eth_addrs */
236 : : FLOW_DISSECTOR_KEY_TIPC, /* struct flow_dissector_key_tipc */
237 : : FLOW_DISSECTOR_KEY_ARP, /* struct flow_dissector_key_arp */
238 : : FLOW_DISSECTOR_KEY_VLAN, /* struct flow_dissector_key_vlan */
239 : : FLOW_DISSECTOR_KEY_FLOW_LABEL, /* struct flow_dissector_key_tags */
240 : : FLOW_DISSECTOR_KEY_GRE_KEYID, /* struct flow_dissector_key_keyid */
241 : : FLOW_DISSECTOR_KEY_MPLS_ENTROPY, /* struct flow_dissector_key_keyid */
242 : : FLOW_DISSECTOR_KEY_ENC_KEYID, /* struct flow_dissector_key_keyid */
243 : : FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS, /* struct flow_dissector_key_ipv4_addrs */
244 : : FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */
245 : : FLOW_DISSECTOR_KEY_ENC_CONTROL, /* struct flow_dissector_key_control */
246 : : FLOW_DISSECTOR_KEY_ENC_PORTS, /* struct flow_dissector_key_ports */
247 : : FLOW_DISSECTOR_KEY_MPLS, /* struct flow_dissector_key_mpls */
248 : : FLOW_DISSECTOR_KEY_TCP, /* struct flow_dissector_key_tcp */
249 : : FLOW_DISSECTOR_KEY_IP, /* struct flow_dissector_key_ip */
250 : : FLOW_DISSECTOR_KEY_CVLAN, /* struct flow_dissector_key_vlan */
251 : : FLOW_DISSECTOR_KEY_ENC_IP, /* struct flow_dissector_key_ip */
252 : : FLOW_DISSECTOR_KEY_ENC_OPTS, /* struct flow_dissector_key_enc_opts */
253 : : FLOW_DISSECTOR_KEY_META, /* struct flow_dissector_key_meta */
254 : : FLOW_DISSECTOR_KEY_CT, /* struct flow_dissector_key_ct */
255 : :
256 : : FLOW_DISSECTOR_KEY_MAX,
257 : : };
258 : :
259 : : #define FLOW_DISSECTOR_F_PARSE_1ST_FRAG BIT(0)
260 : : #define FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL BIT(1)
261 : : #define FLOW_DISSECTOR_F_STOP_AT_ENCAP BIT(2)
262 : :
263 : : struct flow_dissector_key {
264 : : enum flow_dissector_key_id key_id;
265 : : size_t offset; /* offset of struct flow_dissector_key_*
266 : : in target the struct */
267 : : };
268 : :
269 : : struct flow_dissector {
270 : : unsigned int used_keys; /* each bit repesents presence of one key id */
271 : : unsigned short int offset[FLOW_DISSECTOR_KEY_MAX];
272 : : };
273 : :
274 : : struct flow_keys_basic {
275 : : struct flow_dissector_key_control control;
276 : : struct flow_dissector_key_basic basic;
277 : : };
278 : :
279 : : struct flow_keys {
280 : : struct flow_dissector_key_control control;
281 : : #define FLOW_KEYS_HASH_START_FIELD basic
282 : : struct flow_dissector_key_basic basic __aligned(SIPHASH_ALIGNMENT);
283 : : struct flow_dissector_key_tags tags;
284 : : struct flow_dissector_key_vlan vlan;
285 : : struct flow_dissector_key_vlan cvlan;
286 : : struct flow_dissector_key_keyid keyid;
287 : : struct flow_dissector_key_ports ports;
288 : : struct flow_dissector_key_addrs addrs;
289 : : };
290 : :
291 : : #define FLOW_KEYS_HASH_OFFSET \
292 : : offsetof(struct flow_keys, FLOW_KEYS_HASH_START_FIELD)
293 : :
294 : : __be32 flow_get_u32_src(const struct flow_keys *flow);
295 : : __be32 flow_get_u32_dst(const struct flow_keys *flow);
296 : :
297 : : extern struct flow_dissector flow_keys_dissector;
298 : : extern struct flow_dissector flow_keys_basic_dissector;
299 : :
300 : : /* struct flow_keys_digest:
301 : : *
302 : : * This structure is used to hold a digest of the full flow keys. This is a
303 : : * larger "hash" of a flow to allow definitively matching specific flows where
304 : : * the 32 bit skb->hash is not large enough. The size is limited to 16 bytes so
305 : : * that it can be used in CB of skb (see sch_choke for an example).
306 : : */
307 : : #define FLOW_KEYS_DIGEST_LEN 16
308 : : struct flow_keys_digest {
309 : : u8 data[FLOW_KEYS_DIGEST_LEN];
310 : : };
311 : :
312 : : void make_flow_keys_digest(struct flow_keys_digest *digest,
313 : : const struct flow_keys *flow);
314 : :
315 : : static inline bool flow_keys_have_l4(const struct flow_keys *keys)
316 : : {
317 [ - + # # ]: 2060 : return (keys->ports.ports || keys->tags.flow_label);
318 : : }
319 : :
320 : : u32 flow_hash_from_keys(struct flow_keys *keys);
321 : :
322 : : static inline bool dissector_uses_key(const struct flow_dissector *flow_dissector,
323 : : enum flow_dissector_key_id key_id)
324 : : {
325 : 17796 : return flow_dissector->used_keys & (1 << key_id);
326 : : }
327 : :
328 : : static inline void *skb_flow_dissector_target(struct flow_dissector *flow_dissector,
329 : : enum flow_dissector_key_id key_id,
330 : : void *target_container)
331 : : {
332 : 3154 : return ((char *)target_container) + flow_dissector->offset[key_id];
333 : : }
334 : :
335 : : struct bpf_flow_dissector {
336 : : struct bpf_flow_keys *flow_keys;
337 : : const struct sk_buff *skb;
338 : : void *data;
339 : : void *data_end;
340 : : };
341 : :
342 : : static inline void
343 : : flow_dissector_init_keys(struct flow_dissector_key_control *key_control,
344 : : struct flow_dissector_key_basic *key_basic)
345 : : {
346 : : memset(key_control, 0, sizeof(*key_control));
347 : : memset(key_basic, 0, sizeof(*key_basic));
348 : : }
349 : :
350 : : #endif
|