[RAMEN9610-21564]net/flow_dissector: switch to siphash
[GitHub/MotorolaMobilityLLC/kernel-slsi.git] / include / net / flow_dissector.h
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 <uapi/linux/if_ether.h>
9
10 /**
11 * struct flow_dissector_key_control:
12 * @thoff: Transport header offset
13 */
14 struct flow_dissector_key_control {
15 u16 thoff;
16 u16 addr_type;
17 u32 flags;
18 };
19
20 #define FLOW_DIS_IS_FRAGMENT BIT(0)
21 #define FLOW_DIS_FIRST_FRAG BIT(1)
22 #define FLOW_DIS_ENCAPSULATION BIT(2)
23
24 enum flow_dissect_ret {
25 FLOW_DISSECT_RET_OUT_GOOD,
26 FLOW_DISSECT_RET_OUT_BAD,
27 FLOW_DISSECT_RET_PROTO_AGAIN,
28 FLOW_DISSECT_RET_IPPROTO_AGAIN,
29 FLOW_DISSECT_RET_CONTINUE,
30 };
31
32 /**
33 * struct flow_dissector_key_basic:
34 * @thoff: Transport header offset
35 * @n_proto: Network header protocol (eg. IPv4/IPv6)
36 * @ip_proto: Transport header protocol (eg. TCP/UDP)
37 */
38 struct flow_dissector_key_basic {
39 __be16 n_proto;
40 u8 ip_proto;
41 u8 padding;
42 };
43
44 struct flow_dissector_key_tags {
45 u32 flow_label;
46 };
47
48 struct flow_dissector_key_vlan {
49 u16 vlan_id:12,
50 vlan_priority:3;
51 u16 padding;
52 };
53
54 struct flow_dissector_key_mpls {
55 u32 mpls_ttl:8,
56 mpls_bos:1,
57 mpls_tc:3,
58 mpls_label:20;
59 };
60
61 struct flow_dissector_key_keyid {
62 __be32 keyid;
63 };
64
65 /**
66 * struct flow_dissector_key_ipv4_addrs:
67 * @src: source ip address
68 * @dst: destination ip address
69 */
70 struct flow_dissector_key_ipv4_addrs {
71 /* (src,dst) must be grouped, in the same way than in IP header */
72 __be32 src;
73 __be32 dst;
74 };
75
76 /**
77 * struct flow_dissector_key_ipv6_addrs:
78 * @src: source ip address
79 * @dst: destination ip address
80 */
81 struct flow_dissector_key_ipv6_addrs {
82 /* (src,dst) must be grouped, in the same way than in IP header */
83 struct in6_addr src;
84 struct in6_addr dst;
85 };
86
87 /**
88 * struct flow_dissector_key_tipc_addrs:
89 * @srcnode: source node address
90 */
91 struct flow_dissector_key_tipc_addrs {
92 __be32 srcnode;
93 };
94
95 /**
96 * struct flow_dissector_key_addrs:
97 * @v4addrs: IPv4 addresses
98 * @v6addrs: IPv6 addresses
99 */
100 struct flow_dissector_key_addrs {
101 union {
102 struct flow_dissector_key_ipv4_addrs v4addrs;
103 struct flow_dissector_key_ipv6_addrs v6addrs;
104 struct flow_dissector_key_tipc_addrs tipcaddrs;
105 };
106 };
107
108 /**
109 * flow_dissector_key_arp:
110 * @ports: Operation, source and target addresses for an ARP header
111 * for Ethernet hardware addresses and IPv4 protocol addresses
112 * sip: Sender IP address
113 * tip: Target IP address
114 * op: Operation
115 * sha: Sender hardware address
116 * tpa: Target hardware address
117 */
118 struct flow_dissector_key_arp {
119 __u32 sip;
120 __u32 tip;
121 __u8 op;
122 unsigned char sha[ETH_ALEN];
123 unsigned char tha[ETH_ALEN];
124 };
125
126 /**
127 * flow_dissector_key_tp_ports:
128 * @ports: port numbers of Transport header
129 * src: source port number
130 * dst: destination port number
131 */
132 struct flow_dissector_key_ports {
133 union {
134 __be32 ports;
135 struct {
136 __be16 src;
137 __be16 dst;
138 };
139 };
140 };
141
142 /**
143 * flow_dissector_key_icmp:
144 * @ports: type and code of ICMP header
145 * icmp: ICMP type (high) and code (low)
146 * type: ICMP type
147 * code: ICMP code
148 */
149 struct flow_dissector_key_icmp {
150 union {
151 __be16 icmp;
152 struct {
153 u8 type;
154 u8 code;
155 };
156 };
157 };
158
159 /**
160 * struct flow_dissector_key_eth_addrs:
161 * @src: source Ethernet address
162 * @dst: destination Ethernet address
163 */
164 struct flow_dissector_key_eth_addrs {
165 /* (dst,src) must be grouped, in the same way than in ETH header */
166 unsigned char dst[ETH_ALEN];
167 unsigned char src[ETH_ALEN];
168 };
169
170 /**
171 * struct flow_dissector_key_tcp:
172 * @flags: flags
173 */
174 struct flow_dissector_key_tcp {
175 __be16 flags;
176 };
177
178 /**
179 * struct flow_dissector_key_ip:
180 * @tos: tos
181 * @ttl: ttl
182 */
183 struct flow_dissector_key_ip {
184 __u8 tos;
185 __u8 ttl;
186 };
187
188 enum flow_dissector_key_id {
189 FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
190 FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
191 FLOW_DISSECTOR_KEY_IPV4_ADDRS, /* struct flow_dissector_key_ipv4_addrs */
192 FLOW_DISSECTOR_KEY_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */
193 FLOW_DISSECTOR_KEY_PORTS, /* struct flow_dissector_key_ports */
194 FLOW_DISSECTOR_KEY_ICMP, /* struct flow_dissector_key_icmp */
195 FLOW_DISSECTOR_KEY_ETH_ADDRS, /* struct flow_dissector_key_eth_addrs */
196 FLOW_DISSECTOR_KEY_TIPC_ADDRS, /* struct flow_dissector_key_tipc_addrs */
197 FLOW_DISSECTOR_KEY_ARP, /* struct flow_dissector_key_arp */
198 FLOW_DISSECTOR_KEY_VLAN, /* struct flow_dissector_key_flow_vlan */
199 FLOW_DISSECTOR_KEY_FLOW_LABEL, /* struct flow_dissector_key_flow_tags */
200 FLOW_DISSECTOR_KEY_GRE_KEYID, /* struct flow_dissector_key_keyid */
201 FLOW_DISSECTOR_KEY_MPLS_ENTROPY, /* struct flow_dissector_key_keyid */
202 FLOW_DISSECTOR_KEY_ENC_KEYID, /* struct flow_dissector_key_keyid */
203 FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS, /* struct flow_dissector_key_ipv4_addrs */
204 FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */
205 FLOW_DISSECTOR_KEY_ENC_CONTROL, /* struct flow_dissector_key_control */
206 FLOW_DISSECTOR_KEY_ENC_PORTS, /* struct flow_dissector_key_ports */
207 FLOW_DISSECTOR_KEY_MPLS, /* struct flow_dissector_key_mpls */
208 FLOW_DISSECTOR_KEY_TCP, /* struct flow_dissector_key_tcp */
209 FLOW_DISSECTOR_KEY_IP, /* struct flow_dissector_key_ip */
210
211 FLOW_DISSECTOR_KEY_MAX,
212 };
213
214 #define FLOW_DISSECTOR_F_PARSE_1ST_FRAG BIT(0)
215 #define FLOW_DISSECTOR_F_STOP_AT_L3 BIT(1)
216 #define FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL BIT(2)
217 #define FLOW_DISSECTOR_F_STOP_AT_ENCAP BIT(3)
218
219 struct flow_dissector_key {
220 enum flow_dissector_key_id key_id;
221 size_t offset; /* offset of struct flow_dissector_key_*
222 in target the struct */
223 };
224
225 struct flow_dissector {
226 unsigned int used_keys; /* each bit repesents presence of one key id */
227 unsigned short int offset[FLOW_DISSECTOR_KEY_MAX];
228 };
229
230 struct flow_keys {
231 struct flow_dissector_key_control control;
232 #define FLOW_KEYS_HASH_START_FIELD basic
233 struct flow_dissector_key_basic basic __aligned(SIPHASH_ALIGNMENT);
234 struct flow_dissector_key_tags tags;
235 struct flow_dissector_key_vlan vlan;
236 struct flow_dissector_key_keyid keyid;
237 struct flow_dissector_key_ports ports;
238 struct flow_dissector_key_addrs addrs;
239 };
240
241 #define FLOW_KEYS_HASH_OFFSET \
242 offsetof(struct flow_keys, FLOW_KEYS_HASH_START_FIELD)
243
244 __be32 flow_get_u32_src(const struct flow_keys *flow);
245 __be32 flow_get_u32_dst(const struct flow_keys *flow);
246
247 extern struct flow_dissector flow_keys_dissector;
248 extern struct flow_dissector flow_keys_buf_dissector;
249
250 /* struct flow_keys_digest:
251 *
252 * This structure is used to hold a digest of the full flow keys. This is a
253 * larger "hash" of a flow to allow definitively matching specific flows where
254 * the 32 bit skb->hash is not large enough. The size is limited to 16 bytes so
255 * that it can by used in CB of skb (see sch_choke for an example).
256 */
257 #define FLOW_KEYS_DIGEST_LEN 16
258 struct flow_keys_digest {
259 u8 data[FLOW_KEYS_DIGEST_LEN];
260 };
261
262 void make_flow_keys_digest(struct flow_keys_digest *digest,
263 const struct flow_keys *flow);
264
265 static inline bool flow_keys_have_l4(const struct flow_keys *keys)
266 {
267 return (keys->ports.ports || keys->tags.flow_label);
268 }
269
270 u32 flow_hash_from_keys(struct flow_keys *keys);
271
272 static inline bool dissector_uses_key(const struct flow_dissector *flow_dissector,
273 enum flow_dissector_key_id key_id)
274 {
275 return flow_dissector->used_keys & (1 << key_id);
276 }
277
278 static inline void *skb_flow_dissector_target(struct flow_dissector *flow_dissector,
279 enum flow_dissector_key_id key_id,
280 void *target_container)
281 {
282 return ((char *)target_container) + flow_dissector->offset[key_id];
283 }
284
285 #endif