Skip to content
This repository has been archived by the owner on Sep 24, 2020. It is now read-only.

Commit

Permalink
netfilter: synproxy: only register hooks when needed
Browse files Browse the repository at this point in the history
Defer registration of the synproxy hooks until the first SYNPROXY rule is
added.  Also means we only register hooks in namespaces that need it.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  • Loading branch information
Florian Westphal authored and ummakynes committed Apr 26, 2017
1 parent 122868b commit 1fefe14
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 68 deletions.
2 changes: 2 additions & 0 deletions include/net/netfilter/nf_conntrack_synproxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ struct synproxy_stats {
struct synproxy_net {
struct nf_conn *tmpl;
struct synproxy_stats __percpu *stats;
unsigned int hook_ref4;
unsigned int hook_ref6;
};

extern unsigned int synproxy_net_id;
Expand Down
73 changes: 39 additions & 34 deletions net/ipv4/netfilter/ipt_SYNPROXY.c
Original file line number Diff line number Diff line change
Expand Up @@ -409,19 +409,56 @@ static unsigned int ipv4_synproxy_hook(void *priv,
return NF_ACCEPT;
}

static struct nf_hook_ops ipv4_synproxy_ops[] __read_mostly = {
{
.hook = ipv4_synproxy_hook,
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1,
},
{
.hook = ipv4_synproxy_hook,
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_POST_ROUTING,
.priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1,
},
};

static int synproxy_tg4_check(const struct xt_tgchk_param *par)
{
struct synproxy_net *snet = synproxy_pernet(par->net);
const struct ipt_entry *e = par->entryinfo;
int err;

if (e->ip.proto != IPPROTO_TCP ||
e->ip.invflags & XT_INV_PROTO)
return -EINVAL;

return nf_ct_netns_get(par->net, par->family);
err = nf_ct_netns_get(par->net, par->family);
if (err)
return err;

if (snet->hook_ref4 == 0) {
err = nf_register_net_hooks(par->net, ipv4_synproxy_ops,
ARRAY_SIZE(ipv4_synproxy_ops));
if (err) {
nf_ct_netns_put(par->net, par->family);
return err;
}
}

snet->hook_ref4++;
return err;
}

static void synproxy_tg4_destroy(const struct xt_tgdtor_param *par)
{
struct synproxy_net *snet = synproxy_pernet(par->net);

snet->hook_ref4--;
if (snet->hook_ref4 == 0)
nf_unregister_net_hooks(par->net, ipv4_synproxy_ops,
ARRAY_SIZE(ipv4_synproxy_ops));
nf_ct_netns_put(par->net, par->family);
}

Expand All @@ -436,46 +473,14 @@ static struct xt_target synproxy_tg4_reg __read_mostly = {
.me = THIS_MODULE,
};

static struct nf_hook_ops ipv4_synproxy_ops[] __read_mostly = {
{
.hook = ipv4_synproxy_hook,
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1,
},
{
.hook = ipv4_synproxy_hook,
.pf = NFPROTO_IPV4,
.hooknum = NF_INET_POST_ROUTING,
.priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1,
},
};

static int __init synproxy_tg4_init(void)
{
int err;

err = nf_register_hooks(ipv4_synproxy_ops,
ARRAY_SIZE(ipv4_synproxy_ops));
if (err < 0)
goto err1;

err = xt_register_target(&synproxy_tg4_reg);
if (err < 0)
goto err2;

return 0;

err2:
nf_unregister_hooks(ipv4_synproxy_ops, ARRAY_SIZE(ipv4_synproxy_ops));
err1:
return err;
return xt_register_target(&synproxy_tg4_reg);
}

static void __exit synproxy_tg4_exit(void)
{
xt_unregister_target(&synproxy_tg4_reg);
nf_unregister_hooks(ipv4_synproxy_ops, ARRAY_SIZE(ipv4_synproxy_ops));
}

module_init(synproxy_tg4_init);
Expand Down
73 changes: 39 additions & 34 deletions net/ipv6/netfilter/ip6t_SYNPROXY.c
Original file line number Diff line number Diff line change
Expand Up @@ -430,20 +430,57 @@ static unsigned int ipv6_synproxy_hook(void *priv,
return NF_ACCEPT;
}

static struct nf_hook_ops ipv6_synproxy_ops[] __read_mostly = {
{
.hook = ipv6_synproxy_hook,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1,
},
{
.hook = ipv6_synproxy_hook,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_POST_ROUTING,
.priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1,
},
};

static int synproxy_tg6_check(const struct xt_tgchk_param *par)
{
struct synproxy_net *snet = synproxy_pernet(par->net);
const struct ip6t_entry *e = par->entryinfo;
int err;

if (!(e->ipv6.flags & IP6T_F_PROTO) ||
e->ipv6.proto != IPPROTO_TCP ||
e->ipv6.invflags & XT_INV_PROTO)
return -EINVAL;

return nf_ct_netns_get(par->net, par->family);
err = nf_ct_netns_get(par->net, par->family);
if (err)
return err;

if (snet->hook_ref6 == 0) {
err = nf_register_net_hooks(par->net, ipv6_synproxy_ops,
ARRAY_SIZE(ipv6_synproxy_ops));
if (err) {
nf_ct_netns_put(par->net, par->family);
return err;
}
}

snet->hook_ref6++;
return err;
}

static void synproxy_tg6_destroy(const struct xt_tgdtor_param *par)
{
struct synproxy_net *snet = synproxy_pernet(par->net);

snet->hook_ref6--;
if (snet->hook_ref6 == 0)
nf_unregister_net_hooks(par->net, ipv6_synproxy_ops,
ARRAY_SIZE(ipv6_synproxy_ops));
nf_ct_netns_put(par->net, par->family);
}

Expand All @@ -458,46 +495,14 @@ static struct xt_target synproxy_tg6_reg __read_mostly = {
.me = THIS_MODULE,
};

static struct nf_hook_ops ipv6_synproxy_ops[] __read_mostly = {
{
.hook = ipv6_synproxy_hook,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1,
},
{
.hook = ipv6_synproxy_hook,
.pf = NFPROTO_IPV6,
.hooknum = NF_INET_POST_ROUTING,
.priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1,
},
};

static int __init synproxy_tg6_init(void)
{
int err;

err = nf_register_hooks(ipv6_synproxy_ops,
ARRAY_SIZE(ipv6_synproxy_ops));
if (err < 0)
goto err1;

err = xt_register_target(&synproxy_tg6_reg);
if (err < 0)
goto err2;

return 0;

err2:
nf_unregister_hooks(ipv6_synproxy_ops, ARRAY_SIZE(ipv6_synproxy_ops));
err1:
return err;
return xt_register_target(&synproxy_tg6_reg);
}

static void __exit synproxy_tg6_exit(void)
{
xt_unregister_target(&synproxy_tg6_reg);
nf_unregister_hooks(ipv6_synproxy_ops, ARRAY_SIZE(ipv6_synproxy_ops));
}

module_init(synproxy_tg6_init);
Expand Down

0 comments on commit 1fefe14

Please sign in to comment.