summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilly Tarreau <w@1wt.eu>2022-05-02 10:46:12 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-06-25 11:45:20 +0200
commitdd82067bd6cabbc25aa0f459e91a8e5e08fa4782 (patch)
treeef1ac0967e28e38c7c2f66da2ef878203983ea71
parentaa7722529f6d7f3be1dd7b94dcce3f2689ba9756 (diff)
tcp: dynamically allocate the perturb table used by source ports
commit e9261476184be1abd486c9434164b2acbe0ed6c2 upstream. We'll need to further increase the size of this table and it's likely that at some point its size will not be suitable anymore for a static table. Let's allocate it on boot from inet_hashinfo2_init(), which is called from tcp_init(). Cc: Moshe Kol <moshe.kol@mail.huji.ac.il> Cc: Yossi Gilad <yossi.gilad@mail.huji.ac.il> Cc: Amit Klein <aksecurity@gmail.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Willy Tarreau <w@1wt.eu> Signed-off-by: Jakub Kicinski <kuba@kernel.org> [bwh: Backported to 4.9: - There is no inet_hashinfo2_init(), so allocate the table in inet_hashinfo_init() when called by TCP - Adjust context] Signed-off-by: Ben Hutchings <ben@decadent.org.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--net/ipv4/inet_hashtables.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index ff801d6e30f2..f6aa46801ab3 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -546,7 +546,8 @@ EXPORT_SYMBOL_GPL(inet_unhash);
* privacy, this only consumes 1 KB of kernel memory.
*/
#define INET_TABLE_PERTURB_SHIFT 8
-static u32 table_perturb[1 << INET_TABLE_PERTURB_SHIFT];
+#define INET_TABLE_PERTURB_SIZE (1 << INET_TABLE_PERTURB_SHIFT)
+static u32 *table_perturb;
int __inet_hash_connect(struct inet_timewait_death_row *death_row,
struct sock *sk, u64 port_offset,
@@ -586,7 +587,8 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
if (likely(remaining > 1))
remaining &= ~1U;
- net_get_random_once(table_perturb, sizeof(table_perturb));
+ net_get_random_once(table_perturb,
+ INET_TABLE_PERTURB_SIZE * sizeof(*table_perturb));
index = hash_32(port_offset, INET_TABLE_PERTURB_SHIFT);
offset = READ_ONCE(table_perturb[index]) + (port_offset >> 32);
@@ -691,6 +693,15 @@ void inet_hashinfo_init(struct inet_hashinfo *h)
INIT_HLIST_NULLS_HEAD(&h->listening_hash[i].nulls_head,
i + LISTENING_NULLS_BASE);
}
+
+ if (h != &tcp_hashinfo)
+ return;
+
+ /* this one is used for source ports of outgoing connections */
+ table_perturb = kmalloc_array(INET_TABLE_PERTURB_SIZE,
+ sizeof(*table_perturb), GFP_KERNEL);
+ if (!table_perturb)
+ panic("TCP: failed to alloc table_perturb");
}
EXPORT_SYMBOL_GPL(inet_hashinfo_init);