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

Commit b7bd1809 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso
Browse files

netfilter: nfnetlink_queue: get rid of nfnetlink_queue_ct.c



The original intention was to avoid dependencies between nfnetlink_queue and
conntrack without ifdef pollution. However, we can achieve this by moving the
conntrack dependent code into ctnetlink and keep some glue code to access the
nfq_ct indirection from nfqueue.

After this patch, the nfq_ct indirection is always compiled in the netfilter
core to avoid polluting nfqueue with ifdefs. Thus, if nf_conntrack is not
compiled this results in only 8-bytes of memory waste in x86_64.

This patch also adds ctnetlink_nfqueue_seqadj() to avoid that the nf_conn
structure layout if exposed to nf_queue, which creates another dependency with
nf_conntrack at compilation time.

Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent e96f78ab
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -369,14 +369,21 @@ nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family)
extern void (*ip_ct_attach)(struct sk_buff *, const struct sk_buff *) __rcu;
void nf_ct_attach(struct sk_buff *, const struct sk_buff *);
extern void (*nf_ct_destroy)(struct nf_conntrack *) __rcu;
#else
static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {}
#endif

struct nf_conn;
enum ip_conntrack_info;
struct nlattr;

struct nfq_ct_hook {
	struct nf_conn *(*get_ct)(struct sk_buff *skb,
				  enum ip_conntrack_info *ctinfo);
	size_t (*build_size)(const struct nf_conn *ct);
	int (*build)(struct sk_buff *skb, struct nf_conn *ct);
	int (*build)(struct sk_buff *skb, struct nf_conn *ct,
		     enum ip_conntrack_info ctinfo,
		     u_int16_t ct_attr, u_int16_t ct_info_attr);
	int (*parse)(const struct nlattr *attr, struct nf_conn *ct);
	int (*attach_expect)(const struct nlattr *attr, struct nf_conn *ct,
			     u32 portid, u32 report);
@@ -384,9 +391,6 @@ struct nfq_ct_hook {
			   enum ip_conntrack_info ctinfo, s32 off);
};
extern struct nfq_ct_hook __rcu *nfq_ct_hook;
#else
static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {}
#endif

/**
 * nf_skb_duplicated - TEE target has sent a packet
+0 −51
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;

#ifdef CONFIG_NETFILTER_NETLINK_QUEUE_CT
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);
int nfqnl_attach_expect(struct nf_conn *ct, const struct nlattr *attr,
			u32 portid, u32 report);
#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)
{
}

inline int nfqnl_attach_expect(struct nf_conn *ct, const struct nlattr *attr,
			       u32 portid, u32 report)
{
	return 0;
}
#endif /* NF_CONNTRACK */
#endif
+0 −1
Original line number Diff line number Diff line
@@ -11,7 +11,6 @@ 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

+6 −3
Original line number Diff line number Diff line
@@ -348,6 +348,12 @@ int skb_make_writable(struct sk_buff *skb, unsigned int writable_len)
}
EXPORT_SYMBOL(skb_make_writable);

/* This needs to be compiled in any case to avoid dependencies between the
 * nfnetlink_queue code and nf_conntrack.
 */
struct nfq_ct_hook __rcu *nfq_ct_hook __read_mostly;
EXPORT_SYMBOL_GPL(nfq_ct_hook);

#if IS_ENABLED(CONFIG_NF_CONNTRACK)
/* This does not belong here, but locally generated errors need it if connection
   tracking in use: without this, connection may not be in hash table, and hence
@@ -385,9 +391,6 @@ void nf_conntrack_destroy(struct nf_conntrack *nfct)
}
EXPORT_SYMBOL(nf_conntrack_destroy);

struct nfq_ct_hook __rcu *nfq_ct_hook __read_mostly;
EXPORT_SYMBOL_GPL(nfq_ct_hook);

/* Built-in default zone used e.g. by modules. */
const struct nf_conntrack_zone nf_ct_zone_dflt = {
	.id	= NF_CT_DEFAULT_ZONE_ID,
+49 −3
Original line number Diff line number Diff line
@@ -2162,8 +2162,19 @@ ctnetlink_nfqueue_build_size(const struct nf_conn *ct)
	       ;
}

static int
ctnetlink_nfqueue_build(struct sk_buff *skb, struct nf_conn *ct)
static struct nf_conn *ctnetlink_nfqueue_get_ct(struct sk_buff *skb,
						enum ip_conntrack_info *ctinfo)
{
	struct nf_conn *ct;

	ct = nf_ct_get(skb, ctinfo);
	if (ct && nf_ct_is_untracked(ct))
		ct = NULL;

	return ct;
}

static int __ctnetlink_nfqueue_build(struct sk_buff *skb, struct nf_conn *ct)
{
	const struct nf_conntrack_zone *zone;
	struct nlattr *nest_parms;
@@ -2235,6 +2246,31 @@ ctnetlink_nfqueue_build(struct sk_buff *skb, struct nf_conn *ct)
	return -ENOSPC;
}

static int
ctnetlink_nfqueue_build(struct sk_buff *skb, struct nf_conn *ct,
			enum ip_conntrack_info ctinfo,
			u_int16_t ct_attr, u_int16_t ct_info_attr)
{
	struct nlattr *nest_parms;

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

	if (__ctnetlink_nfqueue_build(skb, ct) < 0)
		goto nla_put_failure;

	nla_nest_end(skb, nest_parms);

	if (nla_put_be32(skb, ct_info_attr, htonl(ctinfo)))
		goto nla_put_failure;

	return 0;

nla_put_failure:
	return -ENOSPC;
}

static int
ctnetlink_nfqueue_parse_ct(const struct nlattr *cda[], struct nf_conn *ct)
{
@@ -2350,12 +2386,22 @@ ctnetlink_nfqueue_attach_expect(const struct nlattr *attr, struct nf_conn *ct,
	return 0;
}

static void ctnetlink_nfqueue_seqadj(struct sk_buff *skb, struct nf_conn *ct,
				     enum ip_conntrack_info ctinfo, int diff)
{
	if (!(ct->status & IPS_NAT_MASK))
		return;

	nf_ct_tcp_seqadj_set(skb, ct, ctinfo, diff);
}

static struct nfq_ct_hook ctnetlink_nfqueue_hook = {
	.get_ct		= ctnetlink_nfqueue_get_ct,
	.build_size	= ctnetlink_nfqueue_build_size,
	.build		= ctnetlink_nfqueue_build,
	.parse		= ctnetlink_nfqueue_parse,
	.attach_expect	= ctnetlink_nfqueue_attach_expect,
	.seq_adjust	= nf_ct_tcp_seqadj_set,
	.seq_adjust	= ctnetlink_nfqueue_seqadj,
};
#endif /* CONFIG_NETFILTER_NETLINK_QUEUE_CT */

Loading