diff options
-rw-r--r-- | include/linux/netfilter_ipv4/ip_conntrack.h | 3 | ||||
-rw-r--r-- | include/linux/netfilter_ipv4/ip_conntrack_helper.h | 7 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_amanda.c | 8 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_core.c | 40 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_ftp.c | 14 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_irc.c | 8 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_standalone.c | 2 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_tftp.c | 8 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_nat_amanda.c | 4 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_nat_ftp.c | 4 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_nat_irc.c | 4 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_nat_tftp.c | 4 |
12 files changed, 46 insertions, 60 deletions
diff --git a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h index 3781192ce159..f8da7ddeff3a 100644 --- a/include/linux/netfilter_ipv4/ip_conntrack.h +++ b/include/linux/netfilter_ipv4/ip_conntrack.h | |||
@@ -197,6 +197,9 @@ struct ip_conntrack_expect | |||
197 | /* Timer function; deletes the expectation. */ | 197 | /* Timer function; deletes the expectation. */ |
198 | struct timer_list timeout; | 198 | struct timer_list timeout; |
199 | 199 | ||
200 | /* Usage count. */ | ||
201 | atomic_t use; | ||
202 | |||
200 | #ifdef CONFIG_IP_NF_NAT_NEEDED | 203 | #ifdef CONFIG_IP_NF_NAT_NEEDED |
201 | /* This is the original per-proto part, used to map the | 204 | /* This is the original per-proto part, used to map the |
202 | * expected connection the way the recipient expects. */ | 205 | * expected connection the way the recipient expects. */ |
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_helper.h b/include/linux/netfilter_ipv4/ip_conntrack_helper.h index b1bbba0a12cb..3692daa93dec 100644 --- a/include/linux/netfilter_ipv4/ip_conntrack_helper.h +++ b/include/linux/netfilter_ipv4/ip_conntrack_helper.h | |||
@@ -30,9 +30,10 @@ extern int ip_conntrack_helper_register(struct ip_conntrack_helper *); | |||
30 | extern void ip_conntrack_helper_unregister(struct ip_conntrack_helper *); | 30 | extern void ip_conntrack_helper_unregister(struct ip_conntrack_helper *); |
31 | 31 | ||
32 | /* Allocate space for an expectation: this is mandatory before calling | 32 | /* Allocate space for an expectation: this is mandatory before calling |
33 | ip_conntrack_expect_related. */ | 33 | ip_conntrack_expect_related. You will have to call put afterwards. */ |
34 | extern struct ip_conntrack_expect *ip_conntrack_expect_alloc(void); | 34 | extern struct ip_conntrack_expect * |
35 | extern void ip_conntrack_expect_free(struct ip_conntrack_expect *exp); | 35 | ip_conntrack_expect_alloc(struct ip_conntrack *master); |
36 | extern void ip_conntrack_expect_put(struct ip_conntrack_expect *exp); | ||
36 | 37 | ||
37 | /* Add an expected connection: can have more than one per connection */ | 38 | /* Add an expected connection: can have more than one per connection */ |
38 | extern int ip_conntrack_expect_related(struct ip_conntrack_expect *exp); | 39 | extern int ip_conntrack_expect_related(struct ip_conntrack_expect *exp); |
diff --git a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c index a78a320eee08..01e1b58322a9 100644 --- a/net/ipv4/netfilter/ip_conntrack_amanda.c +++ b/net/ipv4/netfilter/ip_conntrack_amanda.c | |||
@@ -101,14 +101,13 @@ static int help(struct sk_buff **pskb, | |||
101 | if (port == 0 || len > 5) | 101 | if (port == 0 || len > 5) |
102 | break; | 102 | break; |
103 | 103 | ||
104 | exp = ip_conntrack_expect_alloc(); | 104 | exp = ip_conntrack_expect_alloc(ct); |
105 | if (exp == NULL) { | 105 | if (exp == NULL) { |
106 | ret = NF_DROP; | 106 | ret = NF_DROP; |
107 | goto out; | 107 | goto out; |
108 | } | 108 | } |
109 | 109 | ||
110 | exp->expectfn = NULL; | 110 | exp->expectfn = NULL; |
111 | exp->master = ct; | ||
112 | 111 | ||
113 | exp->tuple.src.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; | 112 | exp->tuple.src.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; |
114 | exp->tuple.src.u.tcp.port = 0; | 113 | exp->tuple.src.u.tcp.port = 0; |
@@ -126,10 +125,9 @@ static int help(struct sk_buff **pskb, | |||
126 | ret = ip_nat_amanda_hook(pskb, ctinfo, | 125 | ret = ip_nat_amanda_hook(pskb, ctinfo, |
127 | tmp - amanda_buffer, | 126 | tmp - amanda_buffer, |
128 | len, exp); | 127 | len, exp); |
129 | else if (ip_conntrack_expect_related(exp) != 0) { | 128 | else if (ip_conntrack_expect_related(exp) != 0) |
130 | ip_conntrack_expect_free(exp); | ||
131 | ret = NF_DROP; | 129 | ret = NF_DROP; |
132 | } | 130 | ip_conntrack_expect_put(exp); |
133 | } | 131 | } |
134 | 132 | ||
135 | out: | 133 | out: |
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index 4b78ebeb6635..14af55cad5d6 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c | |||
@@ -137,19 +137,12 @@ ip_ct_invert_tuple(struct ip_conntrack_tuple *inverse, | |||
137 | 137 | ||
138 | 138 | ||
139 | /* ip_conntrack_expect helper functions */ | 139 | /* ip_conntrack_expect helper functions */ |
140 | static void destroy_expect(struct ip_conntrack_expect *exp) | ||
141 | { | ||
142 | ip_conntrack_put(exp->master); | ||
143 | IP_NF_ASSERT(!timer_pending(&exp->timeout)); | ||
144 | kmem_cache_free(ip_conntrack_expect_cachep, exp); | ||
145 | CONNTRACK_STAT_INC(expect_delete); | ||
146 | } | ||
147 | |||
148 | static void unlink_expect(struct ip_conntrack_expect *exp) | 140 | static void unlink_expect(struct ip_conntrack_expect *exp) |
149 | { | 141 | { |
150 | ASSERT_WRITE_LOCK(&ip_conntrack_lock); | 142 | ASSERT_WRITE_LOCK(&ip_conntrack_lock); |
143 | IP_NF_ASSERT(!timer_pending(&exp->timeout)); | ||
151 | list_del(&exp->list); | 144 | list_del(&exp->list); |
152 | /* Logically in destroy_expect, but we hold the lock here. */ | 145 | CONNTRACK_STAT_INC(expect_delete); |
153 | exp->master->expecting--; | 146 | exp->master->expecting--; |
154 | } | 147 | } |
155 | 148 | ||
@@ -160,7 +153,7 @@ static void expectation_timed_out(unsigned long ul_expect) | |||
160 | write_lock_bh(&ip_conntrack_lock); | 153 | write_lock_bh(&ip_conntrack_lock); |
161 | unlink_expect(exp); | 154 | unlink_expect(exp); |
162 | write_unlock_bh(&ip_conntrack_lock); | 155 | write_unlock_bh(&ip_conntrack_lock); |
163 | destroy_expect(exp); | 156 | ip_conntrack_expect_put(exp); |
164 | } | 157 | } |
165 | 158 | ||
166 | /* If an expectation for this connection is found, it gets delete from | 159 | /* If an expectation for this connection is found, it gets delete from |
@@ -198,7 +191,7 @@ static void remove_expectations(struct ip_conntrack *ct) | |||
198 | list_for_each_entry_safe(i, tmp, &ip_conntrack_expect_list, list) { | 191 | list_for_each_entry_safe(i, tmp, &ip_conntrack_expect_list, list) { |
199 | if (i->master == ct && del_timer(&i->timeout)) { | 192 | if (i->master == ct && del_timer(&i->timeout)) { |
200 | unlink_expect(i); | 193 | unlink_expect(i); |
201 | destroy_expect(i); | 194 | ip_conntrack_expect_put(i); |
202 | } | 195 | } |
203 | } | 196 | } |
204 | } | 197 | } |
@@ -537,7 +530,7 @@ init_conntrack(const struct ip_conntrack_tuple *tuple, | |||
537 | if (exp) { | 530 | if (exp) { |
538 | if (exp->expectfn) | 531 | if (exp->expectfn) |
539 | exp->expectfn(conntrack, exp); | 532 | exp->expectfn(conntrack, exp); |
540 | destroy_expect(exp); | 533 | ip_conntrack_expect_put(exp); |
541 | } | 534 | } |
542 | 535 | ||
543 | return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL]; | 536 | return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL]; |
@@ -729,14 +722,14 @@ void ip_conntrack_unexpect_related(struct ip_conntrack_expect *exp) | |||
729 | if (expect_matches(i, exp) && del_timer(&i->timeout)) { | 722 | if (expect_matches(i, exp) && del_timer(&i->timeout)) { |
730 | unlink_expect(i); | 723 | unlink_expect(i); |
731 | write_unlock_bh(&ip_conntrack_lock); | 724 | write_unlock_bh(&ip_conntrack_lock); |
732 | destroy_expect(i); | 725 | ip_conntrack_expect_put(i); |
733 | return; | 726 | return; |
734 | } | 727 | } |
735 | } | 728 | } |
736 | write_unlock_bh(&ip_conntrack_lock); | 729 | write_unlock_bh(&ip_conntrack_lock); |
737 | } | 730 | } |
738 | 731 | ||
739 | struct ip_conntrack_expect *ip_conntrack_expect_alloc(void) | 732 | struct ip_conntrack_expect *ip_conntrack_expect_alloc(struct ip_conntrack *me) |
740 | { | 733 | { |
741 | struct ip_conntrack_expect *new; | 734 | struct ip_conntrack_expect *new; |
742 | 735 | ||
@@ -745,18 +738,23 @@ struct ip_conntrack_expect *ip_conntrack_expect_alloc(void) | |||
745 | DEBUGP("expect_related: OOM allocating expect\n"); | 738 | DEBUGP("expect_related: OOM allocating expect\n"); |
746 | return NULL; | 739 | return NULL; |
747 | } | 740 | } |
748 | new->master = NULL; | 741 | new->master = me; |
742 | atomic_inc(&new->master->ct_general.use); | ||
743 | atomic_set(&new->use, 1); | ||
749 | return new; | 744 | return new; |
750 | } | 745 | } |
751 | 746 | ||
752 | void ip_conntrack_expect_free(struct ip_conntrack_expect *expect) | 747 | void ip_conntrack_expect_put(struct ip_conntrack_expect *exp) |
753 | { | 748 | { |
754 | kmem_cache_free(ip_conntrack_expect_cachep, expect); | 749 | if (atomic_dec_and_test(&exp->use)) { |
750 | ip_conntrack_put(exp->master); | ||
751 | kmem_cache_free(ip_conntrack_expect_cachep, exp); | ||
752 | } | ||
755 | } | 753 | } |
756 | 754 | ||
757 | static void ip_conntrack_expect_insert(struct ip_conntrack_expect *exp) | 755 | static void ip_conntrack_expect_insert(struct ip_conntrack_expect *exp) |
758 | { | 756 | { |
759 | atomic_inc(&exp->master->ct_general.use); | 757 | atomic_inc(&exp->use); |
760 | exp->master->expecting++; | 758 | exp->master->expecting++; |
761 | list_add(&exp->list, &ip_conntrack_expect_list); | 759 | list_add(&exp->list, &ip_conntrack_expect_list); |
762 | 760 | ||
@@ -778,7 +776,7 @@ static void evict_oldest_expect(struct ip_conntrack *master) | |||
778 | if (i->master == master) { | 776 | if (i->master == master) { |
779 | if (del_timer(&i->timeout)) { | 777 | if (del_timer(&i->timeout)) { |
780 | unlink_expect(i); | 778 | unlink_expect(i); |
781 | destroy_expect(i); | 779 | ip_conntrack_expect_put(i); |
782 | } | 780 | } |
783 | break; | 781 | break; |
784 | } | 782 | } |
@@ -810,8 +808,6 @@ int ip_conntrack_expect_related(struct ip_conntrack_expect *expect) | |||
810 | /* Refresh timer: if it's dying, ignore.. */ | 808 | /* Refresh timer: if it's dying, ignore.. */ |
811 | if (refresh_timer(i)) { | 809 | if (refresh_timer(i)) { |
812 | ret = 0; | 810 | ret = 0; |
813 | /* We don't need the one they've given us. */ | ||
814 | ip_conntrack_expect_free(expect); | ||
815 | goto out; | 811 | goto out; |
816 | } | 812 | } |
817 | } else if (expect_clash(i, expect)) { | 813 | } else if (expect_clash(i, expect)) { |
@@ -881,7 +877,7 @@ void ip_conntrack_helper_unregister(struct ip_conntrack_helper *me) | |||
881 | list_for_each_entry_safe(exp, tmp, &ip_conntrack_expect_list, list) { | 877 | list_for_each_entry_safe(exp, tmp, &ip_conntrack_expect_list, list) { |
882 | if (exp->master->helper == me && del_timer(&exp->timeout)) { | 878 | if (exp->master->helper == me && del_timer(&exp->timeout)) { |
883 | unlink_expect(exp); | 879 | unlink_expect(exp); |
884 | destroy_expect(exp); | 880 | ip_conntrack_expect_put(exp); |
885 | } | 881 | } |
886 | } | 882 | } |
887 | /* Get rid of expecteds, set helpers to NULL. */ | 883 | /* Get rid of expecteds, set helpers to NULL. */ |
diff --git a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c index fea6dd2a00b6..7a3b773be3f9 100644 --- a/net/ipv4/netfilter/ip_conntrack_ftp.c +++ b/net/ipv4/netfilter/ip_conntrack_ftp.c | |||
@@ -376,7 +376,7 @@ static int help(struct sk_buff **pskb, | |||
376 | fb_ptr + matchoff, matchlen, ntohl(th->seq) + matchoff); | 376 | fb_ptr + matchoff, matchlen, ntohl(th->seq) + matchoff); |
377 | 377 | ||
378 | /* Allocate expectation which will be inserted */ | 378 | /* Allocate expectation which will be inserted */ |
379 | exp = ip_conntrack_expect_alloc(); | 379 | exp = ip_conntrack_expect_alloc(ct); |
380 | if (exp == NULL) { | 380 | if (exp == NULL) { |
381 | ret = NF_DROP; | 381 | ret = NF_DROP; |
382 | goto out; | 382 | goto out; |
@@ -403,8 +403,7 @@ static int help(struct sk_buff **pskb, | |||
403 | networks, or the packet filter itself). */ | 403 | networks, or the packet filter itself). */ |
404 | if (!loose) { | 404 | if (!loose) { |
405 | ret = NF_ACCEPT; | 405 | ret = NF_ACCEPT; |
406 | ip_conntrack_expect_free(exp); | 406 | goto out_put_expect; |
407 | goto out_update_nl; | ||
408 | } | 407 | } |
409 | exp->tuple.dst.ip = htonl((array[0] << 24) | (array[1] << 16) | 408 | exp->tuple.dst.ip = htonl((array[0] << 24) | (array[1] << 16) |
410 | | (array[2] << 8) | array[3]); | 409 | | (array[2] << 8) | array[3]); |
@@ -419,7 +418,6 @@ static int help(struct sk_buff **pskb, | |||
419 | { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }}); | 418 | { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }}); |
420 | 419 | ||
421 | exp->expectfn = NULL; | 420 | exp->expectfn = NULL; |
422 | exp->master = ct; | ||
423 | 421 | ||
424 | /* Now, NAT might want to mangle the packet, and register the | 422 | /* Now, NAT might want to mangle the packet, and register the |
425 | * (possibly changed) expectation itself. */ | 423 | * (possibly changed) expectation itself. */ |
@@ -428,13 +426,15 @@ static int help(struct sk_buff **pskb, | |||
428 | matchoff, matchlen, exp, &seq); | 426 | matchoff, matchlen, exp, &seq); |
429 | else { | 427 | else { |
430 | /* Can't expect this? Best to drop packet now. */ | 428 | /* Can't expect this? Best to drop packet now. */ |
431 | if (ip_conntrack_expect_related(exp) != 0) { | 429 | if (ip_conntrack_expect_related(exp) != 0) |
432 | ip_conntrack_expect_free(exp); | ||
433 | ret = NF_DROP; | 430 | ret = NF_DROP; |
434 | } else | 431 | else |
435 | ret = NF_ACCEPT; | 432 | ret = NF_ACCEPT; |
436 | } | 433 | } |
437 | 434 | ||
435 | out_put_expect: | ||
436 | ip_conntrack_expect_put(exp); | ||
437 | |||
438 | out_update_nl: | 438 | out_update_nl: |
439 | /* Now if this ends in \n, update ftp info. Seq may have been | 439 | /* Now if this ends in \n, update ftp info. Seq may have been |
440 | * adjusted by NAT code. */ | 440 | * adjusted by NAT code. */ |
diff --git a/net/ipv4/netfilter/ip_conntrack_irc.c b/net/ipv4/netfilter/ip_conntrack_irc.c index cd98772cc332..4a28f297d502 100644 --- a/net/ipv4/netfilter/ip_conntrack_irc.c +++ b/net/ipv4/netfilter/ip_conntrack_irc.c | |||
@@ -197,7 +197,7 @@ static int help(struct sk_buff **pskb, | |||
197 | continue; | 197 | continue; |
198 | } | 198 | } |
199 | 199 | ||
200 | exp = ip_conntrack_expect_alloc(); | 200 | exp = ip_conntrack_expect_alloc(ct); |
201 | if (exp == NULL) { | 201 | if (exp == NULL) { |
202 | ret = NF_DROP; | 202 | ret = NF_DROP; |
203 | goto out; | 203 | goto out; |
@@ -221,16 +221,14 @@ static int help(struct sk_buff **pskb, | |||
221 | { { 0, { 0 } }, | 221 | { { 0, { 0 } }, |
222 | { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }}); | 222 | { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }}); |
223 | exp->expectfn = NULL; | 223 | exp->expectfn = NULL; |
224 | exp->master = ct; | ||
225 | if (ip_nat_irc_hook) | 224 | if (ip_nat_irc_hook) |
226 | ret = ip_nat_irc_hook(pskb, ctinfo, | 225 | ret = ip_nat_irc_hook(pskb, ctinfo, |
227 | addr_beg_p - ib_ptr, | 226 | addr_beg_p - ib_ptr, |
228 | addr_end_p - addr_beg_p, | 227 | addr_end_p - addr_beg_p, |
229 | exp); | 228 | exp); |
230 | else if (ip_conntrack_expect_related(exp) != 0) { | 229 | else if (ip_conntrack_expect_related(exp) != 0) |
231 | ip_conntrack_expect_free(exp); | ||
232 | ret = NF_DROP; | 230 | ret = NF_DROP; |
233 | } | 231 | ip_conntrack_expect_put(exp); |
234 | goto out; | 232 | goto out; |
235 | } /* for .. NUM_DCCPROTO */ | 233 | } /* for .. NUM_DCCPROTO */ |
236 | } /* while data < ... */ | 234 | } /* while data < ... */ |
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c index 1dd824f3cf0a..61798c46e91d 100644 --- a/net/ipv4/netfilter/ip_conntrack_standalone.c +++ b/net/ipv4/netfilter/ip_conntrack_standalone.c | |||
@@ -985,7 +985,7 @@ EXPORT_SYMBOL(ip_ct_refresh_acct); | |||
985 | EXPORT_SYMBOL(ip_ct_protos); | 985 | EXPORT_SYMBOL(ip_ct_protos); |
986 | EXPORT_SYMBOL(ip_ct_find_proto); | 986 | EXPORT_SYMBOL(ip_ct_find_proto); |
987 | EXPORT_SYMBOL(ip_conntrack_expect_alloc); | 987 | EXPORT_SYMBOL(ip_conntrack_expect_alloc); |
988 | EXPORT_SYMBOL(ip_conntrack_expect_free); | 988 | EXPORT_SYMBOL(ip_conntrack_expect_put); |
989 | EXPORT_SYMBOL(ip_conntrack_expect_related); | 989 | EXPORT_SYMBOL(ip_conntrack_expect_related); |
990 | EXPORT_SYMBOL(ip_conntrack_unexpect_related); | 990 | EXPORT_SYMBOL(ip_conntrack_unexpect_related); |
991 | EXPORT_SYMBOL(ip_conntrack_tuple_taken); | 991 | EXPORT_SYMBOL(ip_conntrack_tuple_taken); |
diff --git a/net/ipv4/netfilter/ip_conntrack_tftp.c b/net/ipv4/netfilter/ip_conntrack_tftp.c index 992fac3e36ee..f8ff170f390a 100644 --- a/net/ipv4/netfilter/ip_conntrack_tftp.c +++ b/net/ipv4/netfilter/ip_conntrack_tftp.c | |||
@@ -65,7 +65,7 @@ static int tftp_help(struct sk_buff **pskb, | |||
65 | DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); | 65 | DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); |
66 | DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); | 66 | DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); |
67 | 67 | ||
68 | exp = ip_conntrack_expect_alloc(); | 68 | exp = ip_conntrack_expect_alloc(ct); |
69 | if (exp == NULL) | 69 | if (exp == NULL) |
70 | return NF_DROP; | 70 | return NF_DROP; |
71 | 71 | ||
@@ -75,17 +75,15 @@ static int tftp_help(struct sk_buff **pskb, | |||
75 | exp->mask.dst.u.udp.port = 0xffff; | 75 | exp->mask.dst.u.udp.port = 0xffff; |
76 | exp->mask.dst.protonum = 0xff; | 76 | exp->mask.dst.protonum = 0xff; |
77 | exp->expectfn = NULL; | 77 | exp->expectfn = NULL; |
78 | exp->master = ct; | ||
79 | 78 | ||
80 | DEBUGP("expect: "); | 79 | DEBUGP("expect: "); |
81 | DUMP_TUPLE(&exp->tuple); | 80 | DUMP_TUPLE(&exp->tuple); |
82 | DUMP_TUPLE(&exp->mask); | 81 | DUMP_TUPLE(&exp->mask); |
83 | if (ip_nat_tftp_hook) | 82 | if (ip_nat_tftp_hook) |
84 | ret = ip_nat_tftp_hook(pskb, ctinfo, exp); | 83 | ret = ip_nat_tftp_hook(pskb, ctinfo, exp); |
85 | else if (ip_conntrack_expect_related(exp) != 0) { | 84 | else if (ip_conntrack_expect_related(exp) != 0) |
86 | ip_conntrack_expect_free(exp); | ||
87 | ret = NF_DROP; | 85 | ret = NF_DROP; |
88 | } | 86 | ip_conntrack_expect_put(exp); |
89 | break; | 87 | break; |
90 | case TFTP_OPCODE_DATA: | 88 | case TFTP_OPCODE_DATA: |
91 | case TFTP_OPCODE_ACK: | 89 | case TFTP_OPCODE_ACK: |
diff --git a/net/ipv4/netfilter/ip_nat_amanda.c b/net/ipv4/netfilter/ip_nat_amanda.c index da1f412583ed..706c8074f422 100644 --- a/net/ipv4/netfilter/ip_nat_amanda.c +++ b/net/ipv4/netfilter/ip_nat_amanda.c | |||
@@ -56,10 +56,8 @@ static unsigned int help(struct sk_buff **pskb, | |||
56 | break; | 56 | break; |
57 | } | 57 | } |
58 | 58 | ||
59 | if (port == 0) { | 59 | if (port == 0) |
60 | ip_conntrack_expect_free(exp); | ||
61 | return NF_DROP; | 60 | return NF_DROP; |
62 | } | ||
63 | 61 | ||
64 | sprintf(buffer, "%u", port); | 62 | sprintf(buffer, "%u", port); |
65 | ret = ip_nat_mangle_udp_packet(pskb, exp->master, ctinfo, | 63 | ret = ip_nat_mangle_udp_packet(pskb, exp->master, ctinfo, |
diff --git a/net/ipv4/netfilter/ip_nat_ftp.c b/net/ipv4/netfilter/ip_nat_ftp.c index c6000e794ad6..d83757a70d9f 100644 --- a/net/ipv4/netfilter/ip_nat_ftp.c +++ b/net/ipv4/netfilter/ip_nat_ftp.c | |||
@@ -143,10 +143,8 @@ static unsigned int ip_nat_ftp(struct sk_buff **pskb, | |||
143 | break; | 143 | break; |
144 | } | 144 | } |
145 | 145 | ||
146 | if (port == 0) { | 146 | if (port == 0) |
147 | ip_conntrack_expect_free(exp); | ||
148 | return NF_DROP; | 147 | return NF_DROP; |
149 | } | ||
150 | 148 | ||
151 | if (!mangle[type](pskb, newip, port, matchoff, matchlen, ct, ctinfo, | 149 | if (!mangle[type](pskb, newip, port, matchoff, matchlen, ct, ctinfo, |
152 | seq)) { | 150 | seq)) { |
diff --git a/net/ipv4/netfilter/ip_nat_irc.c b/net/ipv4/netfilter/ip_nat_irc.c index 9c1ca3381d56..de31942babe3 100644 --- a/net/ipv4/netfilter/ip_nat_irc.c +++ b/net/ipv4/netfilter/ip_nat_irc.c | |||
@@ -65,10 +65,8 @@ static unsigned int help(struct sk_buff **pskb, | |||
65 | break; | 65 | break; |
66 | } | 66 | } |
67 | 67 | ||
68 | if (port == 0) { | 68 | if (port == 0) |
69 | ip_conntrack_expect_free(exp); | ||
70 | return NF_DROP; | 69 | return NF_DROP; |
71 | } | ||
72 | 70 | ||
73 | /* strlen("\1DCC CHAT chat AAAAAAAA P\1\n")=27 | 71 | /* strlen("\1DCC CHAT chat AAAAAAAA P\1\n")=27 |
74 | * strlen("\1DCC SCHAT chat AAAAAAAA P\1\n")=28 | 72 | * strlen("\1DCC SCHAT chat AAAAAAAA P\1\n")=28 |
diff --git a/net/ipv4/netfilter/ip_nat_tftp.c b/net/ipv4/netfilter/ip_nat_tftp.c index 0343e0d64674..2215317c76b7 100644 --- a/net/ipv4/netfilter/ip_nat_tftp.c +++ b/net/ipv4/netfilter/ip_nat_tftp.c | |||
@@ -45,10 +45,8 @@ static unsigned int help(struct sk_buff **pskb, | |||
45 | exp->saved_proto.udp.port = exp->tuple.dst.u.tcp.port; | 45 | exp->saved_proto.udp.port = exp->tuple.dst.u.tcp.port; |
46 | exp->dir = IP_CT_DIR_REPLY; | 46 | exp->dir = IP_CT_DIR_REPLY; |
47 | exp->expectfn = ip_nat_follow_master; | 47 | exp->expectfn = ip_nat_follow_master; |
48 | if (ip_conntrack_expect_related(exp) != 0) { | 48 | if (ip_conntrack_expect_related(exp) != 0) |
49 | ip_conntrack_expect_free(exp); | ||
50 | return NF_DROP; | 49 | return NF_DROP; |
51 | } | ||
52 | return NF_ACCEPT; | 50 | return NF_ACCEPT; |
53 | } | 51 | } |
54 | 52 | ||