aboutgitcodebugslistschat
path: root/flow.c
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2024-07-18 15:26:46 +1000
committerStefano Brivio <sbrivio@redhat.com>2024-07-19 18:33:39 +0200
commita45a7e97982acc7c9d00fddb0192fbbfcd2030d6 (patch)
tree371c1d0ce44f09463702386c6dc0c75a6b65cf1c /flow.c
parent8abd06e9fac93b60cc98d90f7310d94cfc295090 (diff)
downloadpasst-a45a7e97982acc7c9d00fddb0192fbbfcd2030d6.tar
passt-a45a7e97982acc7c9d00fddb0192fbbfcd2030d6.tar.gz
passt-a45a7e97982acc7c9d00fddb0192fbbfcd2030d6.tar.bz2
passt-a45a7e97982acc7c9d00fddb0192fbbfcd2030d6.tar.lz
passt-a45a7e97982acc7c9d00fddb0192fbbfcd2030d6.tar.xz
passt-a45a7e97982acc7c9d00fddb0192fbbfcd2030d6.tar.zst
passt-a45a7e97982acc7c9d00fddb0192fbbfcd2030d6.zip
udp: Create flows for datagrams from originating sockets
This implements the first steps of tracking UDP packets with the flow table rather than its own (buggy) set of port maps. Specifically we create flow table entries for datagrams received from a socket (PIF_HOST or PIF_SPLICE). When splitting datagrams from sockets into batches, we group by the flow as well as splicesrc. This may result in smaller batches, but makes things easier down the line. We can re-optimise this later if necessary. For now we don't do anything else with the flow, not even match reply packets to the same flow. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'flow.c')
-rw-r--r--flow.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/flow.c b/flow.c
index 27340df..4e337d4 100644
--- a/flow.c
+++ b/flow.c
@@ -37,6 +37,7 @@ const char *flow_type_str[] = {
[FLOW_TCP_SPLICE] = "TCP connection (spliced)",
[FLOW_PING4] = "ICMP ping sequence",
[FLOW_PING6] = "ICMPv6 ping sequence",
+ [FLOW_UDP] = "UDP flow",
};
static_assert(ARRAY_SIZE(flow_type_str) == FLOW_NUM_TYPES,
"flow_type_str[] doesn't match enum flow_type");
@@ -46,6 +47,7 @@ const uint8_t flow_proto[] = {
[FLOW_TCP_SPLICE] = IPPROTO_TCP,
[FLOW_PING4] = IPPROTO_ICMP,
[FLOW_PING6] = IPPROTO_ICMPV6,
+ [FLOW_UDP] = IPPROTO_UDP,
};
static_assert(ARRAY_SIZE(flow_proto) == FLOW_NUM_TYPES,
"flow_proto[] doesn't match enum flow_type");
@@ -702,6 +704,32 @@ flow_sidx_t flow_lookup_af(const struct ctx *c,
}
/**
+ * flow_lookup_sa() - Look up a flow given an endpoint socket address
+ * @c: Execution context
+ * @proto: Protocol of the flow (IP L4 protocol number)
+ * @pif: Interface of the flow
+ * @esa: Socket address of the endpoint
+ * @fport: Forwarding port number
+ *
+ * Return: sidx of the matching flow & side, FLOW_SIDX_NONE if not found
+ */
+flow_sidx_t flow_lookup_sa(const struct ctx *c, uint8_t proto, uint8_t pif,
+ const void *esa, in_port_t fport)
+{
+ struct flowside side = {
+ .fport = fport,
+ };
+
+ inany_from_sockaddr(&side.eaddr, &side.eport, esa);
+ if (inany_v4(&side.eaddr))
+ side.faddr = inany_any4;
+ else
+ side.faddr = inany_any6;
+
+ return flowside_lookup(c, proto, pif, &side);
+}
+
+/**
* flow_defer_handler() - Handler for per-flow deferred and timed tasks
* @c: Execution context
* @now: Current timestamp
@@ -780,6 +808,10 @@ void flow_defer_handler(const struct ctx *c, const struct timespec *now)
if (timer)
closed = icmp_ping_timer(c, &flow->ping, now);
break;
+ case FLOW_UDP:
+ if (timer)
+ closed = udp_flow_timer(c, &flow->udp, now);
+ break;
default:
/* Assume other flow types don't need any handling */
;