1 // SPDX-License-Identifier: GPL-2.0-only
2 #include <linux/kernel.h>
3 #include <linux/init.h>
4 #include <linux/module.h>
5 #include <linux/netfilter.h>
6 #include <linux/rhashtable.h>
7 #include <linux/netdevice.h>
8 #include <net/ip.h>
9 #include <net/ip6_route.h>
10 #include <net/netfilter/nf_tables.h>
11 #include <net/netfilter/nf_flow_table.h>
12 #include <net/netfilter/nf_conntrack.h>
13 #include <net/netfilter/nf_conntrack_core.h>
14 #include <net/netfilter/nf_conntrack_l4proto.h>
15 #include <net/netfilter/nf_conntrack_tuple.h>
16
17 static DEFINE_MUTEX(flowtable_lock);
18 static LIST_HEAD(flowtables);
19 static __read_mostly struct kmem_cache *flow_offload_cachep;
20
21 static void
flow_offload_fill_dir(struct flow_offload * flow,enum flow_offload_tuple_dir dir)22 flow_offload_fill_dir(struct flow_offload *flow,
23 enum flow_offload_tuple_dir dir)
24 {
25 struct flow_offload_tuple *ft = &flow->tuplehash[dir].tuple;
26 struct nf_conntrack_tuple *ctt = &flow->ct->tuplehash[dir].tuple;
27
28 ft->dir = dir;
29
30 switch (ctt->src.l3num) {
31 case NFPROTO_IPV4:
32 ft->src_v4 = ctt->src.u3.in;
33 ft->dst_v4 = ctt->dst.u3.in;
34 break;
35 case NFPROTO_IPV6:
36 ft->src_v6 = ctt->src.u3.in6;
37 ft->dst_v6 = ctt->dst.u3.in6;
38 break;
39 }
40
41 ft->l3proto = ctt->src.l3num;
42 ft->l4proto = ctt->dst.protonum;
43
44 switch (ctt->dst.protonum) {
45 case IPPROTO_TCP:
46 case IPPROTO_UDP:
47 ft->src_port = ctt->src.u.tcp.port;
48 ft->dst_port = ctt->dst.u.tcp.port;
49 break;
50 }
51 }
52
flow_offload_alloc(struct nf_conn * ct)53 struct flow_offload *flow_offload_alloc(struct nf_conn *ct)
54 {
55 struct flow_offload *flow;
56
57 if (unlikely(nf_ct_is_dying(ct)))
58 return NULL;
59
60 flow = kmem_cache_zalloc(flow_offload_cachep, GFP_ATOMIC);
61 if (!flow)
62 return NULL;
63
64 refcount_inc(&ct->ct_general.use);
65 flow->ct = ct;
66
67 flow_offload_fill_dir(flow, FLOW_OFFLOAD_DIR_ORIGINAL);
68 flow_offload_fill_dir(flow, FLOW_OFFLOAD_DIR_REPLY);
69
70 if (ct->status & IPS_SRC_NAT)
71 __set_bit(NF_FLOW_SNAT, &flow->flags);
72 if (ct->status & IPS_DST_NAT)
73 __set_bit(NF_FLOW_DNAT, &flow->flags);
74
75 return flow;
76 }
77 EXPORT_SYMBOL_GPL(flow_offload_alloc);
78
flow_offload_dst_cookie(struct flow_offload_tuple * flow_tuple)79 static u32 flow_offload_dst_cookie(struct flow_offload_tuple *flow_tuple)
80 {
81 if (flow_tuple->l3proto == NFPROTO_IPV6)
82 return rt6_get_cookie(dst_rt6_info(flow_tuple->dst_cache));
83
84 return 0;
85 }
86
nft_route_dst_fetch(struct nf_flow_route * route,enum flow_offload_tuple_dir dir)87 static struct dst_entry *nft_route_dst_fetch(struct nf_flow_route *route,
88 enum flow_offload_tuple_dir dir)
89 {
90 struct dst_entry *dst = route->tuple[dir].dst;
91
92 route->tuple[dir].dst = NULL;
93
94 return dst;
95 }
96
flow_offload_fill_route(struct flow_offload * flow,struct nf_flow_route * route,enum flow_offload_tuple_dir dir)97 static int flow_offload_fill_route(struct flow_offload *flow,
98 struct nf_flow_route *route,
99 enum flow_offload_tuple_dir dir)
100 {
101 struct flow_offload_tuple *flow_tuple = &flow->tuplehash[dir].tuple;
102 struct dst_entry *dst = nft_route_dst_fetch(route, dir);
103 int i, j = 0;
104
105 switch (flow_tuple->l3proto) {
106 case NFPROTO_IPV4:
107 flow_tuple->mtu = ip_dst_mtu_maybe_forward(dst, true);
108 break;
109 case NFPROTO_IPV6:
110 flow_tuple->mtu = ip6_dst_mtu_maybe_forward(dst, true);
111 break;
112 }
113
114 flow_tuple->iifidx = route->tuple[dir].in.ifindex;
115 for (i = route->tuple[dir].in.num_encaps - 1; i >= 0; i--) {
116 flow_tuple->encap[j].id = route->tuple[dir].in.encap[i].id;
117 flow_tuple->encap[j].proto = route->tuple[dir].in.encap[i].proto;
118 if (route->tuple[dir].in.ingress_vlans & BIT(i))
119 flow_tuple->in_vlan_ingress |= BIT(j);
120 j++;
121 }
122
123 flow_tuple->tun = route->tuple[dir].in.tun;
124 flow_tuple->encap_num = route->tuple[dir].in.num_encaps;
125 flow_tuple->needs_gso_segment = route->tuple[dir].out.needs_gso_segment;
126 flow_tuple->tun_num = route->tuple[dir].in.num_tuns;
127
128 switch (route->tuple[dir].xmit_type) {
129 case FLOW_OFFLOAD_XMIT_DIRECT:
130 if (route->tuple[!dir].in.num_tuns) {
131 flow_tuple->dst_cache = dst;
132 flow_tuple->dst_cookie =
133 flow_offload_dst_cookie(flow_tuple);
134 } else {
135 dst_release(dst);
136 }
137 memcpy(flow_tuple->out.h_dest, route->tuple[dir].out.h_dest,
138 ETH_ALEN);
139 memcpy(flow_tuple->out.h_source, route->tuple[dir].out.h_source,
140 ETH_ALEN);
141 flow_tuple->out.ifidx = route->tuple[dir].out.ifindex;
142 break;
143 case FLOW_OFFLOAD_XMIT_XFRM:
144 case FLOW_OFFLOAD_XMIT_NEIGH:
145 flow_tuple->ifidx = route->tuple[dir].out.ifindex;
146 flow_tuple->dst_cache = dst;
147 flow_tuple->dst_cookie = flow_offload_dst_cookie(flow_tuple);
148 break;
149 default:
150 WARN_ON_ONCE(1);
151 break;
152 }
153 flow_tuple->xmit_type = route->tuple[dir].xmit_type;
154
155 return 0;
156 }
157
nft_flow_dst_release(struct flow_offload * flow,enum flow_offload_tuple_dir dir)158 static void nft_flow_dst_release(struct flow_offload *flow,
159 enum flow_offload_tuple_dir dir)
160 {
161 dst_release(flow->tuplehash[dir].tuple.dst_cache);
162 }
163
flow_offload_route_init(struct flow_offload * flow,struct nf_flow_route * route)164 void flow_offload_route_init(struct flow_offload *flow,
165 struct nf_flow_route *route)
166 {
167 flow_offload_fill_route(flow, route, FLOW_OFFLOAD_DIR_ORIGINAL);
168 flow_offload_fill_route(flow, route, FLOW_OFFLOAD_DIR_REPLY);
169 flow->type = NF_FLOW_OFFLOAD_ROUTE;
170 }
171 EXPORT_SYMBOL_GPL(flow_offload_route_init);
172
nf_flow_has_expired(const struct flow_offload * flow)173 static inline bool nf_flow_has_expired(const struct flow_offload *flow)
174 {
175 return nf_flow_timeout_delta(flow->timeout) <= 0;
176 }
177
flow_offload_fixup_tcp(struct nf_conn * ct,u8 tcp_state)178 static void flow_offload_fixup_tcp(struct nf_conn *ct, u8 tcp_state)
179 {
180 struct ip_ct_tcp *tcp = &ct->proto.tcp;
181
182 spin_lock_bh(&ct->lock);
183 if (tcp->state != tcp_state)
184 tcp->state = tcp_state;
185
186 /* syn packet triggers the TCP reopen case from conntrack. */
187 if (tcp->state == TCP_CONNTRACK_CLOSE)
188 ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_CLOSE_INIT;
189
190 /* Conntrack state is outdated due to offload bypass.
191 * Clear IP_CT_TCP_FLAG_MAXACK_SET, otherwise conntracks
192 * TCP reset validation will fail.
193 */
194 tcp->seen[0].td_maxwin = 0;
195 tcp->seen[0].flags &= ~IP_CT_TCP_FLAG_MAXACK_SET;
196 tcp->seen[1].td_maxwin = 0;
197 tcp->seen[1].flags &= ~IP_CT_TCP_FLAG_MAXACK_SET;
198 spin_unlock_bh(&ct->lock);
199 }
200
flow_offload_fixup_ct(struct flow_offload * flow)201 static void flow_offload_fixup_ct(struct flow_offload *flow)
202 {
203 struct nf_conn *ct = flow->ct;
204 struct net *net = nf_ct_net(ct);
205 int l4num = nf_ct_protonum(ct);
206 bool expired, closing = false;
207 u32 offload_timeout = 0;
208 s32 timeout;
209
210 if (l4num == IPPROTO_TCP) {
211 const struct nf_tcp_net *tn = nf_tcp_pernet(net);
212 u8 tcp_state;
213
214 /* Enter CLOSE state if fin/rst packet has been seen, this
215 * allows TCP reopen from conntrack. Otherwise, pick up from
216 * the last seen TCP state.
217 */
218 closing = test_bit(NF_FLOW_CLOSING, &flow->flags);
219 if (closing) {
220 flow_offload_fixup_tcp(ct, TCP_CONNTRACK_CLOSE);
221 timeout = READ_ONCE(tn->timeouts[TCP_CONNTRACK_CLOSE]);
222 expired = false;
223 } else {
224 tcp_state = READ_ONCE(ct->proto.tcp.state);
225 flow_offload_fixup_tcp(ct, tcp_state);
226 timeout = READ_ONCE(tn->timeouts[tcp_state]);
227 expired = nf_flow_has_expired(flow);
228 }
229 offload_timeout = READ_ONCE(tn->offload_timeout);
230
231 } else if (l4num == IPPROTO_UDP) {
232 const struct nf_udp_net *tn = nf_udp_pernet(net);
233 enum udp_conntrack state =
234 test_bit(IPS_SEEN_REPLY_BIT, &ct->status) ?
235 UDP_CT_REPLIED : UDP_CT_UNREPLIED;
236
237 timeout = READ_ONCE(tn->timeouts[state]);
238 expired = nf_flow_has_expired(flow);
239 offload_timeout = READ_ONCE(tn->offload_timeout);
240 } else {
241 return;
242 }
243
244 if (expired)
245 timeout -= offload_timeout;
246
247 if (timeout < 0)
248 timeout = 0;
249
250 if (closing ||
251 nf_flow_timeout_delta(READ_ONCE(ct->timeout)) > (__s32)timeout)
252 nf_ct_refresh(ct, timeout);
253 }
254
flow_offload_route_release(struct flow_offload * flow)255 static void flow_offload_route_release(struct flow_offload *flow)
256 {
257 nft_flow_dst_release(flow, FLOW_OFFLOAD_DIR_ORIGINAL);
258 nft_flow_dst_release(flow, FLOW_OFFLOAD_DIR_REPLY);
259 }
260
flow_offload_free_rcu(struct rcu_head * rcu_head)261 static void flow_offload_free_rcu(struct rcu_head *rcu_head)
262 {
263 struct flow_offload *flow = container_of(rcu_head, struct flow_offload, rcu_head);
264
265 nf_ct_put(flow->ct);
266 kfree(flow);
267 }
268
flow_offload_free(struct flow_offload * flow)269 void flow_offload_free(struct flow_offload *flow)
270 {
271 switch (flow->type) {
272 case NF_FLOW_OFFLOAD_ROUTE:
273 flow_offload_route_release(flow);
274 break;
275 default:
276 break;
277 }
278 call_rcu(&flow->rcu_head, flow_offload_free_rcu);
279 }
280 EXPORT_SYMBOL_GPL(flow_offload_free);
281
flow_offload_hash(const void * data,u32 len,u32 seed)282 static u32 flow_offload_hash(const void *data, u32 len, u32 seed)
283 {
284 const struct flow_offload_tuple *tuple = data;
285
286 return jhash(tuple, offsetof(struct flow_offload_tuple, __hash), seed);
287 }
288
flow_offload_hash_obj(const void * data,u32 len,u32 seed)289 static u32 flow_offload_hash_obj(const void *data, u32 len, u32 seed)
290 {
291 const struct flow_offload_tuple_rhash *tuplehash = data;
292
293 return jhash(&tuplehash->tuple, offsetof(struct flow_offload_tuple, __hash), seed);
294 }
295
flow_offload_hash_cmp(struct rhashtable_compare_arg * arg,const void * ptr)296 static int flow_offload_hash_cmp(struct rhashtable_compare_arg *arg,
297 const void *ptr)
298 {
299 const struct flow_offload_tuple *tuple = arg->key;
300 const struct flow_offload_tuple_rhash *x = ptr;
301
302 if (memcmp(&x->tuple, tuple, offsetof(struct flow_offload_tuple, __hash)))
303 return 1;
304
305 return 0;
306 }
307
308 static const struct rhashtable_params nf_flow_offload_rhash_params = {
309 .head_offset = offsetof(struct flow_offload_tuple_rhash, node),
310 .hashfn = flow_offload_hash,
311 .obj_hashfn = flow_offload_hash_obj,
312 .obj_cmpfn = flow_offload_hash_cmp,
313 .automatic_shrinking = true,
314 };
315
flow_offload_get_timeout(struct flow_offload * flow)316 unsigned long flow_offload_get_timeout(struct flow_offload *flow)
317 {
318 unsigned long timeout = NF_FLOW_TIMEOUT;
319 struct net *net = nf_ct_net(flow->ct);
320 int l4num = nf_ct_protonum(flow->ct);
321
322 if (l4num == IPPROTO_TCP) {
323 struct nf_tcp_net *tn = nf_tcp_pernet(net);
324
325 timeout = tn->offload_timeout;
326 } else if (l4num == IPPROTO_UDP) {
327 struct nf_udp_net *tn = nf_udp_pernet(net);
328
329 timeout = tn->offload_timeout;
330 }
331
332 return timeout;
333 }
334
flow_offload_add(struct nf_flowtable * flow_table,struct flow_offload * flow)335 int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow)
336 {
337 int err;
338
339 flow->timeout = nf_flowtable_time_stamp + flow_offload_get_timeout(flow);
340
341 err = rhashtable_insert_fast(&flow_table->rhashtable,
342 &flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].node,
343 nf_flow_offload_rhash_params);
344 if (err < 0)
345 return err;
346
347 /* GC only iterates original-direction entries; publish original last. */
348 err = rhashtable_insert_fast(&flow_table->rhashtable,
349 &flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].node,
350 nf_flow_offload_rhash_params);
351 if (err < 0) {
352 rhashtable_remove_fast(&flow_table->rhashtable,
353 &flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].node,
354 nf_flow_offload_rhash_params);
355 return err;
356 }
357
358 nf_ct_refresh(flow->ct, NF_CT_DAY);
359
360 if (nf_flowtable_hw_offload(flow_table))
361 nf_flow_offload_add(flow_table, flow);
362
363 return 0;
364 }
365 EXPORT_SYMBOL_GPL(flow_offload_add);
366
flow_offload_refresh(struct nf_flowtable * flow_table,struct flow_offload * flow,bool force)367 void flow_offload_refresh(struct nf_flowtable *flow_table,
368 struct flow_offload *flow, bool force)
369 {
370 u32 timeout;
371
372 timeout = nf_flowtable_time_stamp + flow_offload_get_timeout(flow);
373 if (force || timeout - READ_ONCE(flow->timeout) > HZ)
374 WRITE_ONCE(flow->timeout, timeout);
375 else
376 return;
377
378 if (likely(!nf_flowtable_hw_offload(flow_table)) ||
379 test_bit(NF_FLOW_CLOSING, &flow->flags))
380 return;
381
382 if (test_bit(NF_FLOW_HW, &flow->flags))
383 nf_flow_offload_refresh(flow_table, flow);
384 }
385 EXPORT_SYMBOL_GPL(flow_offload_refresh);
386
flow_offload_del(struct nf_flowtable * flow_table,struct flow_offload * flow)387 static void flow_offload_del(struct nf_flowtable *flow_table,
388 struct flow_offload *flow)
389 {
390 rhashtable_remove_fast(&flow_table->rhashtable,
391 &flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].node,
392 nf_flow_offload_rhash_params);
393 rhashtable_remove_fast(&flow_table->rhashtable,
394 &flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].node,
395 nf_flow_offload_rhash_params);
396 flow_offload_free(flow);
397 }
398
flow_offload_teardown(struct flow_offload * flow)399 void flow_offload_teardown(struct flow_offload *flow)
400 {
401 clear_bit(IPS_OFFLOAD_BIT, &flow->ct->status);
402 if (!test_and_set_bit(NF_FLOW_TEARDOWN, &flow->flags))
403 flow_offload_fixup_ct(flow);
404 }
405 EXPORT_SYMBOL_GPL(flow_offload_teardown);
406
407 struct flow_offload_tuple_rhash *
flow_offload_lookup(struct nf_flowtable * flow_table,struct flow_offload_tuple * tuple)408 flow_offload_lookup(struct nf_flowtable *flow_table,
409 struct flow_offload_tuple *tuple)
410 {
411 struct flow_offload_tuple_rhash *tuplehash;
412 struct flow_offload *flow;
413 int dir;
414
415 tuplehash = rhashtable_lookup(&flow_table->rhashtable, tuple,
416 nf_flow_offload_rhash_params);
417 if (!tuplehash)
418 return NULL;
419
420 dir = tuplehash->tuple.dir;
421 flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]);
422 if (test_bit(NF_FLOW_TEARDOWN, &flow->flags))
423 return NULL;
424
425 if (unlikely(nf_ct_is_dying(flow->ct)))
426 return NULL;
427
428 return tuplehash;
429 }
430 EXPORT_SYMBOL_GPL(flow_offload_lookup);
431
432 static int
nf_flow_table_iterate(struct nf_flowtable * flow_table,void (* iter)(struct nf_flowtable * flowtable,struct flow_offload * flow,void * data),void * data)433 nf_flow_table_iterate(struct nf_flowtable *flow_table,
434 void (*iter)(struct nf_flowtable *flowtable,
435 struct flow_offload *flow, void *data),
436 void *data)
437 {
438 struct flow_offload_tuple_rhash *tuplehash;
439 struct rhashtable_iter hti;
440 struct flow_offload *flow;
441 int err = 0;
442
443 rhashtable_walk_enter(&flow_table->rhashtable, &hti);
444 rhashtable_walk_start(&hti);
445
446 while ((tuplehash = rhashtable_walk_next(&hti))) {
447 if (IS_ERR(tuplehash)) {
448 if (PTR_ERR(tuplehash) != -EAGAIN) {
449 err = PTR_ERR(tuplehash);
450 break;
451 }
452 continue;
453 }
454 if (tuplehash->tuple.dir)
455 continue;
456
457 flow = container_of(tuplehash, struct flow_offload, tuplehash[0]);
458
459 iter(flow_table, flow, data);
460 }
461 rhashtable_walk_stop(&hti);
462 rhashtable_walk_exit(&hti);
463
464 return err;
465 }
466
nf_flow_custom_gc(struct nf_flowtable * flow_table,const struct flow_offload * flow)467 static bool nf_flow_custom_gc(struct nf_flowtable *flow_table,
468 const struct flow_offload *flow)
469 {
470 return flow_table->type->gc && flow_table->type->gc(flow);
471 }
472
473 /**
474 * nf_flow_table_tcp_timeout() - new timeout of offloaded tcp entry
475 * @ct: Flowtable offloaded tcp ct
476 *
477 * Return: number of seconds when ct entry should expire.
478 */
nf_flow_table_tcp_timeout(const struct nf_conn * ct)479 static u32 nf_flow_table_tcp_timeout(const struct nf_conn *ct)
480 {
481 u8 state = READ_ONCE(ct->proto.tcp.state);
482
483 switch (state) {
484 case TCP_CONNTRACK_SYN_SENT:
485 case TCP_CONNTRACK_SYN_RECV:
486 return 0;
487 case TCP_CONNTRACK_ESTABLISHED:
488 return NF_CT_DAY;
489 case TCP_CONNTRACK_FIN_WAIT:
490 case TCP_CONNTRACK_CLOSE_WAIT:
491 case TCP_CONNTRACK_LAST_ACK:
492 case TCP_CONNTRACK_TIME_WAIT:
493 return 5 * 60 * HZ;
494 case TCP_CONNTRACK_CLOSE:
495 return 0;
496 }
497
498 return 0;
499 }
500
501 /**
502 * nf_flow_table_extend_ct_timeout() - Extend ct timeout of offloaded conntrack entry
503 * @ct: Flowtable offloaded ct
504 *
505 * Datapath lookups in the conntrack table will evict nf_conn entries
506 * if they have expired.
507 *
508 * Once nf_conn entries have been offloaded, nf_conntrack might not see any
509 * packets anymore. Thus ct->timeout is no longer refreshed and ct can
510 * be evicted.
511 *
512 * To avoid the need for an additional check on the offload bit for every
513 * packet processed via nf_conntrack_in(), set an arbitrary timeout large
514 * enough not to ever expire, this save us a check for the IPS_OFFLOAD_BIT
515 * from the packet path via nf_ct_is_expired().
516 */
nf_flow_table_extend_ct_timeout(struct nf_conn * ct)517 static void nf_flow_table_extend_ct_timeout(struct nf_conn *ct)
518 {
519 static const s32 min_timeout = 5 * 60 * HZ;
520 u32 ct_timeout = READ_ONCE(ct->timeout);
521 s32 expires;
522
523 expires = ct_timeout - nfct_time_stamp;
524 if (expires <= 0) /* already expired */
525 return;
526
527 /* normal case: large enough timeout, nothing to do. */
528 if (likely(expires >= min_timeout))
529 return;
530
531 /* must check offload bit after this, we do not hold any locks.
532 * flowtable and ct entries could have been removed on another CPU.
533 */
534 if (!refcount_inc_not_zero(&ct->ct_general.use))
535 return;
536
537 /* load ct->status after refcount increase */
538 smp_acquire__after_ctrl_dep();
539
540 if (nf_ct_is_confirmed(ct) &&
541 test_bit(IPS_OFFLOAD_BIT, &ct->status)) {
542 u8 l4proto = nf_ct_protonum(ct);
543 u32 new_timeout = 1;
544
545 switch (l4proto) {
546 case IPPROTO_UDP:
547 new_timeout = NF_CT_DAY;
548 break;
549 case IPPROTO_TCP:
550 new_timeout = nf_flow_table_tcp_timeout(ct);
551 break;
552 default:
553 WARN_ON_ONCE(1);
554 break;
555 }
556
557 /* Update to ct->timeout from nf_conntrack happens
558 * without holding ct->lock.
559 *
560 * Use cmpxchg to ensure timeout extension doesn't
561 * happen when we race with conntrack datapath.
562 *
563 * The inverse -- datapath updating ->timeout right
564 * after this -- is fine, datapath is authoritative.
565 */
566 if (new_timeout) {
567 new_timeout += nfct_time_stamp;
568 cmpxchg(&ct->timeout, ct_timeout, new_timeout);
569 }
570 }
571
572 nf_ct_put(ct);
573 }
574
nf_flow_offload_gc_step(struct nf_flowtable * flow_table,struct flow_offload * flow,void * data)575 static void nf_flow_offload_gc_step(struct nf_flowtable *flow_table,
576 struct flow_offload *flow, void *data)
577 {
578 bool teardown = test_bit(NF_FLOW_TEARDOWN, &flow->flags);
579
580 if (nf_flow_has_expired(flow) ||
581 nf_ct_is_dying(flow->ct) ||
582 !nf_flow_dst_check(&flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple) ||
583 !nf_flow_dst_check(&flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple) ||
584 nf_flow_custom_gc(flow_table, flow)) {
585 flow_offload_teardown(flow);
586 teardown = true;
587 } else if (!teardown) {
588 nf_flow_table_extend_ct_timeout(flow->ct);
589 }
590
591 if (teardown) {
592 if (test_bit(NF_FLOW_HW, &flow->flags)) {
593 if (!test_bit(NF_FLOW_HW_DYING, &flow->flags))
594 nf_flow_offload_del(flow_table, flow);
595 else if (test_bit(NF_FLOW_HW_DEAD, &flow->flags))
596 flow_offload_del(flow_table, flow);
597 } else {
598 flow_offload_del(flow_table, flow);
599 }
600 } else if (test_bit(NF_FLOW_CLOSING, &flow->flags) &&
601 test_bit(NF_FLOW_HW, &flow->flags) &&
602 !test_bit(NF_FLOW_HW_DYING, &flow->flags)) {
603 nf_flow_offload_del(flow_table, flow);
604 } else if (test_bit(NF_FLOW_HW, &flow->flags)) {
605 nf_flow_offload_stats(flow_table, flow);
606 }
607 }
608
nf_flow_table_gc_run(struct nf_flowtable * flow_table)609 void nf_flow_table_gc_run(struct nf_flowtable *flow_table)
610 {
611 nf_flow_table_iterate(flow_table, nf_flow_offload_gc_step, NULL);
612 }
613
nf_flow_offload_work_gc(struct work_struct * work)614 static void nf_flow_offload_work_gc(struct work_struct *work)
615 {
616 struct nf_flowtable *flow_table;
617
618 flow_table = container_of(work, struct nf_flowtable, gc_work.work);
619 nf_flow_table_gc_run(flow_table);
620 queue_delayed_work(system_power_efficient_wq, &flow_table->gc_work, HZ);
621 }
622
nf_flow_nat_port_tcp(struct sk_buff * skb,unsigned int thoff,__be16 port,__be16 new_port)623 static void nf_flow_nat_port_tcp(struct sk_buff *skb, unsigned int thoff,
624 __be16 port, __be16 new_port)
625 {
626 struct tcphdr *tcph;
627
628 tcph = (void *)(skb_network_header(skb) + thoff);
629 inet_proto_csum_replace2(&tcph->check, skb, port, new_port, false);
630 }
631
nf_flow_nat_port_udp(struct sk_buff * skb,unsigned int thoff,__be16 port,__be16 new_port)632 static void nf_flow_nat_port_udp(struct sk_buff *skb, unsigned int thoff,
633 __be16 port, __be16 new_port)
634 {
635 struct udphdr *udph;
636
637 udph = (void *)(skb_network_header(skb) + thoff);
638 if (udph->check || skb->ip_summed == CHECKSUM_PARTIAL) {
639 inet_proto_csum_replace2(&udph->check, skb, port,
640 new_port, false);
641 if (!udph->check)
642 udph->check = CSUM_MANGLED_0;
643 }
644 }
645
nf_flow_nat_port(struct sk_buff * skb,unsigned int thoff,u8 protocol,__be16 port,__be16 new_port)646 static void nf_flow_nat_port(struct sk_buff *skb, unsigned int thoff,
647 u8 protocol, __be16 port, __be16 new_port)
648 {
649 switch (protocol) {
650 case IPPROTO_TCP:
651 nf_flow_nat_port_tcp(skb, thoff, port, new_port);
652 break;
653 case IPPROTO_UDP:
654 nf_flow_nat_port_udp(skb, thoff, port, new_port);
655 break;
656 }
657 }
658
nf_flow_snat_port(const struct flow_offload * flow,struct sk_buff * skb,unsigned int thoff,u8 protocol,enum flow_offload_tuple_dir dir)659 void nf_flow_snat_port(const struct flow_offload *flow,
660 struct sk_buff *skb, unsigned int thoff,
661 u8 protocol, enum flow_offload_tuple_dir dir)
662 {
663 struct flow_ports *hdr;
664 __be16 port, new_port;
665
666 hdr = (void *)(skb_network_header(skb) + thoff);
667
668 switch (dir) {
669 case FLOW_OFFLOAD_DIR_ORIGINAL:
670 port = hdr->source;
671 new_port = flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.dst_port;
672 hdr->source = new_port;
673 break;
674 case FLOW_OFFLOAD_DIR_REPLY:
675 port = hdr->dest;
676 new_port = flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.src_port;
677 hdr->dest = new_port;
678 break;
679 }
680
681 nf_flow_nat_port(skb, thoff, protocol, port, new_port);
682 }
683 EXPORT_SYMBOL_GPL(nf_flow_snat_port);
684
nf_flow_dnat_port(const struct flow_offload * flow,struct sk_buff * skb,unsigned int thoff,u8 protocol,enum flow_offload_tuple_dir dir)685 void nf_flow_dnat_port(const struct flow_offload *flow, struct sk_buff *skb,
686 unsigned int thoff, u8 protocol,
687 enum flow_offload_tuple_dir dir)
688 {
689 struct flow_ports *hdr;
690 __be16 port, new_port;
691
692 hdr = (void *)(skb_network_header(skb) + thoff);
693
694 switch (dir) {
695 case FLOW_OFFLOAD_DIR_ORIGINAL:
696 port = hdr->dest;
697 new_port = flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple.src_port;
698 hdr->dest = new_port;
699 break;
700 case FLOW_OFFLOAD_DIR_REPLY:
701 port = hdr->source;
702 new_port = flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.dst_port;
703 hdr->source = new_port;
704 break;
705 }
706
707 nf_flow_nat_port(skb, thoff, protocol, port, new_port);
708 }
709 EXPORT_SYMBOL_GPL(nf_flow_dnat_port);
710
nf_flow_table_init(struct nf_flowtable * flowtable)711 int nf_flow_table_init(struct nf_flowtable *flowtable)
712 {
713 int err;
714
715 INIT_DELAYED_WORK(&flowtable->gc_work, nf_flow_offload_work_gc);
716 flow_block_init(&flowtable->flow_block);
717 init_rwsem(&flowtable->flow_block_lock);
718
719 err = rhashtable_init(&flowtable->rhashtable,
720 &nf_flow_offload_rhash_params);
721 if (err < 0)
722 return err;
723
724 queue_delayed_work(system_power_efficient_wq,
725 &flowtable->gc_work, HZ);
726
727 mutex_lock(&flowtable_lock);
728 list_add(&flowtable->list, &flowtables);
729 mutex_unlock(&flowtable_lock);
730
731 return 0;
732 }
733 EXPORT_SYMBOL_GPL(nf_flow_table_init);
734
nf_flow_table_do_cleanup(struct nf_flowtable * flow_table,struct flow_offload * flow,void * data)735 static void nf_flow_table_do_cleanup(struct nf_flowtable *flow_table,
736 struct flow_offload *flow, void *data)
737 {
738 struct net_device *dev = data;
739
740 if (!dev) {
741 flow_offload_teardown(flow);
742 return;
743 }
744
745 if (net_eq(nf_ct_net(flow->ct), dev_net(dev)) &&
746 (flow->tuplehash[0].tuple.iifidx == dev->ifindex ||
747 flow->tuplehash[1].tuple.iifidx == dev->ifindex))
748 flow_offload_teardown(flow);
749 }
750
nf_flow_table_gc_cleanup(struct nf_flowtable * flowtable,struct net_device * dev)751 void nf_flow_table_gc_cleanup(struct nf_flowtable *flowtable,
752 struct net_device *dev)
753 {
754 nf_flow_table_iterate(flowtable, nf_flow_table_do_cleanup, dev);
755 flush_delayed_work(&flowtable->gc_work);
756 nf_flow_table_offload_flush(flowtable);
757 }
758
nf_flow_table_cleanup(struct net_device * dev)759 void nf_flow_table_cleanup(struct net_device *dev)
760 {
761 struct nf_flowtable *flowtable;
762
763 mutex_lock(&flowtable_lock);
764 list_for_each_entry(flowtable, &flowtables, list)
765 nf_flow_table_gc_cleanup(flowtable, dev);
766 mutex_unlock(&flowtable_lock);
767 }
768 EXPORT_SYMBOL_GPL(nf_flow_table_cleanup);
769
nf_flow_table_free(struct nf_flowtable * flow_table)770 void nf_flow_table_free(struct nf_flowtable *flow_table)
771 {
772 mutex_lock(&flowtable_lock);
773 list_del(&flow_table->list);
774 mutex_unlock(&flowtable_lock);
775
776 cancel_delayed_work_sync(&flow_table->gc_work);
777 nf_flow_table_offload_flush(flow_table);
778 /* ... no more pending work after this stage ... */
779 nf_flow_table_iterate(flow_table, nf_flow_table_do_cleanup, NULL);
780 nf_flow_table_gc_run(flow_table);
781 nf_flow_table_offload_flush_cleanup(flow_table);
782 rhashtable_destroy(&flow_table->rhashtable);
783 }
784 EXPORT_SYMBOL_GPL(nf_flow_table_free);
785
nf_flow_table_init_net(struct net * net)786 static int nf_flow_table_init_net(struct net *net)
787 {
788 net->ft.stat = alloc_percpu(struct nf_flow_table_stat);
789 return net->ft.stat ? 0 : -ENOMEM;
790 }
791
nf_flow_table_fini_net(struct net * net)792 static void nf_flow_table_fini_net(struct net *net)
793 {
794 free_percpu(net->ft.stat);
795 }
796
nf_flow_table_pernet_init(struct net * net)797 static int nf_flow_table_pernet_init(struct net *net)
798 {
799 int ret;
800
801 ret = nf_flow_table_init_net(net);
802 if (ret < 0)
803 return ret;
804
805 ret = nf_flow_table_init_proc(net);
806 if (ret < 0)
807 goto out_proc;
808
809 return 0;
810
811 out_proc:
812 nf_flow_table_fini_net(net);
813 return ret;
814 }
815
nf_flow_table_pernet_exit(struct list_head * net_exit_list)816 static void nf_flow_table_pernet_exit(struct list_head *net_exit_list)
817 {
818 struct net *net;
819
820 list_for_each_entry(net, net_exit_list, exit_list) {
821 nf_flow_table_fini_proc(net);
822 nf_flow_table_fini_net(net);
823 }
824 }
825
826 static struct pernet_operations nf_flow_table_net_ops = {
827 .init = nf_flow_table_pernet_init,
828 .exit_batch = nf_flow_table_pernet_exit,
829 };
830
nf_flow_table_module_init(void)831 static int __init nf_flow_table_module_init(void)
832 {
833 int ret;
834
835 flow_offload_cachep = KMEM_CACHE(flow_offload, SLAB_HWCACHE_ALIGN);
836 if (!flow_offload_cachep)
837 return -ENOMEM;
838
839 ret = register_pernet_subsys(&nf_flow_table_net_ops);
840 if (ret < 0)
841 goto out_pernet;
842
843 ret = nf_flow_table_offload_init();
844 if (ret)
845 goto out_offload;
846
847 ret = nf_flow_register_bpf();
848 if (ret)
849 goto out_bpf;
850
851 return 0;
852
853 out_bpf:
854 nf_flow_table_offload_exit();
855 out_offload:
856 unregister_pernet_subsys(&nf_flow_table_net_ops);
857 out_pernet:
858 kmem_cache_destroy(flow_offload_cachep);
859 return ret;
860 }
861
nf_flow_table_module_exit(void)862 static void __exit nf_flow_table_module_exit(void)
863 {
864 rcu_barrier();
865 nf_flow_table_offload_exit();
866 unregister_pernet_subsys(&nf_flow_table_net_ops);
867 kmem_cache_destroy(flow_offload_cachep);
868 }
869
870 module_init(nf_flow_table_module_init);
871 module_exit(nf_flow_table_module_exit);
872
873 MODULE_LICENSE("GPL");
874 MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
875 MODULE_DESCRIPTION("Netfilter flow table module");
876