From nobody Thu Jun 1 21:02:28 2023 X-Original-To: dev-commits-src-main@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 4QXJVX3BJpz4YDC4; Thu, 1 Jun 2023 21:02:28 +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 "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4QXJVX2jJLz49R7; Thu, 1 Jun 2023 21:02:28 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1685653348; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=T5MrzTazov90JBGiUxVKJr7HsZhiEhR9tHihR7o5skg=; b=AWc0nSUryeKaaf+iDp3CWUjZA6LyH47HIs/KX52ig5pHfnG+/uonOZogyMigQIoj1NA6M/ xFGE82TKFmjTMig+3eqXocZRoov0tnMK72prQ5yhdmcrAOVOXL1NzKhdn3V7gm9sRyB2Ew fDShC0qx7cGA0y95GaY34AA9VberTASLULkQRJHBEiPZfPNPYcK5KRYaV3JAJTMNBj6Slu D0nyVPRm2EjG0DhhoezAG8tyHI/SQWJQxVGXe5/AKzkTjBepyYnrlFJLAE3uUm2zP0OpXA d93bym2UuDDFY5zKQgh9/RUKR11dH67RfqHtfl+ov8qhaE8KTqVc8Blc5E3akg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1685653348; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=T5MrzTazov90JBGiUxVKJr7HsZhiEhR9tHihR7o5skg=; b=mOFBb34AEIN/lDRz6TzrUlFu2QZH9IcYmFnwcxghYFE5GM5Ihd3IFwwj+NNB0jzAobweNo eTUhXyBmo2x4SwqFYXwBYsUsJF0B2i4aNQfnLoUb/BPThvaEjqUnbjI8oS9gK7HkHcMk+N IP6eRfTPgsmO+esZkJCzfcqxCRJujbw6PM8Z3Y1tShWllZw4UpfsN1gz6l3gwVPB5NKTU+ P7u47IGdB4/92gr7jvcgTQ4AkLl+xBJNtXTUJBMR4JIWYqaRkn3fwwOBwr3eiyT46Zxwwo GHrMc4AR4VkjtUNHtoZcRtNWEDdBDHdIq1Q4ZgMgxuYFyA2lrWpHFcvDEnGylg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1685653348; a=rsa-sha256; cv=none; b=iMgMF5xX6WIjFN1Jaw0HFAoc5pxJXJw86zqwX8L+2/FMEAfhzT9fJm6QfdwYa2MBpFVKFO pGPcEAD1wge7nvItIm12EdzFw4P+Vj0ifPu1tCgQLu2mcW/XxzR/aRTDQjd/fk0rW6eNjP u3REHGgn0B1cOcwito76bcL4kTgVoWmyBE/T+3gh4C2cl+EbQTTZMBji6DHrZeccaQhoMJ eRAWLTINGCuAu3ploKkbaGjM5IZXmZduz+YaLj+ZHCTCcXml+AyePuNp3btsYknC/QW88j wLKa89XjR2oTpJ+GIqDqqxK7I6aZ7MMKUBfpRZkRSrD5y/xE5hYCs7YTXkkvbQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (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 did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4QXJVX1gMQzXXY; Thu, 1 Jun 2023 21:02:28 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 351L2SRk061500; Thu, 1 Jun 2023 21:02:28 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 351L2SHn061499; Thu, 1 Jun 2023 21:02:28 GMT (envelope-from git) Date: Thu, 1 Jun 2023 21:02:28 GMT Message-Id: <202306012102.351L2SHn061499@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Baptiste Daroussin Subject: git: 8a2af0b469b6 - main - nlsysevent: add a genetlink(4) module to report kernel events List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: bapt X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 8a2af0b469b6d65ee48f2352ca56225b36d32342 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by bapt: URL: https://cgit.FreeBSD.org/src/commit/?id=8a2af0b469b6d65ee48f2352ca56225b36d32342 commit 8a2af0b469b6d65ee48f2352ca56225b36d32342 Author: Baptiste Daroussin AuthorDate: 2023-06-01 21:02:06 +0000 Commit: Baptiste Daroussin CommitDate: 2023-06-01 21:02:06 +0000 nlsysevent: add a genetlink(4) module to report kernel events Hooked to devctl_notify, this allows consumers to received events by subscribing to a system over a generic netlink protocol Reviewed by: imp, melifaro Differential Revision: https://reviews.freebsd.org/D37574 --- sys/modules/Makefile | 1 + sys/modules/nlsysevent/Makefile | 11 +++ sys/netlink/netlink_sysevent.c | 168 ++++++++++++++++++++++++++++++++++++++++ sys/netlink/netlink_sysevent.h | 40 ++++++++++ 4 files changed, 220 insertions(+) diff --git a/sys/modules/Makefile b/sys/modules/Makefile index b9867f25df4e..f14dd383221f 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -282,6 +282,7 @@ SUBDIR= \ nfsd \ nfslockd \ nfssvc \ + nlsysevent \ nge \ nmdm \ nullfs \ diff --git a/sys/modules/nlsysevent/Makefile b/sys/modules/nlsysevent/Makefile new file mode 100644 index 000000000000..d7d2100e3e66 --- /dev/null +++ b/sys/modules/nlsysevent/Makefile @@ -0,0 +1,11 @@ +# $FreeBSD$ + +.PATH: ${SRCTOP}/sys/netlink/ + +KMOD= nlsysevent +SRCS= netlink_sysevent.c + +CFLAGS+= -I${SRCTOP}/sys/contrib/netlink +EXPORT_SYMS= yes + +.include diff --git a/sys/netlink/netlink_sysevent.c b/sys/netlink/netlink_sysevent.c new file mode 100644 index 000000000000..67f18a3e2fe7 --- /dev/null +++ b/sys/netlink/netlink_sysevent.c @@ -0,0 +1,168 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2023 Baptiste Daroussin + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "netlink_sysevent.h" + +#define DEBUG_MOD_NAME nl_sysevent +#define DEBUG_MAX_LEVEL LOG_DEBUG3 +#include +_DECLARE_DEBUG(LOG_INFO); + +MALLOC_DEFINE(M_NLSE, "nlsysevent", "Memory used for Netlink sysevent"); +#define NLSE_FAMILY_NAME "nlsysevent" +static uint32_t ctrl_family_id; + +#define MAX_SYSEVENTS 64 +static struct sysevent { + char *name; + uint32_t id; +} sysevents[MAX_SYSEVENTS] = {}; + +static void +sysevent_write(struct sysevent *se, const char *subsystem, const char *type, + const char *data) +{ + struct nl_writer nw = {}; + + if (!nlmsg_get_group_writer(&nw, NLMSG_LARGE, NETLINK_GENERIC, se->id)) { + NL_LOG(LOG_DEBUG, "error allocating group writer"); + return; + } + struct nlmsghdr hdr = { .nlmsg_type = ctrl_family_id }; + if (!nlmsg_reply(&nw, &hdr, sizeof(struct genlmsghdr))) { + return; + } + + struct genlmsghdr *ghdr = nlmsg_reserve_object(&nw, struct genlmsghdr); + if (ghdr == NULL) { + NL_LOG(LOG_DEBUG, "unable to allocate memory"); + return; + } + ghdr->version = 0; + ghdr->cmd = 0; + ghdr->reserved = 0; + nlattr_add_string(&nw, NLSE_ATTR_SYSTEM, se->name); + nlattr_add_string(&nw, NLSE_ATTR_SUBSYSTEM, subsystem); + nlattr_add_string(&nw, NLSE_ATTR_TYPE, type); + if (data != NULL) + nlattr_add_string(&nw, NLSE_ATTR_DATA, data); + nlmsg_end(&nw); + nlmsg_flush(&nw); +} + +static void +sysevent_send(const char *system, const char *subsystem, const char *type, + const char *data) +{ + struct sysevent *se = NULL; + + for (size_t i = 0; i < MAX_SYSEVENTS; i++) { + if (sysevents[i].name == NULL) { + sysevents[i].name = strdup(system, M_NLSE); + sysevents[i].id = genl_register_group(NLSE_FAMILY_NAME, + system); + se = &sysevents[i]; + break; + } + if (strcmp(sysevents[i].name, system) == 0) { + se = &sysevents[i]; + break; + } + } + if (se == NULL) { + NL_LOG(LOG_WARNING, "impossible to add the event %s, " + "too many events\n", system); + return; + } + + CURVNET_SET(vnet0); + sysevent_write(se, subsystem, type, data); + CURVNET_RESTORE(); +} + +static void +nlsysevent_load(void) +{ + devctl_set_notify_hook(sysevent_send); + ctrl_family_id = genl_register_family(NLSE_FAMILY_NAME, 0, 2, NLSE_ATTR_MAX); + for (size_t i = 0; i < nitems(devctl_systems); i++) { + if (i >= MAX_SYSEVENTS) { + NL_LOG(LOG_WARNING, "impossible to add the event %s, too many events\n", devctl_systems[i]); + continue; + } + sysevents[i].name = strdup(devctl_systems[i], M_NLSE); + sysevents[i].id = genl_register_group(NLSE_FAMILY_NAME, devctl_systems[i]); + } +} + +static void +nlsysevent_unload(void) +{ + devctl_unset_notify_hook(); + genl_unregister_family(NLSE_FAMILY_NAME); + for (size_t i = 0; i < MAX_SYSEVENTS; i++) { + if (sysevents[i].name == NULL) + break; + free(sysevents[i].name, M_NLSE); + } +} + +static int +nlsysevent_loader(module_t mod __unused, int what, void *priv __unused) +{ + int err = 0; + + switch (what) { + case MOD_LOAD: + nlsysevent_load(); + break; + case MOD_UNLOAD: + nlsysevent_unload(); + break; + default: + err = EOPNOTSUPP; + break; + } + return (err); +} +static moduledata_t nlsysevent_mod = { "nlsysevent", nlsysevent_loader, NULL}; + +DECLARE_MODULE(nlsysevent, nlsysevent_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); +MODULE_DEPEND(nlsysevent, netlink, 1, 1, 1); +MODULE_VERSION(nlsysevent, 1); diff --git a/sys/netlink/netlink_sysevent.h b/sys/netlink/netlink_sysevent.h new file mode 100644 index 000000000000..23288d2dd5c3 --- /dev/null +++ b/sys/netlink/netlink_sysevent.h @@ -0,0 +1,40 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2023 Baptiste Daroussin + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _NETLINK_SYSEVENT_H_ +#define _NETLINK_SYSEVENT_H_ + +enum { + NLSE_ATTR_UNSPEC = 0, + NLSE_ATTR_SYSTEM = 1, + NLSE_ATTR_SUBSYSTEM = 2, + NLSE_ATTR_TYPE = 3, + NLSE_ATTR_DATA = 4, + __NLSE_ATTR_MAX, +}; +#define NLSE_ATTR_MAX (__NLSE_ATTR_MAX -1) +#endif