From 8c7d37159a7af48c213faa1c9f5820e6f954f791 Mon Sep 17 00:00:00 2001 From: Radoslaw Pajak Date: Tue, 25 Jun 2013 13:34:15 +0200 Subject: [PATCH] Beginning of kdbus support Working: - connecting to the bus - bus registration (hello message) Tested on the serverClient program made by L.Stempien Not working: - all the rest --- dbus/.cproject | 55 ++++++ dbus/.project | 89 +++++++++ dbus/Makefile.am | 2 + dbus/dbus-bus.c | 69 ++++++- dbus/dbus-bus.h | 5 + dbus/dbus-connection.c | 17 ++ dbus/dbus-transport-kdbus.c | 210 +++++++++++++++++++++ dbus/dbus-transport-kdbus.h | 8 + dbus/dbus-transport.c | 5 +- dbus/kdbus.h | 439 ++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 896 insertions(+), 3 deletions(-) create mode 100644 dbus/.cproject create mode 100644 dbus/.project create mode 100644 dbus/dbus-transport-kdbus.c create mode 100644 dbus/dbus-transport-kdbus.h create mode 100644 dbus/kdbus.h diff --git a/dbus/.cproject b/dbus/.cproject new file mode 100644 index 0000000..d0b6568 --- /dev/null +++ b/dbus/.cproject @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/dbus/.project b/dbus/.project new file mode 100644 index 0000000..598740d --- /dev/null +++ b/dbus/.project @@ -0,0 +1,89 @@ + + + dbus + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.autoBuildTarget + all + + + org.eclipse.cdt.make.core.buildArguments + + + + org.eclipse.cdt.make.core.buildCommand + make + + + org.eclipse.cdt.make.core.buildLocation + ${workspace_loc:/libdbus} + + + org.eclipse.cdt.make.core.cleanBuildTarget + clean + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + false + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.fullBuildTarget + all + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + true + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + org.tizen.nativecpp.apichecker.core.builder + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + org.tizen.nativecpp.apichecker.core.tizenCppNature + + diff --git a/dbus/Makefile.am b/dbus/Makefile.am index 90c2c90..7520382 100644 --- a/dbus/Makefile.am +++ b/dbus/Makefile.am @@ -106,6 +106,8 @@ DBUS_SHARED_arch_sources = \ dbus-sysdeps-pthread.c \ dbus-transport-unix.c \ dbus-transport-unix.h \ + dbus-transport-kdbus.c \ + dbus-transport-kdbus.h \ dbus-userdb.c \ dbus-userdb.h \ sd-daemon.c \ diff --git a/dbus/dbus-bus.c b/dbus/dbus-bus.c index 7b5f09a..6622595 100644 --- a/dbus/dbus-bus.c +++ b/dbus/dbus-bus.c @@ -31,6 +31,8 @@ #include "dbus-threads-internal.h" #include "dbus-connection-internal.h" #include "dbus-string.h" +#include "dbus-transport-kdbus.h" + /** * @defgroup DBusBus Message bus APIs @@ -485,6 +487,8 @@ internal_bus_get (DBusBusType type, goto out; } + _dbus_verbose (" !!! dbus_connection_open finished successfully !!!! \n"); //todo RP to be removed + if (!dbus_bus_register (connection, error)) { _dbus_connection_close_possibly_shared (connection); @@ -598,6 +602,67 @@ dbus_bus_get_private (DBusBusType type, return internal_bus_get (type, TRUE, error); } +/* kdbus add-on [RP] - bus register for kdbus + * Function checks if the method is kdbus. If yes - it registers on the bus, if no - does nothing and returns TRUE + * Must be invoked before dbus_bus_register because in kdbus it's realized in different manner + * and dbus_bus_register can not be used for that. + * It does not collide with dbus_bus_register because dbus_bus_register at the beginning checks + * whether unique_name has already been assigned and doesn't try to do it again. + */ +dbus_bool_t dbus_bus_register_kdbus(DBusAddressEntry *entry, DBusConnection *connection, DBusError *error) +{ + dbus_bool_t retval = TRUE; + const char *method; + + method = dbus_address_entry_get_method (entry); + _dbus_assert (method != NULL); + + if (strcmp (method, "kdbus") == 0) + { + BusData *bd; + + _dbus_return_val_if_fail (connection != NULL, FALSE); + _dbus_return_val_if_error_is_set (error, FALSE); + + retval = FALSE; + + if (!_DBUS_LOCK (bus_datas)) + { + _DBUS_SET_OOM (error); + /* do not "goto out", that would try to unlock */ + return FALSE; + } + + bd = ensure_bus_data (connection); + if (bd == NULL) + { + _DBUS_SET_OOM (error); + goto out; + } + + if (bd->unique_name != NULL) + { + _dbus_verbose ("Ignoring attempt to register the same DBusConnection %s with the message bus a second time.\n", + bd->unique_name); + /* Success! */ + retval = TRUE; + goto out; + } + + if(!bus_register_kdbus(&bd->unique_name, connection, error)) + goto out; + + retval = TRUE; + + out: + _DBUS_UNLOCK (bus_datas); + + if (!retval) + _DBUS_ASSERT_ERROR_IS_SET (error); + } + return retval; +} + /** * Registers a connection with the bus. This must be the first * thing an application does when connecting to the message bus. @@ -652,7 +717,7 @@ dbus_bus_register (DBusConnection *connection, DBusError *error) { DBusMessage *message, *reply; - char *name; + char name[18]; BusData *bd; dbus_bool_t retval; @@ -707,7 +772,7 @@ dbus_bus_register (DBusConnection *connection, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)) goto out; - + bd->unique_name = _dbus_strdup (name); if (bd->unique_name == NULL) { diff --git a/dbus/dbus-bus.h b/dbus/dbus-bus.h index 02a9571..2e6a216 100644 --- a/dbus/dbus-bus.h +++ b/dbus/dbus-bus.h @@ -28,6 +28,7 @@ #define DBUS_BUS_H #include +#include "dbus-address.h" DBUS_BEGIN_DECLS @@ -47,6 +48,10 @@ DBUS_EXPORT dbus_bool_t dbus_bus_register (DBusConnection *connection, DBusError *error); DBUS_EXPORT +dbus_bool_t dbus_bus_register_kdbus (DBusAddressEntry *entry, + DBusConnection *connection, + DBusError *error); +DBUS_EXPORT dbus_bool_t dbus_bus_set_unique_name (DBusConnection *connection, const char *unique_name); DBUS_EXPORT diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 87cfeb0..bb51996 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -44,6 +44,7 @@ #include "dbus-threads-internal.h" #include "dbus-bus.h" #include "dbus-marshal-basic.h" +#include "dbus-transport-kdbus.h" #ifdef DBUS_DISABLE_CHECKS #define TOOK_LOCK_CHECK(connection) @@ -1843,6 +1844,22 @@ connection_try_from_address_entry (DBusAddressEntry *entry, #ifndef DBUS_DISABLE_CHECKS _dbus_assert (!connection->have_connection_lock); #endif + + /* kdbus add-on [RP] - bus register for kdbus + * Function checks if the method is kdbus. If yes - it registers on the bus, if no - does nothing and returns TRUE + * Must be invoked before dbus_bus_register because in kdbus it's realized in different manner + * and dbus_bus_register can not be used for that. + * It does not collide with dbus_bus_register because dbus_bus_register at the beginning checks + * whether unique_name has already been assigned and doesn't try to do it again. + */ + + if(!dbus_bus_register_kdbus(entry, connection, error)) + { + _dbus_connection_close_possibly_shared (connection); + dbus_connection_unref (connection); + connection = NULL; + } + return connection; } diff --git a/dbus/dbus-transport-kdbus.c b/dbus/dbus-transport-kdbus.c new file mode 100644 index 0000000..dfecc64 --- /dev/null +++ b/dbus/dbus-transport-kdbus.c @@ -0,0 +1,210 @@ +/* + * dbus-transport-kdbus.c + * + * Transport layer using kdbus + * + * Created on: Jun 20, 2013 + * Author: r.pajak + * + * + */ + +#include "dbus-transport.h" +#include "dbus-transport-kdbus.h" +#include +#include "dbus-errors.h" +#include +#include +#include +#include +#include + +//todo poniższe do wywalenia po zaimplementowaniu vtable (_dbus_transport_new_for_socket) +#include "dbus-transport-socket.h" + +int _dbus_connect_kdbus (const char *path, DBusError *error); +DBusTransport* _dbus_transport_new_for_kdbus (const char *path, DBusError *error); + + +/** + * Creates a connection to the kdbus bus + * + * This will set FD_CLOEXEC for the socket returned. + * + * @param path the path to UNIX domain socket + * @param error return location for error code + * @returns connection file descriptor or -1 on error + */ +int _dbus_connect_kdbus (const char *path, DBusError *error) +{ + int fd; + + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + _dbus_verbose ("connecting to kdbus bus %s\n", path); + + fd = open(path, O_RDWR|O_CLOEXEC|O_NONBLOCK); //[RP] | O_NONBLOCK added here, in dbus added separately in section commented out below + if (fd < 0) + { + dbus_set_error(error, _dbus_error_from_errno (errno), "Failed to open file descriptor: %s", _dbus_strerror (errno)); + _DBUS_ASSERT_ERROR_IS_SET(error); + return -1; //[RP] not needed here if commented block below is removed + } + + /*if (!_dbus_set_fd_nonblocking (fd, error)) + { + _DBUS_ASSERT_ERROR_IS_SET (error); + _dbus_close (fd, NULL); + return -1; + }*/ + + return fd; +} + + +/** + * Creates a new transport for kdbus. + * This creates a client-side of a transport. + * + * @param path the path to the domain socket. + * @param error address where an error can be returned. + * @returns a new transport, or #NULL on failure. + */ +DBusTransport* _dbus_transport_new_for_kdbus (const char *path, DBusError *error) +{ + int fd; + DBusTransport *transport; + DBusString address; + + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + + if (!_dbus_string_init (&address)) + { + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + return NULL; + } + + fd = -1; + + if (!_dbus_string_append (&address, path)) + { + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + goto failed_0; + } + + fd = _dbus_connect_kdbus (path, error); +// fd = _dbus_connect_unix_socket (path, error); + if (fd < 0) + { + _DBUS_ASSERT_ERROR_IS_SET (error); + goto failed_0; + } + + _dbus_verbose ("Successfully connected to kdbus bus %s\n", path); + + transport = _dbus_transport_new_for_socket (fd, NULL, &address); //todo + if (transport == NULL) + { + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + goto failed_1; + } + + _dbus_string_free (&address); + + return transport; + + failed_1: + _dbus_close_socket (fd, NULL); + failed_0: + _dbus_string_free (&address); + return NULL; +} + + +/** + * Opens kdbus transport. + * + * @param entry the address entry to try opening + * @param transport_p return location for the opened transport + * @param error error to be set + * @returns result of the attempt + */ +DBusTransportOpenResult _dbus_transport_open_kdbus(DBusAddressEntry *entry, + DBusTransport **transport_p, + DBusError *error) +{ + const char *method; + + method = dbus_address_entry_get_method (entry); + _dbus_assert (method != NULL); + + if (strcmp (method, "kdbus") == 0) + { + const char *path = dbus_address_entry_get_value (entry, "path"); + + if (path == NULL) + { + _dbus_set_bad_address (error, "kdbus", "path", NULL); + return DBUS_TRANSPORT_OPEN_BAD_ADDRESS; + } + + *transport_p = _dbus_transport_new_for_kdbus (path, error); + + if (*transport_p == NULL) + { + _DBUS_ASSERT_ERROR_IS_SET (error); + return DBUS_TRANSPORT_OPEN_DID_NOT_CONNECT; + } + else + { + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + return DBUS_TRANSPORT_OPEN_OK; + } + } + else + { + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + return DBUS_TRANSPORT_OPEN_NOT_HANDLED; + } +} + +dbus_bool_t bus_register_kdbus(char** unique_name, DBusConnection *connection, DBusError *error) +{ + dbus_bool_t retval = TRUE; + char name[18]; + struct kdbus_cmd_hello hello; + int fd; + + memset(&hello, 0, sizeof(hello)); + hello.conn_flags = KDBUS_HELLO_ACCEPT_FD | + KDBUS_HELLO_ATTACH_COMM | + KDBUS_HELLO_ATTACH_EXE | + KDBUS_HELLO_ATTACH_CMDLINE | + KDBUS_HELLO_ATTACH_CAPS | + KDBUS_HELLO_ATTACH_CGROUP | + KDBUS_HELLO_ATTACH_SECLABEL | + KDBUS_HELLO_ATTACH_AUDIT; + hello.size = sizeof(struct kdbus_cmd_hello); + hello.pool_size = (16 * 1024LU * 1024LU); //todo was: #define POOL_SIZE + + if(!dbus_connection_get_socket(connection, &fd)) + { + dbus_set_error (error, "failed to get fd for connection", NULL); + return FALSE; + } + if (ioctl(fd, KDBUS_CMD_HELLO, &hello)) + { + dbus_set_error(error,_dbus_error_from_errno (errno), "Failed to send hello: %s", _dbus_strerror (errno)); + return FALSE; + } + + _dbus_verbose("-- Our peer ID is: %llu\n", (unsigned long long)hello.id); //todo [RP] can be removed after development + sprintf(name, "%llx", (unsigned long long)hello.id); + *unique_name = _dbus_strdup(name); + if (*unique_name == NULL) + { + _DBUS_SET_OOM (error); + return FALSE; + } + + return retval; +} diff --git a/dbus/dbus-transport-kdbus.h b/dbus/dbus-transport-kdbus.h new file mode 100644 index 0000000..1b1d98c --- /dev/null +++ b/dbus/dbus-transport-kdbus.h @@ -0,0 +1,8 @@ + +#include "dbus-transport.h" +#include "dbus-transport-protected.h" +#include "dbus-address.h" +#include "dbus-errors.h" + +DBusTransportOpenResult _dbus_transport_open_kdbus(DBusAddressEntry *entry, DBusTransport **transport_p, DBusError *error); +dbus_bool_t bus_register_kdbus(char** uniqe_name, DBusConnection *connection, DBusError *error); diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c index c483d76..972f02c 100644 --- a/dbus/dbus-transport.c +++ b/dbus/dbus-transport.c @@ -21,7 +21,7 @@ * */ -#include +#include <../config.h> #include "dbus-transport-protected.h" #include "dbus-transport-unix.h" #include "dbus-transport-socket.h" @@ -32,6 +32,8 @@ #include "dbus-credentials.h" #include "dbus-mainloop.h" #include "dbus-message.h" + +#include "dbus-transport-kdbus.h" #ifdef DBUS_BUILD_TESTS #include "dbus-server-debug-pipe.h" #endif @@ -347,6 +349,7 @@ static const struct { } open_funcs[] = { { _dbus_transport_open_socket }, { _dbus_transport_open_platform_specific }, + { _dbus_transport_open_kdbus }, { _dbus_transport_open_autolaunch } #ifdef DBUS_BUILD_TESTS , { _dbus_transport_open_debug_pipe } diff --git a/dbus/kdbus.h b/dbus/kdbus.h new file mode 100644 index 0000000..4604eb3 --- /dev/null +++ b/dbus/kdbus.h @@ -0,0 +1,439 @@ +/* + * Copyright (C) 2013 Kay Sievers + * Copyright (C) 2013 Greg Kroah-Hartman + * Copyright (C) 2013 Linux Foundation + * Copyright (C) 2013 Lennart Poettering + * Copyright (C) 2013 Daniel Mack + * + * kdbus is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation; either version 2.1 of the License, or (at + * your option) any later version. + */ + +#ifndef _KDBUS_H_ +#define _KDBUS_H_ + +#ifndef __KERNEL__ +#include +#include +#include +#endif + +#define KDBUS_IOC_MAGIC 0x95 +#define KDBUS_SRC_ID_KERNEL (0) +#define KDBUS_DST_ID_WELL_KNOWN_NAME (0) +#define KDBUS_MATCH_SRC_ID_ANY (~0ULL) +#define KDBUS_DST_ID_BROADCAST (~0ULL) + +/* Common first elements in a structure which are used to iterate over + * a list of elements. */ +#define KDBUS_PART_HEADER \ + struct { \ + __u64 size; \ + __u64 type; \ + } + +/* Message sent from kernel to userspace, when the owner or starter of + * a well-known name changes */ +struct kdbus_manager_msg_name_change { + __u64 old_id; + __u64 new_id; + __u64 flags; /* 0 or (possibly?) KDBUS_NAME_IN_QUEUE */ + char name[0]; +}; + +struct kdbus_manager_msg_id_change { + __u64 id; + __u64 flags; /* The kernel flags field from KDBUS_HELLO */ +}; + +struct kdbus_creds { + __u64 uid; + __u64 gid; + __u64 pid; + __u64 tid; + + /* The starttime of the process PID. This is useful to detect + PID overruns from the client side. i.e. if you use the PID to + look something up in /proc/$PID/ you can afterwards check the + starttime field of it to ensure you didn't run into a PID + ovretun. */ + __u64 starttime; +}; + +struct kdbus_audit { + __u64 sessionid; + __u64 loginuid; +}; + +struct kdbus_timestamp { + __u64 monotonic_ns; + __u64 realtime_ns; +}; + +struct kdbus_vec { + __u64 size; + union { + __u64 address; + __u64 offset; + }; +}; + +struct kdbus_memfd { + __u64 size; + int fd; + __u32 __pad; +}; + +/* Message Item Types */ +enum { + _KDBUS_MSG_NULL, + + /* Filled in by userspace */ + KDBUS_MSG_PAYLOAD_VEC, /* .data_vec, reference to memory area */ + KDBUS_MSG_PAYLOAD_OFF, /* .data_vec, reference to memory area */ + KDBUS_MSG_PAYLOAD_MEMFD, /* file descriptor of a special data file */ + KDBUS_MSG_FDS, /* .data_fds of file descriptors */ + KDBUS_MSG_BLOOM, /* for broadcasts, carries bloom filter blob in .data */ + KDBUS_MSG_DST_NAME, /* destination's well-known name, in .str */ + KDBUS_MSG_PRIORITY, /* queue priority for message */ + + /* Filled in by kernelspace */ + KDBUS_MSG_SRC_NAMES = 0x400,/* NUL separated string list with well-known names of source */ + KDBUS_MSG_TIMESTAMP, /* .timestamp */ + KDBUS_MSG_SRC_CREDS, /* .creds */ + KDBUS_MSG_SRC_PID_COMM, /* optional, in .str */ + KDBUS_MSG_SRC_TID_COMM, /* optional, in .str */ + KDBUS_MSG_SRC_EXE, /* optional, in .str */ + KDBUS_MSG_SRC_CMDLINE, /* optional, in .str (a chain of NUL str) */ + KDBUS_MSG_SRC_CGROUP, /* optional, in .str */ + KDBUS_MSG_SRC_CAPS, /* caps data blob, in .data */ + KDBUS_MSG_SRC_SECLABEL, /* NUL terminated string, in .str */ + KDBUS_MSG_SRC_AUDIT, /* .audit */ + + /* Special messages from kernel, consisting of one and only one of these data blocks */ + KDBUS_MSG_NAME_ADD = 0x800,/* .name_change */ + KDBUS_MSG_NAME_REMOVE, /* .name_change */ + KDBUS_MSG_NAME_CHANGE, /* .name_change */ + KDBUS_MSG_ID_ADD, /* .id_change */ + KDBUS_MSG_ID_REMOVE, /* .id_change */ + KDBUS_MSG_REPLY_TIMEOUT, /* empty, but .reply_cookie in .kdbus_msg is filled in */ + KDBUS_MSG_REPLY_DEAD, /* dito */ +}; + +/** + * struct kdbus_item - chain of data blocks + * + * size: overall data record size + * type: kdbus_item type of data + */ +struct kdbus_item { + KDBUS_PART_HEADER; + union { + /* inline data */ + __u8 data[0]; + __u32 data32[0]; + __u64 data64[0]; + char str[0]; + + /* connection */ + __u64 id; + + /* data vector */ + struct kdbus_vec vec; + + /* process credentials and properties*/ + struct kdbus_creds creds; + struct kdbus_audit audit; + struct kdbus_timestamp timestamp; + + /* specific fields */ + struct kdbus_memfd memfd; + int fds[0]; + struct kdbus_manager_msg_name_change name_change; + struct kdbus_manager_msg_id_change id_change; + }; +}; + +enum { + KDBUS_MSG_FLAGS_EXPECT_REPLY = 1 << 0, + KDBUS_MSG_FLAGS_NO_AUTO_START = 1 << 1, +}; + +enum { + KDBUS_PAYLOAD_KERNEL, + KDBUS_PAYLOAD_DBUS1 = 0x4442757356657231ULL, /* 'DBusVer1' */ + KDBUS_PAYLOAD_GVARIANT = 0x4756617269616e74ULL, /* 'GVariant' */ +}; + +/** + * struct kdbus_msg + * + * set by userspace: + * dst_id: destination id + * flags: KDBUS_MSG_FLAGS_* + * items: data records + * + * set by kernel: + * src_id: who sent the message + */ +struct kdbus_msg { + __u64 size; + __u64 flags; + __u64 dst_id; /* connection, 0 == name in data, ~0 broadcast */ + __u64 src_id; /* connection, 0 == kernel */ + __u64 payload_type; /* 'DBusVer1', 'GVariant', ... */ + __u64 cookie; /* userspace-supplied cookie */ + union { + __u64 cookie_reply; /* cookie we reply to */ + __u64 timeout_ns; /* timespan to wait for reply */ + }; + struct kdbus_item items[0]; +}; + +enum { + _KDBUS_POLICY_NULL, + KDBUS_POLICY_NAME, + KDBUS_POLICY_ACCESS, +}; + +enum { + _KDBUS_POLICY_ACCESS_NULL, + KDBUS_POLICY_ACCESS_USER, + KDBUS_POLICY_ACCESS_GROUP, + KDBUS_POLICY_ACCESS_WORLD, +}; + +enum { + KDBUS_POLICY_RECV = 1 << 2, + KDBUS_POLICY_SEND = 1 << 1, + KDBUS_POLICY_OWN = 1 << 0, +}; + +struct kdbus_policy_access { + __u64 type; /* USER, GROUP, WORLD */ + __u64 bits; /* RECV, SEND, OWN */ + __u64 id; /* uid, gid, 0 */ +}; + +//FIXME: convert access to access[] +struct kdbus_policy { + KDBUS_PART_HEADER; + union { + char name[0]; + struct kdbus_policy_access access; + }; +}; + +/* A series of KDBUS_POLICY_NAME, plus one or more KDBUS_POLICY_ACCESS */ +struct kdbus_cmd_policy { + __u64 size; + struct kdbus_policy policies[0]; +}; + +/* Flags for struct kdbus_cmd_hello */ +enum { + KDBUS_HELLO_STARTER = 1 << 0, + KDBUS_HELLO_ACCEPT_FD = 1 << 1, + + /* The following have an effect on directed messages only -- + * not for broadcasts */ + KDBUS_HELLO_ATTACH_COMM = 1 << 10, + KDBUS_HELLO_ATTACH_EXE = 1 << 11, + KDBUS_HELLO_ATTACH_CMDLINE = 1 << 12, + KDBUS_HELLO_ATTACH_CGROUP = 1 << 13, + KDBUS_HELLO_ATTACH_CAPS = 1 << 14, + KDBUS_HELLO_ATTACH_SECLABEL = 1 << 15, + KDBUS_HELLO_ATTACH_AUDIT = 1 << 16, +}; + +struct kdbus_cmd_hello { + __u64 size; + + /* userspace → kernel, kernel → userspace */ + __u64 conn_flags; /* userspace specifies its + * capabilities and more, kernel + * returns its capabilites and + * more. Kernel might refuse client's + * capabilities by returning an error + * from KDBUS_HELLO */ + + /* kernel → userspace */ + __u64 bus_flags; /* this is .flags copied verbatim from + * from original KDBUS_CMD_BUS_MAKE + * ioctl. It's intended to be useful + * to do negotiation of features of + * the payload that is transfreted. */ + __u64 id; /* id assigned to this connection */ + __u64 bloom_size; /* The bloom filter size chosen by the + * bus owner */ + __u64 pool_size; /* maximum size of pool buffer */ + struct kdbus_item items[0]; +}; + +/* Flags for kdbus_cmd_{bus,ep,ns}_make */ +enum { + KDBUS_MAKE_ACCESS_GROUP = 1 << 0, + KDBUS_MAKE_ACCESS_WORLD = 1 << 1, + KDBUS_MAKE_POLICY_OPEN = 1 << 2, +}; + +/* Items to append to kdbus_cmd_{bus,ep,ns}_make */ +enum { + _KDBUS_MAKE_NULL, + KDBUS_MAKE_NAME, + KDBUS_MAKE_CGROUP, /* the cgroup hierarchy ID for which to attach + * cgroup membership paths to messages. + * FIXME: remove, use *the* hierarchy */ + KDBUS_MAKE_CRED, /* allow translator services which connect + * to the bus on behalf of somebody else, + * allow specifiying the credentials of the + * client to connect on behalf on. Needs + * privileges */ +}; + +struct kdbus_cmd_bus_make { + __u64 size; + __u64 flags; /* userspace → kernel, kernel → userspace + * When creating a bus feature + * kernel negotiation. */ + __u64 bus_flags; /* userspace → kernel + * When a bus is created this value is + * copied verbatim into the bus + * structure and returned from + * KDBUS_CMD_HELLO, later */ + __u64 bloom_size; /* size of the bloom filter for this bus */ + struct kdbus_item items[0]; +}; + +struct kdbus_cmd_ep_make { + __u64 size; + __u64 flags; /* userspace → kernel, kernel → userspace + * When creating an entry point + * feature kernel negotiation done the + * same way as for + * KDBUS_CMD_BUS_MAKE. Unused for + * now. */ + struct kdbus_item items[0]; +}; + +struct kdbus_cmd_ns_make { + __u64 size; + __u64 flags; /* userspace → kernel, kernel → userspace + * When creating an entry point + * feature kernel negotiation done the + * same way as for + * KDBUS_CMD_BUS_MAKE. Unused for + * now. */ + struct kdbus_item items[0]; +}; + +enum { + /* userspace → kernel */ + KDBUS_NAME_REPLACE_EXISTING = 1 << 0, + KDBUS_NAME_QUEUE = 1 << 1, + KDBUS_NAME_ALLOW_REPLACEMENT = 1 << 2, + + /* kernel → userspace */ + KDBUS_NAME_IN_QUEUE = 1 << 16, +}; + +/* We allow (de)regestration of names of other peers */ +struct kdbus_cmd_name { + __u64 size; + __u64 flags; + __u64 id; + __u64 conn_flags; + char name[0]; +}; + +struct kdbus_cmd_names { + __u64 size; + struct kdbus_cmd_name names[0]; +}; + +enum { + _KDBUS_NAME_INFO_ITEM_NULL, + KDBUS_NAME_INFO_ITEM_NAME, /* userspace → kernel */ + KDBUS_NAME_INFO_ITEM_SECLABEL, /* kernel → userspace */ + KDBUS_NAME_INFO_ITEM_AUDIT, /* kernel → userspace */ +}; + +struct kdbus_cmd_name_info { + __u64 size; /* overall size of info */ + __u64 flags; + __u64 id; /* either ID, or 0 and _ITEM_NAME follows */ + struct kdbus_creds creds; + struct kdbus_item items[0]; /* list of item records */ +}; + +enum { + _KDBUS_MATCH_NULL, + KDBUS_MATCH_BLOOM, /* Matches a mask blob against KDBUS_MSG_BLOOM */ + KDBUS_MATCH_SRC_NAME, /* Matches a name string against KDBUS_MSG_SRC_NAMES */ + KDBUS_MATCH_NAME_ADD, /* Matches a name string against KDBUS_MSG_NAME_ADD */ + KDBUS_MATCH_NAME_REMOVE, /* Matches a name string against KDBUS_MSG_NAME_REMOVE */ + KDBUS_MATCH_NAME_CHANGE, /* Matches a name string against KDBUS_MSG_NAME_CHANGE */ + KDBUS_MATCH_ID_ADD, /* Matches an ID against KDBUS_MSG_ID_ADD */ + KDBUS_MATCH_ID_REMOVE, /* Matches an ID against KDBUS_MSG_ID_REMOVE */ +}; + +struct kdbus_cmd_match { + __u64 size; + __u64 id; /* We allow registration/deregestration of matches for other peers */ + __u64 cookie; /* userspace supplied cookie; when removing; kernel deletes everything with same cookie */ + __u64 src_id; /* ~0: any. other: exact unique match */ + struct kdbus_item items[0]; +}; + +struct kdbus_cmd_monitor { + __u64 id; /* We allow setting the monitor flag of other peers */ + unsigned int enable; /* A boolean to enable/disable monitoring */ + __u32 __pad; +}; + +/* FD states: + * control nodes: unset + * bus owner (via KDBUS_CMD_BUS_MAKE) + * ns owner (via KDBUS_CMD_NS_MAKE) + * + * ep nodes: unset + * connected (via KDBUS_CMD_HELLO) + * starter (via KDBUS_CMD_HELLO with KDBUS_CMD_HELLO_STARTER) + * ep owner (via KDBUS_CMD_EP_MAKE) + */ +enum { + /* kdbus control node commands: require unset state */ + KDBUS_CMD_BUS_MAKE = _IOW(KDBUS_IOC_MAGIC, 0x00, struct kdbus_cmd_bus_make), + KDBUS_CMD_NS_MAKE = _IOR(KDBUS_IOC_MAGIC, 0x10, struct kdbus_cmd_ns_make), + + /* kdbus ep node commands: require unset state */ + KDBUS_CMD_EP_MAKE = _IOW(KDBUS_IOC_MAGIC, 0x20, struct kdbus_cmd_ep_make), + KDBUS_CMD_HELLO = _IOWR(KDBUS_IOC_MAGIC, 0x30, struct kdbus_cmd_hello), + + /* kdbus ep node commands: require connected state */ + KDBUS_CMD_MSG_SEND = _IOW(KDBUS_IOC_MAGIC, 0x40, struct kdbus_msg), + KDBUS_CMD_MSG_RECV = _IOR(KDBUS_IOC_MAGIC, 0x41, __u64 *), + KDBUS_CMD_MSG_RELEASE = _IOW(KDBUS_IOC_MAGIC, 0x42, __u64 *), + + KDBUS_CMD_NAME_ACQUIRE = _IOWR(KDBUS_IOC_MAGIC, 0x50, struct kdbus_cmd_name), + KDBUS_CMD_NAME_RELEASE = _IOW(KDBUS_IOC_MAGIC, 0x51, struct kdbus_cmd_name), + KDBUS_CMD_NAME_LIST = _IOWR(KDBUS_IOC_MAGIC, 0x52, struct kdbus_cmd_names), + KDBUS_CMD_NAME_QUERY = _IOWR(KDBUS_IOC_MAGIC, 0x53, struct kdbus_cmd_name_info), + + KDBUS_CMD_MATCH_ADD = _IOW(KDBUS_IOC_MAGIC, 0x60, struct kdbus_cmd_match), + KDBUS_CMD_MATCH_REMOVE = _IOW(KDBUS_IOC_MAGIC, 0x61, struct kdbus_cmd_match), + KDBUS_CMD_MONITOR = _IOW(KDBUS_IOC_MAGIC, 0x62, struct kdbus_cmd_monitor), + + /* kdbus ep node commands: require ep owner state */ + KDBUS_CMD_EP_POLICY_SET = _IOW(KDBUS_IOC_MAGIC, 0x70, struct kdbus_cmd_policy), + + /* kdbus memfd commands: */ + KDBUS_CMD_MEMFD_NEW = _IOR(KDBUS_IOC_MAGIC, 0x80, int *), + KDBUS_CMD_MEMFD_SIZE_GET = _IOR(KDBUS_IOC_MAGIC, 0x81, __u64 *), + KDBUS_CMD_MEMFD_SIZE_SET = _IOW(KDBUS_IOC_MAGIC, 0x82, __u64 *), + KDBUS_CMD_MEMFD_SEAL_GET = _IOR(KDBUS_IOC_MAGIC, 0x83, int *), + KDBUS_CMD_MEMFD_SEAL_SET = _IO(KDBUS_IOC_MAGIC, 0x84), +}; +#endif -- 2.7.4