blob: 78f6437cbc3a8b43b0484d5cadf562f13a3f7aba [file] [log] [blame]
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001/* 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>
David Brazdil0f672f62019-12-10 10:32:29 +00007#include <linux/siphash.h>
Olivier Deprez0e641232021-09-23 10:07:05 +02008#include <linux/string.h>
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00009#include <uapi/linux/if_ether.h>
10
11/**
12 * struct flow_dissector_key_control:
13 * @thoff: Transport header offset
14 */
15struct 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
25enum 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 */
39struct flow_dissector_key_basic {
40 __be16 n_proto;
41 u8 ip_proto;
42 u8 padding;
43};
44
45struct flow_dissector_key_tags {
46 u32 flow_label;
47};
48
49struct flow_dissector_key_vlan {
50 u16 vlan_id:12,
David Brazdil0f672f62019-12-10 10:32:29 +000051 vlan_dei:1,
Andrew Scullb4b6d4a2019-01-02 15:54:55 +000052 vlan_priority:3;
53 __be16 vlan_tpid;
54};
55
56struct 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 */
70struct 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
78struct 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 */
87struct 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 */
98struct 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 */
108struct 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 */
117struct 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 */
135struct 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 */
149struct 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 */
166struct 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 */
181struct 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 */
191struct flow_dissector_key_tcp {
192 __be16 flags;
193};
194
195/**
196 * struct flow_dissector_key_ip:
197 * @tos: tos
198 * @ttl: ttl
199 */
200struct flow_dissector_key_ip {
201 __u8 tos;
202 __u8 ttl;
203};
204
David Brazdil0f672f62019-12-10 10:32:29 +0000205/**
206 * struct flow_dissector_key_meta:
207 * @ingress_ifindex: ingress ifindex
208 */
209struct 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 */
220struct flow_dissector_key_ct {
221 u16 ct_state;
222 u16 ct_zone;
223 u32 ct_mark;
224 u32 ct_labels[4];
225};
226
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000227enum 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 */
Olivier Deprez0e641232021-09-23 10:07:05 +0200233 FLOW_DISSECTOR_KEY_PORTS_RANGE, /* struct flow_dissector_key_ports */
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000234 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 */
David Brazdil0f672f62019-12-10 10:32:29 +0000238 FLOW_DISSECTOR_KEY_VLAN, /* struct flow_dissector_key_vlan */
239 FLOW_DISSECTOR_KEY_FLOW_LABEL, /* struct flow_dissector_key_tags */
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000240 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 */
David Brazdil0f672f62019-12-10 10:32:29 +0000250 FLOW_DISSECTOR_KEY_CVLAN, /* struct flow_dissector_key_vlan */
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000251 FLOW_DISSECTOR_KEY_ENC_IP, /* struct flow_dissector_key_ip */
252 FLOW_DISSECTOR_KEY_ENC_OPTS, /* struct flow_dissector_key_enc_opts */
David Brazdil0f672f62019-12-10 10:32:29 +0000253 FLOW_DISSECTOR_KEY_META, /* struct flow_dissector_key_meta */
254 FLOW_DISSECTOR_KEY_CT, /* struct flow_dissector_key_ct */
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000255
256 FLOW_DISSECTOR_KEY_MAX,
257};
258
259#define FLOW_DISSECTOR_F_PARSE_1ST_FRAG BIT(0)
David Brazdil0f672f62019-12-10 10:32:29 +0000260#define FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL BIT(1)
261#define FLOW_DISSECTOR_F_STOP_AT_ENCAP BIT(2)
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000262
263struct 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
269struct 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
274struct flow_keys_basic {
275 struct flow_dissector_key_control control;
276 struct flow_dissector_key_basic basic;
277};
278
279struct flow_keys {
280 struct flow_dissector_key_control control;
281#define FLOW_KEYS_HASH_START_FIELD basic
David Brazdil0f672f62019-12-10 10:32:29 +0000282 struct flow_dissector_key_basic basic __aligned(SIPHASH_ALIGNMENT);
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000283 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
297extern struct flow_dissector flow_keys_dissector;
298extern 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
308struct flow_keys_digest {
309 u8 data[FLOW_KEYS_DIGEST_LEN];
310};
311
312void make_flow_keys_digest(struct flow_keys_digest *digest,
313 const struct flow_keys *flow);
314
315static inline bool flow_keys_have_l4(const struct flow_keys *keys)
316{
317 return (keys->ports.ports || keys->tags.flow_label);
318}
319
320u32 flow_hash_from_keys(struct flow_keys *keys);
321
322static inline bool dissector_uses_key(const struct flow_dissector *flow_dissector,
323 enum flow_dissector_key_id key_id)
324{
325 return flow_dissector->used_keys & (1 << key_id);
326}
327
328static 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 return ((char *)target_container) + flow_dissector->offset[key_id];
333}
334
David Brazdil0f672f62019-12-10 10:32:29 +0000335struct 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
Olivier Deprez0e641232021-09-23 10:07:05 +0200342static inline void
343flow_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
Andrew Scullb4b6d4a2019-01-02 15:54:55 +0000350#endif