linux/net/ipv6/netfilter/nf_conntrack_reasm.c
<<
>>
Prefs
   1/*
   2 * IPv6 fragment reassembly for connection tracking
   3 *
   4 * Copyright (C)2004 USAGI/WIDE Project
   5 *
   6 * Author:
   7 *      Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp>
   8 *
   9 * Based on: net/ipv6/reassembly.c
  10 *
  11 * This program is free software; you can redistribute it and/or
  12 * modify it under the terms of the GNU General Public License
  13 * as published by the Free Software Foundation; either version
  14 * 2 of the License, or (at your option) any later version.
  15 */
  16
  17#include <linux/errno.h>
  18#include <linux/types.h>
  19#include <linux/string.h>
  20#include <linux/socket.h>
  21#include <linux/sockios.h>
  22#include <linux/jiffies.h>
  23#include <linux/net.h>
  24#include <linux/list.h>
  25#include <linux/netdevice.h>
  26#include <linux/in6.h>
  27#include <linux/ipv6.h>
  28#include <linux/icmpv6.h>
  29#include <linux/random.h>
  30#include <linux/jhash.h>
  31
  32#include <net/sock.h>
  33#include <net/snmp.h>
  34#include <net/inet_frag.h>
  35
  36#include <net/ipv6.h>
  37#include <net/protocol.h>
  38#include <net/transp_v6.h>
  39#include <net/rawv6.h>
  40#include <net/ndisc.h>
  41#include <net/addrconf.h>
  42#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
  43#include <linux/sysctl.h>
  44#include <linux/netfilter.h>
  45#include <linux/netfilter_ipv6.h>
  46#include <linux/kernel.h>
  47#include <linux/module.h>
  48
  49#define NF_CT_FRAG6_HIGH_THRESH 262144 /* == 256*1024 */
  50#define NF_CT_FRAG6_LOW_THRESH 196608  /* == 192*1024 */
  51#define NF_CT_FRAG6_TIMEOUT IPV6_FRAG_TIMEOUT
  52
  53struct nf_ct_frag6_skb_cb
  54{
  55        struct inet6_skb_parm   h;
  56        int                     offset;
  57        struct sk_buff          *orig;
  58};
  59
  60#define NFCT_FRAG6_CB(skb)      ((struct nf_ct_frag6_skb_cb*)((skb)->cb))
  61
  62struct nf_ct_frag6_queue
  63{
  64        struct inet_frag_queue  q;
  65
  66        __be32                  id;             /* fragment id          */
  67        u32                     user;
  68        struct in6_addr         saddr;
  69        struct in6_addr         daddr;
  70
  71        unsigned int            csum;
  72        __u16                   nhoffset;
  73};
  74
  75static struct inet_frags nf_frags;
  76static struct netns_frags nf_init_frags;
  77
  78#ifdef CONFIG_SYSCTL
  79struct ctl_table nf_ct_ipv6_sysctl_table[] = {
  80        {
  81                .procname       = "nf_conntrack_frag6_timeout",
  82                .data           = &nf_init_frags.timeout,
  83                .maxlen         = sizeof(unsigned int),
  84                .mode           = 0644,
  85                .proc_handler   = &proc_dointvec_jiffies,
  86        },
  87        {
  88                .ctl_name       = NET_NF_CONNTRACK_FRAG6_LOW_THRESH,
  89                .procname       = "nf_conntrack_frag6_low_thresh",
  90                .data           = &nf_init_frags.low_thresh,
  91                .maxlen         = sizeof(unsigned int),
  92                .mode           = 0644,
  93                .proc_handler   = &proc_dointvec,
  94        },
  95        {
  96                .ctl_name       = NET_NF_CONNTRACK_FRAG6_HIGH_THRESH,
  97                .procname       = "nf_conntrack_frag6_high_thresh",
  98                .data           = &nf_init_frags.high_thresh,
  99                .maxlen         = sizeof(unsigned int),
 100                .mode           = 0644,
 101                .proc_handler   = &proc_dointvec,
 102        },
 103        { .ctl_name = 0 }
 104};
 105#endif
 106
 107static unsigned int ip6qhashfn(__be32 id, const struct in6_addr *saddr,
 108                               const struct in6_addr *daddr)
 109{
 110        u32 a, b, c;
 111
 112        a = (__force u32)saddr->s6_addr32[0];
 113        b = (__force u32)saddr->s6_addr32[1];
 114        c = (__force u32)saddr->s6_addr32[2];
 115
 116        a += JHASH_GOLDEN_RATIO;
 117        b += JHASH_GOLDEN_RATIO;
 118        c += nf_frags.rnd;
 119        __jhash_mix(a, b, c);
 120
 121        a += (__force u32)saddr->s6_addr32[3];
 122        b += (__force u32)daddr->s6_addr32[0];
 123        c += (__force u32)daddr->s6_addr32[1];
 124        __jhash_mix(a, b, c);
 125
 126        a += (__force u32)daddr->s6_addr32[2];
 127        b += (__force u32)daddr->s6_addr32[3];
 128        c += (__force u32)id;
 129        __jhash_mix(a, b, c);
 130
 131        return c & (INETFRAGS_HASHSZ - 1);
 132}
 133
 134static unsigned int nf_hashfn(struct inet_frag_queue *q)
 135{
 136        const struct nf_ct_frag6_queue *nq;
 137
 138        nq = container_of(q, struct nf_ct_frag6_queue, q);
 139        return ip6qhashfn(nq->id, &nq->saddr, &nq->daddr);
 140}
 141
 142static void nf_skb_free(struct sk_buff *skb)
 143{
 144        if (NFCT_FRAG6_CB(skb)->orig)
 145                kfree_skb(NFCT_FRAG6_CB(skb)->orig);
 146}
 147
 148/* Memory Tracking Functions. */
 149static inline void frag_kfree_skb(struct sk_buff *skb, unsigned int *work)
 150{
 151        if (work)
 152                *work -= skb->truesize;
 153        atomic_sub(skb->truesize, &nf_init_frags.mem);
 154        nf_skb_free(skb);
 155        kfree_skb(skb);
 156}
 157
 158/* Destruction primitives. */
 159
 160static __inline__ void fq_put(struct nf_ct_frag6_queue *fq)
 161{
 162        inet_frag_put(&fq->q, &nf_frags);
 163}
 164
 165/* Kill fq entry. It is not destroyed immediately,
 166 * because caller (and someone more) holds reference count.
 167 */
 168static __inline__ void fq_kill(struct nf_ct_frag6_queue *fq)
 169{
 170        inet_frag_kill(&fq->q, &nf_frags);
 171}
 172
 173static void nf_ct_frag6_evictor(void)
 174{
 175        local_bh_disable();
 176        inet_frag_evictor(&nf_init_frags, &nf_frags);
 177        local_bh_enable();
 178}
 179
 180static void nf_ct_frag6_expire(unsigned long data)
 181{
 182        struct nf_ct_frag6_queue *fq;
 183
 184        fq = container_of((struct inet_frag_queue *)data,
 185                        struct nf_ct_frag6_queue, q);
 186
 187        spin_lock(&fq->q.lock);
 188
 189        if (fq->q.last_in & INET_FRAG_COMPLETE)
 190                goto out;
 191
 192        fq_kill(fq);
 193
 194out:
 195        spin_unlock(&fq->q.lock);
 196        fq_put(fq);
 197}
 198
 199/* Creation primitives. */
 200
 201static __inline__ struct nf_ct_frag6_queue *
 202fq_find(__be32 id, u32 user, struct in6_addr *src, struct in6_addr *dst)
 203{
 204        struct inet_frag_queue *q;
 205        struct ip6_create_arg arg;
 206        unsigned int hash;
 207
 208        arg.id = id;
 209        arg.user = user;
 210        arg.src = src;
 211        arg.dst = dst;
 212
 213        read_lock_bh(&nf_frags.lock);
 214        hash = ip6qhashfn(id, src, dst);
 215
 216        q = inet_frag_find(&nf_init_frags, &nf_frags, &arg, hash);
 217        local_bh_enable();
 218        if (q == NULL)
 219                goto oom;
 220
 221        return container_of(q, struct nf_ct_frag6_queue, q);
 222
 223oom:
 224        pr_debug("Can't alloc new queue\n");
 225        return NULL;
 226}
 227
 228
 229static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
 230                             const struct frag_hdr *fhdr, int nhoff)
 231{
 232        struct sk_buff *prev, *next;
 233        int offset, end;
 234
 235        if (fq->q.last_in & INET_FRAG_COMPLETE) {
 236                pr_debug("Allready completed\n");
 237                goto err;
 238        }
 239
 240        offset = ntohs(fhdr->frag_off) & ~0x7;
 241        end = offset + (ntohs(ipv6_hdr(skb)->payload_len) -
 242                        ((u8 *)(fhdr + 1) - (u8 *)(ipv6_hdr(skb) + 1)));
 243
 244        if ((unsigned int)end > IPV6_MAXPLEN) {
 245                pr_debug("offset is too large.\n");
 246                return -1;
 247        }
 248
 249        if (skb->ip_summed == CHECKSUM_COMPLETE) {
 250                const unsigned char *nh = skb_network_header(skb);
 251                skb->csum = csum_sub(skb->csum,
 252                                     csum_partial(nh, (u8 *)(fhdr + 1) - nh,
 253                                                  0));
 254        }
 255
 256        /* Is this the final fragment? */
 257        if (!(fhdr->frag_off & htons(IP6_MF))) {
 258                /* If we already have some bits beyond end
 259                 * or have different end, the segment is corrupted.
 260                 */
 261                if (end < fq->q.len ||
 262                    ((fq->q.last_in & INET_FRAG_LAST_IN) && end != fq->q.len)) {
 263                        pr_debug("already received last fragment\n");
 264                        goto err;
 265                }
 266                fq->q.last_in |= INET_FRAG_LAST_IN;
 267                fq->q.len = end;
 268        } else {
 269                /* Check if the fragment is rounded to 8 bytes.
 270                 * Required by the RFC.
 271                 */
 272                if (end & 0x7) {
 273                        /* RFC2460 says always send parameter problem in
 274                         * this case. -DaveM
 275                         */
 276                        pr_debug("end of fragment not rounded to 8 bytes.\n");
 277                        return -1;
 278                }
 279                if (end > fq->q.len) {
 280                        /* Some bits beyond end -> corruption. */
 281                        if (fq->q.last_in & INET_FRAG_LAST_IN) {
 282                                pr_debug("last packet already reached.\n");
 283                                goto err;
 284                        }
 285                        fq->q.len = end;
 286                }
 287        }
 288
 289        if (end == offset)
 290                goto err;
 291
 292        /* Point into the IP datagram 'data' part. */
 293        if (!pskb_pull(skb, (u8 *) (fhdr + 1) - skb->data)) {
 294                pr_debug("queue: message is too short.\n");
 295                goto err;
 296        }
 297        if (pskb_trim_rcsum(skb, end - offset)) {
 298                pr_debug("Can't trim\n");
 299                goto err;
 300        }
 301
 302        /* Find out which fragments are in front and at the back of us
 303         * in the chain of fragments so far.  We must know where to put
 304         * this fragment, right?
 305         */
 306        prev = NULL;
 307        for (next = fq->q.fragments; next != NULL; next = next->next) {
 308                if (NFCT_FRAG6_CB(next)->offset >= offset)
 309                        break;  /* bingo! */
 310                prev = next;
 311        }
 312
 313        /* We found where to put this one.  Check for overlap with
 314         * preceding fragment, and, if needed, align things so that
 315         * any overlaps are eliminated.
 316         */
 317        if (prev) {
 318                int i = (NFCT_FRAG6_CB(prev)->offset + prev->len) - offset;
 319
 320                if (i > 0) {
 321                        offset += i;
 322                        if (end <= offset) {
 323                                pr_debug("overlap\n");
 324                                goto err;
 325                        }
 326                        if (!pskb_pull(skb, i)) {
 327                                pr_debug("Can't pull\n");
 328                                goto err;
 329                        }
 330                        if (skb->ip_summed != CHECKSUM_UNNECESSARY)
 331                                skb->ip_summed = CHECKSUM_NONE;
 332                }
 333        }
 334
 335        /* Look for overlap with succeeding segments.
 336         * If we can merge fragments, do it.
 337         */
 338        while (next && NFCT_FRAG6_CB(next)->offset < end) {
 339                /* overlap is 'i' bytes */
 340                int i = end - NFCT_FRAG6_CB(next)->offset;
 341
 342                if (i < next->len) {
 343                        /* Eat head of the next overlapped fragment
 344                         * and leave the loop. The next ones cannot overlap.
 345                         */
 346                        pr_debug("Eat head of the overlapped parts.: %d", i);
 347                        if (!pskb_pull(next, i))
 348                                goto err;
 349
 350                        /* next fragment */
 351                        NFCT_FRAG6_CB(next)->offset += i;
 352                        fq->q.meat -= i;
 353                        if (next->ip_summed != CHECKSUM_UNNECESSARY)
 354                                next->ip_summed = CHECKSUM_NONE;
 355                        break;
 356                } else {
 357                        struct sk_buff *free_it = next;
 358
 359                        /* Old fragmnet is completely overridden with
 360                         * new one drop it.
 361                         */
 362                        next = next->next;
 363
 364                        if (prev)
 365                                prev->next = next;
 366                        else
 367                                fq->q.fragments = next;
 368
 369                        fq->q.meat -= free_it->len;
 370                        frag_kfree_skb(free_it, NULL);
 371                }
 372        }
 373
 374        NFCT_FRAG6_CB(skb)->offset = offset;
 375
 376        /* Insert this fragment in the chain of fragments. */
 377        skb->next = next;
 378        if (prev)
 379                prev->next = skb;
 380        else
 381                fq->q.fragments = skb;
 382
 383        skb->dev = NULL;
 384        fq->q.stamp = skb->tstamp;
 385        fq->q.meat += skb->len;
 386        atomic_add(skb->truesize, &nf_init_frags.mem);
 387
 388        /* The first fragment.
 389         * nhoffset is obtained from the first fragment, of course.
 390         */
 391        if (offset == 0) {
 392                fq->nhoffset = nhoff;
 393                fq->q.last_in |= INET_FRAG_FIRST_IN;
 394        }
 395        write_lock(&nf_frags.lock);
 396        list_move_tail(&fq->q.lru_list, &nf_init_frags.lru_list);
 397        write_unlock(&nf_frags.lock);
 398        return 0;
 399
 400err:
 401        return -1;
 402}
 403
 404/*
 405 *      Check if this packet is complete.
 406 *      Returns NULL on failure by any reason, and pointer
 407 *      to current nexthdr field in reassembled frame.
 408 *
 409 *      It is called with locked fq, and caller must check that
 410 *      queue is eligible for reassembly i.e. it is not COMPLETE,
 411 *      the last and the first frames arrived and all the bits are here.
 412 */
 413static struct sk_buff *
 414nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
 415{
 416        struct sk_buff *fp, *op, *head = fq->q.fragments;
 417        int    payload_len;
 418
 419        fq_kill(fq);
 420
 421        WARN_ON(head == NULL);
 422        WARN_ON(NFCT_FRAG6_CB(head)->offset != 0);
 423
 424        /* Unfragmented part is taken from the first segment. */
 425        payload_len = ((head->data - skb_network_header(head)) -
 426                       sizeof(struct ipv6hdr) + fq->q.len -
 427                       sizeof(struct frag_hdr));
 428        if (payload_len > IPV6_MAXPLEN) {
 429                pr_debug("payload len is too large.\n");
 430                goto out_oversize;
 431        }
 432
 433        /* Head of list must not be cloned. */
 434        if (skb_cloned(head) && pskb_expand_head(head, 0, 0, GFP_ATOMIC)) {
 435                pr_debug("skb is cloned but can't expand head");
 436                goto out_oom;
 437        }
 438
 439        /* If the first fragment is fragmented itself, we split
 440         * it to two chunks: the first with data and paged part
 441         * and the second, holding only fragments. */
 442        if (skb_shinfo(head)->frag_list) {
 443                struct sk_buff *clone;
 444                int i, plen = 0;
 445
 446                if ((clone = alloc_skb(0, GFP_ATOMIC)) == NULL) {
 447                        pr_debug("Can't alloc skb\n");
 448                        goto out_oom;
 449                }
 450                clone->next = head->next;
 451                head->next = clone;
 452                skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list;
 453                skb_shinfo(head)->frag_list = NULL;
 454                for (i=0; i<skb_shinfo(head)->nr_frags; i++)
 455                        plen += skb_shinfo(head)->frags[i].size;
 456                clone->len = clone->data_len = head->data_len - plen;
 457                head->data_len -= clone->len;
 458                head->len -= clone->len;
 459                clone->csum = 0;
 460                clone->ip_summed = head->ip_summed;
 461
 462                NFCT_FRAG6_CB(clone)->orig = NULL;
 463                atomic_add(clone->truesize, &nf_init_frags.mem);
 464        }
 465
 466        /* We have to remove fragment header from datagram and to relocate
 467         * header in order to calculate ICV correctly. */
 468        skb_network_header(head)[fq->nhoffset] = skb_transport_header(head)[0];
 469        memmove(head->head + sizeof(struct frag_hdr), head->head,
 470                (head->data - head->head) - sizeof(struct frag_hdr));
 471        head->mac_header += sizeof(struct frag_hdr);
 472        head->network_header += sizeof(struct frag_hdr);
 473
 474        skb_shinfo(head)->frag_list = head->next;
 475        skb_reset_transport_header(head);
 476        skb_push(head, head->data - skb_network_header(head));
 477        atomic_sub(head->truesize, &nf_init_frags.mem);
 478
 479        for (fp=head->next; fp; fp = fp->next) {
 480                head->data_len += fp->len;
 481                head->len += fp->len;
 482                if (head->ip_summed != fp->ip_summed)
 483                        head->ip_summed = CHECKSUM_NONE;
 484                else if (head->ip_summed == CHECKSUM_COMPLETE)
 485                        head->csum = csum_add(head->csum, fp->csum);
 486                head->truesize += fp->truesize;
 487                atomic_sub(fp->truesize, &nf_init_frags.mem);
 488        }
 489
 490        head->next = NULL;
 491        head->dev = dev;
 492        head->tstamp = fq->q.stamp;
 493        ipv6_hdr(head)->payload_len = htons(payload_len);
 494
 495        /* Yes, and fold redundant checksum back. 8) */
 496        if (head->ip_summed == CHECKSUM_COMPLETE)
 497                head->csum = csum_partial(skb_network_header(head),
 498                                          skb_network_header_len(head),
 499                                          head->csum);
 500
 501        fq->q.fragments = NULL;
 502
 503        /* all original skbs are linked into the NFCT_FRAG6_CB(head).orig */
 504        fp = skb_shinfo(head)->frag_list;
 505        if (NFCT_FRAG6_CB(fp)->orig == NULL)
 506                /* at above code, head skb is divided into two skbs. */
 507                fp = fp->next;
 508
 509        op = NFCT_FRAG6_CB(head)->orig;
 510        for (; fp; fp = fp->next) {
 511                struct sk_buff *orig = NFCT_FRAG6_CB(fp)->orig;
 512
 513                op->next = orig;
 514                op = orig;
 515                NFCT_FRAG6_CB(fp)->orig = NULL;
 516        }
 517
 518        return head;
 519
 520out_oversize:
 521        if (net_ratelimit())
 522                printk(KERN_DEBUG "nf_ct_frag6_reasm: payload len = %d\n", payload_len);
 523        goto out_fail;
 524out_oom:
 525        if (net_ratelimit())
 526                printk(KERN_DEBUG "nf_ct_frag6_reasm: no memory for reassembly\n");
 527out_fail:
 528        return NULL;
 529}
 530
 531/*
 532 * find the header just before Fragment Header.
 533 *
 534 * if success return 0 and set ...
 535 * (*prevhdrp): the value of "Next Header Field" in the header
 536 *              just before Fragment Header.
 537 * (*prevhoff): the offset of "Next Header Field" in the header
 538 *              just before Fragment Header.
 539 * (*fhoff)   : the offset of Fragment Header.
 540 *
 541 * Based on ipv6_skip_hdr() in net/ipv6/exthdr.c
 542 *
 543 */
 544static int
 545find_prev_fhdr(struct sk_buff *skb, u8 *prevhdrp, int *prevhoff, int *fhoff)
 546{
 547        u8 nexthdr = ipv6_hdr(skb)->nexthdr;
 548        const int netoff = skb_network_offset(skb);
 549        u8 prev_nhoff = netoff + offsetof(struct ipv6hdr, nexthdr);
 550        int start = netoff + sizeof(struct ipv6hdr);
 551        int len = skb->len - start;
 552        u8 prevhdr = NEXTHDR_IPV6;
 553
 554        while (nexthdr != NEXTHDR_FRAGMENT) {
 555                struct ipv6_opt_hdr hdr;
 556                int hdrlen;
 557
 558                if (!ipv6_ext_hdr(nexthdr)) {
 559                        return -1;
 560                }
 561                if (len < (int)sizeof(struct ipv6_opt_hdr)) {
 562                        pr_debug("too short\n");
 563                        return -1;
 564                }
 565                if (nexthdr == NEXTHDR_NONE) {
 566                        pr_debug("next header is none\n");
 567                        return -1;
 568                }
 569                if (skb_copy_bits(skb, start, &hdr, sizeof(hdr)))
 570                        BUG();
 571                if (nexthdr == NEXTHDR_AUTH)
 572                        hdrlen = (hdr.hdrlen+2)<<2;
 573                else
 574                        hdrlen = ipv6_optlen(&hdr);
 575
 576                prevhdr = nexthdr;
 577                prev_nhoff = start;
 578
 579                nexthdr = hdr.nexthdr;
 580                len -= hdrlen;
 581                start += hdrlen;
 582        }
 583
 584        if (len < 0)
 585                return -1;
 586
 587        *prevhdrp = prevhdr;
 588        *prevhoff = prev_nhoff;
 589        *fhoff = start;
 590
 591        return 0;
 592}
 593
 594struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
 595{
 596        struct sk_buff *clone;
 597        struct net_device *dev = skb->dev;
 598        struct frag_hdr *fhdr;
 599        struct nf_ct_frag6_queue *fq;
 600        struct ipv6hdr *hdr;
 601        int fhoff, nhoff;
 602        u8 prevhdr;
 603        struct sk_buff *ret_skb = NULL;
 604
 605        /* Jumbo payload inhibits frag. header */
 606        if (ipv6_hdr(skb)->payload_len == 0) {
 607                pr_debug("payload len = 0\n");
 608                return skb;
 609        }
 610
 611        if (find_prev_fhdr(skb, &prevhdr, &nhoff, &fhoff) < 0)
 612                return skb;
 613
 614        clone = skb_clone(skb, GFP_ATOMIC);
 615        if (clone == NULL) {
 616                pr_debug("Can't clone skb\n");
 617                return skb;
 618        }
 619
 620        NFCT_FRAG6_CB(clone)->orig = skb;
 621
 622        if (!pskb_may_pull(clone, fhoff + sizeof(*fhdr))) {
 623                pr_debug("message is too short.\n");
 624                goto ret_orig;
 625        }
 626
 627        skb_set_transport_header(clone, fhoff);
 628        hdr = ipv6_hdr(clone);
 629        fhdr = (struct frag_hdr *)skb_transport_header(clone);
 630
 631        if (!(fhdr->frag_off & htons(0xFFF9))) {
 632                pr_debug("Invalid fragment offset\n");
 633                /* It is not a fragmented frame */
 634                goto ret_orig;
 635        }
 636
 637        if (atomic_read(&nf_init_frags.mem) > nf_init_frags.high_thresh)
 638                nf_ct_frag6_evictor();
 639
 640        fq = fq_find(fhdr->identification, user, &hdr->saddr, &hdr->daddr);
 641        if (fq == NULL) {
 642                pr_debug("Can't find and can't create new queue\n");
 643                goto ret_orig;
 644        }
 645
 646        spin_lock_bh(&fq->q.lock);
 647
 648        if (nf_ct_frag6_queue(fq, clone, fhdr, nhoff) < 0) {
 649                spin_unlock_bh(&fq->q.lock);
 650                pr_debug("Can't insert skb to queue\n");
 651                fq_put(fq);
 652                goto ret_orig;
 653        }
 654
 655        if (fq->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) &&
 656            fq->q.meat == fq->q.len) {
 657                ret_skb = nf_ct_frag6_reasm(fq, dev);
 658                if (ret_skb == NULL)
 659                        pr_debug("Can't reassemble fragmented packets\n");
 660        }
 661        spin_unlock_bh(&fq->q.lock);
 662
 663        fq_put(fq);
 664        return ret_skb;
 665
 666ret_orig:
 667        kfree_skb(clone);
 668        return skb;
 669}
 670
 671void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
 672                        struct net_device *in, struct net_device *out,
 673                        int (*okfn)(struct sk_buff *))
 674{
 675        struct sk_buff *s, *s2;
 676
 677        for (s = NFCT_FRAG6_CB(skb)->orig; s;) {
 678                nf_conntrack_put_reasm(s->nfct_reasm);
 679                nf_conntrack_get_reasm(skb);
 680                s->nfct_reasm = skb;
 681
 682                s2 = s->next;
 683                s->next = NULL;
 684
 685                NF_HOOK_THRESH(PF_INET6, hooknum, s, in, out, okfn,
 686                               NF_IP6_PRI_CONNTRACK_DEFRAG + 1);
 687                s = s2;
 688        }
 689        nf_conntrack_put_reasm(skb);
 690}
 691
 692int nf_ct_frag6_init(void)
 693{
 694        nf_frags.hashfn = nf_hashfn;
 695        nf_frags.constructor = ip6_frag_init;
 696        nf_frags.destructor = NULL;
 697        nf_frags.skb_free = nf_skb_free;
 698        nf_frags.qsize = sizeof(struct nf_ct_frag6_queue);
 699        nf_frags.match = ip6_frag_match;
 700        nf_frags.frag_expire = nf_ct_frag6_expire;
 701        nf_frags.secret_interval = 10 * 60 * HZ;
 702        nf_init_frags.timeout = IPV6_FRAG_TIMEOUT;
 703        nf_init_frags.high_thresh = 256 * 1024;
 704        nf_init_frags.low_thresh = 192 * 1024;
 705        inet_frags_init_net(&nf_init_frags);
 706        inet_frags_init(&nf_frags);
 707
 708        return 0;
 709}
 710
 711void nf_ct_frag6_cleanup(void)
 712{
 713        inet_frags_fini(&nf_frags);
 714
 715        nf_init_frags.low_thresh = 0;
 716        nf_ct_frag6_evictor();
 717}
 718