mirror of
https://passt.top/passt
synced 2025-02-22 10:52:21 +00:00
flow: Clean up and generalise flow traversal macros
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 <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
b79a22d360
commit
65e317a8fc
36
flow.c
36
flow.c
@ -53,28 +53,8 @@ const uint8_t flow_proto[] = {
|
|||||||
static_assert(ARRAY_SIZE(flow_proto) == FLOW_NUM_TYPES,
|
static_assert(ARRAY_SIZE(flow_proto) == FLOW_NUM_TYPES,
|
||||||
"flow_proto[] doesn't match enum flow_type");
|
"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) \
|
#define foreach_established_tcp_flow(flow) \
|
||||||
foreach_tcp_flow((flow)) \
|
flow_foreach_of_type((flow), FLOW_TCP) \
|
||||||
if (!tcp_flow_is_established(&(flow)->tcp)) \
|
if (!tcp_flow_is_established(&(flow)->tcp)) \
|
||||||
/* NOLINTNEXTLINE(bugprone-branch-clone) */ \
|
/* NOLINTNEXTLINE(bugprone-branch-clone) */ \
|
||||||
continue; \
|
continue; \
|
||||||
@ -801,7 +781,7 @@ void flow_defer_handler(const struct ctx *c, const struct timespec *now)
|
|||||||
struct flow_free_cluster *free_head = NULL;
|
struct flow_free_cluster *free_head = NULL;
|
||||||
unsigned *last_next = &flow_first_free;
|
unsigned *last_next = &flow_first_free;
|
||||||
bool timer = false;
|
bool timer = false;
|
||||||
unsigned idx;
|
union flow *flow;
|
||||||
|
|
||||||
if (timespec_diff_ms(now, &flow_timer_run) >= FLOW_TIMER_INTERVAL) {
|
if (timespec_diff_ms(now, &flow_timer_run) >= FLOW_TIMER_INTERVAL) {
|
||||||
timer = true;
|
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 */
|
ASSERT(!flow_new_entry); /* Incomplete flow at end of cycle */
|
||||||
|
|
||||||
for (idx = 0; idx < FLOW_MAX; idx++) {
|
flow_foreach_slot(flow) {
|
||||||
union flow *flow = &flowtab[idx];
|
|
||||||
bool closed = false;
|
bool closed = false;
|
||||||
|
|
||||||
switch (flow->f.state) {
|
switch (flow->f.state) {
|
||||||
@ -828,12 +807,12 @@ void flow_defer_handler(const struct ctx *c, const struct timespec *now)
|
|||||||
} else {
|
} else {
|
||||||
/* New free cluster, add to chain */
|
/* New free cluster, add to chain */
|
||||||
free_head = &flow->free;
|
free_head = &flow->free;
|
||||||
*last_next = idx;
|
*last_next = FLOW_IDX(flow);
|
||||||
last_next = &free_head->next;
|
last_next = &free_head->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip remaining empty entries */
|
/* Skip remaining empty entries */
|
||||||
idx += skip - 1;
|
flow += skip - 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -886,14 +865,15 @@ void flow_defer_handler(const struct ctx *c, const struct timespec *now)
|
|||||||
|
|
||||||
if (free_head) {
|
if (free_head) {
|
||||||
/* Add slot to current free cluster */
|
/* 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++;
|
free_head->n++;
|
||||||
flow->free.n = flow->free.next = 0;
|
flow->free.n = flow->free.next = 0;
|
||||||
} else {
|
} else {
|
||||||
/* Create new free cluster */
|
/* Create new free cluster */
|
||||||
free_head = &flow->free;
|
free_head = &flow->free;
|
||||||
free_head->n = 1;
|
free_head->n = 1;
|
||||||
*last_next = idx;
|
*last_next = FLOW_IDX(flow);
|
||||||
last_next = &free_head->next;
|
last_next = &free_head->next;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
36
flow_table.h
36
flow_table.h
@ -50,6 +50,42 @@ extern union flow flowtab[];
|
|||||||
#define flow_foreach_sidei(sidei_) \
|
#define flow_foreach_sidei(sidei_) \
|
||||||
for ((sidei_) = INISIDE; (sidei_) < SIDES; (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
|
/** flow_idx() - Index of flow from common structure
|
||||||
* @f: Common flow fields pointer
|
* @f: Common flow fields pointer
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user