aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2024-07-05 20:44:00 +1000
committerStefano Brivio <sbrivio@redhat.com>2024-07-05 15:26:25 +0200
commit8f8eb734828dfe8e07903adbe2a772e2afa46872 (patch)
tree5be1c29b510ca355075290d78f560c919b0bcb8b
parent74c1c5efcfec9fcdb6efe0c8d377af2a7d8e4b0a (diff)
downloadpasst-8f8eb734828dfe8e07903adbe2a772e2afa46872.tar
passt-8f8eb734828dfe8e07903adbe2a772e2afa46872.tar.gz
passt-8f8eb734828dfe8e07903adbe2a772e2afa46872.tar.bz2
passt-8f8eb734828dfe8e07903adbe2a772e2afa46872.tar.lz
passt-8f8eb734828dfe8e07903adbe2a772e2afa46872.tar.xz
passt-8f8eb734828dfe8e07903adbe2a772e2afa46872.tar.zst
passt-8f8eb734828dfe8e07903adbe2a772e2afa46872.zip
flow: Add flow_sidx_valid() helper
To implement the TCP hash table, we need an invalid (NULL-like) value for flow_sidx_t. We use FLOW_SIDX_NONE for that, but for defensiveness, we treat (usually) anything with an out of bounds flow index the same way. That's not always done consistently though. In flow_at_sidx() we open code a check on the flow index. In tcp_hash_probe() we instead compare against FLOW_SIDX_NONE, and in some other places we use the fact that flow_at_sidx() will return NULL in this case, even if we don't otherwise need the flow it returns. Clean this up a bit, by adding an explicit flow_sidx_valid() test function. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r--flow.h11
-rw-r--r--flow_table.h2
-rw-r--r--tcp.c7
3 files changed, 15 insertions, 5 deletions
diff --git a/flow.h b/flow.h
index 29ef9f1..d1f49c6 100644
--- a/flow.h
+++ b/flow.h
@@ -177,6 +177,17 @@ static_assert(sizeof(flow_sidx_t) <= sizeof(uint32_t),
#define FLOW_SIDX_NONE ((flow_sidx_t){ .flow = FLOW_MAX })
/**
+ * flow_sidx_valid() - Test if a sidx is valid
+ * @sidx: sidx value
+ *
+ * Return: true if @sidx refers to a valid flow & side
+ */
+static inline bool flow_sidx_valid(flow_sidx_t sidx)
+{
+ return sidx.flow < FLOW_MAX;
+}
+
+/**
* flow_sidx_eq() - Test if two sidx values are equal
* @a, @b: sidx values
*
diff --git a/flow_table.h b/flow_table.h
index 1b16349..226ddbd 100644
--- a/flow_table.h
+++ b/flow_table.h
@@ -73,7 +73,7 @@ static inline unsigned flow_idx(const struct flow_common *f)
*/
static inline union flow *flow_at_sidx(flow_sidx_t sidx)
{
- if (sidx.flow >= FLOW_MAX)
+ if (!flow_sidx_valid(sidx))
return NULL;
return FLOW(sidx.flow);
}
diff --git a/tcp.c b/tcp.c
index a490920..75b959a 100644
--- a/tcp.c
+++ b/tcp.c
@@ -880,8 +880,7 @@ static inline unsigned tcp_hash_probe(const struct ctx *c,
flow_sidx_t sidx = FLOW_SIDX(conn, TAPSIDE(conn));
/* Linear probing */
- while (!flow_sidx_eq(tc_hash[b], FLOW_SIDX_NONE) &&
- !flow_sidx_eq(tc_hash[b], sidx))
+ while (flow_sidx_valid(tc_hash[b]) && !flow_sidx_eq(tc_hash[b], sidx))
b = mod_sub(b, 1, TCP_HASH_TABLE_SIZE);
return b;
@@ -909,9 +908,9 @@ static void tcp_hash_remove(const struct ctx *c,
const struct tcp_tap_conn *conn)
{
unsigned b = tcp_hash_probe(c, conn), s;
- union flow *flow = flow_at_sidx(tc_hash[b]);
+ union flow *flow;
- if (!flow)
+ if (!flow_sidx_valid(tc_hash[b]))
return; /* Redundant remove */
flow_dbg(conn, "hash table remove: sock %i, bucket: %u", conn->sock, b);