18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef _NET_FLOW_DISSECTOR_H
38c2ecf20Sopenharmony_ci#define _NET_FLOW_DISSECTOR_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#include <linux/types.h>
68c2ecf20Sopenharmony_ci#include <linux/in6.h>
78c2ecf20Sopenharmony_ci#include <linux/siphash.h>
88c2ecf20Sopenharmony_ci#include <linux/string.h>
98c2ecf20Sopenharmony_ci#include <uapi/linux/if_ether.h>
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_cistruct bpf_prog;
128c2ecf20Sopenharmony_cistruct net;
138c2ecf20Sopenharmony_cistruct sk_buff;
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci/**
168c2ecf20Sopenharmony_ci * struct flow_dissector_key_control:
178c2ecf20Sopenharmony_ci * @thoff: Transport header offset
188c2ecf20Sopenharmony_ci */
198c2ecf20Sopenharmony_cistruct flow_dissector_key_control {
208c2ecf20Sopenharmony_ci	u16	thoff;
218c2ecf20Sopenharmony_ci	u16	addr_type;
228c2ecf20Sopenharmony_ci	u32	flags;
238c2ecf20Sopenharmony_ci};
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci#define FLOW_DIS_IS_FRAGMENT	BIT(0)
268c2ecf20Sopenharmony_ci#define FLOW_DIS_FIRST_FRAG	BIT(1)
278c2ecf20Sopenharmony_ci#define FLOW_DIS_ENCAPSULATION	BIT(2)
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_cienum flow_dissect_ret {
308c2ecf20Sopenharmony_ci	FLOW_DISSECT_RET_OUT_GOOD,
318c2ecf20Sopenharmony_ci	FLOW_DISSECT_RET_OUT_BAD,
328c2ecf20Sopenharmony_ci	FLOW_DISSECT_RET_PROTO_AGAIN,
338c2ecf20Sopenharmony_ci	FLOW_DISSECT_RET_IPPROTO_AGAIN,
348c2ecf20Sopenharmony_ci	FLOW_DISSECT_RET_CONTINUE,
358c2ecf20Sopenharmony_ci};
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci/**
388c2ecf20Sopenharmony_ci * struct flow_dissector_key_basic:
398c2ecf20Sopenharmony_ci * @n_proto: Network header protocol (eg. IPv4/IPv6)
408c2ecf20Sopenharmony_ci * @ip_proto: Transport header protocol (eg. TCP/UDP)
418c2ecf20Sopenharmony_ci */
428c2ecf20Sopenharmony_cistruct flow_dissector_key_basic {
438c2ecf20Sopenharmony_ci	__be16	n_proto;
448c2ecf20Sopenharmony_ci	u8	ip_proto;
458c2ecf20Sopenharmony_ci	u8	padding;
468c2ecf20Sopenharmony_ci};
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_cistruct flow_dissector_key_tags {
498c2ecf20Sopenharmony_ci	u32	flow_label;
508c2ecf20Sopenharmony_ci};
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_cistruct flow_dissector_key_vlan {
538c2ecf20Sopenharmony_ci	union {
548c2ecf20Sopenharmony_ci		struct {
558c2ecf20Sopenharmony_ci			u16	vlan_id:12,
568c2ecf20Sopenharmony_ci				vlan_dei:1,
578c2ecf20Sopenharmony_ci				vlan_priority:3;
588c2ecf20Sopenharmony_ci		};
598c2ecf20Sopenharmony_ci		__be16	vlan_tci;
608c2ecf20Sopenharmony_ci	};
618c2ecf20Sopenharmony_ci	__be16	vlan_tpid;
628c2ecf20Sopenharmony_ci	__be16	vlan_eth_type;
638c2ecf20Sopenharmony_ci	u16	padding;
648c2ecf20Sopenharmony_ci};
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_cistruct flow_dissector_mpls_lse {
678c2ecf20Sopenharmony_ci	u32	mpls_ttl:8,
688c2ecf20Sopenharmony_ci		mpls_bos:1,
698c2ecf20Sopenharmony_ci		mpls_tc:3,
708c2ecf20Sopenharmony_ci		mpls_label:20;
718c2ecf20Sopenharmony_ci};
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci#define FLOW_DIS_MPLS_MAX 7
748c2ecf20Sopenharmony_cistruct flow_dissector_key_mpls {
758c2ecf20Sopenharmony_ci	struct flow_dissector_mpls_lse ls[FLOW_DIS_MPLS_MAX]; /* Label Stack */
768c2ecf20Sopenharmony_ci	u8 used_lses; /* One bit set for each Label Stack Entry in use */
778c2ecf20Sopenharmony_ci};
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_cistatic inline void dissector_set_mpls_lse(struct flow_dissector_key_mpls *mpls,
808c2ecf20Sopenharmony_ci					  int lse_index)
818c2ecf20Sopenharmony_ci{
828c2ecf20Sopenharmony_ci	mpls->used_lses |= 1 << lse_index;
838c2ecf20Sopenharmony_ci}
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci#define FLOW_DIS_TUN_OPTS_MAX 255
868c2ecf20Sopenharmony_ci/**
878c2ecf20Sopenharmony_ci * struct flow_dissector_key_enc_opts:
888c2ecf20Sopenharmony_ci * @data: tunnel option data
898c2ecf20Sopenharmony_ci * @len: length of tunnel option data
908c2ecf20Sopenharmony_ci * @dst_opt_type: tunnel option type
918c2ecf20Sopenharmony_ci */
928c2ecf20Sopenharmony_cistruct flow_dissector_key_enc_opts {
938c2ecf20Sopenharmony_ci	u8 data[FLOW_DIS_TUN_OPTS_MAX];	/* Using IP_TUNNEL_OPTS_MAX is desired
948c2ecf20Sopenharmony_ci					 * here but seems difficult to #include
958c2ecf20Sopenharmony_ci					 */
968c2ecf20Sopenharmony_ci	u8 len;
978c2ecf20Sopenharmony_ci	__be16 dst_opt_type;
988c2ecf20Sopenharmony_ci};
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_cistruct flow_dissector_key_keyid {
1018c2ecf20Sopenharmony_ci	__be32	keyid;
1028c2ecf20Sopenharmony_ci};
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ci/**
1058c2ecf20Sopenharmony_ci * struct flow_dissector_key_ipv4_addrs:
1068c2ecf20Sopenharmony_ci * @src: source ip address
1078c2ecf20Sopenharmony_ci * @dst: destination ip address
1088c2ecf20Sopenharmony_ci */
1098c2ecf20Sopenharmony_cistruct flow_dissector_key_ipv4_addrs {
1108c2ecf20Sopenharmony_ci	/* (src,dst) must be grouped, in the same way than in IP header */
1118c2ecf20Sopenharmony_ci	__be32 src;
1128c2ecf20Sopenharmony_ci	__be32 dst;
1138c2ecf20Sopenharmony_ci};
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci/**
1168c2ecf20Sopenharmony_ci * struct flow_dissector_key_ipv6_addrs:
1178c2ecf20Sopenharmony_ci * @src: source ip address
1188c2ecf20Sopenharmony_ci * @dst: destination ip address
1198c2ecf20Sopenharmony_ci */
1208c2ecf20Sopenharmony_cistruct flow_dissector_key_ipv6_addrs {
1218c2ecf20Sopenharmony_ci	/* (src,dst) must be grouped, in the same way than in IP header */
1228c2ecf20Sopenharmony_ci	struct in6_addr src;
1238c2ecf20Sopenharmony_ci	struct in6_addr dst;
1248c2ecf20Sopenharmony_ci};
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ci/**
1278c2ecf20Sopenharmony_ci * struct flow_dissector_key_tipc:
1288c2ecf20Sopenharmony_ci * @key: source node address combined with selector
1298c2ecf20Sopenharmony_ci */
1308c2ecf20Sopenharmony_cistruct flow_dissector_key_tipc {
1318c2ecf20Sopenharmony_ci	__be32 key;
1328c2ecf20Sopenharmony_ci};
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ci/**
1358c2ecf20Sopenharmony_ci * struct flow_dissector_key_addrs:
1368c2ecf20Sopenharmony_ci * @v4addrs: IPv4 addresses
1378c2ecf20Sopenharmony_ci * @v6addrs: IPv6 addresses
1388c2ecf20Sopenharmony_ci */
1398c2ecf20Sopenharmony_cistruct flow_dissector_key_addrs {
1408c2ecf20Sopenharmony_ci	union {
1418c2ecf20Sopenharmony_ci		struct flow_dissector_key_ipv4_addrs v4addrs;
1428c2ecf20Sopenharmony_ci		struct flow_dissector_key_ipv6_addrs v6addrs;
1438c2ecf20Sopenharmony_ci		struct flow_dissector_key_tipc tipckey;
1448c2ecf20Sopenharmony_ci	};
1458c2ecf20Sopenharmony_ci};
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ci/**
1488c2ecf20Sopenharmony_ci * flow_dissector_key_arp:
1498c2ecf20Sopenharmony_ci *	@ports: Operation, source and target addresses for an ARP header
1508c2ecf20Sopenharmony_ci *              for Ethernet hardware addresses and IPv4 protocol addresses
1518c2ecf20Sopenharmony_ci *		sip: Sender IP address
1528c2ecf20Sopenharmony_ci *		tip: Target IP address
1538c2ecf20Sopenharmony_ci *		op:  Operation
1548c2ecf20Sopenharmony_ci *		sha: Sender hardware address
1558c2ecf20Sopenharmony_ci *		tpa: Target hardware address
1568c2ecf20Sopenharmony_ci */
1578c2ecf20Sopenharmony_cistruct flow_dissector_key_arp {
1588c2ecf20Sopenharmony_ci	__u32 sip;
1598c2ecf20Sopenharmony_ci	__u32 tip;
1608c2ecf20Sopenharmony_ci	__u8 op;
1618c2ecf20Sopenharmony_ci	unsigned char sha[ETH_ALEN];
1628c2ecf20Sopenharmony_ci	unsigned char tha[ETH_ALEN];
1638c2ecf20Sopenharmony_ci};
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_ci/**
1668c2ecf20Sopenharmony_ci * flow_dissector_key_tp_ports:
1678c2ecf20Sopenharmony_ci *	@ports: port numbers of Transport header
1688c2ecf20Sopenharmony_ci *		src: source port number
1698c2ecf20Sopenharmony_ci *		dst: destination port number
1708c2ecf20Sopenharmony_ci */
1718c2ecf20Sopenharmony_cistruct flow_dissector_key_ports {
1728c2ecf20Sopenharmony_ci	union {
1738c2ecf20Sopenharmony_ci		__be32 ports;
1748c2ecf20Sopenharmony_ci		struct {
1758c2ecf20Sopenharmony_ci			__be16 src;
1768c2ecf20Sopenharmony_ci			__be16 dst;
1778c2ecf20Sopenharmony_ci		};
1788c2ecf20Sopenharmony_ci	};
1798c2ecf20Sopenharmony_ci};
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_ci/**
1828c2ecf20Sopenharmony_ci * flow_dissector_key_icmp:
1838c2ecf20Sopenharmony_ci *		type: ICMP type
1848c2ecf20Sopenharmony_ci *		code: ICMP code
1858c2ecf20Sopenharmony_ci *		id:   session identifier
1868c2ecf20Sopenharmony_ci */
1878c2ecf20Sopenharmony_cistruct flow_dissector_key_icmp {
1888c2ecf20Sopenharmony_ci	struct {
1898c2ecf20Sopenharmony_ci		u8 type;
1908c2ecf20Sopenharmony_ci		u8 code;
1918c2ecf20Sopenharmony_ci	};
1928c2ecf20Sopenharmony_ci	u16 id;
1938c2ecf20Sopenharmony_ci};
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ci/**
1968c2ecf20Sopenharmony_ci * struct flow_dissector_key_eth_addrs:
1978c2ecf20Sopenharmony_ci * @src: source Ethernet address
1988c2ecf20Sopenharmony_ci * @dst: destination Ethernet address
1998c2ecf20Sopenharmony_ci */
2008c2ecf20Sopenharmony_cistruct flow_dissector_key_eth_addrs {
2018c2ecf20Sopenharmony_ci	/* (dst,src) must be grouped, in the same way than in ETH header */
2028c2ecf20Sopenharmony_ci	unsigned char dst[ETH_ALEN];
2038c2ecf20Sopenharmony_ci	unsigned char src[ETH_ALEN];
2048c2ecf20Sopenharmony_ci};
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_ci/**
2078c2ecf20Sopenharmony_ci * struct flow_dissector_key_tcp:
2088c2ecf20Sopenharmony_ci * @flags: flags
2098c2ecf20Sopenharmony_ci */
2108c2ecf20Sopenharmony_cistruct flow_dissector_key_tcp {
2118c2ecf20Sopenharmony_ci	__be16 flags;
2128c2ecf20Sopenharmony_ci};
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ci/**
2158c2ecf20Sopenharmony_ci * struct flow_dissector_key_ip:
2168c2ecf20Sopenharmony_ci * @tos: tos
2178c2ecf20Sopenharmony_ci * @ttl: ttl
2188c2ecf20Sopenharmony_ci */
2198c2ecf20Sopenharmony_cistruct flow_dissector_key_ip {
2208c2ecf20Sopenharmony_ci	__u8	tos;
2218c2ecf20Sopenharmony_ci	__u8	ttl;
2228c2ecf20Sopenharmony_ci};
2238c2ecf20Sopenharmony_ci
2248c2ecf20Sopenharmony_ci/**
2258c2ecf20Sopenharmony_ci * struct flow_dissector_key_meta:
2268c2ecf20Sopenharmony_ci * @ingress_ifindex: ingress ifindex
2278c2ecf20Sopenharmony_ci * @ingress_iftype: ingress interface type
2288c2ecf20Sopenharmony_ci */
2298c2ecf20Sopenharmony_cistruct flow_dissector_key_meta {
2308c2ecf20Sopenharmony_ci	int ingress_ifindex;
2318c2ecf20Sopenharmony_ci	u16 ingress_iftype;
2328c2ecf20Sopenharmony_ci};
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_ci/**
2358c2ecf20Sopenharmony_ci * struct flow_dissector_key_ct:
2368c2ecf20Sopenharmony_ci * @ct_state: conntrack state after converting with map
2378c2ecf20Sopenharmony_ci * @ct_mark: conttrack mark
2388c2ecf20Sopenharmony_ci * @ct_zone: conntrack zone
2398c2ecf20Sopenharmony_ci * @ct_labels: conntrack labels
2408c2ecf20Sopenharmony_ci */
2418c2ecf20Sopenharmony_cistruct flow_dissector_key_ct {
2428c2ecf20Sopenharmony_ci	u16	ct_state;
2438c2ecf20Sopenharmony_ci	u16	ct_zone;
2448c2ecf20Sopenharmony_ci	u32	ct_mark;
2458c2ecf20Sopenharmony_ci	u32	ct_labels[4];
2468c2ecf20Sopenharmony_ci};
2478c2ecf20Sopenharmony_ci
2488c2ecf20Sopenharmony_ci/**
2498c2ecf20Sopenharmony_ci * struct flow_dissector_key_hash:
2508c2ecf20Sopenharmony_ci * @hash: hash value
2518c2ecf20Sopenharmony_ci */
2528c2ecf20Sopenharmony_cistruct flow_dissector_key_hash {
2538c2ecf20Sopenharmony_ci	u32 hash;
2548c2ecf20Sopenharmony_ci};
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_cienum flow_dissector_key_id {
2578c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
2588c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
2598c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_IPV4_ADDRS, /* struct flow_dissector_key_ipv4_addrs */
2608c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */
2618c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_PORTS, /* struct flow_dissector_key_ports */
2628c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_PORTS_RANGE, /* struct flow_dissector_key_ports */
2638c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_ICMP, /* struct flow_dissector_key_icmp */
2648c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_ETH_ADDRS, /* struct flow_dissector_key_eth_addrs */
2658c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_TIPC, /* struct flow_dissector_key_tipc */
2668c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_ARP, /* struct flow_dissector_key_arp */
2678c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_VLAN, /* struct flow_dissector_key_vlan */
2688c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_FLOW_LABEL, /* struct flow_dissector_key_tags */
2698c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_GRE_KEYID, /* struct flow_dissector_key_keyid */
2708c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_MPLS_ENTROPY, /* struct flow_dissector_key_keyid */
2718c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_ENC_KEYID, /* struct flow_dissector_key_keyid */
2728c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS, /* struct flow_dissector_key_ipv4_addrs */
2738c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */
2748c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_ENC_CONTROL, /* struct flow_dissector_key_control */
2758c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_ENC_PORTS, /* struct flow_dissector_key_ports */
2768c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_MPLS, /* struct flow_dissector_key_mpls */
2778c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_TCP, /* struct flow_dissector_key_tcp */
2788c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_IP, /* struct flow_dissector_key_ip */
2798c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_CVLAN, /* struct flow_dissector_key_vlan */
2808c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_ENC_IP, /* struct flow_dissector_key_ip */
2818c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_ENC_OPTS, /* struct flow_dissector_key_enc_opts */
2828c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_META, /* struct flow_dissector_key_meta */
2838c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_CT, /* struct flow_dissector_key_ct */
2848c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_HASH, /* struct flow_dissector_key_hash */
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_ci	FLOW_DISSECTOR_KEY_MAX,
2878c2ecf20Sopenharmony_ci};
2888c2ecf20Sopenharmony_ci
2898c2ecf20Sopenharmony_ci#define FLOW_DISSECTOR_F_PARSE_1ST_FRAG		BIT(0)
2908c2ecf20Sopenharmony_ci#define FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL	BIT(1)
2918c2ecf20Sopenharmony_ci#define FLOW_DISSECTOR_F_STOP_AT_ENCAP		BIT(2)
2928c2ecf20Sopenharmony_ci
2938c2ecf20Sopenharmony_cistruct flow_dissector_key {
2948c2ecf20Sopenharmony_ci	enum flow_dissector_key_id key_id;
2958c2ecf20Sopenharmony_ci	size_t offset; /* offset of struct flow_dissector_key_*
2968c2ecf20Sopenharmony_ci			  in target the struct */
2978c2ecf20Sopenharmony_ci};
2988c2ecf20Sopenharmony_ci
2998c2ecf20Sopenharmony_cistruct flow_dissector {
3008c2ecf20Sopenharmony_ci	unsigned int used_keys; /* each bit repesents presence of one key id */
3018c2ecf20Sopenharmony_ci	unsigned short int offset[FLOW_DISSECTOR_KEY_MAX];
3028c2ecf20Sopenharmony_ci};
3038c2ecf20Sopenharmony_ci
3048c2ecf20Sopenharmony_cistruct flow_keys_basic {
3058c2ecf20Sopenharmony_ci	struct flow_dissector_key_control control;
3068c2ecf20Sopenharmony_ci	struct flow_dissector_key_basic basic;
3078c2ecf20Sopenharmony_ci};
3088c2ecf20Sopenharmony_ci
3098c2ecf20Sopenharmony_cistruct flow_keys {
3108c2ecf20Sopenharmony_ci	struct flow_dissector_key_control control;
3118c2ecf20Sopenharmony_ci#define FLOW_KEYS_HASH_START_FIELD basic
3128c2ecf20Sopenharmony_ci	struct flow_dissector_key_basic basic __aligned(SIPHASH_ALIGNMENT);
3138c2ecf20Sopenharmony_ci	struct flow_dissector_key_tags tags;
3148c2ecf20Sopenharmony_ci	struct flow_dissector_key_vlan vlan;
3158c2ecf20Sopenharmony_ci	struct flow_dissector_key_vlan cvlan;
3168c2ecf20Sopenharmony_ci	struct flow_dissector_key_keyid keyid;
3178c2ecf20Sopenharmony_ci	struct flow_dissector_key_ports ports;
3188c2ecf20Sopenharmony_ci	struct flow_dissector_key_icmp icmp;
3198c2ecf20Sopenharmony_ci	/* 'addrs' must be the last member */
3208c2ecf20Sopenharmony_ci	struct flow_dissector_key_addrs addrs;
3218c2ecf20Sopenharmony_ci};
3228c2ecf20Sopenharmony_ci
3238c2ecf20Sopenharmony_ci#define FLOW_KEYS_HASH_OFFSET		\
3248c2ecf20Sopenharmony_ci	offsetof(struct flow_keys, FLOW_KEYS_HASH_START_FIELD)
3258c2ecf20Sopenharmony_ci
3268c2ecf20Sopenharmony_ci__be32 flow_get_u32_src(const struct flow_keys *flow);
3278c2ecf20Sopenharmony_ci__be32 flow_get_u32_dst(const struct flow_keys *flow);
3288c2ecf20Sopenharmony_ci
3298c2ecf20Sopenharmony_ciextern struct flow_dissector flow_keys_dissector;
3308c2ecf20Sopenharmony_ciextern struct flow_dissector flow_keys_basic_dissector;
3318c2ecf20Sopenharmony_ci
3328c2ecf20Sopenharmony_ci/* struct flow_keys_digest:
3338c2ecf20Sopenharmony_ci *
3348c2ecf20Sopenharmony_ci * This structure is used to hold a digest of the full flow keys. This is a
3358c2ecf20Sopenharmony_ci * larger "hash" of a flow to allow definitively matching specific flows where
3368c2ecf20Sopenharmony_ci * the 32 bit skb->hash is not large enough. The size is limited to 16 bytes so
3378c2ecf20Sopenharmony_ci * that it can be used in CB of skb (see sch_choke for an example).
3388c2ecf20Sopenharmony_ci */
3398c2ecf20Sopenharmony_ci#define FLOW_KEYS_DIGEST_LEN	16
3408c2ecf20Sopenharmony_cistruct flow_keys_digest {
3418c2ecf20Sopenharmony_ci	u8	data[FLOW_KEYS_DIGEST_LEN];
3428c2ecf20Sopenharmony_ci};
3438c2ecf20Sopenharmony_ci
3448c2ecf20Sopenharmony_civoid make_flow_keys_digest(struct flow_keys_digest *digest,
3458c2ecf20Sopenharmony_ci			   const struct flow_keys *flow);
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_cistatic inline bool flow_keys_have_l4(const struct flow_keys *keys)
3488c2ecf20Sopenharmony_ci{
3498c2ecf20Sopenharmony_ci	return (keys->ports.ports || keys->tags.flow_label);
3508c2ecf20Sopenharmony_ci}
3518c2ecf20Sopenharmony_ci
3528c2ecf20Sopenharmony_ciu32 flow_hash_from_keys(struct flow_keys *keys);
3538c2ecf20Sopenharmony_civoid skb_flow_get_icmp_tci(const struct sk_buff *skb,
3548c2ecf20Sopenharmony_ci			   struct flow_dissector_key_icmp *key_icmp,
3558c2ecf20Sopenharmony_ci			   void *data, int thoff, int hlen);
3568c2ecf20Sopenharmony_ci
3578c2ecf20Sopenharmony_cistatic inline bool dissector_uses_key(const struct flow_dissector *flow_dissector,
3588c2ecf20Sopenharmony_ci				      enum flow_dissector_key_id key_id)
3598c2ecf20Sopenharmony_ci{
3608c2ecf20Sopenharmony_ci	return flow_dissector->used_keys & (1 << key_id);
3618c2ecf20Sopenharmony_ci}
3628c2ecf20Sopenharmony_ci
3638c2ecf20Sopenharmony_cistatic inline void *skb_flow_dissector_target(struct flow_dissector *flow_dissector,
3648c2ecf20Sopenharmony_ci					      enum flow_dissector_key_id key_id,
3658c2ecf20Sopenharmony_ci					      void *target_container)
3668c2ecf20Sopenharmony_ci{
3678c2ecf20Sopenharmony_ci	return ((char *)target_container) + flow_dissector->offset[key_id];
3688c2ecf20Sopenharmony_ci}
3698c2ecf20Sopenharmony_ci
3708c2ecf20Sopenharmony_cistruct bpf_flow_dissector {
3718c2ecf20Sopenharmony_ci	struct bpf_flow_keys	*flow_keys;
3728c2ecf20Sopenharmony_ci	const struct sk_buff	*skb;
3738c2ecf20Sopenharmony_ci	void			*data;
3748c2ecf20Sopenharmony_ci	void			*data_end;
3758c2ecf20Sopenharmony_ci};
3768c2ecf20Sopenharmony_ci
3778c2ecf20Sopenharmony_cistatic inline void
3788c2ecf20Sopenharmony_ciflow_dissector_init_keys(struct flow_dissector_key_control *key_control,
3798c2ecf20Sopenharmony_ci			 struct flow_dissector_key_basic *key_basic)
3808c2ecf20Sopenharmony_ci{
3818c2ecf20Sopenharmony_ci	memset(key_control, 0, sizeof(*key_control));
3828c2ecf20Sopenharmony_ci	memset(key_basic, 0, sizeof(*key_basic));
3838c2ecf20Sopenharmony_ci}
3848c2ecf20Sopenharmony_ci
3858c2ecf20Sopenharmony_ci#ifdef CONFIG_BPF_SYSCALL
3868c2ecf20Sopenharmony_ciint flow_dissector_bpf_prog_attach_check(struct net *net,
3878c2ecf20Sopenharmony_ci					 struct bpf_prog *prog);
3888c2ecf20Sopenharmony_ci#endif /* CONFIG_BPF_SYSCALL */
3898c2ecf20Sopenharmony_ci
3908c2ecf20Sopenharmony_ci#endif
391