Commit c51d3901 authored by Davide Caratti's avatar Davide Caratti Committed by Pablo Neira Ayuso

netfilter: conntrack: built-in support for DCCP

CONFIG_NF_CT_PROTO_DCCP is no more a tristate. When set to y, connection
tracking support for DCCP protocol is built-in into nf_conntrack.ko.

footprint test:
$ ls -l net/netfilter/nf_conntrack{_proto_dccp,}.ko \
        net/ipv4/netfilter/nf_conntrack_ipv4.ko \
        net/ipv6/netfilter/nf_conntrack_ipv6.ko

(builtin)||  dccp  |  ipv4  |  ipv6  | nf_conntrack
---------++--------+--------+--------+--------------
none     || 469140 | 828755 | 828676 | 6141434
DCCP     ||   -    | 830566 | 829935 | 6533526
Signed-off-by: default avatarDavide Caratti <dcaratti@redhat.com>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 3fefeb88
...@@ -25,7 +25,7 @@ enum ct_dccp_roles { ...@@ -25,7 +25,7 @@ enum ct_dccp_roles {
#define CT_DCCP_ROLE_MAX (__CT_DCCP_ROLE_MAX - 1) #define CT_DCCP_ROLE_MAX (__CT_DCCP_ROLE_MAX - 1)
#ifdef __KERNEL__ #ifdef __KERNEL__
#include <net/netfilter/nf_conntrack_tuple.h> #include <linux/netfilter/nf_conntrack_tuple_common.h>
struct nf_ct_dccp { struct nf_ct_dccp {
u_int8_t role[IP_CT_DIR_MAX]; u_int8_t role[IP_CT_DIR_MAX];
......
...@@ -15,6 +15,9 @@ extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4; ...@@ -15,6 +15,9 @@ extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4;
extern struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4; extern struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4;
extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4; extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4;
extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp; extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp;
#ifdef CONFIG_NF_CT_PROTO_DCCP
extern struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp4;
#endif
int nf_conntrack_ipv4_compat_init(void); int nf_conntrack_ipv4_compat_init(void);
void nf_conntrack_ipv4_compat_fini(void); void nf_conntrack_ipv4_compat_fini(void);
......
...@@ -6,6 +6,9 @@ extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6; ...@@ -6,6 +6,9 @@ extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6;
extern struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6; extern struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6;
extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6; extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6;
extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6; extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6;
#ifdef CONFIG_NF_CT_PROTO_DCCP
extern struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp6;
#endif
#include <linux/sysctl.h> #include <linux/sysctl.h>
extern struct ctl_table nf_ct_ipv6_sysctl_table[]; extern struct ctl_table nf_ct_ipv6_sysctl_table[];
......
...@@ -6,6 +6,9 @@ ...@@ -6,6 +6,9 @@
#include <linux/atomic.h> #include <linux/atomic.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/netfilter/nf_conntrack_tcp.h> #include <linux/netfilter/nf_conntrack_tcp.h>
#ifdef CONFIG_NF_CT_PROTO_DCCP
#include <linux/netfilter/nf_conntrack_dccp.h>
#endif
#include <linux/seqlock.h> #include <linux/seqlock.h>
struct ctl_table_header; struct ctl_table_header;
...@@ -48,12 +51,23 @@ struct nf_icmp_net { ...@@ -48,12 +51,23 @@ struct nf_icmp_net {
unsigned int timeout; unsigned int timeout;
}; };
#ifdef CONFIG_NF_CT_PROTO_DCCP
struct nf_dccp_net {
struct nf_proto_net pn;
int dccp_loose;
unsigned int dccp_timeout[CT_DCCP_MAX + 1];
};
#endif
struct nf_ip_net { struct nf_ip_net {
struct nf_generic_net generic; struct nf_generic_net generic;
struct nf_tcp_net tcp; struct nf_tcp_net tcp;
struct nf_udp_net udp; struct nf_udp_net udp;
struct nf_icmp_net icmp; struct nf_icmp_net icmp;
struct nf_icmp_net icmpv6; struct nf_icmp_net icmpv6;
#ifdef CONFIG_NF_CT_PROTO_DCCP
struct nf_dccp_net dccp;
#endif
}; };
struct ct_pcpu { struct ct_pcpu {
......
...@@ -340,6 +340,9 @@ static struct nf_conntrack_l4proto *builtin_l4proto4[] = { ...@@ -340,6 +340,9 @@ static struct nf_conntrack_l4proto *builtin_l4proto4[] = {
&nf_conntrack_l4proto_tcp4, &nf_conntrack_l4proto_tcp4,
&nf_conntrack_l4proto_udp4, &nf_conntrack_l4proto_udp4,
&nf_conntrack_l4proto_icmp, &nf_conntrack_l4proto_icmp,
#ifdef CONFIG_NF_CT_PROTO_DCCP
&nf_conntrack_l4proto_dccp4,
#endif
}; };
static int ipv4_net_init(struct net *net) static int ipv4_net_init(struct net *net)
......
...@@ -340,6 +340,9 @@ static struct nf_conntrack_l4proto *builtin_l4proto6[] = { ...@@ -340,6 +340,9 @@ static struct nf_conntrack_l4proto *builtin_l4proto6[] = {
&nf_conntrack_l4proto_tcp6, &nf_conntrack_l4proto_tcp6,
&nf_conntrack_l4proto_udp6, &nf_conntrack_l4proto_udp6,
&nf_conntrack_l4proto_icmpv6, &nf_conntrack_l4proto_icmpv6,
#ifdef CONFIG_NF_CT_PROTO_DCCP
&nf_conntrack_l4proto_dccp6,
#endif
}; };
static int ipv6_net_init(struct net *net) static int ipv6_net_init(struct net *net)
......
...@@ -146,14 +146,14 @@ config NF_CONNTRACK_LABELS ...@@ -146,14 +146,14 @@ config NF_CONNTRACK_LABELS
to connection tracking entries. It selected by the connlabel match. to connection tracking entries. It selected by the connlabel match.
config NF_CT_PROTO_DCCP config NF_CT_PROTO_DCCP
tristate 'DCCP protocol connection tracking support' bool 'DCCP protocol connection tracking support'
depends on NETFILTER_ADVANCED depends on NETFILTER_ADVANCED
default IP_DCCP default y
help help
With this option enabled, the layer 3 independent connection With this option enabled, the layer 3 independent connection
tracking code will be able to do state tracking on DCCP connections. tracking code will be able to do state tracking on DCCP connections.
If unsure, say 'N'. If unsure, say Y.
config NF_CT_PROTO_GRE config NF_CT_PROTO_GRE
tristate tristate
......
...@@ -5,6 +5,7 @@ nf_conntrack-$(CONFIG_NF_CONNTRACK_TIMEOUT) += nf_conntrack_timeout.o ...@@ -5,6 +5,7 @@ nf_conntrack-$(CONFIG_NF_CONNTRACK_TIMEOUT) += nf_conntrack_timeout.o
nf_conntrack-$(CONFIG_NF_CONNTRACK_TIMESTAMP) += nf_conntrack_timestamp.o nf_conntrack-$(CONFIG_NF_CONNTRACK_TIMESTAMP) += nf_conntrack_timestamp.o
nf_conntrack-$(CONFIG_NF_CONNTRACK_EVENTS) += nf_conntrack_ecache.o nf_conntrack-$(CONFIG_NF_CONNTRACK_EVENTS) += nf_conntrack_ecache.o
nf_conntrack-$(CONFIG_NF_CONNTRACK_LABELS) += nf_conntrack_labels.o nf_conntrack-$(CONFIG_NF_CONNTRACK_LABELS) += nf_conntrack_labels.o
nf_conntrack-$(CONFIG_NF_CT_PROTO_DCCP) += nf_conntrack_proto_dccp.o
obj-$(CONFIG_NETFILTER) = netfilter.o obj-$(CONFIG_NETFILTER) = netfilter.o
...@@ -16,8 +17,6 @@ obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o ...@@ -16,8 +17,6 @@ obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o
# connection tracking # connection tracking
obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o
# SCTP protocol connection tracking
obj-$(CONFIG_NF_CT_PROTO_DCCP) += nf_conntrack_proto_dccp.o
obj-$(CONFIG_NF_CT_PROTO_GRE) += nf_conntrack_proto_gre.o obj-$(CONFIG_NF_CT_PROTO_GRE) += nf_conntrack_proto_gre.o
obj-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o obj-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o
obj-$(CONFIG_NF_CT_PROTO_UDPLITE) += nf_conntrack_proto_udplite.o obj-$(CONFIG_NF_CT_PROTO_UDPLITE) += nf_conntrack_proto_udplite.o
......
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
* *
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/sysctl.h> #include <linux/sysctl.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
...@@ -384,17 +383,9 @@ dccp_state_table[CT_DCCP_ROLE_MAX + 1][DCCP_PKT_SYNCACK + 1][CT_DCCP_MAX + 1] = ...@@ -384,17 +383,9 @@ dccp_state_table[CT_DCCP_ROLE_MAX + 1][DCCP_PKT_SYNCACK + 1][CT_DCCP_MAX + 1] =
}, },
}; };
/* this module per-net specifics */ static inline struct nf_dccp_net *dccp_pernet(struct net *net)
static unsigned int dccp_net_id __read_mostly;
struct dccp_net {
struct nf_proto_net pn;
int dccp_loose;
unsigned int dccp_timeout[CT_DCCP_MAX + 1];
};
static inline struct dccp_net *dccp_pernet(struct net *net)
{ {
return net_generic(net, dccp_net_id); return &net->ct.nf_ct_proto.dccp;
} }
static bool dccp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, static bool dccp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
...@@ -424,7 +415,7 @@ static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb, ...@@ -424,7 +415,7 @@ 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)
{ {
struct net *net = nf_ct_net(ct); struct net *net = nf_ct_net(ct);
struct dccp_net *dn; struct nf_dccp_net *dn;
struct dccp_hdr _dh, *dh; struct dccp_hdr _dh, *dh;
const char *msg; const char *msg;
u_int8_t state; u_int8_t state;
...@@ -719,7 +710,7 @@ static int dccp_nlattr_size(void) ...@@ -719,7 +710,7 @@ static int dccp_nlattr_size(void)
static int dccp_timeout_nlattr_to_obj(struct nlattr *tb[], static int dccp_timeout_nlattr_to_obj(struct nlattr *tb[],
struct net *net, void *data) struct net *net, void *data)
{ {
struct dccp_net *dn = dccp_pernet(net); struct nf_dccp_net *dn = dccp_pernet(net);
unsigned int *timeouts = data; unsigned int *timeouts = data;
int i; int i;
...@@ -820,7 +811,7 @@ static struct ctl_table dccp_sysctl_table[] = { ...@@ -820,7 +811,7 @@ static struct ctl_table dccp_sysctl_table[] = {
#endif /* CONFIG_SYSCTL */ #endif /* CONFIG_SYSCTL */
static int dccp_kmemdup_sysctl_table(struct net *net, struct nf_proto_net *pn, static int dccp_kmemdup_sysctl_table(struct net *net, struct nf_proto_net *pn,
struct dccp_net *dn) struct nf_dccp_net *dn)
{ {
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
if (pn->ctl_table) if (pn->ctl_table)
...@@ -850,7 +841,7 @@ static int dccp_kmemdup_sysctl_table(struct net *net, struct nf_proto_net *pn, ...@@ -850,7 +841,7 @@ static int dccp_kmemdup_sysctl_table(struct net *net, struct nf_proto_net *pn,
static int dccp_init_net(struct net *net, u_int16_t proto) static int dccp_init_net(struct net *net, u_int16_t proto)
{ {
struct dccp_net *dn = dccp_pernet(net); struct nf_dccp_net *dn = dccp_pernet(net);
struct nf_proto_net *pn = &dn->pn; struct nf_proto_net *pn = &dn->pn;
if (!pn->users) { if (!pn->users) {
...@@ -868,7 +859,7 @@ static int dccp_init_net(struct net *net, u_int16_t proto) ...@@ -868,7 +859,7 @@ static int dccp_init_net(struct net *net, u_int16_t proto)
return dccp_kmemdup_sysctl_table(net, pn, dn); return dccp_kmemdup_sysctl_table(net, pn, dn);
} }
static struct nf_conntrack_l4proto dccp_proto4 __read_mostly = { struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp4 __read_mostly = {
.l3proto = AF_INET, .l3proto = AF_INET,
.l4proto = IPPROTO_DCCP, .l4proto = IPPROTO_DCCP,
.name = "dccp", .name = "dccp",
...@@ -898,11 +889,11 @@ static struct nf_conntrack_l4proto dccp_proto4 __read_mostly = { ...@@ -898,11 +889,11 @@ static struct nf_conntrack_l4proto dccp_proto4 __read_mostly = {
.nla_policy = dccp_timeout_nla_policy, .nla_policy = dccp_timeout_nla_policy,
}, },
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
.net_id = &dccp_net_id,
.init_net = dccp_init_net, .init_net = dccp_init_net,
}; };
EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_dccp4);
static struct nf_conntrack_l4proto dccp_proto6 __read_mostly = { struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp6 __read_mostly = {
.l3proto = AF_INET6, .l3proto = AF_INET6,
.l4proto = IPPROTO_DCCP, .l4proto = IPPROTO_DCCP,
.name = "dccp", .name = "dccp",
...@@ -932,56 +923,6 @@ static struct nf_conntrack_l4proto dccp_proto6 __read_mostly = { ...@@ -932,56 +923,6 @@ static struct nf_conntrack_l4proto dccp_proto6 __read_mostly = {
.nla_policy = dccp_timeout_nla_policy, .nla_policy = dccp_timeout_nla_policy,
}, },
#endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */ #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
.net_id = &dccp_net_id,
.init_net = dccp_init_net, .init_net = dccp_init_net,
}; };
EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_dccp6);
static struct nf_conntrack_l4proto *dccp_proto[] = {
&dccp_proto4,
&dccp_proto6,
};
static __net_init int dccp_net_init(struct net *net)
{
return nf_ct_l4proto_pernet_register(net, dccp_proto,
ARRAY_SIZE(dccp_proto));
}
static __net_exit void dccp_net_exit(struct net *net)
{
nf_ct_l4proto_pernet_unregister(net, dccp_proto,
ARRAY_SIZE(dccp_proto));
}
static struct pernet_operations dccp_net_ops = {
.init = dccp_net_init,
.exit = dccp_net_exit,
.id = &dccp_net_id,
.size = sizeof(struct dccp_net),
};
static int __init nf_conntrack_proto_dccp_init(void)
{
int ret;
ret = register_pernet_subsys(&dccp_net_ops);
if (ret < 0)
return ret;
ret = nf_ct_l4proto_register(dccp_proto, ARRAY_SIZE(dccp_proto));
if (ret < 0)
unregister_pernet_subsys(&dccp_net_ops);
return ret;
}
static void __exit nf_conntrack_proto_dccp_fini(void)
{
nf_ct_l4proto_unregister(dccp_proto, ARRAY_SIZE(dccp_proto));
unregister_pernet_subsys(&dccp_net_ops);
}
module_init(nf_conntrack_proto_dccp_init);
module_exit(nf_conntrack_proto_dccp_fini);
MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
MODULE_DESCRIPTION("DCCP connection tracking protocol helper");
MODULE_LICENSE("GPL");
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