Page MenuHomeFreeBSD

D40390.diff
No OneTemporary

D40390.diff

diff --git a/sys/netlink/netlink_sysevent.h b/sys/netlink/netlink_sysevent.h
--- a/sys/netlink/netlink_sysevent.h
+++ b/sys/netlink/netlink_sysevent.h
@@ -37,4 +37,13 @@
__NLSE_ATTR_MAX,
};
#define NLSE_ATTR_MAX (__NLSE_ATTR_MAX -1)
+
+/* commands */
+enum {
+ NLSE_CMD_UNSPEC = 0,
+ NLSE_CMD_NEWEVENT = 1,
+ __NLSE_CMD_MAX,
+};
+#define NLSE_CMD_MAX (__NLSE_CMD_MAX - 1)
+
#endif
diff --git a/sys/netlink/netlink_sysevent.c b/sys/netlink/netlink_sysevent.c
--- a/sys/netlink/netlink_sysevent.c
+++ b/sys/netlink/netlink_sysevent.c
@@ -32,6 +32,7 @@
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
+#include <sys/priv.h>
#include <net/vnet.h>
#include <netlink/netlink.h>
#include <netlink/netlink_ctl.h>
@@ -47,12 +48,69 @@
#define NLSE_FAMILY_NAME "nlsysevent"
static uint32_t ctrl_family_id;
+static int nlse_new_event(struct nlmsghdr *hdr, struct nl_pstate *npt);
+void sysevent_send(const char *system, const char *subsystem, const char *type,
+ const char *data);
+
#define MAX_SYSEVENT_GROUPS 64
static struct sysevent_group {
char *name;
uint32_t id;
} sysevent_groups[MAX_SYSEVENT_GROUPS] = {};
+static const struct genl_cmd nlse_cmds[] = {
+ {
+ .cmd_num = NLSE_CMD_NEWEVENT,
+ .cmd_name = "NEWEVENT",
+ .cmd_cb = nlse_new_event,
+ .cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_HASPOL,
+ .cmd_priv = PRIV_EVENTS,
+ }
+};
+
+struct nl_sysevent {
+ char *system;
+ char *subsystem;
+ char *type;
+ char *data;
+};
+
+#define _IN(_field) offsetof(struct genlmsghdr, _field)
+#define _OUT(_field) offsetof(struct nl_sysevent, _field)
+static const struct nlattr_parser nla_p_set[] = {
+ { .type = NLSE_ATTR_SYSTEM, .off = _OUT(system), .cb = nlattr_get_string },
+ { .type = NLSE_ATTR_SUBSYSTEM, .off = _OUT(subsystem), .cb = nlattr_get_string },
+ { .type = NLSE_ATTR_TYPE, .off = _OUT(type), .cb = nlattr_get_string },
+ { .type = NLSE_ATTR_DATA, .off = _OUT(data), .cb = nlattr_get_string },
+};
+static const struct nlfield_parser nlf_p_set[] = {
+};
+NL_DECLARE_PARSER(event_parser, struct genlmsghdr, nlf_p_set, nla_p_set);
+#undef _IN
+#undef _OUT
+
+int
+nlse_new_event(struct nlmsghdr *hdr, struct nl_pstate *npt)
+{
+ struct nl_sysevent se = {};
+ int error;
+
+ error = nl_parse_nlmsg(hdr, &event_parser, npt, &se);
+ if (error != 0)
+ return (error);
+ if (se.system == NULL)
+ return (EINVAL);
+ if (se.subsystem == NULL)
+ return (EINVAL);
+ if (se.type == NULL)
+ return (EINVAL);
+ if (se.data == NULL)
+ return (EINVAL);
+
+ sysevent_send(se.system, se.subsystem, se.type, se.data);
+ return (0);
+}
+
static void
sysevent_write(struct sysevent_group *se, const char *subsystem, const char *type,
const char *data)
@@ -112,7 +170,7 @@
return (NULL);
}
-static void
+void
sysevent_send(const char *system, const char *subsystem, const char *type,
const char *data)
{
@@ -134,6 +192,8 @@
{
devctl_set_notify_hook(sysevent_send);
ctrl_family_id = genl_register_family(NLSE_FAMILY_NAME, 0, 2, NLSE_ATTR_MAX);
+ genl_register_cmds(NLSE_FAMILY_NAME, nlse_cmds, NL_ARRAY_LEN(nlse_cmds));
+
for (size_t i = 0; i < nitems(devctl_systems); i++) {
if (i >= MAX_SYSEVENT_GROUPS) {
NL_LOG(LOG_WARNING, "impossible to add the event %s, too many events\n", devctl_systems[i]);
diff --git a/sys/sys/priv.h b/sys/sys/priv.h
--- a/sys/sys/priv.h
+++ b/sys/sys/priv.h
@@ -83,6 +83,7 @@
#define PRIV_SETTIMEOFDAY 18 /* Can call settimeofday. */
#define _PRIV_SETHOSTID 19 /* Removed. */
#define _PRIV_SETDOMAINNAME 20 /* Removed. */
+#define PRIV_EVENTS 21 /* Can to send events to the kernel */
/*
* Audit subsystem privileges.

File Metadata

Mime Type
text/plain
Expires
Thu, May 14, 1:38 AM (7 m, 5 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33029367
Default Alt Text
D40390.diff (3 KB)

Event Timeline