xref: /openbmc/linux/include/net/flow_dissector.h (revision d7ad70b5ef5ab8dedaa403e0e5c711ca1aa8cb14)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
21bd758ebSJiri Pirko #ifndef _NET_FLOW_DISSECTOR_H
31bd758ebSJiri Pirko #define _NET_FLOW_DISSECTOR_H
41bd758ebSJiri Pirko 
5c3f8eaebSJiri Pirko #include <linux/types.h>
6b924933cSJiri Pirko #include <linux/in6.h>
755667441SEric Dumazet #include <linux/siphash.h>
88a9093c7SJason Baron #include <linux/string.h>
967a900ccSJiri Pirko #include <uapi/linux/if_ether.h>
10c3f8eaebSJiri Pirko 
11b27f7bb5SJakub Sitnicki struct bpf_prog;
12b27f7bb5SJakub Sitnicki struct net;
135dec597eSMatteo Croce struct sk_buff;
145dec597eSMatteo Croce 
15fbff949eSJiri Pirko /**
1642aecaa9STom Herbert  * struct flow_dissector_key_control:
1742aecaa9STom Herbert  * @thoff:     Transport header offset
188c966a10SSimon Horman  * @addr_type: Type of key. One of FLOW_DISSECTOR_KEY_*
198c966a10SSimon Horman  * @flags:     Key flags. Any of FLOW_DIS_(IS_FRAGMENT|FIRST_FRAGENCAPSULATION)
2042aecaa9STom Herbert  */
2142aecaa9STom Herbert struct flow_dissector_key_control {
2242aecaa9STom Herbert 	u16	thoff;
23c3f83241STom Herbert 	u16	addr_type;
244b36993dSDavid S. Miller 	u32	flags;
2542aecaa9STom Herbert };
2642aecaa9STom Herbert 
274b36993dSDavid S. Miller #define FLOW_DIS_IS_FRAGMENT	BIT(0)
284b36993dSDavid S. Miller #define FLOW_DIS_FIRST_FRAG	BIT(1)
294b36993dSDavid S. Miller #define FLOW_DIS_ENCAPSULATION	BIT(2)
304b36993dSDavid S. Miller 
313a1214e8STom Herbert enum flow_dissect_ret {
323a1214e8STom Herbert 	FLOW_DISSECT_RET_OUT_GOOD,
333a1214e8STom Herbert 	FLOW_DISSECT_RET_OUT_BAD,
343a1214e8STom Herbert 	FLOW_DISSECT_RET_PROTO_AGAIN,
353a1214e8STom Herbert 	FLOW_DISSECT_RET_IPPROTO_AGAIN,
363a1214e8STom Herbert 	FLOW_DISSECT_RET_CONTINUE,
373a1214e8STom Herbert };
383a1214e8STom Herbert 
3942aecaa9STom Herbert /**
40fbff949eSJiri Pirko  * struct flow_dissector_key_basic:
41fbff949eSJiri Pirko  * @n_proto:  Network header protocol (eg. IPv4/IPv6)
42fbff949eSJiri Pirko  * @ip_proto: Transport header protocol (eg. TCP/UDP)
438c966a10SSimon Horman  * @padding:  Unused
44fbff949eSJiri Pirko  */
45fbff949eSJiri Pirko struct flow_dissector_key_basic {
46fbff949eSJiri Pirko 	__be16	n_proto;
47fbff949eSJiri Pirko 	u8	ip_proto;
4842aecaa9STom Herbert 	u8	padding;
49fbff949eSJiri Pirko };
50fbff949eSJiri Pirko 
51d34af823STom Herbert struct flow_dissector_key_tags {
52f6a66927SHadar Hen Zion 	u32	flow_label;
53f6a66927SHadar Hen Zion };
54f6a66927SHadar Hen Zion 
55f6a66927SHadar Hen Zion struct flow_dissector_key_vlan {
56a82055afSPablo Neira Ayuso 	union {
57d1746d1eSPetr Machata 		struct {
58f6a66927SHadar Hen Zion 			u16	vlan_id:12,
59f0d2ca15SMaxime Chevallier 				vlan_dei:1,
60f6a66927SHadar Hen Zion 				vlan_priority:3;
61d1746d1eSPetr Machata 		};
62a82055afSPablo Neira Ayuso 		__be16	vlan_tci;
63a82055afSPablo Neira Ayuso 	};
642064c3d4SJianbo Liu 	__be16	vlan_tpid;
652105f700SVlad Buslov 	__be16	vlan_eth_type;
662105f700SVlad Buslov 	u16	padding;
67d34af823STom Herbert };
68d34af823STom Herbert 
6958cff782SGuillaume Nault struct flow_dissector_mpls_lse {
70029c1ecbSBenjamin LaHaise 	u32	mpls_ttl:8,
71029c1ecbSBenjamin LaHaise 		mpls_bos:1,
72029c1ecbSBenjamin LaHaise 		mpls_tc:3,
73029c1ecbSBenjamin LaHaise 		mpls_label:20;
74029c1ecbSBenjamin LaHaise };
75029c1ecbSBenjamin LaHaise 
7658cff782SGuillaume Nault #define FLOW_DIS_MPLS_MAX 7
7758cff782SGuillaume Nault struct flow_dissector_key_mpls {
7858cff782SGuillaume Nault 	struct flow_dissector_mpls_lse ls[FLOW_DIS_MPLS_MAX]; /* Label Stack */
7958cff782SGuillaume Nault 	u8 used_lses; /* One bit set for each Label Stack Entry in use */
8058cff782SGuillaume Nault };
8158cff782SGuillaume Nault 
8258cff782SGuillaume Nault static inline void dissector_set_mpls_lse(struct flow_dissector_key_mpls *mpls,
8358cff782SGuillaume Nault 					  int lse_index)
8458cff782SGuillaume Nault {
8558cff782SGuillaume Nault 	mpls->used_lses |= 1 << lse_index;
8658cff782SGuillaume Nault }
8758cff782SGuillaume Nault 
8892e2c405SSimon Horman #define FLOW_DIS_TUN_OPTS_MAX 255
8992e2c405SSimon Horman /**
9092e2c405SSimon Horman  * struct flow_dissector_key_enc_opts:
9192e2c405SSimon Horman  * @data: tunnel option data
9292e2c405SSimon Horman  * @len: length of tunnel option data
9392e2c405SSimon Horman  * @dst_opt_type: tunnel option type
9492e2c405SSimon Horman  */
9592e2c405SSimon Horman struct flow_dissector_key_enc_opts {
9692e2c405SSimon Horman 	u8 data[FLOW_DIS_TUN_OPTS_MAX];	/* Using IP_TUNNEL_OPTS_MAX is desired
9792e2c405SSimon Horman 					 * here but seems difficult to #include
9892e2c405SSimon Horman 					 */
9992e2c405SSimon Horman 	u8 len;
10092e2c405SSimon Horman 	__be16 dst_opt_type;
10192e2c405SSimon Horman };
10292e2c405SSimon Horman 
1031fdd512cSTom Herbert struct flow_dissector_key_keyid {
1041fdd512cSTom Herbert 	__be32	keyid;
1051fdd512cSTom Herbert };
1061fdd512cSTom Herbert 
107fbff949eSJiri Pirko /**
108c3f83241STom Herbert  * struct flow_dissector_key_ipv4_addrs:
109c3f83241STom Herbert  * @src: source ip address
110c3f83241STom Herbert  * @dst: destination ip address
111fbff949eSJiri Pirko  */
112c3f83241STom Herbert struct flow_dissector_key_ipv4_addrs {
113fbff949eSJiri Pirko 	/* (src,dst) must be grouped, in the same way than in IP header */
114fbff949eSJiri Pirko 	__be32 src;
115fbff949eSJiri Pirko 	__be32 dst;
116fbff949eSJiri Pirko };
117fbff949eSJiri Pirko 
118fbff949eSJiri Pirko /**
119c3f83241STom Herbert  * struct flow_dissector_key_ipv6_addrs:
120c3f83241STom Herbert  * @src: source ip address
121c3f83241STom Herbert  * @dst: destination ip address
122c3f83241STom Herbert  */
123c3f83241STom Herbert struct flow_dissector_key_ipv6_addrs {
124c3f83241STom Herbert 	/* (src,dst) must be grouped, in the same way than in IP header */
125c3f83241STom Herbert 	struct in6_addr src;
126c3f83241STom Herbert 	struct in6_addr dst;
127c3f83241STom Herbert };
128c3f83241STom Herbert 
129c3f83241STom Herbert /**
1308d6e79d3SJon Maloy  * struct flow_dissector_key_tipc:
1318d6e79d3SJon Maloy  * @key: source node address combined with selector
1329f249089STom Herbert  */
1338d6e79d3SJon Maloy struct flow_dissector_key_tipc {
1348d6e79d3SJon Maloy 	__be32 key;
1359f249089STom Herbert };
1369f249089STom Herbert 
1379f249089STom Herbert /**
138c3f83241STom Herbert  * struct flow_dissector_key_addrs:
139c3f83241STom Herbert  * @v4addrs: IPv4 addresses
140c3f83241STom Herbert  * @v6addrs: IPv6 addresses
1418c966a10SSimon Horman  * @tipckey: TIPC key
142c3f83241STom Herbert  */
143c3f83241STom Herbert struct flow_dissector_key_addrs {
144c3f83241STom Herbert 	union {
145c3f83241STom Herbert 		struct flow_dissector_key_ipv4_addrs v4addrs;
146c3f83241STom Herbert 		struct flow_dissector_key_ipv6_addrs v6addrs;
1478d6e79d3SJon Maloy 		struct flow_dissector_key_tipc tipckey;
148c3f83241STom Herbert 	};
149c3f83241STom Herbert };
150c3f83241STom Herbert 
151c3f83241STom Herbert /**
1528c966a10SSimon Horman  * struct flow_dissector_key_arp:
1538c966a10SSimon Horman  * @sip: Sender IP address
1548c966a10SSimon Horman  * @tip: Target IP address
1558c966a10SSimon Horman  * @op:  Operation
1568c966a10SSimon Horman  * @sha: Sender hardware address
1578c966a10SSimon Horman  * @tha: Target hardware address
15855733350SSimon Horman  */
15955733350SSimon Horman struct flow_dissector_key_arp {
16055733350SSimon Horman 	__u32 sip;
16155733350SSimon Horman 	__u32 tip;
16255733350SSimon Horman 	__u8 op;
16355733350SSimon Horman 	unsigned char sha[ETH_ALEN];
16455733350SSimon Horman 	unsigned char tha[ETH_ALEN];
16555733350SSimon Horman };
16655733350SSimon Horman 
16755733350SSimon Horman /**
1688c966a10SSimon Horman  * struct flow_dissector_key_ports:
169fbff949eSJiri Pirko  * @ports: port numbers of Transport header
1708c966a10SSimon Horman  * @src: source port number
1718c966a10SSimon Horman  * @dst: destination port number
172fbff949eSJiri Pirko  */
173fbff949eSJiri Pirko struct flow_dissector_key_ports {
174fbff949eSJiri Pirko 	union {
175fbff949eSJiri Pirko 		__be32 ports;
17659346afeSJiri Pirko 		struct {
17759346afeSJiri Pirko 			__be16 src;
17859346afeSJiri Pirko 			__be16 dst;
17959346afeSJiri Pirko 		};
180fbff949eSJiri Pirko 	};
181fbff949eSJiri Pirko };
182fbff949eSJiri Pirko 
183972d3876SSimon Horman /**
18483d85bb0SMaksym Glubokiy  * struct flow_dissector_key_ports_range
18583d85bb0SMaksym Glubokiy  * @tp: port number from packet
18683d85bb0SMaksym Glubokiy  * @tp_min: min port number in range
18783d85bb0SMaksym Glubokiy  * @tp_max: max port number in range
18883d85bb0SMaksym Glubokiy  */
18983d85bb0SMaksym Glubokiy struct flow_dissector_key_ports_range {
19083d85bb0SMaksym Glubokiy 	union {
19183d85bb0SMaksym Glubokiy 		struct flow_dissector_key_ports tp;
19283d85bb0SMaksym Glubokiy 		struct {
19383d85bb0SMaksym Glubokiy 			struct flow_dissector_key_ports tp_min;
19483d85bb0SMaksym Glubokiy 			struct flow_dissector_key_ports tp_max;
19583d85bb0SMaksym Glubokiy 		};
19683d85bb0SMaksym Glubokiy 	};
19783d85bb0SMaksym Glubokiy };
19883d85bb0SMaksym Glubokiy 
19983d85bb0SMaksym Glubokiy /**
2008c966a10SSimon Horman  * struct flow_dissector_key_icmp:
2018c966a10SSimon Horman  * @type: ICMP type
2028c966a10SSimon Horman  * @code: ICMP code
2038c966a10SSimon Horman  * @id:   Session identifier
204972d3876SSimon Horman  */
205972d3876SSimon Horman struct flow_dissector_key_icmp {
206972d3876SSimon Horman 	struct {
207972d3876SSimon Horman 		u8 type;
208972d3876SSimon Horman 		u8 code;
209972d3876SSimon Horman 	};
2105dec597eSMatteo Croce 	u16 id;
211972d3876SSimon Horman };
212b924933cSJiri Pirko 
21367a900ccSJiri Pirko /**
21467a900ccSJiri Pirko  * struct flow_dissector_key_eth_addrs:
21567a900ccSJiri Pirko  * @src: source Ethernet address
21667a900ccSJiri Pirko  * @dst: destination Ethernet address
21767a900ccSJiri Pirko  */
21867a900ccSJiri Pirko struct flow_dissector_key_eth_addrs {
21967a900ccSJiri Pirko 	/* (dst,src) must be grouped, in the same way than in ETH header */
22067a900ccSJiri Pirko 	unsigned char dst[ETH_ALEN];
22167a900ccSJiri Pirko 	unsigned char src[ETH_ALEN];
22267a900ccSJiri Pirko };
22367a900ccSJiri Pirko 
224ac4bb5deSJiri Pirko /**
225ac4bb5deSJiri Pirko  * struct flow_dissector_key_tcp:
226ac4bb5deSJiri Pirko  * @flags: flags
227ac4bb5deSJiri Pirko  */
228ac4bb5deSJiri Pirko struct flow_dissector_key_tcp {
229ac4bb5deSJiri Pirko 	__be16 flags;
230ac4bb5deSJiri Pirko };
231ac4bb5deSJiri Pirko 
232518d8a2eSOr Gerlitz /**
233518d8a2eSOr Gerlitz  * struct flow_dissector_key_ip:
234518d8a2eSOr Gerlitz  * @tos: tos
235518d8a2eSOr Gerlitz  * @ttl: ttl
236518d8a2eSOr Gerlitz  */
237518d8a2eSOr Gerlitz struct flow_dissector_key_ip {
238518d8a2eSOr Gerlitz 	__u8	tos;
239518d8a2eSOr Gerlitz 	__u8	ttl;
240518d8a2eSOr Gerlitz };
241518d8a2eSOr Gerlitz 
24282828b88SJiri Pirko /**
24382828b88SJiri Pirko  * struct flow_dissector_key_meta:
24482828b88SJiri Pirko  * @ingress_ifindex: ingress ifindex
2458819efc9SPablo Neira Ayuso  * @ingress_iftype: ingress interface type
246d5ccfd90SIdo Schimmel  * @l2_miss: packet did not match an L2 entry during forwarding
24782828b88SJiri Pirko  */
24882828b88SJiri Pirko struct flow_dissector_key_meta {
24982828b88SJiri Pirko 	int ingress_ifindex;
2508819efc9SPablo Neira Ayuso 	u16 ingress_iftype;
251d5ccfd90SIdo Schimmel 	u8 l2_miss;
25282828b88SJiri Pirko };
25382828b88SJiri Pirko 
25475a56758SPaul Blakey /**
25575a56758SPaul Blakey  * struct flow_dissector_key_ct:
25675a56758SPaul Blakey  * @ct_state: conntrack state after converting with map
25775a56758SPaul Blakey  * @ct_mark: conttrack mark
25875a56758SPaul Blakey  * @ct_zone: conntrack zone
25975a56758SPaul Blakey  * @ct_labels: conntrack labels
26075a56758SPaul Blakey  */
26175a56758SPaul Blakey struct flow_dissector_key_ct {
26275a56758SPaul Blakey 	u16	ct_state;
26375a56758SPaul Blakey 	u16	ct_zone;
26475a56758SPaul Blakey 	u32	ct_mark;
26575a56758SPaul Blakey 	u32	ct_labels[4];
26675a56758SPaul Blakey };
26775a56758SPaul Blakey 
2680cb09affSAriel Levkovich /**
2690cb09affSAriel Levkovich  * struct flow_dissector_key_hash:
2700cb09affSAriel Levkovich  * @hash: hash value
2710cb09affSAriel Levkovich  */
2720cb09affSAriel Levkovich struct flow_dissector_key_hash {
2730cb09affSAriel Levkovich 	u32 hash;
2740cb09affSAriel Levkovich };
2750cb09affSAriel Levkovich 
27634951fcfSBoris Sukholitko /**
27734951fcfSBoris Sukholitko  * struct flow_dissector_key_num_of_vlans:
27834951fcfSBoris Sukholitko  * @num_of_vlans: num_of_vlans value
27934951fcfSBoris Sukholitko  */
28034951fcfSBoris Sukholitko struct flow_dissector_key_num_of_vlans {
28134951fcfSBoris Sukholitko 	u8 num_of_vlans;
28234951fcfSBoris Sukholitko };
28334951fcfSBoris Sukholitko 
28446126db9SWojciech Drewek /**
28546126db9SWojciech Drewek  * struct flow_dissector_key_pppoe:
28646126db9SWojciech Drewek  * @session_id: pppoe session id
28746126db9SWojciech Drewek  * @ppp_proto: ppp protocol
28846126db9SWojciech Drewek  * @type: pppoe eth type
28946126db9SWojciech Drewek  */
29046126db9SWojciech Drewek struct flow_dissector_key_pppoe {
29146126db9SWojciech Drewek 	__be16 session_id;
29246126db9SWojciech Drewek 	__be16 ppp_proto;
29346126db9SWojciech Drewek 	__be16 type;
29446126db9SWojciech Drewek };
29546126db9SWojciech Drewek 
296dda2fa08SWojciech Drewek /**
297dda2fa08SWojciech Drewek  * struct flow_dissector_key_l2tpv3:
298dda2fa08SWojciech Drewek  * @session_id: identifier for a l2tp session
299dda2fa08SWojciech Drewek  */
300dda2fa08SWojciech Drewek struct flow_dissector_key_l2tpv3 {
301dda2fa08SWojciech Drewek 	__be32 session_id;
302dda2fa08SWojciech Drewek };
303dda2fa08SWojciech Drewek 
304*d7ad70b5SZahari Doychev /**
305*d7ad70b5SZahari Doychev  * struct flow_dissector_key_cfm
306*d7ad70b5SZahari Doychev  * @mdl_ver: maintenance domain level (mdl) and cfm protocol version
307*d7ad70b5SZahari Doychev  * @opcode: code specifying a type of cfm protocol packet
308*d7ad70b5SZahari Doychev  *
309*d7ad70b5SZahari Doychev  * See 802.1ag, ITU-T G.8013/Y.1731
310*d7ad70b5SZahari Doychev  *         1               2
311*d7ad70b5SZahari Doychev  * |7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|
312*d7ad70b5SZahari Doychev  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
313*d7ad70b5SZahari Doychev  * | mdl | version |     opcode    |
314*d7ad70b5SZahari Doychev  * +-----+---------+-+-+-+-+-+-+-+-+
315*d7ad70b5SZahari Doychev  */
316*d7ad70b5SZahari Doychev struct flow_dissector_key_cfm {
317*d7ad70b5SZahari Doychev 	u8	mdl_ver;
318*d7ad70b5SZahari Doychev 	u8	opcode;
319*d7ad70b5SZahari Doychev };
320*d7ad70b5SZahari Doychev 
321*d7ad70b5SZahari Doychev #define FLOW_DIS_CFM_MDL_MASK GENMASK(7, 5)
322*d7ad70b5SZahari Doychev #define FLOW_DIS_CFM_MDL_MAX 7
323*d7ad70b5SZahari Doychev 
324fbff949eSJiri Pirko enum flow_dissector_key_id {
32542aecaa9STom Herbert 	FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
326fbff949eSJiri Pirko 	FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
327c3f83241STom Herbert 	FLOW_DISSECTOR_KEY_IPV4_ADDRS, /* struct flow_dissector_key_ipv4_addrs */
328c3f83241STom Herbert 	FLOW_DISSECTOR_KEY_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */
329fbff949eSJiri Pirko 	FLOW_DISSECTOR_KEY_PORTS, /* struct flow_dissector_key_ports */
3308ffb055bSYoshiki Komachi 	FLOW_DISSECTOR_KEY_PORTS_RANGE, /* struct flow_dissector_key_ports */
331972d3876SSimon Horman 	FLOW_DISSECTOR_KEY_ICMP, /* struct flow_dissector_key_icmp */
33267a900ccSJiri Pirko 	FLOW_DISSECTOR_KEY_ETH_ADDRS, /* struct flow_dissector_key_eth_addrs */
3338d6e79d3SJon Maloy 	FLOW_DISSECTOR_KEY_TIPC, /* struct flow_dissector_key_tipc */
33455733350SSimon Horman 	FLOW_DISSECTOR_KEY_ARP, /* struct flow_dissector_key_arp */
33591c45956SEdward Cree 	FLOW_DISSECTOR_KEY_VLAN, /* struct flow_dissector_key_vlan */
33691c45956SEdward Cree 	FLOW_DISSECTOR_KEY_FLOW_LABEL, /* struct flow_dissector_key_tags */
3371fdd512cSTom Herbert 	FLOW_DISSECTOR_KEY_GRE_KEYID, /* struct flow_dissector_key_keyid */
338b3baa0fbSTom Herbert 	FLOW_DISSECTOR_KEY_MPLS_ENTROPY, /* struct flow_dissector_key_keyid */
3399ba6a9a9SHadar Hen Zion 	FLOW_DISSECTOR_KEY_ENC_KEYID, /* struct flow_dissector_key_keyid */
3409ba6a9a9SHadar Hen Zion 	FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS, /* struct flow_dissector_key_ipv4_addrs */
3419ba6a9a9SHadar Hen Zion 	FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */
3429ba6a9a9SHadar Hen Zion 	FLOW_DISSECTOR_KEY_ENC_CONTROL, /* struct flow_dissector_key_control */
343f4d997fdSHadar Hen Zion 	FLOW_DISSECTOR_KEY_ENC_PORTS, /* struct flow_dissector_key_ports */
344029c1ecbSBenjamin LaHaise 	FLOW_DISSECTOR_KEY_MPLS, /* struct flow_dissector_key_mpls */
345ac4bb5deSJiri Pirko 	FLOW_DISSECTOR_KEY_TCP, /* struct flow_dissector_key_tcp */
346518d8a2eSOr Gerlitz 	FLOW_DISSECTOR_KEY_IP, /* struct flow_dissector_key_ip */
34791c45956SEdward Cree 	FLOW_DISSECTOR_KEY_CVLAN, /* struct flow_dissector_key_vlan */
3485544adb9SOr Gerlitz 	FLOW_DISSECTOR_KEY_ENC_IP, /* struct flow_dissector_key_ip */
34992e2c405SSimon Horman 	FLOW_DISSECTOR_KEY_ENC_OPTS, /* struct flow_dissector_key_enc_opts */
35082828b88SJiri Pirko 	FLOW_DISSECTOR_KEY_META, /* struct flow_dissector_key_meta */
35175a56758SPaul Blakey 	FLOW_DISSECTOR_KEY_CT, /* struct flow_dissector_key_ct */
3520cb09affSAriel Levkovich 	FLOW_DISSECTOR_KEY_HASH, /* struct flow_dissector_key_hash */
35334951fcfSBoris Sukholitko 	FLOW_DISSECTOR_KEY_NUM_OF_VLANS, /* struct flow_dissector_key_num_of_vlans */
35446126db9SWojciech Drewek 	FLOW_DISSECTOR_KEY_PPPOE, /* struct flow_dissector_key_pppoe */
355dda2fa08SWojciech Drewek 	FLOW_DISSECTOR_KEY_L2TPV3, /* struct flow_dissector_key_l2tpv3 */
356*d7ad70b5SZahari Doychev 	FLOW_DISSECTOR_KEY_CFM, /* struct flow_dissector_key_cfm */
35792e2c405SSimon Horman 
358fbff949eSJiri Pirko 	FLOW_DISSECTOR_KEY_MAX,
359fbff949eSJiri Pirko };
360fbff949eSJiri Pirko 
361807e165dSTom Herbert #define FLOW_DISSECTOR_F_PARSE_1ST_FRAG		BIT(0)
3621cc26450SStanislav Fomichev #define FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL	BIT(1)
3631cc26450SStanislav Fomichev #define FLOW_DISSECTOR_F_STOP_AT_ENCAP		BIT(2)
3646de6e46dSYoshiki Komachi #define FLOW_DISSECTOR_F_STOP_BEFORE_ENCAP	BIT(3)
365807e165dSTom Herbert 
366fbff949eSJiri Pirko struct flow_dissector_key {
367fbff949eSJiri Pirko 	enum flow_dissector_key_id key_id;
368fbff949eSJiri Pirko 	size_t offset; /* offset of struct flow_dissector_key_*
369fbff949eSJiri Pirko 			  in target the struct */
370fbff949eSJiri Pirko };
371fbff949eSJiri Pirko 
372fbff949eSJiri Pirko struct flow_dissector {
373fbff949eSJiri Pirko 	unsigned int used_keys; /* each bit repesents presence of one key id */
374fbff949eSJiri Pirko 	unsigned short int offset[FLOW_DISSECTOR_KEY_MAX];
375fbff949eSJiri Pirko };
376fbff949eSJiri Pirko 
37772a338bcSPaolo Abeni struct flow_keys_basic {
37872a338bcSPaolo Abeni 	struct flow_dissector_key_control control;
37972a338bcSPaolo Abeni 	struct flow_dissector_key_basic basic;
38072a338bcSPaolo Abeni };
38172a338bcSPaolo Abeni 
38206635a35SJiri Pirko struct flow_keys {
38342aecaa9STom Herbert 	struct flow_dissector_key_control control;
38442aecaa9STom Herbert #define FLOW_KEYS_HASH_START_FIELD basic
38555667441SEric Dumazet 	struct flow_dissector_key_basic basic __aligned(SIPHASH_ALIGNMENT);
386d34af823STom Herbert 	struct flow_dissector_key_tags tags;
387f6a66927SHadar Hen Zion 	struct flow_dissector_key_vlan vlan;
38824c590e3SJianbo Liu 	struct flow_dissector_key_vlan cvlan;
3891fdd512cSTom Herbert 	struct flow_dissector_key_keyid keyid;
39042aecaa9STom Herbert 	struct flow_dissector_key_ports ports;
3915dec597eSMatteo Croce 	struct flow_dissector_key_icmp icmp;
39298298e6cSMatteo Croce 	/* 'addrs' must be the last member */
39342aecaa9STom Herbert 	struct flow_dissector_key_addrs addrs;
39406635a35SJiri Pirko };
39506635a35SJiri Pirko 
39642aecaa9STom Herbert #define FLOW_KEYS_HASH_OFFSET		\
39742aecaa9STom Herbert 	offsetof(struct flow_keys, FLOW_KEYS_HASH_START_FIELD)
39842aecaa9STom Herbert 
399c3f83241STom Herbert __be32 flow_get_u32_src(const struct flow_keys *flow);
400c3f83241STom Herbert __be32 flow_get_u32_dst(const struct flow_keys *flow);
401c3f83241STom Herbert 
40206635a35SJiri Pirko extern struct flow_dissector flow_keys_dissector;
40372a338bcSPaolo Abeni extern struct flow_dissector flow_keys_basic_dissector;
40406635a35SJiri Pirko 
4051bd758ebSJiri Pirko /* struct flow_keys_digest:
4061bd758ebSJiri Pirko  *
4071bd758ebSJiri Pirko  * This structure is used to hold a digest of the full flow keys. This is a
4081bd758ebSJiri Pirko  * larger "hash" of a flow to allow definitively matching specific flows where
4091bd758ebSJiri Pirko  * the 32 bit skb->hash is not large enough. The size is limited to 16 bytes so
41053bc017fSWolfram Sang  * that it can be used in CB of skb (see sch_choke for an example).
4111bd758ebSJiri Pirko  */
4121bd758ebSJiri Pirko #define FLOW_KEYS_DIGEST_LEN	16
4131bd758ebSJiri Pirko struct flow_keys_digest {
4141bd758ebSJiri Pirko 	u8	data[FLOW_KEYS_DIGEST_LEN];
4151bd758ebSJiri Pirko };
4161bd758ebSJiri Pirko 
4171bd758ebSJiri Pirko void make_flow_keys_digest(struct flow_keys_digest *digest,
4181bd758ebSJiri Pirko 			   const struct flow_keys *flow);
4191bd758ebSJiri Pirko 
42066fdd05eSGao Feng static inline bool flow_keys_have_l4(const struct flow_keys *keys)
421bcc83839STom Herbert {
422bcc83839STom Herbert 	return (keys->ports.ports || keys->tags.flow_label);
423bcc83839STom Herbert }
424bcc83839STom Herbert 
425c6cc1ca7STom Herbert u32 flow_hash_from_keys(struct flow_keys *keys);
4265dec597eSMatteo Croce void skb_flow_get_icmp_tci(const struct sk_buff *skb,
4275dec597eSMatteo Croce 			   struct flow_dissector_key_icmp *key_icmp,
428f96533cdSAlexander Lobakin 			   const void *data, int thoff, int hlen);
429c6cc1ca7STom Herbert 
4308de2d793SAmir Vadai static inline bool dissector_uses_key(const struct flow_dissector *flow_dissector,
4318de2d793SAmir Vadai 				      enum flow_dissector_key_id key_id)
4328de2d793SAmir Vadai {
4338de2d793SAmir Vadai 	return flow_dissector->used_keys & (1 << key_id);
4348de2d793SAmir Vadai }
4358de2d793SAmir Vadai 
4368de2d793SAmir Vadai static inline void *skb_flow_dissector_target(struct flow_dissector *flow_dissector,
4378de2d793SAmir Vadai 					      enum flow_dissector_key_id key_id,
4388de2d793SAmir Vadai 					      void *target_container)
4398de2d793SAmir Vadai {
4408de2d793SAmir Vadai 	return ((char *)target_container) + flow_dissector->offset[key_id];
4418de2d793SAmir Vadai }
4428de2d793SAmir Vadai 
443089b19a9SStanislav Fomichev struct bpf_flow_dissector {
444089b19a9SStanislav Fomichev 	struct bpf_flow_keys	*flow_keys;
445089b19a9SStanislav Fomichev 	const struct sk_buff	*skb;
446dac06b32SAlexander Lobakin 	const void		*data;
447dac06b32SAlexander Lobakin 	const void		*data_end;
448089b19a9SStanislav Fomichev };
449089b19a9SStanislav Fomichev 
4508a9093c7SJason Baron static inline void
4518a9093c7SJason Baron flow_dissector_init_keys(struct flow_dissector_key_control *key_control,
4528a9093c7SJason Baron 			 struct flow_dissector_key_basic *key_basic)
4538a9093c7SJason Baron {
4548a9093c7SJason Baron 	memset(key_control, 0, sizeof(*key_control));
4558a9093c7SJason Baron 	memset(key_basic, 0, sizeof(*key_basic));
4568a9093c7SJason Baron }
4578a9093c7SJason Baron 
458b27f7bb5SJakub Sitnicki #ifdef CONFIG_BPF_SYSCALL
4593b701699SJakub Sitnicki int flow_dissector_bpf_prog_attach_check(struct net *net,
4603b701699SJakub Sitnicki 					 struct bpf_prog *prog);
461b27f7bb5SJakub Sitnicki #endif /* CONFIG_BPF_SYSCALL */
462b27f7bb5SJakub Sitnicki 
4631bd758ebSJiri Pirko #endif
464