diff options
Diffstat (limited to 'net/ipv4/netfilter/ip_nat_helper.c')
-rw-r--r-- | net/ipv4/netfilter/ip_nat_helper.c | 50 |
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); } |