Skip to content

Commit 82de0be

Browse files
gfreewindummakynes
authored andcommitted
netfilter: Add helper array register/unregister functions
Add nf_ct_helper_init(), nf_conntrack_helpers_register() and nf_conntrack_helpers_unregister() functions to avoid repetitive opencoded initialization in helpers. This patch keeps an id parameter for nf_ct_helper_init() not to break helper matching by name that has been inconsistently exposed to userspace through ports, eg. ftp-2121, and through an incremental id, eg. tftp-1. Signed-off-by: Gao Feng <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent 590025a commit 82de0be

File tree

7 files changed

+165
-181
lines changed

7 files changed

+165
-181
lines changed

include/net/netfilter/nf_conntrack_helper.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,25 @@ struct nf_conntrack_helper *__nf_conntrack_helper_find(const char *name,
5858
struct nf_conntrack_helper *nf_conntrack_helper_try_module_get(const char *name,
5959
u16 l3num,
6060
u8 protonum);
61+
void nf_ct_helper_init(struct nf_conntrack_helper *helper,
62+
u16 l3num, u16 protonum, const char *name,
63+
u16 default_port, u16 spec_port, u32 id,
64+
const struct nf_conntrack_expect_policy *exp_pol,
65+
u32 expect_class_max, u32 data_len,
66+
int (*help)(struct sk_buff *skb, unsigned int protoff,
67+
struct nf_conn *ct,
68+
enum ip_conntrack_info ctinfo),
69+
int (*from_nlattr)(struct nlattr *attr,
70+
struct nf_conn *ct),
71+
struct module *module);
6172

6273
int nf_conntrack_helper_register(struct nf_conntrack_helper *);
6374
void nf_conntrack_helper_unregister(struct nf_conntrack_helper *);
6475

76+
int nf_conntrack_helpers_register(struct nf_conntrack_helper *, unsigned int);
77+
void nf_conntrack_helpers_unregister(struct nf_conntrack_helper *,
78+
unsigned int);
79+
6580
struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct,
6681
struct nf_conntrack_helper *helper,
6782
gfp_t gfp);

net/netfilter/nf_conntrack_ftp.c

Lines changed: 18 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ static int nf_ct_ftp_from_nlattr(struct nlattr *attr, struct nf_conn *ct)
572572
return 0;
573573
}
574574

575-
static struct nf_conntrack_helper ftp[MAX_PORTS][2] __read_mostly;
575+
static struct nf_conntrack_helper ftp[MAX_PORTS * 2] __read_mostly;
576576

577577
static const struct nf_conntrack_expect_policy ftp_exp_policy = {
578578
.max_expected = 1,
@@ -582,24 +582,13 @@ static const struct nf_conntrack_expect_policy ftp_exp_policy = {
582582
/* don't make this __exit, since it's called from __init ! */
583583
static void nf_conntrack_ftp_fini(void)
584584
{
585-
int i, j;
586-
for (i = 0; i < ports_c; i++) {
587-
for (j = 0; j < 2; j++) {
588-
if (ftp[i][j].me == NULL)
589-
continue;
590-
591-
pr_debug("unregistering helper for pf: %d port: %d\n",
592-
ftp[i][j].tuple.src.l3num, ports[i]);
593-
nf_conntrack_helper_unregister(&ftp[i][j]);
594-
}
595-
}
596-
585+
nf_conntrack_helpers_unregister(ftp, ports_c * 2);
597586
kfree(ftp_buffer);
598587
}
599588

600589
static int __init nf_conntrack_ftp_init(void)
601590
{
602-
int i, j = -1, ret = 0;
591+
int i, ret = 0;
603592

604593
ftp_buffer = kmalloc(65536, GFP_KERNEL);
605594
if (!ftp_buffer)
@@ -611,32 +600,21 @@ static int __init nf_conntrack_ftp_init(void)
611600
/* FIXME should be configurable whether IPv4 and IPv6 FTP connections
612601
are tracked or not - YK */
613602
for (i = 0; i < ports_c; i++) {
614-
ftp[i][0].tuple.src.l3num = PF_INET;
615-
ftp[i][1].tuple.src.l3num = PF_INET6;
616-
for (j = 0; j < 2; j++) {
617-
ftp[i][j].data_len = sizeof(struct nf_ct_ftp_master);
618-
ftp[i][j].tuple.src.u.tcp.port = htons(ports[i]);
619-
ftp[i][j].tuple.dst.protonum = IPPROTO_TCP;
620-
ftp[i][j].expect_policy = &ftp_exp_policy;
621-
ftp[i][j].me = THIS_MODULE;
622-
ftp[i][j].help = help;
623-
ftp[i][j].from_nlattr = nf_ct_ftp_from_nlattr;
624-
if (ports[i] == FTP_PORT)
625-
sprintf(ftp[i][j].name, "ftp");
626-
else
627-
sprintf(ftp[i][j].name, "ftp-%d", ports[i]);
628-
629-
pr_debug("registering helper for pf: %d port: %d\n",
630-
ftp[i][j].tuple.src.l3num, ports[i]);
631-
ret = nf_conntrack_helper_register(&ftp[i][j]);
632-
if (ret) {
633-
pr_err("failed to register helper for pf: %d port: %d\n",
634-
ftp[i][j].tuple.src.l3num, ports[i]);
635-
ports_c = i;
636-
nf_conntrack_ftp_fini();
637-
return ret;
638-
}
639-
}
603+
nf_ct_helper_init(&ftp[2 * i], AF_INET, IPPROTO_TCP, "ftp",
604+
FTP_PORT, ports[i], ports[i], &ftp_exp_policy,
605+
0, sizeof(struct nf_ct_ftp_master), help,
606+
nf_ct_ftp_from_nlattr, THIS_MODULE);
607+
nf_ct_helper_init(&ftp[2 * i + 1], AF_INET6, IPPROTO_TCP, "ftp",
608+
FTP_PORT, ports[i], ports[i], &ftp_exp_policy,
609+
0, sizeof(struct nf_ct_ftp_master), help,
610+
nf_ct_ftp_from_nlattr, THIS_MODULE);
611+
}
612+
613+
ret = nf_conntrack_helpers_register(ftp, ports_c * 2);
614+
if (ret < 0) {
615+
pr_err("failed to register helpers\n");
616+
kfree(ftp_buffer);
617+
return ret;
640618
}
641619

642620
return 0;

net/netfilter/nf_conntrack_helper.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,63 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
465465
}
466466
EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister);
467467

468+
void nf_ct_helper_init(struct nf_conntrack_helper *helper,
469+
u16 l3num, u16 protonum, const char *name,
470+
u16 default_port, u16 spec_port, u32 id,
471+
const struct nf_conntrack_expect_policy *exp_pol,
472+
u32 expect_class_max, u32 data_len,
473+
int (*help)(struct sk_buff *skb, unsigned int protoff,
474+
struct nf_conn *ct,
475+
enum ip_conntrack_info ctinfo),
476+
int (*from_nlattr)(struct nlattr *attr,
477+
struct nf_conn *ct),
478+
struct module *module)
479+
{
480+
helper->tuple.src.l3num = l3num;
481+
helper->tuple.dst.protonum = protonum;
482+
helper->tuple.src.u.all = htons(spec_port);
483+
helper->expect_policy = exp_pol;
484+
helper->expect_class_max = expect_class_max;
485+
helper->data_len = data_len;
486+
helper->help = help;
487+
helper->from_nlattr = from_nlattr;
488+
helper->me = module;
489+
490+
if (spec_port == default_port)
491+
snprintf(helper->name, sizeof(helper->name), "%s", name);
492+
else
493+
snprintf(helper->name, sizeof(helper->name), "%s-%u", name, id);
494+
}
495+
EXPORT_SYMBOL_GPL(nf_ct_helper_init);
496+
497+
int nf_conntrack_helpers_register(struct nf_conntrack_helper *helper,
498+
unsigned int n)
499+
{
500+
unsigned int i;
501+
int err = 0;
502+
503+
for (i = 0; i < n; i++) {
504+
err = nf_conntrack_helper_register(&helper[i]);
505+
if (err < 0)
506+
goto err;
507+
}
508+
509+
return err;
510+
err:
511+
if (i > 0)
512+
nf_conntrack_helpers_unregister(helper, i);
513+
return err;
514+
}
515+
EXPORT_SYMBOL_GPL(nf_conntrack_helpers_register);
516+
517+
void nf_conntrack_helpers_unregister(struct nf_conntrack_helper *helper,
518+
unsigned int n)
519+
{
520+
while (n-- > 0)
521+
nf_conntrack_helper_unregister(&helper[n]);
522+
}
523+
EXPORT_SYMBOL_GPL(nf_conntrack_helpers_unregister);
524+
468525
static struct nf_ct_ext_type helper_extend __read_mostly = {
469526
.len = sizeof(struct nf_conn_help),
470527
.align = __alignof__(struct nf_conn_help),

net/netfilter/nf_conntrack_irc.c

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -255,38 +255,26 @@ static int __init nf_conntrack_irc_init(void)
255255
ports[ports_c++] = IRC_PORT;
256256

257257
for (i = 0; i < ports_c; i++) {
258-
irc[i].tuple.src.l3num = AF_INET;
259-
irc[i].tuple.src.u.tcp.port = htons(ports[i]);
260-
irc[i].tuple.dst.protonum = IPPROTO_TCP;
261-
irc[i].expect_policy = &irc_exp_policy;
262-
irc[i].me = THIS_MODULE;
263-
irc[i].help = help;
264-
265-
if (ports[i] == IRC_PORT)
266-
sprintf(irc[i].name, "irc");
267-
else
268-
sprintf(irc[i].name, "irc-%u", i);
269-
270-
ret = nf_conntrack_helper_register(&irc[i]);
271-
if (ret) {
272-
pr_err("failed to register helper for pf: %u port: %u\n",
273-
irc[i].tuple.src.l3num, ports[i]);
274-
ports_c = i;
275-
nf_conntrack_irc_fini();
276-
return ret;
277-
}
258+
nf_ct_helper_init(&irc[i], AF_INET, IPPROTO_TCP, "irc",
259+
IRC_PORT, ports[i], i, &irc_exp_policy,
260+
0, 0, help, NULL, THIS_MODULE);
261+
}
262+
263+
ret = nf_conntrack_helpers_register(&irc[0], ports_c);
264+
if (ret) {
265+
pr_err("failed to register helpers\n");
266+
kfree(irc_buffer);
267+
return ret;
278268
}
269+
279270
return 0;
280271
}
281272

282273
/* This function is intentionally _NOT_ defined as __exit, because
283274
* it is needed by the init function */
284275
static void nf_conntrack_irc_fini(void)
285276
{
286-
int i;
287-
288-
for (i = 0; i < ports_c; i++)
289-
nf_conntrack_helper_unregister(&irc[i]);
277+
nf_conntrack_helpers_unregister(irc, ports_c);
290278
kfree(irc_buffer);
291279
}
292280

net/netfilter/nf_conntrack_sane.c

Lines changed: 20 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ static int help(struct sk_buff *skb,
166166
return ret;
167167
}
168168

169-
static struct nf_conntrack_helper sane[MAX_PORTS][2] __read_mostly;
169+
static struct nf_conntrack_helper sane[MAX_PORTS * 2] __read_mostly;
170170

171171
static const struct nf_conntrack_expect_policy sane_exp_policy = {
172172
.max_expected = 1,
@@ -176,22 +176,13 @@ static const struct nf_conntrack_expect_policy sane_exp_policy = {
176176
/* don't make this __exit, since it's called from __init ! */
177177
static void nf_conntrack_sane_fini(void)
178178
{
179-
int i, j;
180-
181-
for (i = 0; i < ports_c; i++) {
182-
for (j = 0; j < 2; j++) {
183-
pr_debug("unregistering helper for pf: %d port: %d\n",
184-
sane[i][j].tuple.src.l3num, ports[i]);
185-
nf_conntrack_helper_unregister(&sane[i][j]);
186-
}
187-
}
188-
179+
nf_conntrack_helpers_unregister(sane, ports_c * 2);
189180
kfree(sane_buffer);
190181
}
191182

192183
static int __init nf_conntrack_sane_init(void)
193184
{
194-
int i, j = -1, ret = 0;
185+
int i, ret = 0;
195186

196187
sane_buffer = kmalloc(65536, GFP_KERNEL);
197188
if (!sane_buffer)
@@ -203,31 +194,23 @@ static int __init nf_conntrack_sane_init(void)
203194
/* FIXME should be configurable whether IPv4 and IPv6 connections
204195
are tracked or not - YK */
205196
for (i = 0; i < ports_c; i++) {
206-
sane[i][0].tuple.src.l3num = PF_INET;
207-
sane[i][1].tuple.src.l3num = PF_INET6;
208-
for (j = 0; j < 2; j++) {
209-
sane[i][j].data_len = sizeof(struct nf_ct_sane_master);
210-
sane[i][j].tuple.src.u.tcp.port = htons(ports[i]);
211-
sane[i][j].tuple.dst.protonum = IPPROTO_TCP;
212-
sane[i][j].expect_policy = &sane_exp_policy;
213-
sane[i][j].me = THIS_MODULE;
214-
sane[i][j].help = help;
215-
if (ports[i] == SANE_PORT)
216-
sprintf(sane[i][j].name, "sane");
217-
else
218-
sprintf(sane[i][j].name, "sane-%d", ports[i]);
219-
220-
pr_debug("registering helper for pf: %d port: %d\n",
221-
sane[i][j].tuple.src.l3num, ports[i]);
222-
ret = nf_conntrack_helper_register(&sane[i][j]);
223-
if (ret) {
224-
pr_err("failed to register helper for pf: %d port: %d\n",
225-
sane[i][j].tuple.src.l3num, ports[i]);
226-
ports_c = i;
227-
nf_conntrack_sane_fini();
228-
return ret;
229-
}
230-
}
197+
nf_ct_helper_init(&sane[2 * i], AF_INET, IPPROTO_TCP, "sane",
198+
SANE_PORT, ports[i], ports[i],
199+
&sane_exp_policy, 0,
200+
sizeof(struct nf_ct_sane_master), help, NULL,
201+
THIS_MODULE);
202+
nf_ct_helper_init(&sane[2 * i + 1], AF_INET6, IPPROTO_TCP, "sane",
203+
SANE_PORT, ports[i], ports[i],
204+
&sane_exp_policy, 0,
205+
sizeof(struct nf_ct_sane_master), help, NULL,
206+
THIS_MODULE);
207+
}
208+
209+
ret = nf_conntrack_helpers_register(sane, ports_c * 2);
210+
if (ret < 0) {
211+
pr_err("failed to register helpers\n");
212+
kfree(sane_buffer);
213+
return ret;
231214
}
232215

233216
return 0;

0 commit comments

Comments
 (0)