]> err.no Git - linux-2.6/blobdiff - net/ipv4/netfilter/ip_conntrack_ftp.c
[IPV6]: Don't redo xfrm_lookup for cached dst entries
[linux-2.6] / net / ipv4 / netfilter / ip_conntrack_ftp.c
index fea6dd2a00b6b2db30e2ab348f02b354ff40d443..1b79ec36085ffed8896fdd9882126b24400fd57c 100644 (file)
@@ -25,8 +25,7 @@ MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>");
 MODULE_DESCRIPTION("ftp connection tracking helper");
 
 /* This is slow, but it's simple. --RR */
-static char ftp_buffer[65536];
-
+static char *ftp_buffer;
 static DEFINE_SPINLOCK(ip_ftp_lock);
 
 #define MAX_PORTS 8
@@ -262,7 +261,8 @@ static int find_nl_seq(u32 seq, const struct ip_ct_ftp_master *info, int dir)
 }
 
 /* We don't update if it's older than what we have. */
-static void update_nl_seq(u32 nl_seq, struct ip_ct_ftp_master *info, int dir)
+static void update_nl_seq(u32 nl_seq, struct ip_ct_ftp_master *info, int dir,
+                         struct sk_buff *skb)
 {
        unsigned int i, oldest = NUM_SEQ_TO_REMEMBER;
 
@@ -276,10 +276,13 @@ static void update_nl_seq(u32 nl_seq, struct ip_ct_ftp_master *info, int dir)
                        oldest = i;
        }
 
-       if (info->seq_aft_nl_num[dir] < NUM_SEQ_TO_REMEMBER)
+       if (info->seq_aft_nl_num[dir] < NUM_SEQ_TO_REMEMBER) {
                info->seq_aft_nl[dir][info->seq_aft_nl_num[dir]++] = nl_seq;
-       else if (oldest != NUM_SEQ_TO_REMEMBER)
+               ip_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, skb);
+       } else if (oldest != NUM_SEQ_TO_REMEMBER) {
                info->seq_aft_nl[dir][oldest] = nl_seq;
+               ip_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, skb);
+       }
 }
 
 static int help(struct sk_buff **pskb,
@@ -376,7 +379,7 @@ static int help(struct sk_buff **pskb,
               fb_ptr + matchoff, matchlen, ntohl(th->seq) + matchoff);
                         
        /* Allocate expectation which will be inserted */
-       exp = ip_conntrack_expect_alloc();
+       exp = ip_conntrack_expect_alloc(ct);
        if (exp == NULL) {
                ret = NF_DROP;
                goto out;
@@ -403,8 +406,7 @@ static int help(struct sk_buff **pskb,
                   networks, or the packet filter itself). */
                if (!loose) {
                        ret = NF_ACCEPT;
-                       ip_conntrack_expect_free(exp);
-                       goto out_update_nl;
+                       goto out_put_expect;
                }
                exp->tuple.dst.ip = htonl((array[0] << 24) | (array[1] << 16)
                                         | (array[2] << 8) | array[3]);
@@ -419,7 +421,7 @@ static int help(struct sk_buff **pskb,
                  { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }});
 
        exp->expectfn = NULL;
-       exp->master = ct;
+       exp->flags = 0;
 
        /* Now, NAT might want to mangle the packet, and register the
         * (possibly changed) expectation itself. */
@@ -428,18 +430,20 @@ static int help(struct sk_buff **pskb,
                                      matchoff, matchlen, exp, &seq);
        else {
                /* Can't expect this?  Best to drop packet now. */
-               if (ip_conntrack_expect_related(exp) != 0) {
-                       ip_conntrack_expect_free(exp);
+               if (ip_conntrack_expect_related(exp) != 0)
                        ret = NF_DROP;
-               else
+               else
                        ret = NF_ACCEPT;
        }
 
+out_put_expect:
+       ip_conntrack_expect_put(exp);
+
 out_update_nl:
        /* Now if this ends in \n, update ftp info.  Seq may have been
         * adjusted by NAT code. */
        if (ends_in_nl)
-               update_nl_seq(seq, ct_ftp_info,dir);
+               update_nl_seq(seq, ct_ftp_info,dir, *pskb);
  out:
        spin_unlock_bh(&ip_ftp_lock);
        return ret;
@@ -457,6 +461,8 @@ static void fini(void)
                                ports[i]);
                ip_conntrack_helper_unregister(&ftp[i]);
        }
+
+       kfree(ftp_buffer);
 }
 
 static int __init init(void)
@@ -464,6 +470,10 @@ static int __init init(void)
        int i, ret;
        char *tmpname;
 
+       ftp_buffer = kmalloc(65536, GFP_KERNEL);
+       if (!ftp_buffer)
+               return -ENOMEM;
+
        if (ports_c == 0)
                ports[ports_c++] = FTP_PORT;