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>
Subject: [PATCH 04/18] packet: Use iov_tail with packet_add()
Date: Wed,  2 Apr 2025 19:23:29 +0200	[thread overview]
Message-ID: <20250402172343.858187-5-lvivier@redhat.com> (raw)
In-Reply-To: <20250402172343.858187-1-lvivier@redhat.com>

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
---
 iov.h    |  1 +
 packet.c | 15 ++++++++++++---
 packet.h |  8 +++++---
 tap.c    | 32 ++++++++++++++++++--------------
 4 files changed, 36 insertions(+), 20 deletions(-)

diff --git a/iov.h b/iov.h
index f9b5fdf0803e..99442d031549 100644
--- a/iov.h
+++ b/iov.h
@@ -17,6 +17,7 @@
 
 #include <unistd.h>
 #include <string.h>
+#include <stdbool.h>
 
 #define IOV_OF_LVALUE(lval) \
 	(struct iovec){ .iov_base = &(lval), .iov_len = sizeof(lval) }
diff --git a/packet.c b/packet.c
index bcac03750dc0..8b11e0850ff6 100644
--- a/packet.c
+++ b/packet.c
@@ -64,15 +64,16 @@ static int packet_check_range(const struct pool *p, const char *ptr, size_t len,
 /**
  * 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, NULL means no trace()
  * @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 (idx >= p->size) {
 		trace("add packet index %zu to pool with size %zu, %s:%i",
@@ -80,6 +81,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 d099f026631b..f386295da203 100644
--- a/packet.h
+++ b/packet.h
@@ -6,6 +6,8 @@
 #ifndef PACKET_H
 #define PACKET_H
 
+#include "iov.h"
+
 /* Maximum size of a single packet stored in pool, including headers */
 #define PACKET_MAX_LEN	UINT16_MAX
 
@@ -28,15 +30,15 @@ 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_do(const struct pool *p, const size_t idx,
 		    size_t offset, size_t len, size_t *left,
 		    const char *func, int line);
 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(p, idx, offset, len, left)				\
 	packet_get_do(p, idx, offset, len, left, __func__, __LINE__)
diff --git a/tap.c b/tap.c
index ab3effe80f89..4b54807c4101 100644
--- a/tap.c
+++ b/tap.c
@@ -683,6 +683,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;
 
@@ -694,7 +695,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;
 		}
@@ -739,7 +741,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);
@@ -753,7 +756,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;
 		}
@@ -802,7 +806,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++) {
@@ -858,6 +863,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;
@@ -911,7 +917,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;
@@ -930,7 +937,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;
@@ -984,7 +992,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++) {
@@ -1058,18 +1067,13 @@ 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:
-		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:
-		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;
-- 
@@ -683,6 +683,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;
 
@@ -694,7 +695,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;
 		}
@@ -739,7 +741,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);
@@ -753,7 +756,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;
 		}
@@ -802,7 +806,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++) {
@@ -858,6 +863,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;
@@ -911,7 +917,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;
@@ -930,7 +937,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;
@@ -984,7 +992,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++) {
@@ -1058,18 +1067,13 @@ 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:
-		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:
-		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-04-02 17:23 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-04-02 17:23 [PATCH 00/18] Introduce discontiguous frames management Laurent Vivier
2025-04-02 17:23 ` [PATCH 01/18] arp: Don't mix incoming and outgoing buffers Laurent Vivier
2025-04-03  1:57   ` David Gibson
2025-04-02 17:23 ` [PATCH 02/18] iov: Update IOV_REMOVE_HEADER() and IOV_PEEK_HEADER() Laurent Vivier
2025-04-03  2:36   ` David Gibson
2025-04-02 17:23 ` [PATCH 03/18] tap: Use iov_tail with tap_add_packet() Laurent Vivier
2025-04-03  4:50   ` David Gibson
2025-04-02 17:23 ` Laurent Vivier [this message]
2025-04-03  4:54   ` [PATCH 04/18] packet: Use iov_tail with packet_add() David Gibson
2025-04-02 17:23 ` [PATCH 05/18] packet: Add packet_base() Laurent Vivier
2025-04-03  4:59   ` David Gibson
2025-04-02 17:23 ` [PATCH 06/18] arp: Convert to iov_tail Laurent Vivier
2025-04-03  5:00   ` David Gibson
2025-04-02 17:23 ` [PATCH 07/18] ndp: " Laurent Vivier
2025-04-03  5:01   ` David Gibson
2025-04-02 17:23 ` [PATCH 08/18] icmp: " Laurent Vivier
2025-04-03  5:04   ` David Gibson
2025-04-02 17:23 ` [PATCH 09/18] udp: " Laurent Vivier
2025-04-03  5:11   ` David Gibson
2025-04-02 17:23 ` [PATCH 10/18] tcp: Convert tcp_tap_handler() to use iov_tail Laurent Vivier
2025-04-03  5:14   ` David Gibson
2025-04-02 17:23 ` [PATCH 11/18] tcp: Convert tcp_data_from_tap() " Laurent Vivier
2025-04-03  5:20   ` David Gibson
2025-04-02 17:23 ` [PATCH 12/18] dhcpv6: Convert to iov_tail Laurent Vivier
2025-04-03  5:21   ` David Gibson
2025-04-02 17:23 ` [PATCH 13/18] dhcpv6: move offset initialization out of dhcpv6_opt() Laurent Vivier
2025-04-03  5:25   ` David Gibson
2025-04-02 17:23 ` [PATCH 14/18] dhcpv6: Use iov_tail in dhcpv6_opt() Laurent Vivier
2025-04-03  5:37   ` David Gibson
2025-04-02 17:23 ` [PATCH 15/18] dhcp: Convert to iov_tail Laurent Vivier
2025-04-03  5:47   ` David Gibson
2025-04-02 17:23 ` [PATCH 16/18] tap: " Laurent Vivier
2025-04-03 23:19   ` David Gibson
2025-04-02 17:23 ` [PATCH 17/18] ip: Use iov_tail in ipv6_l4hdr() Laurent Vivier
2025-04-03 23:21   ` David Gibson
2025-04-02 17:23 ` [PATCH 18/18] tap: Convert to iov_tail Laurent Vivier
2025-04-03 23:26   ` David Gibson

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=20250402172343.858187-5-lvivier@redhat.com \
    --to=lvivier@redhat.com \
    --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).