From 6ed5943f8735e2b778d92ea4d9805c0a1d89bc2b Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Thu, 15 Nov 2018 10:22:59 +0100 Subject: [PATCH] netfilter: nat: remove l4 protocol port rovers 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 Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/nf_nat_l4proto.h | 2 +- net/netfilter/nf_nat_proto_common.c | 8 ++------ net/netfilter/nf_nat_proto_dccp.c | 5 +---- net/netfilter/nf_nat_proto_sctp.c | 5 +---- net/netfilter/nf_nat_proto_tcp.c | 5 +---- net/netfilter/nf_nat_proto_udp.c | 10 ++-------- 6 files changed, 8 insertions(+), 27 deletions(-) diff --git a/include/net/netfilter/nf_nat_l4proto.h b/include/net/netfilter/nf_nat_l4proto.h index b4d6b29..7ecac2c 100644 --- a/include/net/netfilter/nf_nat_l4proto.h +++ b/include/net/netfilter/nf_nat_l4proto.h @@ -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); diff --git a/net/netfilter/nf_nat_proto_common.c b/net/netfilter/nf_nat_proto_common.c index 5d849d8..a7de939 100644 --- a/net/netfilter/nf_nat_proto_common.c +++ b/net/netfilter/nf_nat_proto_common.c @@ -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; } } diff --git a/net/netfilter/nf_nat_proto_dccp.c b/net/netfilter/nf_nat_proto_dccp.c index 67ea0d8..7d4d2c1 100644 --- a/net/netfilter/nf_nat_proto_dccp.c +++ b/net/netfilter/nf_nat_proto_dccp.c @@ -18,8 +18,6 @@ #include #include -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 diff --git a/net/netfilter/nf_nat_proto_sctp.c b/net/netfilter/nf_nat_proto_sctp.c index 1c5d9b6..f05ad8f 100644 --- a/net/netfilter/nf_nat_proto_sctp.c +++ b/net/netfilter/nf_nat_proto_sctp.c @@ -12,8 +12,6 @@ #include -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 diff --git a/net/netfilter/nf_nat_proto_tcp.c b/net/netfilter/nf_nat_proto_tcp.c index f15fcd4..c312e6b 100644 --- a/net/netfilter/nf_nat_proto_tcp.c +++ b/net/netfilter/nf_nat_proto_tcp.c @@ -18,8 +18,6 @@ #include #include -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 diff --git a/net/netfilter/nf_nat_proto_udp.c b/net/netfilter/nf_nat_proto_udp.c index 5790f70..208c143 100644 --- a/net/netfilter/nf_nat_proto_udp.c +++ b/net/netfilter/nf_nat_proto_udp.c @@ -17,8 +17,6 @@ #include #include -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 = { -- 2.7.4