]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/ipv6/netfilter/nf_conntrack_reasm.c
netfilter: ipv6: fix overlap check for fragments
[net-next-2.6.git] / net / ipv6 / netfilter / nf_conntrack_reasm.c
index 578f3c1a16db614614f986947cbae5a7960fcdb5..79d43aa8fa8da80b405689bf7c751d7a9cc89ad4 100644 (file)
@@ -73,7 +73,7 @@ static struct inet_frags nf_frags;
 static struct netns_frags nf_init_frags;
 
 #ifdef CONFIG_SYSCTL
-struct ctl_table nf_ct_ipv6_sysctl_table[] = {
+struct ctl_table nf_ct_frag6_sysctl_table[] = {
        {
                .procname       = "nf_conntrack_frag6_timeout",
                .data           = &nf_init_frags.timeout,
@@ -97,6 +97,8 @@ struct ctl_table nf_ct_ipv6_sysctl_table[] = {
        },
        { }
 };
+
+static struct ctl_table_header *nf_ct_frag6_sysctl_header;
 #endif
 
 static unsigned int nf_hashfn(struct inet_frag_queue *q)
@@ -284,7 +286,7 @@ found:
 
        /* Check for overlap with preceding fragment. */
        if (prev &&
-           (NFCT_FRAG6_CB(prev)->offset + prev->len) - offset > 0)
+           (NFCT_FRAG6_CB(prev)->offset + prev->len) > offset)
                goto discard_fq;
 
        /* Look for overlap with succeeding segment. */
@@ -363,7 +365,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
        /* If the first fragment is fragmented itself, we split
         * it to two chunks: the first with data and paged part
         * and the second, holding only fragments. */
-       if (skb_has_frags(head)) {
+       if (skb_has_frag_list(head)) {
                struct sk_buff *clone;
                int i, plen = 0;
 
@@ -623,11 +625,24 @@ int nf_ct_frag6_init(void)
        inet_frags_init_net(&nf_init_frags);
        inet_frags_init(&nf_frags);
 
+#ifdef CONFIG_SYSCTL
+       nf_ct_frag6_sysctl_header = register_sysctl_paths(nf_net_netfilter_sysctl_path,
+                                                         nf_ct_frag6_sysctl_table);
+       if (!nf_ct_frag6_sysctl_header) {
+               inet_frags_fini(&nf_frags);
+               return -ENOMEM;
+       }
+#endif
+
        return 0;
 }
 
 void nf_ct_frag6_cleanup(void)
 {
+#ifdef CONFIG_SYSCTL
+       unregister_sysctl_table(nf_ct_frag6_sysctl_header);
+       nf_ct_frag6_sysctl_header = NULL;
+#endif
        inet_frags_fini(&nf_frags);
 
        nf_init_frags.low_thresh = 0;