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

Commit 7c622345 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso
Browse files

netfilter: nfnetlink_queue: fix compilation with NF_CONNTRACK disabled



In "9cb01766 netfilter: add glue code to integrate nfnetlink_queue and ctnetlink"
the compilation with NF_CONNTRACK disabled is broken. This patch fixes this
issue.

I have moved the conntrack part into nfnetlink_queue_ct.c to avoid
peppering the entire nfnetlink_queue.c code with ifdefs.

I also needed to rename nfnetlink_queue.c to nfnetlink_queue_pkt.c
to update the net/netfilter/Makefile to support conditional compilation
of the conntrack integration.

This patch also adds CONFIG_NETFILTER_QUEUE_CT in case you want to explicitly
disable the integration between nf_conntrack and nfnetlink_queue.

Reported-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 6e9c2db3
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
#ifndef _NET_NFNL_QUEUE_H_
#define _NET_NFNL_QUEUE_H_

#include <linux/netfilter/nf_conntrack_common.h>

struct nf_conn;

#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
struct nf_conn *nfqnl_ct_get(struct sk_buff *entskb, size_t *size,
			     enum ip_conntrack_info *ctinfo);
struct nf_conn *nfqnl_ct_parse(const struct sk_buff *skb,
			       const struct nlattr *attr,
			       enum ip_conntrack_info *ctinfo);
int nfqnl_ct_put(struct sk_buff *skb, struct nf_conn *ct,
		 enum ip_conntrack_info ctinfo);
void nfqnl_ct_seq_adjust(struct sk_buff *skb, struct nf_conn *ct,
			 enum ip_conntrack_info ctinfo, int diff);
#else
inline struct nf_conn *
nfqnl_ct_get(struct sk_buff *entskb, size_t *size, enum ip_conntrack_info *ctinfo)
{
	return NULL;
}

inline struct nf_conn *nfqnl_ct_parse(const struct sk_buff *skb,
				      const struct nlattr *attr,
				      enum ip_conntrack_info *ctinfo)
{
	return NULL;
}

inline int
nfqnl_ct_put(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info ctinfo)
{
	return 0;
}

inline void nfqnl_ct_seq_adjust(struct sk_buff *skb, struct nf_conn *ct,
				enum ip_conntrack_info ctinfo, int diff)
{
}
#endif /* NF_CONNTRACK */
#endif
+9 −0
Original line number Diff line number Diff line
@@ -340,6 +340,7 @@ config NF_CT_NETLINK_HELPER
	select NETFILTER_NETLINK
	depends on NF_CT_NETLINK
	depends on NETFILTER_NETLINK_QUEUE
	depends on NETFILTER_NETLINK_QUEUE_CT
	depends on NETFILTER_ADVANCED
	help
	  This option enables the user-space connection tracking helpers
@@ -347,6 +348,14 @@ config NF_CT_NETLINK_HELPER

	  If unsure, say `N'.

config NETFILTER_NETLINK_QUEUE_CT
        bool "NFQUEUE integration with Connection Tracking"
        default n
        depends on NETFILTER_NETLINK_QUEUE
	help
	  If this option is enabled, NFQUEUE can include Connection Tracking
	  information together with the packet is the enqueued via NFNETLINK.

endif # NF_CONNTRACK

# transparent proxy support
+2 −0
Original line number Diff line number Diff line
@@ -9,6 +9,8 @@ obj-$(CONFIG_NETFILTER) = netfilter.o

obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o
obj-$(CONFIG_NETFILTER_NETLINK_ACCT) += nfnetlink_acct.o
nfnetlink_queue-y := nfnetlink_queue_core.o
nfnetlink_queue-$(CONFIG_NETFILTER_NETLINK_QUEUE_CT) += nfnetlink_queue_ct.o
obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o
obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o

+4 −7
Original line number Diff line number Diff line
@@ -1627,8 +1627,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
	return err;
}

#if defined(CONFIG_NETFILTER_NETLINK_QUEUE) ||	\
    defined(CONFIG_NETFILTER_NETLINK_QUEUE_MODULE)
#ifdef CONFIG_NETFILTER_NETLINK_QUEUE_CT
static size_t
ctnetlink_nfqueue_build_size(const struct nf_conn *ct)
{
@@ -1762,7 +1761,7 @@ static struct nfq_ct_hook ctnetlink_nfqueue_hook = {
	.seq_adjust	= nf_nat_tcp_seq_adjust,
#endif
};
#endif /* CONFIG_NETFILTER_NETLINK_QUEUE */
#endif /* CONFIG_NETFILTER_NETLINK_QUEUE_CT */

/***********************************************************************
 * EXPECT
@@ -2568,8 +2567,7 @@ static int __init ctnetlink_init(void)
		pr_err("ctnetlink_init: cannot register pernet operations\n");
		goto err_unreg_exp_subsys;
	}
#if defined(CONFIG_NETFILTER_NETLINK_QUEUE) ||	\
    defined(CONFIG_NETFILTER_NETLINK_QUEUE_MODULE)
#ifdef CONFIG_NETFILTER_NETLINK_QUEUE_CT
	/* setup interaction between nf_queue and nf_conntrack_netlink. */
	RCU_INIT_POINTER(nfq_ct_hook, &ctnetlink_nfqueue_hook);
#endif
@@ -2590,8 +2588,7 @@ static void __exit ctnetlink_exit(void)
	unregister_pernet_subsys(&ctnetlink_net_ops);
	nfnetlink_subsys_unregister(&ctnl_exp_subsys);
	nfnetlink_subsys_unregister(&ctnl_subsys);
#if defined(CONFIG_NETFILTER_NETLINK_QUEUE) ||	\
    defined(CONFIG_NETFILTER_NETLINK_QUEUE_MODULE)
#ifdef CONFIG_NETFILTER_NETLINK_QUEUE_CT
	RCU_INIT_POINTER(nfq_ct_hook, NULL);
#endif
}
+9 −40
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@
#include <linux/list.h>
#include <net/sock.h>
#include <net/netfilter/nf_queue.h>
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nfnetlink_queue.h>

#include <linux/atomic.h>

@@ -234,7 +234,6 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
	struct sk_buff *entskb = entry->skb;
	struct net_device *indev;
	struct net_device *outdev;
	struct nfq_ct_hook *nfq_ct;
	struct nf_conn *ct = NULL;
	enum ip_conntrack_info uninitialized_var(ctinfo);

@@ -270,17 +269,8 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
		break;
	}

	/* rcu_read_lock()ed by __nf_queue already. */
	nfq_ct = rcu_dereference(nfq_ct_hook);
	if (nfq_ct != NULL && (queue->flags & NFQA_CFG_F_CONNTRACK)) {
		ct = nf_ct_get(entskb, &ctinfo);
		if (ct) {
			if (!nf_ct_is_untracked(ct))
				size += nfq_ct->build_size(ct);
			else
				ct = NULL;
		}
	}
	if (queue->flags & NFQA_CFG_F_CONNTRACK)
		ct = nfqnl_ct_get(entskb, &size, &ctinfo);

	skb = alloc_skb(size, GFP_ATOMIC);
	if (!skb)
@@ -404,24 +394,9 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
			BUG();
	}

	if (ct) {
		struct nlattr *nest_parms;
		u_int32_t tmp;

		nest_parms = nla_nest_start(skb, NFQA_CT | NLA_F_NESTED);
		if (!nest_parms)
			goto nla_put_failure;

		if (nfq_ct->build(skb, ct) < 0)
	if (ct && nfqnl_ct_put(skb, ct, ctinfo) < 0)
		goto nla_put_failure;

		nla_nest_end(skb, nest_parms);

		tmp = ctinfo;
		if (nla_put_u32(skb, NFQA_CT_INFO, htonl(ctinfo)))
			goto nla_put_failure;
	}

	nlh->nlmsg_len = skb->tail - old_tail;
	return skb;

@@ -764,7 +739,6 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
	struct nfqnl_instance *queue;
	unsigned int verdict;
	struct nf_queue_entry *entry;
	struct nfq_ct_hook *nfq_ct;
	enum ip_conntrack_info uninitialized_var(ctinfo);
	struct nf_conn *ct = NULL;

@@ -786,13 +760,8 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
		return -ENOENT;

	rcu_read_lock();
	nfq_ct = rcu_dereference(nfq_ct_hook);
	if (nfq_ct != NULL &&
	    (queue->flags & NFQA_CFG_F_CONNTRACK) && nfqa[NFQA_CT]) {
		ct = nf_ct_get(entry->skb, &ctinfo);
		if (ct && !nf_ct_is_untracked(ct))
			nfq_ct->parse(nfqa[NFQA_CT], ct);
	}
	if (nfqa[NFQA_CT] && (queue->flags & NFQA_CFG_F_CONNTRACK))
		ct = nfqnl_ct_parse(entry->skb, nfqa[NFQA_CT], &ctinfo);

	if (nfqa[NFQA_PAYLOAD]) {
		u16 payload_len = nla_len(nfqa[NFQA_PAYLOAD]);
@@ -802,8 +771,8 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
				 payload_len, entry, diff) < 0)
			verdict = NF_DROP;

		if (ct && (ct->status & IPS_NAT_MASK) && diff)
			nfq_ct->seq_adjust(skb, ct, ctinfo, diff);
		if (ct)
			nfqnl_ct_seq_adjust(skb, ct, ctinfo, diff);
	}
	rcu_read_unlock();

Loading