netfilter: nat: remove l4 protocol port rovers
authorFlorian Westphal <fw@strlen.de>
Thu, 15 Nov 2018 09:22:59 +0000 (10:22 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Sat, 1 Dec 2018 11:38:42 +0000 (12:38 +0100)
This is a leftover from days where single-cpu systems were common:
Store last port used to resolve a clash to use it as a starting point when
the next conflict needs to be resolved.

When we have parallel attempt to connect to same address:port pair,
its likely that both cores end up computing the same "available" port,
as both use same starting port, and newly used ports won't become
visible to other cores until the conntrack gets confirmed later.

One of the cores then has to drop the packet at insertion time because
the chosen new tuple turns out to be in use after all.

Lets simplify this: remove port rover and use a pseudo-random starting
point.

Note that this doesn't make netfilter default to 'fully random' mode;
the 'rover' was only used if NAT could not reuse source port as-is.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/net/netfilter/nf_nat_l4proto.h
net/netfilter/nf_nat_proto_common.c
net/netfilter/nf_nat_proto_dccp.c
net/netfilter/nf_nat_proto_sctp.c
net/netfilter/nf_nat_proto_tcp.c
net/netfilter/nf_nat_proto_udp.c

index b4d6b29bca62af11eb25906d0c1f31cd5a97acca..7ecac2cd102067dca870db8e83367ab305727ecb 100644 (file)
@@ -74,7 +74,7 @@ void nf_nat_l4proto_unique_tuple(const struct nf_nat_l3proto *l3proto,
                                 struct nf_conntrack_tuple *tuple,
                                 const struct nf_nat_range2 *range,
                                 enum nf_nat_manip_type maniptype,
-                                const struct nf_conn *ct, u16 *rover);
+                                const struct nf_conn *ct);
 
 int nf_nat_l4proto_nlattr_to_range(struct nlattr *tb[],
                                   struct nf_nat_range2 *range);
index 5d849d835561777f45dc70050509095a08be9cac..a7de939fa5a940c93b66bbc036324fd943b9743b 100644 (file)
@@ -38,8 +38,7 @@ void nf_nat_l4proto_unique_tuple(const struct nf_nat_l3proto *l3proto,
                                 struct nf_conntrack_tuple *tuple,
                                 const struct nf_nat_range2 *range,
                                 enum nf_nat_manip_type maniptype,
-                                const struct nf_conn *ct,
-                                u16 *rover)
+                                const struct nf_conn *ct)
 {
        unsigned int range_size, min, max, i;
        __be16 *portptr;
@@ -86,16 +85,13 @@ void nf_nat_l4proto_unique_tuple(const struct nf_nat_l3proto *l3proto,
        } else if (range->flags & NF_NAT_RANGE_PROTO_OFFSET) {
                off = (ntohs(*portptr) - ntohs(range->base_proto.all));
        } else {
-               off = *rover;
+               off = prandom_u32();
        }
 
        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_ALL|
-                                       NF_NAT_RANGE_PROTO_OFFSET)))
-                       *rover = off;
                return;
        }
 }
index 67ea0d83aa5a8a2399b81628e59b395b598b5267..7d4d2c124990b31cdef268b6c7ae0f2a35b725d3 100644 (file)
@@ -18,8 +18,6 @@
 #include <net/netfilter/nf_nat_l3proto.h>
 #include <net/netfilter/nf_nat_l4proto.h>
 
-static u_int16_t dccp_port_rover;
-
 static void
 dccp_unique_tuple(const struct nf_nat_l3proto *l3proto,
                  struct nf_conntrack_tuple *tuple,
@@ -27,8 +25,7 @@ dccp_unique_tuple(const struct nf_nat_l3proto *l3proto,
                  enum nf_nat_manip_type maniptype,
                  const struct nf_conn *ct)
 {
-       nf_nat_l4proto_unique_tuple(l3proto, tuple, range, maniptype, ct,
-                                   &dccp_port_rover);
+       nf_nat_l4proto_unique_tuple(l3proto, tuple, range, maniptype, ct);
 }
 
 static bool
index 1c5d9b65fbbabb9ce887a1bebbc0f55ee6aeb831..f05ad8fa7b2082fc36c7cc5780c1bef6411df581 100644 (file)
@@ -12,8 +12,6 @@
 
 #include <net/netfilter/nf_nat_l4proto.h>
 
-static u_int16_t nf_sctp_port_rover;
-
 static void
 sctp_unique_tuple(const struct nf_nat_l3proto *l3proto,
                  struct nf_conntrack_tuple *tuple,
@@ -21,8 +19,7 @@ sctp_unique_tuple(const struct nf_nat_l3proto *l3proto,
                  enum nf_nat_manip_type maniptype,
                  const struct nf_conn *ct)
 {
-       nf_nat_l4proto_unique_tuple(l3proto, tuple, range, maniptype, ct,
-                                   &nf_sctp_port_rover);
+       nf_nat_l4proto_unique_tuple(l3proto, tuple, range, maniptype, ct);
 }
 
 static bool
index f15fcd475f98783c1b610e3b3b1e35aac4b7c832..c312e6b3e2ea6975fc92669e23c8d532d9fefb2c 100644 (file)
@@ -18,8 +18,6 @@
 #include <net/netfilter/nf_nat_l4proto.h>
 #include <net/netfilter/nf_nat_core.h>
 
-static u16 tcp_port_rover;
-
 static void
 tcp_unique_tuple(const struct nf_nat_l3proto *l3proto,
                 struct nf_conntrack_tuple *tuple,
@@ -27,8 +25,7 @@ tcp_unique_tuple(const struct nf_nat_l3proto *l3proto,
                 enum nf_nat_manip_type maniptype,
                 const struct nf_conn *ct)
 {
-       nf_nat_l4proto_unique_tuple(l3proto, tuple, range, maniptype, ct,
-                                   &tcp_port_rover);
+       nf_nat_l4proto_unique_tuple(l3proto, tuple, range, maniptype, ct);
 }
 
 static bool
index 5790f70a83b28154490a2a774f8a0f7288a38414..208c1431635996253706f8fa20e9b91088db9bce 100644 (file)
@@ -17,8 +17,6 @@
 #include <net/netfilter/nf_nat_l3proto.h>
 #include <net/netfilter/nf_nat_l4proto.h>
 
-static u16 udp_port_rover;
-
 static void
 udp_unique_tuple(const struct nf_nat_l3proto *l3proto,
                 struct nf_conntrack_tuple *tuple,
@@ -26,8 +24,7 @@ udp_unique_tuple(const struct nf_nat_l3proto *l3proto,
                 enum nf_nat_manip_type maniptype,
                 const struct nf_conn *ct)
 {
-       nf_nat_l4proto_unique_tuple(l3proto, tuple, range, maniptype, ct,
-                                   &udp_port_rover);
+       nf_nat_l4proto_unique_tuple(l3proto, tuple, range, maniptype, ct);
 }
 
 static void
@@ -79,8 +76,6 @@ static bool udp_manip_pkt(struct sk_buff *skb,
 }
 
 #ifdef CONFIG_NF_NAT_PROTO_UDPLITE
-static u16 udplite_port_rover;
-
 static bool udplite_manip_pkt(struct sk_buff *skb,
                              const struct nf_nat_l3proto *l3proto,
                              unsigned int iphdroff, unsigned int hdroff,
@@ -104,8 +99,7 @@ udplite_unique_tuple(const struct nf_nat_l3proto *l3proto,
                     enum nf_nat_manip_type maniptype,
                     const struct nf_conn *ct)
 {
-       nf_nat_l4proto_unique_tuple(l3proto, tuple, range, maniptype, ct,
-                                   &udplite_port_rover);
+       nf_nat_l4proto_unique_tuple(l3proto, tuple, range, maniptype, ct);
 }
 
 const struct nf_nat_l4proto nf_nat_l4proto_udplite = {