public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
From: Laurent Vivier <lvivier@redhat.com>
To: passt-dev@passt.top
Cc: Laurent Vivier <lvivier@redhat.com>,
	David Gibson <david@gibson.dropbear.id.au>
Subject: [PATCH v7 06/31] packet: Use iov_tail with packet_add()
Date: Mon, 23 Jun 2025 13:06:10 +0200	[thread overview]
Message-ID: <20250623110635.1478625-7-lvivier@redhat.com> (raw)
In-Reply-To: <20250623110635.1478625-1-lvivier@redhat.com>

Modify the interface of packet_add_do() to take an iov_tail
rather than a memory pointer and length.

Internally it only supports iovec array with only one entry,
after being pruned. We can accept iovec array with several
entries if the offset allows the function to reduce the number
of entries to 1.

tap4_handler() is updated to create an iov_tail value using
IOV_TAIL_FROM_BUF() from the buffer and the length.

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
---
 packet.c | 15 ++++++++++++---
 packet.h |  7 ++++---
 tap.c    | 32 ++++++++++++++++++--------------
 3 files changed, 34 insertions(+), 20 deletions(-)

diff --git a/packet.c b/packet.c
index 72c61580be1e..98ded4e27aae 100644
--- a/packet.c
+++ b/packet.c
@@ -87,15 +87,16 @@ bool pool_full(const struct pool *p)
 /**
  * packet_add_do() - Add data as packet descriptor to given pool
  * @p:		Existing pool
- * @len:	Length of new descriptor
- * @start:	Start of data
+ * @data:	Data to add
  * @func:	For tracing: name of calling function
  * @line:	For tracing: caller line of function call
  */
-void packet_add_do(struct pool *p, size_t len, const char *start,
+void packet_add_do(struct pool *p, struct iov_tail *data,
 		   const char *func, int line)
 {
 	size_t idx = p->count;
+	const char *start;
+	size_t len;
 
 	if (pool_full(p)) {
 		debug("add packet index %zu to pool with size %zu, %s:%i",
@@ -103,6 +104,14 @@ void packet_add_do(struct pool *p, size_t len, const char *start,
 		return;
 	}
 
+	if (!iov_tail_prune(data))
+		return;
+
+	ASSERT(data->cnt == 1); /* we don't support iovec */
+
+	len = data->iov[0].iov_len - data->off;
+	start = (char *)data->iov[0].iov_base + data->off;
+
 	if (packet_check_range(p, start, len, func, line))
 		return;
 
diff --git a/packet.h b/packet.h
index c94780a5ea54..af40b39b5251 100644
--- a/packet.h
+++ b/packet.h
@@ -7,6 +7,7 @@
 #define PACKET_H
 
 #include <stdbool.h>
+#include "iov.h"
 
 /* Maximum size of a single packet stored in pool, including headers */
 #define PACKET_MAX_LEN	((size_t)UINT16_MAX)
@@ -30,7 +31,7 @@ struct pool {
 };
 
 int vu_packet_check_range(void *buf, const char *ptr, size_t len);
-void packet_add_do(struct pool *p, size_t len, const char *start,
+void packet_add_do(struct pool *p, struct iov_tail *data,
 		   const char *func, int line);
 void *packet_get_try_do(const struct pool *p, const size_t idx,
 			size_t offset, size_t len, size_t *left,
@@ -41,8 +42,8 @@ void *packet_get_do(const struct pool *p, const size_t idx,
 bool pool_full(const struct pool *p);
 void pool_flush(struct pool *p);
 
-#define packet_add(p, len, start)					\
-	packet_add_do(p, len, start, __func__, __LINE__)
+#define packet_add(p, data)					\
+	packet_add_do(p, data, __func__, __LINE__)
 
 #define packet_get_try(p, idx, offset, len, left)			\
 	packet_get_try_do(p, idx, offset, len, left, __func__, __LINE__)
diff --git a/tap.c b/tap.c
index c5520bf3bc76..8d2b118152f1 100644
--- a/tap.c
+++ b/tap.c
@@ -709,6 +709,7 @@ resume:
 		size_t l2len, l3len, hlen, l4len;
 		const struct ethhdr *eh;
 		const struct udphdr *uh;
+		struct iov_tail data;
 		struct iphdr *iph;
 		const char *l4h;
 
@@ -720,7 +721,8 @@ resume:
 		if (ntohs(eh->h_proto) == ETH_P_ARP) {
 			PACKET_POOL_P(pkt, 1, in->buf, in->buf_size);
 
-			packet_add(pkt, l2len, (char *)eh);
+			data = IOV_TAIL_FROM_BUF((void *)eh, l2len, 0);
+			packet_add(pkt, &data);
 			arp(c, pkt);
 			continue;
 		}
@@ -765,7 +767,8 @@ resume:
 
 			tap_packet_debug(iph, NULL, NULL, 0, NULL, 1);
 
-			packet_add(pkt, l4len, l4h);
+			data = IOV_TAIL_FROM_BUF((void *)l4h, l4len, 0);
+			packet_add(pkt, &data);
 			icmp_tap_handler(c, PIF_TAP, AF_INET,
 					 &iph->saddr, &iph->daddr,
 					 pkt, now);
@@ -779,7 +782,8 @@ resume:
 		if (iph->protocol == IPPROTO_UDP) {
 			PACKET_POOL_P(pkt, 1, in->buf, in->buf_size);
 
-			packet_add(pkt, l2len, (char *)eh);
+			data = IOV_TAIL_FROM_BUF((void *)eh, l2len, 0);
+			packet_add(pkt, &data);
 			if (dhcp(c, pkt))
 				continue;
 		}
@@ -830,7 +834,8 @@ resume:
 #undef L4_SET
 
 append:
-		packet_add((struct pool *)&seq->p, l4len, l4h);
+		data = IOV_TAIL_FROM_BUF((void *)l4h, l4len, 0);
+		packet_add((struct pool *)&seq->p, &data);
 	}
 
 	for (j = 0, seq = tap4_l4; j < seq_count; j++, seq++) {
@@ -886,6 +891,7 @@ resume:
 		struct in6_addr *saddr, *daddr;
 		const struct ethhdr *eh;
 		const struct udphdr *uh;
+		struct iov_tail data;
 		struct ipv6hdr *ip6h;
 		uint8_t proto;
 		char *l4h;
@@ -939,7 +945,8 @@ resume:
 			if (l4len < sizeof(struct icmp6hdr))
 				continue;
 
-			packet_add(pkt, l4len, l4h);
+			data = IOV_TAIL_FROM_BUF(l4h, l4len, 0);
+			packet_add(pkt, &data);
 
 			if (ndp(c, (struct icmp6hdr *)l4h, saddr, pkt))
 				continue;
@@ -958,7 +965,8 @@ resume:
 		if (proto == IPPROTO_UDP) {
 			PACKET_POOL_P(pkt, 1, in->buf, in->buf_size);
 
-			packet_add(pkt, l4len, l4h);
+			data = IOV_TAIL_FROM_BUF(l4h, l4len, 0);
+			packet_add(pkt, &data);
 
 			if (dhcpv6(c, pkt, saddr, daddr))
 				continue;
@@ -1014,7 +1022,8 @@ resume:
 #undef L4_SET
 
 append:
-		packet_add((struct pool *)&seq->p, l4len, l4h);
+		data = IOV_TAIL_FROM_BUF(l4h, l4len, 0);
+		packet_add((struct pool *)&seq->p, &data);
 	}
 
 	for (j = 0, seq = tap6_l4; j < seq_count; j++, seq++) {
@@ -1090,9 +1099,6 @@ void tap_add_packet(struct ctx *c, struct iov_tail *data,
 		proto_update_l2_buf(c->guest_mac, NULL);
 	}
 
-	iov_tail_prune(data);
-	ASSERT(data->cnt == 1); /* packet_add() doesn't support iovec */
-
 	switch (ntohs(eh->h_proto)) {
 	case ETH_P_ARP:
 	case ETH_P_IP:
@@ -1100,16 +1106,14 @@ void tap_add_packet(struct ctx *c, struct iov_tail *data,
 			tap4_handler(c, pool_tap4, now);
 			pool_flush(pool_tap4);
 		}
-		packet_add(pool_tap4, data->iov[0].iov_len - data->off,
-			   (char *)data->iov[0].iov_base + data->off);
+		packet_add(pool_tap4, data);
 		break;
 	case ETH_P_IPV6:
 		if (pool_full(pool_tap6)) {
 			tap6_handler(c, pool_tap6, now);
 			pool_flush(pool_tap6);
 		}
-		packet_add(pool_tap6, data->iov[0].iov_len - data->off,
-			   (char *)data->iov[0].iov_base + data->off);
+		packet_add(pool_tap6, data);
 		break;
 	default:
 		break;
-- 
@@ -709,6 +709,7 @@ resume:
 		size_t l2len, l3len, hlen, l4len;
 		const struct ethhdr *eh;
 		const struct udphdr *uh;
+		struct iov_tail data;
 		struct iphdr *iph;
 		const char *l4h;
 
@@ -720,7 +721,8 @@ resume:
 		if (ntohs(eh->h_proto) == ETH_P_ARP) {
 			PACKET_POOL_P(pkt, 1, in->buf, in->buf_size);
 
-			packet_add(pkt, l2len, (char *)eh);
+			data = IOV_TAIL_FROM_BUF((void *)eh, l2len, 0);
+			packet_add(pkt, &data);
 			arp(c, pkt);
 			continue;
 		}
@@ -765,7 +767,8 @@ resume:
 
 			tap_packet_debug(iph, NULL, NULL, 0, NULL, 1);
 
-			packet_add(pkt, l4len, l4h);
+			data = IOV_TAIL_FROM_BUF((void *)l4h, l4len, 0);
+			packet_add(pkt, &data);
 			icmp_tap_handler(c, PIF_TAP, AF_INET,
 					 &iph->saddr, &iph->daddr,
 					 pkt, now);
@@ -779,7 +782,8 @@ resume:
 		if (iph->protocol == IPPROTO_UDP) {
 			PACKET_POOL_P(pkt, 1, in->buf, in->buf_size);
 
-			packet_add(pkt, l2len, (char *)eh);
+			data = IOV_TAIL_FROM_BUF((void *)eh, l2len, 0);
+			packet_add(pkt, &data);
 			if (dhcp(c, pkt))
 				continue;
 		}
@@ -830,7 +834,8 @@ resume:
 #undef L4_SET
 
 append:
-		packet_add((struct pool *)&seq->p, l4len, l4h);
+		data = IOV_TAIL_FROM_BUF((void *)l4h, l4len, 0);
+		packet_add((struct pool *)&seq->p, &data);
 	}
 
 	for (j = 0, seq = tap4_l4; j < seq_count; j++, seq++) {
@@ -886,6 +891,7 @@ resume:
 		struct in6_addr *saddr, *daddr;
 		const struct ethhdr *eh;
 		const struct udphdr *uh;
+		struct iov_tail data;
 		struct ipv6hdr *ip6h;
 		uint8_t proto;
 		char *l4h;
@@ -939,7 +945,8 @@ resume:
 			if (l4len < sizeof(struct icmp6hdr))
 				continue;
 
-			packet_add(pkt, l4len, l4h);
+			data = IOV_TAIL_FROM_BUF(l4h, l4len, 0);
+			packet_add(pkt, &data);
 
 			if (ndp(c, (struct icmp6hdr *)l4h, saddr, pkt))
 				continue;
@@ -958,7 +965,8 @@ resume:
 		if (proto == IPPROTO_UDP) {
 			PACKET_POOL_P(pkt, 1, in->buf, in->buf_size);
 
-			packet_add(pkt, l4len, l4h);
+			data = IOV_TAIL_FROM_BUF(l4h, l4len, 0);
+			packet_add(pkt, &data);
 
 			if (dhcpv6(c, pkt, saddr, daddr))
 				continue;
@@ -1014,7 +1022,8 @@ resume:
 #undef L4_SET
 
 append:
-		packet_add((struct pool *)&seq->p, l4len, l4h);
+		data = IOV_TAIL_FROM_BUF(l4h, l4len, 0);
+		packet_add((struct pool *)&seq->p, &data);
 	}
 
 	for (j = 0, seq = tap6_l4; j < seq_count; j++, seq++) {
@@ -1090,9 +1099,6 @@ void tap_add_packet(struct ctx *c, struct iov_tail *data,
 		proto_update_l2_buf(c->guest_mac, NULL);
 	}
 
-	iov_tail_prune(data);
-	ASSERT(data->cnt == 1); /* packet_add() doesn't support iovec */
-
 	switch (ntohs(eh->h_proto)) {
 	case ETH_P_ARP:
 	case ETH_P_IP:
@@ -1100,16 +1106,14 @@ void tap_add_packet(struct ctx *c, struct iov_tail *data,
 			tap4_handler(c, pool_tap4, now);
 			pool_flush(pool_tap4);
 		}
-		packet_add(pool_tap4, data->iov[0].iov_len - data->off,
-			   (char *)data->iov[0].iov_base + data->off);
+		packet_add(pool_tap4, data);
 		break;
 	case ETH_P_IPV6:
 		if (pool_full(pool_tap6)) {
 			tap6_handler(c, pool_tap6, now);
 			pool_flush(pool_tap6);
 		}
-		packet_add(pool_tap6, data->iov[0].iov_len - data->off,
-			   (char *)data->iov[0].iov_base + data->off);
+		packet_add(pool_tap6, data);
 		break;
 	default:
 		break;
-- 
2.49.0


  parent reply	other threads:[~2025-06-23 11:06 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-06-23 11:06 [PATCH v7 00/31] Introduce discontiguous frames management Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 01/31] style: Fix 'Return' comment style Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 02/31] arp: Don't mix incoming and outgoing buffers Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 03/31] iov: Introduce iov_tail_clone() and iov_tail_drop() Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 04/31] iov: Update IOV_REMOVE_HEADER() and IOV_PEEK_HEADER() Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 05/31] tap: Use iov_tail with tap_add_packet() Laurent Vivier
2025-06-23 11:06 ` Laurent Vivier [this message]
2025-06-23 11:06 ` [PATCH v7 07/31] packet: Add packet_data() Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 08/31] arp: Convert to iov_tail Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 09/31] ndp: " Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 10/31] icmp: " Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 11/31] udp: " Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 12/31] tcp: Convert tcp_tap_handler() to use iov_tail Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 13/31] tcp: Convert tcp_data_from_tap() " Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 14/31] dhcpv6: move offset initialization out of dhcpv6_opt() Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 15/31] dhcpv6: Extract sending of NotOnLink status Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 16/31] dhcpv6: Convert to iov_tail Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 17/31] dhcpv6: Use iov_tail in dhcpv6_opt() Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 18/31] dhcp: Convert to iov_tail Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 19/31] ip: Use iov_tail in ipv6_l4hdr() Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 20/31] tap: Convert tap4_handler() to iov_tail Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 21/31] tap: Convert tap6_handler() " Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 22/31] packet: rename packet_data() to packet_get() Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 23/31] arp: use iov_tail rather than pool Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 24/31] dhcp: " Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 25/31] dhcpv6: " Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 26/31] icmp: " Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 27/31] ndp: " Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 28/31] packet: remove PACKET_POOL() and PACKET_POOL_P() Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 29/31] packet: remove unused parameter from PACKET_POOL_DECL() Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 30/31] packet: add memory regions information into pool Laurent Vivier
2025-06-23 11:06 ` [PATCH v7 31/31] packet: use buf to store iovec array Laurent Vivier

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=20250623110635.1478625-7-lvivier@redhat.com \
    --to=lvivier@redhat.com \
    --cc=david@gibson.dropbear.id.au \
    --cc=passt-dev@passt.top \
    /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).