On Fri, Apr 11, 2025 at 03:10:20PM +0200, Laurent Vivier wrote: > Use packet_base() and extract headers using IOV_REMOVE_HEADER() > and IOV_PEEK_HEADER() rather than packet_get(). > > Signed-off-by: Laurent Vivier > --- > iov.c | 1 - > udp.c | 34 +++++++++++++++++++++++----------- > 2 files changed, 23 insertions(+), 12 deletions(-) > > diff --git a/iov.c b/iov.c > index 9e3786e6efe8..d09e51190d54 100644 > --- a/iov.c > +++ b/iov.c > @@ -175,7 +175,6 @@ size_t iov_size(const struct iovec *iov, size_t iov_cnt) > * iov array, a negative value if there is no enough room in the > * destination iov array > */ > -/* cppcheck-suppress unusedFunction */ > int iov_slice(struct iovec *dst_iov, size_t dst_iov_cnt, > const struct iovec *iov, size_t iov_cnt, > size_t offset, size_t *bytes) > diff --git a/udp.c b/udp.c > index ab3e9d20fd74..75526f743994 100644 > --- a/udp.c > +++ b/udp.c > @@ -862,15 +862,20 @@ int udp_tap_handler(const struct ctx *c, uint8_t pif, > struct iovec m[UIO_MAXIOV]; > const struct udphdr *uh; > struct udp_flow *uflow; > - int i, s, count = 0; > + int i, j, s, count = 0; > + struct iov_tail data; > flow_sidx_t tosidx; > in_port_t src, dst; > + struct udphdr uhc; > uint8_t topif; > socklen_t sl; > > ASSERT(!c->no_udp); > > - uh = packet_get(p, idx, 0, sizeof(*uh), NULL); > + if (!packet_base(p, idx, &data)) > + return 1; > + > + uh = IOV_PEEK_HEADER(&data, uhc); > if (!uh) > return 1; > > @@ -907,23 +912,30 @@ int udp_tap_handler(const struct ctx *c, uint8_t pif, > > pif_sockaddr(c, &to_sa, &sl, topif, &toside->eaddr, toside->eport); > > - for (i = 0; i < (int)p->count - idx; i++) { > - struct udphdr *uh_send; > - size_t len; > + for (i = 0, j = 0; i < (int)p->count - idx && j < UIO_MAXIOV; i++) { > + const struct udphdr *uh_send; > > - uh_send = packet_get(p, idx + i, 0, sizeof(*uh), &len); > + if (!packet_base(p, idx + i, &data)) > + return p->count - idx; > + > + uh_send = IOV_REMOVE_HEADER(&data, uhc); > if (!uh_send) > return p->count - idx; > > mm[i].msg_hdr.msg_name = &to_sa; > mm[i].msg_hdr.msg_namelen = sl; > > - if (len) { > - m[i].iov_base = (char *)(uh_send + 1); > - m[i].iov_len = len; > + if (data.cnt) { > + int len; Variables named 'len' or similar are usually byte counts, not item counts. So maybe a different name here? > + > + len = iov_slice(&m[j], UIO_MAXIOV - j, > + &data.iov[0], data.cnt, data.off, NULL); Might be nice to have a wrapper around iov_slice() that turns the whole of an iov_tail into a new plain iov. > + if (len < 0) > + return p->count - idx; > > - mm[i].msg_hdr.msg_iov = m + i; > - mm[i].msg_hdr.msg_iovlen = 1; > + mm[i].msg_hdr.msg_iov = &m[j]; > + mm[i].msg_hdr.msg_iovlen = len; > + j += len; > } else { > mm[i].msg_hdr.msg_iov = NULL; > mm[i].msg_hdr.msg_iovlen = 0; -- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson