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