aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorLaurent Vivier <lvivier@redhat.com>2024-11-28 13:08:41 +0100
committerStefano Brivio <sbrivio@redhat.com>2024-11-28 14:03:16 +0100
commit020c8b7127e38872e68bffb30ad388001e088552 (patch)
treebc4f9ad34ef1909598962b53364a5b972deaf30c
parentd9c0f8eefb0015a5a06c7259666c877fff6fbe92 (diff)
downloadpasst-020c8b7127e38872e68bffb30ad388001e088552.tar
passt-020c8b7127e38872e68bffb30ad388001e088552.tar.gz
passt-020c8b7127e38872e68bffb30ad388001e088552.tar.bz2
passt-020c8b7127e38872e68bffb30ad388001e088552.tar.lz
passt-020c8b7127e38872e68bffb30ad388001e088552.tar.xz
passt-020c8b7127e38872e68bffb30ad388001e088552.tar.zst
passt-020c8b7127e38872e68bffb30ad388001e088552.zip
tcp_vu: Compute IPv4 header checksum if dlen changes
In tcp_vu_data_from_sock() we compute IPv4 header checksum only for the first and the last packets, and re-use the first packet checksum for all the other packets as the content of the header doesn't change. It's more accurate to check the dlen value to know if the checksum should change as dlen is the only information that can change in the loop. Signed-off-by: Laurent Vivier <lvivier@redhat.com> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r--tcp_vu.c12
1 files changed, 5 insertions, 7 deletions
diff --git a/tcp_vu.c b/tcp_vu.c
index 5d5c97d..10e17d3 100644
--- a/tcp_vu.c
+++ b/tcp_vu.c
@@ -354,12 +354,12 @@ int tcp_vu_data_from_sock(const struct ctx *c, struct tcp_tap_conn *conn)
uint32_t wnd_scaled = conn->wnd_from_tap << conn->ws_from_tap;
struct vu_dev *vdev = c->vdev;
struct vu_virtq *vq = &vdev->vq[VHOST_USER_RX_QUEUE];
+ ssize_t len, previous_dlen;
size_t hdrlen, fillsize;
int v6 = CONN_V6(conn);
uint32_t already_sent;
const uint16_t *check;
int i, iov_cnt;
- ssize_t len;
if (!vu_queue_enabled(vq) || !vu_queue_started(vq)) {
debug("Got packet, but RX virtqueue not usable yet");
@@ -433,19 +433,17 @@ int tcp_vu_data_from_sock(const struct ctx *c, struct tcp_tap_conn *conn)
*/
hdrlen = tcp_vu_hdrlen(v6);
- for (i = 0, check = NULL; i < head_cnt; i++) {
+ for (i = 0, previous_dlen = -1, check = NULL; i < head_cnt; i++) {
struct iovec *iov = &elem[head[i]].in_sg[0];
int buf_cnt = head[i + 1] - head[i];
ssize_t dlen = iov_size(iov, buf_cnt) - hdrlen;
vu_set_vnethdr(vdev, iov->iov_base, buf_cnt);
- /* we compute IPv4 header checksum only for the
- * first and the last, all other checksums are the
- * same as the first one
- */
- if (i + 1 == head_cnt)
+ /* The IPv4 header checksum varies only with dlen */
+ if (previous_dlen != dlen)
check = NULL;
+ previous_dlen = dlen;
tcp_vu_prepare(c, conn, iov, buf_cnt, &check, !*c->pcap);