cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

flow_dissector.h (10445B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2#ifndef _NET_FLOW_DISSECTOR_H
      3#define _NET_FLOW_DISSECTOR_H
      4
      5#include <linux/types.h>
      6#include <linux/in6.h>
      7#include <linux/siphash.h>
      8#include <linux/string.h>
      9#include <uapi/linux/if_ether.h>
     10
     11struct bpf_prog;
     12struct net;
     13struct sk_buff;
     14
     15/**
     16 * struct flow_dissector_key_control:
     17 * @thoff: Transport header offset
     18 */
     19struct flow_dissector_key_control {
     20	u16	thoff;
     21	u16	addr_type;
     22	u32	flags;
     23};
     24
     25#define FLOW_DIS_IS_FRAGMENT	BIT(0)
     26#define FLOW_DIS_FIRST_FRAG	BIT(1)
     27#define FLOW_DIS_ENCAPSULATION	BIT(2)
     28
     29enum flow_dissect_ret {
     30	FLOW_DISSECT_RET_OUT_GOOD,
     31	FLOW_DISSECT_RET_OUT_BAD,
     32	FLOW_DISSECT_RET_PROTO_AGAIN,
     33	FLOW_DISSECT_RET_IPPROTO_AGAIN,
     34	FLOW_DISSECT_RET_CONTINUE,
     35};
     36
     37/**
     38 * struct flow_dissector_key_basic:
     39 * @n_proto: Network header protocol (eg. IPv4/IPv6)
     40 * @ip_proto: Transport header protocol (eg. TCP/UDP)
     41 */
     42struct flow_dissector_key_basic {
     43	__be16	n_proto;
     44	u8	ip_proto;
     45	u8	padding;
     46};
     47
     48struct flow_dissector_key_tags {
     49	u32	flow_label;
     50};
     51
     52struct flow_dissector_key_vlan {
     53	union {
     54		struct {
     55			u16	vlan_id:12,
     56				vlan_dei:1,
     57				vlan_priority:3;
     58		};
     59		__be16	vlan_tci;
     60	};
     61	__be16	vlan_tpid;
     62	__be16	vlan_eth_type;
     63	u16	padding;
     64};
     65
     66struct flow_dissector_mpls_lse {
     67	u32	mpls_ttl:8,
     68		mpls_bos:1,
     69		mpls_tc:3,
     70		mpls_label:20;
     71};
     72
     73#define FLOW_DIS_MPLS_MAX 7
     74struct flow_dissector_key_mpls {
     75	struct flow_dissector_mpls_lse ls[FLOW_DIS_MPLS_MAX]; /* Label Stack */
     76	u8 used_lses; /* One bit set for each Label Stack Entry in use */
     77};
     78
     79static inline void dissector_set_mpls_lse(struct flow_dissector_key_mpls *mpls,
     80					  int lse_index)
     81{
     82	mpls->used_lses |= 1 << lse_index;
     83}
     84
     85#define FLOW_DIS_TUN_OPTS_MAX 255
     86/**
     87 * struct flow_dissector_key_enc_opts:
     88 * @data: tunnel option data
     89 * @len: length of tunnel option data
     90 * @dst_opt_type: tunnel option type
     91 */
     92struct flow_dissector_key_enc_opts {
     93	u8 data[FLOW_DIS_TUN_OPTS_MAX];	/* Using IP_TUNNEL_OPTS_MAX is desired
     94					 * here but seems difficult to #include
     95					 */
     96	u8 len;
     97	__be16 dst_opt_type;
     98};
     99
    100struct flow_dissector_key_keyid {
    101	__be32	keyid;
    102};
    103
    104/**
    105 * struct flow_dissector_key_ipv4_addrs:
    106 * @src: source ip address
    107 * @dst: destination ip address
    108 */
    109struct flow_dissector_key_ipv4_addrs {
    110	/* (src,dst) must be grouped, in the same way than in IP header */
    111	__be32 src;
    112	__be32 dst;
    113};
    114
    115/**
    116 * struct flow_dissector_key_ipv6_addrs:
    117 * @src: source ip address
    118 * @dst: destination ip address
    119 */
    120struct flow_dissector_key_ipv6_addrs {
    121	/* (src,dst) must be grouped, in the same way than in IP header */
    122	struct in6_addr src;
    123	struct in6_addr dst;
    124};
    125
    126/**
    127 * struct flow_dissector_key_tipc:
    128 * @key: source node address combined with selector
    129 */
    130struct flow_dissector_key_tipc {
    131	__be32 key;
    132};
    133
    134/**
    135 * struct flow_dissector_key_addrs:
    136 * @v4addrs: IPv4 addresses
    137 * @v6addrs: IPv6 addresses
    138 */
    139struct flow_dissector_key_addrs {
    140	union {
    141		struct flow_dissector_key_ipv4_addrs v4addrs;
    142		struct flow_dissector_key_ipv6_addrs v6addrs;
    143		struct flow_dissector_key_tipc tipckey;
    144	};
    145};
    146
    147/**
    148 * flow_dissector_key_arp:
    149 *	@ports: Operation, source and target addresses for an ARP header
    150 *              for Ethernet hardware addresses and IPv4 protocol addresses
    151 *		sip: Sender IP address
    152 *		tip: Target IP address
    153 *		op:  Operation
    154 *		sha: Sender hardware address
    155 *		tpa: Target hardware address
    156 */
    157struct flow_dissector_key_arp {
    158	__u32 sip;
    159	__u32 tip;
    160	__u8 op;
    161	unsigned char sha[ETH_ALEN];
    162	unsigned char tha[ETH_ALEN];
    163};
    164
    165/**
    166 * flow_dissector_key_tp_ports:
    167 *	@ports: port numbers of Transport header
    168 *		src: source port number
    169 *		dst: destination port number
    170 */
    171struct flow_dissector_key_ports {
    172	union {
    173		__be32 ports;
    174		struct {
    175			__be16 src;
    176			__be16 dst;
    177		};
    178	};
    179};
    180
    181/**
    182 * flow_dissector_key_icmp:
    183 *		type: ICMP type
    184 *		code: ICMP code
    185 *		id:   session identifier
    186 */
    187struct flow_dissector_key_icmp {
    188	struct {
    189		u8 type;
    190		u8 code;
    191	};
    192	u16 id;
    193};
    194
    195/**
    196 * struct flow_dissector_key_eth_addrs:
    197 * @src: source Ethernet address
    198 * @dst: destination Ethernet address
    199 */
    200struct flow_dissector_key_eth_addrs {
    201	/* (dst,src) must be grouped, in the same way than in ETH header */
    202	unsigned char dst[ETH_ALEN];
    203	unsigned char src[ETH_ALEN];
    204};
    205
    206/**
    207 * struct flow_dissector_key_tcp:
    208 * @flags: flags
    209 */
    210struct flow_dissector_key_tcp {
    211	__be16 flags;
    212};
    213
    214/**
    215 * struct flow_dissector_key_ip:
    216 * @tos: tos
    217 * @ttl: ttl
    218 */
    219struct flow_dissector_key_ip {
    220	__u8	tos;
    221	__u8	ttl;
    222};
    223
    224/**
    225 * struct flow_dissector_key_meta:
    226 * @ingress_ifindex: ingress ifindex
    227 * @ingress_iftype: ingress interface type
    228 */
    229struct flow_dissector_key_meta {
    230	int ingress_ifindex;
    231	u16 ingress_iftype;
    232};
    233
    234/**
    235 * struct flow_dissector_key_ct:
    236 * @ct_state: conntrack state after converting with map
    237 * @ct_mark: conttrack mark
    238 * @ct_zone: conntrack zone
    239 * @ct_labels: conntrack labels
    240 */
    241struct flow_dissector_key_ct {
    242	u16	ct_state;
    243	u16	ct_zone;
    244	u32	ct_mark;
    245	u32	ct_labels[4];
    246};
    247
    248/**
    249 * struct flow_dissector_key_hash:
    250 * @hash: hash value
    251 */
    252struct flow_dissector_key_hash {
    253	u32 hash;
    254};
    255
    256/**
    257 * struct flow_dissector_key_num_of_vlans:
    258 * @num_of_vlans: num_of_vlans value
    259 */
    260struct flow_dissector_key_num_of_vlans {
    261	u8 num_of_vlans;
    262};
    263
    264enum flow_dissector_key_id {
    265	FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
    266	FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
    267	FLOW_DISSECTOR_KEY_IPV4_ADDRS, /* struct flow_dissector_key_ipv4_addrs */
    268	FLOW_DISSECTOR_KEY_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */
    269	FLOW_DISSECTOR_KEY_PORTS, /* struct flow_dissector_key_ports */
    270	FLOW_DISSECTOR_KEY_PORTS_RANGE, /* struct flow_dissector_key_ports */
    271	FLOW_DISSECTOR_KEY_ICMP, /* struct flow_dissector_key_icmp */
    272	FLOW_DISSECTOR_KEY_ETH_ADDRS, /* struct flow_dissector_key_eth_addrs */
    273	FLOW_DISSECTOR_KEY_TIPC, /* struct flow_dissector_key_tipc */
    274	FLOW_DISSECTOR_KEY_ARP, /* struct flow_dissector_key_arp */
    275	FLOW_DISSECTOR_KEY_VLAN, /* struct flow_dissector_key_vlan */
    276	FLOW_DISSECTOR_KEY_FLOW_LABEL, /* struct flow_dissector_key_tags */
    277	FLOW_DISSECTOR_KEY_GRE_KEYID, /* struct flow_dissector_key_keyid */
    278	FLOW_DISSECTOR_KEY_MPLS_ENTROPY, /* struct flow_dissector_key_keyid */
    279	FLOW_DISSECTOR_KEY_ENC_KEYID, /* struct flow_dissector_key_keyid */
    280	FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS, /* struct flow_dissector_key_ipv4_addrs */
    281	FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */
    282	FLOW_DISSECTOR_KEY_ENC_CONTROL, /* struct flow_dissector_key_control */
    283	FLOW_DISSECTOR_KEY_ENC_PORTS, /* struct flow_dissector_key_ports */
    284	FLOW_DISSECTOR_KEY_MPLS, /* struct flow_dissector_key_mpls */
    285	FLOW_DISSECTOR_KEY_TCP, /* struct flow_dissector_key_tcp */
    286	FLOW_DISSECTOR_KEY_IP, /* struct flow_dissector_key_ip */
    287	FLOW_DISSECTOR_KEY_CVLAN, /* struct flow_dissector_key_vlan */
    288	FLOW_DISSECTOR_KEY_ENC_IP, /* struct flow_dissector_key_ip */
    289	FLOW_DISSECTOR_KEY_ENC_OPTS, /* struct flow_dissector_key_enc_opts */
    290	FLOW_DISSECTOR_KEY_META, /* struct flow_dissector_key_meta */
    291	FLOW_DISSECTOR_KEY_CT, /* struct flow_dissector_key_ct */
    292	FLOW_DISSECTOR_KEY_HASH, /* struct flow_dissector_key_hash */
    293	FLOW_DISSECTOR_KEY_NUM_OF_VLANS, /* struct flow_dissector_key_num_of_vlans */
    294
    295	FLOW_DISSECTOR_KEY_MAX,
    296};
    297
    298#define FLOW_DISSECTOR_F_PARSE_1ST_FRAG		BIT(0)
    299#define FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL	BIT(1)
    300#define FLOW_DISSECTOR_F_STOP_AT_ENCAP		BIT(2)
    301#define FLOW_DISSECTOR_F_STOP_BEFORE_ENCAP	BIT(3)
    302
    303struct flow_dissector_key {
    304	enum flow_dissector_key_id key_id;
    305	size_t offset; /* offset of struct flow_dissector_key_*
    306			  in target the struct */
    307};
    308
    309struct flow_dissector {
    310	unsigned int used_keys; /* each bit repesents presence of one key id */
    311	unsigned short int offset[FLOW_DISSECTOR_KEY_MAX];
    312};
    313
    314struct flow_keys_basic {
    315	struct flow_dissector_key_control control;
    316	struct flow_dissector_key_basic basic;
    317};
    318
    319struct flow_keys {
    320	struct flow_dissector_key_control control;
    321#define FLOW_KEYS_HASH_START_FIELD basic
    322	struct flow_dissector_key_basic basic __aligned(SIPHASH_ALIGNMENT);
    323	struct flow_dissector_key_tags tags;
    324	struct flow_dissector_key_vlan vlan;
    325	struct flow_dissector_key_vlan cvlan;
    326	struct flow_dissector_key_keyid keyid;
    327	struct flow_dissector_key_ports ports;
    328	struct flow_dissector_key_icmp icmp;
    329	/* 'addrs' must be the last member */
    330	struct flow_dissector_key_addrs addrs;
    331};
    332
    333#define FLOW_KEYS_HASH_OFFSET		\
    334	offsetof(struct flow_keys, FLOW_KEYS_HASH_START_FIELD)
    335
    336__be32 flow_get_u32_src(const struct flow_keys *flow);
    337__be32 flow_get_u32_dst(const struct flow_keys *flow);
    338
    339extern struct flow_dissector flow_keys_dissector;
    340extern struct flow_dissector flow_keys_basic_dissector;
    341
    342/* struct flow_keys_digest:
    343 *
    344 * This structure is used to hold a digest of the full flow keys. This is a
    345 * larger "hash" of a flow to allow definitively matching specific flows where
    346 * the 32 bit skb->hash is not large enough. The size is limited to 16 bytes so
    347 * that it can be used in CB of skb (see sch_choke for an example).
    348 */
    349#define FLOW_KEYS_DIGEST_LEN	16
    350struct flow_keys_digest {
    351	u8	data[FLOW_KEYS_DIGEST_LEN];
    352};
    353
    354void make_flow_keys_digest(struct flow_keys_digest *digest,
    355			   const struct flow_keys *flow);
    356
    357static inline bool flow_keys_have_l4(const struct flow_keys *keys)
    358{
    359	return (keys->ports.ports || keys->tags.flow_label);
    360}
    361
    362u32 flow_hash_from_keys(struct flow_keys *keys);
    363void skb_flow_get_icmp_tci(const struct sk_buff *skb,
    364			   struct flow_dissector_key_icmp *key_icmp,
    365			   const void *data, int thoff, int hlen);
    366
    367static inline bool dissector_uses_key(const struct flow_dissector *flow_dissector,
    368				      enum flow_dissector_key_id key_id)
    369{
    370	return flow_dissector->used_keys & (1 << key_id);
    371}
    372
    373static inline void *skb_flow_dissector_target(struct flow_dissector *flow_dissector,
    374					      enum flow_dissector_key_id key_id,
    375					      void *target_container)
    376{
    377	return ((char *)target_container) + flow_dissector->offset[key_id];
    378}
    379
    380struct bpf_flow_dissector {
    381	struct bpf_flow_keys	*flow_keys;
    382	const struct sk_buff	*skb;
    383	const void		*data;
    384	const void		*data_end;
    385};
    386
    387static inline void
    388flow_dissector_init_keys(struct flow_dissector_key_control *key_control,
    389			 struct flow_dissector_key_basic *key_basic)
    390{
    391	memset(key_control, 0, sizeof(*key_control));
    392	memset(key_basic, 0, sizeof(*key_basic));
    393}
    394
    395#ifdef CONFIG_BPF_SYSCALL
    396int flow_dissector_bpf_prog_attach_check(struct net *net,
    397					 struct bpf_prog *prog);
    398#endif /* CONFIG_BPF_SYSCALL */
    399
    400#endif