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 | ||
