Add helpers that tell whether a redirector instance should create an AF_PACKET capture socket or inject socket. Later commits use them when wiring up the TAP datapath.
While here, let the indev-only inject role enable allow_send_when_stopped, and guard filter_redirector_vm_state_change() against a missing nc. Signed-off-by: Cindy Lu <[email protected]> --- net/filter-mirror.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/net/filter-mirror.c b/net/filter-mirror.c index ab711e8835..376b7da025 100644 --- a/net/filter-mirror.c +++ b/net/filter-mirror.c @@ -22,6 +22,7 @@ #include "qemu/error-report.h" #include "trace.h" #include "chardev/char-fe.h" +#include "net/vhost_net.h" #include "qemu/iov.h" #include "qemu/sockets.h" #include "block/aio-wait.h" @@ -62,6 +63,24 @@ typedef struct FilterSendCo { int ret; } FilterSendCo; +static bool filter_redirector_use_inject_netdev(NetFilterState *nf) +{ + MirrorState *s = FILTER_REDIRECTOR(nf); + + return s->indev && !s->outdev && + nf->netdev && + get_vhost_net(nf->netdev); +} + +static bool filter_redirector_use_capture_netdev(NetFilterState *nf) +{ + MirrorState *s = FILTER_REDIRECTOR(nf); + + return s->outdev && !s->indev && + nf->netdev && + get_vhost_net(nf->netdev); +} + static int _filter_send(MirrorState *s, char *buf, ssize_t size) @@ -318,13 +337,13 @@ filter_redirector_refresh_allow_send_when_stopped(NetFilterState *nf) /* * Allow sending when stopped if enable_when_stopped is set and we have - * an outdev. This must be independent of nf->on (status) so that packets - * can still flow through the filter chain to other filters even when this - * redirector is disabled. Otherwise, tap_send() will disable read_poll - * when qemu_can_send_packet() returns false, preventing further packet - * processing. + * a redirector output endpoint and the redirector is enabled. + * Keeping this active while redirector status=off can unexpectedly + * drain packets in migration stop windows and perturb vhost ring state. */ - nc->allow_send_when_stopped = (s->enable_when_stopped && s->outdev); + nc->allow_send_when_stopped = (s->enable_when_stopped && + (s->outdev || + filter_redirector_use_inject_netdev(nf))); } static void filter_redirector_vm_state_change(void *opaque, bool running, @@ -334,7 +353,7 @@ static void filter_redirector_vm_state_change(void *opaque, bool running, MirrorState *s = FILTER_REDIRECTOR(nf); NetClientState *nc = nf->netdev; - if (!running && s->enable_when_stopped && nc->info->read_poll) { + if (!running && nc && s->enable_when_stopped && nc->info->read_poll) { nc->info->read_poll(nc, true); } } -- 2.52.0
