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