Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dd82067b authored by Willy Tarreau's avatar Willy Tarreau Committed by Greg Kroah-Hartman
Browse files

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: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarWilly Tarreau <w@1wt.eu>
Signed-off-by: default avatarJakub 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: default avatarBen Hutchings <ben@decadent.org.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent aa772252
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -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);