On Sun, 01 Nov 2026 15:46:24 +0100,
Brad Smith <[email protected]> wrote:
> 
> Here is an update to QEMU 11.1.3.
> 
> Add QEMU guest agent patches for OpenBSD:
> - guest-get-users support
> - guest-network-get-route support
> - guest-get-diskstats support
> - don't try to run the Linux hwclock(8) from guest-set-time on
>   non-Linux systems
>

Thanks, commited

> 
> Index: Makefile
> ===================================================================
> RCS file: /cvs/ports/emulators/qemu/Makefile,v
> retrieving revision 1.269
> diff -u -p -u -p -r1.269 Makefile
> --- Makefile  24 Oct 2026 22:55:20 -0000      1.269
> +++ Makefile  1 Nov 2026 14:37:09 -0000
> @@ -6,9 +6,8 @@ USE_NOBTCFI=  Yes
>  COMMENT-main=        multi system emulator
>  COMMENT-ga=  QEMU guest agent
>  
> -VERSION=     11.1.1
> +VERSION=     11.1.3
>  DISTNAME=    qemu-${VERSION}
> -REVISION=    2
>  CATEGORIES=  emulators
>  SITES=               https://download.qemu.org/
>  EXTRACT_SUFX=        .tar.xz
> Index: distinfo
> ===================================================================
> RCS file: /cvs/ports/emulators/qemu/distinfo,v
> retrieving revision 1.89
> diff -u -p -u -p -r1.89 distinfo
> --- distinfo  3 Sep 2026 08:58:14 -0000       1.89
> +++ distinfo  1 Nov 2026 14:37:09 -0000
> @@ -1,2 +1,2 @@
> -SHA256 (qemu-11.1.1.tar.xz) = B5/7/4pxEbvIkCIQfLq/O7/WFNX8nXzGdZkRlqyhJII=
> -SIZE (qemu-11.1.1.tar.xz) = 141888716
> +SHA256 (qemu-11.1.3.tar.xz) = WoKJx5QNx304c8gabCm6Ov4URvydNud/oWWM2+y4SyI=
> +SIZE (qemu-11.1.3.tar.xz) = 141819712
> Index: patches/patch-hw_usb_hcd-xhci_c
> ===================================================================
> RCS file: /cvs/ports/emulators/qemu/patches/patch-hw_usb_hcd-xhci_c,v
> retrieving revision 1.1
> diff -u -p -u -p -r1.1 patch-hw_usb_hcd-xhci_c
> --- patches/patch-hw_usb_hcd-xhci_c   20 Aug 2026 08:46:20 -0000      1.1
> +++ patches/patch-hw_usb_hcd-xhci_c   1 Nov 2026 14:37:09 -0000
> @@ -24,7 +24,7 @@ Index: hw/usb/hcd-xhci.c
>   static void xhci_write_event(XHCIState *xhci, XHCIEvent *event, int v);
>   static USBEndpoint *xhci_epid_to_usbep(XHCIEPContext *epctx);
>   
> -@@ -602,6 +608,304 @@ static inline int xhci_running(XHCIState *xhci)
> +@@ -608,6 +614,304 @@ static inline int xhci_running(XHCIState *xhci)
>       return !(xhci->usbsts & USBSTS_HCH);
>   }
>   
> @@ -329,7 +329,7 @@ Index: hw/usb/hcd-xhci.c
>   static void xhci_write_event(XHCIState *xhci, XHCIEvent *event, int v)
>   {
>       XHCIInterrupter *intr = &xhci->intr[v];
> -@@ -636,7 +940,7 @@ static void xhci_write_event(XHCIState *xhci, XHCIEven
> +@@ -643,7 +947,7 @@ static void xhci_write_event(XHCIState *xhci, XHCIEven
>       }
>   }
>   
> @@ -338,7 +338,7 @@ Index: hw/usb/hcd-xhci.c
>   {
>       XHCIInterrupter *intr;
>       dma_addr_t erdp;
> -@@ -649,10 +953,15 @@ static void xhci_event(XHCIState *xhci, XHCIEvent *eve
> +@@ -656,10 +960,15 @@ static void xhci_event(XHCIState *xhci, XHCIEvent *eve
>   
>       if (v >= xhci->numintrs) {
>           DPRINTF("intr nr out of range (%d >= %d)\n", v, xhci->numintrs);
> @@ -355,7 +355,7 @@ Index: hw/usb/hcd-xhci.c
>       erdp = xhci_addr64(intr->erdp_low, intr->erdp_high);
>       if (erdp < intr->er_start ||
>           erdp >= (intr->er_start + TRB_SIZE*intr->er_size)) {
> -@@ -660,25 +969,86 @@ static void xhci_event(XHCIState *xhci, XHCIEvent *eve
> +@@ -667,25 +976,86 @@ static void xhci_event(XHCIState *xhci, XHCIEvent *eve
>           DPRINTF("xhci: ER[%d] at "DMA_ADDR_FMT" len %d\n",
>                   v, intr->er_start, intr->er_size);
>           xhci_die(xhci);
> @@ -448,7 +448,7 @@ Index: hw/usb/hcd-xhci.c
>   static void xhci_ring_init(XHCIState *xhci, XHCIRing *ring,
>                              dma_addr_t base)
>   {
> -@@ -802,6 +1172,7 @@ static void xhci_er_reset(XHCIState *xhci, int v)
> +@@ -809,6 +1179,7 @@ static void xhci_er_reset(XHCIState *xhci, int v)
>       XHCIInterrupter *intr = &xhci->intr[v];
>       XHCIEvRingSeg seg;
>       dma_addr_t erstba = xhci_addr64(intr->erstba_low, intr->erstba_high);
> @@ -456,7 +456,7 @@ Index: hw/usb/hcd-xhci.c
>   
>       if (intr->erstsz == 0 || erstba == 0) {
>           /* disabled */
> -@@ -839,13 +1210,25 @@ static void xhci_er_reset(XHCIState *xhci, int v)
> +@@ -846,13 +1217,25 @@ static void xhci_er_reset(XHCIState *xhci, int v)
>   
>       DPRINTF("xhci: event ring[%d]:" DMA_ADDR_FMT " [%d]\n",
>               v, intr->er_start, intr->er_size);
> @@ -482,7 +482,7 @@ Index: hw/usb/hcd-xhci.c
>   }
>   
>   static void xhci_stop(XHCIState *xhci)
> -@@ -853,6 +1236,7 @@ static void xhci_stop(XHCIState *xhci)
> +@@ -860,6 +1243,7 @@ static void xhci_stop(XHCIState *xhci)
>       trace_usb_xhci_stop();
>       xhci->usbsts |= USBSTS_HCH;
>       xhci->crcr_low &= ~CRCR_CRR;
> @@ -490,7 +490,7 @@ Index: hw/usb/hcd-xhci.c
>   }
>   
>   static XHCIStreamContext *xhci_alloc_stream_contexts(unsigned count,
> -@@ -1287,6 +1671,7 @@ static TRBCCode xhci_disable_ep(XHCIState *xhci, unsig
> +@@ -1301,6 +1685,7 @@ static TRBCCode xhci_disable_ep(XHCIState *xhci, unsig
>           return CC_SUCCESS;
>       }
>   
> @@ -498,7 +498,7 @@ Index: hw/usb/hcd-xhci.c
>       xhci_ep_nuke_xfers(xhci, slotid, epid, 0);
>   
>       epctx = slot->eps[epid-1];
> -@@ -1328,6 +1713,7 @@ static TRBCCode xhci_stop_ep(XHCIState *xhci, unsigned
> +@@ -1342,6 +1727,7 @@ static TRBCCode xhci_stop_ep(XHCIState *xhci, unsigned
>           return CC_EP_NOT_ENABLED_ERROR;
>       }
>   
> @@ -506,7 +506,7 @@ Index: hw/usb/hcd-xhci.c
>       if (xhci_ep_nuke_xfers(xhci, slotid, epid, CC_STOPPED) > 0) {
>           DPRINTF("xhci: FIXME: endpoint stopped w/ xfers running, "
>                   "data might be lost\n");
> -@@ -1373,6 +1759,7 @@ static TRBCCode xhci_reset_ep(XHCIState *xhci, unsigne
> +@@ -1387,6 +1773,7 @@ static TRBCCode xhci_reset_ep(XHCIState *xhci, unsigne
>           return CC_CONTEXT_STATE_ERROR;
>       }
>   
> @@ -514,7 +514,7 @@ Index: hw/usb/hcd-xhci.c
>       if (xhci_ep_nuke_xfers(xhci, slotid, epid, 0) > 0) {
>           DPRINTF("xhci: FIXME: endpoint reset w/ xfers running, "
>                   "data might be lost\n");
> -@@ -1893,6 +2280,11 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsi
> +@@ -1905,6 +2292,11 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsi
>       trace_usb_xhci_ep_kick(epctx->slotid, epctx->epid, streamid);
>       assert(!epctx->kick_active);
>   
> @@ -526,7 +526,7 @@ Index: hw/usb/hcd-xhci.c
>       /* If the device has been detached, but the guest has not noticed this
>          yet the 2 above checks will succeed, but we must NOT continue */
>       if (!xhci_slot_ok(xhci, epctx->slotid)) {
> -@@ -1943,6 +2335,11 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsi
> +@@ -1944,6 +2336,11 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsi
>           epctx->retry = NULL;
>       }
>   
> @@ -538,7 +538,7 @@ Index: hw/usb/hcd-xhci.c
>       if (epctx->state == EP_HALTED) {
>           DPRINTF("xhci: ep halted, not running schedule\n");
>           return;
> -@@ -2015,6 +2412,11 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsi
> +@@ -2016,6 +2413,11 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsi
>               xfer = NULL;
>           }
>   
> @@ -550,7 +550,7 @@ Index: hw/usb/hcd-xhci.c
>           if (epctx->state == EP_HALTED) {
>               break;
>           }
> -@@ -2490,6 +2892,9 @@ static void xhci_process_commands(XHCIState *xhci)
> +@@ -2492,6 +2894,9 @@ static void xhci_process_commands(XHCIState *xhci)
>       }
>   
>       xhci->crcr_low |= CRCR_CRR;
> @@ -560,7 +560,7 @@ Index: hw/usb/hcd-xhci.c
>   
>       while ((type = xhci_ring_fetch(xhci, &xhci->cmd_ring, &trb, &addr))) {
>           event.ptr = addr;
> -@@ -2600,7 +3005,9 @@ static void xhci_process_commands(XHCIState *xhci)
> +@@ -2602,7 +3007,9 @@ static void xhci_process_commands(XHCIState *xhci)
>               break;
>           }
>           event.slotid = slotid;
> @@ -571,7 +571,7 @@ Index: hw/usb/hcd-xhci.c
>   
>           if (count++ > COMMAND_LIMIT) {
>               trace_usb_xhci_enforced_limit("commands");
> -@@ -2716,6 +3123,8 @@ static void xhci_reset(DeviceState *dev)
> +@@ -2718,6 +3125,8 @@ static void xhci_reset(DeviceState *dev)
>       xhci->dcbaap_low = 0;
>       xhci->dcbaap_high = 0;
>       xhci->config = 0;
> @@ -580,7 +580,7 @@ Index: hw/usb/hcd-xhci.c
>   
>       for (i = 0; i < xhci->numslots; i++) {
>           xhci_disable_slot(xhci, i+1);
> -@@ -2736,6 +3145,11 @@ static void xhci_reset(DeviceState *dev)
> +@@ -2738,6 +3147,11 @@ static void xhci_reset(DeviceState *dev)
>   
>           xhci->intr[i].er_ep_idx = 0;
>           xhci->intr[i].er_pcs = 1;
> @@ -592,7 +592,7 @@ Index: hw/usb/hcd-xhci.c
>           xhci->intr[i].ev_buffer_put = 0;
>           xhci->intr[i].ev_buffer_get = 0;
>       }
> -@@ -3139,6 +3553,11 @@ static void xhci_runtime_write(void *ptr, hwaddr reg,
> +@@ -3141,6 +3555,11 @@ static void xhci_runtime_write(void *ptr, hwaddr reg,
>               intr->erdp_low &= ~ERDP_EHB;
>           }
>           intr->erdp_low = (val & ~ERDP_EHB) | (intr->erdp_low & ERDP_EHB);
> @@ -604,7 +604,7 @@ Index: hw/usb/hcd-xhci.c
>           if (val & ERDP_EHB) {
>               dma_addr_t erdp = xhci_addr64(intr->erdp_low, intr->erdp_high);
>               unsigned int dp_idx = (erdp - intr->er_start) / TRB_SIZE;
> -@@ -3151,6 +3570,7 @@ static void xhci_runtime_write(void *ptr, hwaddr reg,
> +@@ -3153,6 +3572,7 @@ static void xhci_runtime_write(void *ptr, hwaddr reg,
>           break;
>       case 0x1c: /* ERDP high */
>           intr->erdp_high = val;
> @@ -612,7 +612,7 @@ Index: hw/usb/hcd-xhci.c
>           break;
>       default:
>           trace_usb_xhci_unimplemented("oper write", reg);
> -@@ -3425,6 +3845,15 @@ static void usb_xhci_realize(DeviceState *dev, Error *
> +@@ -3454,6 +3874,15 @@ static void usb_xhci_realize(DeviceState *dev, Error *
>       if (xhci->numslots < 1) {
>           xhci->numslots = 1;
>       }
> @@ -628,7 +628,7 @@ Index: hw/usb/hcd-xhci.c
>       if (xhci_get_flag(xhci, XHCI_FLAG_ENABLE_STREAMS)) {
>           xhci->max_pstreams_mask = 7; /* == 256 primary streams */
>       } else {
> -@@ -3470,6 +3899,14 @@ static void usb_xhci_unrealize(DeviceState *dev)
> +@@ -3499,6 +3928,14 @@ static void usb_xhci_unrealize(DeviceState *dev)
>           xhci_disable_slot(xhci, i + 1);
>       }
>   
> @@ -643,7 +643,7 @@ Index: hw/usb/hcd-xhci.c
>       if (xhci->mfwrap_timer) {
>           timer_free(xhci->mfwrap_timer);
>           xhci->mfwrap_timer = NULL;
> -@@ -3488,17 +3925,70 @@ static void usb_xhci_unrealize(DeviceState *dev)
> +@@ -3517,17 +3954,70 @@ static void usb_xhci_unrealize(DeviceState *dev)
>       usb_bus_release(&xhci->bus);
>   }
>   
> @@ -715,7 +715,7 @@ Index: hw/usb/hcd-xhci.c
>       dcbaap = xhci_addr64(xhci->dcbaap_low, xhci->dcbaap_high);
>   
>       for (slotid = 1; slotid <= xhci->numslots; slotid++) {
> -@@ -3531,11 +4021,19 @@ static int usb_xhci_post_load(void *opaque, int 
> versio
> +@@ -3560,11 +4050,19 @@ static int usb_xhci_post_load(void *opaque, int 
> versio
>               xhci_init_epctx(epctx, pctx, ep_ctx);
>               epctx->state = state;
>               if (state == EP_RUNNING) {
> @@ -737,7 +737,7 @@ Index: hw/usb/hcd-xhci.c
>       return 0;
>   }
>   
> -@@ -3583,6 +4081,38 @@ static const VMStateDescription vmstate_xhci_event = {
> +@@ -3612,6 +4110,38 @@ static const VMStateDescription vmstate_xhci_event = {
>       }
>   };
>   
> @@ -776,7 +776,7 @@ Index: hw/usb/hcd-xhci.c
>   static bool xhci_er_full(void *opaque, int version_id)
>   {
>       return false;
> -@@ -3617,12 +4147,37 @@ static const VMStateDescription vmstate_xhci_intr = {
> +@@ -3646,12 +4176,37 @@ static const VMStateDescription vmstate_xhci_intr = {
>                                     vmstate_xhci_event, XHCIEvent),
>   
>           VMSTATE_END_OF_LIST()
> @@ -814,7 +814,7 @@ Index: hw/usb/hcd-xhci.c
>       .post_load = usb_xhci_post_load,
>       .fields = (const VMStateField[]) {
>           VMSTATE_STRUCT_VARRAY_UINT32(ports, XHCIState, numports, 1,
> -@@ -3648,6 +4203,10 @@ const VMStateDescription vmstate_xhci = {
> +@@ -3677,6 +4232,10 @@ const VMStateDescription vmstate_xhci = {
>           VMSTATE_STRUCT(cmd_ring, XHCIState, 1, vmstate_xhci_ring, XHCIRing),
>   
>           VMSTATE_END_OF_LIST()
> Index: patches/patch-meson_build
> ===================================================================
> RCS file: /cvs/ports/emulators/qemu/patches/patch-meson_build,v
> retrieving revision 1.24
> diff -u -p -u -p -r1.24 patch-meson_build
> --- patches/patch-meson_build 21 Sep 2026 09:48:01 -0000      1.24
> +++ patches/patch-meson_build 1 Nov 2026 14:37:09 -0000
> @@ -1,4 +1,7 @@
>  - util/cutils: Use getexecpath() on OpenBSD for qemu_init_exec_dir()
> +- qga: implement 'guest-network-get-route' for FreeBSD
> +  0ae3840f612ba00330940f26758ae03754f6c6b6
> +- qga: implement 'guest-get-users' for OpenBSD
>  
>  - localstatedir does not belong under prefix
>  - remove hardcoding of optimization
> @@ -15,7 +18,28 @@ Index: meson.build
>   config_host_data.set_quoted('CONFIG_QEMU_MODDIR', get_option('prefix') / 
> qemu_moddir)
>   config_host_data.set_quoted('CONFIG_SYSCONFDIR', get_option('prefix') / 
> get_option('sysconfdir'))
>   
> -@@ -3030,6 +3030,14 @@ config_host_data.set('CONFIG_ELF_AUX_INFO', cc.links(o
> +@@ -2433,6 +2433,7 @@ config_host_data.set('CONFIG_BDRV_WHITELIST_TOOLS', ge
> + config_host_data.set('CONFIG_BRLAPI', brlapi.found())
> + config_host_data.set('CONFIG_BSD', host_os in bsd_oses)
> + config_host_data.set('CONFIG_FREEBSD', host_os == 'freebsd')
> ++config_host_data.set('CONFIG_OPENBSD', host_os == 'openbsd')
> + config_host_data.set('CONFIG_CAPSTONE', capstone.found())
> + config_host_data.set('CONFIG_COCOA', cocoa.found())
> + config_host_data.set('CONFIG_DARWIN', host_os == 'darwin')
> +@@ -2755,6 +2756,12 @@ config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
> + config_host_data.set('HAVE_BLK_ZONE_REP_CAPACITY',
> +                      cc.has_member('struct blk_zone', 'capacity',
> +                                    prefix: '#include <linux/blkzoned.h>'))
> ++config_host_data.set('HAVE_STRUCT_RT_METRICS_RMX_METRIC',
> ++                     cc.has_member('struct rt_metrics', 'rmx_metric',
> ++                                   prefix: '''
> ++                                       #include <sys/types.h>
> ++                                       #include <sys/socket.h>
> ++                                       #include <net/route.h>'''))
> + 
> + # has_type
> + config_host_data.set('CONFIG_IOVEC',
> +@@ -3030,6 +3037,14 @@ config_host_data.set('CONFIG_ELF_AUX_INFO', cc.links(o
>       return hwcap;
>     }'''))
>   
> @@ -30,7 +54,7 @@ Index: meson.build
>   config_host_data.set('CONFIG_USBFS', have_linux_user and cc.compiles('''
>     #include <linux/usbdevice_fs.h>
>   
> -@@ -4753,9 +4761,6 @@ if have_rust
> +@@ -4753,9 +4768,6 @@ if have_rust
>     summary_info += {'bindgen version': bindgen.version()}
>   endif
>   option_cflags = (get_option('debug') ? ['-g'] : [])
> Index: patches/patch-qga_commands-bsd_c
> ===================================================================
> RCS file: /cvs/ports/emulators/qemu/patches/patch-qga_commands-bsd_c,v
> retrieving revision 1.5
> diff -u -p -u -p -r1.5 patch-qga_commands-bsd_c
> --- patches/patch-qga_commands-bsd_c  21 Sep 2026 09:48:01 -0000      1.5
> +++ patches/patch-qga_commands-bsd_c  1 Nov 2026 14:37:09 -0000
> @@ -1,16 +1,22 @@
>  - qga: implement 'guest-get-fsinfo' for FreeBSD
>    2a454b5391ad4241c8d59d8325d8bacac9af7a8c
>  - qga: implement 'guest-get-fsinfo' for NetBSD and OpenBSD
> +  6a24fc259da4b1efa8e53dc9a655d89474d270cc
> +- qga: implement 'guest-network-get-route' for FreeBSD
> +  0ae3840f612ba00330940f26758ae03754f6c6b6
> +- qga: implement 'guest-network-get-route' for NetBSD and OpenBSD
> +- qga: implement 'guest-get-diskstats' for OpenBSD
>  - qga: implement 'guest-get-vcpus' for the BSDs
> +- qga: implement 'guest-get-users' for OpenBSD
>  
>  Index: qga/commands-bsd.c
>  --- qga/commands-bsd.c.orig
>  +++ qga/commands-bsd.c
> -@@ -13,13 +13,13 @@
> - #include "qemu/osdep.h"
> +@@ -14,12 +14,17 @@
>   #include "qga-qapi-commands.h"
>   #include "qapi/error.h"
> --#include "qemu/queue.h"
> + #include "qemu/queue.h"
> ++#include "block/block-common.h"
>   #include "commands-common.h"
>   #include <sys/ioctl.h>
>   #include <sys/param.h>
> @@ -18,16 +24,25 @@ Index: qga/commands-bsd.c
>   #include <sys/mount.h>
>   #include <net/if_dl.h>
>  +#include <sys/statvfs.h>
> ++#include <sys/sysctl.h>
> ++#include <net/route.h>
> ++#include <net/if.h>
>   #if defined(__NetBSD__) || defined(__OpenBSD__)
>   #include <net/if_arp.h>
>   #include <netinet/if_ether.h>
> -@@ -27,12 +27,20 @@
> +@@ -27,12 +32,40 @@
>   #include <net/ethernet.h>
>   #endif
>   #include <paths.h>
>  +#ifdef __FreeBSD__
>  +#include <ufs/ffs/fs.h>
>  +#endif
> ++#ifdef __OpenBSD__
> ++#include <sys/sysctl.h>
> ++#include <sys/disk.h>
> ++#include <util.h>
> ++#include <utmp.h>
> ++#endif
>   
>  -#if defined(CONFIG_FSFREEZE) || defined(CONFIG_FSTRIM)
>  +#ifdef __NetBSD__
> @@ -36,6 +51,20 @@ Index: qga/commands-bsd.c
>  +typedef struct statfs bsd_fsinfo_t;
>  +#endif
>  +
> ++#if defined(__OpenBSD__)
> ++#define RT_FIRST_SA(rtm) \
> ++    ((struct sockaddr *)((char *)(rtm) + (rtm)->rtm_hdrlen))
> ++#define RT_SA_SIZE(sa) \
> ++    ((sa)->sa_len > 0 ? 1 + (((sa)->sa_len - 1) | (sizeof(long) - 1)) \
> ++                      : sizeof(long))
> ++#elif defined(__NetBSD__)
> ++#define RT_FIRST_SA(rtm)  ((struct sockaddr *)((rtm) + 1))
> ++#define RT_SA_SIZE(sa)    RT_ROUNDUP((sa)->sa_len)
> ++#else /* FreeBSD, DragonFly */
> ++#define RT_FIRST_SA(rtm)  ((struct sockaddr *)((rtm) + 1))
> ++#define RT_SA_SIZE(sa)    SA_SIZE(sa)
> ++#endif
> ++
>   bool build_fs_mount_list(FsMountList *mounts, Error **errp)
>   {
>       FsMount *mount;
> @@ -44,7 +73,7 @@ Index: qga/commands-bsd.c
>       struct stat statbuf;
>       int i, count, ret;
>   
> -@@ -55,16 +63,18 @@ bool build_fs_mount_list(FsMountList *mounts, Error **
> +@@ -55,16 +88,18 @@ bool build_fs_mount_list(FsMountList *mounts, Error **
>   
>           mount->dirname = g_strdup(mntp->f_mntonname);
>           mount->devtype = g_strdup(mntp->f_fstypename);
> @@ -65,7 +94,7 @@ Index: qga/commands-bsd.c
>   
>   #if defined(CONFIG_FSFREEZE)
>   static int ufssuspend_fd = -1;
> -@@ -178,3 +188,79 @@ bool guest_get_hw_addr(struct ifaddrs *ifa, unsigned c
> +@@ -178,3 +213,461 @@ bool guest_get_hw_addr(struct ifaddrs *ifa, unsigned c
>       return true;
>   }
>   #endif /* HAVE_GETIFADDRS */
> @@ -144,4 +173,386 @@ Index: qga/commands-bsd.c
>  +
>  +    free_fs_mount_list(&mounts);
>  +    return ret;
> ++}
> ++
> ++#ifdef __OpenBSD__
> ++static uint64_t timeval_to_msec(const struct timeval *tv)
> ++{
> ++    return (uint64_t)tv->tv_sec * 1000ULL + tv->tv_usec / 1000;
> ++}
> ++
> ++static GuestDiskStatsInfo *
> ++guest_diskstats_info_new(const struct diskstats *ds, int rawpart)
> ++{
> ++    GuestDiskStatsInfo *diskstatinfo;
> ++    GuestDiskStats *diskstat;
> ++    struct stat st;
> ++
> ++    diskstatinfo = g_new0(GuestDiskStatsInfo, 1);
> ++    diskstatinfo->name = g_strndup(ds->ds_name, sizeof(ds->ds_name));
> ++
> ++    /*
> ++     * The kernel disk statistics carry no device numbers; take them
> ++     * from the raw partition device node, which covers the whole disk.
> ++     * If that node is missing (e.g. a minimal /dev), report 0.
> ++     */
> ++    if (rawpart >= 0) {
> ++        g_autofree char *devpath = g_strdup_printf(_PATH_DEV "%s%c",
> ++                                                   diskstatinfo->name,
> ++                                                   'a' + rawpart);
> ++
> ++        if (stat(devpath, &st) == 0 && S_ISBLK(st.st_mode)) {
> ++            diskstatinfo->major = major(st.st_rdev);
> ++            diskstatinfo->minor = minor(st.st_rdev);
> ++        }
> ++    }
> ++
> ++    /*
> ++     * OpenBSD tracks transfer counts and bytes per direction, but busy
> ++     * time only in aggregate, and has no discard, flush or merge
> ++     * counters.
> ++     */
> ++    diskstat = g_new0(GuestDiskStats, 1);
> ++    diskstat->has_read_ios = true;
> ++    diskstat->read_ios = ds->ds_rxfer;
> ++    diskstat->has_read_sectors = true;
> ++    diskstat->read_sectors = ds->ds_rbytes / BDRV_SECTOR_SIZE;
> ++
> ++    diskstat->has_write_ios = true;
> ++    diskstat->write_ios = ds->ds_wxfer;
> ++    diskstat->has_write_sectors = true;
> ++    diskstat->write_sectors = ds->ds_wbytes / BDRV_SECTOR_SIZE;
> ++
> ++    if (ds->ds_busy >= 0) {
> ++        diskstat->has_ios_pgr = true;
> ++        diskstat->ios_pgr = ds->ds_busy;
> ++    }
> ++
> ++    diskstat->has_total_ticks = true;
> ++    diskstat->total_ticks = timeval_to_msec(&ds->ds_time);
> ++
> ++    diskstatinfo->stats = diskstat;
> ++    return diskstatinfo;
> ++}
> ++
> ++#define DISKSTATS_MAX_TRIES 5
> ++
> ++GuestDiskStatsInfoList *qmp_guest_get_diskstats(Error **errp)
> ++{
> ++    GuestDiskStatsInfoList *head = NULL, **tail = &head;
> ++    int mib[] = { CTL_HW, HW_DISKSTATS };
> ++    g_autofree struct diskstats *stats = NULL;
> ++    size_t len, i;
> ++    int rawpart = getrawpartition();
> ++    int tries;
> ++
> ++    /* Disks may attach or detach between the two sysctl calls; retry. */
> ++    for (tries = 0; tries < DISKSTATS_MAX_TRIES; tries++) {
> ++        if (sysctl(mib, ARRAY_SIZE(mib), NULL, &len, NULL, 0) == -1) {
> ++            error_setg_errno(errp, errno, "cannot get size of 
> hw.diskstats");
> ++            return NULL;
> ++        }
> ++        if (len == 0) {
> ++            return NULL;
> ++        }
> ++        len += 4 * sizeof(struct diskstats);
> ++        g_free(stats);
> ++        stats = g_malloc(len);
> ++        if (sysctl(mib, ARRAY_SIZE(mib), stats, &len, NULL, 0) == 0) {
> ++            break;
> ++        }
> ++        if (errno != ENOMEM) {
> ++            error_setg_errno(errp, errno, "cannot read hw.diskstats");
> ++            return NULL;
> ++        }
> ++    }
> ++    if (tries == DISKSTATS_MAX_TRIES) {
> ++        error_setg(errp, "hw.diskstats keeps changing size");
> ++        return NULL;
> ++    }
> ++
> ++    for (i = 0; i < len / sizeof(struct diskstats); i++) {
> ++        QAPI_LIST_APPEND(tail, guest_diskstats_info_new(&stats[i], 
> rawpart));
> ++    }
> ++
> ++    return head;
> ++}
> ++
> ++GuestUserList *qmp_guest_get_users(Error **errp)
> ++{
> ++    GHashTable *cache;
> ++    GuestUserList *head = NULL, **tail = &head;
> ++    struct utmp ut;
> ++    FILE *fp = NULL;
> ++
> ++    fp = fopen(_PATH_UTMP, "r");
> ++    if (!fp) {
> ++        error_setg_errno(errp, errno, "failed to open %s", _PATH_UTMP);
> ++        return NULL;
> ++    }
> ++
> ++    cache = g_hash_table_new(g_str_hash, g_str_equal);
> ++
> ++    while (fread(&ut, sizeof(ut), 1, fp) == 1) {
> ++        g_autofree char *name = NULL;
> ++        GuestUser *user;
> ++        double login_time;
> ++
> ++        /* logout(3) clears ut_name; skip empty slots like who(1) does */
> ++        if (ut.ut_name[0] == '\0' || ut.ut_line[0] == '\0') {
> ++            continue;
> ++        }
> ++
> ++        /* ut_name is not NUL-terminated if it fills UT_NAMESIZE */
> ++        name = g_strndup(ut.ut_name, sizeof(ut.ut_name));
> ++        login_time = (double)ut.ut_time;
> ++
> ++        user = g_hash_table_lookup(cache, name);
> ++        if (user) {
> ++            /* We're ensuring the earliest login time to be sent */
> ++            if (login_time < user->login_time) {
> ++                user->login_time = login_time;
> ++            }
> ++            continue;
> ++        }
> ++
> ++        user = g_new0(GuestUser, 1);
> ++        user->user = g_steal_pointer(&name);
> ++        user->login_time = login_time;
> ++
> ++        g_hash_table_insert(cache, user->user, user);
> ++        QAPI_LIST_APPEND(tail, user);
> ++    }
> ++
> ++    fclose(fp);
> ++    g_hash_table_destroy(cache);
> ++    return head;
> ++}
> ++#endif /* __OpenBSD__ */
> ++
> ++static void sockaddr_in6_normalize(const struct sockaddr *sa,
> ++                                   struct sockaddr_in6 *sin6)
> ++{
> ++    size_t len = MIN(sa->sa_len, sizeof(*sin6));
> ++
> ++    memset(sin6, 0, sizeof(*sin6));
> ++    memcpy(sin6, sa, len);
> ++
> ++    sin6->sin6_len = sizeof(*sin6);
> ++
> ++    if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) ||
> ++        (sin6->sin6_addr.s6_addr[0] == 0xff &&
> ++        ((sin6->sin6_addr.s6_addr[1] & 0x0f) == 1 ||
> ++        (sin6->sin6_addr.s6_addr[1] & 0x0f) == 2))) {
> ++        if (sin6->sin6_scope_id == 0) {
> ++            sin6->sin6_scope_id =
> ++                (sin6->sin6_addr.s6_addr[2] << 8) |
> ++                 sin6->sin6_addr.s6_addr[3];
> ++            sin6->sin6_addr.s6_addr[2] = 0;
> ++            sin6->sin6_addr.s6_addr[3] = 0;
> ++        }
> ++    }
> ++}
> ++
> ++GuestNetworkRouteList *qmp_guest_network_get_route(Error **errp)
> ++{
> ++    GuestNetworkRouteList *head = NULL, **tail = &head;
> ++#ifdef __NetBSD__
> ++    int mib[] = { CTL_NET, PF_ROUTE, 0, AF_UNSPEC, NET_RT_DUMP, 0 };
> ++#else
> ++    int mib[] = { CTL_NET, PF_ROUTE, 0, AF_UNSPEC, NET_RT_DUMP, 0, 0 };
> ++#endif
> ++    g_autofree char *buf = NULL;
> ++    size_t len;
> ++
> ++    if (sysctl(mib, ARRAY_SIZE(mib), NULL, &len, NULL, 0) == -1) {
> ++        error_setg_errno(errp, errno, "sysctl size");
> ++        return NULL;
> ++    }
> ++
> ++    buf = g_malloc0(len);
> ++
> ++    if (sysctl(mib, ARRAY_SIZE(mib), buf, &len, NULL, 0) == -1) {
> ++        error_setg_errno(errp, errno, "sysctl routes");
> ++        return NULL;
> ++    }
> ++
> ++    for (char *p = buf, *end = buf + len; p < end; ) {
> ++        struct rt_msghdr *rtm = (struct rt_msghdr *)p;
> ++        struct sockaddr *addresses[RTAX_MAX] = { NULL };
> ++        struct sockaddr *sa;
> ++        struct sockaddr_in6 sin6;
> ++        char destination[NI_MAXHOST];
> ++        char gateway[NI_MAXHOST];
> ++        char ifname[IFNAMSIZ];
> ++        const struct sockaddr *dst = NULL;
> ++        const struct sockaddr *gw = NULL;
> ++        const struct sockaddr *netmask = NULL;
> ++        const struct sockaddr *fmt_sa;
> ++        struct sockaddr_in normalized_mask = { 0 };
> ++        char netmask_buf[INET_ADDRSTRLEN];
> ++        socklen_t salen;
> ++
> ++        g_autoptr(GuestNetworkRoute) route = g_new0(GuestNetworkRoute, 1);
> ++
> ++        if ((size_t)(end - p) < sizeof(*rtm) ||
> ++            rtm->rtm_msglen < sizeof(*rtm) ||
> ++            rtm->rtm_msglen > (size_t)(end - p)) {
> ++            break;
> ++        }
> ++
> ++        p += rtm->rtm_msglen;
> ++
> ++        if (rtm->rtm_version != RTM_VERSION) {
> ++            continue;
> ++        }
> ++
> ++#if defined(RTF_LLINFO)
> ++        /* OpenBSD: skip ARP/NDP entries */
> ++        if (rtm->rtm_flags & RTF_LLINFO) {
> ++            continue;
> ++        }
> ++#elif defined(RTF_LLDATA)
> ++        /* NetBSD: skip ARP/NDP entries */
> ++        if (rtm->rtm_flags & RTF_LLDATA) {
> ++            continue;
> ++        }
> ++#endif
> ++
> ++        sa = RT_FIRST_SA(rtm);
> ++        for (int i = 0; i < RTAX_MAX; i++) {
> ++            if (rtm->rtm_addrs & (1U << i)) {
> ++                addresses[i] = sa;
> ++                sa = (struct sockaddr *)((char *)sa + RT_SA_SIZE(sa));
> ++            }
> ++        }
> ++
> ++        if (if_indextoname(rtm->rtm_index, ifname)) {
> ++            route->iface = g_strdup(ifname);
> ++        } else {
> ++            route->iface = g_strdup_printf("if%u", rtm->rtm_index);
> ++        }
> ++
> ++#if defined(HAVE_STRUCT_RT_METRICS_RMX_METRIC)
> ++        route->metric = rtm->rtm_rmx.rmx_metric;
> ++#endif
> ++
> ++        dst = addresses[RTAX_DST];
> ++        if (!dst) {
> ++            continue;
> ++        }
> ++
> ++        if (dst->sa_family == AF_INET) {
> ++            route->version = 4;
> ++        } else if (dst->sa_family == AF_INET6) {
> ++            route->version = 6;
> ++        } else {
> ++            continue;
> ++        }
> ++
> ++        fmt_sa = dst;
> ++        salen = dst->sa_len;
> ++        if (dst->sa_family == AF_INET6) {
> ++            sockaddr_in6_normalize(dst, &sin6);
> ++            fmt_sa = (struct sockaddr *)&sin6;
> ++            salen = sizeof(sin6);
> ++        }
> ++        if (getnameinfo(fmt_sa, salen,
> ++                        destination, NI_MAXHOST,
> ++                        NULL, 0, NI_NUMERICHOST) != 0) {
> ++            continue;
> ++        }
> ++        route->destination = g_strdup(destination);
> ++
> ++        gw = addresses[RTAX_GATEWAY];
> ++        if (gw && (gw->sa_family == AF_INET || gw->sa_family == AF_INET6)) {
> ++            fmt_sa = gw;
> ++            salen = gw->sa_len;
> ++            if (gw->sa_family == AF_INET6) {
> ++                sockaddr_in6_normalize(gw, &sin6);
> ++                fmt_sa = (struct sockaddr *)&sin6;
> ++                salen = sizeof(sin6);
> ++            }
> ++            if (getnameinfo(fmt_sa, salen, gateway,
> ++                            NI_MAXHOST, NULL, 0,
> ++                            NI_NUMERICHOST) != 0) {
> ++                continue;
> ++            }
> ++            if (gw->sa_family == AF_INET) {
> ++                route->gateway = g_strdup(gateway);
> ++            } else if (gw->sa_family == AF_INET6) {
> ++                route->nexthop = g_strdup(gateway);
> ++            }
> ++        }
> ++
> ++        netmask = addresses[RTAX_NETMASK];
> ++        if (dst->sa_family == AF_INET) {
> ++            if (netmask && netmask->sa_len != 0) {
> ++                memcpy(&normalized_mask, netmask,
> ++                       MIN(netmask->sa_len, sizeof(normalized_mask)));
> ++            } else if (rtm->rtm_flags & RTF_HOST) {
> ++                normalized_mask.sin_addr.s_addr = 0xFFFFFFFF;
> ++            }
> ++
> ++            if (inet_ntop(AF_INET, &normalized_mask.sin_addr,
> ++                          netmask_buf, sizeof(netmask_buf)) != NULL) {
> ++                route->mask = g_strdup(netmask_buf);
> ++            } else {
> ++                route->mask = NULL;
> ++            }
> ++        } else if (dst->sa_family == AF_INET6) {
> ++            struct sockaddr_in6 normalized_mask6;
> ++            memset(&normalized_mask6, 0, sizeof(normalized_mask6));
> ++
> ++            if (netmask && netmask->sa_len != 0) {
> ++                int prefix_len = 0;
> ++                bool valid_mask = true;
> ++                bool zero_found = false;
> ++
> ++                memcpy(&normalized_mask6, netmask,
> ++                       MIN(netmask->sa_len, sizeof(normalized_mask6)));
> ++
> ++                for (int i = 0; i < sizeof(normalized_mask6.sin6_addr); 
> i++) {
> ++                    uint8_t byte = normalized_mask6.sin6_addr.s6_addr[i];
> ++                    for (int bit = 7; bit >= 0; bit--) {
> ++                        if ((byte >> bit) & 1) {
> ++                            if (zero_found) {
> ++                                valid_mask = false;
> ++                                break;
> ++                            }
> ++                            prefix_len++;
> ++                        } else {
> ++                            zero_found = true;
> ++                        }
> ++                    }
> ++                    if (!valid_mask) {
> ++                        break;
> ++                    }
> ++                }
> ++
> ++                if (valid_mask) {
> ++                    route->desprefixlen = g_strdup_printf("%d", prefix_len);
> ++                } else {
> ++                    route->desprefixlen = NULL;
> ++                }
> ++            } else if (rtm->rtm_flags & RTF_HOST) {
> ++                route->desprefixlen = g_strdup("128");
> ++            } else {
> ++                route->desprefixlen = g_strdup("0");
> ++            }
> ++        }
> ++
> ++        if (rtm->rtm_rmx.rmx_mtu) {
> ++            route->mtu = rtm->rtm_rmx.rmx_mtu;
> ++            route->has_mtu = true;
> ++        }
> ++
> ++        route->flags = (uint32_t)rtm->rtm_flags;
> ++        route->has_flags = true;
> ++
> ++        QAPI_LIST_APPEND(tail, route);
> ++        route = NULL;
> ++    }
> ++
> ++    return head;
>  +}
> Index: patches/patch-qga_commands-common_h
> ===================================================================
> RCS file: /cvs/ports/emulators/qemu/patches/patch-qga_commands-common_h,v
> retrieving revision 1.1
> diff -u -p -u -p -r1.1 patch-qga_commands-common_h
> --- patches/patch-qga_commands-common_h       21 Sep 2026 09:48:01 -0000      
> 1.1
> +++ patches/patch-qga_commands-common_h       1 Nov 2026 14:37:09 -0000
> @@ -1,6 +1,7 @@
>  - qga: implement 'guest-get-fsinfo' for FreeBSD
>    2a454b5391ad4241c8d59d8325d8bacac9af7a8c
>  - qga: implement 'guest-get-fsinfo' for NetBSD and OpenBSD
> +  6a24fc259da4b1efa8e53dc9a655d89474d270cc
>  
>  Index: qga/commands-common.h
>  --- qga/commands-common.h.orig
> Index: patches/patch-qga_commands-posix_c
> ===================================================================
> RCS file: /cvs/ports/emulators/qemu/patches/patch-qga_commands-posix_c,v
> retrieving revision 1.13
> diff -u -p -u -p -r1.13 patch-qga_commands-posix_c
> --- patches/patch-qga_commands-posix_c        21 Sep 2026 09:48:01 -0000      
> 1.13
> +++ patches/patch-qga_commands-posix_c        1 Nov 2026 14:37:09 -0000
> @@ -1,11 +1,35 @@
>  - qga: implement 'guest-get-fsinfo' for FreeBSD
>    2a454b5391ad4241c8d59d8325d8bacac9af7a8c
>  - qga: implement 'guest-get-fsinfo' for NetBSD and OpenBSD
> +  6a24fc259da4b1efa8e53dc9a655d89474d270cc
> +- qga: do not run hwclock(8) on non-Linux POSIX OSes
> +  e1d00ea443da6f15dc10aea8c3ab4ad7ffeb68cc
>  
>  Index: qga/commands-posix.c
>  --- qga/commands-posix.c.orig
>  +++ qga/commands-posix.c
> -@@ -718,7 +718,7 @@ void qmp_guest_file_flush(int64_t handle, Error **errp
> +@@ -322,6 +322,20 @@ void qmp_guest_set_time(bool has_time, int64_t time_ns
> +         }
> +     }
> + 
> ++#if !defined(CONFIG_LINUX)
> ++    /*
> ++     * BSDs (FreeBSD, OpenBSD, NetBSD) and illumos do not have the
> ++     * hwclock(8) tool. These systems update hardware clock when
> ++     * settimeofday() sets system time, so no additional actions
> ++     * are needed. Setting system time from RTC is not supported.
> ++     */
> ++    if (!has_time) {
> ++        error_setg(errp, "Setting system time from RTC is not supported");
> ++    }
> ++
> ++    return;
> ++#endif
> ++
> +     /* Now, if user has passed a time to set and the system time is set, we
> +      * just need to synchronize the hardware clock. However, if no time was
> +      * passed, user is requesting the opposite: set the system time from the
> +@@ -718,7 +732,7 @@ void qmp_guest_file_flush(int64_t handle, Error **errp
>       }
>   }
>   
> @@ -14,7 +38,7 @@ Index: qga/commands-posix.c
>   void free_fs_mount_list(FsMountList *mounts)
>   {
>        FsMount *mount, *temp;
> -@@ -731,6 +731,9 @@ void free_fs_mount_list(FsMountList *mounts)
> +@@ -731,6 +745,9 @@ void free_fs_mount_list(FsMountList *mounts)
>            QTAILQ_REMOVE(mounts, mount, next);
>            g_free(mount->dirname);
>            g_free(mount->devtype);
> Index: patches/patch-qga_meson_build
> ===================================================================
> RCS file: patches/patch-qga_meson_build
> diff -N patches/patch-qga_meson_build
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ patches/patch-qga_meson_build     1 Nov 2026 14:37:09 -0000
> @@ -0,0 +1,15 @@
> +- qga: implement 'guest-get-diskstats' for OpenBSD
> +
> +Index: qga/meson.build
> +--- qga/meson.build.orig
> ++++ qga/meson.build
> +@@ -93,6 +93,9 @@ qga_ss = qga_ss.apply({})
> + 
> + gen_tlb = []
> + qga_libs = []
> ++if host_os == 'openbsd'
> ++  qga_libs += ['-lutil']
> ++endif
> + if host_os == 'windows'
> +   qga_libs += ['-lws2_32', '-lwinmm', '-lpowrprof', '-lwtsapi32', 
> '-lwininet', '-liphlpapi', '-lnetapi32',
> +                '-lsetupapi', '-lcfgmgr32', '-luserenv', '-lpdh' ]
> Index: patches/patch-qga_qapi-schema_json
> ===================================================================
> RCS file: /cvs/ports/emulators/qemu/patches/patch-qga_qapi-schema_json,v
> retrieving revision 1.5
> diff -u -p -u -p -r1.5 patch-qga_qapi-schema_json
> --- patches/patch-qga_qapi-schema_json        21 Sep 2026 09:48:01 -0000      
> 1.5
> +++ patches/patch-qga_qapi-schema_json        1 Nov 2026 14:37:09 -0000
> @@ -1,6 +1,11 @@
>  - qga: implement 'guest-get-fsinfo' for FreeBSD
>    2a454b5391ad4241c8d59d8325d8bacac9af7a8c
>  - qga: implement 'guest-get-fsinfo' for NetBSD and OpenBSD
> +  6a24fc259da4b1efa8e53dc9a655d89474d270cc
> +- qga: implement 'guest-network-get-route' for FreeBSD
> +  0ae3840f612ba00330940f26758ae03754f6c6b6 
> +- qga: implement 'guest-network-get-route' for NetBSD and OpenBSD
> +- qga: implement 'guest-get-diskstats' for OpenBSD
>  - qga: implement 'guest-get-vcpus' for the BSDs
>  
>  Index: qga/qapi-schema.json
> @@ -78,3 +83,122 @@ Index: qga/qapi-schema.json
>   
>   ##
>   # @guest-set-user-password:
> +@@ -1407,7 +1407,7 @@
> + ##
> + { 'struct': 'GuestUser',
> +   'data': { 'user': 'str', 'login-time': 'number', '*domain': 'str' },
> +-  'if': { 'any': ['CONFIG_WIN32', 'HAVE_UTMPX' ] } }
> ++  'if': { 'any': ['CONFIG_WIN32', 'HAVE_UTMPX', 'CONFIG_OPENBSD' ] } }
> + 
> + ##
> + # @guest-get-users:
> +@@ -1420,7 +1420,7 @@
> + ##
> + { 'command': 'guest-get-users',
> +   'returns': ['GuestUser'],
> +-  'if': { 'any': ['CONFIG_WIN32', 'HAVE_UTMPX' ] } }
> ++  'if': { 'any': ['CONFIG_WIN32', 'HAVE_UTMPX', 'CONFIG_OPENBSD' ] } }
> + 
> + ##
> + # @GuestTimezone:
> +@@ -1714,7 +1714,7 @@
> +            '*total-ticks': 'uint64',
> +            '*weight-ticks': 'uint64'
> +            },
> +-  'if': 'CONFIG_LINUX' }
> ++  'if': { 'any': ['CONFIG_LINUX', 'CONFIG_BSD'] } }
> + 
> + ##
> + # @GuestDiskStatsInfo:
> +@@ -1732,7 +1732,7 @@
> +            'major': 'uint64',
> +            'minor': 'uint64',
> +            'stats': 'GuestDiskStats' },
> +-  'if': 'CONFIG_LINUX' }
> ++  'if': { 'any': ['CONFIG_LINUX', 'CONFIG_BSD'] } }
> + 
> + ##
> + # @guest-get-diskstats:
> +@@ -1745,7 +1745,7 @@
> + ##
> + { 'command': 'guest-get-diskstats',
> +   'returns': ['GuestDiskStatsInfo'],
> +-  'if': 'CONFIG_LINUX'
> ++  'if': { 'any': ['CONFIG_LINUX', 'CONFIG_BSD'] }
> + }
> + 
> + ##
> +@@ -1879,8 +1879,8 @@
> + ##
> + # @GuestNetworkRoute:
> + #
> +-# Route information.  Supported on Linux (since 9.1) and Windows
> +-# (since 11.0).
> ++#     Route information.  Supported on Linux (since 9.1), Windows
> ++#     (since 11.0), and BSD (since 11.2).
> + #
> + # @iface: The destination network or host's egress network interface
> + #     in the routing table
> +@@ -1894,30 +1894,31 @@
> + #
> + # @mask: Subnet Mask (IPv4 only)
> + #
> +-# @irtt: Initial round-trip delay (not for windows, IPv4 only)
> ++# @irtt: Initial round-trip delay (not for Windows and BSD,
> ++#     IPv4 only)
> + #
> +-# @flags: Route flags (not for windows)
> ++# @flags: Route flags (not for Windows)
> + #
> +-# @refcnt: The route's reference count (not for windows)
> ++# @refcnt: The route's reference count (not for Windows and BSD)
> + #
> +-# @use: Route usage count (not for windows)
> ++# @use: Route usage count (not for Windows and BSD)
> + #
> +-# @window: TCP window size, used for flow control (not for windows,
> +-#     IPv4 only)
> ++# @window: TCP window size, used for flow control (not for Windows
> ++#     and BSD, IPv4 only)
> + #
> +-# @mtu: Data link layer maximum packet size (not for windows)
> ++# @mtu: Data link layer maximum packet size (not for Windows)
> + #
> + # @desprefixlen: Destination prefix length (for IPv6)
> + #
> +-# @source: Source IP address (for IPv6)
> ++# @source: Source IP address (not for BSD, IPv6 only)
> + #
> +-# @srcprefixlen: Source prefix length (for IPv6)
> ++# @srcprefixlen: Source prefix length (not for BSD, IPv6 only)
> + #
> + # @nexthop: Next hop IP address (for IPv6)
> + #
> + # @version: IP version (4 or 6)
> + #
> +-# Since: 9.1 (Linux only); 11.0 (Windows)
> ++# Since: 9.1 (Linux only); 11.0 (Windows); 11.2 (BSD)
> + ##
> + { 'struct': 'GuestNetworkRoute',
> +   'data': {'iface': 'str',
> +@@ -1937,7 +1938,7 @@
> +            '*nexthop': 'str',
> +            'version': 'int'
> +            },
> +-  'if': { 'any': ['CONFIG_LINUX', 'CONFIG_WIN32'] } }
> ++  'if': { 'any': ['CONFIG_LINUX', 'CONFIG_WIN32', 'CONFIG_BSD'] } }
> + 
> + ##
> + # @guest-network-get-route:
> +@@ -1946,9 +1947,9 @@
> + #
> + # Returns: List of route info of guest.
> + #
> +-# Since: 9.1 (Linux only); 11.0 (Windows)
> ++# Since: 9.1 (Linux only); 11.0 (Windows); 11.2 (BSD)
> + ##
> + { 'command': 'guest-network-get-route',
> +   'returns': ['GuestNetworkRoute'],
> +-  'if': { 'any': ['CONFIG_LINUX', 'CONFIG_WIN32'] }
> ++  'if': { 'any': ['CONFIG_LINUX', 'CONFIG_WIN32', 'CONFIG_BSD'] }
> + }
> 

-- 
wbr, Kirill

Reply via email to