Index: linux/net/ipv4/netfilter/ip_nat_core.c =================================================================== --- linux.orig/net/ipv4/netfilter/ip_nat_core.c 2004-03-06 18:52:05.000000000 +0100 +++ linux/net/ipv4/netfilter/ip_nat_core.c 2004-03-07 13:05:42.000000000 +0100 @@ -176,20 +176,25 @@ const struct ip_conntrack_tuple *tuple, const struct ip_nat_multi_range *mr) { - return (i->conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum - == tuple->dst.protonum - && i->conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip - == tuple->src.ip - && i->conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.all - == tuple->src.u.all - && in_range(tuple, - &i->conntrack->tuplehash[IP_CT_DIR_ORIGINAL] - .tuple.src, - mr)); + struct ip_conntrack_tuple reverse; + + if (i->conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum + == tuple->dst.protonum + && i->conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip + == tuple->src.ip + && i->conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.all + == tuple->src.u.all) { + /* the original source is the same, check if the same manip + * would be appropriate for the given multi-range */ + invert_tuplepr(&reverse, &i->conntrack->tuplehash[IP_CT_DIR_REPLY].tuple); + return in_range(tuple, &reverse.src, mr); + } + + return 0; } /* Only called for SRC manip */ -static struct ip_conntrack_manip * +static struct ip_conntrack_tuple * find_appropriate_src(const struct ip_conntrack_tuple *tuple, const struct ip_nat_multi_range *mr) { @@ -199,7 +204,7 @@ MUST_BE_READ_LOCKED(&ip_nat_lock); i = LIST_FIND(&bysource[h], src_cmp, struct ip_nat_hash *, tuple, mr); if (i) - return &i->conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src; + return &i->conntrack->tuplehash[IP_CT_DIR_REPLY].tuple; else return NULL; } @@ -419,13 +424,14 @@ So far, we don't do local source mappings, so multiple manips not an issue. */ if (hooknum == NF_IP_POST_ROUTING) { - struct ip_conntrack_manip *manip; + struct ip_conntrack_tuple *srctuple, mtuple; - manip = find_appropriate_src(orig_tuple, mr); - if (manip) { + srctuple = find_appropriate_src(orig_tuple, mr); + if (srctuple) { /* Apply same source manipulation. */ + invert_tuplepr(&mtuple, srctuple); *tuple = ((struct ip_conntrack_tuple) - { *manip, orig_tuple->dst }); + { mtuple.src, orig_tuple->dst }); DEBUGP("get_unique_tuple: Found current src map\n"); if (!ip_nat_used_tuple(tuple, conntrack)) return 1;