From nobody Tue Jul 21 20:07:41 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4h4T2Q2Kjjz6mPQs for ; Tue, 21 Jul 2026 20:07:42 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4h4T2P6xjrz3QbK for ; Tue, 21 Jul 2026 20:07:41 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1784664462; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=f0DrBhTT1RWKZCSDFxb46E8wxvxGEJnhEJzSNgYX9a4=; b=Z1qdW29Gfbc6sfipBBNo/h1zN3KFlajn45DTfzoIS/CjvcdJSVSyqMqA4JKWSrqH/9AEC0 BG5WWt6oxd/xU/Q+axNNzQtLKtIlJrVjuORSpAxzaR/K9kvNqNCMyYEklPHhrOZq4g2fqx oqSpj/F03OgtSGLnD0zhStcWCjS8u0uGrCsf9I5EeUcENHWinedy3nrYFClWag6HfdgMaI V0P/4RRvREMXerd7q5bLWbkDXYz03seloWpFYNLNIiuYrOu/CP7ZLu4Yxk5ElmNuN5IeCq lKaFVhzTX72L4L3W4OoNhzJvU3u02nnsJ8VEu9WhwJZN3hOcVmKvsHCBPfqs0A== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1784664462; a=rsa-sha256; cv=none; b=pB9Tw222gz+3HIalTO/pkkggl+K97vcdzOLYbhYM6faAATKrm78SrnpBqhmrJ0fFP3l1Li sEwsoTdqgePDbnhjmu8SEwtlAscLsN9jHEgJJV0CXjqB2zi/dfrivVib0ODhfTe0r4lDQ1 Po551LS0RNRtUCFIc79rERVric7wDa1erX2x9aiEU6BpciTMgb4CPQB5TgersjfJn3oXp1 3L/0E/dgB1JU5PhueyJLTN1rW/7kjvGxErvfKDUE+npkj/uj6br9SkSkVqymLv/V7xwsxR iaNdZoTWJjD3j14rx2NE8KjxS86/iRt3lWwGcgbZWVLuEiG3mqA1abJjPkOleg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1784664462; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=f0DrBhTT1RWKZCSDFxb46E8wxvxGEJnhEJzSNgYX9a4=; b=GrZOVXYHgLPoirRXPFRDSW2xRElbSh0Yze1JWDAFnzU8ExWI2iFnVIyXOpCgAOsHq0POen 1HUgJeh7LKpkBDWiNO9tJdqnL9Vvk77hIFK4rWMSyVDfvJd/GU3Ofbzxa2E0TDESi+jRi2 ugNtV/ua3IRhdUxKo1RKvsP7ipGBfE97VGwEH0lvCqqTnUnWfWvXlMOY7ZxiYA+rNmVpOA zjywvoNcwLQUA2BeJFCteQXry8I4YfBynUiSeVJUurcqHXW86xMBldZK/kIwF9rWucNu+v N8s+DYwnlgfIAS93nlhyIlRlhIpfxb7+k9AWmUal8Khy8XRzC722rUBMJtPYGQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4h4T2P5WGGz12fF for ; Tue, 21 Jul 2026 20:07:41 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 22243 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Tue, 21 Jul 2026 20:07:41 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Cc: Faraz Vahedi From: Pouria Mousavizadeh Tehrani Subject: git: c5caf8564533 - main - vtnet: Implement VIRTIO_NET_F_GUEST_ANNOUNCE List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: pouria X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: c5caf856453325728155a18d3bb02a9cd651a0a0 Auto-Submitted: auto-generated Date: Tue, 21 Jul 2026 20:07:41 +0000 Message-Id: <6a5fd18d.22243.7937b2fa@gitrepo.freebsd.org> The branch main has been updated by pouria: URL: https://cgit.FreeBSD.org/src/commit/?id=c5caf856453325728155a18d3bb02a9cd651a0a0 commit c5caf856453325728155a18d3bb02a9cd651a0a0 Author: Faraz Vahedi AuthorDate: 2026-07-12 20:46:20 +0000 Commit: Pouria Mousavizadeh Tehrani CommitDate: 2026-07-21 20:06:35 +0000 vtnet: Implement VIRTIO_NET_F_GUEST_ANNOUNCE When the device sets VIRTIO_NET_S_ANNOUNCE in the config status field, for example after a VM migrates to a new host, announce the interface's presence on the network so peers and switches learn the new attachment point, then acknowledge the request with the VIRTIO_NET_CTRL_ANNOUNCE_ACK control command, as per VirtIO v1.3, 5.1.6.5.4. The announcement raises iflladdr_event: the stack sends gratuitous ARPs and unsolicited neighbor advertisements for the interface's addresses, and stacked interfaces such as vlan(4) propagate the event and announce theirs as well. The event handlers may sleep, so the work is deferred from the config change interrupt to a task on taskqueue_thread; that context also allows the acknowledgement to be skipped safely if the interface was stopped in the meantime, in which case the device keeps the bit set and the request is re-delivered with the next config change interrupt. Signed-off-by: Faraz Vahedi Reviewed by: adrian Pull Request: https://github.com/freebsd/freebsd-src/pull/2322 --- sys/dev/virtio/network/if_vtnet.c | 88 ++++++++++++++++++++++++++++++++++++ sys/dev/virtio/network/if_vtnetvar.h | 2 + 2 files changed, 90 insertions(+) diff --git a/sys/dev/virtio/network/if_vtnet.c b/sys/dev/virtio/network/if_vtnet.c index ac5c08f60a0e..e9683698decb 100644 --- a/sys/dev/virtio/network/if_vtnet.c +++ b/sys/dev/virtio/network/if_vtnet.c @@ -224,6 +224,9 @@ static int vtnet_exec_ctrl_cmd(struct vtnet_softc *, uint8_t *, static int vtnet_ctrl_mac_cmd(struct vtnet_softc *, uint8_t *); static int vtnet_ctrl_guest_offloads(struct vtnet_softc *, uint64_t); static int vtnet_ctrl_mq_cmd(struct vtnet_softc *, uint16_t); +static int vtnet_ctrl_announce_ack_cmd(struct vtnet_softc *); +static bool vtnet_announce_pending(struct vtnet_softc *); +static void vtnet_announce(void *, int); static int vtnet_ctrl_rx_cmd(struct vtnet_softc *, uint8_t, bool); static int vtnet_set_promisc(struct vtnet_softc *, bool); static int vtnet_set_allmulti(struct vtnet_softc *, bool); @@ -468,6 +471,7 @@ vtnet_attach(device_t dev) VTNET_CORE_LOCK_INIT(sc); callout_init_mtx(&sc->vtnet_tick_ch, VTNET_CORE_MTX(sc), 0); + TASK_INIT(&sc->vtnet_announce_task, 0, vtnet_announce, sc); vtnet_load_tunables(sc); vtnet_alloc_interface(sc); @@ -642,6 +646,8 @@ vtnet_detach(device_t dev) ether_ifdetach(ifp); } + taskqueue_drain(taskqueue_thread, &sc->vtnet_announce_task); + #ifdef DEV_NETMAP netmap_detach(ifp); #endif @@ -746,6 +752,8 @@ vtnet_config_change(device_t dev) VTNET_CORE_LOCK(sc); vtnet_update_link_status(sc); + if (vtnet_announce_pending(sc)) + taskqueue_enqueue(taskqueue_thread, &sc->vtnet_announce_task); if (sc->vtnet_link_active != 0) vtnet_tx_start_all(sc); VTNET_CORE_UNLOCK(sc); @@ -4056,6 +4064,86 @@ error_out: return (error); } +static int +vtnet_ctrl_announce_ack_cmd(struct vtnet_softc *sc) +{ + struct sglist_seg segs[2]; + bus_dmamap_t hdr_dmap; + bus_addr_t hdr_paddr; + struct sglist sg; + struct virtio_net_ctrl_hdr hdr __aligned(2); + uint8_t ack; + int error; + + error = bus_dmamap_create(sc->vtnet_hdr_dmat, 0, &hdr_dmap); + if (error != 0) + goto error_out; + + error = bus_dmamap_load(sc->vtnet_hdr_dmat, hdr_dmap, &hdr, + sizeof(hdr), vtnet_load_callback, &hdr_paddr, BUS_DMA_NOWAIT); + if (error != 0) + goto error_destroy_hdr; + + hdr.class = VIRTIO_NET_CTRL_ANNOUNCE; + hdr.cmd = VIRTIO_NET_CTRL_ANNOUNCE_ACK; + ack = VIRTIO_NET_ERR; + bus_dmamap_sync(sc->vtnet_hdr_dmat, hdr_dmap, BUS_DMASYNC_PREWRITE); + + sglist_init(&sg, nitems(segs), segs); + error = sglist_append_phys(&sg, hdr_paddr, sizeof(hdr)); + MPASS(error == 0 && sg.sg_nseg == nitems(segs) - 1); + + if (error == 0) + error = vtnet_exec_ctrl_cmd(sc, &ack, &sg, sg.sg_nseg, 1); + if (error == 0) + error = (ack == VIRTIO_NET_OK ? 0 : EIO); + + bus_dmamap_unload(sc->vtnet_hdr_dmat, hdr_dmap); +error_destroy_hdr: + bus_dmamap_destroy(sc->vtnet_hdr_dmat, hdr_dmap); +error_out: + return (error); +} + +static bool +vtnet_announce_pending(struct vtnet_softc *sc) +{ + uint16_t status; + + if ((sc->vtnet_features & VIRTIO_NET_F_GUEST_ANNOUNCE) == 0 || + (sc->vtnet_features & VIRTIO_NET_F_CTRL_VQ) == 0 || + (sc->vtnet_features & VIRTIO_NET_F_STATUS) == 0) + return (false); + + status = virtio_read_dev_config_2(sc->vtnet_dev, + offsetof(struct virtio_net_config, status)); + + return ((status & VIRTIO_NET_S_ANNOUNCE) != 0); +} + +static void +vtnet_announce(void *xsc, int pending __unused) +{ + struct vtnet_softc *sc; + if_t ifp; + + sc = xsc; + ifp = sc->vtnet_ifp; + + if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0) + return; + + CURVNET_SET(if_getvnet(ifp)); + EVENTHANDLER_INVOKE(iflladdr_event, ifp); + CURVNET_RESTORE(); + + VTNET_CORE_LOCK(sc); + if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) != 0 && + vtnet_ctrl_announce_ack_cmd(sc) != 0) + device_printf(sc->vtnet_dev, "cannot ack announcement\n"); + VTNET_CORE_UNLOCK(sc); +} + static int vtnet_ctrl_rx_cmd(struct vtnet_softc *sc, uint8_t cmd, bool on) { diff --git a/sys/dev/virtio/network/if_vtnetvar.h b/sys/dev/virtio/network/if_vtnetvar.h index 77a7680e5b43..904050c7864a 100644 --- a/sys/dev/virtio/network/if_vtnetvar.h +++ b/sys/dev/virtio/network/if_vtnetvar.h @@ -183,6 +183,7 @@ struct vtnet_softc { uint64_t vtnet_negotiated_features; struct vtnet_statistics vtnet_stats; struct callout vtnet_tick_ch; + struct task vtnet_announce_task; struct ifmedia vtnet_media; eventhandler_tag vtnet_vlan_attach; eventhandler_tag vtnet_vlan_detach; @@ -338,6 +339,7 @@ CTASSERT(sizeof(struct vtnet_mac_filter) <= PAGE_SIZE); VIRTIO_NET_F_CTRL_RX | \ VIRTIO_NET_F_CTRL_MAC_ADDR | \ VIRTIO_NET_F_CTRL_VLAN | \ + VIRTIO_NET_F_GUEST_ANNOUNCE | \ VIRTIO_NET_F_CSUM | \ VIRTIO_NET_F_HOST_TSO4 | \ VIRTIO_NET_F_HOST_TSO6 | \