linux/include/net/netfilter/nf_flow_table.h
<<
>>
Prefs
   1#ifndef _NF_FLOW_TABLE_H
   2#define _NF_FLOW_TABLE_H
   3
   4#include <linux/in.h>
   5#include <linux/in6.h>
   6#include <linux/netdevice.h>
   7#include <linux/rhashtable-types.h>
   8#include <linux/rcupdate.h>
   9#include <linux/netfilter.h>
  10#include <linux/netfilter/nf_conntrack_tuple_common.h>
  11#include <net/flow_offload.h>
  12#include <net/dst.h>
  13
  14struct nf_flowtable;
  15struct nf_flow_rule;
  16struct flow_offload;
  17enum flow_offload_tuple_dir;
  18
  19struct nf_flow_key {
  20        struct flow_dissector_key_meta                  meta;
  21        struct flow_dissector_key_control               control;
  22        struct flow_dissector_key_control               enc_control;
  23        struct flow_dissector_key_basic                 basic;
  24        struct flow_dissector_key_vlan                  vlan;
  25        struct flow_dissector_key_vlan                  cvlan;
  26        union {
  27                struct flow_dissector_key_ipv4_addrs    ipv4;
  28                struct flow_dissector_key_ipv6_addrs    ipv6;
  29        };
  30        struct flow_dissector_key_keyid                 enc_key_id;
  31        union {
  32                struct flow_dissector_key_ipv4_addrs    enc_ipv4;
  33                struct flow_dissector_key_ipv6_addrs    enc_ipv6;
  34        };
  35        struct flow_dissector_key_tcp                   tcp;
  36        struct flow_dissector_key_ports                 tp;
  37} __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. */
  38
  39struct nf_flow_match {
  40        struct flow_dissector   dissector;
  41        struct nf_flow_key      key;
  42        struct nf_flow_key      mask;
  43};
  44
  45struct nf_flow_rule {
  46        struct nf_flow_match    match;
  47        struct flow_rule        *rule;
  48};
  49
  50struct nf_flowtable_type {
  51        struct list_head                list;
  52        int                             family;
  53        int                             (*init)(struct nf_flowtable *ft);
  54        int                             (*setup)(struct nf_flowtable *ft,
  55                                                 struct net_device *dev,
  56                                                 enum flow_block_command cmd);
  57        int                             (*action)(struct net *net,
  58                                                  const struct flow_offload *flow,
  59                                                  enum flow_offload_tuple_dir dir,
  60                                                  struct nf_flow_rule *flow_rule);
  61        void                            (*free)(struct nf_flowtable *ft);
  62        nf_hookfn                       *hook;
  63        struct module                   *owner;
  64};
  65
  66enum nf_flowtable_flags {
  67        NF_FLOWTABLE_HW_OFFLOAD         = 0x1,  /* NFT_FLOWTABLE_HW_OFFLOAD */
  68        NF_FLOWTABLE_COUNTER            = 0x2,  /* NFT_FLOWTABLE_COUNTER */
  69};
  70
  71struct nf_flowtable {
  72        struct list_head                list;
  73        struct rhashtable               rhashtable;
  74        int                             priority;
  75        const struct nf_flowtable_type  *type;
  76        struct delayed_work             gc_work;
  77        unsigned int                    flags;
  78        struct flow_block               flow_block;
  79        struct rw_semaphore             flow_block_lock; /* Guards flow_block */
  80        possible_net_t                  net;
  81};
  82
  83static inline bool nf_flowtable_hw_offload(struct nf_flowtable *flowtable)
  84{
  85        return flowtable->flags & NF_FLOWTABLE_HW_OFFLOAD;
  86}
  87
  88enum flow_offload_tuple_dir {
  89        FLOW_OFFLOAD_DIR_ORIGINAL = IP_CT_DIR_ORIGINAL,
  90        FLOW_OFFLOAD_DIR_REPLY = IP_CT_DIR_REPLY,
  91};
  92#define FLOW_OFFLOAD_DIR_MAX    IP_CT_DIR_MAX
  93
  94enum flow_offload_xmit_type {
  95        FLOW_OFFLOAD_XMIT_UNSPEC        = 0,
  96        FLOW_OFFLOAD_XMIT_NEIGH,
  97        FLOW_OFFLOAD_XMIT_XFRM,
  98        FLOW_OFFLOAD_XMIT_DIRECT,
  99};
 100
 101#define NF_FLOW_TABLE_ENCAP_MAX         2
 102
 103struct flow_offload_tuple {
 104        union {
 105                struct in_addr          src_v4;
 106                struct in6_addr         src_v6;
 107        };
 108        union {
 109                struct in_addr          dst_v4;
 110                struct in6_addr         dst_v6;
 111        };
 112        struct {
 113                __be16                  src_port;
 114                __be16                  dst_port;
 115        };
 116
 117        int                             iifidx;
 118
 119        u8                              l3proto;
 120        u8                              l4proto;
 121        struct {
 122                u16                     id;
 123                __be16                  proto;
 124        } encap[NF_FLOW_TABLE_ENCAP_MAX];
 125
 126        /* All members above are keys for lookups, see flow_offload_hash(). */
 127        struct { }                      __hash;
 128
 129        u8                              dir:2,
 130                                        xmit_type:2,
 131                                        encap_num:2,
 132                                        in_vlan_ingress:2;
 133        u16                             mtu;
 134        union {
 135                struct {
 136                        struct dst_entry *dst_cache;
 137                        u32             dst_cookie;
 138                };
 139                struct {
 140                        u32             ifidx;
 141                        u32             hw_ifidx;
 142                        u8              h_source[ETH_ALEN];
 143                        u8              h_dest[ETH_ALEN];
 144                } out;
 145        };
 146};
 147
 148struct flow_offload_tuple_rhash {
 149        struct rhash_head               node;
 150        struct flow_offload_tuple       tuple;
 151};
 152
 153enum nf_flow_flags {
 154        NF_FLOW_SNAT,
 155        NF_FLOW_DNAT,
 156        NF_FLOW_TEARDOWN,
 157        NF_FLOW_HW,
 158        NF_FLOW_HW_DYING,
 159        NF_FLOW_HW_DEAD,
 160        NF_FLOW_HW_PENDING,
 161};
 162
 163enum flow_offload_type {
 164        NF_FLOW_OFFLOAD_UNSPEC  = 0,
 165        NF_FLOW_OFFLOAD_ROUTE,
 166};
 167
 168struct flow_offload {
 169        struct flow_offload_tuple_rhash         tuplehash[FLOW_OFFLOAD_DIR_MAX];
 170        struct nf_conn                          *ct;
 171        unsigned long                           flags;
 172        u16                                     type;
 173        u32                                     timeout;
 174        struct rcu_head                         rcu_head;
 175};
 176
 177#define NF_FLOW_TIMEOUT (30 * HZ)
 178#define nf_flowtable_time_stamp (u32)jiffies
 179
 180unsigned long flow_offload_get_timeout(struct flow_offload *flow);
 181
 182static inline __s32 nf_flow_timeout_delta(unsigned int timeout)
 183{
 184        return (__s32)(timeout - nf_flowtable_time_stamp);
 185}
 186
 187struct nf_flow_route {
 188        struct {
 189                struct dst_entry                *dst;
 190                struct {
 191                        u32                     ifindex;
 192                        struct {
 193                                u16             id;
 194                                __be16          proto;
 195                        } encap[NF_FLOW_TABLE_ENCAP_MAX];
 196                        u8                      num_encaps:2,
 197                                                ingress_vlans:2;
 198                } in;
 199                struct {
 200                        u32                     ifindex;
 201                        u32                     hw_ifindex;
 202                        u8                      h_source[ETH_ALEN];
 203                        u8                      h_dest[ETH_ALEN];
 204                } out;
 205                enum flow_offload_xmit_type     xmit_type;
 206        } tuple[FLOW_OFFLOAD_DIR_MAX];
 207};
 208
 209struct flow_offload *flow_offload_alloc(struct nf_conn *ct);
 210void flow_offload_free(struct flow_offload *flow);
 211
 212static inline int
 213nf_flow_table_offload_add_cb(struct nf_flowtable *flow_table,
 214                             flow_setup_cb_t *cb, void *cb_priv)
 215{
 216        struct flow_block *block = &flow_table->flow_block;
 217        struct flow_block_cb *block_cb;
 218        int err = 0;
 219
 220        down_write(&flow_table->flow_block_lock);
 221        block_cb = flow_block_cb_lookup(block, cb, cb_priv);
 222        if (block_cb) {
 223                err = -EEXIST;
 224                goto unlock;
 225        }
 226
 227        block_cb = flow_block_cb_alloc(cb, cb_priv, cb_priv, NULL);
 228        if (IS_ERR(block_cb)) {
 229                err = PTR_ERR(block_cb);
 230                goto unlock;
 231        }
 232
 233        list_add_tail(&block_cb->list, &block->cb_list);
 234
 235unlock:
 236        up_write(&flow_table->flow_block_lock);
 237        return err;
 238}
 239
 240static inline void
 241nf_flow_table_offload_del_cb(struct nf_flowtable *flow_table,
 242                             flow_setup_cb_t *cb, void *cb_priv)
 243{
 244        struct flow_block *block = &flow_table->flow_block;
 245        struct flow_block_cb *block_cb;
 246
 247        down_write(&flow_table->flow_block_lock);
 248        block_cb = flow_block_cb_lookup(block, cb, cb_priv);
 249        if (block_cb) {
 250                list_del(&block_cb->list);
 251                flow_block_cb_free(block_cb);
 252        } else {
 253                WARN_ON(true);
 254        }
 255        up_write(&flow_table->flow_block_lock);
 256}
 257
 258int flow_offload_route_init(struct flow_offload *flow,
 259                            const struct nf_flow_route *route);
 260
 261int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow);
 262void flow_offload_refresh(struct nf_flowtable *flow_table,
 263                          struct flow_offload *flow);
 264
 265struct flow_offload_tuple_rhash *flow_offload_lookup(struct nf_flowtable *flow_table,
 266                                                     struct flow_offload_tuple *tuple);
 267void nf_flow_table_gc_cleanup(struct nf_flowtable *flowtable,
 268                              struct net_device *dev);
 269void nf_flow_table_cleanup(struct net_device *dev);
 270
 271int nf_flow_table_init(struct nf_flowtable *flow_table);
 272void nf_flow_table_free(struct nf_flowtable *flow_table);
 273
 274void flow_offload_teardown(struct flow_offload *flow);
 275
 276void nf_flow_snat_port(const struct flow_offload *flow,
 277                       struct sk_buff *skb, unsigned int thoff,
 278                       u8 protocol, enum flow_offload_tuple_dir dir);
 279void nf_flow_dnat_port(const struct flow_offload *flow,
 280                       struct sk_buff *skb, unsigned int thoff,
 281                       u8 protocol, enum flow_offload_tuple_dir dir);
 282
 283struct flow_ports {
 284        __be16 source, dest;
 285};
 286
 287unsigned int nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb,
 288                                     const struct nf_hook_state *state);
 289unsigned int nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,
 290                                       const struct nf_hook_state *state);
 291
 292#define MODULE_ALIAS_NF_FLOWTABLE(family)       \
 293        MODULE_ALIAS("nf-flowtable-" __stringify(family))
 294
 295void nf_flow_offload_add(struct nf_flowtable *flowtable,
 296                         struct flow_offload *flow);
 297void nf_flow_offload_del(struct nf_flowtable *flowtable,
 298                         struct flow_offload *flow);
 299void nf_flow_offload_stats(struct nf_flowtable *flowtable,
 300                           struct flow_offload *flow);
 301
 302void nf_flow_table_offload_flush(struct nf_flowtable *flowtable);
 303int nf_flow_table_offload_setup(struct nf_flowtable *flowtable,
 304                                struct net_device *dev,
 305                                enum flow_block_command cmd);
 306int nf_flow_rule_route_ipv4(struct net *net, const struct flow_offload *flow,
 307                            enum flow_offload_tuple_dir dir,
 308                            struct nf_flow_rule *flow_rule);
 309int nf_flow_rule_route_ipv6(struct net *net, const struct flow_offload *flow,
 310                            enum flow_offload_tuple_dir dir,
 311                            struct nf_flow_rule *flow_rule);
 312
 313int nf_flow_table_offload_init(void);
 314void nf_flow_table_offload_exit(void);
 315
 316#endif /* _NF_FLOW_TABLE_H */
 317