diff options
author | Patrick McHardy <kaber@trash.net> | 2006-01-07 02:05:17 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-01-07 15:57:34 -0500 |
commit | 4e8e9de7c25315669e2d5565acc50ec379522c28 (patch) | |
tree | 3d101041c9d28a70b8eec77af279cbfbb72b3027 /net/ipv4 | |
parent | 3e3850e989c5d2eb1aab6f0fd9257759f0f4cbc6 (diff) |
[NETFILTER]: Use conntrack information to determine if packet was NATed
Preparation for IPsec support for NAT:
Use conntrack information instead of saving the saving and comparing the
addresses to determine if a packet was NATed and needs to be rerouted to
make it easier to extend the key.
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_nat_standalone.c | 34 |
1 files changed, 19 insertions, 15 deletions
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index f04111f74e09..1bb50897a5a2 100644 --- a/net/ipv4/netfilter/ip_nat_standalone.c +++ b/net/ipv4/netfilter/ip_nat_standalone.c | |||
@@ -162,18 +162,20 @@ ip_nat_in(unsigned int hooknum, | |||
162 | const struct net_device *out, | 162 | const struct net_device *out, |
163 | int (*okfn)(struct sk_buff *)) | 163 | int (*okfn)(struct sk_buff *)) |
164 | { | 164 | { |
165 | u_int32_t saddr, daddr; | 165 | struct ip_conntrack *ct; |
166 | enum ip_conntrack_info ctinfo; | ||
166 | unsigned int ret; | 167 | unsigned int ret; |
167 | 168 | ||
168 | saddr = (*pskb)->nh.iph->saddr; | ||
169 | daddr = (*pskb)->nh.iph->daddr; | ||
170 | |||
171 | ret = ip_nat_fn(hooknum, pskb, in, out, okfn); | 169 | ret = ip_nat_fn(hooknum, pskb, in, out, okfn); |
172 | if (ret != NF_DROP && ret != NF_STOLEN | 170 | if (ret != NF_DROP && ret != NF_STOLEN |
173 | && ((*pskb)->nh.iph->saddr != saddr | 171 | && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) { |
174 | || (*pskb)->nh.iph->daddr != daddr)) { | 172 | enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); |
175 | dst_release((*pskb)->dst); | 173 | |
176 | (*pskb)->dst = NULL; | 174 | if (ct->tuplehash[dir].tuple.src.ip != |
175 | ct->tuplehash[!dir].tuple.dst.ip) { | ||
176 | dst_release((*pskb)->dst); | ||
177 | (*pskb)->dst = NULL; | ||
178 | } | ||
177 | } | 179 | } |
178 | return ret; | 180 | return ret; |
179 | } | 181 | } |
@@ -200,7 +202,8 @@ ip_nat_local_fn(unsigned int hooknum, | |||
200 | const struct net_device *out, | 202 | const struct net_device *out, |
201 | int (*okfn)(struct sk_buff *)) | 203 | int (*okfn)(struct sk_buff *)) |
202 | { | 204 | { |
203 | u_int32_t saddr, daddr; | 205 | struct ip_conntrack *ct; |
206 | enum ip_conntrack_info ctinfo; | ||
204 | unsigned int ret; | 207 | unsigned int ret; |
205 | 208 | ||
206 | /* root is playing with raw sockets. */ | 209 | /* root is playing with raw sockets. */ |
@@ -208,14 +211,15 @@ ip_nat_local_fn(unsigned int hooknum, | |||
208 | || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) | 211 | || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) |
209 | return NF_ACCEPT; | 212 | return NF_ACCEPT; |
210 | 213 | ||
211 | saddr = (*pskb)->nh.iph->saddr; | ||
212 | daddr = (*pskb)->nh.iph->daddr; | ||
213 | |||
214 | ret = ip_nat_fn(hooknum, pskb, in, out, okfn); | 214 | ret = ip_nat_fn(hooknum, pskb, in, out, okfn); |
215 | if (ret != NF_DROP && ret != NF_STOLEN | 215 | if (ret != NF_DROP && ret != NF_STOLEN |
216 | && ((*pskb)->nh.iph->saddr != saddr | 216 | && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) { |
217 | || (*pskb)->nh.iph->daddr != daddr)) | 217 | enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); |
218 | return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP; | 218 | |
219 | if (ct->tuplehash[dir].tuple.dst.ip != | ||
220 | ct->tuplehash[!dir].tuple.src.ip) | ||
221 | return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP; | ||
222 | } | ||
219 | return ret; | 223 | return ret; |
220 | } | 224 | } |
221 | 225 | ||