1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * inet fragments management
4 *
5 * Authors: Pavel Emelyanov <xemul@openvz.org>
6 * Started as consolidation of ipv4/ip_fragment.c,
7 * ipv6/reassembly. and ipv6 nf conntrack reassembly
8 */
9
10 #include <linux/list.h>
11 #include <linux/spinlock.h>
12 #include <linux/module.h>
13 #include <linux/timer.h>
14 #include <linux/mm.h>
15 #include <linux/random.h>
16 #include <linux/skbuff.h>
17 #include <linux/rtnetlink.h>
18 #include <linux/slab.h>
19 #include <linux/rhashtable.h>
20
21 #include <net/sock.h>
22 #include <net/inet_frag.h>
23 #include <net/inet_ecn.h>
24 #include <net/ip.h>
25 #include <net/ipv6.h>
26
27 /* Use skb->cb to track consecutive/adjacent fragments coming at
28 * the end of the queue. Nodes in the rb-tree queue will
29 * contain "runs" of one or more adjacent fragments.
30 *
31 * Invariants:
32 * - next_frag is NULL at the tail of a "run";
33 * - the head of a "run" has the sum of all fragment lengths in frag_run_len.
34 */
35 struct ipfrag_skb_cb {
36 union {
37 struct inet_skb_parm h4;
38 struct inet6_skb_parm h6;
39 };
40 struct sk_buff *next_frag;
41 int frag_run_len;
42 int ip_defrag_offset;
43 };
44
45 #define FRAG_CB(skb) ((struct ipfrag_skb_cb *)((skb)->cb))
46
fragcb_clear(struct sk_buff * skb)47 static void fragcb_clear(struct sk_buff *skb)
48 {
49 RB_CLEAR_NODE(&skb->rbnode);
50 FRAG_CB(skb)->next_frag = NULL;
51 FRAG_CB(skb)->frag_run_len = skb->len;
52 }
53
54 /* Append skb to the last "run". */
fragrun_append_to_last(struct inet_frag_queue * q,struct sk_buff * skb)55 static void fragrun_append_to_last(struct inet_frag_queue *q,
56 struct sk_buff *skb)
57 {
58 fragcb_clear(skb);
59
60 FRAG_CB(q->last_run_head)->frag_run_len += skb->len;
61 FRAG_CB(q->fragments_tail)->next_frag = skb;
62 q->fragments_tail = skb;
63 }
64
65 /* Create a new "run" with the skb. */
fragrun_create(struct inet_frag_queue * q,struct sk_buff * skb)66 static void fragrun_create(struct inet_frag_queue *q, struct sk_buff *skb)
67 {
68 BUILD_BUG_ON(sizeof(struct ipfrag_skb_cb) > sizeof(skb->cb));
69 fragcb_clear(skb);
70
71 if (q->last_run_head)
72 rb_link_node(&skb->rbnode, &q->last_run_head->rbnode,
73 &q->last_run_head->rbnode.rb_right);
74 else
75 rb_link_node(&skb->rbnode, NULL, &q->rb_fragments.rb_node);
76 rb_insert_color(&skb->rbnode, &q->rb_fragments);
77
78 q->fragments_tail = skb;
79 q->last_run_head = skb;
80 }
81
82 /* Given the OR values of all fragments, apply RFC 3168 5.3 requirements
83 * Value : 0xff if frame should be dropped.
84 * 0 or INET_ECN_CE value, to be ORed in to final iph->tos field
85 */
86 const u8 ip_frag_ecn_table[16] = {
87 /* at least one fragment had CE, and others ECT_0 or ECT_1 */
88 [IPFRAG_ECN_CE | IPFRAG_ECN_ECT_0] = INET_ECN_CE,
89 [IPFRAG_ECN_CE | IPFRAG_ECN_ECT_1] = INET_ECN_CE,
90 [IPFRAG_ECN_CE | IPFRAG_ECN_ECT_0 | IPFRAG_ECN_ECT_1] = INET_ECN_CE,
91
92 /* invalid combinations : drop frame */
93 [IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_CE] = 0xff,
94 [IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_ECT_0] = 0xff,
95 [IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_ECT_1] = 0xff,
96 [IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_ECT_0 | IPFRAG_ECN_ECT_1] = 0xff,
97 [IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_CE | IPFRAG_ECN_ECT_0] = 0xff,
98 [IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_CE | IPFRAG_ECN_ECT_1] = 0xff,
99 [IPFRAG_ECN_NOT_ECT | IPFRAG_ECN_CE | IPFRAG_ECN_ECT_0 | IPFRAG_ECN_ECT_1] = 0xff,
100 };
101 EXPORT_SYMBOL(ip_frag_ecn_table);
102
inet_frags_init(struct inet_frags * f)103 int inet_frags_init(struct inet_frags *f)
104 {
105 f->frags_cachep = kmem_cache_create(f->frags_cache_name, f->qsize, 0, 0,
106 NULL);
107 if (!f->frags_cachep)
108 return -ENOMEM;
109
110 refcount_set(&f->refcnt, 1);
111 init_completion(&f->completion);
112 return 0;
113 }
114 EXPORT_SYMBOL(inet_frags_init);
115
inet_frags_fini(struct inet_frags * f)116 void inet_frags_fini(struct inet_frags *f)
117 {
118 if (refcount_dec_and_test(&f->refcnt))
119 complete(&f->completion);
120
121 wait_for_completion(&f->completion);
122
123 kmem_cache_destroy(f->frags_cachep);
124 f->frags_cachep = NULL;
125 }
126 EXPORT_SYMBOL(inet_frags_fini);
127
128 /* called from rhashtable_free_and_destroy() at netns_frags dismantle */
inet_frags_free_cb(void * ptr,void * arg)129 static void inet_frags_free_cb(void *ptr, void *arg)
130 {
131 struct inet_frag_queue *fq = ptr;
132 int count;
133
134 count = timer_delete_sync(&fq->timer) ? 1 : 0;
135
136 spin_lock_bh(&fq->lock);
137 fq->flags |= INET_FRAG_DROP;
138 if (!(fq->flags & INET_FRAG_COMPLETE)) {
139 fq->flags |= INET_FRAG_COMPLETE;
140 count++;
141 } else if (fq->flags & INET_FRAG_HASH_DEAD) {
142 count++;
143 }
144 spin_unlock_bh(&fq->lock);
145
146 inet_frag_putn(fq, count);
147 }
148
149 static LLIST_HEAD(fqdir_free_list);
150
fqdir_free_fn(struct work_struct * work)151 static void fqdir_free_fn(struct work_struct *work)
152 {
153 struct llist_node *kill_list;
154 struct fqdir *fqdir, *tmp;
155 struct inet_frags *f;
156
157 /* Atomically snapshot the list of fqdirs to free */
158 kill_list = llist_del_all(&fqdir_free_list);
159
160 /* We need to make sure all ongoing call_rcu(..., inet_frag_destroy_rcu)
161 * have completed, since they need to dereference fqdir.
162 * Would it not be nice to have kfree_rcu_barrier() ? :)
163 */
164 rcu_barrier();
165
166 llist_for_each_entry_safe(fqdir, tmp, kill_list, free_list) {
167 f = fqdir->f;
168 if (refcount_dec_and_test(&f->refcnt))
169 complete(&f->completion);
170
171 kfree(fqdir);
172 }
173 }
174
175 static DECLARE_DELAYED_WORK(fqdir_free_work, fqdir_free_fn);
176
fqdir_work_fn(struct work_struct * work)177 static void fqdir_work_fn(struct work_struct *work)
178 {
179 struct fqdir *fqdir = container_of(work, struct fqdir, destroy_work);
180
181 rhashtable_free_and_destroy(&fqdir->rhashtable, inet_frags_free_cb, NULL);
182
183 if (llist_add(&fqdir->free_list, &fqdir_free_list))
184 queue_delayed_work(system_percpu_wq, &fqdir_free_work, HZ);
185 }
186
fqdir_init(struct fqdir ** fqdirp,struct inet_frags * f,struct net * net)187 int fqdir_init(struct fqdir **fqdirp, struct inet_frags *f, struct net *net)
188 {
189 struct fqdir *fqdir = kzalloc_obj(*fqdir);
190 int res;
191
192 if (!fqdir)
193 return -ENOMEM;
194 fqdir->f = f;
195 fqdir->net = net;
196 res = rhashtable_init(&fqdir->rhashtable, &fqdir->f->rhash_params);
197 if (res < 0) {
198 kfree(fqdir);
199 return res;
200 }
201 refcount_inc(&f->refcnt);
202 *fqdirp = fqdir;
203 return 0;
204 }
205 EXPORT_SYMBOL(fqdir_init);
206
207 static struct workqueue_struct *inet_frag_wq;
208
inet_frag_wq_init(void)209 static int __init inet_frag_wq_init(void)
210 {
211 inet_frag_wq = create_workqueue("inet_frag_wq");
212 if (!inet_frag_wq)
213 panic("Could not create inet frag workq");
214 return 0;
215 }
216
217 pure_initcall(inet_frag_wq_init);
218
fqdir_pre_exit(struct fqdir * fqdir)219 void fqdir_pre_exit(struct fqdir *fqdir)
220 {
221 struct inet_frag_queue *fq;
222 struct rhashtable_iter hti;
223
224 /* Prevent creation of new frags.
225 * Pairs with READ_ONCE() in inet_frag_find().
226 */
227 WRITE_ONCE(fqdir->high_thresh, 0);
228
229 /* Pairs with READ_ONCE() in inet_frag_kill(), ip_expire()
230 * and ip6frag_expire_frag_queue().
231 */
232 WRITE_ONCE(fqdir->dead, true);
233
234 rhashtable_walk_enter(&fqdir->rhashtable, &hti);
235 rhashtable_walk_start(&hti);
236
237 while ((fq = rhashtable_walk_next(&hti))) {
238 int refs = 0;
239
240 if (IS_ERR(fq)) {
241 if (PTR_ERR(fq) != -EAGAIN)
242 break;
243 continue;
244 }
245 spin_lock_bh(&fq->lock);
246 if (!(fq->flags & INET_FRAG_COMPLETE))
247 inet_frag_kill(fq, &refs);
248
249 if (fq->flags & INET_FRAG_HASH_DEAD)
250 inet_frag_queue_flush(fq, 0);
251 spin_unlock_bh(&fq->lock);
252 inet_frag_putn(fq, refs);
253 }
254
255 rhashtable_walk_stop(&hti);
256 rhashtable_walk_exit(&hti);
257 }
258 EXPORT_SYMBOL(fqdir_pre_exit);
259
fqdir_exit(struct fqdir * fqdir)260 void fqdir_exit(struct fqdir *fqdir)
261 {
262 INIT_WORK(&fqdir->destroy_work, fqdir_work_fn);
263 queue_work(inet_frag_wq, &fqdir->destroy_work);
264 }
265 EXPORT_SYMBOL(fqdir_exit);
266
inet_frag_kill(struct inet_frag_queue * fq,int * refs)267 void inet_frag_kill(struct inet_frag_queue *fq, int *refs)
268 {
269 if (timer_delete(&fq->timer))
270 (*refs)++;
271
272 if (!(fq->flags & INET_FRAG_COMPLETE)) {
273 struct fqdir *fqdir = fq->fqdir;
274
275 fq->flags |= INET_FRAG_COMPLETE;
276 rcu_read_lock();
277 /* The RCU read lock provides a memory barrier
278 * guaranteeing that if fqdir->dead is false then
279 * the hash table destruction will not start until
280 * after we unlock. Paired with fqdir_pre_exit().
281 */
282 if (!READ_ONCE(fqdir->dead)) {
283 rhashtable_remove_fast(&fqdir->rhashtable, &fq->node,
284 fqdir->f->rhash_params);
285 (*refs)++;
286 } else {
287 fq->flags |= INET_FRAG_HASH_DEAD;
288 }
289 rcu_read_unlock();
290 }
291 }
292 EXPORT_SYMBOL(inet_frag_kill);
293
inet_frag_destroy_rcu(struct rcu_head * head)294 static void inet_frag_destroy_rcu(struct rcu_head *head)
295 {
296 struct inet_frag_queue *q = container_of(head, struct inet_frag_queue,
297 rcu);
298 struct inet_frags *f = q->fqdir->f;
299
300 if (f->destructor)
301 f->destructor(q);
302 kmem_cache_free(f->frags_cachep, q);
303 }
304
305 static unsigned int
inet_frag_rbtree_purge(struct rb_root * root,enum skb_drop_reason reason)306 inet_frag_rbtree_purge(struct rb_root *root, enum skb_drop_reason reason)
307 {
308 struct rb_node *p = rb_first(root);
309 unsigned int sum = 0;
310
311 while (p) {
312 struct sk_buff *skb = rb_entry(p, struct sk_buff, rbnode);
313
314 p = rb_next(p);
315 rb_erase(&skb->rbnode, root);
316 while (skb) {
317 struct sk_buff *next = FRAG_CB(skb)->next_frag;
318
319 sum += skb->truesize;
320 kfree_skb_reason(skb, reason);
321 skb = next;
322 }
323 }
324 return sum;
325 }
326
inet_frag_queue_flush(struct inet_frag_queue * q,enum skb_drop_reason reason)327 void inet_frag_queue_flush(struct inet_frag_queue *q,
328 enum skb_drop_reason reason)
329 {
330 unsigned int sum;
331
332 reason = reason ?: SKB_DROP_REASON_FRAG_REASM_TIMEOUT;
333 sum = inet_frag_rbtree_purge(&q->rb_fragments, reason);
334 sub_frag_mem_limit(q->fqdir, sum);
335 q->rb_fragments = RB_ROOT;
336 q->fragments_tail = NULL;
337 q->last_run_head = NULL;
338 }
339 EXPORT_SYMBOL(inet_frag_queue_flush);
340
inet_frag_destroy(struct inet_frag_queue * q)341 void inet_frag_destroy(struct inet_frag_queue *q)
342 {
343 unsigned int sum, sum_truesize = 0;
344 enum skb_drop_reason reason;
345 struct inet_frags *f;
346 struct fqdir *fqdir;
347
348 WARN_ON(!(q->flags & INET_FRAG_COMPLETE));
349 reason = (q->flags & INET_FRAG_DROP) ?
350 SKB_DROP_REASON_FRAG_REASM_TIMEOUT :
351 SKB_CONSUMED;
352 WARN_ON(timer_delete(&q->timer) != 0);
353
354 /* Release all fragment data. */
355 fqdir = q->fqdir;
356 f = fqdir->f;
357 sum_truesize = inet_frag_rbtree_purge(&q->rb_fragments, reason);
358 sum = sum_truesize + f->qsize;
359
360 call_rcu(&q->rcu, inet_frag_destroy_rcu);
361
362 sub_frag_mem_limit(fqdir, sum);
363 }
364 EXPORT_SYMBOL(inet_frag_destroy);
365
inet_frag_alloc(struct fqdir * fqdir,struct inet_frags * f,void * arg)366 static struct inet_frag_queue *inet_frag_alloc(struct fqdir *fqdir,
367 struct inet_frags *f,
368 void *arg)
369 {
370 struct inet_frag_queue *q;
371
372 q = kmem_cache_zalloc(f->frags_cachep, GFP_ATOMIC);
373 if (!q)
374 return NULL;
375
376 q->fqdir = fqdir;
377 f->constructor(q, arg);
378 add_frag_mem_limit(fqdir, f->qsize);
379
380 timer_setup(&q->timer, f->frag_expire, 0);
381 spin_lock_init(&q->lock);
382 /* One reference for the timer, one for the hash table.
383 * We never take any extra references, only decrement this field.
384 */
385 refcount_set(&q->refcnt, 2);
386
387 return q;
388 }
389
inet_frag_create(struct fqdir * fqdir,void * arg,struct inet_frag_queue ** prev)390 static struct inet_frag_queue *inet_frag_create(struct fqdir *fqdir,
391 void *arg,
392 struct inet_frag_queue **prev)
393 {
394 struct inet_frags *f = fqdir->f;
395 struct inet_frag_queue *q;
396
397 q = inet_frag_alloc(fqdir, f, arg);
398 if (!q) {
399 *prev = ERR_PTR(-ENOMEM);
400 return NULL;
401 }
402
403 spin_lock_bh(&q->lock);
404 *prev = rhashtable_lookup_get_insert_key(&fqdir->rhashtable, &q->key,
405 &q->node, f->rhash_params);
406 if (*prev) {
407 /* We could not insert in the hash table,
408 * we need to cancel what inet_frag_alloc()
409 * anticipated.
410 */
411 q->flags |= INET_FRAG_COMPLETE;
412 spin_unlock_bh(&q->lock);
413 inet_frag_putn(q, 2);
414 return NULL;
415 }
416 mod_timer(&q->timer, jiffies + fqdir->timeout);
417 spin_unlock_bh(&q->lock);
418 return q;
419 }
420
inet_frag_find(struct fqdir * fqdir,void * key)421 struct inet_frag_queue *inet_frag_find(struct fqdir *fqdir, void *key)
422 {
423 /* This pairs with WRITE_ONCE() in fqdir_pre_exit(). */
424 long high_thresh = READ_ONCE(fqdir->high_thresh);
425 struct inet_frag_queue *fq = NULL, *prev;
426
427 if (!high_thresh || frag_mem_limit(fqdir) > high_thresh)
428 return NULL;
429
430 prev = rhashtable_lookup(&fqdir->rhashtable, key, fqdir->f->rhash_params);
431 if (!prev)
432 fq = inet_frag_create(fqdir, key, &prev);
433 if (!IS_ERR_OR_NULL(prev))
434 fq = prev;
435 return fq;
436 }
437 EXPORT_SYMBOL(inet_frag_find);
438
inet_frag_queue_insert(struct inet_frag_queue * q,struct sk_buff * skb,int offset,int end)439 int inet_frag_queue_insert(struct inet_frag_queue *q, struct sk_buff *skb,
440 int offset, int end)
441 {
442 struct sk_buff *last = q->fragments_tail;
443
444 /* An IP fragment is never a GSO packet, but an untrusted source
445 * (virtio_net_hdr) may have attached GSO metadata to it. Do not let
446 * that reach the reassembled skb, whose head keeps the first
447 * fragment's shinfo and whose frag_list is not GRO-shaped.
448 */
449 skb_gso_reset(skb);
450
451 /* RFC5722, Section 4, amended by Errata ID : 3089
452 * When reassembling an IPv6 datagram, if
453 * one or more its constituent fragments is determined to be an
454 * overlapping fragment, the entire datagram (and any constituent
455 * fragments) MUST be silently discarded.
456 *
457 * Duplicates, however, should be ignored (i.e. skb dropped, but the
458 * queue/fragments kept for later reassembly).
459 */
460 if (!last)
461 fragrun_create(q, skb); /* First fragment. */
462 else if (FRAG_CB(last)->ip_defrag_offset + last->len < end) {
463 /* This is the common case: skb goes to the end. */
464 /* Detect and discard overlaps. */
465 if (offset < FRAG_CB(last)->ip_defrag_offset + last->len)
466 return IPFRAG_OVERLAP;
467 if (offset == FRAG_CB(last)->ip_defrag_offset + last->len)
468 fragrun_append_to_last(q, skb);
469 else
470 fragrun_create(q, skb);
471 } else {
472 /* Binary search. Note that skb can become the first fragment,
473 * but not the last (covered above).
474 */
475 struct rb_node **rbn, *parent;
476
477 rbn = &q->rb_fragments.rb_node;
478 do {
479 struct sk_buff *curr;
480 int curr_run_end;
481
482 parent = *rbn;
483 curr = rb_to_skb(parent);
484 curr_run_end = FRAG_CB(curr)->ip_defrag_offset +
485 FRAG_CB(curr)->frag_run_len;
486 if (end <= FRAG_CB(curr)->ip_defrag_offset)
487 rbn = &parent->rb_left;
488 else if (offset >= curr_run_end)
489 rbn = &parent->rb_right;
490 else if (offset >= FRAG_CB(curr)->ip_defrag_offset &&
491 end <= curr_run_end)
492 return IPFRAG_DUP;
493 else
494 return IPFRAG_OVERLAP;
495 } while (*rbn);
496 /* Here we have parent properly set, and rbn pointing to
497 * one of its NULL left/right children. Insert skb.
498 */
499 fragcb_clear(skb);
500 rb_link_node(&skb->rbnode, parent, rbn);
501 rb_insert_color(&skb->rbnode, &q->rb_fragments);
502 }
503
504 FRAG_CB(skb)->ip_defrag_offset = offset;
505 if (offset)
506 nf_reset_ct(skb);
507
508 return IPFRAG_OK;
509 }
510 EXPORT_SYMBOL(inet_frag_queue_insert);
511
inet_frag_reasm_prepare(struct inet_frag_queue * q,struct sk_buff * skb,struct sk_buff * parent)512 void *inet_frag_reasm_prepare(struct inet_frag_queue *q, struct sk_buff *skb,
513 struct sk_buff *parent)
514 {
515 struct sk_buff *fp, *head = skb_rb_first(&q->rb_fragments);
516 void (*destructor)(struct sk_buff *);
517 unsigned int orig_truesize = 0;
518 struct sk_buff **nextp = NULL;
519 struct sock *sk = skb->sk;
520 int delta;
521
522 if (sk && is_skb_wmem(skb)) {
523 /* TX: skb->sk might have been passed as argument to
524 * dst->output and must remain valid until tx completes.
525 *
526 * Move sk to reassembled skb and fix up wmem accounting.
527 */
528 orig_truesize = skb->truesize;
529 destructor = skb->destructor;
530 }
531
532 if (head != skb) {
533 fp = skb_clone(skb, GFP_ATOMIC);
534 if (!fp) {
535 head = skb;
536 goto out_restore_sk;
537 }
538 if (RB_EMPTY_NODE(&skb->rbnode))
539 FRAG_CB(parent)->next_frag = fp;
540 else
541 rb_replace_node(&skb->rbnode, &fp->rbnode,
542 &q->rb_fragments);
543 if (q->fragments_tail == skb)
544 q->fragments_tail = fp;
545
546 if (orig_truesize) {
547 /* prevent skb_morph from releasing sk */
548 skb->sk = NULL;
549 skb->destructor = NULL;
550 }
551 skb_morph(skb, head);
552 rb_replace_node(&head->rbnode, &skb->rbnode,
553 &q->rb_fragments);
554 consume_skb(head);
555 head = skb;
556 }
557 WARN_ON(FRAG_CB(head)->ip_defrag_offset != 0);
558
559 delta = -head->truesize;
560
561 /* Head of list must not be cloned. */
562 if (skb_unclone(head, GFP_ATOMIC))
563 goto out_restore_sk;
564
565 delta += head->truesize;
566 if (delta)
567 add_frag_mem_limit(q->fqdir, delta);
568
569 /* If the first fragment is fragmented itself, we split
570 * it to two chunks: the first with data and paged part
571 * and the second, holding only fragments.
572 */
573 if (skb_has_frag_list(head)) {
574 struct sk_buff *clone;
575 int i, plen = 0;
576
577 clone = alloc_skb(0, GFP_ATOMIC);
578 if (!clone)
579 goto out_restore_sk;
580 skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list;
581 skb_frag_list_init(head);
582 for (i = 0; i < skb_shinfo(head)->nr_frags; i++)
583 plen += skb_frag_size(&skb_shinfo(head)->frags[i]);
584 clone->data_len = head->data_len - plen;
585 clone->len = clone->data_len;
586 head->truesize += clone->truesize;
587 clone->csum = 0;
588 clone->ip_summed = head->ip_summed;
589 add_frag_mem_limit(q->fqdir, clone->truesize);
590 skb_shinfo(head)->frag_list = clone;
591 nextp = &clone->next;
592 } else {
593 nextp = &skb_shinfo(head)->frag_list;
594 }
595
596 out_restore_sk:
597 if (orig_truesize) {
598 int ts_delta = head->truesize - orig_truesize;
599
600 /* if this reassembled skb is fragmented later,
601 * fraglist skbs will get skb->sk assigned from head->sk,
602 * and each frag skb will be released via sock_wfree.
603 *
604 * Update sk_wmem_alloc.
605 */
606 head->sk = sk;
607 head->destructor = destructor;
608 refcount_add(ts_delta, &sk->sk_wmem_alloc);
609 }
610
611 return nextp;
612 }
613 EXPORT_SYMBOL(inet_frag_reasm_prepare);
614
inet_frag_reasm_finish(struct inet_frag_queue * q,struct sk_buff * head,void * reasm_data,bool try_coalesce)615 void inet_frag_reasm_finish(struct inet_frag_queue *q, struct sk_buff *head,
616 void *reasm_data, bool try_coalesce)
617 {
618 struct sock *sk = is_skb_wmem(head) ? head->sk : NULL;
619 const unsigned int head_truesize = head->truesize;
620 struct sk_buff **nextp = reasm_data;
621 struct rb_node *rbn;
622 struct sk_buff *fp;
623 int sum_truesize;
624
625 skb_push(head, head->data - skb_network_header(head));
626
627 /* Traverse the tree in order, to build frag_list. */
628 fp = FRAG_CB(head)->next_frag;
629 rbn = rb_next(&head->rbnode);
630 rb_erase(&head->rbnode, &q->rb_fragments);
631
632 sum_truesize = head->truesize;
633 while (rbn || fp) {
634 /* fp points to the next sk_buff in the current run;
635 * rbn points to the next run.
636 */
637 /* Go through the current run. */
638 while (fp) {
639 struct sk_buff *next_frag = FRAG_CB(fp)->next_frag;
640 bool stolen;
641 int delta;
642
643 sum_truesize += fp->truesize;
644 if (head->ip_summed != fp->ip_summed)
645 head->ip_summed = CHECKSUM_NONE;
646 else if (head->ip_summed == CHECKSUM_COMPLETE)
647 head->csum = csum_add(head->csum, fp->csum);
648
649 if (try_coalesce && skb_try_coalesce(head, fp, &stolen,
650 &delta)) {
651 kfree_skb_partial(fp, stolen);
652 } else {
653 fp->prev = NULL;
654 memset(&fp->rbnode, 0, sizeof(fp->rbnode));
655 fp->sk = NULL;
656
657 head->data_len += fp->len;
658 head->len += fp->len;
659 head->truesize += fp->truesize;
660
661 *nextp = fp;
662 nextp = &fp->next;
663 }
664
665 fp = next_frag;
666 }
667 /* Move to the next run. */
668 if (rbn) {
669 struct rb_node *rbnext = rb_next(rbn);
670
671 fp = rb_to_skb(rbn);
672 rb_erase(rbn, &q->rb_fragments);
673 rbn = rbnext;
674 }
675 }
676 sub_frag_mem_limit(q->fqdir, sum_truesize);
677
678 *nextp = NULL;
679 skb_mark_not_on_list(head);
680 head->prev = NULL;
681 head->tstamp = q->stamp;
682 head->tstamp_type = q->tstamp_type;
683
684 if (sk)
685 refcount_add(sum_truesize - head_truesize, &sk->sk_wmem_alloc);
686 }
687 EXPORT_SYMBOL(inet_frag_reasm_finish);
688
inet_frag_pull_head(struct inet_frag_queue * q)689 struct sk_buff *inet_frag_pull_head(struct inet_frag_queue *q)
690 {
691 struct sk_buff *head, *skb;
692
693 head = skb_rb_first(&q->rb_fragments);
694 if (!head)
695 return NULL;
696 skb = FRAG_CB(head)->next_frag;
697 if (skb)
698 rb_replace_node(&head->rbnode, &skb->rbnode,
699 &q->rb_fragments);
700 else
701 rb_erase(&head->rbnode, &q->rb_fragments);
702 memset(&head->rbnode, 0, sizeof(head->rbnode));
703 barrier();
704
705 if (head == q->fragments_tail)
706 q->fragments_tail = NULL;
707
708 sub_frag_mem_limit(q->fqdir, head->truesize);
709
710 return head;
711 }
712 EXPORT_SYMBOL(inet_frag_pull_head);
713