xref: /openbmc/linux/include/net/flow_dissector.h (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
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 
dissector_set_mpls_lse(struct flow_dissector_key_mpls * mpls,int lse_index)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 
304d7ad70b5SZahari Doychev /**
305*a57c34a8SRatheesh Kannoth  * struct flow_dissector_key_ipsec:
306*a57c34a8SRatheesh Kannoth  * @spi: identifier for a ipsec connection
307*a57c34a8SRatheesh Kannoth  */
308*a57c34a8SRatheesh Kannoth struct flow_dissector_key_ipsec {
309*a57c34a8SRatheesh Kannoth 	__be32 spi;
310*a57c34a8SRatheesh Kannoth };
311*a57c34a8SRatheesh Kannoth 
312*a57c34a8SRatheesh Kannoth /**
313d7ad70b5SZahari Doychev  * struct flow_dissector_key_cfm
314d7ad70b5SZahari Doychev  * @mdl_ver: maintenance domain level (mdl) and cfm protocol version
315d7ad70b5SZahari Doychev  * @opcode: code specifying a type of cfm protocol packet
316d7ad70b5SZahari Doychev  *
317d7ad70b5SZahari Doychev  * See 802.1ag, ITU-T G.8013/Y.1731
318d7ad70b5SZahari Doychev  *         1               2
319d7ad70b5SZahari Doychev  * |7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|
320d7ad70b5SZahari Doychev  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
321d7ad70b5SZahari Doychev  * | mdl | version |     opcode    |
322d7ad70b5SZahari Doychev  * +-----+---------+-+-+-+-+-+-+-+-+
323d7ad70b5SZahari Doychev  */
324d7ad70b5SZahari Doychev struct flow_dissector_key_cfm {
325d7ad70b5SZahari Doychev 	u8	mdl_ver;
326d7ad70b5SZahari Doychev 	u8	opcode;
327d7ad70b5SZahari Doychev };
328d7ad70b5SZahari Doychev 
329d7ad70b5SZahari Doychev #define FLOW_DIS_CFM_MDL_MASK GENMASK(7, 5)
330d7ad70b5SZahari Doychev #define FLOW_DIS_CFM_MDL_MAX 7
331d7ad70b5SZahari Doychev 
332fbff949eSJiri Pirko enum flow_dissector_key_id {
33342aecaa9STom Herbert 	FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
334fbff949eSJiri Pirko 	FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
335c3f83241STom Herbert 	FLOW_DISSECTOR_KEY_IPV4_ADDRS, /* struct flow_dissector_key_ipv4_addrs */
336c3f83241STom Herbert 	FLOW_DISSECTOR_KEY_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */
337fbff949eSJiri Pirko 	FLOW_DISSECTOR_KEY_PORTS, /* struct flow_dissector_key_ports */
3388ffb055bSYoshiki Komachi 	FLOW_DISSECTOR_KEY_PORTS_RANGE, /* struct flow_dissector_key_ports */
339972d3876SSimon Horman 	FLOW_DISSECTOR_KEY_ICMP, /* struct flow_dissector_key_icmp */
34067a900ccSJiri Pirko 	FLOW_DISSECTOR_KEY_ETH_ADDRS, /* struct flow_dissector_key_eth_addrs */
3418d6e79d3SJon Maloy 	FLOW_DISSECTOR_KEY_TIPC, /* struct flow_dissector_key_tipc */
34255733350SSimon Horman 	FLOW_DISSECTOR_KEY_ARP, /* struct flow_dissector_key_arp */
34391c45956SEdward Cree 	FLOW_DISSECTOR_KEY_VLAN, /* struct flow_dissector_key_vlan */
34491c45956SEdward Cree 	FLOW_DISSECTOR_KEY_FLOW_LABEL, /* struct flow_dissector_key_tags */
3451fdd512cSTom Herbert 	FLOW_DISSECTOR_KEY_GRE_KEYID, /* struct flow_dissector_key_keyid */
346b3baa0fbSTom Herbert 	FLOW_DISSECTOR_KEY_MPLS_ENTROPY, /* struct flow_dissector_key_keyid */
3479ba6a9a9SHadar Hen Zion 	FLOW_DISSECTOR_KEY_ENC_KEYID, /* struct flow_dissector_key_keyid */
3489ba6a9a9SHadar Hen Zion 	FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS, /* struct flow_dissector_key_ipv4_addrs */
3499ba6a9a9SHadar Hen Zion 	FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */
3509ba6a9a9SHadar Hen Zion 	FLOW_DISSECTOR_KEY_ENC_CONTROL, /* struct flow_dissector_key_control */
351f4d997fdSHadar Hen Zion 	FLOW_DISSECTOR_KEY_ENC_PORTS, /* struct flow_dissector_key_ports */
352029c1ecbSBenjamin LaHaise 	FLOW_DISSECTOR_KEY_MPLS, /* struct flow_dissector_key_mpls */
353ac4bb5deSJiri Pirko 	FLOW_DISSECTOR_KEY_TCP, /* struct flow_dissector_key_tcp */
354518d8a2eSOr Gerlitz 	FLOW_DISSECTOR_KEY_IP, /* struct flow_dissector_key_ip */
35591c45956SEdward Cree 	FLOW_DISSECTOR_KEY_CVLAN, /* struct flow_dissector_key_vlan */
3565544adb9SOr Gerlitz 	FLOW_DISSECTOR_KEY_ENC_IP, /* struct flow_dissector_key_ip */
35792e2c405SSimon Horman 	FLOW_DISSECTOR_KEY_ENC_OPTS, /* struct flow_dissector_key_enc_opts */
35882828b88SJiri Pirko 	FLOW_DISSECTOR_KEY_META, /* struct flow_dissector_key_meta */
35975a56758SPaul Blakey 	FLOW_DISSECTOR_KEY_CT, /* struct flow_dissector_key_ct */
3600cb09affSAriel Levkovich 	FLOW_DISSECTOR_KEY_HASH, /* struct flow_dissector_key_hash */
36134951fcfSBoris Sukholitko 	FLOW_DISSECTOR_KEY_NUM_OF_VLANS, /* struct flow_dissector_key_num_of_vlans */
36246126db9SWojciech Drewek 	FLOW_DISSECTOR_KEY_PPPOE, /* struct flow_dissector_key_pppoe */
363dda2fa08SWojciech Drewek 	FLOW_DISSECTOR_KEY_L2TPV3, /* struct flow_dissector_key_l2tpv3 */
364d7ad70b5SZahari Doychev 	FLOW_DISSECTOR_KEY_CFM, /* struct flow_dissector_key_cfm */
365*a57c34a8SRatheesh Kannoth 	FLOW_DISSECTOR_KEY_IPSEC, /* struct flow_dissector_key_ipsec */
36692e2c405SSimon Horman 
367fbff949eSJiri Pirko 	FLOW_DISSECTOR_KEY_MAX,
368fbff949eSJiri Pirko };
369fbff949eSJiri Pirko 
370807e165dSTom Herbert #define FLOW_DISSECTOR_F_PARSE_1ST_FRAG		BIT(0)
3711cc26450SStanislav Fomichev #define FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL	BIT(1)
3721cc26450SStanislav Fomichev #define FLOW_DISSECTOR_F_STOP_AT_ENCAP		BIT(2)
3736de6e46dSYoshiki Komachi #define FLOW_DISSECTOR_F_STOP_BEFORE_ENCAP	BIT(3)
374807e165dSTom Herbert 
375fbff949eSJiri Pirko struct flow_dissector_key {
376fbff949eSJiri Pirko 	enum flow_dissector_key_id key_id;
377fbff949eSJiri Pirko 	size_t offset; /* offset of struct flow_dissector_key_*
378fbff949eSJiri Pirko 			  in target the struct */
379fbff949eSJiri Pirko };
380fbff949eSJiri Pirko 
381fbff949eSJiri Pirko struct flow_dissector {
3822b3082c6SRatheesh Kannoth 	unsigned long long  used_keys;
3832b3082c6SRatheesh Kannoth 		/* each bit represents presence of one key id */
384fbff949eSJiri Pirko 	unsigned short int offset[FLOW_DISSECTOR_KEY_MAX];
385fbff949eSJiri Pirko };
386fbff949eSJiri Pirko 
38772a338bcSPaolo Abeni struct flow_keys_basic {
38872a338bcSPaolo Abeni 	struct flow_dissector_key_control control;
38972a338bcSPaolo Abeni 	struct flow_dissector_key_basic basic;
39072a338bcSPaolo Abeni };
39172a338bcSPaolo Abeni 
39206635a35SJiri Pirko struct flow_keys {
39342aecaa9STom Herbert 	struct flow_dissector_key_control control;
39442aecaa9STom Herbert #define FLOW_KEYS_HASH_START_FIELD basic
39555667441SEric Dumazet 	struct flow_dissector_key_basic basic __aligned(SIPHASH_ALIGNMENT);
396d34af823STom Herbert 	struct flow_dissector_key_tags tags;
397f6a66927SHadar Hen Zion 	struct flow_dissector_key_vlan vlan;
39824c590e3SJianbo Liu 	struct flow_dissector_key_vlan cvlan;
3991fdd512cSTom Herbert 	struct flow_dissector_key_keyid keyid;
40042aecaa9STom Herbert 	struct flow_dissector_key_ports ports;
4015dec597eSMatteo Croce 	struct flow_dissector_key_icmp icmp;
40298298e6cSMatteo Croce 	/* 'addrs' must be the last member */
40342aecaa9STom Herbert 	struct flow_dissector_key_addrs addrs;
40406635a35SJiri Pirko };
40506635a35SJiri Pirko 
40642aecaa9STom Herbert #define FLOW_KEYS_HASH_OFFSET		\
40742aecaa9STom Herbert 	offsetof(struct flow_keys, FLOW_KEYS_HASH_START_FIELD)
40842aecaa9STom Herbert 
409c3f83241STom Herbert __be32 flow_get_u32_src(const struct flow_keys *flow);
410c3f83241STom Herbert __be32 flow_get_u32_dst(const struct flow_keys *flow);
411c3f83241STom Herbert 
41206635a35SJiri Pirko extern struct flow_dissector flow_keys_dissector;
41372a338bcSPaolo Abeni extern struct flow_dissector flow_keys_basic_dissector;
41406635a35SJiri Pirko 
4151bd758ebSJiri Pirko /* struct flow_keys_digest:
4161bd758ebSJiri Pirko  *
4171bd758ebSJiri Pirko  * This structure is used to hold a digest of the full flow keys. This is a
4181bd758ebSJiri Pirko  * larger "hash" of a flow to allow definitively matching specific flows where
4191bd758ebSJiri Pirko  * the 32 bit skb->hash is not large enough. The size is limited to 16 bytes so
42053bc017fSWolfram Sang  * that it can be used in CB of skb (see sch_choke for an example).
4211bd758ebSJiri Pirko  */
4221bd758ebSJiri Pirko #define FLOW_KEYS_DIGEST_LEN	16
4231bd758ebSJiri Pirko struct flow_keys_digest {
4241bd758ebSJiri Pirko 	u8	data[FLOW_KEYS_DIGEST_LEN];
4251bd758ebSJiri Pirko };
4261bd758ebSJiri Pirko 
4271bd758ebSJiri Pirko void make_flow_keys_digest(struct flow_keys_digest *digest,
4281bd758ebSJiri Pirko 			   const struct flow_keys *flow);
4291bd758ebSJiri Pirko 
flow_keys_have_l4(const struct flow_keys * keys)43066fdd05eSGao Feng static inline bool flow_keys_have_l4(const struct flow_keys *keys)
431bcc83839STom Herbert {
432bcc83839STom Herbert 	return (keys->ports.ports || keys->tags.flow_label);
433bcc83839STom Herbert }
434bcc83839STom Herbert 
435c6cc1ca7STom Herbert u32 flow_hash_from_keys(struct flow_keys *keys);
4365dec597eSMatteo Croce void skb_flow_get_icmp_tci(const struct sk_buff *skb,
4375dec597eSMatteo Croce 			   struct flow_dissector_key_icmp *key_icmp,
438f96533cdSAlexander Lobakin 			   const void *data, int thoff, int hlen);
439c6cc1ca7STom Herbert 
dissector_uses_key(const struct flow_dissector * flow_dissector,enum flow_dissector_key_id key_id)4408de2d793SAmir Vadai static inline bool dissector_uses_key(const struct flow_dissector *flow_dissector,
4418de2d793SAmir Vadai 				      enum flow_dissector_key_id key_id)
4428de2d793SAmir Vadai {
4432b3082c6SRatheesh Kannoth 	return flow_dissector->used_keys & (1ULL << key_id);
4448de2d793SAmir Vadai }
4458de2d793SAmir Vadai 
skb_flow_dissector_target(struct flow_dissector * flow_dissector,enum flow_dissector_key_id key_id,void * target_container)4468de2d793SAmir Vadai static inline void *skb_flow_dissector_target(struct flow_dissector *flow_dissector,
4478de2d793SAmir Vadai 					      enum flow_dissector_key_id key_id,
4488de2d793SAmir Vadai 					      void *target_container)
4498de2d793SAmir Vadai {
4508de2d793SAmir Vadai 	return ((char *)target_container) + flow_dissector->offset[key_id];
4518de2d793SAmir Vadai }
4528de2d793SAmir Vadai 
453089b19a9SStanislav Fomichev struct bpf_flow_dissector {
454089b19a9SStanislav Fomichev 	struct bpf_flow_keys	*flow_keys;
455089b19a9SStanislav Fomichev 	const struct sk_buff	*skb;
456dac06b32SAlexander Lobakin 	const void		*data;
457dac06b32SAlexander Lobakin 	const void		*data_end;
458089b19a9SStanislav Fomichev };
459089b19a9SStanislav Fomichev 
4608a9093c7SJason Baron static inline void
flow_dissector_init_keys(struct flow_dissector_key_control * key_control,struct flow_dissector_key_basic * key_basic)4618a9093c7SJason Baron flow_dissector_init_keys(struct flow_dissector_key_control *key_control,
4628a9093c7SJason Baron 			 struct flow_dissector_key_basic *key_basic)
4638a9093c7SJason Baron {
4648a9093c7SJason Baron 	memset(key_control, 0, sizeof(*key_control));
4658a9093c7SJason Baron 	memset(key_basic, 0, sizeof(*key_basic));
4668a9093c7SJason Baron }
4678a9093c7SJason Baron 
468b27f7bb5SJakub Sitnicki #ifdef CONFIG_BPF_SYSCALL
4693b701699SJakub Sitnicki int flow_dissector_bpf_prog_attach_check(struct net *net,
4703b701699SJakub Sitnicki 					 struct bpf_prog *prog);
471b27f7bb5SJakub Sitnicki #endif /* CONFIG_BPF_SYSCALL */
472b27f7bb5SJakub Sitnicki 
4731bd758ebSJiri Pirko #endif
474