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