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
 203/**
 204 * struct flow_dissector_key_meta:
 205 * @ingress_ifindex: ingress ifindex
 206 */
 207struct flow_dissector_key_meta {
 208        int ingress_ifindex;
 209};
 210
 211/**
 212 * struct flow_dissector_key_ct:
 213 * @ct_state: conntrack state after converting with map
 214 * @ct_mark: conttrack mark
 215 * @ct_zone: conntrack zone
 216 * @ct_labels: conntrack labels
 217 */
 218struct flow_dissector_key_ct {
 219        u16     ct_state;
 220        u16     ct_zone;
 221        u32     ct_mark;
 222        u32     ct_labels[4];
 223};
 224
 225enum flow_dissector_key_id {
 226        FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
 227        FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
 228        FLOW_DISSECTOR_KEY_IPV4_ADDRS, /* struct flow_dissector_key_ipv4_addrs */
 229        FLOW_DISSECTOR_KEY_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */
 230        FLOW_DISSECTOR_KEY_PORTS, /* struct flow_dissector_key_ports */
 231        FLOW_DISSECTOR_KEY_ICMP, /* struct flow_dissector_key_icmp */
 232        FLOW_DISSECTOR_KEY_ETH_ADDRS, /* struct flow_dissector_key_eth_addrs */
 233        FLOW_DISSECTOR_KEY_TIPC, /* struct flow_dissector_key_tipc */
 234        FLOW_DISSECTOR_KEY_ARP, /* struct flow_dissector_key_arp */
 235        FLOW_DISSECTOR_KEY_VLAN, /* struct flow_dissector_key_vlan */
 236        FLOW_DISSECTOR_KEY_FLOW_LABEL, /* struct flow_dissector_key_tags */
 237        FLOW_DISSECTOR_KEY_GRE_KEYID, /* struct flow_dissector_key_keyid */
 238        FLOW_DISSECTOR_KEY_MPLS_ENTROPY, /* struct flow_dissector_key_keyid */
 239        FLOW_DISSECTOR_KEY_ENC_KEYID, /* struct flow_dissector_key_keyid */
 240        FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS, /* struct flow_dissector_key_ipv4_addrs */
 241        FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */
 242        FLOW_DISSECTOR_KEY_ENC_CONTROL, /* struct flow_dissector_key_control */
 243        FLOW_DISSECTOR_KEY_ENC_PORTS, /* struct flow_dissector_key_ports */
 244        FLOW_DISSECTOR_KEY_MPLS, /* struct flow_dissector_key_mpls */
 245        FLOW_DISSECTOR_KEY_TCP, /* struct flow_dissector_key_tcp */
 246        FLOW_DISSECTOR_KEY_IP, /* struct flow_dissector_key_ip */
 247        FLOW_DISSECTOR_KEY_CVLAN, /* struct flow_dissector_key_vlan */
 248        FLOW_DISSECTOR_KEY_ENC_IP, /* struct flow_dissector_key_ip */
 249        FLOW_DISSECTOR_KEY_ENC_OPTS, /* struct flow_dissector_key_enc_opts */
 250        FLOW_DISSECTOR_KEY_META, /* struct flow_dissector_key_meta */
 251        FLOW_DISSECTOR_KEY_CT, /* struct flow_dissector_key_ct */
 252
 253        FLOW_DISSECTOR_KEY_MAX,
 254};
 255
 256#define FLOW_DISSECTOR_F_PARSE_1ST_FRAG         BIT(0)
 257#define FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL     BIT(1)
 258#define FLOW_DISSECTOR_F_STOP_AT_ENCAP          BIT(2)
 259
 260struct flow_dissector_key {
 261        enum flow_dissector_key_id key_id;
 262        size_t offset; /* offset of struct flow_dissector_key_*
 263                          in target the struct */
 264};
 265
 266struct flow_dissector {
 267        unsigned int used_keys; /* each bit repesents presence of one key id */
 268        unsigned short int offset[FLOW_DISSECTOR_KEY_MAX];
 269};
 270
 271struct flow_keys_basic {
 272        struct flow_dissector_key_control control;
 273        struct flow_dissector_key_basic basic;
 274};
 275
 276struct flow_keys {
 277        struct flow_dissector_key_control control;
 278#define FLOW_KEYS_HASH_START_FIELD basic
 279        struct flow_dissector_key_basic basic;
 280        struct flow_dissector_key_tags tags;
 281        struct flow_dissector_key_vlan vlan;
 282        struct flow_dissector_key_vlan cvlan;
 283        struct flow_dissector_key_keyid keyid;
 284        struct flow_dissector_key_ports ports;
 285        struct flow_dissector_key_addrs addrs;
 286};
 287
 288#define FLOW_KEYS_HASH_OFFSET           \
 289        offsetof(struct flow_keys, FLOW_KEYS_HASH_START_FIELD)
 290
 291__be32 flow_get_u32_src(const struct flow_keys *flow);
 292__be32 flow_get_u32_dst(const struct flow_keys *flow);
 293
 294extern struct flow_dissector flow_keys_dissector;
 295extern struct flow_dissector flow_keys_basic_dissector;
 296
 297/* struct flow_keys_digest:
 298 *
 299 * This structure is used to hold a digest of the full flow keys. This is a
 300 * larger "hash" of a flow to allow definitively matching specific flows where
 301 * the 32 bit skb->hash is not large enough. The size is limited to 16 bytes so
 302 * that it can be used in CB of skb (see sch_choke for an example).
 303 */
 304#define FLOW_KEYS_DIGEST_LEN    16
 305struct flow_keys_digest {
 306        u8      data[FLOW_KEYS_DIGEST_LEN];
 307};
 308
 309void make_flow_keys_digest(struct flow_keys_digest *digest,
 310                           const struct flow_keys *flow);
 311
 312static inline bool flow_keys_have_l4(const struct flow_keys *keys)
 313{
 314        return (keys->ports.ports || keys->tags.flow_label);
 315}
 316
 317u32 flow_hash_from_keys(struct flow_keys *keys);
 318
 319static inline bool dissector_uses_key(const struct flow_dissector *flow_dissector,
 320                                      enum flow_dissector_key_id key_id)
 321{
 322        return flow_dissector->used_keys & (1 << key_id);
 323}
 324
 325static inline void *skb_flow_dissector_target(struct flow_dissector *flow_dissector,
 326                                              enum flow_dissector_key_id key_id,
 327                                              void *target_container)
 328{
 329        return ((char *)target_container) + flow_dissector->offset[key_id];
 330}
 331
 332struct bpf_flow_dissector {
 333        struct bpf_flow_keys    *flow_keys;
 334        const struct sk_buff    *skb;
 335        void                    *data;
 336        void                    *data_end;
 337};
 338
 339#endif
 340