diff options
author | Patrick McHardy <kaber@trash.net> | 2006-09-20 15:11:30 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-09-22 18:20:20 -0400 |
commit | 4c5de695cf7f71c85ad8cfff509f6475b8bd4d27 (patch) | |
tree | 5175e20ab9244b4a0961ae98d85c8823956aad77 /net/ipv4 | |
parent | fd5e3befa405ea64d4db6b393b821644bf963c57 (diff) |
[NETFILTER]: PPTP conntrack: fix another GRE keymap leak
When the master PPTP connection times out while still having unfullfilled
expectations (and a GRE keymap entry) associated with it, the keymap entry
is not destroyed.
Add a destroy callback to struct ip_conntrack_helper and use it to destroy
PPTP siblings when the master is destroyed.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_core.c | 5 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_helper_pptp.c | 12 |
2 files changed, 7 insertions, 10 deletions
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index 2b6f24fc727e..c432b3163609 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c | |||
@@ -307,6 +307,7 @@ destroy_conntrack(struct nf_conntrack *nfct) | |||
307 | { | 307 | { |
308 | struct ip_conntrack *ct = (struct ip_conntrack *)nfct; | 308 | struct ip_conntrack *ct = (struct ip_conntrack *)nfct; |
309 | struct ip_conntrack_protocol *proto; | 309 | struct ip_conntrack_protocol *proto; |
310 | struct ip_conntrack_helper *helper; | ||
310 | 311 | ||
311 | DEBUGP("destroy_conntrack(%p)\n", ct); | 312 | DEBUGP("destroy_conntrack(%p)\n", ct); |
312 | IP_NF_ASSERT(atomic_read(&nfct->use) == 0); | 313 | IP_NF_ASSERT(atomic_read(&nfct->use) == 0); |
@@ -315,6 +316,10 @@ destroy_conntrack(struct nf_conntrack *nfct) | |||
315 | ip_conntrack_event(IPCT_DESTROY, ct); | 316 | ip_conntrack_event(IPCT_DESTROY, ct); |
316 | set_bit(IPS_DYING_BIT, &ct->status); | 317 | set_bit(IPS_DYING_BIT, &ct->status); |
317 | 318 | ||
319 | helper = ct->helper; | ||
320 | if (helper && helper->destroy) | ||
321 | helper->destroy(ct); | ||
322 | |||
318 | /* To make sure we don't get any weird locking issues here: | 323 | /* To make sure we don't get any weird locking issues here: |
319 | * destroy_conntrack() MUST NOT be called with a write lock | 324 | * destroy_conntrack() MUST NOT be called with a write lock |
320 | * to ip_conntrack_lock!!! -HW */ | 325 | * to ip_conntrack_lock!!! -HW */ |
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_pptp.c b/net/ipv4/netfilter/ip_conntrack_helper_pptp.c index 98267b0d2a47..fb0aee691721 100644 --- a/net/ipv4/netfilter/ip_conntrack_helper_pptp.c +++ b/net/ipv4/netfilter/ip_conntrack_helper_pptp.c | |||
@@ -553,15 +553,6 @@ conntrack_pptp_help(struct sk_buff **pskb, | |||
553 | nexthdr_off += tcph->doff * 4; | 553 | nexthdr_off += tcph->doff * 4; |
554 | datalen = tcplen - tcph->doff * 4; | 554 | datalen = tcplen - tcph->doff * 4; |
555 | 555 | ||
556 | if (tcph->fin || tcph->rst) { | ||
557 | DEBUGP("RST/FIN received, timeouting GRE\n"); | ||
558 | /* can't do this after real newnat */ | ||
559 | info->cstate = PPTP_CALL_NONE; | ||
560 | |||
561 | /* untrack this call id, unexpect GRE packets */ | ||
562 | pptp_destroy_siblings(ct); | ||
563 | } | ||
564 | |||
565 | pptph = skb_header_pointer(*pskb, nexthdr_off, sizeof(_pptph), &_pptph); | 556 | pptph = skb_header_pointer(*pskb, nexthdr_off, sizeof(_pptph), &_pptph); |
566 | if (!pptph) { | 557 | if (!pptph) { |
567 | DEBUGP("no full PPTP header, can't track\n"); | 558 | DEBUGP("no full PPTP header, can't track\n"); |
@@ -640,7 +631,8 @@ static struct ip_conntrack_helper pptp = { | |||
640 | .protonum = 0xff | 631 | .protonum = 0xff |
641 | } | 632 | } |
642 | }, | 633 | }, |
643 | .help = conntrack_pptp_help | 634 | .help = conntrack_pptp_help, |
635 | .destroy = pptp_destroy_siblings, | ||
644 | }; | 636 | }; |
645 | 637 | ||
646 | extern void ip_ct_proto_gre_fini(void); | 638 | extern void ip_ct_proto_gre_fini(void); |