]> err.no Git - linux-2.6/blobdiff - net/ipv4/inet_fragment.c
[NETFILTER]: Convert old checksum helper names
[linux-2.6] / net / ipv4 / inet_fragment.c
index 15054eb3d4b9626f40552edf5852e40febaa15b4..737910767ff1a3aac8440043bd33d7f6a0c45bee 100644 (file)
@@ -66,9 +66,8 @@ void inet_frags_init(struct inet_frags *f)
        f->nqueues = 0;
        atomic_set(&f->mem, 0);
 
-       init_timer(&f->secret_timer);
-       f->secret_timer.function = inet_frag_secret_rebuild;
-       f->secret_timer.data = (unsigned long)f;
+       setup_timer(&f->secret_timer, inet_frag_secret_rebuild,
+                       (unsigned long)f);
        f->secret_timer.expires = jiffies + f->ctl->secret_interval;
        add_timer(&f->secret_timer);
 }
@@ -136,7 +135,9 @@ void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f,
                *work -= f->qsize;
        atomic_sub(f->qsize, &f->mem);
 
-       f->destructor(q);
+       if (f->destructor)
+               f->destructor(q);
+       kfree(q);
 
 }
 EXPORT_SYMBOL(inet_frag_destroy);
@@ -173,8 +174,8 @@ int inet_frag_evictor(struct inet_frags *f)
 }
 EXPORT_SYMBOL(inet_frag_evictor);
 
-struct inet_frag_queue *inet_frag_intern(struct inet_frag_queue *qp_in,
-               struct inet_frags *f, unsigned int hash)
+static struct inet_frag_queue *inet_frag_intern(struct inet_frag_queue *qp_in,
+               struct inet_frags *f, unsigned int hash, void *arg)
 {
        struct inet_frag_queue *qp;
 #ifdef CONFIG_SMP
@@ -188,7 +189,7 @@ struct inet_frag_queue *inet_frag_intern(struct inet_frag_queue *qp_in,
         * promoted read lock to write lock.
         */
        hlist_for_each_entry(qp, n, &f->hash[hash], list) {
-               if (f->equal(qp, qp_in)) {
+               if (f->match(qp, arg)) {
                        atomic_inc(&qp->refcnt);
                        write_unlock(&f->lock);
                        qp_in->last_in |= COMPLETE;
@@ -208,4 +209,52 @@ struct inet_frag_queue *inet_frag_intern(struct inet_frag_queue *qp_in,
        write_unlock(&f->lock);
        return qp;
 }
-EXPORT_SYMBOL(inet_frag_intern);
+
+static struct inet_frag_queue *inet_frag_alloc(struct inet_frags *f, void *arg)
+{
+       struct inet_frag_queue *q;
+
+       q = kzalloc(f->qsize, GFP_ATOMIC);
+       if (q == NULL)
+               return NULL;
+
+       f->constructor(q, arg);
+       atomic_add(f->qsize, &f->mem);
+       setup_timer(&q->timer, f->frag_expire, (unsigned long)q);
+       spin_lock_init(&q->lock);
+       atomic_set(&q->refcnt, 1);
+
+       return q;
+}
+
+static struct inet_frag_queue *inet_frag_create(struct inet_frags *f,
+               void *arg, unsigned int hash)
+{
+       struct inet_frag_queue *q;
+
+       q = inet_frag_alloc(f, arg);
+       if (q == NULL)
+               return NULL;
+
+       return inet_frag_intern(q, f, hash, arg);
+}
+
+struct inet_frag_queue *inet_frag_find(struct inet_frags *f, void *key,
+               unsigned int hash)
+{
+       struct inet_frag_queue *q;
+       struct hlist_node *n;
+
+       read_lock(&f->lock);
+       hlist_for_each_entry(q, n, &f->hash[hash], list) {
+               if (f->match(q, key)) {
+                       atomic_inc(&q->refcnt);
+                       read_unlock(&f->lock);
+                       return q;
+               }
+       }
+       read_unlock(&f->lock);
+
+       return inet_frag_create(f, key, hash);
+}
+EXPORT_SYMBOL(inet_frag_find);