aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorLaurent Vivier <lvivier@redhat.com>2025-09-02 09:52:34 +0200
committerStefano Brivio <sbrivio@redhat.com>2025-09-03 20:42:33 +0200
commit87cc7abc8536064e851006cdf772aa4a53e3f1cf (patch)
tree34c8eb0ae24b0a5c65058c1cccd290bc8f2639ed
parentd9604f06570e472f46c41a0f84945efd5fa2a162 (diff)
downloadpasst-87cc7abc8536064e851006cdf772aa4a53e3f1cf.tar
passt-87cc7abc8536064e851006cdf772aa4a53e3f1cf.tar.gz
passt-87cc7abc8536064e851006cdf772aa4a53e3f1cf.tar.bz2
passt-87cc7abc8536064e851006cdf772aa4a53e3f1cf.tar.lz
passt-87cc7abc8536064e851006cdf772aa4a53e3f1cf.tar.xz
passt-87cc7abc8536064e851006cdf772aa4a53e3f1cf.tar.zst
passt-87cc7abc8536064e851006cdf772aa4a53e3f1cf.zip
tcp: Convert tcp_tap_handler() to use iov_tail
Use packet_data() and extract headers using IOV_REMOVE_HEADER() and iov_remove_header_() rather than packet_get(). Signed-off-by: Laurent Vivier <lvivier@redhat.com> Reviewed-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r--tcp.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/tcp.c b/tcp.c
index 957b498..f1048d7 100644
--- a/tcp.c
+++ b/tcp.c
@@ -310,6 +310,16 @@
#include "tcp_buf.h"
#include "tcp_vu.h"
+/*
+ * The size of TCP header (including options) is given by doff (Data Offset)
+ * that is a 4-bit value specifying the number of 32-bit words in the header.
+ * The maximum value of doff is 15 [(1 << 4) - 1].
+ * The maximum length in bytes of options is 15 minus the number of 32-bit
+ * words in the minimal TCP header (5) multiplied by the length of a 32-bit
+ * word (4).
+ */
+#define OPTLEN_MAX (((1UL << 4) - 1 - 5) * 4UL)
+
#ifndef __USE_MISC
/* From Linux UAPI, missing in netinet/tcp.h provided by musl */
struct tcp_repair_opt {
@@ -1957,8 +1967,11 @@ int tcp_tap_handler(const struct ctx *c, uint8_t pif, sa_family_t af,
const struct pool *p, int idx, const struct timespec *now)
{
struct tcp_tap_conn *conn;
+ struct tcphdr th_storage;
const struct tcphdr *th;
- size_t optlen, len;
+ char optsc[OPTLEN_MAX];
+ struct iov_tail data;
+ size_t optlen, l4len;
const char *opts;
union flow *flow;
flow_sidx_t sidx;
@@ -1967,15 +1980,19 @@ int tcp_tap_handler(const struct ctx *c, uint8_t pif, sa_family_t af,
(void)pif;
- th = packet_get(p, idx, 0, sizeof(*th), &len);
+ if (!packet_data(p, idx, &data))
+ return 1;
+
+ l4len = iov_tail_size(&data);
+
+ th = IOV_REMOVE_HEADER(&data, th_storage);
if (!th)
return 1;
- len += sizeof(*th);
optlen = th->doff * 4UL - sizeof(*th);
/* Static checkers might fail to see this: */
- optlen = MIN(optlen, ((1UL << 4) /* from doff width */ - 6) * 4UL);
- opts = packet_get(p, idx, sizeof(*th), optlen, NULL);
+ optlen = MIN(optlen, OPTLEN_MAX);
+ opts = (char *)iov_remove_header_(&data, &optsc[0], optlen, 1);
sidx = flow_lookup_af(c, IPPROTO_TCP, PIF_TAP, af, saddr, daddr,
ntohs(th->source), ntohs(th->dest));
@@ -1987,7 +2004,7 @@ int tcp_tap_handler(const struct ctx *c, uint8_t pif, sa_family_t af,
tcp_conn_from_tap(c, af, saddr, daddr, th,
opts, optlen, now);
else
- tcp_rst_no_conn(c, af, saddr, daddr, flow_lbl, th, len);
+ tcp_rst_no_conn(c, af, saddr, daddr, flow_lbl, th, l4len);
return 1;
}
@@ -1995,7 +2012,7 @@ int tcp_tap_handler(const struct ctx *c, uint8_t pif, sa_family_t af,
ASSERT(pif_at_sidx(sidx) == PIF_TAP);
conn = &flow->tcp;
- flow_trace(conn, "packet length %zu from tap", len);
+ flow_trace(conn, "packet length %zu from tap", l4len);
if (th->rst) {
conn_event(c, conn, CLOSED);