Skip to content

Commit

Permalink
netfilter: nat: remove l4 protocol port rovers
Browse files Browse the repository at this point in the history
commit 6ed5943 upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Florian Westphal authored and pavelmachek committed Mar 16, 2022
1 parent a09b2d8 commit da0f7c7
Show file tree
Hide file tree
Showing 7 changed files with 8 additions and 26 deletions.
2 changes: 1 addition & 1 deletion include/net/netfilter/nf_nat_l4proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ void nf_nat_l4proto_unique_tuple(const struct nf_nat_l3proto *l3proto,
struct nf_conntrack_tuple *tuple,
const struct nf_nat_range *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_range *range);
Expand Down
7 changes: 2 additions & 5 deletions net/netfilter/nf_nat_proto_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_range *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;
Expand Down Expand Up @@ -84,15 +83,13 @@ void nf_nat_l4proto_unique_tuple(const struct nf_nat_l3proto *l3proto,
} else if (range->flags & NF_NAT_RANGE_PROTO_RANDOM_FULLY) {
off = prandom_u32();
} 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))
*rover = off;
return;
}
}
Expand Down
5 changes: 1 addition & 4 deletions net/netfilter/nf_nat_proto_dccp.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,14 @@
#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,
const struct nf_nat_range *range,
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
Expand Down
5 changes: 1 addition & 4 deletions net/netfilter/nf_nat_proto_sctp.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,14 @@

#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,
const struct nf_nat_range *range,
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
Expand Down
5 changes: 1 addition & 4 deletions net/netfilter/nf_nat_proto_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,14 @@
#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,
const struct nf_nat_range *range,
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
Expand Down
5 changes: 1 addition & 4 deletions net/netfilter/nf_nat_proto_udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,14 @@
#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,
const struct nf_nat_range *range,
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 bool
Expand Down
5 changes: 1 addition & 4 deletions net/netfilter/nf_nat_proto_udplite.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,14 @@
#include <net/netfilter/nf_nat_l3proto.h>
#include <net/netfilter/nf_nat_l4proto.h>

static u16 udplite_port_rover;

static void
udplite_unique_tuple(const struct nf_nat_l3proto *l3proto,
struct nf_conntrack_tuple *tuple,
const struct nf_nat_range *range,
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);
}

static bool
Expand Down

0 comments on commit da0f7c7

Please sign in to comment.