#include <linux/netfilter.h>
 #include <linux/netfilter/nf_conntrack_tuple_common.h>
 
-#define NF_NAT_RANGE_MAP_IPS           1
-#define NF_NAT_RANGE_PROTO_SPECIFIED   2
-#define NF_NAT_RANGE_PROTO_RANDOM      4
-#define NF_NAT_RANGE_PERSISTENT                8
+#define NF_NAT_RANGE_MAP_IPS                   (1 << 0)
+#define NF_NAT_RANGE_PROTO_SPECIFIED           (1 << 1)
+#define NF_NAT_RANGE_PROTO_RANDOM              (1 << 2)
+#define NF_NAT_RANGE_PERSISTENT                        (1 << 3)
+#define NF_NAT_RANGE_PROTO_RANDOM_FULLY                (1 << 4)
+
+#define NF_NAT_RANGE_PROTO_RANDOM_ALL          \
+       (NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PROTO_RANDOM_FULLY)
 
 struct nf_nat_ipv4_range {
        unsigned int                    flags;
 
         * manips not an issue.
         */
        if (maniptype == NF_NAT_MANIP_SRC &&
-           !(range->flags & NF_NAT_RANGE_PROTO_RANDOM)) {
+           !(range->flags & NF_NAT_RANGE_PROTO_RANDOM_ALL)) {
                /* try the original tuple first */
                if (in_range(l3proto, l4proto, orig_tuple, range)) {
                        if (!nf_nat_used_tuple(orig_tuple, ct)) {
         */
 
        /* Only bother mapping if it's not already in range and unique */
-       if (!(range->flags & NF_NAT_RANGE_PROTO_RANDOM)) {
+       if (!(range->flags & NF_NAT_RANGE_PROTO_RANDOM_ALL)) {
                if (range->flags & NF_NAT_RANGE_PROTO_SPECIFIED) {
                        if (l4proto->in_range(tuple, maniptype,
                                              &range->min_proto,
 
                range_size = ntohs(range->max_proto.all) - min + 1;
        }
 
-       if (range->flags & NF_NAT_RANGE_PROTO_RANDOM)
+       if (range->flags & NF_NAT_RANGE_PROTO_RANDOM) {
                off = l3proto->secure_port(tuple, maniptype == NF_NAT_MANIP_SRC
                                                  ? tuple->dst.u.all
                                                  : tuple->src.u.all);
-       else
+       } else if (range->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY) {
+               off = prandom_u32();
+       } else {
                off = *rover;
+       }
 
        for (i = 0; ; ++off) {
                *portptr = htons(min + off % range_size);
                if (++i != range_size && nf_nat_used_tuple(tuple, ct))
                        continue;
-               if (!(range->flags & NF_NAT_RANGE_PROTO_RANDOM))
+               if (!(range->flags & NF_NAT_RANGE_PROTO_RANDOM_ALL))
                        *rover = off;
                return;
        }
-       return;
 }
 EXPORT_SYMBOL_GPL(nf_nat_l4proto_unique_tuple);