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 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 39 struct nf_flow_match { 40 struct flow_dissector dissector; 41 struct nf_flow_key key; 42 struct nf_flow_key mask; 43 }; 44 45 struct nf_flow_rule { 46 struct nf_flow_match match; 47 struct flow_rule *rule; 48 }; 49 50 struct 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 66 enum nf_flowtable_flags { 67 NF_FLOWTABLE_HW_OFFLOAD = 0x1, /* NFT_FLOWTABLE_HW_OFFLOAD */ 68 NF_FLOWTABLE_COUNTER = 0x2, /* NFT_FLOWTABLE_COUNTER */ 69 }; 70 71 struct 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 83 static inline bool nf_flowtable_hw_offload(struct nf_flowtable *flowtable) 84 { 85 return flowtable->flags & NF_FLOWTABLE_HW_OFFLOAD; 86 } 87 88 enum 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 94 enum 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 103 struct 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 148 struct flow_offload_tuple_rhash { 149 struct rhash_head node; 150 struct flow_offload_tuple tuple; 151 }; 152 153 enum 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 163 enum flow_offload_type { 164 NF_FLOW_OFFLOAD_UNSPEC = 0, 165 NF_FLOW_OFFLOAD_ROUTE, 166 }; 167 168 struct 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 180 unsigned long flow_offload_get_timeout(struct flow_offload *flow); 181 182 static inline __s32 nf_flow_timeout_delta(unsigned int timeout) 183 { 184 return (__s32)(timeout - nf_flowtable_time_stamp); 185 } 186 187 struct 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 209 struct flow_offload *flow_offload_alloc(struct nf_conn *ct); 210 void flow_offload_free(struct flow_offload *flow); 211 212 static inline int 213 nf_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 235 unlock: 236 up_write(&flow_table->flow_block_lock); 237 return err; 238 } 239 240 static inline void 241 nf_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 258 int flow_offload_route_init(struct flow_offload *flow, 259 const struct nf_flow_route *route); 260 261 int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow); 262 void flow_offload_refresh(struct nf_flowtable *flow_table, 263 struct flow_offload *flow); 264 265 struct flow_offload_tuple_rhash *flow_offload_lookup(struct nf_flowtable *flow_table, 266 struct flow_offload_tuple *tuple); 267 void nf_flow_table_gc_cleanup(struct nf_flowtable *flowtable, 268 struct net_device *dev); 269 void nf_flow_table_cleanup(struct net_device *dev); 270 271 int nf_flow_table_init(struct nf_flowtable *flow_table); 272 void nf_flow_table_free(struct nf_flowtable *flow_table); 273 274 void flow_offload_teardown(struct flow_offload *flow); 275 276 void 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); 279 void 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 283 struct flow_ports { 284 __be16 source, dest; 285 }; 286 287 unsigned int nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb, 288 const struct nf_hook_state *state); 289 unsigned 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 295 void nf_flow_offload_add(struct nf_flowtable *flowtable, 296 struct flow_offload *flow); 297 void nf_flow_offload_del(struct nf_flowtable *flowtable, 298 struct flow_offload *flow); 299 void nf_flow_offload_stats(struct nf_flowtable *flowtable, 300 struct flow_offload *flow); 301 302 void nf_flow_table_offload_flush(struct nf_flowtable *flowtable); 303 int nf_flow_table_offload_setup(struct nf_flowtable *flowtable, 304 struct net_device *dev, 305 enum flow_block_command cmd); 306 int 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); 309 int 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 313 int nf_flow_table_offload_init(void); 314 void nf_flow_table_offload_exit(void); 315 316 #endif /* _NF_FLOW_TABLE_H */ 317