On Tue, Aug 05, 2025 at 05:46:10PM +0200, Laurent Vivier wrote:
Use packet_data() and extract headers using IOV_PEEK_HEADER() rather than packet_get().
Signed-off-by: Laurent Vivier
Reviewed-by: David Gibson
--- tcp.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-)
diff --git a/tcp.c b/tcp.c index f1048d7230c9..e0efc4cacb9b 100644 --- a/tcp.c +++ b/tcp.c @@ -1651,16 +1651,22 @@ static int tcp_data_from_tap(const struct ctx *c, struct tcp_tap_conn *conn,
for (i = idx, iov_i = 0; i < (int)p->count; i++) { uint32_t seq, seq_offset, ack_seq; + struct tcphdr th_storage; const struct tcphdr *th; - char *data; - size_t off; + struct iov_tail data; + size_t off, size; + int count;
- th = packet_get(p, i, 0, sizeof(*th), &len); + if (!packet_data(p, i, &data)) + return -1; + + th = IOV_PEEK_HEADER(&data, th_storage); if (!th) return -1; - len += sizeof(*th); + len = iov_tail_size(&data);
off = th->doff * 4UL; + if (off < sizeof(*th) || off > len) return -1;
@@ -1670,9 +1676,7 @@ static int tcp_data_from_tap(const struct ctx *c, struct tcp_tap_conn *conn, }
len -= off; - data = packet_get(p, i, off, len, NULL); - if (!data) - continue; + iov_tail_drop(&data, off);
seq = ntohl(th->seq); if (SEQ_LT(seq, conn->seq_from_tap) && len <= 1) { @@ -1746,10 +1750,14 @@ static int tcp_data_from_tap(const struct ctx *c, struct tcp_tap_conn *conn, continue; }
- tcp_iov[iov_i].iov_base = data + seq_offset; - tcp_iov[iov_i].iov_len = len - seq_offset; - seq_from_tap += tcp_iov[iov_i].iov_len; - iov_i++; + iov_tail_drop(&data, seq_offset); + size = len - seq_offset; + count = iov_tail_clone(&tcp_iov[iov_i], UIO_MAXIOV - iov_i, + &data); + if (count < 0) + break; + seq_from_tap += size; + iov_i += count;
if (keep == i) keep = -1;
-- David Gibson (he or they) | 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