[NETNS][IPV6]: inet6_addr - make ipv6_chk_home_addr namespace aware
[powerpc.git] / net / ipv6 / reassembly.c
index ce87340..5cd0bc6 100644 (file)
@@ -82,13 +82,6 @@ struct frag_queue
        __u16                   nhoffset;
 };
 
-struct inet_frags_ctl ip6_frags_ctl __read_mostly = {
-       .high_thresh     = 256 * 1024,
-       .low_thresh      = 192 * 1024,
-       .timeout         = IPV6_FRAG_TIMEOUT,
-       .secret_interval = 10 * 60 * HZ,
-};
-
 static struct inet_frags ip6_frags;
 
 int ip6_frag_nqueues(void)
@@ -143,17 +136,17 @@ static unsigned int ip6_hashfn(struct inet_frag_queue *q)
        return ip6qhashfn(fq->id, &fq->saddr, &fq->daddr);
 }
 
-int ip6_frag_equal(struct inet_frag_queue *q1, struct inet_frag_queue *q2)
+int ip6_frag_match(struct inet_frag_queue *q, void *a)
 {
-       struct frag_queue *fq1, *fq2;
+       struct frag_queue *fq;
+       struct ip6_create_arg *arg = a;
 
-       fq1 = container_of(q1, struct frag_queue, q);
-       fq2 = container_of(q2, struct frag_queue, q);
-       return (fq1->id == fq2->id &&
-                       ipv6_addr_equal(&fq2->saddr, &fq1->saddr) &&
-                       ipv6_addr_equal(&fq2->daddr, &fq1->daddr));
+       fq = container_of(q, struct frag_queue, q);
+       return (fq->id == arg->id &&
+                       ipv6_addr_equal(&fq->saddr, arg->src) &&
+                       ipv6_addr_equal(&fq->daddr, arg->dst));
 }
-EXPORT_SYMBOL(ip6_frag_equal);
+EXPORT_SYMBOL(ip6_frag_match);
 
 /* Memory Tracking Functions. */
 static inline void frag_kfree_skb(struct sk_buff *skb, int *work)
@@ -175,11 +168,6 @@ void ip6_frag_init(struct inet_frag_queue *q, void *a)
 }
 EXPORT_SYMBOL(ip6_frag_init);
 
-static void ip6_frag_free(struct inet_frag_queue *fq)
-{
-       kfree(container_of(fq, struct frag_queue, q));
-}
-
 /* Destruction primitives. */
 
 static __inline__ void fq_put(struct frag_queue *fq)
@@ -245,20 +233,20 @@ out:
        fq_put(fq);
 }
 
-/* Creation primitives. */
-
-static struct frag_queue *
-ip6_frag_create(__be32 id, struct in6_addr *src, struct in6_addr *dst,
-               struct inet6_dev *idev, unsigned int hash)
+static __inline__ struct frag_queue *
+fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst,
+       struct inet6_dev *idev)
 {
        struct inet_frag_queue *q;
        struct ip6_create_arg arg;
+       unsigned int hash;
 
        arg.id = id;
        arg.src = src;
        arg.dst = dst;
+       hash = ip6qhashfn(id, src, dst);
 
-       q = inet_frag_create(&ip6_frags, &arg, hash);
+       q = inet_frag_find(&ip6_frags, &arg, hash);
        if (q == NULL)
                goto oom;
 
@@ -269,31 +257,6 @@ oom:
        return NULL;
 }
 
-static __inline__ struct frag_queue *
-fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst,
-       struct inet6_dev *idev)
-{
-       struct frag_queue *fq;
-       struct hlist_node *n;
-       unsigned int hash;
-
-       read_lock(&ip6_frags.lock);
-       hash = ip6qhashfn(id, src, dst);
-       hlist_for_each_entry(fq, n, &ip6_frags.hash[hash], q.list) {
-               if (fq->id == id &&
-                   ipv6_addr_equal(src, &fq->saddr) &&
-                   ipv6_addr_equal(dst, &fq->daddr)) {
-                       atomic_inc(&fq->q.refcnt);
-                       read_unlock(&ip6_frags.lock);
-                       return fq;
-               }
-       }
-       read_unlock(&ip6_frags.lock);
-
-       return ip6_frag_create(id, src, dst, idev, hash);
-}
-
-
 static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
                           struct frag_hdr *fhdr, int nhoff)
 {
@@ -635,7 +598,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
                return 1;
        }
 
-       if (atomic_read(&ip6_frags.mem) > ip6_frags_ctl.high_thresh)
+       if (atomic_read(&ip6_frags.mem) > init_net.ipv6.sysctl.frags.high_thresh)
                ip6_evictor(ip6_dst_idev(skb->dst));
 
        if ((fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr,
@@ -662,18 +625,33 @@ static struct inet6_protocol frag_protocol =
        .flags          =       INET6_PROTO_NOPOLICY,
 };
 
-void __init ipv6_frag_init(void)
+void ipv6_frag_sysctl_init(struct net *net)
 {
-       if (inet6_add_protocol(&frag_protocol, IPPROTO_FRAGMENT) < 0)
-               printk(KERN_ERR "ipv6_frag_init: Could not register protocol\n");
+       ip6_frags.ctl = &net->ipv6.sysctl.frags;
+}
+
+int __init ipv6_frag_init(void)
+{
+       int ret;
+
+       ret = inet6_add_protocol(&frag_protocol, IPPROTO_FRAGMENT);
+       if (ret)
+               goto out;
 
-       ip6_frags.ctl = &ip6_frags_ctl;
        ip6_frags.hashfn = ip6_hashfn;
        ip6_frags.constructor = ip6_frag_init;
-       ip6_frags.destructor = ip6_frag_free;
+       ip6_frags.destructor = NULL;
        ip6_frags.skb_free = NULL;
        ip6_frags.qsize = sizeof(struct frag_queue);
-       ip6_frags.equal = ip6_frag_equal;
+       ip6_frags.match = ip6_frag_match;
        ip6_frags.frag_expire = ip6_frag_expire;
        inet_frags_init(&ip6_frags);
+out:
+       return ret;
+}
+
+void ipv6_frag_exit(void)
+{
+       inet_frags_fini(&ip6_frags);
+       inet6_del_protocol(&frag_protocol, IPPROTO_FRAGMENT);
 }