aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/netfilter/ip_nat_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/netfilter/ip_nat_helper.c')
-rw-r--r--net/ipv4/netfilter/ip_nat_helper.c50
1 files changed, 16 insertions, 34 deletions
diff --git a/net/ipv4/netfilter/ip_nat_helper.c b/net/ipv4/netfilter/ip_nat_helper.c
index 9bca2faa52bc6..b7a5179d266a6 100644
--- a/net/ipv4/netfilter/ip_nat_helper.c
+++ b/net/ipv4/netfilter/ip_nat_helper.c
@@ -405,46 +405,28 @@ ip_nat_seq_adjust(struct sk_buff **pskb,
return 1;
}
-/* We look at the master's nat fields without ip_nat_lock. This works
- because the master's NAT must be fully initialized, because we
- don't match expectations set up by unconfirmed connections. We
- can't grab the lock because we hold the ip_conntrack_lock, and that
- would be backwards from other locking orders. */
-static void ip_nat_copy_manip(struct ip_nat_info *master,
- struct ip_conntrack_expect *exp,
- struct ip_conntrack *ct)
-{
- struct ip_nat_range range;
- unsigned int i;
-
- range.flags = IP_NAT_RANGE_MAP_IPS;
-
- /* Find what master is mapped to (if any), so we can do the same. */
- for (i = 0; i < master->num_manips; i++) {
- if (master->manips[i].direction != exp->dir)
- continue;
-
- range.min_ip = range.max_ip = master->manips[i].manip.ip;
-
- /* If this is a DST manip, map port here to where it's
- * expected. */
- if (master->manips[i].maniptype == IP_NAT_MANIP_DST) {
- range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
- range.min = range.max = exp->saved_proto;
- }
- ip_nat_setup_info(ct, &range, master->manips[i].hooknum);
- }
-}
-
/* Setup NAT on this expected conntrack so it follows master. */
/* If we fail to get a free NAT slot, we'll get dropped on confirm */
void ip_nat_follow_master(struct ip_conntrack *ct,
- struct ip_conntrack_expect *this)
+ struct ip_conntrack_expect *exp)
{
- struct ip_nat_info *master = &ct->master->nat.info;
+ struct ip_nat_range range;
/* This must be a fresh one. */
BUG_ON(ct->nat.info.initialized);
- ip_nat_copy_manip(master, this, ct);
+ /* 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;
+ /* 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 | IP_NAT_RANGE_PROTO_SPECIFIED);
+ range.min = range.max = exp->saved_proto;
+ range.min_ip = range.max_ip
+ = ct->master->tuplehash[!exp->dir].tuple.src.ip;
+ /* hook doesn't matter, but it has to do destination manip */
+ ip_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING);
}