Signed-off-by: Laurent Vivier
---
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
#include
+#include
#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;
--
2.49.0