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

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

netfilter: conntrack: handle builtin l4proto packet functions via direct calls



The l4 protocol trackers are invoked via indirect call: l4proto->packet().

With one exception (gre), all l4trackers are builtin, so we can make
.packet optional and use a direct call for most protocols.

Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 75dd48e2
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -99,6 +99,43 @@ int nf_conntrack_icmpv6_error(struct nf_conn *tmpl,
			      struct sk_buff *skb,
			      unsigned int dataoff,
			      const struct nf_hook_state *state);

int nf_conntrack_icmp_packet(struct nf_conn *ct,
			     struct sk_buff *skb,
			     enum ip_conntrack_info ctinfo,
			     const struct nf_hook_state *state);

int nf_conntrack_icmpv6_packet(struct nf_conn *ct,
			       struct sk_buff *skb,
			       enum ip_conntrack_info ctinfo,
			       const struct nf_hook_state *state);

int nf_conntrack_udp_packet(struct nf_conn *ct,
			    struct sk_buff *skb,
			    unsigned int dataoff,
			    enum ip_conntrack_info ctinfo,
			    const struct nf_hook_state *state);
int nf_conntrack_udplite_packet(struct nf_conn *ct,
				struct sk_buff *skb,
				unsigned int dataoff,
				enum ip_conntrack_info ctinfo,
				const struct nf_hook_state *state);
int nf_conntrack_tcp_packet(struct nf_conn *ct,
			    struct sk_buff *skb,
			    unsigned int dataoff,
			    enum ip_conntrack_info ctinfo,
			    const struct nf_hook_state *state);
int nf_conntrack_dccp_packet(struct nf_conn *ct,
			     struct sk_buff *skb,
			     unsigned int dataoff,
			     enum ip_conntrack_info ctinfo,
			     const struct nf_hook_state *state);
int nf_conntrack_sctp_packet(struct nf_conn *ct,
			     struct sk_buff *skb,
			     unsigned int dataoff,
			     enum ip_conntrack_info ctinfo,
			     const struct nf_hook_state *state);

/* Existing built-in generic protocol */
extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_generic;

+44 −1
Original line number Diff line number Diff line
@@ -1522,6 +1522,45 @@ nf_conntrack_handle_icmp(struct nf_conn *tmpl,
	return ret;
}

/* Returns verdict for packet, or -1 for invalid. */
static int nf_conntrack_handle_packet(struct nf_conn *ct,
				      struct sk_buff *skb,
				      unsigned int dataoff,
				      enum ip_conntrack_info ctinfo,
				      const struct nf_hook_state *state)
{
	switch (nf_ct_protonum(ct)) {
	case IPPROTO_TCP:
		return nf_conntrack_tcp_packet(ct, skb, dataoff,
					       ctinfo, state);
	case IPPROTO_UDP:
		return nf_conntrack_udp_packet(ct, skb, dataoff,
					       ctinfo, state);
	case IPPROTO_ICMP:
		return nf_conntrack_icmp_packet(ct, skb, ctinfo, state);
	case IPPROTO_ICMPV6:
		return nf_conntrack_icmpv6_packet(ct, skb, ctinfo, state);
#ifdef CONFIG_NF_CT_PROTO_UDPLITE
	case IPPROTO_UDPLITE:
		return nf_conntrack_udplite_packet(ct, skb, dataoff,
						   ctinfo, state);
#endif
#ifdef CONFIG_NF_CT_PROTO_SCTP
	case IPPROTO_SCTP:
		return nf_conntrack_sctp_packet(ct, skb, dataoff,
						ctinfo, state);
#endif
#ifdef CONFIG_NF_CT_PROTO_DCCP
	case IPPROTO_DCCP:
		return nf_conntrack_dccp_packet(ct, skb, dataoff,
						ctinfo, state);
#endif
	}

	WARN_ON_ONCE(1);
	return -NF_ACCEPT;
}

unsigned int
nf_conntrack_in(struct sk_buff *skb, const struct nf_hook_state *state)
{
@@ -1583,7 +1622,11 @@ nf_conntrack_in(struct sk_buff *skb, const struct nf_hook_state *state)
		goto out;
	}

	if (l4proto->packet)
		ret = l4proto->packet(ct, skb, dataoff, ctinfo, state);
	else
		ret = nf_conntrack_handle_packet(ct, skb, dataoff, ctinfo, state);

	if (ret <= 0) {
		/* Invalid: inverse of the return code tells
		 * the netfilter core what to do */
+4 −4
Original line number Diff line number Diff line
@@ -472,8 +472,9 @@ static bool dccp_error(const struct dccp_hdr *dh,
	return true;
}

static int dccp_packet(struct nf_conn *ct, struct sk_buff *skb,
		       unsigned int dataoff, enum ip_conntrack_info ctinfo,
int nf_conntrack_dccp_packet(struct nf_conn *ct, struct sk_buff *skb,
			     unsigned int dataoff,
			     enum ip_conntrack_info ctinfo,
			     const struct nf_hook_state *state)
{
	enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
@@ -839,7 +840,6 @@ static struct nf_proto_net *dccp_get_net_proto(struct net *net)

const struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp = {
	.l4proto		= IPPROTO_DCCP,
	.packet			= dccp_packet,
	.can_early_drop		= dccp_can_early_drop,
#ifdef CONFIG_NF_CONNTRACK_PROCFS
	.print_conntrack	= dccp_print_conntrack,
+4 −8
Original line number Diff line number Diff line
@@ -68,9 +68,8 @@ static bool icmp_invert_tuple(struct nf_conntrack_tuple *tuple,
}

/* Returns verdict for packet, or -1 for invalid. */
static int icmp_packet(struct nf_conn *ct,
int nf_conntrack_icmp_packet(struct nf_conn *ct,
			     struct sk_buff *skb,
		       unsigned int dataoff,
			     enum ip_conntrack_info ctinfo,
			     const struct nf_hook_state *state)
{
@@ -350,9 +349,6 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp =
	.l4proto		= IPPROTO_ICMP,
	.pkt_to_tuple		= icmp_pkt_to_tuple,
	.invert_tuple		= icmp_invert_tuple,
	.packet			= icmp_packet,
	.destroy		= NULL,
	.me			= NULL,
#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
	.tuple_to_nlattr	= icmp_tuple_to_nlattr,
	.nlattr_tuple_size	= icmp_nlattr_tuple_size,
+4 −6
Original line number Diff line number Diff line
@@ -86,9 +86,8 @@ static unsigned int *icmpv6_get_timeouts(struct net *net)
}

/* Returns verdict for packet, or -1 for invalid. */
static int icmpv6_packet(struct nf_conn *ct,
int nf_conntrack_icmpv6_packet(struct nf_conn *ct,
			       struct sk_buff *skb,
		         unsigned int dataoff,
			       enum ip_conntrack_info ctinfo,
			       const struct nf_hook_state *state)
{
@@ -361,7 +360,6 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 =
	.l4proto		= IPPROTO_ICMPV6,
	.pkt_to_tuple		= icmpv6_pkt_to_tuple,
	.invert_tuple		= icmpv6_invert_tuple,
	.packet			= icmpv6_packet,
#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
	.tuple_to_nlattr	= icmpv6_tuple_to_nlattr,
	.nlattr_tuple_size	= icmpv6_nlattr_tuple_size,
Loading