]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/netfilter/nfnetlink_log.c
[NETFILTER]: nfnetlink_log: flush queue early
[linux-2.6-omap-h63xx.git] / net / netfilter / nfnetlink_log.c
index a90a26bd618b6c714f41de41e438a6194b423409..0fa17421bbc6b5c65d462868664900b74c9fc9e9 100644 (file)
@@ -188,7 +188,7 @@ out_unlock:
        return NULL;
 }
 
-static int __nfulnl_send(struct nfulnl_instance *inst);
+static void __nfulnl_flush(struct nfulnl_instance *inst);
 
 static void
 __instance_destroy(struct nfulnl_instance *inst)
@@ -202,17 +202,8 @@ __instance_destroy(struct nfulnl_instance *inst)
        /* then flush all pending packets from skb */
 
        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) {
-                       kfree_skb(inst->skb);
-                       inst->skb = NULL;
-               }
-       }
+       if (inst->skb)
+               __nfulnl_flush(inst);
        spin_unlock_bh(&inst->lock);
 
        /* and finally put the refcount */
@@ -364,6 +355,16 @@ nlmsg_failure:
        return status;
 }
 
+static void
+__nfulnl_flush(struct nfulnl_instance *inst)
+{
+       /* timer holds a reference */
+       if (del_timer(&inst->timer))
+               instance_put(inst);
+       if (inst->skb)
+               __nfulnl_send(inst);
+}
+
 static void nfulnl_timer(unsigned long data)
 {
        struct nfulnl_instance *inst = (struct nfulnl_instance *)data;
@@ -643,17 +644,13 @@ nfulnl_log_packet(unsigned int pf,
                goto unlock_and_release;
        }
 
-       if (inst->qlen >= qthreshold ||
-           (inst->skb && size >
-            skb_tailroom(inst->skb) - sizeof(struct nfgenmsg))) {
+       if (inst->skb &&
+           size > skb_tailroom(inst->skb) - sizeof(struct nfgenmsg)) {
                /* either the queue len is too high or we don't have
                 * 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);
+               __nfulnl_flush(inst);
        }
 
        if (!inst->skb) {
@@ -668,9 +665,11 @@ nfulnl_log_packet(unsigned int pf,
        __build_packet_message(inst, skb, data_len, pf,
                                hooknum, in, out, li, prefix, plen);
 
+       if (inst->qlen >= qthreshold)
+               __nfulnl_flush(inst);
        /* timer_pending always called within inst->lock, so there
         * is no chance of a race here */
-       if (!timer_pending(&inst->timer)) {
+       else if (!timer_pending(&inst->timer)) {
                instance_get(inst);
                inst->timer.expires = jiffies + (inst->flushtimeout*HZ/100);
                add_timer(&inst->timer);