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