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