| <?xml version='1.0'?> <!--*-nxml-*--> |
| <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" |
| "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> |
| |
| <refentry id="kdbus.match"> |
| |
| <refentryinfo> |
| <title>kdbus.match</title> |
| <productname>kdbus.match</productname> |
| </refentryinfo> |
| |
| <refmeta> |
| <refentrytitle>kdbus.match</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </refmeta> |
| |
| <refnamediv> |
| <refname>kdbus.match</refname> |
| <refpurpose>kdbus match</refpurpose> |
| </refnamediv> |
| |
| <refsect1> |
| <title>Description</title> |
| |
| <para> |
| kdbus connections can install matches in order to subscribe to signal |
| messages sent on the bus. Such signal messages can be either directed |
| to a single connection (by setting a specific connection ID in |
| <varname>struct kdbus_msg.dst_id</varname> or by sending it to a |
| well-known name), or to potentially <emphasis>all</emphasis> currently |
| active connections on the bus (by setting |
| <varname>struct kdbus_msg.dst_id</varname> to |
| <constant>KDBUS_DST_ID_BROADCAST</constant>). |
| A signal message always has the <constant>KDBUS_MSG_SIGNAL</constant> |
| bit set in the <varname>flags</varname> bitfield. |
| Also, signal messages can originate from either the kernel (called |
| <emphasis>notifications</emphasis>), or from other bus connections. |
| In either case, a bus connection needs to have a suitable |
| <emphasis>match</emphasis> installed in order to receive any signal |
| message. Without any rules installed in the connection, no signal message |
| will be received. |
| </para> |
| </refsect1> |
| |
| <refsect1> |
| <title>Matches for signal messages from other connections</title> |
| <para> |
| Matches for messages from other connections (not kernel notifications) |
| are implemented as bloom filters (see below). The sender adds certain |
| properties of the message as elements to a bloom filter bit field, and |
| sends that along with the signal message. |
| |
| The receiving connection adds the message properties it is interested in |
| as elements to a bloom mask bit field, and uploads the mask as match rule, |
| possibly along with some other rules to further limit the match. |
| |
| The kernel will match the signal message's bloom filter against the |
| connection's bloom mask (simply by &-ing it), and will decide whether |
| the message should be delivered to a connection. |
| </para> |
| <para> |
| The kernel has no notion of any specific properties of the signal message, |
| all it sees are the bit fields of the bloom filter and the mask to match |
| against. The use of bloom filters allows simple and efficient matching, |
| without exposing any message properties or internals to the kernel side. |
| Clients need to deal with the fact that they might receive signal messages |
| which they did not subscribe to, as the bloom filter might allow |
| false-positives to pass the filter. |
| |
| To allow the future extension of the set of elements in the bloom filter, |
| the filter specifies a <emphasis>generation</emphasis> number. A later |
| generation must always contain all elements of the set of the previous |
| generation, but can add new elements to the set. The match rules mask can |
| carry an array with all previous generations of masks individually stored. |
| When the filter and mask are matched by the kernel, the mask with the |
| closest matching generation is selected as the index into the mask array. |
| </para> |
| </refsect1> |
| |
| <refsect1> |
| <title>Bloom filters</title> |
| <para> |
| Bloom filters allow checking whether a given word is present in a |
| dictionary. This allows connections to set up a mask for information it |
| is interested in, and will be delivered signal messages that have a |
| matching filter. |
| |
| For general information, see |
| <ulink url="https://en.wikipedia.org/wiki/Bloom_filter">the Wikipedia |
| article on bloom filters</ulink>. |
| </para> |
| <para> |
| The size of the bloom filter is defined per bus when it is created, in |
| <varname>kdbus_bloom_parameter.size</varname>. All bloom filters attached |
| to signal messages on the bus must match this size, and all bloom filter |
| matches uploaded by connections must also match the size, or a multiple |
| thereof (see below). |
| |
| The calculation of the mask has to be done in userspace applications. The |
| kernel just checks the bitmasks to decide whether or not to let the |
| message pass. All bits in the mask must match the filter in and bit-wise |
| <emphasis>AND</emphasis> logic, but the mask may have more bits set than |
| the filter. Consequently, false positive matches are expected to happen, |
| and programs must deal with that fact by checking the contents of the |
| payload again at receive time. |
| </para> |
| <para> |
| Masks are entities that are always passed to the kernel as part of a |
| match (with an item of type <constant>KDBUS_ITEM_BLOOM_MASK</constant>), |
| and filters can be attached to signals, with an item of type |
| <constant>KDBUS_ITEM_BLOOM_FILTER</constant>. For a filter to match, all |
| its bits have to be set in the match mask as well. |
| </para> |
| <para> |
| For example, consider a bus that has a bloom size of 8 bytes, and the |
| following mask/filter combinations: |
| </para> |
| <programlisting><![CDATA[ |
| filter 0x0101010101010101 |
| mask 0x0101010101010101 |
| -> matches |
| |
| filter 0x0303030303030303 |
| mask 0x0101010101010101 |
| -> doesn't match |
| |
| filter 0x0101010101010101 |
| mask 0x0303030303030303 |
| -> matches |
| ]]></programlisting> |
| |
| <para> |
| Hence, in order to catch all messages, a mask filled with |
| <constant>0xff</constant> bytes can be installed as a wildcard match rule. |
| </para> |
| |
| <refsect2> |
| <title>Generations</title> |
| |
| <para> |
| Uploaded matches may contain multiple masks, which have to be as large |
| as the bloom filter size defined by the bus. Each block of a mask is |
| called a <emphasis>generation</emphasis>, starting at index 0. |
| |
| At match time, when a signal is about to be delivered, a bloom mask |
| generation is passed, which denotes which of the bloom masks the filter |
| should be matched against. This allows programs to provide backward |
| compatible masks at upload time, while older clients can still match |
| against older versions of filters. |
| </para> |
| </refsect2> |
| </refsect1> |
| |
| <refsect1> |
| <title>Matches for kernel notifications</title> |
| <para> |
| To receive kernel generated notifications (see |
| <citerefentry> |
| <refentrytitle>kdbus.message</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </citerefentry>), |
| a connection must install match rules that are different from |
| the bloom filter matches described in the section above. They can be |
| filtered by the connection ID that caused the notification to be sent, by |
| one of the names it currently owns, or by the type of the notification |
| (ID/name add/remove/change). |
| </para> |
| </refsect1> |
| |
| <refsect1> |
| <title>Adding a match</title> |
| <para> |
| To add a match, the <constant>KDBUS_CMD_MATCH_ADD</constant> ioctl is |
| used, which takes a <type>struct kdbus_cmd_match</type> as an argument |
| described below. |
| |
| Note that each of the items attached to this command will internally |
| create one match <emphasis>rule</emphasis>, and the collection of them, |
| which is submitted as one block via the ioctl, is called a |
| <emphasis>match</emphasis>. To allow a message to pass, all rules of a |
| match have to be satisfied. Hence, adding more items to the command will |
| only narrow the possibility of a match to effectively let the message |
| pass, and will decrease the chance that the connection's process will be |
| woken up needlessly. |
| |
| Multiple matches can be installed per connection. As long as one of it has |
| a set of rules which allows the message to pass, this one will be |
| decisive. |
| </para> |
| |
| <programlisting> |
| struct kdbus_cmd_match { |
| __u64 size; |
| __u64 flags; |
| __u64 return_flags; |
| __u64 cookie; |
| struct kdbus_item items[0]; |
| }; |
| </programlisting> |
| |
| <para>The fields in this struct are described below.</para> |
| |
| <variablelist> |
| <varlistentry> |
| <term><varname>size</varname></term> |
| <listitem><para> |
| The overall size of the struct, including its items. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>flags</varname></term> |
| <listitem><para>Flags to control the behavior of the ioctl.</para> |
| <variablelist> |
| <varlistentry> |
| <term><constant>KDBUS_MATCH_REPLACE</constant></term> |
| <listitem> |
| <para>Make the endpoint file group-accessible</para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>KDBUS_FLAG_NEGOTIATE</constant></term> |
| <listitem> |
| <para> |
| Requests a set of valid flags for this ioctl. When this bit is |
| set, no action is taken; the ioctl will return |
| <errorcode>0</errorcode>, and the <varname>flags</varname> |
| field will have all bits set that are valid for this command. |
| The <constant>KDBUS_FLAG_NEGOTIATE</constant> bit will be |
| cleared by the operation. |
| </para> |
| </listitem> |
| </varlistentry> |
| </variablelist> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>return_flags</varname></term> |
| <listitem><para> |
| Flags returned by the kernel. Currently unused and always set to |
| <constant>0</constant> by the kernel. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>cookie</varname></term> |
| <listitem><para> |
| A cookie which identifies the match, so it can be referred to when |
| removing it. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>items</varname></term> |
| <listitem> |
| <para> |
| Items to define the actual rules of the matches. The following item |
| types are expected. Each item will create one new match rule. |
| </para> |
| <variablelist> |
| <varlistentry> |
| <term><constant>KDBUS_ITEM_BLOOM_MASK</constant></term> |
| <listitem> |
| <para> |
| An item that carries the bloom filter mask to match against |
| in its data field. The payload size must match the bloom |
| filter size that was specified when the bus was created. |
| See the "Bloom filters" section above for more information on |
| bloom filters. |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>KDBUS_ITEM_NAME</constant></term> |
| <listitem> |
| <para> |
| When used as part of kernel notifications, this item specifies |
| a name that is acquired, lost or that changed its owner (see |
| below). When used as part of a match for user-generated signal |
| messages, it specifies a name that the sending connection must |
| own at the time of sending the signal. |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>KDBUS_ITEM_ID</constant></term> |
| <listitem> |
| <para> |
| Specify a sender connection's ID that will match this rule. |
| For kernel notifications, this specifies the ID of a |
| connection that was added to or removed from the bus. |
| For used-generated signals, it specifies the ID of the |
| connection that sent the signal message. |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>KDBUS_ITEM_NAME_ADD</constant></term> |
| <term><constant>KDBUS_ITEM_NAME_REMOVE</constant></term> |
| <term><constant>KDBUS_ITEM_NAME_CHANGE</constant></term> |
| <listitem> |
| <para> |
| These items request delivery of kernel notifications that |
| describe a name acquisition, loss, or change. The details |
| are stored in the item's |
| <varname>kdbus_notify_name_change</varname> member. |
| All information specified must be matched in order to make |
| the message pass. Use |
| <constant>KDBUS_MATCH_ID_ANY</constant> to |
| match against any unique connection ID. |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>KDBUS_ITEM_ID_ADD</constant></term> |
| <term><constant>KDBUS_ITEM_ID_REMOVE</constant></term> |
| <listitem> |
| <para> |
| These items request delivery of kernel notifications that are |
| generated when a connection is created or terminated. |
| <type>struct kdbus_notify_id_change</type> is used to |
| store the actual match information. This item can be used to |
| monitor one particular connection ID, or, when the ID field |
| is set to <constant>KDBUS_MATCH_ID_ANY</constant>, |
| all of them. |
| </para> |
| </listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>KDBUS_ITEM_NEGOTIATE</constant></term> |
| <listitem><para> |
| With this item, programs can <emphasis>probe</emphasis> the |
| kernel for known item types. See |
| <citerefentry> |
| <refentrytitle>kdbus.item</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </citerefentry> |
| for more details. |
| </para></listitem> |
| </varlistentry> |
| </variablelist> |
| |
| <para> |
| Unrecognized items are rejected, and the ioctl will fail with |
| <varname>errno</varname> set to <constant>EINVAL</constant>. |
| </para> |
| </listitem> |
| </varlistentry> |
| </variablelist> |
| |
| <para> |
| Refer to |
| <citerefentry> |
| <refentrytitle>kdbus.message</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </citerefentry> |
| for more information on message types. |
| </para> |
| </refsect1> |
| |
| <refsect1> |
| <title>Removing a match</title> |
| <para> |
| Matches can be removed with the |
| <constant>KDBUS_CMD_MATCH_REMOVE</constant> ioctl, which takes |
| <type>struct kdbus_cmd_match</type> as argument, but its fields |
| usage slightly differs compared to that of |
| <constant>KDBUS_CMD_MATCH_ADD</constant>. |
| </para> |
| |
| <programlisting> |
| struct kdbus_cmd_match { |
| __u64 size; |
| __u64 cookie; |
| __u64 flags; |
| __u64 return_flags; |
| struct kdbus_item items[0]; |
| }; |
| </programlisting> |
| |
| <para>The fields in this struct are described below.</para> |
| |
| <variablelist> |
| <varlistentry> |
| <term><varname>size</varname></term> |
| <listitem><para> |
| The overall size of the struct, including its items. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>cookie</varname></term> |
| <listitem><para> |
| The cookie of the match, as it was passed when the match was added. |
| All matches that have this cookie will be removed. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>flags</varname></term> |
| <listitem><para> |
| No flags are supported for this use case. |
| <constant>KDBUS_FLAG_NEGOTIATE</constant> is accepted to probe for |
| valid flags. If set, the ioctl will fail with |
| <errorcode>-1</errorcode>, <varname>errno</varname> is set to |
| <constant>EPROTO</constant>, and the <varname>flags</varname> field |
| is set to <constant>0</constant>. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>return_flags</varname></term> |
| <listitem><para> |
| Flags returned by the kernel. Currently unused and always set to |
| <constant>0</constant> by the kernel. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><varname>items</varname></term> |
| <listitem> |
| <para> |
| No items are supported for this use case, but |
| <constant>KDBUS_ITEM_NEGOTIATE</constant> is allowed nevertheless. |
| </para> |
| </listitem> |
| </varlistentry> |
| </variablelist> |
| </refsect1> |
| |
| <refsect1> |
| <title>Return value</title> |
| <para> |
| On success, all mentioned ioctl commands return <errorcode>0</errorcode>; |
| on error, <errorcode>-1</errorcode> is returned, and |
| <varname>errno</varname> is set to indicate the error. |
| If the issued ioctl is illegal for the file descriptor used, |
| <varname>errno</varname> will be set to <constant>ENOTTY</constant>. |
| </para> |
| |
| <refsect2> |
| <title> |
| <constant>KDBUS_CMD_MATCH_ADD</constant> may fail with the following |
| errors |
| </title> |
| |
| <variablelist> |
| <varlistentry> |
| <term><constant>EINVAL</constant></term> |
| <listitem><para> |
| Illegal flags or items. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>EDOM</constant></term> |
| <listitem><para> |
| Illegal bloom filter size. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>EMFILE</constant></term> |
| <listitem><para> |
| Too many matches for this connection. |
| </para></listitem> |
| </varlistentry> |
| </variablelist> |
| </refsect2> |
| |
| <refsect2> |
| <title> |
| <constant>KDBUS_CMD_MATCH_REMOVE</constant> may fail with the following |
| errors |
| </title> |
| |
| <variablelist> |
| <varlistentry> |
| <term><constant>EINVAL</constant></term> |
| <listitem><para> |
| Illegal flags. |
| </para></listitem> |
| </varlistentry> |
| |
| <varlistentry> |
| <term><constant>EBADSLT</constant></term> |
| <listitem><para> |
| A match entry with the given cookie could not be found. |
| </para></listitem> |
| </varlistentry> |
| </variablelist> |
| </refsect2> |
| </refsect1> |
| |
| <refsect1> |
| <title>See Also</title> |
| <simplelist type="inline"> |
| <member> |
| <citerefentry> |
| <refentrytitle>kdbus</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </citerefentry> |
| </member> |
| <member> |
| <citerefentry> |
| <refentrytitle>kdbus.bus</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </citerefentry> |
| </member> |
| <member> |
| <citerefentry> |
| <refentrytitle>kdbus.match</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </citerefentry> |
| </member> |
| <member> |
| <citerefentry> |
| <refentrytitle>kdbus.fs</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </citerefentry> |
| </member> |
| <member> |
| <citerefentry> |
| <refentrytitle>kdbus.item</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </citerefentry> |
| </member> |
| <member> |
| <citerefentry> |
| <refentrytitle>kdbus.message</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </citerefentry> |
| </member> |
| <member> |
| <citerefentry> |
| <refentrytitle>kdbus.name</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </citerefentry> |
| </member> |
| <member> |
| <citerefentry> |
| <refentrytitle>kdbus.pool</refentrytitle> |
| <manvolnum>7</manvolnum> |
| </citerefentry> |
| </member> |
| </simplelist> |
| </refsect1> |
| </refentry> |