]> git.proxmox.com Git - mirror_ovs.git/blame - datapath/linux/compat/ip_fragment.c
compat: Simplify inet_fragment backports.
[mirror_ovs.git] / datapath / linux / compat / ip_fragment.c
CommitLineData
595e069a
JS
1/*
2 * IP fragmentation backport, heavily based on linux/net/ipv4/ip_fragment.c,
3 * copied from Linux 192132b9a034 net: Add support for VRFs to inetpeer cache
4 *
5 * INET An implementation of the TCP/IP protocol suite for the LINUX
6 * operating system. INET is implemented using the BSD Socket
7 * interface as the means of communication with the user level.
8 *
9 * The IP fragmentation functionality.
10 *
11 * Authors: Fred N. van Kempen <waltje@uWalt.NL.Mugnet.ORG>
12 * Alan Cox <alan@lxorguk.ukuu.org.uk>
13 *
14 * Fixes:
15 * Alan Cox : Split from ip.c , see ip_input.c for history.
16 * David S. Miller : Begin massive cleanup...
17 * Andi Kleen : Add sysctls.
18 * xxxx : Overlapfrag bug.
19 * Ultima : ip_expire() kernel panic.
20 * Bill Hawes : Frag accounting and evictor fixes.
21 * John McDonald : 0 length frag bug.
22 * Alexey Kuznetsov: SMP races, threading, cleanup.
23 * Patrick McHardy : LRU queue of frag heads for evictor.
24 */
25
26#include <linux/version.h>
27
3cdc5697 28#ifndef HAVE_CORRECT_MRU_HANDLING
595e069a
JS
29
30#define pr_fmt(fmt) "IPv4: " fmt
31
32#include <linux/compiler.h>
33#include <linux/module.h>
34#include <linux/types.h>
35#include <linux/mm.h>
36#include <linux/jiffies.h>
37#include <linux/skbuff.h>
38#include <linux/list.h>
39#include <linux/ip.h>
40#include <linux/icmp.h>
41#include <linux/netdevice.h>
42#include <linux/jhash.h>
43#include <linux/random.h>
44#include <linux/slab.h>
45#include <net/route.h>
46#include <net/dst.h>
47#include <net/sock.h>
48#include <net/ip.h>
49#include <net/icmp.h>
50#include <net/checksum.h>
51#include <net/inetpeer.h>
52#include <net/inet_frag.h>
53#include <linux/tcp.h>
54#include <linux/udp.h>
55#include <linux/inet.h>
56#include <linux/netfilter_ipv4.h>
57#include <net/inet_ecn.h>
58#include <net/vrf.h>
59#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
60
61/* NOTE. Logic of IP defragmentation is parallel to corresponding IPv6
62 * code now. If you change something here, _PLEASE_ update ipv6/reassembly.c
63 * as well. Or notify me, at least. --ANK
64 */
65
66static int sysctl_ipfrag_max_dist __read_mostly = 64;
63129291 67static const char ip_frag_cache_name[] = "ovs-frag4";
595e069a
JS
68
69struct ipfrag_skb_cb
70{
71 struct inet_skb_parm h;
72 int offset;
73};
74
75#define FRAG_CB(skb) ((struct ipfrag_skb_cb *)((skb)->cb))
76
77/* Describe an entry in the "incomplete datagrams" queue. */
78struct ipq {
ccd0a13b 79 struct inet_frag_queue q;
595e069a
JS
80
81 u32 user;
82 __be32 saddr;
83 __be32 daddr;
84 __be16 id;
85 u8 protocol;
86 u8 ecn; /* RFC3168 support */
87 u16 max_df_size; /* largest frag with DF set seen */
88 int iif;
89 int vif; /* VRF device index */
90 unsigned int rid;
91 struct inet_peer *peer;
92};
93
94static u8 ip4_frag_ecn(u8 tos)
95{
96 return 1 << (tos & INET_ECN_MASK);
97}
98
99static struct inet_frags ip4_frags;
100
101static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
102 struct net_device *dev);
103
104struct ip4_create_arg {
105 struct iphdr *iph;
106 u32 user;
107 int vif;
108};
109
110static unsigned int ipqhashfn(__be16 id, __be32 saddr, __be32 daddr, u8 prot)
111{
112 net_get_random_once(&ip4_frags.rnd, sizeof(ip4_frags.rnd));
113 return jhash_3words((__force u32)id << 16 | prot,
114 (__force u32)saddr, (__force u32)daddr,
115 ip4_frags.rnd);
116}
ccd0a13b
JS
117/* fb3cfe6e75b9 ("inet: frag: remove hash size assumptions from callers")
118 * shifted this logic into inet_fragment, but prior kernels still need this.
119 */
120#if LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0)
121#define ipqhashfn(a, b, c, d) (ipqhashfn(a, b, c, d) & (INETFRAGS_HASHSZ - 1))
122#endif
595e069a
JS
123
124#ifdef HAVE_INET_FRAGS_CONST
125static unsigned int ip4_hashfn(const struct inet_frag_queue *q)
126#else
127static unsigned int ip4_hashfn(struct inet_frag_queue *q)
128#endif
129{
130 const struct ipq *ipq;
131
132 ipq = container_of(q, struct ipq, q);
133 return ipqhashfn(ipq->id, ipq->saddr, ipq->daddr, ipq->protocol);
134}
135
136#ifdef HAVE_INET_FRAGS_CONST
137static bool ip4_frag_match(const struct inet_frag_queue *q, const void *a)
138#else
139static bool ip4_frag_match(struct inet_frag_queue *q, void *a)
140#endif
141{
142 const struct ipq *qp;
143 const struct ip4_create_arg *arg = a;
144
145 qp = container_of(q, struct ipq, q);
146 return qp->id == arg->iph->id &&
147 qp->saddr == arg->iph->saddr &&
148 qp->daddr == arg->iph->daddr &&
149 qp->protocol == arg->iph->protocol &&
150 qp->user == arg->user &&
151 qp->vif == arg->vif;
152}
153
154#ifdef HAVE_INET_FRAGS_CONST
155static void ip4_frag_init(struct inet_frag_queue *q, const void *a)
156#else
157static void ip4_frag_init(struct inet_frag_queue *q, void *a)
158#endif
159{
160 struct ipq *qp = container_of(q, struct ipq, q);
161 struct netns_ipv4 *ipv4 = container_of(q->net, struct netns_ipv4,
162 frags);
163 struct net *net = container_of(ipv4, struct net, ipv4);
164
165 const struct ip4_create_arg *arg = a;
166
167 qp->protocol = arg->iph->protocol;
168 qp->id = arg->iph->id;
169 qp->ecn = ip4_frag_ecn(arg->iph->tos);
170 qp->saddr = arg->iph->saddr;
171 qp->daddr = arg->iph->daddr;
172 qp->vif = arg->vif;
173 qp->user = arg->user;
174 qp->peer = sysctl_ipfrag_max_dist ?
175 inet_getpeer_v4(net->ipv4.peers, arg->iph->saddr, arg->vif, 1) :
176 NULL;
177}
178
179static void ip4_frag_free(struct inet_frag_queue *q)
180{
181 struct ipq *qp;
182
183 qp = container_of(q, struct ipq, q);
184 if (qp->peer)
185 inet_putpeer(qp->peer);
186}
187
188
189/* Destruction primitives. */
190
191static void ipq_put(struct ipq *ipq)
192{
193 inet_frag_put(&ipq->q, &ip4_frags);
194}
195
196/* Kill ipq entry. It is not destroyed immediately,
197 * because caller (and someone more) holds reference count.
198 */
199static void ipq_kill(struct ipq *ipq)
200{
201 inet_frag_kill(&ipq->q, &ip4_frags);
202}
203
204static bool frag_expire_skip_icmp(u32 user)
205{
206 return user == IP_DEFRAG_AF_PACKET ||
207 ip_defrag_user_in_between(user, IP_DEFRAG_CONNTRACK_IN,
208 __IP_DEFRAG_CONNTRACK_IN_END) ||
209 ip_defrag_user_in_between(user, IP_DEFRAG_CONNTRACK_BRIDGE_IN,
210 __IP_DEFRAG_CONNTRACK_BRIDGE_IN);
211}
212
213/*
214 * Oops, a fragment queue timed out. Kill it and send an ICMP reply.
215 */
216static void ip_expire(unsigned long arg)
217{
218 struct ipq *qp;
219 struct net *net;
220
221 qp = container_of((struct inet_frag_queue *) arg, struct ipq, q);
222 net = container_of(qp->q.net, struct net, ipv4.frags);
223
224 spin_lock(&qp->q.lock);
225
226 if (qp_flags(qp) & INET_FRAG_COMPLETE)
227 goto out;
228
229 ipq_kill(qp);
230 IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS);
231
232 if (!inet_frag_evicting(&qp->q)) {
233 struct sk_buff *head = qp->q.fragments;
234 const struct iphdr *iph;
235 int err;
236
237 IP_INC_STATS_BH(net, IPSTATS_MIB_REASMTIMEOUT);
238
239 if (!(qp_flags(qp) & INET_FRAG_FIRST_IN) || !qp->q.fragments)
240 goto out;
241
242 rcu_read_lock();
243 head->dev = dev_get_by_index_rcu(net, qp->iif);
244 if (!head->dev)
245 goto out_rcu_unlock;
246
247 /* skb has no dst, perform route lookup again */
248 iph = ip_hdr(head);
249 err = ip_route_input_noref(head, iph->daddr, iph->saddr,
250 iph->tos, head->dev);
251 if (err)
252 goto out_rcu_unlock;
253
254 /* Only an end host needs to send an ICMP
255 * "Fragment Reassembly Timeout" message, per RFC792.
256 */
257 if (frag_expire_skip_icmp(qp->user) &&
258 (skb_rtable(head)->rt_type != RTN_LOCAL))
259 goto out_rcu_unlock;
260
261 /* Send an ICMP "Fragment Reassembly Timeout" message. */
262 icmp_send(head, ICMP_TIME_EXCEEDED, ICMP_EXC_FRAGTIME, 0);
263out_rcu_unlock:
264 rcu_read_unlock();
265 }
266out:
267 spin_unlock(&qp->q.lock);
268 ipq_put(qp);
269}
270
ccd0a13b
JS
271#ifdef HAVE_INET_FRAG_EVICTOR
272/* Memory limiting on fragments. Evictor trashes the oldest
273 * fragment queue until we are back under the threshold.
274 *
275 * Necessary for kernels earlier than v3.17. Replaced in commit
276 * b13d3cbfb8e8 ("inet: frag: move eviction of queues to work queue").
277 */
278static void ip_evictor(struct net *net)
279{
280 int evicted;
281
282 evicted = inet_frag_evictor(&net->ipv4.frags, &ip4_frags, false);
283 if (evicted)
284 IP_ADD_STATS_BH(net, IPSTATS_MIB_REASMFAILS, evicted);
285}
286#endif
287
595e069a
JS
288/* Find the correct entry in the "incomplete datagrams" queue for
289 * this IP datagram, and create new one, if nothing is found.
290 */
291static struct ipq *ip_find(struct net *net, struct iphdr *iph,
292 u32 user, int vif)
293{
294 struct inet_frag_queue *q;
295 struct ip4_create_arg arg;
296 unsigned int hash;
297
298 arg.iph = iph;
299 arg.user = user;
300 arg.vif = vif;
301
ccd0a13b
JS
302#ifdef HAVE_INET_FRAGS_WITH_RWLOCK
303 read_lock(&ip4_frags.lock);
304#endif
595e069a
JS
305 hash = ipqhashfn(iph->id, iph->saddr, iph->daddr, iph->protocol);
306
307 q = inet_frag_find(&net->ipv4.frags, &ip4_frags, &arg, hash);
308 if (IS_ERR_OR_NULL(q)) {
309 inet_frag_maybe_warn_overflow(q, pr_fmt());
310 return NULL;
311 }
312 return container_of(q, struct ipq, q);
313}
314
315/* Is the fragment too far ahead to be part of ipq? */
316static int ip_frag_too_far(struct ipq *qp)
317{
318 struct inet_peer *peer = qp->peer;
319 unsigned int max = sysctl_ipfrag_max_dist;
320 unsigned int start, end;
321
322 int rc;
323
324 if (!peer || !max)
325 return 0;
326
327 start = qp->rid;
328 end = atomic_inc_return(&peer->rid);
329 qp->rid = end;
330
331 rc = qp->q.fragments && (end - start) > max;
332
333 if (rc) {
334 struct net *net;
335
336 net = container_of(qp->q.net, struct net, ipv4.frags);
337 IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS);
338 }
339
340 return rc;
341}
342
343static int ip_frag_reinit(struct ipq *qp)
344{
345 struct sk_buff *fp;
346 unsigned int sum_truesize = 0;
347
348 if (!mod_timer(&qp->q.timer, jiffies + qp->q.net->timeout)) {
349 atomic_inc(&qp->q.refcnt);
350 return -ETIMEDOUT;
351 }
352
353 fp = qp->q.fragments;
354 do {
355 struct sk_buff *xp = fp->next;
356
357 sum_truesize += fp->truesize;
358 kfree_skb(fp);
359 fp = xp;
360 } while (fp);
361 sub_frag_mem_limit(qp->q.net, sum_truesize);
362
363 qp_flags(qp) = 0;
364 qp->q.len = 0;
365 qp->q.meat = 0;
366 qp->q.fragments = NULL;
367 qp->q.fragments_tail = NULL;
368 qp->iif = 0;
369 qp->ecn = 0;
370
371 return 0;
372}
373
374/* Add new segment to existing queue. */
375static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
376{
377 struct sk_buff *prev, *next;
378 struct net_device *dev;
379 unsigned int fragsize;
380 int flags, offset;
381 int ihl, end;
382 int err = -ENOENT;
383 u8 ecn;
384
385 if (qp_flags(qp) & INET_FRAG_COMPLETE)
386 goto err;
387
388 if (!(IPCB(skb)->flags & IPSKB_FRAG_COMPLETE) &&
389 unlikely(ip_frag_too_far(qp)) &&
390 unlikely(err = ip_frag_reinit(qp))) {
391 ipq_kill(qp);
392 goto err;
393 }
394
395 ecn = ip4_frag_ecn(ip_hdr(skb)->tos);
396 offset = ntohs(ip_hdr(skb)->frag_off);
397 flags = offset & ~IP_OFFSET;
398 offset &= IP_OFFSET;
399 offset <<= 3; /* offset is in 8-byte chunks */
400 ihl = ip_hdrlen(skb);
401
402 /* Determine the position of this fragment. */
403 end = offset + skb->len - skb_network_offset(skb) - ihl;
404 err = -EINVAL;
405
406 /* Is this the final fragment? */
407 if ((flags & IP_MF) == 0) {
408 /* If we already have some bits beyond end
409 * or have different end, the segment is corrupted.
410 */
411 if (end < qp->q.len ||
412 ((qp_flags(qp) & INET_FRAG_LAST_IN) && end != qp->q.len))
413 goto err;
414 qp_flags(qp) |= INET_FRAG_LAST_IN;
415 qp->q.len = end;
416 } else {
417 if (end&7) {
418 end &= ~7;
419 if (skb->ip_summed != CHECKSUM_UNNECESSARY)
420 skb->ip_summed = CHECKSUM_NONE;
421 }
422 if (end > qp->q.len) {
423 /* Some bits beyond end -> corruption. */
424 if (qp_flags(qp) & INET_FRAG_LAST_IN)
425 goto err;
426 qp->q.len = end;
427 }
428 }
429 if (end == offset)
430 goto err;
431
432 err = -ENOMEM;
433 if (!pskb_pull(skb, skb_network_offset(skb) + ihl))
434 goto err;
435
436 err = pskb_trim_rcsum(skb, end - offset);
437 if (err)
438 goto err;
439
440 /* Find out which fragments are in front and at the back of us
441 * in the chain of fragments so far. We must know where to put
442 * this fragment, right?
443 */
444 prev = qp->q.fragments_tail;
445 if (!prev || FRAG_CB(prev)->offset < offset) {
446 next = NULL;
447 goto found;
448 }
449 prev = NULL;
450 for (next = qp->q.fragments; next != NULL; next = next->next) {
451 if (FRAG_CB(next)->offset >= offset)
452 break; /* bingo! */
453 prev = next;
454 }
455
456found:
457 /* We found where to put this one. Check for overlap with
458 * preceding fragment, and, if needed, align things so that
459 * any overlaps are eliminated.
460 */
461 if (prev) {
462 int i = (FRAG_CB(prev)->offset + prev->len) - offset;
463
464 if (i > 0) {
465 offset += i;
466 err = -EINVAL;
467 if (end <= offset)
468 goto err;
469 err = -ENOMEM;
470 if (!pskb_pull(skb, i))
471 goto err;
472 if (skb->ip_summed != CHECKSUM_UNNECESSARY)
473 skb->ip_summed = CHECKSUM_NONE;
474 }
475 }
476
477 err = -ENOMEM;
478
479 while (next && FRAG_CB(next)->offset < end) {
480 int i = end - FRAG_CB(next)->offset; /* overlap is 'i' bytes */
481
482 if (i < next->len) {
483 /* Eat head of the next overlapped fragment
484 * and leave the loop. The next ones cannot overlap.
485 */
486 if (!pskb_pull(next, i))
487 goto err;
488 FRAG_CB(next)->offset += i;
489 qp->q.meat -= i;
490 if (next->ip_summed != CHECKSUM_UNNECESSARY)
491 next->ip_summed = CHECKSUM_NONE;
492 break;
493 } else {
494 struct sk_buff *free_it = next;
495
496 /* Old fragment is completely overridden with
497 * new one drop it.
498 */
499 next = next->next;
500
501 if (prev)
502 prev->next = next;
503 else
504 qp->q.fragments = next;
505
506 qp->q.meat -= free_it->len;
507 sub_frag_mem_limit(qp->q.net, free_it->truesize);
508 kfree_skb(free_it);
509 }
510 }
511
512 FRAG_CB(skb)->offset = offset;
513
514 /* Insert this fragment in the chain of fragments. */
515 skb->next = next;
516 if (!next)
517 qp->q.fragments_tail = skb;
518 if (prev)
519 prev->next = skb;
520 else
521 qp->q.fragments = skb;
522
523 dev = skb->dev;
524 if (dev) {
525 qp->iif = dev->ifindex;
526 skb->dev = NULL;
527 }
528 qp->q.stamp = skb->tstamp;
529 qp->q.meat += skb->len;
530 qp->ecn |= ecn;
531 add_frag_mem_limit(qp->q.net, skb->truesize);
532 if (offset == 0)
533 qp_flags(qp) |= INET_FRAG_FIRST_IN;
534
535 fragsize = skb->len + ihl;
536
537 if (fragsize > qp->q.max_size)
538 qp->q.max_size = fragsize;
539
540 if (ip_hdr(skb)->frag_off & htons(IP_DF) &&
541 fragsize > qp->max_df_size)
542 qp->max_df_size = fragsize;
543
544 if (qp_flags(qp) == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) &&
545 qp->q.meat == qp->q.len) {
546 unsigned long orefdst = skb->_skb_refdst;
547
548 skb->_skb_refdst = 0UL;
549 err = ip_frag_reasm(qp, prev, dev);
550 skb->_skb_refdst = orefdst;
551 return err;
552 }
553
554 skb_dst_drop(skb);
555 return -EINPROGRESS;
556
557err:
558 kfree_skb(skb);
559 return err;
560}
561
562
563/* Build a new IP datagram from all its fragments. */
564
565static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
566 struct net_device *dev)
567{
568 struct net *net = container_of(qp->q.net, struct net, ipv4.frags);
569 struct iphdr *iph;
570 struct sk_buff *fp, *head = qp->q.fragments;
571 int len;
572 int ihlen;
573 int err;
574 u8 ecn;
575
576 ipq_kill(qp);
577
578 ecn = ip_frag_ecn_table[qp->ecn];
579 if (unlikely(ecn == 0xff)) {
580 err = -EINVAL;
581 goto out_fail;
582 }
583 /* Make the one we just received the head. */
584 if (prev) {
585 head = prev->next;
586 fp = skb_clone(head, GFP_ATOMIC);
587 if (!fp)
588 goto out_nomem;
589
590 fp->next = head->next;
591 if (!fp->next)
592 qp->q.fragments_tail = fp;
593 prev->next = fp;
594
595 skb_morph(head, qp->q.fragments);
596 head->next = qp->q.fragments->next;
597
598 consume_skb(qp->q.fragments);
599 qp->q.fragments = head;
600 }
601
602 WARN_ON(!head);
603 WARN_ON(FRAG_CB(head)->offset != 0);
604
605 /* Allocate a new buffer for the datagram. */
606 ihlen = ip_hdrlen(head);
607 len = ihlen + qp->q.len;
608
609 err = -E2BIG;
610 if (len > 65535)
611 goto out_oversize;
612
613 /* Head of list must not be cloned. */
614 if (skb_unclone(head, GFP_ATOMIC))
615 goto out_nomem;
616
617 /* If the first fragment is fragmented itself, we split
618 * it to two chunks: the first with data and paged part
619 * and the second, holding only fragments. */
620 if (skb_has_frag_list(head)) {
621 struct sk_buff *clone;
622 int i, plen = 0;
623
624 clone = alloc_skb(0, GFP_ATOMIC);
625 if (!clone)
626 goto out_nomem;
627 clone->next = head->next;
628 head->next = clone;
629 skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list;
630 skb_frag_list_init(head);
631 for (i = 0; i < skb_shinfo(head)->nr_frags; i++)
632 plen += skb_frag_size(&skb_shinfo(head)->frags[i]);
633 clone->len = clone->data_len = head->data_len - plen;
634 head->data_len -= clone->len;
635 head->len -= clone->len;
636 clone->csum = 0;
637 clone->ip_summed = head->ip_summed;
638 add_frag_mem_limit(qp->q.net, clone->truesize);
639 }
640
641 skb_shinfo(head)->frag_list = head->next;
642 skb_push(head, head->data - skb_network_header(head));
643
644 for (fp=head->next; fp; fp = fp->next) {
645 head->data_len += fp->len;
646 head->len += fp->len;
647 if (head->ip_summed != fp->ip_summed)
648 head->ip_summed = CHECKSUM_NONE;
649 else if (head->ip_summed == CHECKSUM_COMPLETE)
650 head->csum = csum_add(head->csum, fp->csum);
651 head->truesize += fp->truesize;
652 }
653 sub_frag_mem_limit(qp->q.net, head->truesize);
654
655 head->next = NULL;
656 head->dev = dev;
657 head->tstamp = qp->q.stamp;
658 IPCB(head)->frag_max_size = max(qp->max_df_size, qp->q.max_size);
659
660 iph = ip_hdr(head);
661 iph->tot_len = htons(len);
662 iph->tos |= ecn;
663
664 /* When we set IP_DF on a refragmented skb we must also force a
665 * call to ip_fragment to avoid forwarding a DF-skb of size s while
666 * original sender only sent fragments of size f (where f < s).
667 *
668 * We only set DF/IPSKB_FRAG_PMTU if such DF fragment was the largest
669 * frag seen to avoid sending tiny DF-fragments in case skb was built
670 * from one very small df-fragment and one large non-df frag.
671 */
672 if (qp->max_df_size == qp->q.max_size) {
673 IPCB(head)->flags |= IPSKB_FRAG_PMTU;
674 iph->frag_off = htons(IP_DF);
675 } else {
676 iph->frag_off = 0;
677 }
678
679 ip_send_check(iph);
680
681 IP_INC_STATS_BH(net, IPSTATS_MIB_REASMOKS);
682 qp->q.fragments = NULL;
683 qp->q.fragments_tail = NULL;
684 return 0;
685
686out_nomem:
687 net_dbg_ratelimited("queue_glue: no memory for gluing queue %p\n", qp);
688 err = -ENOMEM;
689 goto out_fail;
690out_oversize:
691 net_info_ratelimited("Oversized IP packet from %pI4\n", &qp->saddr);
692out_fail:
693 IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS);
694 return err;
695}
696
697/* Process an incoming IP datagram fragment. */
39c0ff22 698int rpl_ip_defrag(struct net *net, struct sk_buff *skb, u32 user)
595e069a
JS
699{
700 struct net_device *dev = skb->dev ? : skb_dst(skb)->dev;
701 int vif = vrf_master_ifindex_rcu(dev);
595e069a
JS
702 struct ipq *qp;
703
704 IP_INC_STATS_BH(net, IPSTATS_MIB_REASMREQDS);
792e5ed7 705 skb_orphan(skb);
595e069a 706
ccd0a13b
JS
707#ifdef HAVE_INET_FRAG_EVICTOR
708 /* Start by cleaning up the memory. */
709 ip_evictor(net);
710#endif
711
595e069a
JS
712 /* Lookup (or create) queue header */
713 qp = ip_find(net, ip_hdr(skb), user, vif);
714 if (qp) {
715 int ret;
716
717 spin_lock(&qp->q.lock);
718
719 ret = ip_frag_queue(qp, skb);
720
721 spin_unlock(&qp->q.lock);
722 ipq_put(qp);
723 return ret;
724 }
725
726 IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS);
727 kfree_skb(skb);
728 return -ENOMEM;
729}
595e069a
JS
730
731static int __net_init ipv4_frags_init_net(struct net *net)
732{
733 nf_defrag_ipv4_enable();
734
735 return 0;
736}
737
738static void __net_exit ipv4_frags_exit_net(struct net *net)
739{
740 inet_frags_exit_net(&net->ipv4.frags, &ip4_frags);
741}
742
743static struct pernet_operations ip4_frags_ops = {
744 .init = ipv4_frags_init_net,
745 .exit = ipv4_frags_exit_net,
746};
747
748int __init rpl_ipfrag_init(void)
749{
750 register_pernet_subsys(&ip4_frags_ops);
751 ip4_frags.hashfn = ip4_hashfn;
752 ip4_frags.constructor = ip4_frag_init;
753 ip4_frags.destructor = ip4_frag_free;
754 ip4_frags.skb_free = NULL;
755 ip4_frags.qsize = sizeof(struct ipq);
756 ip4_frags.match = ip4_frag_match;
757 ip4_frags.frag_expire = ip_expire;
91408ae0 758#ifdef HAVE_INET_FRAGS_WITH_FRAGS_WORK
595e069a
JS
759 ip4_frags.frags_cache_name = ip_frag_cache_name;
760#endif
761 if (inet_frags_init(&ip4_frags)) {
762 pr_warn("IP: failed to allocate ip4_frags cache\n");
763 return -ENOMEM;
764 }
765 return 0;
766}
767
768void rpl_ipfrag_fini(void)
769{
770 inet_frags_fini(&ip4_frags);
771 unregister_pernet_subsys(&ip4_frags_ops);
772}
773
3cdc5697 774#endif /* !HAVE_CORRECT_MRU_HANDLING */