Use packet_data() and extract headers using IOV_PEEK_HEADER() rather than packet_get(). Signed-off-by: Laurent Vivier <lvivier(a)redhat.com> --- tcp.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/tcp.c b/tcp.c index 67d656a1cf97..a25fbc7ae182 100644 --- a/tcp.c +++ b/tcp.c @@ -1651,15 +1651,21 @@ 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; const struct tcphdr *th; - char *data; - size_t off; + struct iov_tail data; + struct tcphdr thc; + 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, thc); if (!th) return -1; - len += sizeof(*th); + len = iov_tail_size(&data); off = th->doff * 4UL; + if (off < sizeof(*th) || off > len) return -1; @@ -1669,9 +1675,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) { @@ -1745,10 +1749,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_slice(&tcp_iov[iov_i], UIO_MAXIOV - iov_i, + &data, &size); + if (count < 0) + break; + seq_from_tap += size; + iov_i += count; if (keep == i) keep = -1; -- 2.49.0