162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef _NET_FLOW_DISSECTOR_H
362306a36Sopenharmony_ci#define _NET_FLOW_DISSECTOR_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <linux/types.h>
662306a36Sopenharmony_ci#include <linux/in6.h>
762306a36Sopenharmony_ci#include <linux/siphash.h>
862306a36Sopenharmony_ci#include <linux/string.h>
962306a36Sopenharmony_ci#include <uapi/linux/if_ether.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_cistruct bpf_prog;
1262306a36Sopenharmony_cistruct net;
1362306a36Sopenharmony_cistruct sk_buff;
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci/**
1662306a36Sopenharmony_ci * struct flow_dissector_key_control:
1762306a36Sopenharmony_ci * @thoff:     Transport header offset
1862306a36Sopenharmony_ci * @addr_type: Type of key. One of FLOW_DISSECTOR_KEY_*
1962306a36Sopenharmony_ci * @flags:     Key flags. Any of FLOW_DIS_(IS_FRAGMENT|FIRST_FRAGENCAPSULATION)
2062306a36Sopenharmony_ci */
2162306a36Sopenharmony_cistruct flow_dissector_key_control {
2262306a36Sopenharmony_ci	u16	thoff;
2362306a36Sopenharmony_ci	u16	addr_type;
2462306a36Sopenharmony_ci	u32	flags;
2562306a36Sopenharmony_ci};
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci#define FLOW_DIS_IS_FRAGMENT	BIT(0)
2862306a36Sopenharmony_ci#define FLOW_DIS_FIRST_FRAG	BIT(1)
2962306a36Sopenharmony_ci#define FLOW_DIS_ENCAPSULATION	BIT(2)
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_cienum flow_dissect_ret {
3262306a36Sopenharmony_ci	FLOW_DISSECT_RET_OUT_GOOD,
3362306a36Sopenharmony_ci	FLOW_DISSECT_RET_OUT_BAD,
3462306a36Sopenharmony_ci	FLOW_DISSECT_RET_PROTO_AGAIN,
3562306a36Sopenharmony_ci	FLOW_DISSECT_RET_IPPROTO_AGAIN,
3662306a36Sopenharmony_ci	FLOW_DISSECT_RET_CONTINUE,
3762306a36Sopenharmony_ci};
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci/**
4062306a36Sopenharmony_ci * struct flow_dissector_key_basic:
4162306a36Sopenharmony_ci * @n_proto:  Network header protocol (eg. IPv4/IPv6)
4262306a36Sopenharmony_ci * @ip_proto: Transport header protocol (eg. TCP/UDP)
4362306a36Sopenharmony_ci * @padding:  Unused
4462306a36Sopenharmony_ci */
4562306a36Sopenharmony_cistruct flow_dissector_key_basic {
4662306a36Sopenharmony_ci	__be16	n_proto;
4762306a36Sopenharmony_ci	u8	ip_proto;
4862306a36Sopenharmony_ci	u8	padding;
4962306a36Sopenharmony_ci};
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_cistruct flow_dissector_key_tags {
5262306a36Sopenharmony_ci	u32	flow_label;
5362306a36Sopenharmony_ci};
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_cistruct flow_dissector_key_vlan {
5662306a36Sopenharmony_ci	union {
5762306a36Sopenharmony_ci		struct {
5862306a36Sopenharmony_ci			u16	vlan_id:12,
5962306a36Sopenharmony_ci				vlan_dei:1,
6062306a36Sopenharmony_ci				vlan_priority:3;
6162306a36Sopenharmony_ci		};
6262306a36Sopenharmony_ci		__be16	vlan_tci;
6362306a36Sopenharmony_ci	};
6462306a36Sopenharmony_ci	__be16	vlan_tpid;
6562306a36Sopenharmony_ci	__be16	vlan_eth_type;
6662306a36Sopenharmony_ci	u16	padding;
6762306a36Sopenharmony_ci};
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_cistruct flow_dissector_mpls_lse {
7062306a36Sopenharmony_ci	u32	mpls_ttl:8,
7162306a36Sopenharmony_ci		mpls_bos:1,
7262306a36Sopenharmony_ci		mpls_tc:3,
7362306a36Sopenharmony_ci		mpls_label:20;
7462306a36Sopenharmony_ci};
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci#define FLOW_DIS_MPLS_MAX 7
7762306a36Sopenharmony_cistruct flow_dissector_key_mpls {
7862306a36Sopenharmony_ci	struct flow_dissector_mpls_lse ls[FLOW_DIS_MPLS_MAX]; /* Label Stack */
7962306a36Sopenharmony_ci	u8 used_lses; /* One bit set for each Label Stack Entry in use */
8062306a36Sopenharmony_ci};
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_cistatic inline void dissector_set_mpls_lse(struct flow_dissector_key_mpls *mpls,
8362306a36Sopenharmony_ci					  int lse_index)
8462306a36Sopenharmony_ci{
8562306a36Sopenharmony_ci	mpls->used_lses |= 1 << lse_index;
8662306a36Sopenharmony_ci}
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci#define FLOW_DIS_TUN_OPTS_MAX 255
8962306a36Sopenharmony_ci/**
9062306a36Sopenharmony_ci * struct flow_dissector_key_enc_opts:
9162306a36Sopenharmony_ci * @data: tunnel option data
9262306a36Sopenharmony_ci * @len: length of tunnel option data
9362306a36Sopenharmony_ci * @dst_opt_type: tunnel option type
9462306a36Sopenharmony_ci */
9562306a36Sopenharmony_cistruct flow_dissector_key_enc_opts {
9662306a36Sopenharmony_ci	u8 data[FLOW_DIS_TUN_OPTS_MAX];	/* Using IP_TUNNEL_OPTS_MAX is desired
9762306a36Sopenharmony_ci					 * here but seems difficult to #include
9862306a36Sopenharmony_ci					 */
9962306a36Sopenharmony_ci	u8 len;
10062306a36Sopenharmony_ci	__be16 dst_opt_type;
10162306a36Sopenharmony_ci};
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_cistruct flow_dissector_key_keyid {
10462306a36Sopenharmony_ci	__be32	keyid;
10562306a36Sopenharmony_ci};
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci/**
10862306a36Sopenharmony_ci * struct flow_dissector_key_ipv4_addrs:
10962306a36Sopenharmony_ci * @src: source ip address
11062306a36Sopenharmony_ci * @dst: destination ip address
11162306a36Sopenharmony_ci */
11262306a36Sopenharmony_cistruct flow_dissector_key_ipv4_addrs {
11362306a36Sopenharmony_ci	/* (src,dst) must be grouped, in the same way than in IP header */
11462306a36Sopenharmony_ci	__be32 src;
11562306a36Sopenharmony_ci	__be32 dst;
11662306a36Sopenharmony_ci};
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci/**
11962306a36Sopenharmony_ci * struct flow_dissector_key_ipv6_addrs:
12062306a36Sopenharmony_ci * @src: source ip address
12162306a36Sopenharmony_ci * @dst: destination ip address
12262306a36Sopenharmony_ci */
12362306a36Sopenharmony_cistruct flow_dissector_key_ipv6_addrs {
12462306a36Sopenharmony_ci	/* (src,dst) must be grouped, in the same way than in IP header */
12562306a36Sopenharmony_ci	struct in6_addr src;
12662306a36Sopenharmony_ci	struct in6_addr dst;
12762306a36Sopenharmony_ci};
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci/**
13062306a36Sopenharmony_ci * struct flow_dissector_key_tipc:
13162306a36Sopenharmony_ci * @key: source node address combined with selector
13262306a36Sopenharmony_ci */
13362306a36Sopenharmony_cistruct flow_dissector_key_tipc {
13462306a36Sopenharmony_ci	__be32 key;
13562306a36Sopenharmony_ci};
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci/**
13862306a36Sopenharmony_ci * struct flow_dissector_key_addrs:
13962306a36Sopenharmony_ci * @v4addrs: IPv4 addresses
14062306a36Sopenharmony_ci * @v6addrs: IPv6 addresses
14162306a36Sopenharmony_ci * @tipckey: TIPC key
14262306a36Sopenharmony_ci */
14362306a36Sopenharmony_cistruct flow_dissector_key_addrs {
14462306a36Sopenharmony_ci	union {
14562306a36Sopenharmony_ci		struct flow_dissector_key_ipv4_addrs v4addrs;
14662306a36Sopenharmony_ci		struct flow_dissector_key_ipv6_addrs v6addrs;
14762306a36Sopenharmony_ci		struct flow_dissector_key_tipc tipckey;
14862306a36Sopenharmony_ci	};
14962306a36Sopenharmony_ci};
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci/**
15262306a36Sopenharmony_ci * struct flow_dissector_key_arp:
15362306a36Sopenharmony_ci * @sip: Sender IP address
15462306a36Sopenharmony_ci * @tip: Target IP address
15562306a36Sopenharmony_ci * @op:  Operation
15662306a36Sopenharmony_ci * @sha: Sender hardware address
15762306a36Sopenharmony_ci * @tha: Target hardware address
15862306a36Sopenharmony_ci */
15962306a36Sopenharmony_cistruct flow_dissector_key_arp {
16062306a36Sopenharmony_ci	__u32 sip;
16162306a36Sopenharmony_ci	__u32 tip;
16262306a36Sopenharmony_ci	__u8 op;
16362306a36Sopenharmony_ci	unsigned char sha[ETH_ALEN];
16462306a36Sopenharmony_ci	unsigned char tha[ETH_ALEN];
16562306a36Sopenharmony_ci};
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_ci/**
16862306a36Sopenharmony_ci * struct flow_dissector_key_ports:
16962306a36Sopenharmony_ci * @ports: port numbers of Transport header
17062306a36Sopenharmony_ci * @src: source port number
17162306a36Sopenharmony_ci * @dst: destination port number
17262306a36Sopenharmony_ci */
17362306a36Sopenharmony_cistruct flow_dissector_key_ports {
17462306a36Sopenharmony_ci	union {
17562306a36Sopenharmony_ci		__be32 ports;
17662306a36Sopenharmony_ci		struct {
17762306a36Sopenharmony_ci			__be16 src;
17862306a36Sopenharmony_ci			__be16 dst;
17962306a36Sopenharmony_ci		};
18062306a36Sopenharmony_ci	};
18162306a36Sopenharmony_ci};
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci/**
18462306a36Sopenharmony_ci * struct flow_dissector_key_ports_range
18562306a36Sopenharmony_ci * @tp: port number from packet
18662306a36Sopenharmony_ci * @tp_min: min port number in range
18762306a36Sopenharmony_ci * @tp_max: max port number in range
18862306a36Sopenharmony_ci */
18962306a36Sopenharmony_cistruct flow_dissector_key_ports_range {
19062306a36Sopenharmony_ci	union {
19162306a36Sopenharmony_ci		struct flow_dissector_key_ports tp;
19262306a36Sopenharmony_ci		struct {
19362306a36Sopenharmony_ci			struct flow_dissector_key_ports tp_min;
19462306a36Sopenharmony_ci			struct flow_dissector_key_ports tp_max;
19562306a36Sopenharmony_ci		};
19662306a36Sopenharmony_ci	};
19762306a36Sopenharmony_ci};
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci/**
20062306a36Sopenharmony_ci * struct flow_dissector_key_icmp:
20162306a36Sopenharmony_ci * @type: ICMP type
20262306a36Sopenharmony_ci * @code: ICMP code
20362306a36Sopenharmony_ci * @id:   Session identifier
20462306a36Sopenharmony_ci */
20562306a36Sopenharmony_cistruct flow_dissector_key_icmp {
20662306a36Sopenharmony_ci	struct {
20762306a36Sopenharmony_ci		u8 type;
20862306a36Sopenharmony_ci		u8 code;
20962306a36Sopenharmony_ci	};
21062306a36Sopenharmony_ci	u16 id;
21162306a36Sopenharmony_ci};
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci/**
21462306a36Sopenharmony_ci * struct flow_dissector_key_eth_addrs:
21562306a36Sopenharmony_ci * @src: source Ethernet address
21662306a36Sopenharmony_ci * @dst: destination Ethernet address
21762306a36Sopenharmony_ci */
21862306a36Sopenharmony_cistruct flow_dissector_key_eth_addrs {
21962306a36Sopenharmony_ci	/* (dst,src) must be grouped, in the same way than in ETH header */
22062306a36Sopenharmony_ci	unsigned char dst[ETH_ALEN];
22162306a36Sopenharmony_ci	unsigned char src[ETH_ALEN];
22262306a36Sopenharmony_ci};
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci/**
22562306a36Sopenharmony_ci * struct flow_dissector_key_tcp:
22662306a36Sopenharmony_ci * @flags: flags
22762306a36Sopenharmony_ci */
22862306a36Sopenharmony_cistruct flow_dissector_key_tcp {
22962306a36Sopenharmony_ci	__be16 flags;
23062306a36Sopenharmony_ci};
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ci/**
23362306a36Sopenharmony_ci * struct flow_dissector_key_ip:
23462306a36Sopenharmony_ci * @tos: tos
23562306a36Sopenharmony_ci * @ttl: ttl
23662306a36Sopenharmony_ci */
23762306a36Sopenharmony_cistruct flow_dissector_key_ip {
23862306a36Sopenharmony_ci	__u8	tos;
23962306a36Sopenharmony_ci	__u8	ttl;
24062306a36Sopenharmony_ci};
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ci/**
24362306a36Sopenharmony_ci * struct flow_dissector_key_meta:
24462306a36Sopenharmony_ci * @ingress_ifindex: ingress ifindex
24562306a36Sopenharmony_ci * @ingress_iftype: ingress interface type
24662306a36Sopenharmony_ci * @l2_miss: packet did not match an L2 entry during forwarding
24762306a36Sopenharmony_ci */
24862306a36Sopenharmony_cistruct flow_dissector_key_meta {
24962306a36Sopenharmony_ci	int ingress_ifindex;
25062306a36Sopenharmony_ci	u16 ingress_iftype;
25162306a36Sopenharmony_ci	u8 l2_miss;
25262306a36Sopenharmony_ci};
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_ci/**
25562306a36Sopenharmony_ci * struct flow_dissector_key_ct:
25662306a36Sopenharmony_ci * @ct_state: conntrack state after converting with map
25762306a36Sopenharmony_ci * @ct_mark: conttrack mark
25862306a36Sopenharmony_ci * @ct_zone: conntrack zone
25962306a36Sopenharmony_ci * @ct_labels: conntrack labels
26062306a36Sopenharmony_ci */
26162306a36Sopenharmony_cistruct flow_dissector_key_ct {
26262306a36Sopenharmony_ci	u16	ct_state;
26362306a36Sopenharmony_ci	u16	ct_zone;
26462306a36Sopenharmony_ci	u32	ct_mark;
26562306a36Sopenharmony_ci	u32	ct_labels[4];
26662306a36Sopenharmony_ci};
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci/**
26962306a36Sopenharmony_ci * struct flow_dissector_key_hash:
27062306a36Sopenharmony_ci * @hash: hash value
27162306a36Sopenharmony_ci */
27262306a36Sopenharmony_cistruct flow_dissector_key_hash {
27362306a36Sopenharmony_ci	u32 hash;
27462306a36Sopenharmony_ci};
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_ci/**
27762306a36Sopenharmony_ci * struct flow_dissector_key_num_of_vlans:
27862306a36Sopenharmony_ci * @num_of_vlans: num_of_vlans value
27962306a36Sopenharmony_ci */
28062306a36Sopenharmony_cistruct flow_dissector_key_num_of_vlans {
28162306a36Sopenharmony_ci	u8 num_of_vlans;
28262306a36Sopenharmony_ci};
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci/**
28562306a36Sopenharmony_ci * struct flow_dissector_key_pppoe:
28662306a36Sopenharmony_ci * @session_id: pppoe session id
28762306a36Sopenharmony_ci * @ppp_proto: ppp protocol
28862306a36Sopenharmony_ci * @type: pppoe eth type
28962306a36Sopenharmony_ci */
29062306a36Sopenharmony_cistruct flow_dissector_key_pppoe {
29162306a36Sopenharmony_ci	__be16 session_id;
29262306a36Sopenharmony_ci	__be16 ppp_proto;
29362306a36Sopenharmony_ci	__be16 type;
29462306a36Sopenharmony_ci};
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci/**
29762306a36Sopenharmony_ci * struct flow_dissector_key_l2tpv3:
29862306a36Sopenharmony_ci * @session_id: identifier for a l2tp session
29962306a36Sopenharmony_ci */
30062306a36Sopenharmony_cistruct flow_dissector_key_l2tpv3 {
30162306a36Sopenharmony_ci	__be32 session_id;
30262306a36Sopenharmony_ci};
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_ci/**
30562306a36Sopenharmony_ci * struct flow_dissector_key_ipsec:
30662306a36Sopenharmony_ci * @spi: identifier for a ipsec connection
30762306a36Sopenharmony_ci */
30862306a36Sopenharmony_cistruct flow_dissector_key_ipsec {
30962306a36Sopenharmony_ci	__be32 spi;
31062306a36Sopenharmony_ci};
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_ci/**
31362306a36Sopenharmony_ci * struct flow_dissector_key_cfm
31462306a36Sopenharmony_ci * @mdl_ver: maintenance domain level (mdl) and cfm protocol version
31562306a36Sopenharmony_ci * @opcode: code specifying a type of cfm protocol packet
31662306a36Sopenharmony_ci *
31762306a36Sopenharmony_ci * See 802.1ag, ITU-T G.8013/Y.1731
31862306a36Sopenharmony_ci *         1               2
31962306a36Sopenharmony_ci * |7 6 5 4 3 2 1 0|7 6 5 4 3 2 1 0|
32062306a36Sopenharmony_ci * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
32162306a36Sopenharmony_ci * | mdl | version |     opcode    |
32262306a36Sopenharmony_ci * +-----+---------+-+-+-+-+-+-+-+-+
32362306a36Sopenharmony_ci */
32462306a36Sopenharmony_cistruct flow_dissector_key_cfm {
32562306a36Sopenharmony_ci	u8	mdl_ver;
32662306a36Sopenharmony_ci	u8	opcode;
32762306a36Sopenharmony_ci};
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_ci#define FLOW_DIS_CFM_MDL_MASK GENMASK(7, 5)
33062306a36Sopenharmony_ci#define FLOW_DIS_CFM_MDL_MAX 7
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_cienum flow_dissector_key_id {
33362306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
33462306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
33562306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_IPV4_ADDRS, /* struct flow_dissector_key_ipv4_addrs */
33662306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */
33762306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_PORTS, /* struct flow_dissector_key_ports */
33862306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_PORTS_RANGE, /* struct flow_dissector_key_ports */
33962306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_ICMP, /* struct flow_dissector_key_icmp */
34062306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_ETH_ADDRS, /* struct flow_dissector_key_eth_addrs */
34162306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_TIPC, /* struct flow_dissector_key_tipc */
34262306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_ARP, /* struct flow_dissector_key_arp */
34362306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_VLAN, /* struct flow_dissector_key_vlan */
34462306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_FLOW_LABEL, /* struct flow_dissector_key_tags */
34562306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_GRE_KEYID, /* struct flow_dissector_key_keyid */
34662306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_MPLS_ENTROPY, /* struct flow_dissector_key_keyid */
34762306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_ENC_KEYID, /* struct flow_dissector_key_keyid */
34862306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS, /* struct flow_dissector_key_ipv4_addrs */
34962306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */
35062306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_ENC_CONTROL, /* struct flow_dissector_key_control */
35162306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_ENC_PORTS, /* struct flow_dissector_key_ports */
35262306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_MPLS, /* struct flow_dissector_key_mpls */
35362306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_TCP, /* struct flow_dissector_key_tcp */
35462306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_IP, /* struct flow_dissector_key_ip */
35562306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_CVLAN, /* struct flow_dissector_key_vlan */
35662306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_ENC_IP, /* struct flow_dissector_key_ip */
35762306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_ENC_OPTS, /* struct flow_dissector_key_enc_opts */
35862306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_META, /* struct flow_dissector_key_meta */
35962306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_CT, /* struct flow_dissector_key_ct */
36062306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_HASH, /* struct flow_dissector_key_hash */
36162306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_NUM_OF_VLANS, /* struct flow_dissector_key_num_of_vlans */
36262306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_PPPOE, /* struct flow_dissector_key_pppoe */
36362306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_L2TPV3, /* struct flow_dissector_key_l2tpv3 */
36462306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_CFM, /* struct flow_dissector_key_cfm */
36562306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_IPSEC, /* struct flow_dissector_key_ipsec */
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_ci	FLOW_DISSECTOR_KEY_MAX,
36862306a36Sopenharmony_ci};
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ci#define FLOW_DISSECTOR_F_PARSE_1ST_FRAG		BIT(0)
37162306a36Sopenharmony_ci#define FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL	BIT(1)
37262306a36Sopenharmony_ci#define FLOW_DISSECTOR_F_STOP_AT_ENCAP		BIT(2)
37362306a36Sopenharmony_ci#define FLOW_DISSECTOR_F_STOP_BEFORE_ENCAP	BIT(3)
37462306a36Sopenharmony_ci
37562306a36Sopenharmony_cistruct flow_dissector_key {
37662306a36Sopenharmony_ci	enum flow_dissector_key_id key_id;
37762306a36Sopenharmony_ci	size_t offset; /* offset of struct flow_dissector_key_*
37862306a36Sopenharmony_ci			  in target the struct */
37962306a36Sopenharmony_ci};
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_cistruct flow_dissector {
38262306a36Sopenharmony_ci	unsigned long long  used_keys;
38362306a36Sopenharmony_ci		/* each bit represents presence of one key id */
38462306a36Sopenharmony_ci	unsigned short int offset[FLOW_DISSECTOR_KEY_MAX];
38562306a36Sopenharmony_ci};
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_cistruct flow_keys_basic {
38862306a36Sopenharmony_ci	struct flow_dissector_key_control control;
38962306a36Sopenharmony_ci	struct flow_dissector_key_basic basic;
39062306a36Sopenharmony_ci};
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_cistruct flow_keys {
39362306a36Sopenharmony_ci	struct flow_dissector_key_control control;
39462306a36Sopenharmony_ci#define FLOW_KEYS_HASH_START_FIELD basic
39562306a36Sopenharmony_ci	struct flow_dissector_key_basic basic __aligned(SIPHASH_ALIGNMENT);
39662306a36Sopenharmony_ci	struct flow_dissector_key_tags tags;
39762306a36Sopenharmony_ci	struct flow_dissector_key_vlan vlan;
39862306a36Sopenharmony_ci	struct flow_dissector_key_vlan cvlan;
39962306a36Sopenharmony_ci	struct flow_dissector_key_keyid keyid;
40062306a36Sopenharmony_ci	struct flow_dissector_key_ports ports;
40162306a36Sopenharmony_ci	struct flow_dissector_key_icmp icmp;
40262306a36Sopenharmony_ci	/* 'addrs' must be the last member */
40362306a36Sopenharmony_ci	struct flow_dissector_key_addrs addrs;
40462306a36Sopenharmony_ci};
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ci#define FLOW_KEYS_HASH_OFFSET		\
40762306a36Sopenharmony_ci	offsetof(struct flow_keys, FLOW_KEYS_HASH_START_FIELD)
40862306a36Sopenharmony_ci
40962306a36Sopenharmony_ci__be32 flow_get_u32_src(const struct flow_keys *flow);
41062306a36Sopenharmony_ci__be32 flow_get_u32_dst(const struct flow_keys *flow);
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_ciextern struct flow_dissector flow_keys_dissector;
41362306a36Sopenharmony_ciextern struct flow_dissector flow_keys_basic_dissector;
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_ci/* struct flow_keys_digest:
41662306a36Sopenharmony_ci *
41762306a36Sopenharmony_ci * This structure is used to hold a digest of the full flow keys. This is a
41862306a36Sopenharmony_ci * larger "hash" of a flow to allow definitively matching specific flows where
41962306a36Sopenharmony_ci * the 32 bit skb->hash is not large enough. The size is limited to 16 bytes so
42062306a36Sopenharmony_ci * that it can be used in CB of skb (see sch_choke for an example).
42162306a36Sopenharmony_ci */
42262306a36Sopenharmony_ci#define FLOW_KEYS_DIGEST_LEN	16
42362306a36Sopenharmony_cistruct flow_keys_digest {
42462306a36Sopenharmony_ci	u8	data[FLOW_KEYS_DIGEST_LEN];
42562306a36Sopenharmony_ci};
42662306a36Sopenharmony_ci
42762306a36Sopenharmony_civoid make_flow_keys_digest(struct flow_keys_digest *digest,
42862306a36Sopenharmony_ci			   const struct flow_keys *flow);
42962306a36Sopenharmony_ci
43062306a36Sopenharmony_cistatic inline bool flow_keys_have_l4(const struct flow_keys *keys)
43162306a36Sopenharmony_ci{
43262306a36Sopenharmony_ci	return (keys->ports.ports || keys->tags.flow_label);
43362306a36Sopenharmony_ci}
43462306a36Sopenharmony_ci
43562306a36Sopenharmony_ciu32 flow_hash_from_keys(struct flow_keys *keys);
43662306a36Sopenharmony_civoid skb_flow_get_icmp_tci(const struct sk_buff *skb,
43762306a36Sopenharmony_ci			   struct flow_dissector_key_icmp *key_icmp,
43862306a36Sopenharmony_ci			   const void *data, int thoff, int hlen);
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_cistatic inline bool dissector_uses_key(const struct flow_dissector *flow_dissector,
44162306a36Sopenharmony_ci				      enum flow_dissector_key_id key_id)
44262306a36Sopenharmony_ci{
44362306a36Sopenharmony_ci	return flow_dissector->used_keys & (1ULL << key_id);
44462306a36Sopenharmony_ci}
44562306a36Sopenharmony_ci
44662306a36Sopenharmony_cistatic inline void *skb_flow_dissector_target(struct flow_dissector *flow_dissector,
44762306a36Sopenharmony_ci					      enum flow_dissector_key_id key_id,
44862306a36Sopenharmony_ci					      void *target_container)
44962306a36Sopenharmony_ci{
45062306a36Sopenharmony_ci	return ((char *)target_container) + flow_dissector->offset[key_id];
45162306a36Sopenharmony_ci}
45262306a36Sopenharmony_ci
45362306a36Sopenharmony_cistruct bpf_flow_dissector {
45462306a36Sopenharmony_ci	struct bpf_flow_keys	*flow_keys;
45562306a36Sopenharmony_ci	const struct sk_buff	*skb;
45662306a36Sopenharmony_ci	const void		*data;
45762306a36Sopenharmony_ci	const void		*data_end;
45862306a36Sopenharmony_ci};
45962306a36Sopenharmony_ci
46062306a36Sopenharmony_cistatic inline void
46162306a36Sopenharmony_ciflow_dissector_init_keys(struct flow_dissector_key_control *key_control,
46262306a36Sopenharmony_ci			 struct flow_dissector_key_basic *key_basic)
46362306a36Sopenharmony_ci{
46462306a36Sopenharmony_ci	memset(key_control, 0, sizeof(*key_control));
46562306a36Sopenharmony_ci	memset(key_basic, 0, sizeof(*key_basic));
46662306a36Sopenharmony_ci}
46762306a36Sopenharmony_ci
46862306a36Sopenharmony_ci#ifdef CONFIG_BPF_SYSCALL
46962306a36Sopenharmony_ciint flow_dissector_bpf_prog_attach_check(struct net *net,
47062306a36Sopenharmony_ci					 struct bpf_prog *prog);
47162306a36Sopenharmony_ci#endif /* CONFIG_BPF_SYSCALL */
47262306a36Sopenharmony_ci
47362306a36Sopenharmony_ci#endif
474