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). This will inconvenience future changes, so alter it to expect just the frame as appropriate for the tap backend type. We alter the TCP code which uses it to match, setting up the base of iovec to include or exclude the vnet_len as needed. Signed-off-by: David Gibson <david(a)gibson.dropbear.id.au> --- tap.c | 5 ++--- tcp.c | 30 ++++++++++++++++++++++-------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/tap.c b/tap.c index 558a734..2dd14f1 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); } PACKET_POOL_DECL(pool_l4, UIO_MAXIOV, pkt_buf); diff --git a/tcp.c b/tcp.c index f560b96..e5fa5ae 100644 --- a/tcp.c +++ b/tcp.c @@ -1053,8 +1053,9 @@ void tcp_update_l2_buf(const unsigned char *eth_d, const unsigned char *eth_s, /** * tcp_sock4_iov_init() - Initialise scatter-gather L2 buffers for IPv4 sockets + * @ctx: Execution context */ -static void tcp_sock4_iov_init(void) +static void tcp_sock4_iov_init(const struct ctx *c) { struct iovec *iov; int i; @@ -1076,18 +1077,25 @@ static void tcp_sock4_iov_init(void) } for (i = 0, iov = tcp4_l2_iov; i < TCP_FRAMES_MEM; i++, iov++) { - iov->iov_base = &tcp4_l2_buf[i].vnet_len; + if (c->mode == MODE_PASTA) + iov->iov_base = &tcp4_l2_buf[i].eh; + else + iov->iov_base = &tcp4_l2_buf[i].vnet_len; iov->iov_len = MSS_DEFAULT; } for (i = 0, iov = tcp4_l2_flags_iov; i < TCP_FRAMES_MEM; i++, iov++) - iov->iov_base = &tcp4_l2_flags_buf[i].vnet_len; + if (c->mode == MODE_PASTA) + iov->iov_base = &tcp4_l2_flags_buf[i].eh; + else + iov->iov_base = &tcp4_l2_flags_buf[i].vnet_len; } /** * tcp_sock6_iov_init() - Initialise scatter-gather L2 buffers for IPv6 sockets + * @ctx: Execution context */ -static void tcp_sock6_iov_init(void) +static void tcp_sock6_iov_init(const struct ctx *c) { struct iovec *iov; int i; @@ -1109,12 +1117,18 @@ static void tcp_sock6_iov_init(void) } for (i = 0, iov = tcp6_l2_iov; i < TCP_FRAMES_MEM; i++, iov++) { - iov->iov_base = &tcp6_l2_buf[i].vnet_len; + if (c->mode == MODE_PASTA) + iov->iov_base = &tcp6_l2_buf[i].eh; + else + iov->iov_base = &tcp6_l2_buf[i].vnet_len; iov->iov_len = MSS_DEFAULT; } for (i = 0, iov = tcp6_l2_flags_iov; i < TCP_FRAMES_MEM; i++, iov++) - iov->iov_base = &tcp6_l2_flags_buf[i].vnet_len; + if (c->mode == MODE_PASTA) + iov->iov_base = &tcp6_l2_flags_buf[i].eh; + else + iov->iov_base = &tcp6_l2_flags_buf[i].vnet_len; } /** @@ -3131,10 +3145,10 @@ int tcp_init(struct ctx *c) tcp_l2_mh[i] = (struct mmsghdr) { .msg_hdr.msg_iovlen = 1 }; if (c->ifi4) - tcp_sock4_iov_init(); + tcp_sock4_iov_init(c); if (c->ifi6) - tcp_sock6_iov_init(); + tcp_sock6_iov_init(c); memset(init_sock_pool4, 0xff, sizeof(init_sock_pool4)); memset(init_sock_pool6, 0xff, sizeof(init_sock_pool6)); -- 2.38.1