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