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