public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
From: Jon Maloy <jmaloy@redhat.com>
To: passt-dev@passt.top, sbrivio@redhat.com, lvivier@redhat.com,
	dgibson@redhat.com, jmaloy@redhat.com
Subject: [PATCH v5 1/2] tcp: set ip and eth headers in l2 tap queues on the fly
Date: Mon, 28 Oct 2024 22:13:59 -0400	[thread overview]
Message-ID: <20241029021400.784052-2-jmaloy@redhat.com> (raw)
In-Reply-To: <20241029021400.784052-1-jmaloy@redhat.com>

l2 tap queue entries are currently initialized at system start, and
reused with preset headers through its whole life time. The only
fields we need to update per message are things like payload size
and checksums.

If we want to reuse these entries between ipv4 and ipv6 messages we
will need to set the pointer to the right header on the fly per
message, since the header type may differ between entries in the same
queue.

The same needs to be done for the ethernet header.

We do these changes here.

Signed-off-by: Jon Maloy <jmaloy@redhat.com>

---
v2: Setting pointers to pre-initialized IP and MAC headers instead of
    copying them in on the fly.
v3: Adapted to D. Gibson's recent commit eliminitaing overlapping memcpy()
v5: Fixed two bugs as per feedback from D. Gibson.
---
 tcp_buf.c | 50 ++++++++++++++++++++++++++++----------------------
 1 file changed, 28 insertions(+), 22 deletions(-)

diff --git a/tcp_buf.c b/tcp_buf.c
index cb6742c..e249c6b 100644
--- a/tcp_buf.c
+++ b/tcp_buf.c
@@ -130,8 +130,7 @@ void tcp_sock4_iov_init(const struct ctx *c)
 		iov = tcp4_l2_iov[i];
 
 		iov[TCP_IOV_TAP] = tap_hdr_iov(c, &tcp4_payload_tap_hdr[i]);
-		iov[TCP_IOV_ETH] = IOV_OF_LVALUE(tcp4_eth_src);
-		iov[TCP_IOV_IP] = IOV_OF_LVALUE(tcp4_payload_ip[i]);
+		iov[TCP_IOV_ETH].iov_len = sizeof(struct ethhdr);
 		iov[TCP_IOV_PAYLOAD].iov_base = &tcp4_payload[i];
 	}
 
@@ -173,8 +172,7 @@ void tcp_sock6_iov_init(const struct ctx *c)
 		iov = tcp6_l2_iov[i];
 
 		iov[TCP_IOV_TAP] = tap_hdr_iov(c, &tcp6_payload_tap_hdr[i]);
-		iov[TCP_IOV_ETH] = IOV_OF_LVALUE(tcp6_eth_src);
-		iov[TCP_IOV_IP] = IOV_OF_LVALUE(tcp6_payload_ip[i]);
+		iov[TCP_IOV_ETH].iov_len = sizeof(struct ethhdr);
 		iov[TCP_IOV_PAYLOAD].iov_base = &tcp6_payload[i];
 	}
 
@@ -273,11 +271,17 @@ int tcp_buf_send_flag(const struct ctx *c, struct tcp_tap_conn *conn, int flags)
 	uint32_t seq;
 	int ret;
 
-	if (CONN_V4(conn))
-		iov = tcp4_l2_flags_iov[tcp4_flags_used++];
-	else
-		iov = tcp6_l2_flags_iov[tcp6_flags_used++];
-
+	if (CONN_V4(conn)) {
+		iov = tcp4_l2_flags_iov[tcp4_flags_used];
+		iov[TCP_IOV_IP] = IOV_OF_LVALUE(tcp4_flags_ip[tcp4_flags_used]);
+		iov[TCP_IOV_ETH].iov_base = &tcp4_eth_src;
+		tcp4_flags_used++;
+	} else {
+		iov = tcp6_l2_flags_iov[tcp6_flags_used];
+		iov[TCP_IOV_IP] = IOV_OF_LVALUE(tcp6_flags_ip[tcp6_flags_used]);
+		iov[TCP_IOV_ETH].iov_base = &tcp6_eth_src;
+		tcp6_flags_used++;
+	}
 	payload = iov[TCP_IOV_PAYLOAD].iov_base;
 
 	seq = conn->seq_to_tap;
@@ -296,21 +300,19 @@ int tcp_buf_send_flag(const struct ctx *c, struct tcp_tap_conn *conn, int flags)
 
 	if (flags & DUP_ACK) {
 		struct iovec *dup_iov;
-		int i;
 
 		if (CONN_V4(conn))
 			dup_iov = tcp4_l2_flags_iov[tcp4_flags_used++];
 		else
 			dup_iov = tcp6_l2_flags_iov[tcp6_flags_used++];
 
-		for (i = 0; i < TCP_NUM_IOVS; i++) {
-			/* All frames share the same ethernet header buffer */
-			if (i != TCP_IOV_ETH) {
-				memcpy(dup_iov[i].iov_base, iov[i].iov_base,
-				       iov[i].iov_len);
-			}
-		}
-		dup_iov[TCP_IOV_PAYLOAD].iov_len = iov[TCP_IOV_PAYLOAD].iov_len;
+		memcpy(dup_iov[TCP_IOV_TAP].iov_base, iov[TCP_IOV_TAP].iov_base,
+		       iov[TCP_IOV_TAP].iov_len);
+		dup_iov[TCP_IOV_ETH].iov_base = iov[TCP_IOV_ETH].iov_base;
+		dup_iov[TCP_IOV_IP] = iov[TCP_IOV_IP];
+		memcpy(dup_iov[TCP_IOV_PAYLOAD].iov_base,
+		       iov[TCP_IOV_PAYLOAD].iov_base, l4len);
+		dup_iov[TCP_IOV_PAYLOAD].iov_len = l4len;
 	}
 
 	if (CONN_V4(conn)) {
@@ -350,8 +352,10 @@ static void tcp_data_to_tap(const struct ctx *c, struct tcp_tap_conn *conn,
 		}
 
 		tcp4_frame_conns[tcp4_payload_used] = conn;
-
-		iov = tcp4_l2_iov[tcp4_payload_used++];
+		iov = tcp4_l2_iov[tcp4_payload_used];
+		iov[TCP_IOV_IP] =
+			IOV_OF_LVALUE(tcp4_payload_ip[tcp4_payload_used++]);
+		iov[TCP_IOV_ETH].iov_base = &tcp4_eth_src;
 		l4len = tcp_l2_buf_fill_headers(conn, iov, dlen, check, seq,
 						false);
 		iov[TCP_IOV_PAYLOAD].iov_len = l4len;
@@ -359,8 +363,10 @@ static void tcp_data_to_tap(const struct ctx *c, struct tcp_tap_conn *conn,
 			tcp_payload_flush(c);
 	} else if (CONN_V6(conn)) {
 		tcp6_frame_conns[tcp6_payload_used] = conn;
-
-		iov = tcp6_l2_iov[tcp6_payload_used++];
+		iov = tcp6_l2_iov[tcp6_payload_used];
+		iov[TCP_IOV_IP] =
+			IOV_OF_LVALUE(tcp6_payload_ip[tcp6_payload_used++]);
+		iov[TCP_IOV_ETH].iov_base = &tcp6_eth_src;
 		l4len = tcp_l2_buf_fill_headers(conn, iov, dlen, NULL, seq,
 						false);
 		iov[TCP_IOV_PAYLOAD].iov_len = l4len;
-- 
@@ -130,8 +130,7 @@ void tcp_sock4_iov_init(const struct ctx *c)
 		iov = tcp4_l2_iov[i];
 
 		iov[TCP_IOV_TAP] = tap_hdr_iov(c, &tcp4_payload_tap_hdr[i]);
-		iov[TCP_IOV_ETH] = IOV_OF_LVALUE(tcp4_eth_src);
-		iov[TCP_IOV_IP] = IOV_OF_LVALUE(tcp4_payload_ip[i]);
+		iov[TCP_IOV_ETH].iov_len = sizeof(struct ethhdr);
 		iov[TCP_IOV_PAYLOAD].iov_base = &tcp4_payload[i];
 	}
 
@@ -173,8 +172,7 @@ void tcp_sock6_iov_init(const struct ctx *c)
 		iov = tcp6_l2_iov[i];
 
 		iov[TCP_IOV_TAP] = tap_hdr_iov(c, &tcp6_payload_tap_hdr[i]);
-		iov[TCP_IOV_ETH] = IOV_OF_LVALUE(tcp6_eth_src);
-		iov[TCP_IOV_IP] = IOV_OF_LVALUE(tcp6_payload_ip[i]);
+		iov[TCP_IOV_ETH].iov_len = sizeof(struct ethhdr);
 		iov[TCP_IOV_PAYLOAD].iov_base = &tcp6_payload[i];
 	}
 
@@ -273,11 +271,17 @@ int tcp_buf_send_flag(const struct ctx *c, struct tcp_tap_conn *conn, int flags)
 	uint32_t seq;
 	int ret;
 
-	if (CONN_V4(conn))
-		iov = tcp4_l2_flags_iov[tcp4_flags_used++];
-	else
-		iov = tcp6_l2_flags_iov[tcp6_flags_used++];
-
+	if (CONN_V4(conn)) {
+		iov = tcp4_l2_flags_iov[tcp4_flags_used];
+		iov[TCP_IOV_IP] = IOV_OF_LVALUE(tcp4_flags_ip[tcp4_flags_used]);
+		iov[TCP_IOV_ETH].iov_base = &tcp4_eth_src;
+		tcp4_flags_used++;
+	} else {
+		iov = tcp6_l2_flags_iov[tcp6_flags_used];
+		iov[TCP_IOV_IP] = IOV_OF_LVALUE(tcp6_flags_ip[tcp6_flags_used]);
+		iov[TCP_IOV_ETH].iov_base = &tcp6_eth_src;
+		tcp6_flags_used++;
+	}
 	payload = iov[TCP_IOV_PAYLOAD].iov_base;
 
 	seq = conn->seq_to_tap;
@@ -296,21 +300,19 @@ int tcp_buf_send_flag(const struct ctx *c, struct tcp_tap_conn *conn, int flags)
 
 	if (flags & DUP_ACK) {
 		struct iovec *dup_iov;
-		int i;
 
 		if (CONN_V4(conn))
 			dup_iov = tcp4_l2_flags_iov[tcp4_flags_used++];
 		else
 			dup_iov = tcp6_l2_flags_iov[tcp6_flags_used++];
 
-		for (i = 0; i < TCP_NUM_IOVS; i++) {
-			/* All frames share the same ethernet header buffer */
-			if (i != TCP_IOV_ETH) {
-				memcpy(dup_iov[i].iov_base, iov[i].iov_base,
-				       iov[i].iov_len);
-			}
-		}
-		dup_iov[TCP_IOV_PAYLOAD].iov_len = iov[TCP_IOV_PAYLOAD].iov_len;
+		memcpy(dup_iov[TCP_IOV_TAP].iov_base, iov[TCP_IOV_TAP].iov_base,
+		       iov[TCP_IOV_TAP].iov_len);
+		dup_iov[TCP_IOV_ETH].iov_base = iov[TCP_IOV_ETH].iov_base;
+		dup_iov[TCP_IOV_IP] = iov[TCP_IOV_IP];
+		memcpy(dup_iov[TCP_IOV_PAYLOAD].iov_base,
+		       iov[TCP_IOV_PAYLOAD].iov_base, l4len);
+		dup_iov[TCP_IOV_PAYLOAD].iov_len = l4len;
 	}
 
 	if (CONN_V4(conn)) {
@@ -350,8 +352,10 @@ static void tcp_data_to_tap(const struct ctx *c, struct tcp_tap_conn *conn,
 		}
 
 		tcp4_frame_conns[tcp4_payload_used] = conn;
-
-		iov = tcp4_l2_iov[tcp4_payload_used++];
+		iov = tcp4_l2_iov[tcp4_payload_used];
+		iov[TCP_IOV_IP] =
+			IOV_OF_LVALUE(tcp4_payload_ip[tcp4_payload_used++]);
+		iov[TCP_IOV_ETH].iov_base = &tcp4_eth_src;
 		l4len = tcp_l2_buf_fill_headers(conn, iov, dlen, check, seq,
 						false);
 		iov[TCP_IOV_PAYLOAD].iov_len = l4len;
@@ -359,8 +363,10 @@ static void tcp_data_to_tap(const struct ctx *c, struct tcp_tap_conn *conn,
 			tcp_payload_flush(c);
 	} else if (CONN_V6(conn)) {
 		tcp6_frame_conns[tcp6_payload_used] = conn;
-
-		iov = tcp6_l2_iov[tcp6_payload_used++];
+		iov = tcp6_l2_iov[tcp6_payload_used];
+		iov[TCP_IOV_IP] =
+			IOV_OF_LVALUE(tcp6_payload_ip[tcp6_payload_used++]);
+		iov[TCP_IOV_ETH].iov_base = &tcp6_eth_src;
 		l4len = tcp_l2_buf_fill_headers(conn, iov, dlen, NULL, seq,
 						false);
 		iov[TCP_IOV_PAYLOAD].iov_len = l4len;
-- 
2.45.2


  reply	other threads:[~2024-10-29  2:14 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-29  2:13 [PATCH v5 0/2] tcp: unify IPv4 and IPv6 tap queues Jon Maloy
2024-10-29  2:13 ` Jon Maloy [this message]
2024-10-29  4:11   ` [PATCH v5 1/2] tcp: set ip and eth headers in l2 tap queues on the fly David Gibson
2024-10-29  2:14 ` [PATCH v5 2/2] tcp: unify l2 TCPv4 and TCPv6 queues and structures Jon Maloy
2024-10-29  4:11 ` [PATCH v5 0/2] tcp: unify IPv4 and IPv6 tap queues David Gibson
2024-10-29 13:57 ` Stefano Brivio

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20241029021400.784052-2-jmaloy@redhat.com \
    --to=jmaloy@redhat.com \
    --cc=dgibson@redhat.com \
    --cc=lvivier@redhat.com \
    --cc=passt-dev@passt.top \
    --cc=sbrivio@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://passt.top/passt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).