Skip to content

Commit 1fefe14

Browse files
Florian Westphalummakynes
authored andcommitted
netfilter: synproxy: only register hooks when needed
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>
1 parent 122868b commit 1fefe14

File tree

3 files changed

+80
-68
lines changed

3 files changed

+80
-68
lines changed

include/net/netfilter/nf_conntrack_synproxy.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ struct synproxy_stats {
5252
struct synproxy_net {
5353
struct nf_conn *tmpl;
5454
struct synproxy_stats __percpu *stats;
55+
unsigned int hook_ref4;
56+
unsigned int hook_ref6;
5557
};
5658

5759
extern unsigned int synproxy_net_id;

net/ipv4/netfilter/ipt_SYNPROXY.c

Lines changed: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -409,19 +409,56 @@ static unsigned int ipv4_synproxy_hook(void *priv,
409409
return NF_ACCEPT;
410410
}
411411

412+
static struct nf_hook_ops ipv4_synproxy_ops[] __read_mostly = {
413+
{
414+
.hook = ipv4_synproxy_hook,
415+
.pf = NFPROTO_IPV4,
416+
.hooknum = NF_INET_LOCAL_IN,
417+
.priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1,
418+
},
419+
{
420+
.hook = ipv4_synproxy_hook,
421+
.pf = NFPROTO_IPV4,
422+
.hooknum = NF_INET_POST_ROUTING,
423+
.priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1,
424+
},
425+
};
426+
412427
static int synproxy_tg4_check(const struct xt_tgchk_param *par)
413428
{
429+
struct synproxy_net *snet = synproxy_pernet(par->net);
414430
const struct ipt_entry *e = par->entryinfo;
431+
int err;
415432

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

420-
return nf_ct_netns_get(par->net, par->family);
437+
err = nf_ct_netns_get(par->net, par->family);
438+
if (err)
439+
return err;
440+
441+
if (snet->hook_ref4 == 0) {
442+
err = nf_register_net_hooks(par->net, ipv4_synproxy_ops,
443+
ARRAY_SIZE(ipv4_synproxy_ops));
444+
if (err) {
445+
nf_ct_netns_put(par->net, par->family);
446+
return err;
447+
}
448+
}
449+
450+
snet->hook_ref4++;
451+
return err;
421452
}
422453

423454
static void synproxy_tg4_destroy(const struct xt_tgdtor_param *par)
424455
{
456+
struct synproxy_net *snet = synproxy_pernet(par->net);
457+
458+
snet->hook_ref4--;
459+
if (snet->hook_ref4 == 0)
460+
nf_unregister_net_hooks(par->net, ipv4_synproxy_ops,
461+
ARRAY_SIZE(ipv4_synproxy_ops));
425462
nf_ct_netns_put(par->net, par->family);
426463
}
427464

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

439-
static struct nf_hook_ops ipv4_synproxy_ops[] __read_mostly = {
440-
{
441-
.hook = ipv4_synproxy_hook,
442-
.pf = NFPROTO_IPV4,
443-
.hooknum = NF_INET_LOCAL_IN,
444-
.priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1,
445-
},
446-
{
447-
.hook = ipv4_synproxy_hook,
448-
.pf = NFPROTO_IPV4,
449-
.hooknum = NF_INET_POST_ROUTING,
450-
.priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1,
451-
},
452-
};
453-
454476
static int __init synproxy_tg4_init(void)
455477
{
456-
int err;
457-
458-
err = nf_register_hooks(ipv4_synproxy_ops,
459-
ARRAY_SIZE(ipv4_synproxy_ops));
460-
if (err < 0)
461-
goto err1;
462-
463-
err = xt_register_target(&synproxy_tg4_reg);
464-
if (err < 0)
465-
goto err2;
466-
467-
return 0;
468-
469-
err2:
470-
nf_unregister_hooks(ipv4_synproxy_ops, ARRAY_SIZE(ipv4_synproxy_ops));
471-
err1:
472-
return err;
478+
return xt_register_target(&synproxy_tg4_reg);
473479
}
474480

475481
static void __exit synproxy_tg4_exit(void)
476482
{
477483
xt_unregister_target(&synproxy_tg4_reg);
478-
nf_unregister_hooks(ipv4_synproxy_ops, ARRAY_SIZE(ipv4_synproxy_ops));
479484
}
480485

481486
module_init(synproxy_tg4_init);

net/ipv6/netfilter/ip6t_SYNPROXY.c

Lines changed: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -430,20 +430,57 @@ static unsigned int ipv6_synproxy_hook(void *priv,
430430
return NF_ACCEPT;
431431
}
432432

433+
static struct nf_hook_ops ipv6_synproxy_ops[] __read_mostly = {
434+
{
435+
.hook = ipv6_synproxy_hook,
436+
.pf = NFPROTO_IPV6,
437+
.hooknum = NF_INET_LOCAL_IN,
438+
.priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1,
439+
},
440+
{
441+
.hook = ipv6_synproxy_hook,
442+
.pf = NFPROTO_IPV6,
443+
.hooknum = NF_INET_POST_ROUTING,
444+
.priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1,
445+
},
446+
};
447+
433448
static int synproxy_tg6_check(const struct xt_tgchk_param *par)
434449
{
450+
struct synproxy_net *snet = synproxy_pernet(par->net);
435451
const struct ip6t_entry *e = par->entryinfo;
452+
int err;
436453

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

442-
return nf_ct_netns_get(par->net, par->family);
459+
err = nf_ct_netns_get(par->net, par->family);
460+
if (err)
461+
return err;
462+
463+
if (snet->hook_ref6 == 0) {
464+
err = nf_register_net_hooks(par->net, ipv6_synproxy_ops,
465+
ARRAY_SIZE(ipv6_synproxy_ops));
466+
if (err) {
467+
nf_ct_netns_put(par->net, par->family);
468+
return err;
469+
}
470+
}
471+
472+
snet->hook_ref6++;
473+
return err;
443474
}
444475

445476
static void synproxy_tg6_destroy(const struct xt_tgdtor_param *par)
446477
{
478+
struct synproxy_net *snet = synproxy_pernet(par->net);
479+
480+
snet->hook_ref6--;
481+
if (snet->hook_ref6 == 0)
482+
nf_unregister_net_hooks(par->net, ipv6_synproxy_ops,
483+
ARRAY_SIZE(ipv6_synproxy_ops));
447484
nf_ct_netns_put(par->net, par->family);
448485
}
449486

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

461-
static struct nf_hook_ops ipv6_synproxy_ops[] __read_mostly = {
462-
{
463-
.hook = ipv6_synproxy_hook,
464-
.pf = NFPROTO_IPV6,
465-
.hooknum = NF_INET_LOCAL_IN,
466-
.priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1,
467-
},
468-
{
469-
.hook = ipv6_synproxy_hook,
470-
.pf = NFPROTO_IPV6,
471-
.hooknum = NF_INET_POST_ROUTING,
472-
.priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1,
473-
},
474-
};
475-
476498
static int __init synproxy_tg6_init(void)
477499
{
478-
int err;
479-
480-
err = nf_register_hooks(ipv6_synproxy_ops,
481-
ARRAY_SIZE(ipv6_synproxy_ops));
482-
if (err < 0)
483-
goto err1;
484-
485-
err = xt_register_target(&synproxy_tg6_reg);
486-
if (err < 0)
487-
goto err2;
488-
489-
return 0;
490-
491-
err2:
492-
nf_unregister_hooks(ipv6_synproxy_ops, ARRAY_SIZE(ipv6_synproxy_ops));
493-
err1:
494-
return err;
500+
return xt_register_target(&synproxy_tg6_reg);
495501
}
496502

497503
static void __exit synproxy_tg6_exit(void)
498504
{
499505
xt_unregister_target(&synproxy_tg6_reg);
500-
nf_unregister_hooks(ipv6_synproxy_ops, ARRAY_SIZE(ipv6_synproxy_ops));
501506
}
502507

503508
module_init(synproxy_tg6_init);

0 commit comments

Comments
 (0)