aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2024-09-06 15:17:05 +1000
committerStefano Brivio <sbrivio@redhat.com>2024-09-06 12:52:31 +0200
commit7ad9f9bd2bbda8d705e0c6faf5acf2792fce063c (patch)
treef2f061d10bbdfa66068af3e511722f2a4c7d7864
parent0ea60e5a7741658ad7056a0a6674e00e72d2d288 (diff)
downloadpasst-7ad9f9bd2bbda8d705e0c6faf5acf2792fce063c.tar
passt-7ad9f9bd2bbda8d705e0c6faf5acf2792fce063c.tar.gz
passt-7ad9f9bd2bbda8d705e0c6faf5acf2792fce063c.tar.bz2
passt-7ad9f9bd2bbda8d705e0c6faf5acf2792fce063c.tar.lz
passt-7ad9f9bd2bbda8d705e0c6faf5acf2792fce063c.tar.xz
passt-7ad9f9bd2bbda8d705e0c6faf5acf2792fce063c.tar.zst
passt-7ad9f9bd2bbda8d705e0c6faf5acf2792fce063c.zip
flow: Fix incorrect hash probe in flowside_lookup()
Our flow hash table uses linear probing in which we step backwards through clusters of adjacent hash entries when we have near collisions. Usually that's implemented by flow_hash_probe(). However, due to some details we need a second implementation in flowside_lookup(). An embarrassing oversight in rebasing from earlier versions has mean that version is incorrect, trying to step forward through clusters rather than backward. In situations with the right sorts of has near-collisions this can lead to us not associating an ACK from the tap device with the right flow, leaving it in a not-quite-established state. If the remote peer does a shutdown() at the right time, this can lead to a storm of EPOLLRDHUP events causing high CPU load. Fixes: acca4235c46f ("flow, tcp: Generalise TCP hash table to general flow hash table") Link: https://bugs.passt.top/show_bug.cgi?id=94 Suggested-by: Stefano Brivio <sbrivio@redhat.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r--flow.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/flow.c b/flow.c
index 02631eb..a00e01d 100644
--- a/flow.c
+++ b/flow.c
@@ -697,7 +697,7 @@ static flow_sidx_t flowside_lookup(const struct ctx *c, uint8_t proto,
!(FLOW_PROTO(&flow->f) == proto &&
flow->f.pif[sidx.sidei] == pif &&
flowside_eq(&flow->f.side[sidx.sidei], side)))
- b = (b + 1) % FLOW_HASH_SIZE;
+ b = mod_sub(b, 1, FLOW_HASH_SIZE);
return flow_hashtab[b];
}