Merge git://oss.sgi.com:8090/xfs/xfs-2.6
[linux-drm-fsl-dcu.git] / net / ipv4 / netfilter / nf_nat_core.c
index 86a92272b05398fa46206c3f8f6babbdc1057557..cf1010827be1f38036d4b48c693ebf0bfad9dd9e 100644 (file)
@@ -254,8 +254,9 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,
        if (maniptype == IP_NAT_MANIP_SRC) {
                if (find_appropriate_src(orig_tuple, tuple, range)) {
                        DEBUGP("get_unique_tuple: Found current src map\n");
-                       if (!nf_nat_used_tuple(tuple, ct))
-                               return;
+                       if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM))
+                               if (!nf_nat_used_tuple(tuple, ct))
+                                       return;
                }
        }
 
@@ -269,6 +270,13 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,
 
        proto = nf_nat_proto_find_get(orig_tuple->dst.protonum);
 
+       /* Change protocol info to have some randomization */
+       if (range->flags & IP_NAT_RANGE_PROTO_RANDOM) {
+               proto->unique_tuple(tuple, range, maniptype, ct);
+               nf_nat_proto_put(proto);
+               return;
+       }
+
        /* Only bother mapping if it's not already in range and unique */
        if ((!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED) ||
             proto->in_range(tuple, maniptype, &range->min, &range->max)) &&
@@ -444,8 +452,8 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct,
                     (*pskb)->nfctinfo == IP_CT_RELATED+IP_CT_IS_REPLY);
 
        /* Redirects on non-null nats must be dropped, else they'll
-           start talking to each other without our translation, and be
-           confused... --RR */
+          start talking to each other without our translation, and be
+          confused... --RR */
        if (inside->icmp.type == ICMP_REDIRECT) {
                /* If NAT isn't finished, assume it and drop. */
                if ((ct->status & IPS_NAT_DONE_MASK) != IPS_NAT_DONE_MASK)
@@ -461,13 +469,13 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct,
        if (!nf_ct_get_tuple(*pskb,
                             (*pskb)->nh.iph->ihl*4 + sizeof(struct icmphdr),
                             (*pskb)->nh.iph->ihl*4 +
-                            sizeof(struct icmphdr) + inside->ip.ihl*4,
-                            (u_int16_t)AF_INET,
-                            inside->ip.protocol,
-                            &inner,
-                            l3proto,
+                            sizeof(struct icmphdr) + inside->ip.ihl*4,
+                            (u_int16_t)AF_INET,
+                            inside->ip.protocol,
+                            &inner,
+                            l3proto,
                             __nf_ct_l4proto_find((u_int16_t)PF_INET,
-                                                 inside->ip.protocol)))
+                                                 inside->ip.protocol)))
                return 0;
 
        /* Change inner back to look like incoming packet.  We do the