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