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

netfilter: conntrack: avoid l4proto pkt_to_tuple calls

Handle common protocols (udp, tcp, ..), in the core and only
do the call if needed by the l4proto tracker.
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 8b3892ea
...@@ -235,6 +235,10 @@ nf_ct_get_tuple(const struct sk_buff *skb, ...@@ -235,6 +235,10 @@ nf_ct_get_tuple(const struct sk_buff *skb,
unsigned int size; unsigned int size;
const __be32 *ap; const __be32 *ap;
__be32 _addrs[8]; __be32 _addrs[8];
struct {
__be16 sport;
__be16 dport;
} _inet_hdr, *inet_hdr;
memset(tuple, 0, sizeof(*tuple)); memset(tuple, 0, sizeof(*tuple));
...@@ -270,7 +274,17 @@ nf_ct_get_tuple(const struct sk_buff *skb, ...@@ -270,7 +274,17 @@ nf_ct_get_tuple(const struct sk_buff *skb,
tuple->dst.protonum = protonum; tuple->dst.protonum = protonum;
tuple->dst.dir = IP_CT_DIR_ORIGINAL; tuple->dst.dir = IP_CT_DIR_ORIGINAL;
if (unlikely(l4proto->pkt_to_tuple))
return l4proto->pkt_to_tuple(skb, dataoff, net, tuple); return l4proto->pkt_to_tuple(skb, dataoff, net, tuple);
/* Actually only need first 4 bytes to get ports. */
inet_hdr = skb_header_pointer(skb, dataoff, sizeof(_inet_hdr), &_inet_hdr);
if (!inet_hdr)
return false;
tuple->src.u.udp.port = inet_hdr->sport;
tuple->dst.u.udp.port = inet_hdr->dport;
return true;
} }
static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
......
...@@ -388,21 +388,6 @@ static inline struct nf_dccp_net *dccp_pernet(struct net *net) ...@@ -388,21 +388,6 @@ static inline struct nf_dccp_net *dccp_pernet(struct net *net)
return &net->ct.nf_ct_proto.dccp; return &net->ct.nf_ct_proto.dccp;
} }
static bool dccp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
struct net *net, struct nf_conntrack_tuple *tuple)
{
struct dccp_hdr _hdr, *dh;
/* Actually only need first 4 bytes to get ports. */
dh = skb_header_pointer(skb, dataoff, 4, &_hdr);
if (dh == NULL)
return false;
tuple->src.u.dccp.port = dh->dccph_sport;
tuple->dst.u.dccp.port = dh->dccph_dport;
return true;
}
static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb, static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb,
unsigned int dataoff, unsigned int *timeouts) unsigned int dataoff, unsigned int *timeouts)
{ {
...@@ -856,7 +841,6 @@ static struct nf_proto_net *dccp_get_net_proto(struct net *net) ...@@ -856,7 +841,6 @@ static struct nf_proto_net *dccp_get_net_proto(struct net *net)
const struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp4 = { const struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp4 = {
.l3proto = AF_INET, .l3proto = AF_INET,
.l4proto = IPPROTO_DCCP, .l4proto = IPPROTO_DCCP,
.pkt_to_tuple = dccp_pkt_to_tuple,
.new = dccp_new, .new = dccp_new,
.packet = dccp_packet, .packet = dccp_packet,
.get_timeouts = dccp_get_timeouts, .get_timeouts = dccp_get_timeouts,
...@@ -891,7 +875,6 @@ EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_dccp4); ...@@ -891,7 +875,6 @@ EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_dccp4);
const struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp6 = { const struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp6 = {
.l3proto = AF_INET6, .l3proto = AF_INET6,
.l4proto = IPPROTO_DCCP, .l4proto = IPPROTO_DCCP,
.pkt_to_tuple = dccp_pkt_to_tuple,
.new = dccp_new, .new = dccp_new,
.packet = dccp_packet, .packet = dccp_packet,
.get_timeouts = dccp_get_timeouts, .get_timeouts = dccp_get_timeouts,
......
...@@ -150,22 +150,6 @@ static inline struct nf_sctp_net *sctp_pernet(struct net *net) ...@@ -150,22 +150,6 @@ static inline struct nf_sctp_net *sctp_pernet(struct net *net)
return &net->ct.nf_ct_proto.sctp; return &net->ct.nf_ct_proto.sctp;
} }
static bool sctp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
struct net *net, struct nf_conntrack_tuple *tuple)
{
const struct sctphdr *hp;
struct sctphdr _hdr;
/* Actually only need first 4 bytes to get ports. */
hp = skb_header_pointer(skb, dataoff, 4, &_hdr);
if (hp == NULL)
return false;
tuple->src.u.sctp.port = hp->source;
tuple->dst.u.sctp.port = hp->dest;
return true;
}
#ifdef CONFIG_NF_CONNTRACK_PROCFS #ifdef CONFIG_NF_CONNTRACK_PROCFS
/* Print out the private part of the conntrack. */ /* Print out the private part of the conntrack. */
static void sctp_print_conntrack(struct seq_file *s, struct nf_conn *ct) static void sctp_print_conntrack(struct seq_file *s, struct nf_conn *ct)
...@@ -772,7 +756,6 @@ static struct nf_proto_net *sctp_get_net_proto(struct net *net) ...@@ -772,7 +756,6 @@ static struct nf_proto_net *sctp_get_net_proto(struct net *net)
const struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 = { const struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 = {
.l3proto = PF_INET, .l3proto = PF_INET,
.l4proto = IPPROTO_SCTP, .l4proto = IPPROTO_SCTP,
.pkt_to_tuple = sctp_pkt_to_tuple,
#ifdef CONFIG_NF_CONNTRACK_PROCFS #ifdef CONFIG_NF_CONNTRACK_PROCFS
.print_conntrack = sctp_print_conntrack, .print_conntrack = sctp_print_conntrack,
#endif #endif
...@@ -808,7 +791,6 @@ EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_sctp4); ...@@ -808,7 +791,6 @@ EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_sctp4);
const struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 = { const struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 = {
.l3proto = PF_INET6, .l3proto = PF_INET6,
.l4proto = IPPROTO_SCTP, .l4proto = IPPROTO_SCTP,
.pkt_to_tuple = sctp_pkt_to_tuple,
#ifdef CONFIG_NF_CONNTRACK_PROCFS #ifdef CONFIG_NF_CONNTRACK_PROCFS
.print_conntrack = sctp_print_conntrack, .print_conntrack = sctp_print_conntrack,
#endif #endif
......
...@@ -276,23 +276,6 @@ static inline struct nf_tcp_net *tcp_pernet(struct net *net) ...@@ -276,23 +276,6 @@ static inline struct nf_tcp_net *tcp_pernet(struct net *net)
return &net->ct.nf_ct_proto.tcp; return &net->ct.nf_ct_proto.tcp;
} }
static bool tcp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
struct net *net, struct nf_conntrack_tuple *tuple)
{
const struct tcphdr *hp;
struct tcphdr _hdr;
/* Actually only need first 4 bytes to get ports. */
hp = skb_header_pointer(skb, dataoff, 4, &_hdr);
if (hp == NULL)
return false;
tuple->src.u.tcp.port = hp->source;
tuple->dst.u.tcp.port = hp->dest;
return true;
}
#ifdef CONFIG_NF_CONNTRACK_PROCFS #ifdef CONFIG_NF_CONNTRACK_PROCFS
/* Print out the private part of the conntrack. */ /* Print out the private part of the conntrack. */
static void tcp_print_conntrack(struct seq_file *s, struct nf_conn *ct) static void tcp_print_conntrack(struct seq_file *s, struct nf_conn *ct)
...@@ -1551,7 +1534,6 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 = ...@@ -1551,7 +1534,6 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 =
{ {
.l3proto = PF_INET, .l3proto = PF_INET,
.l4proto = IPPROTO_TCP, .l4proto = IPPROTO_TCP,
.pkt_to_tuple = tcp_pkt_to_tuple,
#ifdef CONFIG_NF_CONNTRACK_PROCFS #ifdef CONFIG_NF_CONNTRACK_PROCFS
.print_conntrack = tcp_print_conntrack, .print_conntrack = tcp_print_conntrack,
#endif #endif
...@@ -1588,7 +1570,6 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6 = ...@@ -1588,7 +1570,6 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6 =
{ {
.l3proto = PF_INET6, .l3proto = PF_INET6,
.l4proto = IPPROTO_TCP, .l4proto = IPPROTO_TCP,
.pkt_to_tuple = tcp_pkt_to_tuple,
#ifdef CONFIG_NF_CONNTRACK_PROCFS #ifdef CONFIG_NF_CONNTRACK_PROCFS
.print_conntrack = tcp_print_conntrack, .print_conntrack = tcp_print_conntrack,
#endif #endif
......
...@@ -36,25 +36,6 @@ static inline struct nf_udp_net *udp_pernet(struct net *net) ...@@ -36,25 +36,6 @@ static inline struct nf_udp_net *udp_pernet(struct net *net)
return &net->ct.nf_ct_proto.udp; return &net->ct.nf_ct_proto.udp;
} }
static bool udp_pkt_to_tuple(const struct sk_buff *skb,
unsigned int dataoff,
struct net *net,
struct nf_conntrack_tuple *tuple)
{
const struct udphdr *hp;
struct udphdr _hdr;
/* Actually only need first 4 bytes to get ports. */
hp = skb_header_pointer(skb, dataoff, 4, &_hdr);
if (hp == NULL)
return false;
tuple->src.u.udp.port = hp->source;
tuple->dst.u.udp.port = hp->dest;
return true;
}
static unsigned int *udp_get_timeouts(struct net *net) static unsigned int *udp_get_timeouts(struct net *net)
{ {
return udp_pernet(net)->timeouts; return udp_pernet(net)->timeouts;
...@@ -293,7 +274,6 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 = ...@@ -293,7 +274,6 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 =
.l3proto = PF_INET, .l3proto = PF_INET,
.l4proto = IPPROTO_UDP, .l4proto = IPPROTO_UDP,
.allow_clash = true, .allow_clash = true,
.pkt_to_tuple = udp_pkt_to_tuple,
.packet = udp_packet, .packet = udp_packet,
.get_timeouts = udp_get_timeouts, .get_timeouts = udp_get_timeouts,
.new = udp_new, .new = udp_new,
...@@ -324,7 +304,6 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 = ...@@ -324,7 +304,6 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 =
.l3proto = PF_INET, .l3proto = PF_INET,
.l4proto = IPPROTO_UDPLITE, .l4proto = IPPROTO_UDPLITE,
.allow_clash = true, .allow_clash = true,
.pkt_to_tuple = udp_pkt_to_tuple,
.packet = udp_packet, .packet = udp_packet,
.get_timeouts = udp_get_timeouts, .get_timeouts = udp_get_timeouts,
.new = udp_new, .new = udp_new,
...@@ -355,7 +334,6 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6 = ...@@ -355,7 +334,6 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6 =
.l3proto = PF_INET6, .l3proto = PF_INET6,
.l4proto = IPPROTO_UDP, .l4proto = IPPROTO_UDP,
.allow_clash = true, .allow_clash = true,
.pkt_to_tuple = udp_pkt_to_tuple,
.packet = udp_packet, .packet = udp_packet,
.get_timeouts = udp_get_timeouts, .get_timeouts = udp_get_timeouts,
.new = udp_new, .new = udp_new,
...@@ -386,7 +364,6 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6 = ...@@ -386,7 +364,6 @@ const struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6 =
.l3proto = PF_INET6, .l3proto = PF_INET6,
.l4proto = IPPROTO_UDPLITE, .l4proto = IPPROTO_UDPLITE,
.allow_clash = true, .allow_clash = true,
.pkt_to_tuple = udp_pkt_to_tuple,
.packet = udp_packet, .packet = udp_packet,
.get_timeouts = udp_get_timeouts, .get_timeouts = udp_get_timeouts,
.new = udp_new, .new = udp_new,
......
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