On 16/09/2024 09:00, David Gibson wrote:
--- a/tap.c +++ b/tap.c @@ -58,6 +58,7 @@ #include "packet.h" #include "tap.h" #include "log.h" +#include "vhost_user.h"
/* IPv4 (plus ARP) and IPv6 message batches from tap/guest to IP handlers */ static PACKET_POOL_NOINIT(pool_tap4, TAP_MSGS, pkt_buf); @@ -78,16 +79,22 @@ void tap_send_single(const struct ctx *c, const void *data, size_t l2len) struct iovec iov[2]; size_t iovcnt = 0;
- if (c->mode == MODE_PASST) { + switch (c->mode) { + case MODE_PASST: iov[iovcnt] = IOV_OF_LVALUE(vnet_len); iovcnt++; - } - - iov[iovcnt].iov_base = (void *)data; - iov[iovcnt].iov_len = l2len; - iovcnt++; + /* fall through */ + case MODE_PASTA: + iov[iovcnt].iov_base = (void *)data; + iov[iovcnt].iov_len = l2len; + iovcnt++;
- tap_send_frames(c, iov, iovcnt, 1); + tap_send_frames(c, iov, iovcnt, 1); + break; + case MODE_VU: + vu_send(c->vdev, data, l2len); I'm a bit uneasy re-introducing a parallel send function for the slow path, rather than using a common tap_send_frames() interface. Any chance you can unify those sensibly? Bearing in mind that this_is_ the slow path, so if you have to copy a bunch of stuff, that's ok.
I tried but it's over complicated to take in input an iovec array and to use another iovec array (provided by the guest) to send data. It's easier to have a buffer and to copy it to the iovec array buffers of the guest. Moreover we don't need to have a tap_send_frames_vu() (see vu_handle_tx()), so we will introduce it to always send an iovec array with only one entry. Thanks, Laurent