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