]>
Commit | Line | Data |
---|---|---|
3b49e2e9 PNA |
1 | #ifndef _NF_FLOW_TABLE_H |
2 | #define _NF_FLOW_TABLE_H | |
3 | ||
ac2a6666 PNA |
4 | #include <linux/in.h> |
5 | #include <linux/in6.h> | |
6 | #include <linux/netdevice.h> | |
0eb71a9d | 7 | #include <linux/rhashtable-types.h> |
ac2a6666 | 8 | #include <linux/rcupdate.h> |
a1b2f04e | 9 | #include <linux/netfilter.h> |
af81f9e7 | 10 | #include <linux/netfilter/nf_conntrack_tuple_common.h> |
8bb69f3b | 11 | #include <net/flow_offload.h> |
ac2a6666 | 12 | #include <net/dst.h> |
3b49e2e9 PNA |
13 | |
14 | struct nf_flowtable; | |
c29f74e0 PNA |
15 | struct nf_flow_rule; |
16 | struct flow_offload; | |
17 | enum flow_offload_tuple_dir; | |
3b49e2e9 | 18 | |
9c26ba9b PB |
19 | struct nf_flow_key { |
20 | struct flow_dissector_key_meta meta; | |
21 | struct flow_dissector_key_control control; | |
cfab6dbd | 22 | struct flow_dissector_key_control enc_control; |
9c26ba9b PB |
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 | }; | |
cfab6dbd | 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 | }; | |
9c26ba9b PB |
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 | ||
3b49e2e9 PNA |
48 | struct nf_flowtable_type { |
49 | struct list_head list; | |
50 | int family; | |
a268de77 | 51 | int (*init)(struct nf_flowtable *ft); |
8bb69f3b PNA |
52 | int (*setup)(struct nf_flowtable *ft, |
53 | struct net_device *dev, | |
54 | enum flow_block_command cmd); | |
c29f74e0 PNA |
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); | |
b408c5b0 | 59 | void (*free)(struct nf_flowtable *ft); |
3b49e2e9 PNA |
60 | nf_hookfn *hook; |
61 | struct module *owner; | |
62 | }; | |
63 | ||
8bb69f3b | 64 | enum nf_flowtable_flags { |
cfbd1125 | 65 | NF_FLOWTABLE_HW_OFFLOAD = 0x1, /* NFT_FLOWTABLE_HW_OFFLOAD */ |
53c2b289 | 66 | NF_FLOWTABLE_COUNTER = 0x2, /* NFT_FLOWTABLE_COUNTER */ |
8bb69f3b PNA |
67 | }; |
68 | ||
3b49e2e9 | 69 | struct nf_flowtable { |
84453a90 | 70 | struct list_head list; |
3b49e2e9 | 71 | struct rhashtable rhashtable; |
71a8a63b | 72 | int priority; |
3b49e2e9 PNA |
73 | const struct nf_flowtable_type *type; |
74 | struct delayed_work gc_work; | |
8bb69f3b PNA |
75 | unsigned int flags; |
76 | struct flow_block flow_block; | |
422c032a | 77 | struct rw_semaphore flow_block_lock; /* Guards flow_block */ |
8bb69f3b | 78 | possible_net_t net; |
3b49e2e9 PNA |
79 | }; |
80 | ||
a5449cdc PNA |
81 | static inline bool nf_flowtable_hw_offload(struct nf_flowtable *flowtable) |
82 | { | |
83 | return flowtable->flags & NF_FLOWTABLE_HW_OFFLOAD; | |
84 | } | |
85 | ||
ac2a6666 | 86 | enum flow_offload_tuple_dir { |
af81f9e7 FF |
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 | |
ac2a6666 | 90 | }; |
ac2a6666 PNA |
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 | u8 dir; | |
111 | ||
4f3780c0 FF |
112 | u16 mtu; |
113 | ||
ac2a6666 PNA |
114 | struct dst_entry *dst_cache; |
115 | }; | |
116 | ||
117 | struct flow_offload_tuple_rhash { | |
118 | struct rhash_head node; | |
119 | struct flow_offload_tuple tuple; | |
120 | }; | |
121 | ||
355a8b13 PNA |
122 | enum nf_flow_flags { |
123 | NF_FLOW_SNAT, | |
124 | NF_FLOW_DNAT, | |
125 | NF_FLOW_TEARDOWN, | |
126 | NF_FLOW_HW, | |
127 | NF_FLOW_HW_DYING, | |
128 | NF_FLOW_HW_DEAD, | |
f698fe40 | 129 | NF_FLOW_HW_REFRESH, |
355a8b13 | 130 | }; |
ac2a6666 | 131 | |
f1363e05 PNA |
132 | enum flow_offload_type { |
133 | NF_FLOW_OFFLOAD_UNSPEC = 0, | |
134 | NF_FLOW_OFFLOAD_ROUTE, | |
135 | }; | |
136 | ||
ac2a6666 PNA |
137 | struct flow_offload { |
138 | struct flow_offload_tuple_rhash tuplehash[FLOW_OFFLOAD_DIR_MAX]; | |
b32d2f34 | 139 | struct nf_conn *ct; |
355a8b13 | 140 | unsigned long flags; |
f1363e05 | 141 | u16 type; |
9f48e9bf | 142 | u32 timeout; |
62248df8 | 143 | struct rcu_head rcu_head; |
ac2a6666 PNA |
144 | }; |
145 | ||
146 | #define NF_FLOW_TIMEOUT (30 * HZ) | |
fb46f1b7 PNA |
147 | #define nf_flowtable_time_stamp (u32)jiffies |
148 | ||
149 | static inline __s32 nf_flow_timeout_delta(unsigned int timeout) | |
150 | { | |
151 | return (__s32)(timeout - nf_flowtable_time_stamp); | |
152 | } | |
ac2a6666 PNA |
153 | |
154 | struct nf_flow_route { | |
155 | struct { | |
156 | struct dst_entry *dst; | |
ac2a6666 PNA |
157 | } tuple[FLOW_OFFLOAD_DIR_MAX]; |
158 | }; | |
159 | ||
f1363e05 | 160 | struct flow_offload *flow_offload_alloc(struct nf_conn *ct); |
ac2a6666 PNA |
161 | void flow_offload_free(struct flow_offload *flow); |
162 | ||
978703f4 PB |
163 | int nf_flow_table_offload_add_cb(struct nf_flowtable *flow_table, |
164 | flow_setup_cb_t *cb, void *cb_priv); | |
165 | void nf_flow_table_offload_del_cb(struct nf_flowtable *flow_table, | |
166 | flow_setup_cb_t *cb, void *cb_priv); | |
167 | ||
f1363e05 PNA |
168 | int flow_offload_route_init(struct flow_offload *flow, |
169 | const struct nf_flow_route *route); | |
170 | ||
ac2a6666 | 171 | int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow); |
8b3646d6 PB |
172 | void flow_offload_refresh(struct nf_flowtable *flow_table, |
173 | struct flow_offload *flow); | |
174 | ||
ac2a6666 PNA |
175 | struct flow_offload_tuple_rhash *flow_offload_lookup(struct nf_flowtable *flow_table, |
176 | struct flow_offload_tuple *tuple); | |
5f1be84a | 177 | void nf_flow_table_cleanup(struct net_device *dev); |
c0ea1bcb | 178 | |
a268de77 | 179 | int nf_flow_table_init(struct nf_flowtable *flow_table); |
b408c5b0 | 180 | void nf_flow_table_free(struct nf_flowtable *flow_table); |
ac2a6666 | 181 | |
59c466dd | 182 | void flow_offload_teardown(struct flow_offload *flow); |
ac2a6666 PNA |
183 | |
184 | int nf_flow_snat_port(const struct flow_offload *flow, | |
185 | struct sk_buff *skb, unsigned int thoff, | |
186 | u8 protocol, enum flow_offload_tuple_dir dir); | |
187 | int nf_flow_dnat_port(const struct flow_offload *flow, | |
188 | struct sk_buff *skb, unsigned int thoff, | |
189 | u8 protocol, enum flow_offload_tuple_dir dir); | |
190 | ||
191 | struct flow_ports { | |
192 | __be16 source, dest; | |
193 | }; | |
194 | ||
7c23b629 PNA |
195 | unsigned int nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb, |
196 | const struct nf_hook_state *state); | |
197 | unsigned int nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb, | |
198 | const struct nf_hook_state *state); | |
199 | ||
ac2a6666 PNA |
200 | #define MODULE_ALIAS_NF_FLOWTABLE(family) \ |
201 | MODULE_ALIAS("nf-flowtable-" __stringify(family)) | |
202 | ||
c29f74e0 PNA |
203 | void nf_flow_offload_add(struct nf_flowtable *flowtable, |
204 | struct flow_offload *flow); | |
205 | void nf_flow_offload_del(struct nf_flowtable *flowtable, | |
206 | struct flow_offload *flow); | |
207 | void nf_flow_offload_stats(struct nf_flowtable *flowtable, | |
208 | struct flow_offload *flow); | |
209 | ||
210 | void nf_flow_table_offload_flush(struct nf_flowtable *flowtable); | |
211 | int nf_flow_table_offload_setup(struct nf_flowtable *flowtable, | |
212 | struct net_device *dev, | |
213 | enum flow_block_command cmd); | |
5c27d8d7 PNA |
214 | int nf_flow_rule_route_ipv4(struct net *net, const struct flow_offload *flow, |
215 | enum flow_offload_tuple_dir dir, | |
216 | struct nf_flow_rule *flow_rule); | |
217 | int nf_flow_rule_route_ipv6(struct net *net, const struct flow_offload *flow, | |
218 | enum flow_offload_tuple_dir dir, | |
219 | struct nf_flow_rule *flow_rule); | |
c29f74e0 PNA |
220 | |
221 | int nf_flow_table_offload_init(void); | |
222 | void nf_flow_table_offload_exit(void); | |
8bb69f3b | 223 | |
0286fbc6 | 224 | #endif /* _NF_FLOW_TABLE_H */ |