aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorLaurent Vivier <lvivier@redhat.com>2025-09-02 09:52:28 +0200
committerStefano Brivio <sbrivio@redhat.com>2025-09-03 20:42:21 +0200
commitde469a3e85b06377762a52c82269ff3eaf2ae3ea (patch)
tree1ddf1a544ca78b64cb8dbbd45d7f35c5dda6d69e
parent720d8fc06946bef73ddb042c431a0c71bd6cf409 (diff)
downloadpasst-de469a3e85b06377762a52c82269ff3eaf2ae3ea.tar
passt-de469a3e85b06377762a52c82269ff3eaf2ae3ea.tar.gz
passt-de469a3e85b06377762a52c82269ff3eaf2ae3ea.tar.bz2
passt-de469a3e85b06377762a52c82269ff3eaf2ae3ea.tar.lz
passt-de469a3e85b06377762a52c82269ff3eaf2ae3ea.tar.xz
passt-de469a3e85b06377762a52c82269ff3eaf2ae3ea.tar.zst
passt-de469a3e85b06377762a52c82269ff3eaf2ae3ea.zip
packet: Use iov_tail with packet_add()
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> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r--packet.c15
-rw-r--r--packet.h7
-rw-r--r--tap.c32
3 files changed, 34 insertions, 20 deletions
diff --git a/packet.c b/packet.c
index 72c6158..98ded4e 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 c94780a..af40b39 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 b1de0c5..7cb7494 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;