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

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
...@@ -99,6 +99,43 @@ int nf_conntrack_icmpv6_error(struct nf_conn *tmpl, ...@@ -99,6 +99,43 @@ int nf_conntrack_icmpv6_error(struct nf_conn *tmpl,
struct sk_buff *skb, struct sk_buff *skb,
unsigned int dataoff, unsigned int dataoff,
const struct nf_hook_state *state); 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 */ /* Existing built-in generic protocol */
extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_generic; extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_generic;
......
...@@ -1522,6 +1522,45 @@ nf_conntrack_handle_icmp(struct nf_conn *tmpl, ...@@ -1522,6 +1522,45 @@ nf_conntrack_handle_icmp(struct nf_conn *tmpl,
return ret; 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 unsigned int
nf_conntrack_in(struct sk_buff *skb, const struct nf_hook_state *state) 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) ...@@ -1583,7 +1622,11 @@ nf_conntrack_in(struct sk_buff *skb, const struct nf_hook_state *state)
goto out; goto out;
} }
ret = l4proto->packet(ct, skb, dataoff, ctinfo, state); 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) { if (ret <= 0) {
/* Invalid: inverse of the return code tells /* Invalid: inverse of the return code tells
* the netfilter core what to do */ * the netfilter core what to do */
......
...@@ -472,9 +472,10 @@ static bool dccp_error(const struct dccp_hdr *dh, ...@@ -472,9 +472,10 @@ static bool dccp_error(const struct dccp_hdr *dh,
return true; return true;
} }
static int dccp_packet(struct nf_conn *ct, struct sk_buff *skb, int nf_conntrack_dccp_packet(struct nf_conn *ct, struct sk_buff *skb,
unsigned int dataoff, enum ip_conntrack_info ctinfo, unsigned int dataoff,
const struct nf_hook_state *state) enum ip_conntrack_info ctinfo,
const struct nf_hook_state *state)
{ {
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
struct dccp_hdr _dh, *dh; struct dccp_hdr _dh, *dh;
...@@ -839,7 +840,6 @@ static struct nf_proto_net *dccp_get_net_proto(struct net *net) ...@@ -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 = { const struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp = {
.l4proto = IPPROTO_DCCP, .l4proto = IPPROTO_DCCP,
.packet = dccp_packet,
.can_early_drop = dccp_can_early_drop, .can_early_drop = dccp_can_early_drop,
#ifdef CONFIG_NF_CONNTRACK_PROCFS #ifdef CONFIG_NF_CONNTRACK_PROCFS
.print_conntrack = dccp_print_conntrack, .print_conntrack = dccp_print_conntrack,
......
...@@ -68,11 +68,10 @@ static bool icmp_invert_tuple(struct nf_conntrack_tuple *tuple, ...@@ -68,11 +68,10 @@ static bool icmp_invert_tuple(struct nf_conntrack_tuple *tuple,
} }
/* Returns verdict for packet, or -1 for invalid. */ /* 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, struct sk_buff *skb,
unsigned int dataoff, enum ip_conntrack_info ctinfo,
enum ip_conntrack_info ctinfo, const struct nf_hook_state *state)
const struct nf_hook_state *state)
{ {
/* Do not immediately delete the connection after the first /* Do not immediately delete the connection after the first
successful reply to avoid excessive conntrackd traffic successful reply to avoid excessive conntrackd traffic
...@@ -350,9 +349,6 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp = ...@@ -350,9 +349,6 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp =
.l4proto = IPPROTO_ICMP, .l4proto = IPPROTO_ICMP,
.pkt_to_tuple = icmp_pkt_to_tuple, .pkt_to_tuple = icmp_pkt_to_tuple,
.invert_tuple = icmp_invert_tuple, .invert_tuple = icmp_invert_tuple,
.packet = icmp_packet,
.destroy = NULL,
.me = NULL,
#if IS_ENABLED(CONFIG_NF_CT_NETLINK) #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
.tuple_to_nlattr = icmp_tuple_to_nlattr, .tuple_to_nlattr = icmp_tuple_to_nlattr,
.nlattr_tuple_size = icmp_nlattr_tuple_size, .nlattr_tuple_size = icmp_nlattr_tuple_size,
......
...@@ -86,11 +86,10 @@ static unsigned int *icmpv6_get_timeouts(struct net *net) ...@@ -86,11 +86,10 @@ static unsigned int *icmpv6_get_timeouts(struct net *net)
} }
/* Returns verdict for packet, or -1 for invalid. */ /* 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, struct sk_buff *skb,
unsigned int dataoff, enum ip_conntrack_info ctinfo,
enum ip_conntrack_info ctinfo, const struct nf_hook_state *state)
const struct nf_hook_state *state)
{ {
unsigned int *timeout = nf_ct_timeout_lookup(ct); unsigned int *timeout = nf_ct_timeout_lookup(ct);
static const u8 valid_new[] = { static const u8 valid_new[] = {
...@@ -361,7 +360,6 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 = ...@@ -361,7 +360,6 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 =
.l4proto = IPPROTO_ICMPV6, .l4proto = IPPROTO_ICMPV6,
.pkt_to_tuple = icmpv6_pkt_to_tuple, .pkt_to_tuple = icmpv6_pkt_to_tuple,
.invert_tuple = icmpv6_invert_tuple, .invert_tuple = icmpv6_invert_tuple,
.packet = icmpv6_packet,
#if IS_ENABLED(CONFIG_NF_CT_NETLINK) #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
.tuple_to_nlattr = icmpv6_tuple_to_nlattr, .tuple_to_nlattr = icmpv6_tuple_to_nlattr,
.nlattr_tuple_size = icmpv6_nlattr_tuple_size, .nlattr_tuple_size = icmpv6_nlattr_tuple_size,
......
...@@ -357,11 +357,11 @@ static bool sctp_error(struct sk_buff *skb, ...@@ -357,11 +357,11 @@ static bool sctp_error(struct sk_buff *skb,
} }
/* Returns verdict for packet, or -NF_ACCEPT for invalid. */ /* Returns verdict for packet, or -NF_ACCEPT for invalid. */
static int sctp_packet(struct nf_conn *ct, int nf_conntrack_sctp_packet(struct nf_conn *ct,
struct sk_buff *skb, struct sk_buff *skb,
unsigned int dataoff, unsigned int dataoff,
enum ip_conntrack_info ctinfo, enum ip_conntrack_info ctinfo,
const struct nf_hook_state *state) const struct nf_hook_state *state)
{ {
enum sctp_conntrack new_state, old_state; enum sctp_conntrack new_state, old_state;
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
...@@ -759,9 +759,7 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp = { ...@@ -759,9 +759,7 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp = {
#ifdef CONFIG_NF_CONNTRACK_PROCFS #ifdef CONFIG_NF_CONNTRACK_PROCFS
.print_conntrack = sctp_print_conntrack, .print_conntrack = sctp_print_conntrack,
#endif #endif
.packet = sctp_packet,
.can_early_drop = sctp_can_early_drop, .can_early_drop = sctp_can_early_drop,
.me = THIS_MODULE,
#if IS_ENABLED(CONFIG_NF_CT_NETLINK) #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
.nlattr_size = SCTP_NLATTR_SIZE, .nlattr_size = SCTP_NLATTR_SIZE,
.to_nlattr = sctp_to_nlattr, .to_nlattr = sctp_to_nlattr,
......
...@@ -829,11 +829,11 @@ static noinline bool tcp_new(struct nf_conn *ct, const struct sk_buff *skb, ...@@ -829,11 +829,11 @@ static noinline bool tcp_new(struct nf_conn *ct, const struct sk_buff *skb,
} }
/* Returns verdict for packet, or -1 for invalid. */ /* Returns verdict for packet, or -1 for invalid. */
static int tcp_packet(struct nf_conn *ct, int nf_conntrack_tcp_packet(struct nf_conn *ct,
struct sk_buff *skb, struct sk_buff *skb,
unsigned int dataoff, unsigned int dataoff,
enum ip_conntrack_info ctinfo, enum ip_conntrack_info ctinfo,
const struct nf_hook_state *state) const struct nf_hook_state *state)
{ {
struct net *net = nf_ct_net(ct); struct net *net = nf_ct_net(ct);
struct nf_tcp_net *tn = nf_tcp_pernet(net); struct nf_tcp_net *tn = nf_tcp_pernet(net);
...@@ -1535,7 +1535,6 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp = ...@@ -1535,7 +1535,6 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp =
#ifdef CONFIG_NF_CONNTRACK_PROCFS #ifdef CONFIG_NF_CONNTRACK_PROCFS
.print_conntrack = tcp_print_conntrack, .print_conntrack = tcp_print_conntrack,
#endif #endif
.packet = tcp_packet,
.can_early_drop = tcp_can_early_drop, .can_early_drop = tcp_can_early_drop,
#if IS_ENABLED(CONFIG_NF_CT_NETLINK) #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
.to_nlattr = tcp_to_nlattr, .to_nlattr = tcp_to_nlattr,
......
...@@ -85,11 +85,11 @@ static bool udp_error(struct sk_buff *skb, ...@@ -85,11 +85,11 @@ static bool udp_error(struct sk_buff *skb,
} }
/* Returns verdict for packet, and may modify conntracktype */ /* Returns verdict for packet, and may modify conntracktype */
static int udp_packet(struct nf_conn *ct, int nf_conntrack_udp_packet(struct nf_conn *ct,
struct sk_buff *skb, struct sk_buff *skb,
unsigned int dataoff, unsigned int dataoff,
enum ip_conntrack_info ctinfo, enum ip_conntrack_info ctinfo,
const struct nf_hook_state *state) const struct nf_hook_state *state)
{ {
unsigned int *timeouts; unsigned int *timeouts;
...@@ -177,11 +177,11 @@ static bool udplite_error(struct sk_buff *skb, ...@@ -177,11 +177,11 @@ static bool udplite_error(struct sk_buff *skb,
} }
/* Returns verdict for packet, and may modify conntracktype */ /* Returns verdict for packet, and may modify conntracktype */
static int udplite_packet(struct nf_conn *ct, int nf_conntrack_udplite_packet(struct nf_conn *ct,
struct sk_buff *skb, struct sk_buff *skb,
unsigned int dataoff, unsigned int dataoff,
enum ip_conntrack_info ctinfo, enum ip_conntrack_info ctinfo,
const struct nf_hook_state *state) const struct nf_hook_state *state)
{ {
unsigned int *timeouts; unsigned int *timeouts;
...@@ -319,7 +319,6 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_udp = ...@@ -319,7 +319,6 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_udp =
{ {
.l4proto = IPPROTO_UDP, .l4proto = IPPROTO_UDP,
.allow_clash = true, .allow_clash = true,
.packet = udp_packet,
#if IS_ENABLED(CONFIG_NF_CT_NETLINK) #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
.tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
.nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
...@@ -344,7 +343,6 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite = ...@@ -344,7 +343,6 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite =
{ {
.l4proto = IPPROTO_UDPLITE, .l4proto = IPPROTO_UDPLITE,
.allow_clash = true, .allow_clash = true,
.packet = udplite_packet,
#if IS_ENABLED(CONFIG_NF_CT_NETLINK) #if IS_ENABLED(CONFIG_NF_CT_NETLINK)
.tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
.nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment