On Wed, Jan 28, 2026 at 10:55 AM Jason Wang <[email protected]> wrote:
>
> On Tue, Jan 27, 2026 at 10:04 PM Juraj Marcin <[email protected]> wrote:
> >
> > From: Juraj Marcin <[email protected]>
> >
> > During migration switchover both the source and the destination machines
> > are paused (compute downtime). During this period network still routes
> > network packets to the source machine, as this is the last place where
> > the recipient MAC address has been seen. Once the destination side
> > starts and sends network announcement, all subsequent frames are routed
> > correctly. However, frames delivered to the source machine are never
> > processed and lost. This causes also a network downtime with roughly the
> > same duration as compute downtime.
> >
> > This can cause problems not only for protocols that cannot handle packet
> > loss, but can also introduce delays in protocols that can handle them.
> >
> > To resolve this, this feature instantiates a network filter for each
> > network backend present during migration setup on both migration sides.
> > On the source side, this filter caches all packets received from the
> > backend during switchover. Once the destination machine starts, all
> > cached packets are sent through the migration channel and the respective
> > filter object on the destination side injects them to the NIC attached
> > to the backend.
> >
> > Signed-off-by: Juraj Marcin <[email protected]>
> > ---
> >  include/migration/vmstate.h |   6 +
> >  include/net/net.h           |   5 +
> >  migration/meson.build       |   1 +
> >  migration/migration.c       |  49 ++++++-
> >  migration/migration.h       |   2 +
> >  migration/netpass.c         | 246 ++++++++++++++++++++++++++++++++++++
> >  migration/netpass.h         |  14 ++
> >  migration/options.c         |  21 +++
> >  migration/options.h         |   1 +
> >  migration/savevm.c          |  37 ++++++
> >  migration/savevm.h          |   2 +
> >  migration/trace-events      |   9 ++
> >  net/net.c                   |  11 ++
> >  net/tap.c                   |  11 +-
> >  qapi/migration.json         |   7 +-
> >  15 files changed, 418 insertions(+), 4 deletions(-)
> >  create mode 100644 migration/netpass.c
> >  create mode 100644 migration/netpass.h
> >
> > diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
> > index 62d7e9fe38..7987e6c85a 100644
> > --- a/include/migration/vmstate.h
> > +++ b/include/migration/vmstate.h
> > @@ -200,6 +200,12 @@ typedef enum {
> >       * save_setup() in VMSD structures.
> >       */
> >      VMS_PHASE_EARLY_SETUP,
> > +    /*
> > +     * Specifies a netpass VMSD, these devices are copied right after the
> > +     * destination is started regardless of precopy/postcopy. Failure in 
> > this
> > +     * phase does not fail the migration in case of precopy.
> > +     */
> > +    VMS_PHASE_NETPASS,
> >  } VMStateSavePhase;
> >
> >  struct VMStateDescription {
> > diff --git a/include/net/net.h b/include/net/net.h
> > index 45bc86fc86..510908845b 100644
> > --- a/include/net/net.h
> > +++ b/include/net/net.h
> > @@ -82,6 +82,7 @@ typedef void (NetAnnounce)(NetClientState *);
> >  typedef bool (SetSteeringEBPF)(NetClientState *, int);
> >  typedef bool (NetCheckPeerType)(NetClientState *, ObjectClass *, Error **);
> >  typedef struct vhost_net *(GetVHostNet)(NetClientState *nc);
> > +typedef void (NetpassEnabledNotify)(NetClientState *nc, void *opaque);
> >
> >  typedef struct NetClientInfo {
> >      NetClientDriver type;
> > @@ -130,6 +131,9 @@ struct NetClientState {
> >      bool is_netdev;
> >      bool do_not_pad; /* do not pad to the minimum ethernet frame length */
> >      bool is_datapath;
> > +    bool netpass_enabled;
> > +    NetpassEnabledNotify *netpass_enabled_notify;
> > +    void *netpass_enabled_notify_opaque;
> >      QTAILQ_HEAD(, NetFilterState) filters;
> >  };
> >
>
> Adding Cindy, Eugenio can Chen.
>
> I think we can simple reuse the existing filters:
>
> redirector: which can redirect traffic from the source to the
> destination via chardev
> buffer: which can hold the packets until the destination is released
>
> And let the libvirt install/uninstall those filters at the correct time.
>
> Which means:
>
> On the source: there would be a redirector that can be enabled when vm
> is paused, and it redirect the traffic to a socket/chardev
> On the destination: there would be a redirector as well as the buffer,
> redirector receives packets from the socket and send it to buffer,
> buffer will hold those packets until VM in the destination is resumed.
>
> The current filters need some tweaks (e.g letting filters (redirector)
> work when VM is paused). The advantages of this are:
>
> 1) reuse the existing filters
> 2) don't need to care about the vhost support on the source as vhost
> is disabled, for vDPA we can reuse shadow virtqueue
> 3) for the destination we can install a redirector to packet socket to
> let vhost works like socket -> redirector -> buffer -> redirector ->
> packet socket.

and 4) there's no need to touch migration code in Qemu.

Thanks

>
> Thanks


Reply via email to