Commit 4e8e9de7 authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller

[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: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3e3850e9
...@@ -162,19 +162,21 @@ ip_nat_in(unsigned int hooknum, ...@@ -162,19 +162,21 @@ ip_nat_in(unsigned int hooknum,
const struct net_device *out, const struct net_device *out,
int (*okfn)(struct sk_buff *)) int (*okfn)(struct sk_buff *))
{ {
u_int32_t saddr, daddr; struct ip_conntrack *ct;
enum ip_conntrack_info ctinfo;
unsigned int ret; unsigned int ret;
saddr = (*pskb)->nh.iph->saddr;
daddr = (*pskb)->nh.iph->daddr;
ret = ip_nat_fn(hooknum, pskb, in, out, okfn); ret = ip_nat_fn(hooknum, pskb, in, out, okfn);
if (ret != NF_DROP && ret != NF_STOLEN if (ret != NF_DROP && ret != NF_STOLEN
&& ((*pskb)->nh.iph->saddr != saddr && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) {
|| (*pskb)->nh.iph->daddr != daddr)) { enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
if (ct->tuplehash[dir].tuple.src.ip !=
ct->tuplehash[!dir].tuple.dst.ip) {
dst_release((*pskb)->dst); dst_release((*pskb)->dst);
(*pskb)->dst = NULL; (*pskb)->dst = NULL;
} }
}
return ret; return ret;
} }
...@@ -200,7 +202,8 @@ ip_nat_local_fn(unsigned int hooknum, ...@@ -200,7 +202,8 @@ ip_nat_local_fn(unsigned int hooknum,
const struct net_device *out, const struct net_device *out,
int (*okfn)(struct sk_buff *)) int (*okfn)(struct sk_buff *))
{ {
u_int32_t saddr, daddr; struct ip_conntrack *ct;
enum ip_conntrack_info ctinfo;
unsigned int ret; unsigned int ret;
/* root is playing with raw sockets. */ /* root is playing with raw sockets. */
...@@ -208,14 +211,15 @@ ip_nat_local_fn(unsigned int hooknum, ...@@ -208,14 +211,15 @@ ip_nat_local_fn(unsigned int hooknum,
|| (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
return NF_ACCEPT; return NF_ACCEPT;
saddr = (*pskb)->nh.iph->saddr;
daddr = (*pskb)->nh.iph->daddr;
ret = ip_nat_fn(hooknum, pskb, in, out, okfn); ret = ip_nat_fn(hooknum, pskb, in, out, okfn);
if (ret != NF_DROP && ret != NF_STOLEN if (ret != NF_DROP && ret != NF_STOLEN
&& ((*pskb)->nh.iph->saddr != saddr && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) {
|| (*pskb)->nh.iph->daddr != daddr)) enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
if (ct->tuplehash[dir].tuple.dst.ip !=
ct->tuplehash[!dir].tuple.src.ip)
return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP; return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
}
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment