[PATCH 0/6] Introduce unified flow table, first steps
Here's my latest revision of some of the basics of the flow table. So far it's basically just a renaming of the existing TCP connection table. It's used for some new logging helpers, but otherwise doesn't really function any differently. However, this subset of the flow table work no longer bloats flow/connection entries over a single cache line. That removes the most prominent drawback of earlier revisions, meaning I think this series is ready for merge now. Doing so will mean the later series making more substantive changes to the flow behaviour are simpler. David Gibson (6): test: Make handling of shell prompts with escapes a little more reliable flow, tcp: Generalise connection types flow, tcp: Move TCP connection table to unified flow table flow, tcp: Consolidate flow pointer<->index helpers flow: Make unified version of flow table compaction flow, tcp: Add logging helpers for connection related messages Makefile | 14 +-- flow.c | 87 +++++++++++++++++++ flow.h | 60 +++++++++++++ flow_table.h | 45 ++++++++++ passt.h | 3 + tcp.c | 232 +++++++++++++++++++++++--------------------------- tcp.h | 5 -- tcp_conn.h | 46 +++------- tcp_splice.c | 88 +++++++++---------- test/lib/term | 6 +- 10 files changed, 361 insertions(+), 225 deletions(-) create mode 100644 flow.c create mode 100644 flow.h create mode 100644 flow_table.h -- 2.42.0
When using the old-style "pane" methods of executing commands during the
tests, we need to scan the shell output for prompts in order to tell when
commands have finished. This is inherently unreliable because commands
could output things that look like prompts, and prompts might not look like
we expect them to. The only way to really fix this is to use a better way
of dispatching commands, like the newer "context" system.
However, it's awkward to convert everything to "context" right at the
moment, so we're still relying on some tests that do work most of the time.
It is, however, particularly sensitive to fancy coloured prompts using
escape sequences. Currently we try to handle this by stripping actual
ESC characters with tr, then looking for some common variants.
We can do a bit better: instead strip all escape sequences using sed before
looking for our prompt. Or, at least, any one using [a-zA-Z] as the
terminating character. Strictly speaking ANSI escapes can be terminated by
any character in 0x40..0x7e, which isn't easily expressed in a regexp.
This should capture all common ones, though.
With this transformation we can simplify the list of patterns we then look
for as a prompt, removing some redundant variants.
Signed-off-by: David Gibson
Currently TCP connections use a 1-bit selector, 'spliced', to determine the
rest of the contents of the structure. We want to generalise the TCP
connection table to other types of flows in other protocols. Make a start
on this by replacing the tcp_conn_common structure with a new flow_common
structure with an enum rather than a simple boolean indicating the type of
flow.
Signed-off-by: David Gibson
We want to generalise "connection" tracking to things other than true TCP
connections. Continue implenenting this by renaming the TCP connection
table to the "flow table" and moving it to flow.c. The definitions are
split between flow.h and flow_table.h - we need this separation to avoid
circular dependencies: the definitions in flow.h will be needed by many
headers using the flow mechanism, but flow_table.h needs all those protocol
specific headers in order to define the full flow table entry.
Signed-off-by: David Gibson
Both tcp.c and tcp_splice.c define CONN_IDX() variants to find the index
of their connection structures in the connection table, now become the
unified flow table. We can easily combine these into a common helper.
While we're there, add some trickery for some additional type safety.
They also define their own CONN() versions, which aren't so easily combined
since they need to return different types, but we can have them use a
common helper.
Signed-off-by: David Gibson
tcp_table_compact() will move entries in the connection/flow table to keep
it compact when other entries are removed. The moved entries need not have
the same type as the flow removed, so it needs to be able to handle moving
any type of flow. Therefore, move it to flow.c rather than being
purportedly TCP specific.
Signed-off-by: David Gibson
Most of the messages logged by the TCP code (be they errors, debug or
trace messages) are related to a specific connection / flow. We're fairly
consistent about prefixing these with the type of connection and the
connection / flow index. However there are a few places where we put the
index later in the message or omit it entirely. The template with the
prefix is also a little bulky to carry around for every message,
particularly for spliced connections.
To help keep this consistent, introduce some helpers to log messages
linked to a specific flow. It takes the flow as a parameter and adds a
uniform prefix to each message. This makes things slightly neater now, but
more importantly will help keep formatting consistent as we add more things
to the flow table.
Signed-off-by: David Gibson
On Thu, 23 Nov 2023 13:36:29 +1100
David Gibson
Most of the messages logged by the TCP code (be they errors, debug or trace messages) are related to a specific connection / flow. We're fairly consistent about prefixing these with the type of connection and the connection / flow index. However there are a few places where we put the index later in the message or omit it entirely. The template with the prefix is also a little bulky to carry around for every message, particularly for spliced connections.
To help keep this consistent, introduce some helpers to log messages linked to a specific flow. It takes the flow as a parameter and adds a uniform prefix to each message. This makes things slightly neater now, but more importantly will help keep formatting consistent as we add more things to the flow table.
Signed-off-by: David Gibson
--- flow.c | 21 ++++++++++++++ flow.h | 14 +++++++++ tcp.c | 81 ++++++++++++++++++++++++---------------------------- tcp_splice.c | 61 +++++++++++++++++---------------------- 4 files changed, 99 insertions(+), 78 deletions(-) diff --git a/flow.c b/flow.c index 0fff119..cb2cf62 100644 --- a/flow.c +++ b/flow.c @@ -64,3 +64,24 @@ void flow_table_compact(struct ctx *c, union flow *hole)
memset(from, 0, sizeof(*from)); } + +/** flow_log_ - Log flow-related message + * @f: flow the message is related to + * @pri: Log priority + * @fmt: Format string + * @...: printf-arguments + * + * @fmt must include an initial "%s" to expand to the prefix we generate + * (typically added by the flow_log() macro).
I don't understand how it does that -- flow_log() seems to just pass __VA_ARGS__ through?
+ */ +void flow_log_(const struct flow_common *f, int pri, const char *fmt, ...) +{ + char msg[BUFSIZ]; + va_list args; + + va_start(args, fmt); + (void)vsnprintf(msg, sizeof(msg), fmt, args); + va_end(args); + + logmsg(pri, "Flow %u (%s): %s", flow_idx(f), FLOW_TYPE(f), msg); +} diff --git a/flow.h b/flow.h index 9f49195..b6da516 100644 --- a/flow.h +++ b/flow.h @@ -43,4 +43,18 @@ union flow;
void flow_table_compact(struct ctx *c, union flow *hole);
+void flow_log_(const struct flow_common *f, int pri, const char *fmt, ...) + __attribute__((format(printf, 3, 4))); + +#define flow_log(f_, pri, ...) flow_log_(&(f_)->f, (pri), __VA_ARGS__) + +#define flow_dbg(f, ...) flow_log((f), LOG_DEBUG, __VA_ARGS__) +#define flow_err(f, ...) flow_log((f), LOG_ERR, __VA_ARGS__) + +#define flow_trace(f, ...) \ + do { \ + if (log_trace) \ + flow_dbg((f), __VA_ARGS__); \ + } while (0) + #endif /* FLOW_H */
-- Stefano
On Thu, Nov 23, 2023 at 07:58:45AM +0100, Stefano Brivio wrote:
On Thu, 23 Nov 2023 13:36:29 +1100 David Gibson
wrote: Most of the messages logged by the TCP code (be they errors, debug or trace messages) are related to a specific connection / flow. We're fairly consistent about prefixing these with the type of connection and the connection / flow index. However there are a few places where we put the index later in the message or omit it entirely. The template with the prefix is also a little bulky to carry around for every message, particularly for spliced connections.
To help keep this consistent, introduce some helpers to log messages linked to a specific flow. It takes the flow as a parameter and adds a uniform prefix to each message. This makes things slightly neater now, but more importantly will help keep formatting consistent as we add more things to the flow table.
Signed-off-by: David Gibson
--- flow.c | 21 ++++++++++++++ flow.h | 14 +++++++++ tcp.c | 81 ++++++++++++++++++++++++---------------------------- tcp_splice.c | 61 +++++++++++++++++---------------------- 4 files changed, 99 insertions(+), 78 deletions(-) diff --git a/flow.c b/flow.c index 0fff119..cb2cf62 100644 --- a/flow.c +++ b/flow.c @@ -64,3 +64,24 @@ void flow_table_compact(struct ctx *c, union flow *hole)
memset(from, 0, sizeof(*from)); } + +/** flow_log_ - Log flow-related message + * @f: flow the message is related to + * @pri: Log priority + * @fmt: Format string + * @...: printf-arguments + * + * @fmt must include an initial "%s" to expand to the prefix we generate + * (typically added by the flow_log() macro).
I don't understand how it does that -- flow_log() seems to just pass __VA_ARGS__ through?
Oops, that's a leftover from an earlier version. I formatting the prefix first, then adding it to the message, rather than the message first and adding it to the prefix. I was attempting to avoid a fixed size buffer for the message, but it just turned out weird and troublesome. Plus vlogmsg() has a fixed sized buffer anyway, so why bother. Anyway, I've removed the stale comment. -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
On Thu, Nov 23, 2023 at 01:36:23PM +1100, David Gibson wrote:
Here's my latest revision of some of the basics of the flow table. So far it's basically just a renaming of the existing TCP connection table. It's used for some new logging helpers, but otherwise doesn't really function any differently.
However, this subset of the flow table work no longer bloats flow/connection entries over a single cache line. That removes the most prominent drawback of earlier revisions, meaning I think this series is ready for merge now. Doing so will mean the later series making more substantive changes to the flow behaviour are simpler.
Since posting this, I've come up with some small revisions. So, please don't apply as is. I'll respin once you review incorporating both your feedback and the changes I already made.
David Gibson (6): test: Make handling of shell prompts with escapes a little more reliable flow, tcp: Generalise connection types flow, tcp: Move TCP connection table to unified flow table flow, tcp: Consolidate flow pointer<->index helpers flow: Make unified version of flow table compaction flow, tcp: Add logging helpers for connection related messages
Makefile | 14 +-- flow.c | 87 +++++++++++++++++++ flow.h | 60 +++++++++++++ flow_table.h | 45 ++++++++++ passt.h | 3 + tcp.c | 232 +++++++++++++++++++++++--------------------------- tcp.h | 5 -- tcp_conn.h | 46 +++------- tcp_splice.c | 88 +++++++++---------- test/lib/term | 6 +- 10 files changed, 361 insertions(+), 225 deletions(-) create mode 100644 flow.c create mode 100644 flow.h create mode 100644 flow_table.h
-- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
participants (2)
-
David Gibson
-
Stefano Brivio