diff --git a/share/man/man4/tcp.4 b/share/man/man4/tcp.4 --- a/share/man/man4/tcp.4 +++ b/share/man/man4/tcp.4 @@ -34,7 +34,7 @@ .\" From: @(#)tcp.4 8.1 (Berkeley) 6/5/93 .\" $FreeBSD$ .\" -.Dd February 13, 2021 +.Dd April 8, 2021 .Dt TCP 4 .Os .Sh NAME @@ -628,7 +628,6 @@ Enable support for TCP Explicit Congestion Notification (ECN). ECN allows a TCP sender to reduce the transmission rate in order to avoid packet drops. -Settings: .Bl -tag -compact .It 0 Disable ECN. @@ -638,6 +637,7 @@ .It 2 Allow incoming connections to request ECN. Outgoing connections will not request ECN. +(default) .El .It Va ecn.maxretries Number of retries (SYN or SYN/ACK retransmits) before disabling ECN on a @@ -674,6 +674,54 @@ MSS to try for IPv4 if PMTU blackhole detection is turned on. .It Va v6pmtud_blackhole_mss MSS to try for IPv6 if PMTU blackhole detection is turned on. +.It Va hostcache.enable +The TCP host cache is used to cache connection details and metrics to +improve future performance of connections between the same hosts. +At the completion of a TCP connection, a host will cache information +for the connection for some defined period of time. +.Bl -tag -compact +.It 0 +Disable the host cache. +.It 1 +Enable the host cache. (default) +.It Va hostcache.purgenow +Immediately purge all entries once set to any value. +Setting this to 2 will also reseed the hash salt. +.It Va hostcache.purge +Expire all entires on next pruning of host cache entries. +Any non-zero setting will be reset to zero, once the pruge +is running. +.Bl -tag -compact +.It 0 +Do not purge all entries when pruning the host cache. (default) +.It 1 +Purge all entries when doing the next pruning. +.It 2 +Purge all entries, and also reseed the hash salt. +.It Va hostcache.prune +Time in seconds between pruning expired host cache entries. +Defaults to 300 (5 minutes). +.It Va hostcache.expire +Time in seconds, how long a entry should be kept in the +host cache since last accessed. +Defaults to 3600 (1 hour). +.It Va hostcache.count +The current number of entries in the host cache. +.It Va hostcache.bucketlimit +The maximum number of entries for the same hash. +Defaults to 30. +.It Va hostcache.hashsize +Size of TCP hostcache hashtable. +This number has to be a power of two, or will be rejected. +Defaults to 512. +.It Va hostcache.cachelimit +Overall entry limit for hostcache. +Defaults to hashsize * bucketlimit. +.It Va hostcache.histo +Provide a Histogram of the hostcache hash utilization. +.It Va hostcache.list +Provide a complete list of all current entries in the host +cache. .It Va functions_available List of available TCP function blocks (TCP stacks). .It Va functions_default diff --git a/sys/netinet/tcp_hostcache.c b/sys/netinet/tcp_hostcache.c --- a/sys/netinet/tcp_hostcache.c +++ b/sys/netinet/tcp_hostcache.c @@ -71,6 +71,7 @@ #include #include +#include #include #include #include @@ -127,6 +128,7 @@ uma_zone_t zone; u_int hashsize; u_int hashmask; + u_int hashsalt; u_int bucket_limit; u_int cache_count; u_int cache_limit; @@ -210,16 +212,14 @@ static MALLOC_DEFINE(M_HOSTCACHE, "hostcache", "TCP hostcache"); +/* Use jenkins_hash32(), as in other parts of the tcp stack */ #define HOSTCACHE_HASH(ip) \ - (((ip)->s_addr ^ ((ip)->s_addr >> 7) ^ ((ip)->s_addr >> 17)) & \ - V_tcp_hostcache.hashmask) + (jenkins_hash32((uint32_t *)(ip), 1, V_tcp_hostcache.hashsalt) & \ + V_tcp_hostcache.hashmask) -/* XXX: What is the recommended hash to get good entropy for IPv6 addresses? */ #define HOSTCACHE_HASH6(ip6) \ - (((ip6)->s6_addr32[0] ^ \ - (ip6)->s6_addr32[1] ^ \ - (ip6)->s6_addr32[2] ^ \ - (ip6)->s6_addr32[3]) & \ + (jenkins_hash32((uint32_t *)&((ip6)->s6_addr32[0]), 4, \ + V_tcp_hostcache.hashsalt) & \ V_tcp_hostcache.hashmask) #define THC_LOCK(lp) mtx_lock(lp) @@ -239,6 +239,7 @@ V_tcp_hostcache.bucket_limit = TCP_HOSTCACHE_BUCKETLIMIT; V_tcp_hostcache.expire = TCP_HOSTCACHE_EXPIRE; V_tcp_hostcache.prune = TCP_HOSTCACHE_PRUNE; + V_tcp_hostcache.hashsalt = arc4random(); TUNABLE_INT_FETCH("net.inet.tcp.hostcache.hashsize", &V_tcp_hostcache.hashsize); @@ -836,6 +837,8 @@ int all = 0; if (V_tcp_hostcache.purgeall) { + if (V_tcp_hostcache.purgeall == 2) + V_tcp_hostcache.hashsalt = arc4random(); all = 1; V_tcp_hostcache.purgeall = 0; } @@ -860,6 +863,8 @@ if (error || !req->newptr) return (error); + if (val == 2) + V_tcp_hostcache.hashsalt = arc4random(); tcp_hc_purge_internal(1); callout_reset(&V_tcp_hc_callout, V_tcp_hostcache.prune * hz,