blob: 90bd210be06075818a8ba3213006e16eb610c602 [file] [log] [blame]
Greg Kroah-Hartmanb2441312017-11-01 15:07:57 +01001/* SPDX-License-Identifier: GPL-2.0 */
Jiri Pirko1bd758e2015-05-12 14:56:07 +02002#ifndef _NET_FLOW_DISSECTOR_H
3#define _NET_FLOW_DISSECTOR_H
Eric Dumazet0744dd02011-11-28 05:22:18 +00004
Jiri Pirkoc3f8eae2015-05-12 14:56:17 +02005#include <linux/types.h>
Jiri Pirkob9249332015-05-12 14:56:18 +02006#include <linux/in6.h>
Jiri Pirko67a900c2015-05-12 14:56:19 +02007#include <uapi/linux/if_ether.h>
Jiri Pirkoc3f8eae2015-05-12 14:56:17 +02008
Jiri Pirkofbff9492015-05-12 14:56:15 +02009/**
Tom Herbert42aecaa2015-06-04 09:16:39 -070010 * struct flow_dissector_key_control:
11 * @thoff: Transport header offset
12 */
13struct flow_dissector_key_control {
14 u16 thoff;
Tom Herbertc3f83242015-06-04 09:16:40 -070015 u16 addr_type;
David S. Miller4b369932015-09-01 16:46:08 -070016 u32 flags;
Tom Herbert42aecaa2015-06-04 09:16:39 -070017};
18
David S. Miller4b369932015-09-01 16:46:08 -070019#define FLOW_DIS_IS_FRAGMENT BIT(0)
20#define FLOW_DIS_FIRST_FRAG BIT(1)
21#define FLOW_DIS_ENCAPSULATION BIT(2)
22
Tom Herbert3a1214e2017-09-01 14:04:11 -070023enum 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
Tom Herbert42aecaa2015-06-04 09:16:39 -070031/**
Jiri Pirkofbff9492015-05-12 14:56:15 +020032 * struct flow_dissector_key_basic:
33 * @thoff: Transport header offset
34 * @n_proto: Network header protocol (eg. IPv4/IPv6)
35 * @ip_proto: Transport header protocol (eg. TCP/UDP)
36 */
37struct flow_dissector_key_basic {
Jiri Pirkofbff9492015-05-12 14:56:15 +020038 __be16 n_proto;
39 u8 ip_proto;
Tom Herbert42aecaa2015-06-04 09:16:39 -070040 u8 padding;
Jiri Pirkofbff9492015-05-12 14:56:15 +020041};
42
Tom Herbertd34af822015-06-04 09:16:43 -070043struct flow_dissector_key_tags {
Hadar Hen Zionf6a66922016-08-17 13:36:11 +030044 u32 flow_label;
45};
46
47struct flow_dissector_key_vlan {
48 u16 vlan_id:12,
Maxime Chevallierf0d2ca12019-06-12 17:18:38 +020049 vlan_dei:1,
Hadar Hen Zionf6a66922016-08-17 13:36:11 +030050 vlan_priority:3;
Jianbo Liu2064c3d2018-07-06 05:38:12 +000051 __be16 vlan_tpid;
Tom Herbertd34af822015-06-04 09:16:43 -070052};
53
Benjamin LaHaise029c1ec2017-04-22 16:52:46 -040054struct flow_dissector_key_mpls {
55 u32 mpls_ttl:8,
56 mpls_bos:1,
57 mpls_tc:3,
58 mpls_label:20;
59};
60
Simon Horman92e2c402018-08-07 17:36:00 +020061#define FLOW_DIS_TUN_OPTS_MAX 255
62/**
63 * struct flow_dissector_key_enc_opts:
64 * @data: tunnel option data
65 * @len: length of tunnel option data
66 * @dst_opt_type: tunnel option type
67 */
68struct flow_dissector_key_enc_opts {
69 u8 data[FLOW_DIS_TUN_OPTS_MAX]; /* Using IP_TUNNEL_OPTS_MAX is desired
70 * here but seems difficult to #include
71 */
72 u8 len;
73 __be16 dst_opt_type;
74};
75
Tom Herbert1fdd5122015-06-04 09:16:45 -070076struct flow_dissector_key_keyid {
77 __be32 keyid;
78};
79
Jiri Pirkofbff9492015-05-12 14:56:15 +020080/**
Tom Herbertc3f83242015-06-04 09:16:40 -070081 * struct flow_dissector_key_ipv4_addrs:
82 * @src: source ip address
83 * @dst: destination ip address
Jiri Pirkofbff9492015-05-12 14:56:15 +020084 */
Tom Herbertc3f83242015-06-04 09:16:40 -070085struct flow_dissector_key_ipv4_addrs {
Jiri Pirkofbff9492015-05-12 14:56:15 +020086 /* (src,dst) must be grouped, in the same way than in IP header */
87 __be32 src;
88 __be32 dst;
89};
90
91/**
Tom Herbertc3f83242015-06-04 09:16:40 -070092 * struct flow_dissector_key_ipv6_addrs:
93 * @src: source ip address
94 * @dst: destination ip address
95 */
96struct flow_dissector_key_ipv6_addrs {
97 /* (src,dst) must be grouped, in the same way than in IP header */
98 struct in6_addr src;
99 struct in6_addr dst;
100};
101
102/**
Jon Maloy8d6e79d2017-11-08 09:59:26 +0100103 * struct flow_dissector_key_tipc:
104 * @key: source node address combined with selector
Tom Herbert9f249082015-06-04 09:16:41 -0700105 */
Jon Maloy8d6e79d2017-11-08 09:59:26 +0100106struct flow_dissector_key_tipc {
107 __be32 key;
Tom Herbert9f249082015-06-04 09:16:41 -0700108};
109
110/**
Tom Herbertc3f83242015-06-04 09:16:40 -0700111 * struct flow_dissector_key_addrs:
112 * @v4addrs: IPv4 addresses
113 * @v6addrs: IPv6 addresses
114 */
115struct flow_dissector_key_addrs {
116 union {
117 struct flow_dissector_key_ipv4_addrs v4addrs;
118 struct flow_dissector_key_ipv6_addrs v6addrs;
Jon Maloy8d6e79d2017-11-08 09:59:26 +0100119 struct flow_dissector_key_tipc tipckey;
Tom Herbertc3f83242015-06-04 09:16:40 -0700120 };
121};
122
123/**
Simon Horman55733352017-01-11 14:05:42 +0100124 * flow_dissector_key_arp:
125 * @ports: Operation, source and target addresses for an ARP header
126 * for Ethernet hardware addresses and IPv4 protocol addresses
127 * sip: Sender IP address
128 * tip: Target IP address
129 * op: Operation
130 * sha: Sender hardware address
131 * tpa: Target hardware address
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/**
Jiri Pirkofbff9492015-05-12 14:56:15 +0200142 * flow_dissector_key_tp_ports:
143 * @ports: port numbers of Transport header
Jiri Pirko59346af2015-05-12 14:56:20 +0200144 * src: source port number
145 * dst: destination port number
Jiri Pirkofbff9492015-05-12 14:56:15 +0200146 */
147struct flow_dissector_key_ports {
148 union {
149 __be32 ports;
Jiri Pirko59346af2015-05-12 14:56:20 +0200150 struct {
151 __be16 src;
152 __be16 dst;
153 };
Jiri Pirkofbff9492015-05-12 14:56:15 +0200154 };
155};
156
Simon Horman972d3872016-12-07 13:48:27 +0100157/**
158 * flow_dissector_key_icmp:
159 * @ports: type and code of ICMP header
160 * icmp: ICMP type (high) and code (low)
161 * type: ICMP type
162 * code: ICMP code
163 */
164struct flow_dissector_key_icmp {
165 union {
166 __be16 icmp;
167 struct {
168 u8 type;
169 u8 code;
170 };
171 };
172};
Jiri Pirkob9249332015-05-12 14:56:18 +0200173
Jiri Pirko67a900c2015-05-12 14:56:19 +0200174/**
175 * struct flow_dissector_key_eth_addrs:
176 * @src: source Ethernet address
177 * @dst: destination Ethernet address
178 */
179struct flow_dissector_key_eth_addrs {
180 /* (dst,src) must be grouped, in the same way than in ETH header */
181 unsigned char dst[ETH_ALEN];
182 unsigned char src[ETH_ALEN];
183};
184
Jiri Pirkoac4bb5d2017-05-23 18:40:44 +0200185/**
186 * struct flow_dissector_key_tcp:
187 * @flags: flags
188 */
189struct flow_dissector_key_tcp {
190 __be16 flags;
191};
192
Or Gerlitz518d8a22017-06-01 21:37:37 +0300193/**
194 * struct flow_dissector_key_ip:
195 * @tos: tos
196 * @ttl: ttl
197 */
198struct flow_dissector_key_ip {
199 __u8 tos;
200 __u8 ttl;
201};
202
Jiri Pirko82828b82019-06-19 09:41:02 +0300203/**
204 * struct flow_dissector_key_meta:
205 * @ingress_ifindex: ingress ifindex
206 */
207struct flow_dissector_key_meta {
208 int ingress_ifindex;
209};
210
Paul Blakey75a56752019-07-09 10:30:49 +0300211/**
212 * struct flow_dissector_key_ct:
213 * @ct_state: conntrack state after converting with map
214 * @ct_mark: conttrack mark
215 * @ct_zone: conntrack zone
216 * @ct_labels: conntrack labels
217 */
218struct flow_dissector_key_ct {
219 u16 ct_state;
220 u16 ct_zone;
221 u32 ct_mark;
222 u32 ct_labels[4];
223};
224
Jiri Pirkofbff9492015-05-12 14:56:15 +0200225enum flow_dissector_key_id {
Tom Herbert42aecaa2015-06-04 09:16:39 -0700226 FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
Jiri Pirkofbff9492015-05-12 14:56:15 +0200227 FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
Tom Herbertc3f83242015-06-04 09:16:40 -0700228 FLOW_DISSECTOR_KEY_IPV4_ADDRS, /* struct flow_dissector_key_ipv4_addrs */
229 FLOW_DISSECTOR_KEY_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */
Jiri Pirkofbff9492015-05-12 14:56:15 +0200230 FLOW_DISSECTOR_KEY_PORTS, /* struct flow_dissector_key_ports */
Simon Horman972d3872016-12-07 13:48:27 +0100231 FLOW_DISSECTOR_KEY_ICMP, /* struct flow_dissector_key_icmp */
Jiri Pirko67a900c2015-05-12 14:56:19 +0200232 FLOW_DISSECTOR_KEY_ETH_ADDRS, /* struct flow_dissector_key_eth_addrs */
Jon Maloy8d6e79d2017-11-08 09:59:26 +0100233 FLOW_DISSECTOR_KEY_TIPC, /* struct flow_dissector_key_tipc */
Simon Horman55733352017-01-11 14:05:42 +0100234 FLOW_DISSECTOR_KEY_ARP, /* struct flow_dissector_key_arp */
Edward Cree91c45952018-11-27 15:40:59 +0000235 FLOW_DISSECTOR_KEY_VLAN, /* struct flow_dissector_key_vlan */
236 FLOW_DISSECTOR_KEY_FLOW_LABEL, /* struct flow_dissector_key_tags */
Tom Herbert1fdd5122015-06-04 09:16:45 -0700237 FLOW_DISSECTOR_KEY_GRE_KEYID, /* struct flow_dissector_key_keyid */
Tom Herbertb3baa0f2015-06-04 09:16:46 -0700238 FLOW_DISSECTOR_KEY_MPLS_ENTROPY, /* struct flow_dissector_key_keyid */
Hadar Hen Zion9ba6a9a2016-11-07 15:14:37 +0200239 FLOW_DISSECTOR_KEY_ENC_KEYID, /* struct flow_dissector_key_keyid */
240 FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS, /* struct flow_dissector_key_ipv4_addrs */
241 FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */
242 FLOW_DISSECTOR_KEY_ENC_CONTROL, /* struct flow_dissector_key_control */
Hadar Hen Zionf4d997f2016-11-07 15:14:39 +0200243 FLOW_DISSECTOR_KEY_ENC_PORTS, /* struct flow_dissector_key_ports */
Benjamin LaHaise029c1ec2017-04-22 16:52:46 -0400244 FLOW_DISSECTOR_KEY_MPLS, /* struct flow_dissector_key_mpls */
Jiri Pirkoac4bb5d2017-05-23 18:40:44 +0200245 FLOW_DISSECTOR_KEY_TCP, /* struct flow_dissector_key_tcp */
Or Gerlitz518d8a22017-06-01 21:37:37 +0300246 FLOW_DISSECTOR_KEY_IP, /* struct flow_dissector_key_ip */
Edward Cree91c45952018-11-27 15:40:59 +0000247 FLOW_DISSECTOR_KEY_CVLAN, /* struct flow_dissector_key_vlan */
Or Gerlitz5544adb2018-07-17 19:27:17 +0300248 FLOW_DISSECTOR_KEY_ENC_IP, /* struct flow_dissector_key_ip */
Simon Horman92e2c402018-08-07 17:36:00 +0200249 FLOW_DISSECTOR_KEY_ENC_OPTS, /* struct flow_dissector_key_enc_opts */
Jiri Pirko82828b82019-06-19 09:41:02 +0300250 FLOW_DISSECTOR_KEY_META, /* struct flow_dissector_key_meta */
Paul Blakey75a56752019-07-09 10:30:49 +0300251 FLOW_DISSECTOR_KEY_CT, /* struct flow_dissector_key_ct */
Simon Horman92e2c402018-08-07 17:36:00 +0200252
Jiri Pirkofbff9492015-05-12 14:56:15 +0200253 FLOW_DISSECTOR_KEY_MAX,
254};
255
Tom Herbert807e1652015-09-01 09:24:28 -0700256#define FLOW_DISSECTOR_F_PARSE_1ST_FRAG BIT(0)
Stanislav Fomichev1cc26452019-05-31 14:05:06 -0700257#define FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL BIT(1)
258#define FLOW_DISSECTOR_F_STOP_AT_ENCAP BIT(2)
Tom Herbert807e1652015-09-01 09:24:28 -0700259
Jiri Pirkofbff9492015-05-12 14:56:15 +0200260struct flow_dissector_key {
261 enum flow_dissector_key_id key_id;
262 size_t offset; /* offset of struct flow_dissector_key_*
263 in target the struct */
264};
265
266struct flow_dissector {
267 unsigned int used_keys; /* each bit repesents presence of one key id */
268 unsigned short int offset[FLOW_DISSECTOR_KEY_MAX];
269};
270
Paolo Abeni72a338b2018-05-04 11:32:59 +0200271struct flow_keys_basic {
272 struct flow_dissector_key_control control;
273 struct flow_dissector_key_basic basic;
274};
275
Jiri Pirko06635a32015-05-12 14:56:16 +0200276struct flow_keys {
Tom Herbert42aecaa2015-06-04 09:16:39 -0700277 struct flow_dissector_key_control control;
278#define FLOW_KEYS_HASH_START_FIELD basic
Jiri Pirko06635a32015-05-12 14:56:16 +0200279 struct flow_dissector_key_basic basic;
Tom Herbertd34af822015-06-04 09:16:43 -0700280 struct flow_dissector_key_tags tags;
Hadar Hen Zionf6a66922016-08-17 13:36:11 +0300281 struct flow_dissector_key_vlan vlan;
Jianbo Liu24c590e2018-07-06 05:38:14 +0000282 struct flow_dissector_key_vlan cvlan;
Tom Herbert1fdd5122015-06-04 09:16:45 -0700283 struct flow_dissector_key_keyid keyid;
Tom Herbert42aecaa2015-06-04 09:16:39 -0700284 struct flow_dissector_key_ports ports;
285 struct flow_dissector_key_addrs addrs;
Jiri Pirko06635a32015-05-12 14:56:16 +0200286};
287
Tom Herbert42aecaa2015-06-04 09:16:39 -0700288#define FLOW_KEYS_HASH_OFFSET \
289 offsetof(struct flow_keys, FLOW_KEYS_HASH_START_FIELD)
290
Tom Herbertc3f83242015-06-04 09:16:40 -0700291__be32 flow_get_u32_src(const struct flow_keys *flow);
292__be32 flow_get_u32_dst(const struct flow_keys *flow);
293
Jiri Pirko06635a32015-05-12 14:56:16 +0200294extern struct flow_dissector flow_keys_dissector;
Paolo Abeni72a338b2018-05-04 11:32:59 +0200295extern struct flow_dissector flow_keys_basic_dissector;
Jiri Pirko06635a32015-05-12 14:56:16 +0200296
Tom Herbert2f59e1e2015-05-01 11:30:17 -0700297/* struct flow_keys_digest:
298 *
299 * This structure is used to hold a digest of the full flow keys. This is a
300 * larger "hash" of a flow to allow definitively matching specific flows where
301 * the 32 bit skb->hash is not large enough. The size is limited to 16 bytes so
Wolfram Sang53bc0172018-05-06 13:23:52 +0200302 * that it can be used in CB of skb (see sch_choke for an example).
Tom Herbert2f59e1e2015-05-01 11:30:17 -0700303 */
304#define FLOW_KEYS_DIGEST_LEN 16
305struct flow_keys_digest {
306 u8 data[FLOW_KEYS_DIGEST_LEN];
307};
308
309void make_flow_keys_digest(struct flow_keys_digest *digest,
310 const struct flow_keys *flow);
311
Gao Feng66fdd052016-08-31 11:16:22 +0800312static inline bool flow_keys_have_l4(const struct flow_keys *keys)
Tom Herbertbcc83832015-09-01 09:24:24 -0700313{
314 return (keys->ports.ports || keys->tags.flow_label);
315}
316
Tom Herbertc6cc1ca2015-09-01 09:24:25 -0700317u32 flow_hash_from_keys(struct flow_keys *keys);
318
Amir Vadai8de2d792016-03-08 12:42:30 +0200319static inline bool dissector_uses_key(const struct flow_dissector *flow_dissector,
320 enum flow_dissector_key_id key_id)
321{
322 return flow_dissector->used_keys & (1 << key_id);
323}
324
325static inline void *skb_flow_dissector_target(struct flow_dissector *flow_dissector,
326 enum flow_dissector_key_id key_id,
327 void *target_container)
328{
329 return ((char *)target_container) + flow_dissector->offset[key_id];
330}
331
Stanislav Fomichev089b19a2019-04-22 08:55:44 -0700332struct bpf_flow_dissector {
333 struct bpf_flow_keys *flow_keys;
334 const struct sk_buff *skb;
335 void *data;
336 void *data_end;
337};
338
Eric Dumazet0744dd02011-11-28 05:22:18 +0000339#endif