Skip to content

Commit

Permalink
netfilter: conntrack: gre: switch module to be built-in
Browse files Browse the repository at this point in the history
This makes the last of the modular l4 trackers 'bool'.

After this, all infrastructure to handle dynamic l4 protocol registration
becomes obsolete and can be removed in followup patches.

Old:
302824 net/netfilter/nf_conntrack.ko
 21504 net/netfilter/nf_conntrack_proto_gre.ko

New:
313728 net/netfilter/nf_conntrack.ko

Old:
   text	   data	    bss	    dec	    hex	filename
   6281	   1732	      4	   8017	   1f51	nf_conntrack_proto_gre.ko
 108356	  20613	    236	 129205	  1f8b5	nf_conntrack.ko
New:
 112095	  21381	    240	 133716	  20a54	nf_conntrack.ko

The size increase is only temporary.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  • Loading branch information
Florian Westphal authored and Pablo Neira Ayuso committed Jan 18, 2019
1 parent 202e651 commit 22fc4c4
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 98 deletions.
14 changes: 1 addition & 13 deletions include/linux/netfilter/nf_conntrack_proto_gre.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,11 @@ struct nf_ct_gre_keymap {
struct rcu_head rcu;
};

enum grep_conntrack {
GRE_CT_UNREPLIED,
GRE_CT_REPLIED,
GRE_CT_MAX
};

struct netns_proto_gre {
struct nf_proto_net nf;
rwlock_t keymap_lock;
struct list_head keymap_list;
unsigned int gre_timeouts[GRE_CT_MAX];
};

/* add new tuple->key_reply pair to keymap */
int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
struct nf_conntrack_tuple *t);

void nf_ct_gre_keymap_flush(struct net *net);
/* delete keymap entries */
void nf_ct_gre_keymap_destroy(struct nf_conn *ct);

Expand Down
3 changes: 3 additions & 0 deletions include/net/netfilter/ipv4/nf_conntrack_ipv4.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,8 @@ extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp;
#ifdef CONFIG_NF_CT_PROTO_UDPLITE
extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite;
#endif
#ifdef CONFIG_NF_CT_PROTO_GRE
extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_gre;
#endif

#endif /*_NF_CONNTRACK_IPV4_H*/
7 changes: 7 additions & 0 deletions include/net/netfilter/nf_conntrack_l4proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,4 +239,11 @@ static inline struct nf_sctp_net *nf_sctp_pernet(struct net *net)
}
#endif

#ifdef CONFIG_NF_CT_PROTO_GRE
static inline struct nf_gre_net *nf_gre_pernet(struct net *net)
{
return &net->ct.nf_ct_proto.gre;
}
#endif

#endif /*_NF_CONNTRACK_PROTOCOL_H*/
17 changes: 17 additions & 0 deletions include/net/netns/conntrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,20 @@ struct nf_sctp_net {
};
#endif

#ifdef CONFIG_NF_CT_PROTO_GRE
enum gre_conntrack {
GRE_CT_UNREPLIED,
GRE_CT_REPLIED,
GRE_CT_MAX
};

struct nf_gre_net {
struct nf_proto_net nf;
struct list_head keymap_list;
unsigned int timeouts[GRE_CT_MAX];
};
#endif

struct nf_ip_net {
struct nf_generic_net generic;
struct nf_tcp_net tcp;
Expand All @@ -82,6 +96,9 @@ struct nf_ip_net {
#ifdef CONFIG_NF_CT_PROTO_SCTP
struct nf_sctp_net sctp;
#endif
#ifdef CONFIG_NF_CT_PROTO_GRE
struct nf_gre_net gre;
#endif
};

struct ct_pcpu {
Expand Down
2 changes: 1 addition & 1 deletion net/netfilter/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ config NF_CT_PROTO_DCCP
If unsure, say Y.

config NF_CT_PROTO_GRE
tristate
bool

config NF_CT_PROTO_SCTP
bool 'SCTP protocol connection tracking support'
Expand Down
3 changes: 1 addition & 2 deletions net/netfilter/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ nf_conntrack-$(CONFIG_NF_CONNTRACK_EVENTS) += nf_conntrack_ecache.o
nf_conntrack-$(CONFIG_NF_CONNTRACK_LABELS) += nf_conntrack_labels.o
nf_conntrack-$(CONFIG_NF_CT_PROTO_DCCP) += nf_conntrack_proto_dccp.o
nf_conntrack-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o
nf_conntrack-$(CONFIG_NF_CT_PROTO_GRE) += nf_conntrack_proto_gre.o

obj-$(CONFIG_NETFILTER) = netfilter.o

Expand All @@ -25,8 +26,6 @@ obj-$(CONFIG_NETFILTER_NETLINK_OSF) += nfnetlink_osf.o
# connection tracking
obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o

obj-$(CONFIG_NF_CT_PROTO_GRE) += nf_conntrack_proto_gre.o

# netlink interface for nf_conntrack
obj-$(CONFIG_NF_CT_NETLINK) += nf_conntrack_netlink.o
obj-$(CONFIG_NF_CT_NETLINK_TIMEOUT) += nfnetlink_cttimeout.o
Expand Down
7 changes: 6 additions & 1 deletion net/netfilter/nf_conntrack_proto.c
Original file line number Diff line number Diff line change
Expand Up @@ -817,6 +817,9 @@ static const struct nf_conntrack_l4proto * const builtin_l4proto[] = {
#ifdef CONFIG_NF_CT_PROTO_UDPLITE
&nf_conntrack_l4proto_udplite,
#endif
#ifdef CONFIG_NF_CT_PROTO_GRE
&nf_conntrack_l4proto_gre,
#endif
#if IS_ENABLED(CONFIG_IPV6)
&nf_conntrack_l4proto_icmpv6,
#endif /* CONFIG_IPV6 */
Expand Down Expand Up @@ -897,9 +900,11 @@ void nf_conntrack_proto_pernet_fini(struct net *net)
ARRAY_SIZE(builtin_l4proto));
pn->users--;
nf_ct_l4proto_unregister_sysctl(pn);
#ifdef CONFIG_NF_CT_PROTO_GRE
nf_ct_gre_keymap_flush(net);
#endif
}


module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint,
&nf_conntrack_htable_size, 0600);

Expand Down
93 changes: 18 additions & 75 deletions net/netfilter/nf_conntrack_proto_gre.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,17 @@ static const unsigned int gre_timeouts[GRE_CT_MAX] = {
[GRE_CT_REPLIED] = 180*HZ,
};

static unsigned int proto_gre_net_id __read_mostly;
/* used when expectation is added */
static DEFINE_SPINLOCK(keymap_lock);

static inline struct netns_proto_gre *gre_pernet(struct net *net)
static inline struct nf_gre_net *gre_pernet(struct net *net)
{
return net_generic(net, proto_gre_net_id);
return &net->ct.nf_ct_proto.gre;
}

static void nf_ct_gre_keymap_flush(struct net *net)
void nf_ct_gre_keymap_flush(struct net *net)
{
struct netns_proto_gre *net_gre = gre_pernet(net);
struct nf_gre_net *net_gre = gre_pernet(net);
struct nf_ct_gre_keymap *km, *tmp;

spin_lock_bh(&keymap_lock);
Expand All @@ -83,7 +82,7 @@ static inline int gre_key_cmpfn(const struct nf_ct_gre_keymap *km,
/* look up the source key for a given tuple */
static __be16 gre_keymap_lookup(struct net *net, struct nf_conntrack_tuple *t)
{
struct netns_proto_gre *net_gre = gre_pernet(net);
struct nf_gre_net *net_gre = gre_pernet(net);
struct nf_ct_gre_keymap *km;
__be16 key = 0;

Expand All @@ -105,7 +104,7 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
struct nf_conntrack_tuple *t)
{
struct net *net = nf_ct_net(ct);
struct netns_proto_gre *net_gre = gre_pernet(net);
struct nf_gre_net *net_gre = gre_pernet(net);
struct nf_ct_pptp_master *ct_pptp_info = nfct_help_data(ct);
struct nf_ct_gre_keymap **kmp, *km;

Expand Down Expand Up @@ -210,7 +209,7 @@ static void gre_print_conntrack(struct seq_file *s, struct nf_conn *ct)

static unsigned int *gre_get_timeouts(struct net *net)
{
return gre_pernet(net)->gre_timeouts;
return gre_pernet(net)->timeouts;
}

/* Returns verdict for packet, and may modify conntrack */
Expand Down Expand Up @@ -272,13 +271,13 @@ static int gre_timeout_nlattr_to_obj(struct nlattr *tb[],
struct net *net, void *data)
{
unsigned int *timeouts = data;
struct netns_proto_gre *net_gre = gre_pernet(net);
struct nf_gre_net *net_gre = gre_pernet(net);

if (!timeouts)
timeouts = gre_get_timeouts(net);
/* set default timeouts for GRE. */
timeouts[GRE_CT_UNREPLIED] = net_gre->gre_timeouts[GRE_CT_UNREPLIED];
timeouts[GRE_CT_REPLIED] = net_gre->gre_timeouts[GRE_CT_REPLIED];
timeouts[GRE_CT_UNREPLIED] = net_gre->timeouts[GRE_CT_UNREPLIED];
timeouts[GRE_CT_REPLIED] = net_gre->timeouts[GRE_CT_REPLIED];

if (tb[CTA_TIMEOUT_GRE_UNREPLIED]) {
timeouts[GRE_CT_UNREPLIED] =
Expand Down Expand Up @@ -332,10 +331,11 @@ static struct ctl_table gre_sysctl_table[] = {
};
#endif

static int gre_kmemdup_sysctl_table(struct net *net, struct nf_proto_net *nf,
struct netns_proto_gre *net_gre)
static int gre_kmemdup_sysctl_table(struct net *net)
{
#ifdef CONFIG_SYSCTL
struct nf_gre_net *net_gre = gre_pernet(net);
struct nf_proto_net *nf = &net_gre->nf;
int i;

if (nf->ctl_table)
Expand All @@ -348,26 +348,25 @@ static int gre_kmemdup_sysctl_table(struct net *net, struct nf_proto_net *nf,
return -ENOMEM;

for (i = 0; i < GRE_CT_MAX; i++)
nf->ctl_table[i].data = &net_gre->gre_timeouts[i];
nf->ctl_table[i].data = &net_gre->timeouts[i];
#endif
return 0;
}

static int gre_init_net(struct net *net)
{
struct netns_proto_gre *net_gre = gre_pernet(net);
struct nf_proto_net *nf = &net_gre->nf;
struct nf_gre_net *net_gre = gre_pernet(net);
int i;

INIT_LIST_HEAD(&net_gre->keymap_list);
for (i = 0; i < GRE_CT_MAX; i++)
net_gre->gre_timeouts[i] = gre_timeouts[i];
net_gre->timeouts[i] = gre_timeouts[i];

return gre_kmemdup_sysctl_table(net, nf, net_gre);
return gre_kmemdup_sysctl_table(net);
}

/* protocol helper struct */
static const struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 = {
const struct nf_conntrack_l4proto nf_conntrack_l4proto_gre = {
.l4proto = IPPROTO_GRE,
.pkt_to_tuple = gre_pkt_to_tuple,
#ifdef CONFIG_NF_CONNTRACK_PROCFS
Expand All @@ -391,61 +390,5 @@ static const struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 = {
.nla_policy = gre_timeout_nla_policy,
},
#endif /* CONFIG_NF_CONNTRACK_TIMEOUT */
.net_id = &proto_gre_net_id,
.init_net = gre_init_net,
};

static int proto_gre_net_init(struct net *net)
{
int ret = 0;

ret = nf_ct_l4proto_pernet_register_one(net,
&nf_conntrack_l4proto_gre4);
if (ret < 0)
pr_err("nf_conntrack_gre4: pernet registration failed.\n");
return ret;
}

static void proto_gre_net_exit(struct net *net)
{
nf_ct_l4proto_pernet_unregister_one(net, &nf_conntrack_l4proto_gre4);
nf_ct_gre_keymap_flush(net);
}

static struct pernet_operations proto_gre_net_ops = {
.init = proto_gre_net_init,
.exit = proto_gre_net_exit,
.id = &proto_gre_net_id,
.size = sizeof(struct netns_proto_gre),
};

static int __init nf_ct_proto_gre_init(void)
{
int ret;

BUILD_BUG_ON(offsetof(struct netns_proto_gre, nf) != 0);

ret = register_pernet_subsys(&proto_gre_net_ops);
if (ret < 0)
goto out_pernet;
ret = nf_ct_l4proto_register_one(&nf_conntrack_l4proto_gre4);
if (ret < 0)
goto out_gre4;

return 0;
out_gre4:
unregister_pernet_subsys(&proto_gre_net_ops);
out_pernet:
return ret;
}

static void __exit nf_ct_proto_gre_fini(void)
{
nf_ct_l4proto_unregister_one(&nf_conntrack_l4proto_gre4);
unregister_pernet_subsys(&proto_gre_net_ops);
}

module_init(nf_ct_proto_gre_init);
module_exit(nf_ct_proto_gre_fini);

MODULE_LICENSE("GPL");
7 changes: 1 addition & 6 deletions net/netfilter/nfnetlink_cttimeout.c
Original file line number Diff line number Diff line change
Expand Up @@ -474,12 +474,7 @@ static int cttimeout_default_get(struct net *net, struct sock *ctnl,
break;
case IPPROTO_GRE:
#ifdef CONFIG_NF_CT_PROTO_GRE
if (l4proto->net_id) {
struct netns_proto_gre *net_gre;

net_gre = net_generic(net, *l4proto->net_id);
timeouts = net_gre->gre_timeouts;
}
timeouts = nf_gre_pernet(net)->timeouts;
#endif
break;
case 255:
Expand Down

0 comments on commit 22fc4c4

Please sign in to comment.