From nobody Mon Dec 1 16:38:10 2025 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 4dKqMk34wbz6Js2K for ; Mon, 01 Dec 2025 16:38:10 +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 "R12" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4dKqMk0w7Cz3dQF for ; Mon, 01 Dec 2025 16:38:10 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1764607090; 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=LmeCURUPxeH70aOEIGWOFSIBAk2A8FFONJagPRmUmaY=; b=mgVbZkJJ4gMiL8q3h7315N887jT//rxiXg6aHZTTCAcAH8pOTf3UOOPvxbOCq47yRcoOF5 T2dm5VqaBFBu/ENmpY4yW/78C6jA5NozSpubWrQZ2ii3MOsHgkauI3xN06V51E+Nl654JW nq3Gtbl0QIqRzQjQi6I+lp+G5F5Mbncw2B8bAeZSpSgJV2g8fKr66OjWvlRGAjVfIg86Si GJ7Xuvsf5IFqeBlNvInkFEppQCW2CzQtqZDXBp7/cbfxS+zGhJsNEuuNCll5e8JFPgnrg6 zO0lmxbSmWMJORGaRZ/hUVSbRfcJDTWju9r9OFVrYkBeuOuO6AofPwRNmXkBBA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1764607090; 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=LmeCURUPxeH70aOEIGWOFSIBAk2A8FFONJagPRmUmaY=; b=YWWbKWOqChRyUmSqa9D9MxO86AKt1roIBNqHfRgwzbPbwqAOReAxWig0R02d8M6xlgGxs6 MHdp1rR/Xc3n6akL7FKxeTkITsA7gWMKgISQWtxIujZyW83cmlKo8EgFDhD6miPkxDlgA0 Y6qt4jPN18bgF7ZsrL5Hhaw/VGTHZT/ukHNKn509YTSiUMOOoaXXoy2Cn+g7kWUff6VML1 KDNSXGGQtjyhOur2IjPqKdPoEwPr/DQ3DcR0AVWLTp4rATN7EmDbITAm7qHvqsjsW85DuY jDome46XZ99Fm0ESamd2pklsrO2SYvOMOIHnmjelZSRtLSKzFpxEsDOygMHh+Q== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1764607090; a=rsa-sha256; cv=none; b=xEkULQZTFe51jbi9GXJBk1dJTqq8bEpBBZZMSj4f36io1VEyiKXPbUBu2t4gmKyhQyx2cJ Zx2o+tl060UwxDq06uyZVqsWB/K6HmhtXCHq6VP/Uvn2bRgjJa0sdisos5ct3HoRJMt1Vw +OZ9zAuNnQtKouAWJdU5764+AdMntZZSkJ5G33p/5Jt5uZX7Q+njZoY8qq4Javz3RQw4cK 2yflXjyoyA0PYo0Fc8vXzGgKYDUA4izrSTB5CFpczy3gUZkIjta48PLSB/ewf/BWZiYy4j Pom2GDfoS7MQwHIm92skX/oE2hvpNm8RS3Xsslu4iMF7Y6y3OEKPwKCqu5/JUg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4dKqMk0RK7zD7Z for ; Mon, 01 Dec 2025 16:38:10 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 36dbe by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Mon, 01 Dec 2025 16:38:10 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Cc: Quent=?utf-8?Q?in Th=C3=A9?=bault From: Mark Johnston Subject: git: e1834bc89e64 - stable/15 - ng_device: add kqueue support 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 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: e1834bc89e640a313ead585fdf2e3f1a944acdde Auto-Submitted: auto-generated Date: Mon, 01 Dec 2025 16:38:10 +0000 Message-Id: <692dc472.36dbe.77c3a43d@gitrepo.freebsd.org> The branch stable/15 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=e1834bc89e640a313ead585fdf2e3f1a944acdde commit e1834bc89e640a313ead585fdf2e3f1a944acdde Author: Quentin Thébault AuthorDate: 2025-09-09 03:48:46 +0000 Commit: Mark Johnston CommitDate: 2025-12-01 16:37:57 +0000 ng_device: add kqueue support Signed-off-by: Quentin Thébault Sponsored by: Defenso Reviewed by: markj MFC after: 1 month Differential Revision: https://reviews.freebsd.org/D52541 Pull Request: https://github.com/freebsd/freebsd-src/pull/1880 (cherry picked from commit a505b80b2f038409300cd05e2ea95822942404e2) --- sys/netgraph/ng_device.c | 126 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 123 insertions(+), 3 deletions(-) diff --git a/sys/netgraph/ng_device.c b/sys/netgraph/ng_device.c index 582f877ff3ed..066e3be29694 100644 --- a/sys/netgraph/ng_device.c +++ b/sys/netgraph/ng_device.c @@ -3,6 +3,7 @@ * * Copyright (c) 2002 Mark Santcroos * Copyright (c) 2004-2005 Gleb Smirnoff + * Copyright (c) 2025 Quentin Thébault * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -50,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -117,12 +119,15 @@ struct ngd_private { struct ng_node *node; struct ng_hook *hook; struct cdev *ngddev; + struct selinfo rsel; + struct selinfo wsel; struct mtx ngd_mtx; int unit; int ether_align; uint16_t flags; #define NGDF_OPEN 0x0001 #define NGDF_RWAIT 0x0002 +#define NGDF_DYING 0x0004 }; typedef struct ngd_private *priv_p; @@ -138,6 +143,24 @@ static d_read_t ngdread; static d_write_t ngdwrite; static d_ioctl_t ngdioctl; static d_poll_t ngdpoll; +static d_kqfilter_t ngdkqfilter; + +static int ngd_kqread_event(struct knote *, long); +static int ngd_kqwrite_event(struct knote *, long); +static void ngd_kqread_detach(struct knote *); +static void ngd_kqwrite_detach(struct knote *); + +static const struct filterops ngd_read_filterops = { + .f_isfd = 1, + .f_detach = ngd_kqread_detach, + .f_event = ngd_kqread_event +}; + +static const struct filterops ngd_write_filterops = { + .f_isfd = 1, + .f_detach = ngd_kqwrite_detach, + .f_event = ngd_kqwrite_event +}; static struct cdevsw ngd_cdevsw = { .d_version = D_VERSION, @@ -146,6 +169,7 @@ static struct cdevsw ngd_cdevsw = { .d_read = ngdread, .d_write = ngdwrite, .d_ioctl = ngdioctl, + .d_kqfilter = ngdkqfilter, .d_poll = ngdpoll, .d_name = NG_DEVICE_DEVNAME, }; @@ -198,6 +222,9 @@ ng_device_constructor(node_p node) mtx_init(&priv->readq.ifq_mtx, "ng_device queue", NULL, MTX_DEF); IFQ_SET_MAXLEN(&priv->readq, ifqmaxlen); + knlist_init_mtx(&priv->rsel.si_note, &priv->ngd_mtx); + knlist_init_mtx(&priv->wsel.si_note, &priv->ngd_mtx); + /* Link everything together */ NG_NODE_SET_PRIVATE(node, priv); priv->node = node; @@ -206,6 +233,8 @@ ng_device_constructor(node_p node) GID_WHEEL, 0600, NG_DEVICE_DEVNAME "%d", priv->unit); if (priv->ngddev == NULL) { printf("%s(): make_dev() failed\n", __func__); + knlist_destroy(&priv->rsel.si_note); + knlist_destroy(&priv->wsel.si_note); mtx_destroy(&priv->ngd_mtx); mtx_destroy(&priv->readq.ifq_mtx); free_unr(ngd_unit, priv->unit); @@ -319,6 +348,8 @@ ng_device_rcvdata(hook_p hook, item_p item) priv->flags &= ~NGDF_RWAIT; wakeup(priv); } + selwakeup(&priv->rsel); + KNOTE_LOCKED(&priv->rsel.si_note, 0); mtx_unlock(&priv->ngd_mtx); return (0); @@ -334,9 +365,22 @@ ng_device_disconnect(hook_p hook) DBG; + mtx_lock(&priv->ngd_mtx); + priv->flags |= NGDF_DYING; + wakeup(priv); + mtx_unlock(&priv->ngd_mtx); + destroy_dev(priv->ngddev); + + knlist_clear(&priv->rsel.si_note, 0); + knlist_clear(&priv->wsel.si_note, 0); + knlist_destroy(&priv->rsel.si_note); + knlist_destroy(&priv->wsel.si_note); mtx_destroy(&priv->ngd_mtx); + seldrain(&priv->rsel); + seldrain(&priv->wsel); + IF_DRAIN(&priv->readq); mtx_destroy(&(priv)->readq.ifq_mtx); @@ -493,9 +537,13 @@ ngdread(struct cdev *dev, struct uio *uio, int flag) return (EWOULDBLOCK); mtx_lock(&priv->ngd_mtx); priv->flags |= NGDF_RWAIT; - if ((error = msleep(priv, &priv->ngd_mtx, - PDROP | PCATCH | PZERO, - "ngdread", 0)) != 0) + if (priv->flags & NGDF_DYING) { + mtx_unlock(&priv->ngd_mtx); + error = ENXIO; + } else + error = mtx_sleep(priv, &priv->ngd_mtx, + PDROP | PCATCH, "ngdread", 0); + if (error != 0) return (error); } } while (m == NULL); @@ -538,9 +586,12 @@ ngdwrite(struct cdev *dev, struct uio *uio, int flag) if (m == NULL) return (ENOBUFS); + /* Setting VNET is required if connecting to a ng_bridge. */ + CURVNET_SET(priv->node->nd_vnet); NET_EPOCH_ENTER(et); NG_SEND_DATA_ONLY(error, priv->hook, m); NET_EPOCH_EXIT(et); + CURVNET_RESTORE(); return (error); } @@ -561,3 +612,72 @@ ngdpoll(struct cdev *dev, int events, struct thread *td) return (revents); } + +static void +ngd_kqread_detach(struct knote *kn) +{ + priv_p priv = (priv_p)kn->kn_hook; + + knlist_remove(&priv->rsel.si_note, kn, 0); +} + +static int +ngd_kqread_event(struct knote *kn, long hint) +{ + priv_p priv = (priv_p)kn->kn_hook; + struct mbuf *m; + + IFQ_LOCK(&priv->readq); + if (IFQ_IS_EMPTY(&priv->readq)) { + kn->kn_data = 0; + } else { + /* + * Since the queue does not store the total number of bytes that + * could be read across all packets and we do not want to + * traverse the whole queue, we only report the number of bytes + * for the first packet in the queue. + */ + IF_POLL(&priv->readq, m); + kn->kn_data = m->m_len; + } + IFQ_UNLOCK(&priv->readq); + + return (kn->kn_data > 0); +} + +static void +ngd_kqwrite_detach(struct knote *kn) +{ + priv_p priv = (priv_p)kn->kn_hook; + + knlist_remove(&priv->wsel.si_note, kn, 0); +} + +static int +ngd_kqwrite_event(struct knote *kn, long hint) +{ + kn->kn_data = IP_MAXPACKET; + + return (1); +} + +static int +ngdkqfilter(struct cdev *dev, struct knote *kn) +{ + priv_p priv = (priv_p)dev->si_drv1; + + switch (kn->kn_filter) { + case EVFILT_READ: + kn->kn_fop = &ngd_read_filterops; + kn->kn_hook = priv; + knlist_add(&priv->rsel.si_note, kn, 0); + return (0); + case EVFILT_WRITE: + kn->kn_fop = &ngd_write_filterops; + kn->kn_hook = priv; + knlist_add(&priv->wsel.si_note, kn, 0); + return (0); + default: + return (EINVAL); + } +}