The migration code adds more places that need to iterate through the flow table. Introduce some macros to make that easier. Signed-off-by: David Gibson <david(a)gibson.dropbear.id.au> --- flow.c | 14 +++++++------- flow_table.h | 31 +++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/flow.c b/flow.c index 3ac551bd..d9b888ce 100644 --- a/flow.c +++ b/flow.c @@ -771,7 +771,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; @@ -780,8 +780,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) { @@ -798,12 +797,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; } @@ -856,14 +855,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..6ff6d0f6 100644 --- a/flow_table.h +++ b/flow_table.h @@ -74,6 +74,37 @@ static inline unsigned flow_idx(const struct flow_common *f) */ #define FLOW(idx) (&flowtab[(idx)]) +/** + * flow_foreach_slot() - 'for' type macro to step through every flow slot + * @flow_: Points to each flow entry in order, including free slots + */ +#define flow_foreach_slot(flow_) \ + for ((flow_) = flowtab; FLOW_IDX(flow_) < FLOW_MAX; (flow_)++) + +/** + * flow_foreach() - 'for' type macro to step through every active flow + * @flow_: Points to each active flow in order + */ +#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_), "BUG: Traversing non-active flow"); \ + continue; \ + } else + +/** + * flow_foreach_of_type() - step through active flows of one type + * @flow_: Points to each active flow in order + * @type_: Flow type to select + */ +#define flow_foreach_of_type(flow_, type_) \ + flow_foreach(flow_) \ + if ((flow_)->f.type != (type_)) \ + continue; \ + else + /** flow_at_sidx() - Flow entry for a given sidx * @sidx: Flow & side index * -- 2.48.1