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

Commit 9976fc6e authored by Florian Westphal's avatar Florian Westphal Committed by Pablo Neira Ayuso
Browse files

netfilter: conntrack: remove the l4proto->new() function



->new() gets invoked after ->error() and before ->packet() if
a conntrack lookup has found no result for the tuple.

We can fold it into ->packet() -- the packet() implementations
can check if the conntrack is confirmed (new) or not
(already in hash).

If its unconfirmed, the conntrack isn't in the hash yet so current
skb created a new conntrack entry.

Only relevant side effect -- if packet() doesn't return NF_ACCEPT
but -NF_ACCEPT (or drop), while the conntrack was just created,
then the newly allocated conntrack is freed right away, rather than not
created in the first place.

Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 93e66024
Loading
Loading
Loading
Loading
+0 −5
Original line number Diff line number Diff line
@@ -48,11 +48,6 @@ struct nf_conntrack_l4proto {
		      enum ip_conntrack_info ctinfo,
		      const struct nf_hook_state *state);

	/* Called when a new connection for this protocol found;
	 * returns TRUE if it's OK.  If so, packet() called next. */
	bool (*new)(struct nf_conn *ct, const struct sk_buff *skb,
		    unsigned int dataoff);

	/* Called when a conntrack entry is destroyed */
	void (*destroy)(struct nf_conn *ct);

+0 −6
Original line number Diff line number Diff line
@@ -1370,12 +1370,6 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,

	timeout_ext = tmpl ? nf_ct_timeout_find(tmpl) : NULL;

	if (!l4proto->new(ct, skb, dataoff)) {
		nf_conntrack_free(ct);
		pr_debug("can't track with proto module\n");
		return NULL;
	}

	if (timeout_ext)
		nf_ct_timeout_ext_add(ct, rcu_dereference(timeout_ext->timeout),
				      GFP_ATOMIC);
+8 −9
Original line number Diff line number Diff line
@@ -389,18 +389,15 @@ static inline struct nf_dccp_net *dccp_pernet(struct net *net)
	return &net->ct.nf_ct_proto.dccp;
}

static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb,
		     unsigned int dataoff)
static noinline bool
dccp_new(struct nf_conn *ct, const struct sk_buff *skb,
	 const struct dccp_hdr *dh)
{
	struct net *net = nf_ct_net(ct);
	struct nf_dccp_net *dn;
	struct dccp_hdr _dh, *dh;
	const char *msg;
	u_int8_t state;

	dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
	BUG_ON(dh == NULL);

	state = dccp_state_table[CT_DCCP_ROLE_CLIENT][dh->dccph_type][CT_DCCP_NONE];
	switch (state) {
	default:
@@ -449,8 +446,12 @@ static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
	unsigned int *timeouts;

	dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
	BUG_ON(dh == NULL);
	if (!dh)
		return NF_DROP;

	type = dh->dccph_type;
	if (!nf_ct_is_confirmed(ct) && !dccp_new(ct, skb, dh))
		return -NF_ACCEPT;

	if (type == DCCP_PKT_RESET &&
	    !test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
@@ -850,7 +851,6 @@ static struct nf_proto_net *dccp_get_net_proto(struct net *net)
const struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp4 = {
	.l3proto		= AF_INET,
	.l4proto		= IPPROTO_DCCP,
	.new			= dccp_new,
	.packet			= dccp_packet,
	.error			= dccp_error,
	.can_early_drop		= dccp_can_early_drop,
@@ -883,7 +883,6 @@ EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_dccp4);
const struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp6 = {
	.l3proto		= AF_INET6,
	.l4proto		= IPPROTO_DCCP,
	.new			= dccp_new,
	.packet			= dccp_packet,
	.error			= dccp_error,
	.can_early_drop		= dccp_can_early_drop,
+6 −14
Original line number Diff line number Diff line
@@ -51,6 +51,12 @@ static int generic_packet(struct nf_conn *ct,
{
	const unsigned int *timeout = nf_ct_timeout_lookup(ct);

	if (!nf_generic_should_process(nf_ct_protonum(ct))) {
		pr_warn_once("conntrack: generic helper won't handle protocol %d. Please consider loading the specific helper module.\n",
			     nf_ct_protonum(ct));
		return -NF_ACCEPT;
	}

	if (!timeout)
		timeout = &generic_pernet(nf_ct_net(ct))->timeout;

@@ -58,19 +64,6 @@ static int generic_packet(struct nf_conn *ct,
	return NF_ACCEPT;
}

/* Called when a new connection for this protocol found. */
static bool generic_new(struct nf_conn *ct, const struct sk_buff *skb,
			unsigned int dataoff)
{
	bool ret;

	ret = nf_generic_should_process(nf_ct_protonum(ct));
	if (!ret)
		pr_warn_once("conntrack: generic helper won't handle protocol %d. Please consider loading the specific helper module.\n",
			     nf_ct_protonum(ct));
	return ret;
}

#ifdef CONFIG_NF_CONNTRACK_TIMEOUT

#include <linux/netfilter/nfnetlink.h>
@@ -164,7 +157,6 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_generic =
	.l4proto		= 255,
	.pkt_to_tuple		= generic_pkt_to_tuple,
	.packet			= generic_packet,
	.new			= generic_new,
#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
	.ctnl_timeout		= {
		.nlattr_to_obj	= generic_timeout_nlattr_to_obj,
+12 −21
Original line number Diff line number Diff line
@@ -238,6 +238,18 @@ static int gre_packet(struct nf_conn *ct,
		      enum ip_conntrack_info ctinfo,
		      const struct nf_hook_state *state)
{
	if (!nf_ct_is_confirmed(ct)) {
		unsigned int *timeouts = nf_ct_timeout_lookup(ct);

		if (!timeouts)
			timeouts = gre_get_timeouts(nf_ct_net(ct));

		/* initialize to sane value.  Ideally a conntrack helper
		 * (e.g. in case of pptp) is increasing them */
		ct->proto.gre.stream_timeout = timeouts[GRE_CT_REPLIED];
		ct->proto.gre.timeout = timeouts[GRE_CT_UNREPLIED];
	}

	/* If we've seen traffic both ways, this is a GRE connection.
	 * Extend timeout. */
	if (ct->status & IPS_SEEN_REPLY) {
@@ -253,26 +265,6 @@ static int gre_packet(struct nf_conn *ct,
	return NF_ACCEPT;
}

/* Called when a new connection for this protocol found. */
static bool gre_new(struct nf_conn *ct, const struct sk_buff *skb,
		    unsigned int dataoff)
{
	unsigned int *timeouts = nf_ct_timeout_lookup(ct);

	if (!timeouts)
		timeouts = gre_get_timeouts(nf_ct_net(ct));

	pr_debug(": ");
	nf_ct_dump_tuple(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);

	/* initialize to sane value.  Ideally a conntrack helper
	 * (e.g. in case of pptp) is increasing them */
	ct->proto.gre.stream_timeout = timeouts[GRE_CT_REPLIED];
	ct->proto.gre.timeout = timeouts[GRE_CT_UNREPLIED];

	return true;
}

/* Called when a conntrack entry has already been removed from the hashes
 * and is about to be deleted from memory */
static void gre_destroy(struct nf_conn *ct)
@@ -359,7 +351,6 @@ static const struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 = {
	.print_conntrack = gre_print_conntrack,
#endif
	.packet		 = gre_packet,
	.new		 = gre_new,
	.destroy	 = gre_destroy,
	.me 		 = THIS_MODULE,
#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
Loading