aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
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/netfilter
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/netfilter')
-rw-r--r--net/netfilter/nf_conntrack_ftp.c77
1 files changed, 43 insertions, 34 deletions
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. */