[NETFILTER]: PPTP conntrack: fix another GRE keymap leak
Patrick McHardy [Wed, 20 Sep 2006 19:11:30 +0000 (12:11 -0700)]
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>

include/linux/netfilter_ipv4/ip_conntrack_helper.h
net/ipv4/netfilter/ip_conntrack_core.c
net/ipv4/netfilter/ip_conntrack_helper_pptp.c

index 8d69279..77fe868 100644 (file)
@@ -25,6 +25,8 @@ struct ip_conntrack_helper
                    struct ip_conntrack *ct,
                    enum ip_conntrack_info conntrackinfo);
 
+       void (*destroy)(struct ip_conntrack *ct);
+
        int (*to_nfattr)(struct sk_buff *skb, const struct ip_conntrack *ct);
 };
 
index 2b6f24f..c432b31 100644 (file)
@@ -307,6 +307,7 @@ destroy_conntrack(struct nf_conntrack *nfct)
 {
        struct ip_conntrack *ct = (struct ip_conntrack *)nfct;
        struct ip_conntrack_protocol *proto;
+       struct ip_conntrack_helper *helper;
 
        DEBUGP("destroy_conntrack(%p)\n", ct);
        IP_NF_ASSERT(atomic_read(&nfct->use) == 0);
@@ -315,6 +316,10 @@ destroy_conntrack(struct nf_conntrack *nfct)
        ip_conntrack_event(IPCT_DESTROY, ct);
        set_bit(IPS_DYING_BIT, &ct->status);
 
+       helper = ct->helper;
+       if (helper && helper->destroy)
+               helper->destroy(ct);
+
        /* To make sure we don't get any weird locking issues here:
         * destroy_conntrack() MUST NOT be called with a write lock
         * to ip_conntrack_lock!!! -HW */
index 98267b0..fb0aee6 100644 (file)
@@ -553,15 +553,6 @@ conntrack_pptp_help(struct sk_buff **pskb,
        nexthdr_off += tcph->doff * 4;
        datalen = tcplen - tcph->doff * 4;
 
-       if (tcph->fin || tcph->rst) {
-               DEBUGP("RST/FIN received, timeouting GRE\n");
-               /* can't do this after real newnat */
-               info->cstate = PPTP_CALL_NONE;
-
-               /* untrack this call id, unexpect GRE packets */
-               pptp_destroy_siblings(ct);
-       }
-
        pptph = skb_header_pointer(*pskb, nexthdr_off, sizeof(_pptph), &_pptph);
        if (!pptph) {
                DEBUGP("no full PPTP header, can't track\n");
@@ -640,7 +631,8 @@ static struct ip_conntrack_helper pptp = {
                           .protonum = 0xff
                         }
                },
-       .help = conntrack_pptp_help
+       .help = conntrack_pptp_help,
+       .destroy = pptp_destroy_siblings,
 };
 
 extern void ip_ct_proto_gre_fini(void);