aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2006-05-29 21:25:38 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-06-18 00:29:07 -0400
commit7d8c50181778b6ba10c2bba9a2f22db9493bb245 (patch)
treeb0a87854e0c377eccca3849351951d5456687729 /net
parent695ecea3299dba2239d1cb4fd4d4e4c95a5b9ce7 (diff)
[NETFILTER]: FTP helper: search optimization
Instead of skipping search entries for the wrong direction simply index them by direction. Based on patch by Pablo Neira <pablo@netfilter.org> Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/netfilter/ip_conntrack_ftp.c77
-rw-r--r--net/netfilter/nf_conntrack_ftp.c77
2 files changed, 86 insertions, 68 deletions
diff --git a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c
index 3e542bf28a9..4dcf526c394 100644
--- a/net/ipv4/netfilter/ip_conntrack_ftp.c
+++ b/net/ipv4/netfilter/ip_conntrack_ftp.c
@@ -56,37 +56,48 @@ static int try_eprt(const char *, size_t, u_int32_t [], char);
56static int try_epsv_response(const char *, size_t, u_int32_t [], char); 56static int try_epsv_response(const char *, size_t, u_int32_t [], char);
57 57
58static const struct ftp_search { 58static const struct ftp_search {
59 enum ip_conntrack_dir dir;
60 const char *pattern; 59 const char *pattern;
61 size_t plen; 60 size_t plen;
62 char skip; 61 char skip;
63 char term; 62 char term;
64 enum ip_ct_ftp_type ftptype; 63 enum ip_ct_ftp_type ftptype;
65 int (*getnum)(const char *, size_t, u_int32_t[], char); 64 int (*getnum)(const char *, size_t, u_int32_t[], char);
66} search[] = { 65} search[IP_CT_DIR_MAX][2] = {
67 { 66 [IP_CT_DIR_ORIGINAL] = {
68 IP_CT_DIR_ORIGINAL, 67 {
69 "PORT", sizeof("PORT") - 1, ' ', '\r', 68 .pattern = "PORT",
70 IP_CT_FTP_PORT, 69 .plen = sizeof("PORT") - 1,
71 try_rfc959, 70 .skip = ' ',
71 .term = '\r',
72 .ftptype = IP_CT_FTP_PORT,
73 .getnum = try_rfc959,
74 },
75 {
76 .pattern = "EPRT",
77 .plen = sizeof("EPRT") - 1,
78 .skip = ' ',
79 .term = '\r',
80 .ftptype = IP_CT_FTP_EPRT,
81 .getnum = try_eprt,
82 },
72 }, 83 },
73 { 84 [IP_CT_DIR_REPLY] = {
74 IP_CT_DIR_REPLY, 85 {
75 "227 ", sizeof("227 ") - 1, '(', ')', 86 .pattern = "227 ",
76 IP_CT_FTP_PASV, 87 .plen = sizeof("227 ") - 1,
77 try_rfc959, 88 .skip = '(',
78 }, 89 .term = ')',
79 { 90 .ftptype = IP_CT_FTP_PASV,
80 IP_CT_DIR_ORIGINAL, 91 .getnum = try_rfc959,
81 "EPRT", sizeof("EPRT") - 1, ' ', '\r', 92 },
82 IP_CT_FTP_EPRT, 93 {
83 try_eprt, 94 .pattern = "229 ",
84 }, 95 .plen = sizeof("229 ") - 1,
85 { 96 .skip = '(',
86 IP_CT_DIR_REPLY, 97 .term = ')',
87 "229 ", sizeof("229 ") - 1, '(', ')', 98 .ftptype = IP_CT_FTP_EPSV,
88 IP_CT_FTP_EPSV, 99 .getnum = try_epsv_response,
89 try_epsv_response, 100 },
90 }, 101 },
91}; 102};
92 103
@@ -346,17 +357,15 @@ static int help(struct sk_buff **pskb,
346 array[2] = (ntohl(ct->tuplehash[dir].tuple.src.ip) >> 8) & 0xFF; 357 array[2] = (ntohl(ct->tuplehash[dir].tuple.src.ip) >> 8) & 0xFF;
347 array[3] = ntohl(ct->tuplehash[dir].tuple.src.ip) & 0xFF; 358 array[3] = ntohl(ct->tuplehash[dir].tuple.src.ip) & 0xFF;
348 359
349 for (i = 0; i < ARRAY_SIZE(search); i++) { 360 for (i = 0; i < ARRAY_SIZE(search[dir]); i++) {
350 if (search[i].dir != dir) continue;
351
352 found = find_pattern(fb_ptr, (*pskb)->len - dataoff, 361 found = find_pattern(fb_ptr, (*pskb)->len - dataoff,
353 search[i].pattern, 362 search[dir][i].pattern,
354 search[i].plen, 363 search[dir][i].plen,
355 search[i].skip, 364 search[dir][i].skip,
356 search[i].term, 365 search[dir][i].term,
357 &matchoff, &matchlen, 366 &matchoff, &matchlen,
358 array, 367 array,
359 search[i].getnum); 368 search[dir][i].getnum);
360 if (found) break; 369 if (found) break;
361 } 370 }
362 if (found == -1) { 371 if (found == -1) {
@@ -366,7 +375,7 @@ static int help(struct sk_buff **pskb,
366 this case. */ 375 this case. */
367 if (net_ratelimit()) 376 if (net_ratelimit())
368 printk("conntrack_ftp: partial %s %u+%u\n", 377 printk("conntrack_ftp: partial %s %u+%u\n",
369 search[i].pattern, 378 search[dir][i].pattern,
370 ntohl(th->seq), datalen); 379 ntohl(th->seq), datalen);
371 ret = NF_DROP; 380 ret = NF_DROP;
372 goto out; 381 goto out;
@@ -426,7 +435,7 @@ static int help(struct sk_buff **pskb,
426 /* Now, NAT might want to mangle the packet, and register the 435 /* Now, NAT might want to mangle the packet, and register the
427 * (possibly changed) expectation itself. */ 436 * (possibly changed) expectation itself. */
428 if (ip_nat_ftp_hook) 437 if (ip_nat_ftp_hook)
429 ret = ip_nat_ftp_hook(pskb, ctinfo, search[i].ftptype, 438 ret = ip_nat_ftp_hook(pskb, ctinfo, search[dir][i].ftptype,
430 matchoff, matchlen, exp, &seq); 439 matchoff, matchlen, exp, &seq);
431 else { 440 else {
432 /* Can't expect this? Best to drop packet now. */ 441 /* Can't expect this? Best to drop packet now. */
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index e38a4b5a308..11d3be24353 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -67,37 +67,48 @@ static int try_epsv_response(const char *, size_t, struct nf_conntrack_man *,
67 char); 67 char);
68 68
69static struct ftp_search { 69static struct ftp_search {
70 enum ip_conntrack_dir dir;
71 const char *pattern; 70 const char *pattern;
72 size_t plen; 71 size_t plen;
73 char skip; 72 char skip;
74 char term; 73 char term;
75 enum ip_ct_ftp_type ftptype; 74 enum ip_ct_ftp_type ftptype;
76 int (*getnum)(const char *, size_t, struct nf_conntrack_man *, char); 75 int (*getnum)(const char *, size_t, struct nf_conntrack_man *, char);
77} search[] = { 76} search[IP_CT_DIR_MAX][2] = {
78 { 77 [IP_CT_DIR_ORIGINAL] = {
79 IP_CT_DIR_ORIGINAL, 78 {
80 "PORT", sizeof("PORT") - 1, ' ', '\r', 79 .pattern = "PORT",
81 IP_CT_FTP_PORT, 80 .plen = sizeof("PORT") - 1,
82 try_rfc959, 81 .skip = ' ',
82 .term = '\r',
83 .ftptype = IP_CT_FTP_PORT,
84 .getnum = try_rfc959,
85 },
86 {
87 .pattern = "EPRT",
88 .plen = sizeof("EPRT") - 1,
89 .skip = ' ',
90 .term = '\r',
91 .ftptype = IP_CT_FTP_EPRT,
92 .getnum = try_eprt,
93 },
83 }, 94 },
84 { 95 [IP_CT_DIR_REPLY] = {
85 IP_CT_DIR_REPLY, 96 {
86 "227 ", sizeof("227 ") - 1, '(', ')', 97 .pattern = "227 ",
87 IP_CT_FTP_PASV, 98 .plen = sizeof("227 ") - 1,
88 try_rfc959, 99 .skip = '(',
89 }, 100 .term = ')',
90 { 101 .ftptype = IP_CT_FTP_PASV,
91 IP_CT_DIR_ORIGINAL, 102 .getnum = try_rfc959,
92 "EPRT", sizeof("EPRT") - 1, ' ', '\r', 103 },
93 IP_CT_FTP_EPRT, 104 {
94 try_eprt, 105 .pattern = "229 ",
95 }, 106 .plen = sizeof("229 ") - 1,
96 { 107 .skip = '(',
97 IP_CT_DIR_REPLY, 108 .term = ')',
98 "229 ", sizeof("229 ") - 1, '(', ')', 109 .ftptype = IP_CT_FTP_EPSV,
99 IP_CT_FTP_EPSV, 110 .getnum = try_epsv_response,
100 try_epsv_response, 111 },
101 }, 112 },
102}; 113};
103 114
@@ -492,17 +503,15 @@ static int help(struct sk_buff **pskb,
492 memcpy(cmd.u3.all, &ct->tuplehash[dir].tuple.src.u3.all, 503 memcpy(cmd.u3.all, &ct->tuplehash[dir].tuple.src.u3.all,
493 sizeof(cmd.u3.all)); 504 sizeof(cmd.u3.all));
494 505
495 for (i = 0; i < ARRAY_SIZE(search); i++) { 506 for (i = 0; i < ARRAY_SIZE(search[dir]); i++) {
496 if (search[i].dir != dir) continue;
497
498 found = find_pattern(fb_ptr, datalen, 507 found = find_pattern(fb_ptr, datalen,
499 search[i].pattern, 508 search[dir][i].pattern,
500 search[i].plen, 509 search[dir][i].plen,
501 search[i].skip, 510 search[dir][i].skip,
502 search[i].term, 511 search[dir][i].term,
503 &matchoff, &matchlen, 512 &matchoff, &matchlen,
504 &cmd, 513 &cmd,
505 search[i].getnum); 514 search[dir][i].getnum);
506 if (found) break; 515 if (found) break;
507 } 516 }
508 if (found == -1) { 517 if (found == -1) {
@@ -512,7 +521,7 @@ static int help(struct sk_buff **pskb,
512 this case. */ 521 this case. */
513 if (net_ratelimit()) 522 if (net_ratelimit())
514 printk("conntrack_ftp: partial %s %u+%u\n", 523 printk("conntrack_ftp: partial %s %u+%u\n",
515 search[i].pattern, 524 search[dir][i].pattern,
516 ntohl(th->seq), datalen); 525 ntohl(th->seq), datalen);
517 ret = NF_DROP; 526 ret = NF_DROP;
518 goto out; 527 goto out;
@@ -597,7 +606,7 @@ static int help(struct sk_buff **pskb,
597 /* Now, NAT might want to mangle the packet, and register the 606 /* Now, NAT might want to mangle the packet, and register the
598 * (possibly changed) expectation itself. */ 607 * (possibly changed) expectation itself. */
599 if (nf_nat_ftp_hook) 608 if (nf_nat_ftp_hook)
600 ret = nf_nat_ftp_hook(pskb, ctinfo, search[i].ftptype, 609 ret = nf_nat_ftp_hook(pskb, ctinfo, search[dir][i].ftptype,
601 matchoff, matchlen, exp, &seq); 610 matchoff, matchlen, exp, &seq);
602 else { 611 else {
603 /* Can't expect this? Best to drop packet now. */ 612 /* Can't expect this? Best to drop packet now. */