Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4b3d15ef authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller
Browse files

[NETFILTER]: {nfnetlink,ip,ip6}_queue: kill issue_verdict



Now that issue_verdict doesn't need to free the queue entries anymore,
all it does is disable local BHs and call nf_reinject. Move the BH
disabling to the okfn invocation in nf_reinject and kill the
issue_verdict functions.

Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 02f014d8
Loading
Loading
Loading
Loading
+2 −15
Original line number Diff line number Diff line
@@ -49,19 +49,6 @@ static struct sock *ipqnl __read_mostly;
static LIST_HEAD(queue_list);
static DEFINE_MUTEX(ipqnl_mutex);

static void
ipq_issue_verdict(struct nf_queue_entry *entry, int verdict)
{
	/* TCP input path (and probably other bits) assume to be called
	 * from softirq context, not from syscall, like ipq_issue_verdict is
	 * called.  TCP input path deadlocks with locks taken from timer
	 * softirq, e.g.  We therefore emulate this by local_bh_disable() */

	local_bh_disable();
	nf_reinject(entry, verdict);
	local_bh_enable();
}

static inline void
__ipq_enqueue_entry(struct nf_queue_entry *entry)
{
@@ -138,7 +125,7 @@ __ipq_flush(ipq_cmpfn cmpfn, unsigned long data)
		if (!cmpfn || cmpfn(entry, data)) {
			list_del(&entry->list);
			queue_total--;
			ipq_issue_verdict(entry, NF_DROP);
			nf_reinject(entry, NF_DROP);
		}
	}
}
@@ -345,7 +332,7 @@ ipq_set_verdict(struct ipq_verdict_msg *vmsg, unsigned int len)
			if (ipq_mangle_ipv4(vmsg, entry) < 0)
				verdict = NF_DROP;

		ipq_issue_verdict(entry, verdict);
		nf_reinject(entry, verdict);
		return 0;
	}
}
+2 −10
Original line number Diff line number Diff line
@@ -53,14 +53,6 @@ static struct sock *ipqnl __read_mostly;
static LIST_HEAD(queue_list);
static DEFINE_MUTEX(ipqnl_mutex);

static void
ipq_issue_verdict(struct nf_queue_entry *entry, int verdict)
{
	local_bh_disable();
	nf_reinject(entry, verdict);
	local_bh_enable();
}

static inline void
__ipq_enqueue_entry(struct nf_queue_entry *entry)
{
@@ -137,7 +129,7 @@ __ipq_flush(ipq_cmpfn cmpfn, unsigned long data)
		if (!cmpfn || cmpfn(entry, data)) {
			list_del(&entry->list);
			queue_total--;
			ipq_issue_verdict(entry, NF_DROP);
			nf_reinject(entry, NF_DROP);
		}
	}
}
@@ -343,7 +335,7 @@ ipq_set_verdict(struct ipq_verdict_msg *vmsg, unsigned int len)
			if (ipq_mangle_ipv6(vmsg, entry) < 0)
				verdict = NF_DROP;

		ipq_issue_verdict(entry, verdict);
		nf_reinject(entry, verdict);
		return 0;
	}
}
+2 −0
Original line number Diff line number Diff line
@@ -275,7 +275,9 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
	switch (verdict & NF_VERDICT_MASK) {
	case NF_ACCEPT:
	case NF_STOP:
		local_bh_disable();
		entry->okfn(skb);
		local_bh_enable();
	case NF_STOLEN:
		break;
	case NF_QUEUE:
+2 −19
Original line number Diff line number Diff line
@@ -202,23 +202,6 @@ instance_destroy(struct nfqnl_instance *inst)
	_instance_destroy2(inst, 1);
}



static void
issue_verdict(struct nf_queue_entry *entry, int verdict)
{
	QDEBUG("entering for entry %p, verdict %u\n", entry, verdict);

	/* TCP input path (and probably other bits) assume to be called
	 * from softirq context, not from syscall, like issue_verdict is
	 * called.  TCP input path deadlocks with locks taken from timer
	 * softirq, e.g.  We therefore emulate this by local_bh_disable() */

	local_bh_disable();
	nf_reinject(entry, verdict);
	local_bh_enable();
}

static inline void
__enqueue_entry(struct nfqnl_instance *queue, struct nf_queue_entry *entry)
{
@@ -289,7 +272,7 @@ nfqnl_flush(struct nfqnl_instance *queue, nfqnl_cmpfn cmpfn, unsigned long data)
		if (!cmpfn || cmpfn(entry, data)) {
			list_del(&entry->list);
			queue->queue_total--;
			issue_verdict(entry, NF_DROP);
			nf_reinject(entry, NF_DROP);
		}
	}
	spin_unlock_bh(&queue->lock);
@@ -761,7 +744,7 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
		entry->skb->mark = ntohl(*(__be32 *)
					 nla_data(nfqa[NFQA_MARK]));

	issue_verdict(entry, verdict);
	nf_reinject(entry, verdict);
	instance_put(queue);
	return 0;