From: Willy Tarreau <w@xxxxxx> 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@xxxxxxxxxxxxxxx> Cc: Yossi Gilad <yossi.gilad@xxxxxxxxxxxxxxx> Cc: Amit Klein <aksecurity@xxxxxxxxx> Reviewed-by: Eric Dumazet <edumazet@xxxxxxxxxx> Signed-off-by: Willy Tarreau <w@xxxxxx> Signed-off-by: Jakub Kicinski <kuba@xxxxxxxxxx> [bwh: Backported to 4.14: - 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@xxxxxxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- net/ipv4/inet_hashtables.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c @@ -596,7 +596,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, @@ -636,7 +637,8 @@ int __inet_hash_connect(struct inet_time 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); @@ -741,6 +743,15 @@ void inet_hashinfo_init(struct inet_hash 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);