diff options
author | Philip Craig <philipc@snapgear.com> | 2005-11-09 16:01:53 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-11-09 16:01:53 -0500 |
commit | 5978a9b82c55b82a1087bd86e0ae8b00f94d0d0b (patch) | |
tree | 1f24eed476d8e23116714ae16a947fcac855dfa5 /net/ipv4 | |
parent | 81e5c27d08bb39e646fe822ea80ab8feba62b94d (diff) |
[NETFILTER] PPTP helper: fix PNS-PAC expectation call id
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: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/netfilter/ip_nat_helper_pptp.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/net/ipv4/netfilter/ip_nat_helper_pptp.c b/net/ipv4/netfilter/ip_nat_helper_pptp.c index ee6ab74ad3a9..e546203f5662 100644 --- a/net/ipv4/netfilter/ip_nat_helper_pptp.c +++ b/net/ipv4/netfilter/ip_nat_helper_pptp.c | |||
@@ -73,6 +73,7 @@ static void pptp_nat_expected(struct ip_conntrack *ct, | |||
73 | struct ip_conntrack_tuple t; | 73 | struct ip_conntrack_tuple t; |
74 | struct ip_ct_pptp_master *ct_pptp_info; | 74 | struct ip_ct_pptp_master *ct_pptp_info; |
75 | struct ip_nat_pptp *nat_pptp_info; | 75 | struct ip_nat_pptp *nat_pptp_info; |
76 | struct ip_nat_range range; | ||
76 | 77 | ||
77 | ct_pptp_info = &master->help.ct_pptp_info; | 78 | ct_pptp_info = &master->help.ct_pptp_info; |
78 | nat_pptp_info = &master->nat.help.nat_pptp_info; | 79 | nat_pptp_info = &master->nat.help.nat_pptp_info; |
@@ -110,7 +111,30 @@ static void pptp_nat_expected(struct ip_conntrack *ct, | |||
110 | DEBUGP("not found!\n"); | 111 | DEBUGP("not found!\n"); |
111 | } | 112 | } |
112 | 113 | ||
113 | ip_nat_follow_master(ct, exp); | 114 | /* This must be a fresh one. */ |
115 | BUG_ON(ct->status & IPS_NAT_DONE_MASK); | ||
116 | |||
117 | /* Change src to where master sends to */ | ||
118 | range.flags = IP_NAT_RANGE_MAP_IPS; | ||
119 | range.min_ip = range.max_ip | ||
120 | = ct->master->tuplehash[!exp->dir].tuple.dst.ip; | ||
121 | if (exp->dir == IP_CT_DIR_ORIGINAL) { | ||
122 | range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED; | ||
123 | range.min = range.max = exp->saved_proto; | ||
124 | } | ||
125 | /* hook doesn't matter, but it has to do source manip */ | ||
126 | ip_nat_setup_info(ct, &range, NF_IP_POST_ROUTING); | ||
127 | |||
128 | /* For DST manip, map port here to where it's expected. */ | ||
129 | range.flags = IP_NAT_RANGE_MAP_IPS; | ||
130 | range.min_ip = range.max_ip | ||
131 | = ct->master->tuplehash[!exp->dir].tuple.src.ip; | ||
132 | if (exp->dir == IP_CT_DIR_REPLY) { | ||
133 | range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED; | ||
134 | range.min = range.max = exp->saved_proto; | ||
135 | } | ||
136 | /* hook doesn't matter, but it has to do destination manip */ | ||
137 | ip_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING); | ||
114 | } | 138 | } |
115 | 139 | ||
116 | /* outbound packets == from PNS to PAC */ | 140 | /* outbound packets == from PNS to PAC */ |
@@ -213,7 +237,7 @@ pptp_exp_gre(struct ip_conntrack_expect *expect_orig, | |||
213 | 237 | ||
214 | /* alter expectation for PNS->PAC direction */ | 238 | /* alter expectation for PNS->PAC direction */ |
215 | invert_tuplepr(&inv_t, &expect_orig->tuple); | 239 | invert_tuplepr(&inv_t, &expect_orig->tuple); |
216 | expect_orig->saved_proto.gre.key = htons(nat_pptp_info->pac_call_id); | 240 | expect_orig->saved_proto.gre.key = htons(ct_pptp_info->pns_call_id); |
217 | expect_orig->tuple.src.u.gre.key = htons(nat_pptp_info->pns_call_id); | 241 | expect_orig->tuple.src.u.gre.key = htons(nat_pptp_info->pns_call_id); |
218 | expect_orig->tuple.dst.u.gre.key = htons(ct_pptp_info->pac_call_id); | 242 | expect_orig->tuple.dst.u.gre.key = htons(ct_pptp_info->pac_call_id); |
219 | expect_orig->dir = IP_CT_DIR_ORIGINAL; | 243 | expect_orig->dir = IP_CT_DIR_ORIGINAL; |