* in cookie_reply
* @KDBUS_MSG_NO_AUTO_START: Do not start a service, if the addressed
* name is not currently active
+ * @KDBUS_MSG_SIGNAL: Treat this message as signal
*/
enum kdbus_msg_flags {
KDBUS_MSG_EXPECT_REPLY = 1ULL << 0,
KDBUS_MSG_NO_AUTO_START = 1ULL << 1,
+ KDBUS_MSG_SIGNAL = 1ULL << 2,
};
/**
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 broadcast messages that have a matching filter.
+and will be delivered signal messages that have a matching filter.
For general information on bloom filters, see
https://en.wikipedia.org/wiki/Bloom_filter
The size of the bloom filter is defined per bus when it is created, in
-kdbus_bloom_parameter.size. All bloom filters attached to broadcast 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).
+kdbus_bloom_parameter.size. All bloom filters attached to signals 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 on the userspace side. The kernel
just checks the bitmasks to decide whether or not to let the message pass. All
Masks are entities that are always passed to the kernel as part of a match
(with an item of type KDBUS_ITEM_BLOOM_MASK), and filters can be attached to
-broadcast messages (with an item of type KDBUS_ITEM_BLOOM_FILTER).
+signals, with an item of type KDBUS_ITEM_BLOOM_FILTER.
-For a broadcast to match, all set bits in the filter have to be set in the
-installed match mask as well. For example, consider a bus has a bloom size
-of 8 bytes, and the following mask/filter combinations:
+For a filter to match, all its bits have to be set in the match mask as well.
+For example, consider a bus has a bloom size of 8 bytes, and the following
+mask/filter combinations:
filter 0x0101010101010101
mask 0x0101010101010101
bloom size defined by the bus. Each block of a mask is called a 'generation',
starting at index 0.
-At match time, when a broadcast message 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 userspace to provide backward compatible
-masks at upload time, while older clients can still match against older
-versions of filters.
+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 userspace to provide backward compatible masks at upload
+time, while older clients can still match against older versions of filters.
10.5 Removing a match
bool has_bloom = false;
bool has_name = false;
bool has_fds = false;
+ bool is_broadcast;
+ bool is_signal;
u64 vec_size;
+ is_broadcast = (msg->dst_id == KDBUS_DST_ID_BROADCAST);
+ is_signal = !!(msg->flags & KDBUS_MSG_SIGNAL);
+
/* count data payloads */
n_vecs = 0;
n_memfds = 0;
return -EEXIST;
has_fds = true;
- /* do not allow to broadcast file descriptors */
- if (msg->dst_id == KDBUS_DST_ID_BROADCAST)
+ /* Do not allow to broadcast file descriptors */
+ if (is_broadcast)
return -ENOTUNIQ;
if (fds_count > KDBUS_MSG_MAX_FDS)
if (msg->dst_id == KDBUS_DST_ID_NAME && !has_name)
return -EDESTADDRREQ;
- if (msg->dst_id == KDBUS_DST_ID_BROADCAST) {
- /* broadcasts can't take names */
+ if (is_broadcast) {
+ /* Broadcasts can't take names */
if (has_name)
return -EBADMSG;
- /* broadcast messages require a bloom filter */
- if (!has_bloom)
+ /* All broadcasts have to be signals */
+ if (!is_signal)
return -EBADMSG;
- /* timeouts are not allowed for broadcasts */
+ /* Timeouts are not allowed for broadcasts */
if (msg->timeout_ns > 0)
return -ENOTUNIQ;
}
- /* bloom filters are for undirected messages only */
- if (has_name && has_bloom)
+ /*
+ * Signal messages require a bloom filter, and bloom filters are
+ * only valid with signals.
+ */
+ if (is_signal ^ has_bloom)
return -EBADMSG;
return 0;
ret = kdbus_check_and_write_flags(m->msg.flags, buf,
offsetof(struct kdbus_cmd_send,
kernel_msg_flags),
- KDBUS_MSG_EXPECT_REPLY |
- KDBUS_MSG_NO_AUTO_START);
+ KDBUS_MSG_EXPECT_REPLY |
+ KDBUS_MSG_NO_AUTO_START |
+ KDBUS_MSG_SIGNAL);
if (ret < 0)
goto exit_free;
ret = -ENOTUNIQ;
goto exit_free;
}
+
+ /* replies may not be expected for signals */
+ if (m->msg.flags & KDBUS_MSG_SIGNAL) {
+ ret = -EINVAL;
+ goto exit_free;
+ }
} else {
/*
* KDBUS_SEND_SYNC_REPLY is only valid together with
return ret;
}
+ if (dst_id == KDBUS_DST_ID_BROADCAST)
+ flags |= KDBUS_MSG_SIGNAL;
+
memset(msg, 0, size);
msg->flags = flags;
msg->priority = priority;
item->type = KDBUS_ITEM_BLOOM_FILTER;
item->size = KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64;
item = KDBUS_ITEM_NEXT(item);
+
+ msg->flags |= KDBUS_MSG_SIGNAL;
}
make_item_memfds(item, memfds_array, memfd_count);
item->type = KDBUS_ITEM_BLOOM_FILTER;
item->size = KDBUS_ITEM_SIZE(sizeof(struct kdbus_bloom_filter)) + 64;
item = KDBUS_ITEM_NEXT(item);
+
+ msg->flags |= KDBUS_MSG_SIGNAL;
}
make_item_fds(item, fd_array, fd_count);
msg->size = size;
msg->src_id = conn->id;
msg->dst_id = KDBUS_DST_ID_BROADCAST;
+ msg->flags = KDBUS_MSG_SIGNAL;
msg->payload_type = KDBUS_PAYLOAD_DBUS;
msg->cookie = cookie;