Currently tap_send_frames() expects the frames it is given to include the vnet_len field, even in pasta mode which doesn't use it (although it need not be initialized in that case). To match, tap_iov_base() and tap_iov_len() construct the frame in that way. This will inconvenience future changes, so alter things to set the buffers to include just the frame needed by the tap backend type. Signed-off-by: David Gibson <david(a)gibson.dropbear.id.au> --- tap.c | 5 ++--- tap.h | 6 ++++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/tap.c b/tap.c index d0dd72c..5ec6b70 100644 --- a/tap.c +++ b/tap.c @@ -317,8 +317,7 @@ static void tap_send_frames_pasta(struct ctx *c, size_t i; for (i = 0; i < n; i++) { - if (write(c->fd_tap, (char *)iov->iov_base + 4, - iov->iov_len - 4) < 0) { + if (write(c->fd_tap, (char *)iov->iov_base, iov->iov_len) < 0) { debug("tap write: %s", strerror(errno)); if (errno != EAGAIN && errno != EWOULDBLOCK) tap_handler(c, c->fd_tap, EPOLLERR, NULL); @@ -383,7 +382,7 @@ void tap_send_frames(struct ctx *c, const struct iovec *iov, size_t n) else tap_send_frames_pasta(c, iov, n); - pcap_multiple(iov, n, sizeof(uint32_t)); + pcap_multiple(iov, n, c->mode == MODE_PASST ? sizeof(uint32_t) : 0); } /** diff --git a/tap.h b/tap.h index 8fe460a..40cf480 100644 --- a/tap.h +++ b/tap.h @@ -20,8 +20,10 @@ struct tap_hdr { static inline size_t tap_hdr_len_(const struct ctx *c) { - (void)c; - return sizeof(struct tap_hdr); + if (c->mode == MODE_PASST) + return sizeof(struct tap_hdr); + else + return sizeof(struct ethhdr); } /** -- 2.39.0