From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: passt.top; dkim=pass (2048-bit key; secure) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.a=rsa-sha256 header.s=202502 header.b=SOuRCXN3; dkim-atps=neutral Received: from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by passt.top (Postfix) with ESMTPS id 90F095A0276 for ; Wed, 19 Feb 2025 03:28:46 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202502; t=1739932118; bh=Z1WViTjLZnT8PL81gEnoPohvW8EzbxPIXSse+BvnBJw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SOuRCXN3hoayJ3Bv0wk2Vf0dgJFS5XGrmp0M7czrDEe+FF/D9Fw9YX+jPHU1D+ruj ueoLbXnZLJ+LH35K/NbiZZo8eTKsSuJulrNgQ0VsYpewShfSOlRWsdJWkGDAPP8H5/ fv6lHCbARHnCZb+8NNnNQNc/xSNm/Qx5g6SYvumit76a7/C272wdOgUVxmhFiLNBKq m5HxWNnmzVDRo4oJ/O0NZNOgnntpp0YADQDNyGRPTzm6taiYUA2KcNmvbUv3NH5tu2 vah5k0xe8PVUwv0PUWKsfVvTOenbWUs8mk/XyJVSppkawOBGSnwdQistgbe94uRw16 kev912LGfa4Cg== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4YyL124KLyz4x3S; Wed, 19 Feb 2025 13:28:38 +1100 (AEDT) From: David Gibson To: passt-dev@passt.top, Stefano Brivio Subject: [PATCH 3/3] flow: Clean up and generalise flow traversal macros Date: Wed, 19 Feb 2025 13:28:36 +1100 Message-ID: <20250219022836.3345243-4-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250219022836.3345243-1-david@gibson.dropbear.id.au> References: <20250219022836.3345243-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: PVDBRECVMDB2DXPYJJODXQJBE3V4XUFY X-Message-ID-Hash: PVDBRECVMDB2DXPYJJODXQJBE3V4XUFY X-MailFrom: dgibson@gandalf.ozlabs.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: David Gibson X-Mailman-Version: 3.3.8 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: The migration code introduced a number of 'foreach' macros to traverse the flow table. These aren't inherently tied to migration, so polish up their naming, move them to flow_table.h and also use in flow_defer_handler() which is the other place we need to traverse the whole table. For now we keep foreach_established_tcp_flow() as is. Signed-off-by: David Gibson --- flow.c | 36 ++++++++---------------------------- flow_table.h | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 28 deletions(-) diff --git a/flow.c b/flow.c index 602fea79..bb5dcc3c 100644 --- a/flow.c +++ b/flow.c @@ -53,28 +53,8 @@ const uint8_t flow_proto[] = { static_assert(ARRAY_SIZE(flow_proto) == FLOW_NUM_TYPES, "flow_proto[] doesn't match enum flow_type"); -#define foreach_flow(flow) \ - for ((flow) = flowtab; FLOW_IDX(flow) < FLOW_MAX; (flow)++) \ - if ((flow)->f.state == FLOW_STATE_FREE) \ - (flow) += (flow)->free.n - 1; \ - else - -#define foreach_active_flow(flow) \ - foreach_flow((flow)) \ - if ((flow)->f.state != FLOW_STATE_ACTIVE) \ - /* NOLINTNEXTLINE(bugprone-branch-clone) */ \ - continue; \ - else - -#define foreach_tcp_flow(flow) \ - foreach_active_flow((flow)) \ - if ((flow)->f.type != FLOW_TCP) \ - /* NOLINTNEXTLINE(bugprone-branch-clone) */ \ - continue; \ - else - #define foreach_established_tcp_flow(flow) \ - foreach_tcp_flow((flow)) \ + flow_foreach_of_type((flow), FLOW_TCP) \ if (!tcp_flow_is_established(&(flow)->tcp)) \ /* NOLINTNEXTLINE(bugprone-branch-clone) */ \ continue; \ @@ -801,7 +781,7 @@ void flow_defer_handler(const struct ctx *c, const struct timespec *now) struct flow_free_cluster *free_head = NULL; unsigned *last_next = &flow_first_free; bool timer = false; - unsigned idx; + union flow *flow; if (timespec_diff_ms(now, &flow_timer_run) >= FLOW_TIMER_INTERVAL) { timer = true; @@ -810,8 +790,7 @@ void flow_defer_handler(const struct ctx *c, const struct timespec *now) ASSERT(!flow_new_entry); /* Incomplete flow at end of cycle */ - for (idx = 0; idx < FLOW_MAX; idx++) { - union flow *flow = &flowtab[idx]; + flow_foreach_slot(flow) { bool closed = false; switch (flow->f.state) { @@ -828,12 +807,12 @@ void flow_defer_handler(const struct ctx *c, const struct timespec *now) } else { /* New free cluster, add to chain */ free_head = &flow->free; - *last_next = idx; + *last_next = FLOW_IDX(flow); last_next = &free_head->next; } /* Skip remaining empty entries */ - idx += skip - 1; + flow += skip - 1; continue; } @@ -886,14 +865,15 @@ void flow_defer_handler(const struct ctx *c, const struct timespec *now) if (free_head) { /* Add slot to current free cluster */ - ASSERT(idx == FLOW_IDX(free_head) + free_head->n); + ASSERT(FLOW_IDX(flow) == + FLOW_IDX(free_head) + free_head->n); free_head->n++; flow->free.n = flow->free.next = 0; } else { /* Create new free cluster */ free_head = &flow->free; free_head->n = 1; - *last_next = idx; + *last_next = FLOW_IDX(flow); last_next = &free_head->next; } } else { diff --git a/flow_table.h b/flow_table.h index 9a2ff24a..fd2c57b9 100644 --- a/flow_table.h +++ b/flow_table.h @@ -50,6 +50,42 @@ extern union flow flowtab[]; #define flow_foreach_sidei(sidei_) \ for ((sidei_) = INISIDE; (sidei_) < SIDES; (sidei_)++) + +/** + * flow_foreach_slot() - Step through each flow table entry + * @flow: Takes values of pointer to each flow table entry + * + * Includes FREE slots. + */ +#define flow_foreach_slot(flow) \ + for ((flow) = flowtab; FLOW_IDX(flow) < FLOW_MAX; (flow)++) + +/** + * flow_foreach() - Step through each active flow + * @flow: Takes values of pointer to each active flow + */ +#define flow_foreach(flow) \ + flow_foreach_slot((flow)) \ + if ((flow)->f.state == FLOW_STATE_FREE) \ + (flow) += (flow)->free.n - 1; \ + else if ((flow)->f.state != FLOW_STATE_ACTIVE) { \ + flow_err((flow), "Bad flow state during traversal"); \ + continue; \ + } else + +/** + * flow_foreach_of_type() - Step through each active flow of given type + * @flow: Takes values of pointer to each flow + * @type_: Type of flow to traverse + */ +#define flow_foreach_of_type(flow, type_) \ + flow_foreach((flow)) \ + if ((flow)->f.type != (type_)) \ + /* NOLINTNEXTLINE(bugprone-branch-clone) */ \ + continue; \ + else + + /** flow_idx() - Index of flow from common structure * @f: Common flow fields pointer * -- 2.48.1