]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
[PATCH] PPTP helper: fix PNS-PAC expectation call id
authorPhilip Craig <philipc@snapgear.com>
Tue, 15 Nov 2005 12:32:36 +0000 (13:32 +0100)
committerChris Wright <chrisw@osdl.org>
Thu, 24 Nov 2005 22:10:10 +0000 (14:10 -0800)
The reply tuple of the PNS->PAC expectation was using the wrong call id.

So we had the following situation:
- PNS behind NAT firewall
- PNS call id requires NATing
- PNS->PAC gre packet arrives first

then the PNS->PAC expectation is matched, and the other expectation
is deleted, but the PAC->PNS gre packets do not match the gre conntrack
because the call id is wrong.

We also cannot use ip_nat_follow_master().

Signed-off-by: Philip Craig <philipc@snapgear.com>
Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: Chris Wright <chrisw@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
net/ipv4/netfilter/ip_nat_helper_pptp.c

index 3cdd0684d30d32242963309f35941c123f041504..56e29fae641b7588266e7bb0964c8f3ccd0808d7 100644 (file)
@@ -73,6 +73,7 @@ static void pptp_nat_expected(struct ip_conntrack *ct,
        struct ip_conntrack_tuple t;
        struct ip_ct_pptp_master *ct_pptp_info;
        struct ip_nat_pptp *nat_pptp_info;
+       struct ip_nat_range range;
 
        ct_pptp_info = &master->help.ct_pptp_info;
        nat_pptp_info = &master->nat.help.nat_pptp_info;
@@ -110,7 +111,30 @@ static void pptp_nat_expected(struct ip_conntrack *ct,
                DEBUGP("not found!\n");
        }
 
-       ip_nat_follow_master(ct, exp);
+       /* This must be a fresh one. */
+       BUG_ON(ct->status & IPS_NAT_DONE_MASK);
+
+       /* Change src to where master sends to */
+       range.flags = IP_NAT_RANGE_MAP_IPS;
+       range.min_ip = range.max_ip
+               = ct->master->tuplehash[!exp->dir].tuple.dst.ip;
+       if (exp->dir == IP_CT_DIR_ORIGINAL) {
+               range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
+               range.min = range.max = exp->saved_proto;
+       }
+       /* hook doesn't matter, but it has to do source manip */
+       ip_nat_setup_info(ct, &range, NF_IP_POST_ROUTING);
+
+       /* For DST manip, map port here to where it's expected. */
+       range.flags = IP_NAT_RANGE_MAP_IPS;
+       range.min_ip = range.max_ip
+               = ct->master->tuplehash[!exp->dir].tuple.src.ip;
+       if (exp->dir == IP_CT_DIR_REPLY) {
+               range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
+               range.min = range.max = exp->saved_proto;
+       }
+       /* hook doesn't matter, but it has to do destination manip */
+       ip_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING);
 }
 
 /* outbound packets == from PNS to PAC */
@@ -213,7 +237,7 @@ pptp_exp_gre(struct ip_conntrack_expect *expect_orig,
 
        /* alter expectation for PNS->PAC direction */
        invert_tuplepr(&inv_t, &expect_orig->tuple);
-       expect_orig->saved_proto.gre.key = htons(nat_pptp_info->pac_call_id);
+       expect_orig->saved_proto.gre.key = htons(ct_pptp_info->pns_call_id);
        expect_orig->tuple.src.u.gre.key = htons(nat_pptp_info->pns_call_id);
        expect_orig->tuple.dst.u.gre.key = htons(ct_pptp_info->pac_call_id);
        inv_t.src.ip = reply_t->src.ip;