@@ -20,7 +20,8 @@ struct nf_queue_entry {
/* Packet queuing */
struct nf_queue_handler {
int (*outfn)(struct nf_queue_entry *entry,
- unsigned int queuenum);
+ unsigned int queuenum,
+ int failopen);
char *name;
};
@@ -225,7 +225,8 @@ nlmsg_failure:
}
static int
-ipq_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
+ipq_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum,
+ int failopen)
{
int status = -EINVAL;
struct sk_buff *nskb;
@@ -262,7 +263,7 @@ ipq_enqueue_packet(struct nf_queue_entry
__ipq_enqueue_entry(entry);
spin_unlock_bh(&queue_lock);
- return status;
+ return 0;
err_out_free_nskb:
kfree_skb(nskb);
@@ -225,7 +225,8 @@ nlmsg_failure:
}
static int
-ipq_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
+ipq_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum,
+ int failopen)
{
int status = -EINVAL;
struct sk_buff *nskb;
@@ -262,7 +263,7 @@ ipq_enqueue_packet(struct nf_queue_entry
__ipq_enqueue_entry(entry);
spin_unlock_bh(&queue_lock);
- return status;
+ return 0;
err_out_free_nskb:
kfree_skb(nskb);
@@ -401,7 +401,8 @@ nla_put_failure:
}
static int
-nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum)
+nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum,
+ int failopen)
{
struct sk_buff *nskb;
struct nfqnl_instance *queue;
@@ -432,11 +433,16 @@ nfqnl_enqueue_packet(struct nf_queue_ent
goto err_out_free_nskb;
}
if (queue->queue_total >= queue->queue_maxlen) {
- queue->queue_dropped++;
- if (net_ratelimit())
- printk(KERN_WARNING "nf_queue: full at %d entries, "
- "dropping packets(s).\n",
- queue->queue_total);
+ if (failopen) {
+ /* Accept the packet temporarily skipping rules */
+ err = 1;
+ } else {
+ queue->queue_dropped++;
+ if (net_ratelimit())
+ printk(KERN_WARNING "nf_queue: full at %d "
+ "entries, dropping packets(s).\n",
+ queue->queue_total);
+ }
goto err_out_free_nskb;
}
entry->id = ++queue->id_sequence;
@@ -185,7 +185,7 @@ static int __nf_queue(struct sk_buff *sk
#endif
skb_dst_force(skb);
afinfo->saveroute(skb, entry);
- status = qh->outfn(entry, queuenum);
+ status = qh->outfn(entry, queuenum, 0);
rcu_read_unlock();