|
@@ -133,6 +133,7 @@ instance_put(struct nfulnl_instance *inst)
|
|
|
if (inst && atomic_dec_and_test(&inst->use)) {
|
|
|
UDEBUG("kfree(inst=%p)\n", inst);
|
|
|
kfree(inst);
|
|
|
+ module_put(THIS_MODULE);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -217,6 +218,9 @@ _instance_destroy2(struct nfulnl_instance *inst, int lock)
|
|
|
|
|
|
spin_lock_bh(&inst->lock);
|
|
|
if (inst->skb) {
|
|
|
+ /* timer "holds" one reference (we have one more) */
|
|
|
+ if (del_timer(&inst->timer))
|
|
|
+ instance_put(inst);
|
|
|
if (inst->qlen)
|
|
|
__nfulnl_send(inst);
|
|
|
if (inst->skb) {
|
|
@@ -228,8 +232,6 @@ _instance_destroy2(struct nfulnl_instance *inst, int lock)
|
|
|
|
|
|
/* and finally put the refcount */
|
|
|
instance_put(inst);
|
|
|
-
|
|
|
- module_put(THIS_MODULE);
|
|
|
}
|
|
|
|
|
|
static inline void
|
|
@@ -363,9 +365,6 @@ __nfulnl_send(struct nfulnl_instance *inst)
|
|
|
{
|
|
|
int status;
|
|
|
|
|
|
- if (timer_pending(&inst->timer))
|
|
|
- del_timer(&inst->timer);
|
|
|
-
|
|
|
if (!inst->skb)
|
|
|
return 0;
|
|
|
|
|
@@ -393,8 +392,8 @@ static void nfulnl_timer(unsigned long data)
|
|
|
|
|
|
spin_lock_bh(&inst->lock);
|
|
|
__nfulnl_send(inst);
|
|
|
- instance_put(inst);
|
|
|
spin_unlock_bh(&inst->lock);
|
|
|
+ instance_put(inst);
|
|
|
}
|
|
|
|
|
|
/* This is an inline function, we don't really care about a long
|
|
@@ -560,6 +559,7 @@ __build_packet_message(struct nfulnl_instance *inst,
|
|
|
}
|
|
|
|
|
|
nlh->nlmsg_len = inst->skb->tail - old_tail;
|
|
|
+ inst->lastnlh = nlh;
|
|
|
return 0;
|
|
|
|
|
|
nlmsg_failure:
|
|
@@ -689,6 +689,9 @@ nfulnl_log_packet(unsigned int pf,
|
|
|
* enough room in the skb left. flush to userspace. */
|
|
|
UDEBUG("flushing old skb\n");
|
|
|
|
|
|
+ /* timer "holds" one reference (we have another one) */
|
|
|
+ if (del_timer(&inst->timer))
|
|
|
+ instance_put(inst);
|
|
|
__nfulnl_send(inst);
|
|
|
|
|
|
if (!(inst->skb = nfulnl_alloc_skb(nlbufsiz, size))) {
|
|
@@ -711,15 +714,16 @@ nfulnl_log_packet(unsigned int pf,
|
|
|
inst->timer.expires = jiffies + (inst->flushtimeout*HZ/100);
|
|
|
add_timer(&inst->timer);
|
|
|
}
|
|
|
- spin_unlock_bh(&inst->lock);
|
|
|
|
|
|
+unlock_and_release:
|
|
|
+ spin_unlock_bh(&inst->lock);
|
|
|
+ instance_put(inst);
|
|
|
return;
|
|
|
|
|
|
alloc_failure:
|
|
|
- spin_unlock_bh(&inst->lock);
|
|
|
- instance_put(inst);
|
|
|
UDEBUG("error allocating skb\n");
|
|
|
/* FIXME: statistics */
|
|
|
+ goto unlock_and_release;
|
|
|
}
|
|
|
|
|
|
static int
|
|
@@ -856,6 +860,9 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
|
|
|
ret = -EINVAL;
|
|
|
break;
|
|
|
}
|
|
|
+
|
|
|
+ if (!inst)
|
|
|
+ goto out;
|
|
|
} else {
|
|
|
if (!inst) {
|
|
|
UDEBUG("no config command, and no instance for "
|
|
@@ -909,6 +916,7 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
|
|
|
|
|
|
out_put:
|
|
|
instance_put(inst);
|
|
|
+out:
|
|
|
return ret;
|
|
|
}
|
|
|
|